/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axutil_qname.h>
#include <axis2_svc.h>
#include <axiom_soap_header.h>
#include <axiom_soap_body.h>
#include <axiom_soap_header_block.h>
#include <axis2_endpoint_ref.h>
#include <axutil_property.h>
#include <rampart_username_token.h>
#include <rampart_constants.h>
#include <rampart_crypto_util.h>
#include <rampart_util.h>
#include <rampart_callback.h>
#include <rampart_handler_util.h>
#include <rampart_sec_processed_result.h>
#include <rampart_authn_provider.h>
#include <oxs_axiom.h>
#include <oxs_utility.h>

/** public functions*/

axis2_status_t AXIS2_CALL
rampart_username_token_build(
    const axutil_env_t *env,
    rampart_context_t *rampart_context,
    axiom_node_t *sec_node,
    axiom_namespace_t *sec_ns_obj)
{

    axiom_node_t *ut_node = NULL;
    axiom_node_t *un_node = NULL;
    axiom_node_t *pw_node = NULL;
    axiom_node_t *nonce_node = NULL;
    axiom_node_t *created_node = NULL;
    axiom_element_t  *ut_ele = NULL;
    axiom_element_t *un_ele = NULL;
    axiom_element_t *pw_ele = NULL;
    axiom_element_t *nonce_ele = NULL;
    axiom_element_t *created_ele = NULL;
    axiom_namespace_t *wsu_ns_obj = NULL;
    axiom_attribute_t *om_attr = NULL;
    axis2_char_t *password = NULL;
    axis2_char_t *username = NULL;
    rampart_callback_t *password_callback = NULL;
    /*  axis2_bool_t isdigest = AXIS2_FALSE;*/
    axis2_char_t *password_type = NULL;
    password_callback_fn password_function = NULL;
    void *param = NULL;


    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    /*Directly call the password from callback module*/

    username = rampart_context_get_user(rampart_context, env);
    if(!username)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_usernametoken] User is not specified.");
        return AXIS2_FAILURE;
    }

    password = rampart_context_get_password(rampart_context, env);

    if(!password)
    {
        password_function = rampart_context_get_pwcb_function(rampart_context, env);
        if(password_function)
        {
            param = rampart_context_get_pwcb_user_params(rampart_context, env);
            if(!param)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                               "[rampart][rampart_usernametoken] Param is not set.");
                return AXIS2_FAILURE;
            }
            password = (*password_function)(env, username, param);
        }
        else
        {
            password_callback = rampart_context_get_password_callback(rampart_context, env);
            if(!password_callback)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                               "[rampart][rampart_usernametoken] password callback module is not loaded. ERROR");
                return AXIS2_FAILURE;
            }
            password = rampart_callback_password(env, password_callback, username);
        }
    }
    if (!password)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_usernametoken] Cannot find the password for user %s. ERROR", username);
        return AXIS2_FAILURE;
    }

    axiom_namespace_increment_ref(sec_ns_obj, env);
    ut_ele = axiom_element_create(env, sec_node,
                                  RAMPART_SECURITY_USERNAMETOKEN,
                                  sec_ns_obj,
                                  &ut_node);

    wsu_ns_obj = axiom_namespace_create(env, RAMPART_WSU_XMLNS,
                                        RAMPART_WSU);
    axiom_element_declare_namespace(ut_ele, env,
                                    ut_node, wsu_ns_obj);

    if (ut_ele)
    {

        axiom_namespace_increment_ref(sec_ns_obj, env);
        un_ele = axiom_element_create(env, ut_node,
                                      RAMPART_SECURITY_USERNAMETOKEN_USERNAME, sec_ns_obj, &un_node);
        if (un_ele)
        {
            axiom_element_set_text(un_ele, env, username, un_node);
        }

        password_type = rampart_context_get_password_type(rampart_context, env);
        if(!password_type)
        {
            password_type = RAMPART_PASSWORD_TEXT;
        }

        if (0 == axutil_strcmp(password_type, RAMPART_PASSWORD_DIGEST))
        {
            axis2_char_t *nonce_val = NULL;
            axis2_char_t *created_val = NULL;
            axis2_char_t *digest_val = NULL;

            nonce_val = oxs_util_generate_nonce(env, 24) ;
            created_val = rampart_generate_time(env, 0);
            digest_val = rampart_crypto_sha1(env, nonce_val, created_val, password);

            axiom_namespace_increment_ref(sec_ns_obj, env);
            pw_ele = axiom_element_create(env, ut_node,
                                          RAMPART_SECURITY_USERNAMETOKEN_PASSWORD, sec_ns_obj, &pw_node);
            if (pw_ele)
            {

                axiom_element_set_text(pw_ele, env, digest_val, pw_node);

                om_attr = axiom_attribute_create(env, RAMPART_SECURITY_USERNAMETOKEN_PASSWORD_ATTR_TYPE,
                                                 RAMPART_PASSWORD_DIGEST_URI, NULL);

                axiom_element_add_attribute(pw_ele, env, om_attr, pw_node);

            }

			axiom_namespace_increment_ref(sec_ns_obj, env);
            nonce_ele = axiom_element_create(env, ut_node,
                                             RAMPART_SECURITY_USERNAMETOKEN_NONCE, sec_ns_obj, &nonce_node);
            if (nonce_ele)
            {
                axiom_element_set_text(nonce_ele, env, nonce_val , nonce_node);
            }

            created_ele = axiom_element_create(env, ut_node,
                                               RAMPART_SECURITY_USERNAMETOKEN_CREATED, wsu_ns_obj, &created_node);
            if (created_ele)
            {
                axiom_element_set_text(created_ele, env, created_val, created_node);
            }

            if(nonce_val){
                AXIS2_FREE(env->allocator, nonce_val);
                nonce_val = NULL;
            }
            if(created_val)
            {
                AXIS2_FREE(env->allocator, created_val);
                created_val = NULL;
            }
            if(digest_val)
            {
                AXIS2_FREE(env->allocator, digest_val);
                digest_val = NULL;
            }
        }

        else /*default is passwordText*/
        {
			axiom_namespace_increment_ref(sec_ns_obj, env);
            pw_ele = axiom_element_create(env, ut_node,
                                          RAMPART_SECURITY_USERNAMETOKEN_PASSWORD, sec_ns_obj, &pw_node);
            if (pw_ele)
            {
                axiom_element_set_text(pw_ele, env, password, pw_node);

                om_attr = axiom_attribute_create(env,
                                                 RAMPART_SECURITY_USERNAMETOKEN_PASSWORD_ATTR_TYPE, RAMPART_PASSWORD_TEXT_URI, NULL);

                axiom_element_add_attribute(pw_ele, env, om_attr, pw_node);
            }
        } /*End if passwordType == passwordText*/
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
rampart_username_token_validate(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    axiom_node_t *ut_node,
    rampart_context_t *rampart_context)
{
    axiom_child_element_iterator_t *children = NULL;
    axis2_char_t *username = NULL;
    axis2_char_t *password = NULL;
    axis2_char_t *nonce = NULL;
    axis2_char_t *created = NULL;
    axis2_char_t *password_type = NULL;
    rampart_callback_t *password_callback = NULL;
    rampart_authn_provider_t *authn_provider = NULL;
    axis2_char_t *password_from_svr = NULL;
    axis2_char_t *password_to_compare = NULL;
	axis2_bool_t free_password_to_compare = AXIS2_FALSE;
    axis2_ctx_t *ctx = NULL;
    rampart_authn_provider_status_t auth_status= RAMPART_AUTHN_PROVIDER_GENERAL_ERROR ;
    axiom_element_t *ut_ele = NULL;
    password_callback_fn password_function = NULL;
    void *param = NULL;
    auth_password_func authenticate_with_password = NULL;
    auth_digest_func authenticate_with_digest = NULL;
    axis2_char_t *password_type_pol = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    ut_ele = axiom_node_get_data_element(ut_node, env);
    if(!ut_ele)
    {

        return AXIS2_FAILURE;
    }

    /*Check: Any USERNAME_TOKEN MUST NOT have more than one PASSWORD*/
    if (1 <  oxs_axiom_get_number_of_children_with_qname(env, ut_node,
            RAMPART_SECURITY_USERNAMETOKEN_PASSWORD, RAMPART_WSSE_XMLNS, RAMPART_WSSE))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_usernametoken] Username token must not have more than one password");
        return AXIS2_FAILURE;
    }

    /*Check: Any USERNAME_TOKEN MUST NOT have more than one CREATED*/
    if (1 <  oxs_axiom_get_number_of_children_with_qname(env,
            ut_node, RAMPART_SECURITY_USERNAMETOKEN_CREATED, RAMPART_WSSE_XMLNS, RAMPART_WSSE))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_usernametoken] Username token must not have more than one creted element");
        return AXIS2_FAILURE;
    }

    /*Check: Any USERNAME_TOKEN MUST NOT have more than one NONCE*/
    if (1 < oxs_axiom_get_number_of_children_with_qname(env, ut_node,
            RAMPART_SECURITY_USERNAMETOKEN_NONCE, RAMPART_WSSE_XMLNS, RAMPART_WSSE))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_usernametoken] Username token must not have more than one nonce element");
        return AXIS2_FAILURE;
    }

    /*Go thru children of UsernameToken element*/
    children = axiom_element_get_child_elements(ut_ele, env, ut_node);
    if (children)
    {
        /*Go thru children and find username token parameters*/
        while (AXIS2_TRUE == axiom_child_element_iterator_has_next(children, env))
        {
            axiom_node_t *node = NULL;
            axiom_element_t *element = NULL;
            axis2_char_t *localname = NULL;

            node = axiom_child_element_iterator_next(children, env);
            element = axiom_node_get_data_element(node, env);
            localname =  axiom_element_get_localname(element, env);

            if (0 == axutil_strcmp(localname,
                                   RAMPART_SECURITY_USERNAMETOKEN_USERNAME))
            {
                username = axiom_element_get_text(element, env, node);

            }
            else if (0 == axutil_strcmp(localname ,
                                        RAMPART_SECURITY_USERNAMETOKEN_PASSWORD))
            {
                password_type = axiom_element_get_attribute_value_by_name(element,
                                env, RAMPART_SECURITY_USERNAMETOKEN_PASSWORD_ATTR_TYPE);

                if (!password_type)
                {
                    /*ERROR: R4201 Any PASSWORD MUST specify a Type attribute */
                    /*AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][rampart_usernametoken] Password Type is not specified in the password element");
                    return AXIS2_FAILURE;*/
                    password_type = RAMPART_PASSWORD_TEXT_URI;
                }

                /*Then we must check the password type with policy*/
                password_type_pol = rampart_context_get_password_type(rampart_context, env);
                if(!password_type_pol)
                {
                    password_type_pol = RP_PLAINTEXT;
                }

                if(axutil_strcmp(password_type_pol, RP_DIGEST)==0)
                {
                    if(0 != axutil_strcmp(password_type, RAMPART_PASSWORD_DIGEST_URI))
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[rampart][shp] Password Type is Wrong ");
                        rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_AUTHENTICATION,
                                                      "Password Type is Wrong. Should be Digested.",
                                                      RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);

                        return AXIS2_FAILURE;
                    }
                }
                else if(axutil_strcmp(password_type_pol, RP_PLAINTEXT)==0)
                {
                    if(0 == axutil_strcmp(password_type, RAMPART_PASSWORD_DIGEST_URI))
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[rampart][shp] Password Type is Wrong ");
                        rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_AUTHENTICATION,
                                                      "Password Type is Wrong. Should be PlainText.",
                                                      RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);

                        return AXIS2_FAILURE;
                    }
                }
                password = axiom_element_get_text(element, env, node);

            }
            else if (0 == axutil_strcmp(localname,
                                        RAMPART_SECURITY_USERNAMETOKEN_NONCE))
            {
                nonce = axiom_element_get_text(element, env, node);
                rampart_set_security_processed_result(env, msg_ctx,
                                                      RAMPART_SPR_UT_NONCE, nonce);

            }
            else if (0 == axutil_strcmp(localname ,
                                        RAMPART_SECURITY_USERNAMETOKEN_CREATED))
            {
                created = axiom_element_get_text(element, env, node);
                rampart_set_security_processed_result(env,
                                                      msg_ctx, RAMPART_SPR_UT_CREATED, created);

            }
            else
            {
                AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                               "\n[rampart][rampart_usernametoken] Unknown element found %s -> %s",
                               localname, axiom_element_get_text(element, env, node));
            }


        }/*end of while*/
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_usernametoken] Cannot find child elements of Usernametoken");
        return AXIS2_FAILURE;
    }

    /*Now we process collected usernametoken parameters*/
    if (!username)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_usernametoken] Username is not specified");
        return AXIS2_FAILURE;
    }

    /*Set the username to the SPR*/
    rampart_set_security_processed_result(env,
                                          msg_ctx, RAMPART_SPR_UT_USERNAME, username);
    ctx = axis2_msg_ctx_get_base(msg_ctx, env);

    /**
     * NOTE: Here we will try two apraoches to get the UT validated
     * 1. Authentication module
     * 2. Password callback module
     *
     * If authentication module is defined use it. 
     * Else try the usual approach to get password from the callback and compare
     **/


    /*In both authentication and password callback methods we should first try to
     *use function pointers. */

    if (0 == axutil_strcmp(password_type, RAMPART_PASSWORD_DIGEST_URI))
    {
        authenticate_with_digest = rampart_context_get_auth_digest_function(
                                       rampart_context, env);
        if(authenticate_with_digest)
        {
            auth_status = authenticate_with_digest(env,
                                                   username, nonce, created, password, NULL);
            if(RAMPART_AUTHN_PROVIDER_GRANTED == auth_status)
            {
                AXIS2_LOG_INFO(env->log,
                               "[rampart][rampart_usernametoken] User authenticated");
                rampart_set_security_processed_result(env,
                                                      msg_ctx,RAMPART_SPR_UT_CHECKED, RAMPART_YES);
                return AXIS2_SUCCESS;
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_usernametoken] Password is not valid for user %s : status %d",
                                username, auth_status);
                return AXIS2_FAILURE;
            }
        }
    }

    else
    {
        authenticate_with_password =
            rampart_context_get_auth_password_function(rampart_context, env);
        if(authenticate_with_password)
        {
            auth_status = authenticate_with_password(env, username, password, NULL);
            if(RAMPART_AUTHN_PROVIDER_GRANTED == auth_status)
            {
                AXIS2_LOG_INFO(env->log,  "[rampart][rampart_usernametoken] User authenticated");
                rampart_set_security_processed_result(env,
                                                      msg_ctx, RAMPART_SPR_UT_CHECKED, RAMPART_YES);
                return AXIS2_SUCCESS;
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_usernametoken] Password is not valid for user %s : status %d",
                                username, auth_status);
                return AXIS2_FAILURE;
            }
        }
    }

    authn_provider = rampart_context_get_authn_provider(rampart_context, env);
    if(authn_provider)
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_usernametoken] Password authentication using AUTH MODULE");
        auth_status = rampart_authenticate_un_pw(env, authn_provider,
                      username, password, nonce, created, password_type, msg_ctx);
        if(RAMPART_AUTHN_PROVIDER_GRANTED == auth_status)
        {
            AXIS2_LOG_INFO(env->log,  "[rampart][rampart_usernametoken] User authenticated");
            rampart_set_security_processed_result(env, msg_ctx,
                                                  RAMPART_SPR_UT_CHECKED, RAMPART_YES);
            return AXIS2_SUCCESS;
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_usernametoken] Password is not valid for user %s : status %d",
                            username, auth_status);
            return AXIS2_FAILURE;
        }

    }
    else
    {
        /*Auth module is NULL. Use Callback password*/
        /*First we must check the password in rampart_context.*/

        password_from_svr = rampart_context_get_password(
                                rampart_context, env);

        /*If the direct passowrd is available, then chk for the username too in the context. We need to compare it with the message's:
          The reason is here we do not use callbacks. Thus there will be no failure if the username is wrong and the password is correct*/
        if(password_from_svr){
            axis2_char_t *context_usr = NULL;

            context_usr = rampart_context_get_user(rampart_context, env);
            if(0 != axutil_strcmp(context_usr, username)){
                rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                                  "Username is not valid", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                 "[rampart][rampart_usernametoken] Username id not valid");
                return AXIS2_FAILURE;
            }
        }

        /*If not then check the call  back function*/
        if(!password_from_svr)
        {
            password_function = rampart_context_get_pwcb_function(rampart_context, env);
            if(password_function)
            {
                param = rampart_context_get_pwcb_user_params(rampart_context, env);
                if(!param)
                {
                    rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                                  "Error in the Internal configuration.", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][rampart_usernametoken] Error in the pwcb function.");
                    return AXIS2_FAILURE;
                }
                password_from_svr = (*password_function)(env, username, param);
            }
            else
            {
                password_callback = rampart_context_get_password_callback(rampart_context, env);
                if(!password_callback)
                {
                    rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                                  "Error in the Internal configuration.", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][rampart_usernametoken] Password callback module is not specified");

                    return AXIS2_FAILURE;
                }
                AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                               "[rampart][rampart_usernametoken] Password authentication using CALLBACK MODULE ");
                password_from_svr = rampart_callback_password(env, password_callback, username);
            }
        }else{

            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                           "[rampart][rampart_usernametoken] Using the password is in the context");
        }

        if (!password_from_svr)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_usernametoken] Cannot get the password for user %s", username);
            return AXIS2_FAILURE;
        }

        /*Alright NOW we have the password. Is digest needed?*/
        if (0 == axutil_strcmp(password_type, RAMPART_PASSWORD_DIGEST_URI))
        {
            AXIS2_LOG_INFO(env->log,
                           "[rampart][rampart_usernametoken] Generating digest to compare from the password");
            password_to_compare = rampart_crypto_sha1(env, nonce,
                                  created, password_from_svr);
            rampart_set_security_processed_result(env, msg_ctx,
                                                  RAMPART_SPR_UT_PASSWORD_TYPE, RAMPART_PASSWORD_DIGEST_URI);
			free_password_to_compare = AXIS2_TRUE;
        }
        else
        {
            password_to_compare = password_from_svr;
            rampart_set_security_processed_result(env, msg_ctx,
                                                  RAMPART_SPR_UT_PASSWORD_TYPE, RAMPART_PASSWORD_TEXT_URI);
        }

        /*The BIG moment. Compare passwords*/
        if (0 == axutil_strcmp(password_to_compare , password))
        {
            AXIS2_LOG_INFO(env->log,
                           "[rampart][rampart_usernametoken] Password comparison SUCCESS");
            rampart_set_security_processed_result(env, msg_ctx,
                                                  RAMPART_SPR_UT_CHECKED, RAMPART_YES);
			if(free_password_to_compare)
			{
				AXIS2_FREE(env->allocator, password_to_compare);
			}
            return AXIS2_SUCCESS;
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_usernametoken] Password is not valid for user %s",
                            username);
			if(free_password_to_compare)
			{
				AXIS2_FREE(env->allocator, password_to_compare);
			}
            return AXIS2_FAILURE;
        }
    }
}
