/*
 * 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 <rampart_engine.h>
#include <axis2_ctx.h>
#include <axis2_svc.h>
#include <axis2_desc.h>
#include <axis2_policy_include.h>
#include <rp_secpolicy_builder.h>
#include <neethi_policy.h>
#include <rampart_authn_provider.h>
#include <rampart_util.h>
#include <rampart_constants.h>
#include <rampart_callback.h>
#include <axis2_msg.h>
#include <axis2_conf_ctx.h>
#include <rampart_handler_util.h>
#include <rampart_config.h>
#include <axis2_options.h>
#include <openssl_pkcs12_keystore.h>
#include <rampart_sct_provider_utility.h>

/*This method sets all the configurations
 loads required modules and start rampart.*/


neethi_policy_t *AXIS2_CALL
build_policy(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    axis2_bool_t is_inflow);


axis2_status_t AXIS2_CALL
set_rampart_user_properties(
    const axutil_env_t *env,
    rampart_context_t *rampart_context);

axis2_status_t AXIS2_CALL
rampart_engine_retrieve_key_mgr_prop_from_policy(
	rampart_context_t *rampart_context, 
	const axutil_env_t *env);

AXIS2_EXTERN rampart_context_t *AXIS2_CALL
rampart_engine_build_configuration(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    axis2_bool_t is_inflow)
{

    rp_secpolicy_t *secpolicy = NULL;
    rampart_context_t *rampart_context = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    axis2_bool_t is_server_side = AXIS2_TRUE;
    neethi_policy_t *policy = NULL;
    axutil_property_t *property = NULL;
    void *value = NULL;

	/* Key Manager related */
    oxs_key_mgr_t *key_mgr = NULL;
    axis2_char_t *password = NULL;
    axis2_char_t *enc_user = NULL;
    axis2_char_t *pkcs12_file = NULL;
    axis2_char_t *pkcs12_password = NULL;
    axis2_char_t *pkcs12_buf = NULL;
    password_callback_fn password_function = NULL;
    rampart_callback_t *password_callback = NULL;   
    pkcs12_keystore_t *key_store = NULL;

    is_server_side = axis2_msg_ctx_get_server_side(msg_ctx, env);

    /*policy has to be created for inflow and outflow for server side. 
    but for client side, it will be created only on outflow*/
    if(is_server_side || (!is_server_side && !is_inflow))
    {
        policy = build_policy(env, msg_ctx, is_inflow);
        if(!policy)
        {
            rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                          "Error in the Internal configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_engine] Policy creation failed.");
            return NULL;
        }
    }
    
    /* for server side's outflow and client side's inflow, we have to use rampart context 
     * created in server side's inflow or client side's out flow
     */
    if((is_server_side && !is_inflow) || (!is_server_side && is_inflow))
    {
        if(is_server_side)
        {
            property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT);
        }
        else
        {
            /* Options from client's out message context will not be copied to in message context. 
             * So, we have to get original out message context to access the property
             */
            axis2_op_ctx_t *op_ctx = NULL;
            op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
            if(op_ctx)
            {
                axis2_msg_ctx_t *out_msg_ctx = NULL;
                out_msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_OUT);
                if(out_msg_ctx)
                {
                    property = axis2_msg_ctx_get_property(out_msg_ctx, env, RAMPART_CONTEXT);
                }
            }

        }

        if(property)
        {
            rampart_context = (rampart_context_t *)axutil_property_get_value(property, env);

            /*for serverside, recreate security policy and attach it to rampart context. This is because, 
            there might be differnt policy for inflow and outflow (only for server side. we are still not 
            supporting this feature for client side*/
            if(is_server_side)
            {
                secpolicy = rp_secpolicy_builder_build(env, policy);
                if(!secpolicy)
                {
                    rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                                  "Error in the Internal security policy configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][rampart_engine] Cannot create security policy from policy.");
                    return NULL;
                }
                rampart_context_set_secpolicy(rampart_context, env, secpolicy);
            }
            return (rampart_context_t *)axutil_property_get_value(property, env);
        }
        else
        {
            rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                          "Error in the Internal security policy configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_engine] Cannot get saved rampart_context");
            return NULL;
        }
    }

    /*rampart context will be created for server side's inflow and client side's out flow*/
    value = rampart_get_rampart_configuration(env, msg_ctx, RAMPART_CONFIGURATION);
    if(value)
    {
        rampart_context = (rampart_context_t *)value;
        rampart_context_increment_ref(rampart_context, env);
        if(!rampart_context_get_secpolicy(rampart_context, env))
        {
            secpolicy = rp_secpolicy_builder_build(env, policy);
            if(!secpolicy)
            {
                rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                              "Error in the Internal security policy configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_engine] Cannot create security policy from policy.");

                return NULL;
            }
            rampart_context_set_secpolicy(rampart_context, env, secpolicy);
        }
    }
    else
    {
        rampart_context = rampart_context_create(env);
        secpolicy = rp_secpolicy_builder_build(env, policy);
        if(!secpolicy)
        {
            rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                          "Error in the Internal configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_engine] Cannot create security policy from policy.");

            rampart_context_free(rampart_context, env);
            rampart_context = NULL;
            return NULL;
        }

        rampart_context_set_secpolicy(rampart_context, env, secpolicy);
        status = set_rampart_user_properties(env, rampart_context);
        if(status != AXIS2_SUCCESS)
        {
            rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
                                          "Error in the Internal configuration.", RAMPART_FAULT_IN_POLICY, msg_ctx);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_engine] rampc policies creation failed.");

            rampart_context_free(rampart_context, env);
            rampart_context = NULL;
            return NULL;
        }  
        
        rampart_engine_retrieve_key_mgr_prop_from_policy(rampart_context, env);
    }
    
    key_mgr = rampart_context_get_key_mgr(rampart_context, env);
    if (!key_mgr)
    {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][engine] Key mgr creation failed.");
            return NULL;
    }		

    /* Retrieve the password for obtaining private keys */
    enc_user = rampart_context_get_encryption_user(rampart_context, env);
    if(!enc_user)
    {
        enc_user = rampart_context_get_user(rampart_context, env);
    }
    if(enc_user)
    {
        password_function = rampart_context_get_pwcb_function(rampart_context, env);
        if(password_function)
        {
            void *param = NULL;
            param = rampart_context_get_pwcb_user_params(rampart_context, env);
            password = (*password_function)(env, enc_user, param);
            pkcs12_password = password;
        }
        else
        {
            password_callback = rampart_context_get_password_callback(
                                    rampart_context, env);
            if(password_callback)
            {
                password = rampart_callback_password(env, password_callback, enc_user);
                pkcs12_password = rampart_callback_pkcs12_password(env, password_callback, enc_user);
            }
            else
            {
                password = rampart_context_get_password(rampart_context, env);
                pkcs12_password = password;
            }
        }
    } 
    
    pkcs12_file = rampart_context_get_pkcs12_file_name(rampart_context, env);
    if(pkcs12_file && pkcs12_password)
    {
        key_store = pkcs12_keystore_create(env, pkcs12_file, pkcs12_password);
        if(!key_store)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][engine] PKCS12 KeyStore creation failed.");
            return NULL;	
        }        
    }
    else if(pkcs12_password && (pkcs12_buf = (axis2_char_t*)rampart_context_get_key_store_buff(rampart_context, env)))
    {
        key_store = pkcs12_keystore_create_from_buffer(env, pkcs12_buf, password,
                    oxs_key_mgr_get_key_store_buff_len(key_mgr, env));
        if(!key_store)
        {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][engine] PKCS12 KeyStore creation failed.");
                return NULL;	
        }  
    }
    
    oxs_key_mgr_set_key_store(key_mgr, env, key_store);

    if (password)
    {
        oxs_key_mgr_set_prv_key_password(key_mgr, env, password);
    }

    /* Since rampart_context is for request scope, we have to store in a container which has 
     * request scope 
     */
    property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST ,
               AXIS2_TRUE, (void *)rampart_context_free, rampart_context);
    axis2_msg_ctx_set_property(msg_ctx, env, RAMPART_CONTEXT, property);

    /*For the client side*/
    if(!is_server_side)
    {
        value = axis2_msg_ctx_get_property_value(msg_ctx, env, RAMPART_CLIENT_CONFIGURATION);
        if(value)
        {
            rampart_config_t *client_config = NULL;
            axutil_array_list_t *saml_tokens = NULL;
            axis2_char_t *config_value = NULL;
            issued_token_callback_func issued_token_aquire = NULL;
            int ttl = 0;

            client_config = (rampart_config_t*)value;
            config_value = rampart_config_get_username(client_config, env);
            if(config_value)
            {
                rampart_context_set_user(rampart_context, env, config_value);
            }
            
            config_value = rampart_config_get_password(client_config, env);
            if(config_value)
            {
                rampart_context_set_password(rampart_context, env, config_value);
            }

            config_value = rampart_config_get_password_type(client_config, env);
            if(config_value)
            {
                rampart_context_set_password_type(rampart_context, env, config_value);
            }

            ttl = rampart_config_get_ttl(client_config, env);
            if(ttl > 0)
            {
                rampart_context_set_ttl(rampart_context, env, ttl);
            }
            saml_tokens = rampart_config_get_saml_tokens(client_config, env);
            if (saml_tokens)
            {
                rampart_context_set_saml_tokens(rampart_context, env, saml_tokens);
            }
            issued_token_aquire = rampart_config_get_issued_token_aquire_function(client_config, env);
            if (issued_token_aquire)
            {
                rampart_context_set_issued_token_aquire_function(rampart_context, env, issued_token_aquire); 
            }
        }
    }
    return rampart_context;
}


