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
18 #include <encoding/payloads/sa_payload.h>
20 typedef struct private_set_proposal_number_t private_set_proposal_number_t
;
23 * Private data of an set_proposal_number_t object.
25 struct private_set_proposal_number_t
{
28 * Implements the hook_t interface.
33 * Alter requests or responses?
38 * ID of message to alter.
43 * Proposal number to modify
48 * Proposal number to set
54 * Copy all algs from given type from one proposal to another
56 static void copy_proposal_algs(proposal_t
*from
, proposal_t
*to
,
57 transform_type_t type
)
59 enumerator_t
*enumerator
;
60 u_int16_t alg
, key_size
;
62 enumerator
= from
->create_enumerator(from
, type
);
63 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
65 to
->add_algorithm(to
, type
, alg
, key_size
);
67 enumerator
->destroy(enumerator
);
70 METHOD(listener_t
, message
, bool,
71 private_set_proposal_number_t
*this, ike_sa_t
*ike_sa
, message_t
*message
,
75 message
->get_request(message
) == this->req
&&
76 message
->get_message_id(message
) == this->id
)
78 enumerator_t
*enumerator
;
80 linked_list_t
*list
= NULL
, *updated
;
82 proposal_t
*proposal
, *new;
84 updated
= linked_list_create();
85 enumerator
= message
->create_payload_enumerator(message
);
86 while (enumerator
->enumerate(enumerator
, &payload
))
88 if (payload
->get_type(payload
) == SECURITY_ASSOCIATION
)
90 sa
= (sa_payload_t
*)payload
;
91 list
= sa
->get_proposals(sa
);
92 message
->remove_payload_at(message
, enumerator
);
96 enumerator
->destroy(enumerator
);
100 enumerator
= list
->create_enumerator(list
);
101 while (enumerator
->enumerate(enumerator
, &proposal
))
103 if (proposal
->get_number(proposal
) == this->from
)
105 DBG1(DBG_CFG
, "setting proposal number from %d to %d",
106 this->from
, this->to
);
107 new = proposal_create(proposal
->get_protocol(proposal
),
109 copy_proposal_algs(proposal
, new, ENCRYPTION_ALGORITHM
);
110 copy_proposal_algs(proposal
, new, INTEGRITY_ALGORITHM
);
111 copy_proposal_algs(proposal
, new, PSEUDO_RANDOM_FUNCTION
);
112 copy_proposal_algs(proposal
, new, DIFFIE_HELLMAN_GROUP
);
113 copy_proposal_algs(proposal
, new, EXTENDED_SEQUENCE_NUMBERS
);
114 updated
->insert_last(updated
, new);
118 list
->remove_at(list
, enumerator
);
119 updated
->insert_last(updated
, proposal
);
122 enumerator
->destroy(enumerator
);
124 sa
= sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION
, updated
);
125 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
126 updated
->destroy_offset(updated
, offsetof(proposal_t
, destroy
));
127 message
->add_payload(message
, (payload_t
*)sa
);
132 METHOD(hook_t
, destroy
, void,
133 private_set_proposal_number_t
*this)
139 * Create the IKE_AUTH fill hook
141 hook_t
*set_proposal_number_hook_create(char *name
)
143 private_set_proposal_number_t
*this;
152 .req
= conftest
->test
->get_bool(conftest
->test
,
153 "hooks.%s.request", TRUE
, name
),
154 .id
= conftest
->test
->get_int(conftest
->test
,
155 "hooks.%s.id", 0, name
),
156 .from
= conftest
->test
->get_int(conftest
->test
,
157 "hooks.%s.from", 0, name
),
158 .to
= conftest
->test
->get_int(conftest
->test
,
159 "hooks.%s.to", 1, name
),