Exemple #1
0
/**
 * Traverse thru the node and its descendents. Check if the node has a particular attibure value, 
 * whose attribute name as in @attr and value as in @val
 * @param env Environment. MUST NOT be NULL,
 * @param node the node to be searched
 * @param attr the attribute name of the node
 * @param val the attribute value of the node
 * @param ns namespace of the attribute
 * @return the node if found, else NULL
 */
AXIS2_EXTERN axiom_node_t* AXIS2_CALL
oxs_axiom_get_node_by_id(
    const axutil_env_t *env,
    axiom_node_t *node,
    axis2_char_t *attr,
    axis2_char_t *val,
    axis2_char_t *ns)
{
    axis2_char_t *attribute_value = NULL;

    if(!node)
    {
        return NULL;
    }

    if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
    {
        return NULL;
    }

    attribute_value = oxs_axiom_get_attribute_value_of_node_by_name(env, node, attr, ns);
    
    if(!axutil_strcmp(val, attribute_value))
    {
        /* Gottcha.. return this node */
        return node;
    }
    else
    {
        /* Doesn't match? Get the children and search recursively. */
        axiom_node_t *temp_node = NULL;
        temp_node = axiom_node_get_first_element(node, env);
        while (temp_node)
        {
            axiom_node_t *res_node = NULL;
            res_node = oxs_axiom_get_node_by_id(env, temp_node, attr, val, ns);
            if(res_node)
            {
                return res_node;
            }
            temp_node = axiom_node_get_next_sibling(temp_node, env);
        }
    }

    return NULL;
}
Exemple #2
0
axis2_status_t __euca_authenticate(const axutil_env_t *env,axis2_msg_ctx_t *out_msg_ctx, axis2_op_ctx_t *op_ctx)
{
  //***** First get the message context before doing anything dumb w/ a NULL pointer *****/
  axis2_msg_ctx_t *msg_ctx = NULL; //<--- incoming msg context, it is NULL, see?
  msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_IN);  

  //***** Print everything from the security results, just for testing now *****//
  rampart_context_t *rampart_context = NULL;
  axutil_property_t *property = NULL;

  property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT);
  if(property)
  {
     rampart_context = (rampart_context_t *)axutil_property_get_value(property, env);
     //     AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ======== PRINTING PROCESSED WSSEC TOKENS ======== ");
     rampart_print_security_processed_results_set(env,msg_ctx);
  }

  //***** Extract Security Node from header from enveloper from msg_ctx *****//
  axiom_soap_envelope_t *soap_envelope = NULL;
  axiom_soap_header_t *soap_header = NULL;
  axiom_node_t *sec_node = NULL;


  soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
  if(!soap_envelope) NO_U_FAIL("SOAP envelope cannot be found."); 
  soap_header = axiom_soap_envelope_get_header(soap_envelope, env);
  if (!soap_header) NO_U_FAIL("SOAP header cannot be found.");
  sec_node = rampart_get_security_header(env, msg_ctx, soap_header); // <---- here it is!
  if(!sec_node)NO_U_FAIL("No node wsse:Security -- required: ws-security");

  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** Path is: Security/
  //** *sec_node must be non-NULL, kkthx **//
  axiom_node_t *sig_node = NULL;
  axiom_node_t *key_info_node = NULL;
  axiom_node_t *sec_token_ref_node = NULL;
  /** the ds:Signature node **/
  sig_node = oxs_axiom_get_first_child_node_by_name(env,sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, OXS_DS );
  if(!sig_node)NO_U_FAIL("No node ds:Signature -- required: signature");
  /** the ds:KeyInfo **/
  key_info_node = oxs_axiom_get_first_child_node_by_name(env, sig_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, NULL );
  if(!key_info_node)NO_U_FAIL("No node ds:KeyInfo -- required: signature key");
  /** the wsse:SecurityTokenReference **/ 
  sec_token_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL);
  if(!sec_token_ref_node)NO_U_FAIL("No node wsse:SecurityTokenReference -- required: signing token");
  //** in theory this is the branching point for supporting all kinds of tokens -- we only do BST Direct Reference **/

  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** *sec_token_ref_node must be non-NULL **/
  axis2_char_t *ref = NULL;
  axis2_char_t *ref_id = NULL;
  axiom_node_t *token_ref_node = NULL;
  axiom_node_t *bst_node = NULL;
  /** the wsse:Reference node **/
  token_ref_node = oxs_axiom_get_first_child_node_by_name(env, sec_token_ref_node,OXS_NODE_REFERENCE, OXS_WSSE_XMLNS, NULL);
  /** pull out the name of the BST node **/
  ref = oxs_token_get_reference(env, token_ref_node);
  ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1);
  /** get the wsse:BinarySecurityToken used to sign the message **/
  bst_node = oxs_axiom_get_node_by_id(env, sec_node, "Id", ref_id, OXS_WSU_XMLNS);
  if(!bst_node){oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id);NO_U_FAIL("Cant find the required node");}


  //***** Find the wsse:Reference to the BinarySecurityToken *****//
  //** *bst_node must be non-NULL **/
  axis2_char_t *data = NULL;
  oxs_x509_cert_t *_cert = NULL;
  oxs_x509_cert_t *recv_cert = NULL;
  axis2_char_t *file_name = NULL;
  axis2_char_t *recv_x509_buf = NULL;
  axis2_char_t *msg_x509_buf = NULL;

  /** pull out the data from the BST **/
  data = oxs_axiom_get_node_content(env, bst_node);
  /** create an oxs_X509_cert **/
  _cert = oxs_key_mgr_load_x509_cert_from_string(env, data);
  if(_cert)
  {
    //***** FINALLY -- we have the certificate used to sign the message.  authenticate it HERE *****//
    msg_x509_buf = oxs_x509_cert_get_data(_cert,env);
    if(!msg_x509_buf)NO_U_FAIL("OMG WHAT NOW?!");
    /*
    recv_x509_buf = (axis2_char_t *)rampart_context_get_receiver_certificate(rampart_context, env);
    if(recv_x509_buf)
        recv_cert = oxs_key_mgr_load_x509_cert_from_string(env, recv_x509_buf);
    else
    {
        file_name = rampart_context_get_receiver_certificate_file(rampart_context, env);
        if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!");
	if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing");
        recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);
    }
    */

    file_name = rampart_context_get_receiver_certificate_file(rampart_context, env);
    if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!");
    if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing");
    recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);

    if (recv_cert) {
      recv_x509_buf = oxs_x509_cert_get_data(recv_cert,env);
    } else {
      NO_U_FAIL("could not populate receiver cert");
    }

    if( axutil_strcmp(recv_x509_buf,msg_x509_buf)!=0){
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Received x509 certificate value ---------" );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, msg_x509_buf );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Local x509 certificate value! ---------" );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, recv_x509_buf );
      AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ---------------------------------------------------" );
      NO_U_FAIL("The certificate specified is invalid!");
    }
  }
  else 
  {
    oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_DEFAULT, "Cannot load certificate from string =%s", data); 
    NO_U_FAIL("Failed to build certificate from BinarySecurityToken");
  }
  oxs_x509_cert_free(_cert, env);
  oxs_x509_cert_free(recv_cert, env);
  return AXIS2_SUCCESS;

}
/**
 * Verifes that Body, Timestamp, To, Action, and MessageId elements are signed and located
 * where expected by the application logic. Timestamp is checked for expiration regardless
 * of its actual location.
 */
