2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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>.
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
20 #include <encoding/payloads/sa_payload.h>
21 #include <config/proposal.h>
23 typedef struct private_custom_proposal_t private_custom_proposal_t
;
26 * Private data of an custom_proposal_t object.
28 struct private_custom_proposal_t
{
31 * Implements the hook_t interface.
36 * Alter requests or responses?
41 * ID of message to alter.
52 * Load custom proposal configuration to proposal list
54 static linked_list_t
* load_proposals(private_custom_proposal_t
*this,
55 protocol_id_t proto
, uint64_t spi
)
57 enumerator_t
*props
, *algs
;
58 char *number
, *key
, *value
;
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
))
66 const proposal_token_t
*token
= NULL
;
68 uint16_t type
, alg
, keysize
= 0;
71 proposal
= proposal_create(proto
, atoi(number
));
72 proposal
->set_spi(proposal
, spi
);
74 algs
= conftest
->test
->create_key_value_enumerator(conftest
->test
,
75 "hooks.%s.%s", this->name
, number
);
76 while (algs
->enumerate(algs
, &key
, &value
))
79 type
= strtoul(key
, &end
, 10);
80 if (end
== key
|| errno
)
82 if (!enum_from_name(transform_type_names
, key
, &type
))
84 DBG1(DBG_CFG
, "unknown transform: '%s', skipped", key
);
89 alg
= strtoul(value
, &end
, 10);
90 if (end
== value
|| errno
)
92 token
= lib
->proposal
->get_token(lib
->proposal
, value
);
95 DBG1(DBG_CFG
, "unknown algorithm: '%s', skipped", value
);
98 keysize
= token
->keysize
;
99 alg
= token
->algorithm
;
101 proposal
->add_algorithm(proposal
, type
, alg
, keysize
);
104 list
->insert_last(list
, proposal
);
106 props
->destroy(props
);
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
)
114 if (!incoming
&& plain
&&
115 message
->get_request(message
) == this->req
&&
116 message
->get_message_id(message
) == this->id
)
118 enumerator_t
*enumerator
;
120 sa_payload_t
*new, *old
= NULL
;
121 linked_list_t
*new_props
, *old_props
;
122 proposal_t
*proposal
;
124 enumerator
= message
->create_payload_enumerator(message
);
125 while (enumerator
->enumerate(enumerator
, &payload
))
127 if (payload
->get_type(payload
) == PLV2_SECURITY_ASSOCIATION
)
129 old
= (sa_payload_t
*)payload
;
130 message
->remove_payload_at(message
, enumerator
);
133 enumerator
->destroy(enumerator
);
137 old_props
= old
->get_proposals(old
);
139 enumerator
= old_props
->create_enumerator(old_props
);
140 if (enumerator
->enumerate(enumerator
, &proposal
))
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
));
150 enumerator
->destroy(enumerator
);
151 old_props
->destroy_offset(old_props
, offsetof(proposal_t
, destroy
));
157 METHOD(hook_t
, destroy
, void,
158 private_custom_proposal_t
*this)
165 * Create the IKE_AUTH fill hook
167 hook_t
*custom_proposal_hook_create(char *name
)
169 private_custom_proposal_t
*this;
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
),