| /* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * Licensed 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 <axis2_handler_desc.h> |
| #include <axis2_qname.h> |
| #include <axis2_svc.h> |
| #include <axiom_soap.h> |
| #include <rampart_util.h> |
| #include <axis2_endpoint_ref.h> |
| #include <axis2_property.h> |
| #include <rampart_constants.h> |
| #include <rampart_username_token.h> |
| #include <rampart_handler_util.h> |
| #include <rampart_timestamp_token.h> |
| #include <rampart_crypto_engine.h> |
| #include <rampart_action.h> |
| |
| /*********************** Function headers *********************************/ |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| rampart_out_handler_invoke(struct axis2_handler *handler, |
| const axis2_env_t * env, |
| struct axis2_msg_ctx *msg_ctx); |
| |
| |
| |
| /**********************end of header functions ****************************/ |
| |
| AXIS2_EXTERN axis2_handler_t *AXIS2_CALL |
| rampart_out_handler_create(const axis2_env_t *env, axis2_qname_t *qname) |
| { |
| axis2_handler_t *handler = NULL; |
| axis2_qname_t *handler_qname = NULL; |
| |
| AXIS2_ENV_CHECK(env, NULL); |
| |
| if (qname) |
| { |
| handler_qname = AXIS2_QNAME_CLONE(qname, env); |
| if (!(handler_qname)) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, |
| AXIS2_FAILURE); |
| return NULL; |
| } |
| } |
| else |
| { |
| /* create default qname */ |
| handler_qname = axis2_qname_create(env, "rampart_out_handler", |
| "http://axis.ws.apache.org", |
| NULL); |
| if (!handler_qname) |
| { |
| return NULL; |
| } |
| } |
| |
| handler = axis2_handler_create(env); |
| if (!handler) |
| { |
| return NULL; |
| } |
| |
| /* set the base struct's invoke op */ |
| if (handler->ops) |
| handler->ops->invoke = rampart_out_handler_invoke; |
| |
| AXIS2_QNAME_FREE(handler_qname, env); |
| |
| return handler; |
| } |
| |
| axis2_status_t AXIS2_CALL |
| rampart_out_handler_invoke(struct axis2_handler * handler, |
| const axis2_env_t * env, axis2_msg_ctx_t * msg_ctx) |
| { |
| axis2_msg_info_headers_t *msg_info_headers = NULL; |
| axis2_ctx_t *ctx = NULL; |
| axiom_soap_envelope_t *soap_envelope = NULL; |
| axiom_soap_header_t *soap_header = NULL; |
| axiom_node_t *soap_header_node = NULL; |
| axiom_element_t *soap_header_ele = NULL; |
| axis2_param_t *param_out_flow_security = NULL; |
| axis2_array_list_t *action_list = NULL; |
| axis2_param_t *param_action = NULL; |
| axis2_char_t *items = NULL; |
| axis2_status_t enc_status = AXIS2_FAILURE; |
| rampart_actions_t *actions = NULL; |
| axis2_status_t status = AXIS2_FAILURE; |
| |
| AXIS2_ENV_CHECK(env, AXIS2_FAILURE); |
| AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); |
| |
| msg_info_headers = AXIS2_MSG_CTX_GET_MSG_INFO_HEADERS(msg_ctx, env); |
| \ |
| |
| soap_envelope = AXIS2_MSG_CTX_GET_SOAP_ENVELOPE(msg_ctx, env); |
| if (!soap_envelope) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No SOAP envelope found. ERROR"); |
| return AXIS2_FAILURE; |
| } |
| |
| /*We are checking for the soap header element*/ |
| soap_header = AXIOM_SOAP_ENVELOPE_GET_HEADER(soap_envelope, env); |
| |
| if (!soap_header) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No SOAP header found. ERROR"); |
| /*No SOAP header, so no point of proceeding*/ |
| return AXIS2_SUCCESS; |
| } |
| |
| /*if the soap header is available then add the security header*/ |
| if (soap_header) |
| { |
| axiom_soap_header_block_t *sec_header_block = NULL; |
| axiom_namespace_t *sec_ns_obj = NULL; |
| soap_header_node = AXIOM_SOAP_HEADER_GET_BASE_NODE(soap_header, env); |
| soap_header_ele = (axiom_element_t *)AXIOM_NODE_GET_DATA_ELEMENT(soap_header_node, env); |
| |
| |
| ctx = AXIS2_MSG_CTX_GET_BASE(msg_ctx, env); |
| param_out_flow_security = rampart_get_security_param(env, msg_ctx, RAMPART_OUTFLOW_SECURITY); |
| |
| if (!param_out_flow_security) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No Outflow Security. So nothing to do"); |
| return AXIS2_SUCCESS; |
| } |
| |
| /*Get actions*/ |
| action_list = rampart_get_actions(env, ctx, param_out_flow_security); |
| |
| if (!action_list) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No actions defined in outflow security"); |
| return AXIS2_SUCCESS; |
| } |
| |
| if (AXIS2_ARRAY_LIST_IS_EMPTY(action_list, env)) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No actions defined in outflow security"); |
| return AXIS2_SUCCESS; |
| } |
| |
| /*Now we support only one action.*/ |
| param_action = (axis2_param_t*) AXIS2_ARRAY_LIST_GET(action_list, env, 0); |
| |
| if (!param_action) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Cannot find first action element ERROR"); |
| return AXIS2_FAILURE; |
| } |
| |
| /*Create and populate rampart actions*/ |
| actions = rampart_actions_create(env); |
| status = RAMPART_ACTIONS_POPULATE_FROM_PARAMS(actions, env, param_action); |
| |
| /*Then re-populate using the axis2_ctx*/ |
| status = RAMPART_ACTIONS_POPULATE_FROM_CTX(actions, env, ctx); |
| |
| items = AXIS2_STRDUP(RAMPART_ACTIONS_GET_ITEMS(actions, env), env); |
| |
| if (!items) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] No action items defined. ERROR"); |
| return AXIS2_FAILURE; |
| } |
| |
| sec_ns_obj = axiom_namespace_create(env, RAMPART_WSSE_XMLNS, |
| RAMPART_WSSE); |
| |
| sec_header_block = AXIOM_SOAP_HEADER_ADD_HEADER_BLOCK(soap_header, |
| env, RAMPART_SECURITY, sec_ns_obj); |
| |
| if (sec_header_block) |
| { |
| axis2_char_t* item = NULL; |
| axiom_node_t *sec_node = NULL; |
| axiom_element_t *sec_ele = NULL; |
| axis2_array_list_t *string_list = NULL; |
| int i = 0, size = 0; |
| |
| sec_node = AXIOM_SOAP_HEADER_BLOCK_GET_BASE_NODE(sec_header_block, env); |
| sec_ele = (axiom_element_t *) |
| AXIOM_NODE_GET_DATA_ELEMENT(sec_node, env); |
| |
| /*Get action items seperated by spaces*/ |
| string_list = axis2_tokenize(env, items, ' '); |
| if (string_list) |
| { |
| size = AXIS2_ARRAY_LIST_SIZE(string_list, env); |
| } |
| |
| /*Iterate thru items. Eg. Usernmaetoken, Timestamp, Encrypt, Signature*/ |
| for (i = 0; i < size; i++) |
| { |
| item = AXIS2_ARRAY_LIST_GET(string_list, env, i); |
| /*Username token*/ |
| if (0 == AXIS2_STRCMP(RAMPART_ACTION_ITEMS_USERNAMETOKEN , |
| AXIS2_STRTRIM(env, item, NULL))) |
| { |
| rampart_username_token_t *username_token = NULL; |
| username_token = rampart_username_token_create(env); |
| |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] building UsernmaeToken"); |
| status = RAMPART_USERNAME_TOKEN_BUILD(username_token, |
| env, |
| ctx, |
| actions, |
| sec_node, |
| sec_ns_obj); |
| if (status == AXIS2_FAILURE) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] UsernmaeToken build failed. ERROR"); |
| return AXIS2_FAILURE; |
| } |
| /*TODO free*/ |
| /*Timestamp token*/ |
| } |
| else if (0 == AXIS2_STRCMP(RAMPART_ACTION_ITEMS_TIMESTAMP, |
| AXIS2_STRTRIM(env, item, NULL))) |
| { |
| rampart_timestamp_token_t *timestamp_token = NULL; |
| axis2_char_t *ttl_str = NULL; |
| int ttl = -1; |
| |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] building Timestamp Token"); |
| ttl_str = RAMPART_ACTIONS_GET_TIME_TO_LIVE(actions, env); |
| ttl = atoi(RAMPART_ACTIONS_GET_TIME_TO_LIVE(actions, env)); |
| if (ttl <= 0) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Using default timeToLive value %s", |
| RAMPART_TIMESTAMP_TOKEN_DEFAULT_TIME_TO_LIVE); |
| ttl = RAMPART_TIMESTAMP_TOKEN_DEFAULT_TIME_TO_LIVE; |
| } |
| timestamp_token = rampart_timestamp_token_create(env); |
| status = RAMPART_TIMESTAMP_TOKEN_BUILD(timestamp_token, env, |
| ctx, sec_node, sec_ns_obj, ttl); |
| if (status == AXIS2_FAILURE) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Timestamp Token build failed. ERROR"); |
| return AXIS2_FAILURE; |
| } |
| /*Encrypt*/ |
| } |
| else if (0 == AXIS2_STRCMP(RAMPART_ACTION_ITEMS_ENCRYPT, |
| AXIS2_STRTRIM(env, item, NULL))) |
| { |
| rampart_crypto_engine_t *engine = NULL; |
| |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Encrypting message"); |
| engine = rampart_crypto_engine_create(env); |
| |
| enc_status = RAMPART_CRYPTO_ENGINE_ENCRYPT_MESSAGE(engine, env, msg_ctx, actions, soap_envelope, sec_node); |
| |
| RAMPART_CRYPTO_ENGINE_FREE(engine, env); |
| |
| if (enc_status != AXIS2_SUCCESS) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Encryption failed. ERROR"); |
| return AXIS2_FAILURE; |
| } |
| |
| enc_status = AXIS2_SUCCESS;/*TODO Remove*/ |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Encryption success"); |
| |
| /*Signature*/ |
| } |
| else if (0 == AXIS2_STRCMP(RAMPART_ACTION_ITEMS_SIGNATURE, |
| AXIS2_STRTRIM(env, item, NULL))) |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Signing message. We do not support yet"); |
| |
| /*Any other type of action*/ |
| } |
| else |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] We do not support %s item yet" , item); |
| } |
| }/*End of for*/ |
| |
| } |
| else |
| { |
| AXIS2_LOG_INFO(env->log, "[rampart][rampart_out_handler] Security header block is NULL"); |
| } |
| |
| } |
| return AXIS2_SUCCESS; |
| } |
| |
| |
| |