Annotation of embedaddon/strongswan/src/conftest/hooks/custom_proposal.c, revision 1.1.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>