- state ike_sa_init_responded implemented (has some memleaks)
[strongswan.git] / Source / charon / sa / states / ike_auth_requested.c
1 /**
2 * @file ike_auth_requested.c
3 *
4 * @brief Implementation of ike_auth_requested_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "ike_auth_requested.h"
24
25 #include <daemon.h>
26 #include <utils/allocator.h>
27 #include <encoding/payloads/ts_payload.h>
28 #include <encoding/payloads/sa_payload.h>
29 #include <encoding/payloads/id_payload.h>
30 #include <encoding/payloads/auth_payload.h>
31 #include <transforms/signers/signer.h>
32 #include <transforms/crypters/crypter.h>
33 #include <sa/states/ike_sa_established.h>
34
35 typedef struct private_ike_auth_requested_t private_ike_auth_requested_t;
36
37 /**
38 * Private data of a ike_auth_requested_t object.
39 *
40 */
41 struct private_ike_auth_requested_t {
42 /**
43 * methods of the state_t interface
44 */
45 ike_auth_requested_t public;
46
47 /**
48 * Sent nonce value
49 */
50 chunk_t sent_nonce;
51
52 /**
53 * Received nonce
54 */
55 chunk_t received_nonce;
56
57 /**
58 * Assigned IKE_SA
59 */
60 protected_ike_sa_t *ike_sa;
61
62 /**
63 * SA config, just a copy of the one stored in the ike_sa
64 */
65 sa_config_t *sa_config;
66
67 /**
68 * Logger used to log data
69 *
70 * Is logger of ike_sa!
71 */
72 logger_t *logger;
73
74 status_t (*process_idr_payload) (private_ike_auth_requested_t *this, id_payload_t *idr_payload);
75 status_t (*process_sa_payload) (private_ike_auth_requested_t *this, sa_payload_t *sa_payload);
76 status_t (*process_auth_payload) (private_ike_auth_requested_t *this, auth_payload_t *auth_payload);
77 status_t (*process_ts_payload) (private_ike_auth_requested_t *this, bool ts_initiator, ts_payload_t *ts_payload);
78
79 };
80
81
82 /**
83 * Implements state_t.process_message
84 */
85 static status_t process_message(private_ike_auth_requested_t *this, message_t *request)
86 {
87 status_t status;
88 signer_t *signer;
89 crypter_t *crypter;
90 iterator_t *payloads;
91 exchange_type_t exchange_type;
92 id_payload_t *idr_payload;
93 auth_payload_t *auth_payload;
94 sa_payload_t *sa_payload;
95 ts_payload_t *tsi_payload, *tsr_payload;
96
97 return SUCCESS;
98
99 exchange_type = request->get_exchange_type(request);
100 if (exchange_type != IKE_AUTH)
101 {
102 this->logger->log(this->logger, ERROR | MORE, "Message of type %s not supported in state ike_auth_requested",
103 mapping_find(exchange_type_m,exchange_type));
104 return FAILED;
105 }
106
107 if (request->get_request(request))
108 {
109 this->logger->log(this->logger, ERROR | MORE, "Only responses of type IKE_AUTH supported in state ike_auth_requested");
110 return FAILED;
111 }
112
113 /* get signer for verification and crypter for decryption */
114 signer = this->ike_sa->get_signer_responder(this->ike_sa);
115 crypter = this->ike_sa->get_crypter_responder(this->ike_sa);
116
117 /* parse incoming message */
118 status = request->parse_body(request, crypter, signer);
119 if (status != SUCCESS)
120 {
121 this->logger->log(this->logger, ERROR | MORE, "Could not parse body of request message");
122 return status;
123 }
124
125 this->sa_config = this->ike_sa->get_sa_config(this->ike_sa);
126
127 /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */
128 payloads = request->get_payload_iterator(request);
129 while (payloads->has_next(payloads))
130 {
131 payload_t *payload;
132 payloads->current(payloads, (void**)&payload);
133
134 switch (payload->get_type(payload))
135 {
136 case AUTHENTICATION:
137 {
138 auth_payload = (auth_payload_t*)payload;
139 break;
140 }
141 case ID_RESPONDER:
142 {
143 idr_payload = (id_payload_t*)payload;
144 break;
145 }
146 case SECURITY_ASSOCIATION:
147 {
148 sa_payload = (sa_payload_t*)payload;
149 break;
150 }
151 case CERTIFICATE:
152 {
153 /* TODO handle cert payloads */
154 break;
155 }
156 case TRAFFIC_SELECTOR_INITIATOR:
157 {
158 tsi_payload = (ts_payload_t*)payload;
159 break;
160 }
161 case TRAFFIC_SELECTOR_RESPONDER:
162 {
163 tsr_payload = (ts_payload_t*)payload;
164 break;
165 }
166 default:
167 {
168 /* can't happen, since message is verified, notify's? */
169 break;
170 }
171 }
172 }
173 /* iterator can be destroyed */
174 payloads->destroy(payloads);
175
176
177 /* add payloads to it */
178 status = this->process_idr_payload(this, idr_payload);
179 if (status != SUCCESS)
180 {
181 this->logger->log(this->logger, ERROR, "Processing idr payload failed");
182 return status;
183 }
184 status = this->process_sa_payload(this, sa_payload);
185 if (status != SUCCESS)
186 {
187 this->logger->log(this->logger, ERROR, "Processing sa payload failed");
188 return status;
189 }
190 status = this->process_auth_payload(this, auth_payload);
191 if (status != SUCCESS)
192 {
193 this->logger->log(this->logger, ERROR, "Processing auth payload failed");
194 return status;
195 }
196 status = this->process_ts_payload(this, TRUE, tsi_payload);
197 if (status != SUCCESS)
198 {
199 this->logger->log(this->logger, ERROR, "Processing tsi payload failed");
200 return status;
201 }
202 status = this->process_ts_payload(this, FALSE, tsr_payload);
203 if (status != SUCCESS)
204 {
205 this->logger->log(this->logger, ERROR, "Processing tsr payload failed");
206 return status;
207 }
208
209 this->logger->log(this->logger, CONTROL | MORE, "IKE_AUTH response successfully handled. IKE_SA established.");
210
211 /* create new state */
212 this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
213
214 return SUCCESS;
215 }
216
217 /**
218 * Implements private_ike_auth_requested_t.build_idr_payload
219 */
220 static status_t process_idr_payload(private_ike_auth_requested_t *this, id_payload_t *idr_payload)
221 {
222 identification_t *other_id, *configured_other_id;
223
224 other_id = idr_payload->get_identification(idr_payload);
225
226 configured_other_id = this->sa_config->get_other_id(this->sa_config);
227 if (configured_other_id)
228 {
229 if (!other_id->equals(other_id, configured_other_id))
230 {
231 this->logger->log(this->logger, ERROR, "IKE_AUTH reply didn't contain requested id");
232 return FAILED;
233 }
234 }
235
236 /* TODO do we have to store other_id somewhere ? */
237 return SUCCESS;
238 }
239
240 /**
241 * Implements private_ike_auth_requested_t.build_sa_payload
242 */
243 static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payload_t *sa_payload)
244 {
245 child_proposal_t *proposals, *proposal_chosen;
246 size_t proposal_count;
247 status_t status;
248
249 /* dummy spis, until we have a child sa to request them */
250 u_int8_t ah_spi[4] = {0x01, 0x02, 0x03, 0x04};
251 u_int8_t esp_spi[4] = {0x05, 0x06, 0x07, 0x08};
252
253 /* check selected proposal */
254 status = sa_payload->get_child_proposals(sa_payload, &proposals, &proposal_count);
255 if (status != SUCCESS)
256 {
257 this->logger->log(this->logger, ERROR, "responders sa payload contained no proposals");
258 return FAILED;
259 }
260 if (proposal_count > 1)
261 {
262 allocator_free(proposals);
263 this->logger->log(this->logger, ERROR, "responders sa payload contained more than one proposal");
264 return FAILED;
265 }
266
267 proposal_chosen = this->sa_config->select_proposal(this->sa_config, ah_spi, esp_spi, proposals, proposal_count);
268 if (proposal_chosen == NULL)
269 {
270 this->logger->log(this->logger, ERROR, "responder selected an not offered proposal");
271 allocator_free(proposals);
272 return FAILED;
273 }
274 else
275 {
276 allocator_free(proposal_chosen);
277 }
278
279 allocator_free(proposals);
280
281 return SUCCESS;
282 }
283
284 /**
285 * Implements private_ike_auth_requested_t.build_auth_payload
286 */
287 static status_t process_auth_payload(private_ike_auth_requested_t *this, auth_payload_t *auth_payload)
288 {
289 /* TODO VERIFY auth here */
290 return SUCCESS;
291 }
292
293 /**
294 * Implements private_ike_auth_requested_t.build_ts_payload
295 */
296 static status_t process_ts_payload(private_ike_auth_requested_t *this, bool ts_initiator, ts_payload_t *ts_payload)
297 {
298 traffic_selector_t **ts_received, **ts_selected;
299 size_t ts_received_count, ts_selected_count;
300 status_t status = SUCCESS;
301
302 /* get ts form payload */
303 ts_received_count = ts_payload->get_traffic_selectors(ts_payload, &ts_received);
304 /* select ts depending on payload type */
305 if (ts_initiator)
306 {
307 ts_selected_count = this->sa_config->select_traffic_selectors_initiator(this->sa_config, ts_received, ts_received_count, &ts_selected);
308 }
309 else
310 {
311 ts_selected_count = this->sa_config->select_traffic_selectors_responder(this->sa_config, ts_received, ts_received_count, &ts_selected);
312 }
313 /* check if the responder selected valid proposals */
314 if (ts_selected_count != ts_received_count)
315 {
316 this->logger->log(this->logger, ERROR, "responder selected invalid traffic selectors");
317 status = FAILED;
318 }
319
320 /* cleanup */
321 while(ts_received_count--)
322 {
323 traffic_selector_t *ts = *ts_received + ts_received_count;
324 ts->destroy(ts);
325 }
326 allocator_free(ts_received);
327 while(ts_selected_count--)
328 {
329 traffic_selector_t *ts = *ts_selected + ts_selected_count;
330 ts->destroy(ts);
331 }
332 allocator_free(ts_selected);
333 return status;
334 }
335 /**
336 * Implements state_t.get_state
337 */
338 static ike_sa_state_t get_state(private_ike_auth_requested_t *this)
339 {
340 return IKE_AUTH_REQUESTED;
341 }
342
343 /**
344 * Implements state_t.get_state
345 */
346 static void destroy(private_ike_auth_requested_t *this)
347 {
348 allocator_free(this->sent_nonce.ptr);
349 allocator_free(this->received_nonce.ptr);
350 allocator_free(this);
351 }
352
353 /*
354 * Described in header.
355 */
356 ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa, chunk_t sent_nonce, chunk_t received_nonce)
357 {
358 private_ike_auth_requested_t *this = allocator_alloc_thing(private_ike_auth_requested_t);
359
360 /* interface functions */
361 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
362 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
363 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
364
365 /* private functions */
366
367 this->process_idr_payload = process_idr_payload;
368 this->process_sa_payload = process_sa_payload;
369 this->process_auth_payload = process_auth_payload;
370 this->process_ts_payload = process_ts_payload;
371
372 /* private data */
373 this->ike_sa = ike_sa;
374 this->sent_nonce = sent_nonce;
375 this->received_nonce = received_nonce;
376
377
378 return &(this->public);
379 }