axis2_status_t verify_references(axiom_node_t *sig_node, const axutil_env_t *env, axis2_msg_ctx_t *msg_ctx, axiom_soap_envelope_t *envelope) {
  axiom_node_t *si_node = NULL;
  axiom_node_t *ref_node = NULL;
  axis2_status_t status = AXIS2_SUCCESS;

  si_node = oxs_axiom_get_first_child_node_by_name(env,sig_node, OXS_NODE_SIGNEDINFO, OXS_DSIG_NS, OXS_DS);

  if(!si_node) {
    axis2_char_t *tmp = axiom_node_to_string(sig_node, env);
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart]sig = %s", tmp);
    NO_U_FAIL("Couldn't find SignedInfo!");
  }

  axutil_qname_t *qname = NULL;
  axiom_element_t *parent_elem = NULL; 
  axiom_children_qname_iterator_t *qname_iter = NULL; 

  parent_elem = axiom_node_get_data_element(si_node, env);  
  if(!parent_elem)                                                                                                                          
    {                                                                                                                                        
       NO_U_FAIL("Could not get Reference elem");                                                                                                                           
    }     

  axis2_char_t *ref = NULL;
  axis2_char_t *ref_id = NULL;
  axiom_node_t *signed_node = NULL;
  axiom_node_t *envelope_node = NULL;

  short signed_elems[5] = {0,0,0,0,0};

  envelope_node = axiom_soap_envelope_get_base_node(envelope, env);

  qname = axutil_qname_create(env, OXS_NODE_REFERENCE, OXS_DSIG_NS, NULL);                                                                            
  qname_iter = axiom_element_get_children_with_qname(parent_elem, env, qname, si_node); 
  while (axiom_children_qname_iterator_has_next(qname_iter , env)) {
      ref_node = axiom_children_qname_iterator_next(qname_iter, env);     
      axis2_char_t *txt = axiom_node_to_string(ref_node, env); 

      /* get reference to a signed element */
      ref = oxs_token_get_reference(env, ref_node);
      if(ref == NULL || strlen(ref) == 0 || ref[0] != '#') {
	oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unsupported reference ID in %s", txt);
	status = AXIS2_FAILURE;
	break;
      }

      AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] %s, ref = %s", txt, ref); 
  
      /* get rid of '#' */
      ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1);
      signed_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, ref_id, OXS_WSU_XMLNS);
      if(!signed_node) {
	  oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id);
	  status = AXIS2_FAILURE;
	  break;
      }
      if(verify_node(signed_node, env, msg_ctx, ref, signed_elems)) {
	status = AXIS2_FAILURE;
	break;
      }
    }         

  
  axutil_qname_free(qname, env);                                                                                                           
  qname = NULL;                   
  
  if(status == AXIS2_FAILURE) {
    NO_U_FAIL("Failed to verify location of signed elements!");
  }

  /* This is needed to make sure that all security-critical elements are signed */
  for(int i = 0; i < 5; i++) {
    if(signed_elems[i] == 0) {
      NO_U_FAIL("Not all required elements are signed");
    }
  }

  return status;

}
/**
 * extract certificate/key using reference id given in reference node
 */