neethi_policy_t *AXIS2_CALL
build_policy(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    axis2_bool_t is_inflow)
{
    axis2_desc_t *desc = NULL;
    axis2_policy_include_t *policy_include = NULL;
    neethi_policy_t *service_policy = NULL;
    axis2_op_t *op = NULL;
    axis2_msg_t *msg = NULL;

    op = axis2_msg_ctx_get_op(msg_ctx, env);
    if(!op)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[rampart][rampart_engine] Cannot find policy. Operation is NULL.");
        return NULL;
    }

    if(is_inflow)
    {
        msg = axis2_op_get_msg(op, env, "in");
    }
    else
    {
        msg = axis2_op_get_msg(op, env, "out");
    }

    if(!msg)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[rampart][rampart_engine] Cannot find policy. Message is NULL.");
        return NULL;
    }

    desc = axis2_msg_get_base(msg, env);
    if(!desc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[rampart][rampart_engine] Cannot find policy. Axis2 description is NULL.");
        return NULL;
    }

    policy_include = axis2_desc_get_policy_include(desc, env);
    if(!policy_include)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[rampart][rampart_engine] Policy include is NULL.");
        return NULL;
    }

    service_policy = axis2_policy_include_get_effective_policy(policy_include, env);
    if(!service_policy)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
            "[rampart][rampart_engine] Policy is NULL.");
        return NULL;
    }

    return service_policy;
}


