Annotation of embedaddon/strongswan/src/conftest/hooks/custom_proposal.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "hook.h"
! 17:
! 18: #include <errno.h>
! 19:
! 20: #include <encoding/payloads/sa_payload.h>
! 21: #include <crypto/proposal/proposal.h>
! 22:
! 23: typedef struct private_custom_proposal_t private_custom_proposal_t;
! 24:
! 25: /**
! 26: * Private data of an custom_proposal_t object.
! 27: */
! 28: struct private_custom_proposal_t {
! 29:
! 30: /**
! 31: * Implements the hook_t interface.
! 32: */
! 33: hook_t hook;
! 34:
! 35: /**
! 36: * Alter requests or responses?
! 37: */
! 38: bool req;
! 39:
! 40: /**
! 41: * ID of message to alter.
! 42: */
! 43: int id;
! 44:
! 45: /**
! 46: * hook name
! 47: */
! 48: char *name;
! 49: };
! 50:
! 51: /**
! 52: * Load custom proposal configuration to proposal list
! 53: */
! 54: static linked_list_t* load_proposals(private_custom_proposal_t *this,
! 55: protocol_id_t proto, uint64_t spi)
! 56: {
! 57: enumerator_t *props, *algs;
! 58: char *number, *key, *value;
! 59: linked_list_t *list;
! 60:
! 61: list = linked_list_create();
! 62: props = conftest->test->create_section_enumerator(conftest->test,
! 63: "hooks.%s", this->name);
! 64: while (props->enumerate(props, &number))
! 65: {
! 66: const proposal_token_t *token = NULL;
! 67: proposal_t *proposal;
! 68: uint16_t type, alg, keysize = 0;
! 69: char *end;
! 70:
! 71: proposal = proposal_create(proto, atoi(number));
! 72: proposal->set_spi(proposal, spi);
! 73:
! 74: algs = conftest->test->create_key_value_enumerator(conftest->test,
! 75: "hooks.%s.%s", this->name, number);
! 76: while (algs->enumerate(algs, &key, &value))
! 77: {
! 78: errno = 0;
! 79: type = strtoul(key, &end, 10);
! 80: if (end == key || errno)
! 81: {
! 82: if (!enum_from_name(transform_type_names, key, &type))
! 83: {
! 84: DBG1(DBG_CFG, "unknown transform: '%s', skipped", key);
! 85: continue;
! 86: }
! 87: }
! 88: errno = 0;
! 89: alg = strtoul(value, &end, 10);
! 90: if (end == value || errno)
! 91: {
! 92: token = lib->proposal->get_token(lib->proposal, value);
! 93: if (!token)
! 94: {
! 95: DBG1(DBG_CFG, "unknown algorithm: '%s', skipped", value);
! 96: continue;
! 97: }
! 98: keysize = token->keysize;
! 99: alg = token->algorithm;
! 100: }
! 101: proposal->add_algorithm(proposal, type, alg, keysize);
! 102: }
! 103: algs->destroy(algs);
! 104: list->insert_last(list, proposal);
! 105: }
! 106: props->destroy(props);
! 107: return list;
! 108: }
! 109:
! 110: METHOD(listener_t, message, bool,
! 111: private_custom_proposal_t *this, ike_sa_t *ike_sa, message_t *message,
! 112: bool incoming, bool plain)
! 113: {
! 114: if (!incoming && plain &&
! 115: message->get_request(message) == this->req &&
! 116: message->get_message_id(message) == this->id)
! 117: {
! 118: enumerator_t *enumerator;
! 119: payload_t *payload;
! 120: sa_payload_t *new, *old = NULL;
! 121: linked_list_t *new_props, *old_props;
! 122: proposal_t *proposal;
! 123:
! 124: enumerator = message->create_payload_enumerator(message);
! 125: while (enumerator->enumerate(enumerator, &payload))
! 126: {
! 127: if (payload->get_type(payload) == PLV2_SECURITY_ASSOCIATION)
! 128: {
! 129: old = (sa_payload_t*)payload;
! 130: message->remove_payload_at(message, enumerator);
! 131: }
! 132: }
! 133: enumerator->destroy(enumerator);
! 134:
! 135: if (old)
! 136: {
! 137: old_props = old->get_proposals(old);
! 138: old->destroy(old);
! 139: enumerator = old_props->create_enumerator(old_props);
! 140: if (enumerator->enumerate(enumerator, &proposal))
! 141: {
! 142: new_props = load_proposals(this,
! 143: proposal->get_protocol(proposal),
! 144: proposal->get_spi(proposal));
! 145: DBG1(DBG_CFG, "injecting custom proposal: %#P", new_props);
! 146: new = sa_payload_create_from_proposals_v2(new_props);
! 147: message->add_payload(message, (payload_t*)new);
! 148: new_props->destroy_offset(new_props, offsetof(proposal_t, destroy));
! 149: }
! 150: enumerator->destroy(enumerator);
! 151: old_props->destroy_offset(old_props, offsetof(proposal_t, destroy));
! 152: }
! 153: }
! 154: return TRUE;
! 155: }
! 156:
! 157: METHOD(hook_t, destroy, void,
! 158: private_custom_proposal_t *this)
! 159: {
! 160: free(this->name);
! 161: free(this);
! 162: }
! 163:
! 164: /**
! 165: * Create the IKE_AUTH fill hook
! 166: */
! 167: hook_t *custom_proposal_hook_create(char *name)
! 168: {
! 169: private_custom_proposal_t *this;
! 170:
! 171: INIT(this,
! 172: .hook = {
! 173: .listener = {
! 174: .message = _message,
! 175: },
! 176: .destroy = _destroy,
! 177: },
! 178: .req = conftest->test->get_bool(conftest->test,
! 179: "hooks.%s.request", TRUE, name),
! 180: .id = conftest->test->get_int(conftest->test,
! 181: "hooks.%s.id", 0, name),
! 182: .name = strdup(name),
! 183: );
! 184:
! 185: return &this->hook;
! 186: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>