static axis2_status_t
rampart_token_process_direct_ref(
    const axutil_env_t *env,
    axiom_node_t *ref_node,
    axiom_node_t *scope_node,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    oxs_x509_cert_t **cert,
    oxs_key_t **key,
    axis2_char_t **token_type)
{
    axis2_char_t *ref_id = NULL;
    axis2_bool_t external_reference = AXIS2_TRUE;

    /* Get the reference value in the @URI */
    ref_id = oxs_token_get_reference(env, ref_node);
    *token_type = oxs_token_get_reference_value_type(env, ref_node);

    if(!ref_id)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to get key name from reference node");
        return AXIS2_FAILURE;
    }

    if(ref_id[0] == '#')
    {
        /* Need to remove # sign from the ID */
        axis2_char_t *id = NULL;
        id = axutil_string_substring_starting_at(axutil_strdup(env, ref_id), 1);
        external_reference = AXIS2_FALSE;
        ref_id = id;
        if(!ref_id)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to get key name from reference node");
            return AXIS2_FAILURE;
        }
    }

    if(!external_reference)
    {
        /* this could point to binary security token, which means it is x509 token */
        axiom_node_t *bst_node = NULL;
        axis2_char_t *data = NULL;

        bst_node = oxs_axiom_get_node_by_id(env, scope_node, OXS_ATTR_ID, ref_id, OXS_WSU_XMLNS);
        if(bst_node)
        {
            axis2_char_t *local_name = NULL;
            local_name = axiom_util_get_localname(bst_node, env);
            if(!axutil_strcmp(local_name, OXS_NODE_BINARY_SECURITY_TOKEN))
            {
                /* This is an X509 token */
                *token_type = oxs_token_get_reference_value_type(env, bst_node);

                /* Process data. */
                data = oxs_axiom_get_node_content(env, bst_node);
                *cert = oxs_key_mgr_load_x509_cert_from_string(env, data);
                if(*cert)
                {
                    return AXIS2_SUCCESS;
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "Cannot load certificate from string =%s", data);
                    return AXIS2_FAILURE;
                }
            }
        }
    }

    *key = rampart_context_get_key(rampart_context, env, ref_id);
    if(!(*key) && external_reference)
    {
        if((0 == axutil_strcmp(*token_type, OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_02)) ||
            (0 == axutil_strcmp(*token_type, OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_12)))
        {
            rampart_shp_add_security_context_token(env, ref_id, ref_id, rampart_context, msg_ctx);
        }
        *key = rampart_context_get_key(rampart_context, env, ref_id);
    }

    if(!(*key))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find key referenced by URI %s", ref_id);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}