axis2_status_t AXIS2_CALL
set_rampart_user_properties(
    const axutil_env_t *env,
    rampart_context_t *rampart_context)
{

    rampart_callback_t* password_callback_module = NULL;
    rampart_authn_provider_t *authn_provider = NULL;
	rampart_replay_detector_t *replay_detector = NULL;
    rampart_sct_provider_t* sct_provider = NULL;
    axis2_char_t *pwcb_module_name = NULL;
    axis2_char_t *authn_provider_name = NULL;
	axis2_char_t *replay_detector_name = NULL;
    axis2_char_t *sct_provider_name = NULL;

    if(rampart_context_set_user_from_file(rampart_context,env) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if(rampart_context_set_ttl_from_file(rampart_context,env) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if(rampart_context_set_clock_skew_buffer_from_file(rampart_context,env) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if(rampart_context_set_need_millisecond_precision_from_file(rampart_context,env)!= AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if(rampart_context_set_rd_val_from_file(rampart_context,env) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if(rampart_context_set_password_type_from_file(rampart_context,env) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    pwcb_module_name = rampart_context_get_password_callback_class(rampart_context,env);
    if(pwcb_module_name)
    {
        password_callback_module = rampart_load_pwcb_module(env, pwcb_module_name);
        if(password_callback_module)
        {
            rampart_context_set_password_callback(rampart_context,env,password_callback_module);
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }

    authn_provider_name = rampart_context_get_authn_module_name(rampart_context,env);
    if(authn_provider_name)
    {
        authn_provider = rampart_load_auth_module(env,authn_provider_name);
        if(authn_provider)
        {
            rampart_context_set_authn_provider(rampart_context,env,authn_provider);
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }

    replay_detector_name = rampart_context_get_replay_detector_name(rampart_context,env);
    if(replay_detector_name)
    {
        replay_detector = rampart_load_replay_detector(env,replay_detector_name);
        if(replay_detector)
        {
            rampart_context_set_replay_detector(rampart_context,env,(void*)replay_detector);
        }
        else
        {
            return AXIS2_FAILURE;
        }
    }
    else
    {
        /* if replay detector is not set, we can use replay detection function. We have to check 
         * whether user has already set it. If not, we can use default function */
        if(!rampart_context_get_replay_detect_function(rampart_context, env))
        {
            rampart_context_set_replay_detect_function(
                rampart_context, env, rampart_replay_detector_default, NULL);
        }
    }

    sct_provider_name = rampart_context_get_sct_provider_name(rampart_context,env);
    if(sct_provider_name)
    {
        sct_provider = rampart_load_sct_provider(env,sct_provider_name);
        if(sct_provider)
        {
            rampart_sct_provider_ops_t *ops = NULL;
            rampart_context_set_sct_provider(rampart_context,env,(void*)sct_provider);
            ops = sct_provider->ops;

            if(ops)
            {
                
                void *user_param = NULL;
                store_security_context_token_fn store_fn = NULL;
                obtain_security_context_token_fn obtain_fn = NULL;
                delete_security_context_token_fn delete_fn = NULL;
                validate_security_context_token_fn validate_fn = NULL;

                /* we have to call sct_provider's get user param method */
                if(ops->get_user_params)
                {
                    user_param = ops->get_user_params(env);
                    rampart_context_set_security_context_token_user_params(
                        rampart_context, env, user_param);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                        "[rampart]Cannot find 'get user param' operation of secrutiy context token "
                        "provider.");
                    return AXIS2_FAILURE;
                }

                /* get function pointers and set it to rampart context */
                store_fn = ops->store_security_context_token;
                if(store_fn)
                {
                    rampart_context_set_store_security_context_token_fn(
                        rampart_context, env, store_fn);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                        "[rampart]Cannot find 'store' operation of secrutiy context token provider.");
                    return AXIS2_FAILURE;
                }

                obtain_fn = ops->obtain_security_context_token;
                if(obtain_fn)
                {
                    rampart_context_set_obtain_security_context_token_fn(
                        rampart_context, env, obtain_fn);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                        "[rampart]Cannot find 'obtain' operation of secrutiy context token provider.");
                    return AXIS2_FAILURE;
                }

                delete_fn = ops->delete_security_context_token;
                if(delete_fn)
                {
                    rampart_context_set_delete_security_context_token_fn(
                        rampart_context, env, delete_fn);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                        "[rampart]Cannot find 'delete' operation of secrutiy context token provider.");
                    return AXIS2_FAILURE;
                }

                validate_fn = ops->validate_security_context_token;
                if(validate_fn)
                {
                    rampart_context_set_validate_security_context_token_fn(
                        rampart_context, env, validate_fn);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                        "[rampart]Cannot find 'validate' operation of secrutiy context token provider.");
                    return AXIS2_FAILURE;
                }
            }
            else
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
                    "[rampart]Cannot find operations of secrutiy context token provider.");
                return AXIS2_FAILURE;
            }
        }
        else 
        {
            return AXIS2_FAILURE;
        }
    }
    else
    {
        /* If sct_provider is not set, we can use sct functions. We have to check whether user has 
         * already set it. If not, we can use default function */
        if(!rampart_context_get_obtain_security_context_token_fn(rampart_context, env))
        {
            rampart_context_set_obtain_security_context_token_fn(
                rampart_context, env, sct_provider_obtain_sct_default);
        }

        if(!rampart_context_get_store_security_context_token_fn(rampart_context, env))
        {
            rampart_context_set_store_security_context_token_fn(
                rampart_context, env, sct_provider_store_sct_default);
        }

        if(!rampart_context_get_delete_security_context_token_fn(rampart_context, env))
        {
            rampart_context_set_delete_security_context_token_fn(
                rampart_context, env, sct_provider_delete_sct_default);
        }

        if(!rampart_context_get_validate_security_context_token_fn(rampart_context, env))
        {
            rampart_context_set_validate_security_context_token_fn(
                rampart_context, env, sct_provider_validate_sct_default);
        }
    }
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
rampart_engine_retrieve_key_mgr_prop_from_policy(rampart_context_t *rampart_context, 
												 const axutil_env_t *env)
{	
	axis2_char_t *value = NULL;
	rp_rampart_config_t *config = NULL;    
	oxs_key_mgr_t *key_mgr = NULL;
	rp_secpolicy_t *secpolicy = NULL;
	secpolicy = rampart_context_get_secpolicy(rampart_context, env);
    config = rp_secpolicy_get_rampart_config(secpolicy, env);
    if (!config)
        return AXIS2_FAILURE;    

	key_mgr = rampart_context_get_key_mgr(rampart_context, env);

	value = rp_rampart_config_get_certificate_file(config, env);
	if (value)
	{
		oxs_key_mgr_set_certificate_file(key_mgr, env, value);
	}

	value = rp_rampart_config_get_private_key_file(config, env);
	if (value)
	{
		oxs_key_mgr_set_private_key_file(key_mgr, env, value);
	}

	value = rp_rampart_config_get_receiver_certificate_file(config, env);
	if (value)
	{
		oxs_key_mgr_set_reciever_certificate_file(key_mgr, env, value);
	}
	return AXIS2_SUCCESS;
}
