]> git.ipfire.org Git - thirdparty/strongswan.git/blame - Source/charon/encoding/message.c
- code cleaned up
[thirdparty/strongswan.git] / Source / charon / encoding / message.c
CommitLineData
cb5c6cc7
JH
1/**
2 * @file message.c
79538669 3 *
27e43205 4 * @brief Implementation of message_t.
79538669 5 *
cb5c6cc7
JH
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
ca6dd4f6 23#include <stdlib.h>
ca6dd4f6 24
b85d20d1
MW
25#include "message.h"
26
021c2322 27#include <types.h>
0e96f7d8 28#include <daemon.h>
96f79ff1 29#include <sa/ike_sa_id.h>
4a962238
MW
30#include <encoding/generator.h>
31#include <encoding/parser.h>
021c2322
MW
32#include <utils/linked_list.h>
33#include <utils/allocator.h>
34#include <utils/logger_manager.h>
4a962238
MW
35#include <encoding/payloads/encodings.h>
36#include <encoding/payloads/payload.h>
81796a52 37#include <encoding/payloads/encryption_payload.h>
668f9fcb 38#include <encoding/payloads/unknown_payload.h>
110dc83a 39
f6ba78c3
JH
40/**
41 * Max number of notify payloads per IKEv2 Message
42 */
43#define MAX_NOTIFY_PAYLOADS 10
44
9da406cf 45
668f9fcb 46typedef struct payload_rule_t payload_rule_t;
95c61cb9 47
9da406cf 48/**
668f9fcb
MW
49 * A payload rule defines the rules for a payload
50 * in a specific message rule. It defines if and how
51 * many times a payload must/can occur in a message
52 * and if it must be encrypted.
9da406cf 53 */
668f9fcb 54struct payload_rule_t {
9da406cf 55 /**
27e43205 56 * Payload type.
9da406cf
JH
57 */
58 payload_type_t payload_type;
59
60 /**
27e43205 61 * Minimal occurence of this payload.
9da406cf
JH
62 */
63 size_t min_occurence;
64
65 /**
27e43205 66 * Max occurence of this payload.
9da406cf
JH
67 */
68 size_t max_occurence;
f890d8fe
JH
69
70 /**
668f9fcb 71 * TRUE if payload must be encrypted
f890d8fe
JH
72 */
73 bool encrypted;
ae3012a0
JH
74
75 /**
668f9fcb
MW
76 * If this payload occurs, the message rule is
77 * fullfilled in any case. This applies e.g. to
78 * notify_payloads.
ae3012a0 79 */
668f9fcb 80 bool sufficient;
9da406cf
JH
81};
82
95c61cb9
JH
83typedef struct message_rule_t message_rule_t;
84
9da406cf 85/**
668f9fcb
MW
86 * A message rule defines the kind of a message,
87 * if it has encrypted contents and a list
88 * of payload rules.
9da406cf
JH
89 *
90 */
95c61cb9 91struct message_rule_t {
9da406cf 92 /**
27e43205 93 * Type of message.
9da406cf
JH
94 */
95 exchange_type_t exchange_type;
96
97 /**
27e43205 98 * Is message a request or response.
9da406cf
JH
99 */
100 bool is_request;
d440fe6d
JH
101
102 /**
103 * Message contains encrypted content.
104 */
105 bool encrypted_content;
106
668f9fcb
MW
107 /**
108 * Number of payload rules which will follow
109 */
110 size_t payload_rule_count;
d440fe6d 111
9da406cf 112 /**
668f9fcb 113 * Pointer to first payload rule
9da406cf 114 */
668f9fcb 115 payload_rule_t *payload_rules;
9da406cf
JH
116};
117
e0d60939 118/**
27e43205 119 * Message rule for IKE_SA_INIT from initiator.
e0d60939 120 */
668f9fcb 121static payload_rule_t ike_sa_init_i_payload_rules[] = {
f6ba78c3 122 {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,FALSE},
ae3012a0
JH
123 {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
124 {KEY_EXCHANGE,1,1,FALSE,FALSE},
125 {NONCE,1,1,FALSE,FALSE},
9da406cf
JH
126};
127
e0d60939 128/**
27e43205 129 * Message rule for IKE_SA_INIT from responder.
e0d60939 130 */
668f9fcb 131static payload_rule_t ike_sa_init_r_payload_rules[] = {
f6ba78c3 132 {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,TRUE},
ae3012a0
JH
133 {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
134 {KEY_EXCHANGE,1,1,FALSE,FALSE},
135 {NONCE,1,1,FALSE,FALSE},
9da406cf
JH
136};
137
f890d8fe
JH
138/**
139 * Message rule for IKE_AUTH from initiator.
140 */
668f9fcb 141static payload_rule_t ike_auth_i_payload_rules[] = {
f6ba78c3 142 {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
ae3012a0
JH
143 {ID_INITIATOR,1,1,TRUE,FALSE},
144 {CERTIFICATE,0,1,TRUE,FALSE},
145 {CERTIFICATE_REQUEST,0,1,TRUE,FALSE},
146 {ID_RESPONDER,0,1,TRUE,FALSE},
147 {AUTHENTICATION,1,1,TRUE,FALSE},
148 {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
149 {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
150 {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
668f9fcb 151 {CONFIGURATION,0,1,TRUE,FALSE},
f890d8fe
JH
152};
153
154/**
155 * Message rule for IKE_AUTH from responder.
156 */
668f9fcb 157static payload_rule_t ike_auth_r_payload_rules[] = {
f6ba78c3 158 {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
ae3012a0 159 {CERTIFICATE,0,1,TRUE,FALSE},
01de2f3c 160 {ID_RESPONDER,1,1,TRUE,FALSE},
ae3012a0
JH
161 {AUTHENTICATION,1,1,TRUE,FALSE},
162 {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
163 {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
164 {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
668f9fcb 165 {CONFIGURATION,0,1,TRUE,FALSE},
f890d8fe 166};
e0d60939
MW
167
168/**
27e43205 169 * Message rules, defines allowed payloads.
e0d60939 170 */
93a9a115 171static message_rule_t message_rules[] = {
668f9fcb
MW
172 {IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules},
173 {IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules},
174 {IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules},
175 {IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules}
110dc83a
JH
176};
177
ca6dd4f6 178
5796aa16
MW
179typedef struct private_message_t private_message_t;
180
ca6dd4f6 181/**
27e43205 182 * Private data of an message_t object.
ca6dd4f6 183 */
5796aa16 184struct private_message_t {
ca6dd4f6
JH
185
186 /**
27e43205 187 * Public part of a message_t object.
ca6dd4f6
JH
188 */
189 message_t public;
79538669 190
9da406cf 191 /**
27e43205 192 * Minor version of message.
9da406cf
JH
193 */
194 u_int8_t major_version;
195
196 /**
27e43205 197 * Major version of message.
9da406cf
JH
198 */
199 u_int8_t minor_version;
200
201 /**
27e43205 202 * First Payload in message.
9da406cf
JH
203 */
204 payload_type_t first_payload;
205
110dc83a 206 /**
27e43205 207 * Assigned exchange type.
110dc83a 208 */
523526ec 209 exchange_type_t exchange_type;
3a8f9f44 210
110dc83a 211 /**
668f9fcb 212 * TRUE if message is a request, FALSE if a reply.
110dc83a
JH
213 */
214 bool is_request;
c64d7032 215
525250c6 216 /**
27e43205 217 * Message ID of this message.
525250c6
JH
218 */
219 u_int32_t message_id;
220
221 /**
27e43205 222 * ID of assigned IKE_SA.
525250c6
JH
223 */
224 ike_sa_id_t *ike_sa_id;
225
c64d7032 226 /**
668f9fcb 227 * Assigned UDP packet, stores incoming packet or last generated one.
c64d7032 228 */
523526ec 229 packet_t *packet;
c64d7032 230
523526ec 231 /**
27e43205 232 * Linked List where payload data are stored in.
523526ec 233 */
c64d7032 234 linked_list_t *payloads;
523526ec 235
91443667 236 /**
27e43205 237 * Assigned parser to parse Header and Body of this message.
91443667
JH
238 */
239 parser_t *parser;
240
668f9fcb
MW
241 /**
242 * The message rule for this message instance
243 */
244 message_rule_t *message_rule;
245
523526ec 246 /**
27e43205 247 * Assigned logger.
523526ec
MW
248 */
249 logger_t *logger;
250
93a9a115 251 /**
668f9fcb
MW
252 * Sets the private message_rule member to the rule which
253 * applies to this message. Must be called before get_payload_rule().
93a9a115 254 *
f6039334 255 * @param this calling object
27e43205 256 * @return
f6039334 257 * - SUCCESS
668f9fcb 258 * - NOT_FOUND if no message rule applies to this message.
93a9a115 259 */
668f9fcb 260 status_t (*set_message_rule) (private_message_t *this);
f6039334
JH
261
262 /**
668f9fcb 263 * Gets the payload_rule_t for a specific message_rule_t and payload type.
f6039334
JH
264 *
265 * @param this calling object
f6039334 266 * @param payload_type payload type
668f9fcb 267 * @param[out] payload_rule returned payload_rule_t
f6039334
JH
268 * @return
269 * - SUCCESS
668f9fcb
MW
270 * - NOT_FOUND if payload not defined in current message rule
271 * - INVALID_STATE if message rule is not set via set_message_rule()
f6039334 272 */
668f9fcb 273 status_t (*get_payload_rule) (private_message_t *this, payload_type_t payload_type, payload_rule_t **payload_rule);
93a9a115 274
f890d8fe
JH
275 /**
276 * Encrypts all payloads which has to get encrypted.
277 *
f6039334
JH
278 * Can also be called with messages not containing encrypted content.
279 *
280 * @param this calling object
d440fe6d
JH
281 * @param crypter crypter_t object
282 * @param signer signer_t object
668f9fcb
MW
283 * @return
284 * - SUCCESS
285 * - INVALID_STATE if no crypter/signer supplied but needed
f890d8fe
JH
286 */
287 status_t (*encrypt_payloads) (private_message_t *this,crypter_t *crypter, signer_t* signer);
288
d440fe6d 289 /**
668f9fcb 290 * Decrypts encrypted contents, and checks if a payload is encrypted if it has to be.
d440fe6d
JH
291 *
292 * @param this calling object
293 * @param crypter crypter_t object
294 * @param signer signer_t object
668f9fcb
MW
295 * @return
296 * - SUCCESS
297 * - FAILED if decryption not successfull
298 * - INVALID_STATE if no crypter/signer supplied but needed
299 */
300 status_t (*decrypt_payloads) (private_message_t *this,crypter_t *crypter, signer_t* signer);
301
302 /**
303 * Verifies the message. Checks for payloads count.
304 *
305 * @param calling object
306 * @return
307 * - SUCCESS if message valid, or
308 * - FAILED if message does not align with message rules.
d440fe6d 309 */
668f9fcb 310 status_t (*verify) (private_message_t *this);
ca6dd4f6
JH
311};
312
93a9a115 313/**
668f9fcb 314 * Implementation of private_message_t.set_message_rule.
93a9a115 315 */
668f9fcb 316static status_t set_message_rule(private_message_t *this)
93a9a115
JH
317{
318 int i;
d440fe6d 319
93a9a115
JH
320 for (i = 0; i < (sizeof(message_rules) / sizeof(message_rule_t)); i++)
321 {
d440fe6d
JH
322 if ((this->exchange_type == message_rules[i].exchange_type) &&
323 (this->is_request == message_rules[i].is_request))
93a9a115
JH
324 {
325 /* found rule for given exchange_type*/
668f9fcb 326 this->message_rule = &(message_rules[i]);
93a9a115
JH
327 return SUCCESS;
328 }
93a9a115 329 }
668f9fcb 330 this->message_rule = NULL;
d440fe6d
JH
331 return NOT_FOUND;
332}
333
f6039334 334/**
668f9fcb 335 * Implementation of private_message_t.get_payload_rule.
f6039334 336 */
668f9fcb 337static status_t get_payload_rule(private_message_t *this, payload_type_t payload_type, payload_rule_t **payload_rule)
d440fe6d
JH
338{
339 int i;
340
668f9fcb 341 for (i = 0; i < this->message_rule->payload_rule_count;i++)
d440fe6d 342 {
668f9fcb 343 if (this->message_rule->payload_rules[i].payload_type == payload_type)
d440fe6d 344 {
668f9fcb 345 *payload_rule = &(this->message_rule->payload_rules[i]);
d440fe6d
JH
346 return SUCCESS;
347 }
348 }
349
668f9fcb 350 *payload_rule = NULL;
93a9a115
JH
351 return NOT_FOUND;
352}
525250c6
JH
353
354/**
27e43205 355 * Implementation of message_t.set_ike_sa_id.
525250c6 356 */
27e43205 357static void set_ike_sa_id (private_message_t *this,ike_sa_id_t *ike_sa_id)
525250c6 358{
d048df5c 359 this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
525250c6
JH
360}
361
362/**
27e43205 363 * Implementation of message_t.get_ike_sa_id.
525250c6
JH
364 */
365static status_t get_ike_sa_id (private_message_t *this,ike_sa_id_t **ike_sa_id)
366{
525250c6
JH
367 if (this->ike_sa_id == NULL)
368 {
369 return FAILED;
370 }
d048df5c 371 *ike_sa_id = this->ike_sa_id->clone(this->ike_sa_id);
27e43205 372 return SUCCESS;
525250c6
JH
373}
374
525250c6 375/**
27e43205 376 * Implementation of message_t.set_message_id.
525250c6 377 */
27e43205 378static void set_message_id (private_message_t *this,u_int32_t message_id)
525250c6
JH
379{
380 this->message_id = message_id;
525250c6
JH
381}
382
525250c6 383/**
27e43205 384 * Implementation of message_t.get_message_id.
525250c6
JH
385 */
386static u_int32_t get_message_id (private_message_t *this)
387{
388 return this->message_id;
389}
390
21981473 391/**
27e43205 392 * Implementation of message_t.get_responder_spi.
21981473
JH
393 */
394static u_int64_t get_responder_spi (private_message_t *this)
395{
396 return (this->ike_sa_id->get_responder_spi(this->ike_sa_id));
397}
398
9da406cf 399/**
27e43205 400 * Implementation of message_t.set_major_version.
9da406cf 401 */
27e43205 402static void set_major_version (private_message_t *this,u_int8_t major_version)
9da406cf
JH
403{
404 this->major_version = major_version;
9da406cf
JH
405}
406
407
408/**
27e43205 409 * Implementation of message_t.set_major_version.
9da406cf
JH
410 */
411static u_int8_t get_major_version (private_message_t *this)
412{
413 return this->major_version;
414}
415
416/**
27e43205 417 * Implementation of message_t.set_minor_version.
9da406cf 418 */
27e43205 419static void set_minor_version (private_message_t *this,u_int8_t minor_version)
9da406cf
JH
420{
421 this->minor_version = minor_version;
9da406cf
JH
422}
423
9da406cf 424/**
27e43205 425 * Implementation of message_t.get_minor_version.
9da406cf
JH
426 */
427static u_int8_t get_minor_version (private_message_t *this)
428{
429 return this->minor_version;
430}
525250c6 431
110dc83a 432/**
27e43205 433 * Implementation of message_t.set_exchange_type.
110dc83a 434 */
27e43205 435static void set_exchange_type (private_message_t *this,exchange_type_t exchange_type)
110dc83a
JH
436{
437 this->exchange_type = exchange_type;
110dc83a
JH
438}
439
110dc83a 440/**
27e43205 441 * Implementation of message_t.get_exchange_type.
110dc83a
JH
442 */
443static exchange_type_t get_exchange_type (private_message_t *this)
444{
445 return this->exchange_type;
446}
447
110dc83a 448/**
27e43205 449 * Implementation of message_t.set_request.
110dc83a 450 */
27e43205 451static void set_request (private_message_t *this,bool request)
110dc83a
JH
452{
453 this->is_request = request;
110dc83a
JH
454}
455
456/**
27e43205 457 * Implementation of message_t.get_request.
110dc83a
JH
458 */
459static exchange_type_t get_request (private_message_t *this)
460{
461 return this->is_request;
462}
463
27e43205
JH
464/**
465 * Implementation of message_t.add_payload.
466 */
467static void add_payload(private_message_t *this, payload_t *payload)
523526ec 468{
7b3d1389 469 payload_t *last_payload;
27e43205 470 if (this->payloads->get_count(this->payloads) > 0)
7b3d1389 471 {
27e43205 472 this->payloads->get_last(this->payloads,(void **) &last_payload);
ee29afd4 473 last_payload->set_next_type(last_payload, payload->get_type(payload));
7b3d1389
MW
474 }
475 else
476 {
ee29afd4 477 this->first_payload = payload->get_type(payload);
7b3d1389 478 }
ee29afd4
MW
479 payload->set_next_type(payload, NO_PAYLOAD);
480 this->payloads->insert_last(this->payloads, (void*)payload);
481
f6039334
JH
482 this->logger->log(this->logger, CONTROL|MORE, "Added payload of type %s to message",
483 mapping_find(payload_type_m, payload->get_type(payload)));
523526ec
MW
484}
485
27e43205
JH
486/**
487 * Implementation of message_t.set_source.
488 */
489static void set_source(private_message_t *this, host_t *host)
523526ec
MW
490{
491 if (this->packet->source != NULL)
492 {
493 this->packet->source->destroy(this->packet->source);
494 }
495 this->packet->source = host;
523526ec
MW
496}
497
27e43205
JH
498/**
499 * Implementation of message_t.set_destination.
500 */
501static void set_destination(private_message_t *this, host_t *host)
523526ec
MW
502{
503 if (this->packet->destination != NULL)
504 {
505 this->packet->destination->destroy(this->packet->destination);
506 }
507 this->packet->destination = host;
523526ec
MW
508}
509
27e43205
JH
510/**
511 * Implementation of message_t.get_source.
512 */
f6039334 513static host_t* get_source(private_message_t *this)
523526ec 514{
f6039334 515 return this->packet->source;
523526ec
MW
516}
517
27e43205
JH
518/**
519 * Implementation of message_t.get_destination.
520 */
f6039334 521static host_t * get_destination(private_message_t *this)
523526ec 522{
f6039334 523 return this->packet->destination;
523526ec
MW
524}
525
27e43205
JH
526/**
527 * Implementation of message_t.get_destination.
528 */
a0753941 529static iterator_t *get_payload_iterator(private_message_t *this)
501a41b9 530{
a0753941 531 return this->payloads->create_iterator(this->payloads, TRUE);
501a41b9
MW
532}
533
534
110dc83a 535/**
27e43205 536 * Implementation of message_t.generate.
110dc83a 537 */
81796a52 538static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* signer, packet_t **packet)
110dc83a 539{
523526ec
MW
540 generator_t *generator;
541 ike_header_t *ike_header;
542 payload_t *payload, *next_payload;
bdb141cb 543 iterator_t *iterator;
523526ec
MW
544 status_t status;
545
f6039334
JH
546 this->logger->log(this->logger, CONTROL, "Generating message of type %s, contains %d payloads",
547 mapping_find(exchange_type_m,this->exchange_type),
548 this->payloads->get_count(this->payloads));
e0d60939 549
523526ec
MW
550 if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
551 {
668f9fcb
MW
552 this->logger->log(this->logger, ERROR | MORE, "Exchange type %s is not defined",
553 mapping_find(exchange_type_m,this->exchange_type));
523526ec
MW
554 return INVALID_STATE;
555 }
556
557 if (this->packet->source == NULL ||
558 this->packet->destination == NULL)
559 {
668f9fcb
MW
560 this->logger->log(this->logger, ERROR|MORE, "%s not defined",
561 !this->packet->source ? "source" : "destination");
523526ec
MW
562 return INVALID_STATE;
563 }
564
668f9fcb
MW
565 /* set the rules for this messge */
566 status = this->set_message_rule(this);
567 if (status != SUCCESS)
568 {
569 this->logger->log(this->logger, ERROR, "No message rules specified for a %s %s",
570 mapping_find(exchange_type_m,this->exchange_type),
571 this->is_request ? "request" : "response");
572 return NOT_SUPPORTED;
573 }
574
575
f6039334 576 /* going to encrypt all content which have to be encrypted */
668f9fcb 577 status = this->encrypt_payloads(this, crypter, signer);
f890d8fe
JH
578 if (status != SUCCESS)
579 {
f6039334 580 this->logger->log(this->logger, ERROR | MORE, "Could not encrypt payloads");
f890d8fe
JH
581 return status;
582 }
583
81796a52 584 /* build ike header */
523526ec 585 ike_header = ike_header_create();
27e43205 586
523526ec 587 ike_header->set_exchange_type(ike_header, this->exchange_type);
523526ec
MW
588 ike_header->set_message_id(ike_header, this->message_id);
589 ike_header->set_response_flag(ike_header, !this->is_request);
7b3d1389
MW
590 ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id));
591 ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
592 ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id));
f890d8fe 593
523526ec
MW
594 generator = generator_create();
595
596 payload = (payload_t*)ike_header;
597
27e43205 598
668f9fcb
MW
599 /* generate every payload expect last one, this is doen later*/
600 iterator = this->payloads->create_iterator(this->payloads, TRUE);
523526ec 601 while(iterator->has_next(iterator))
110dc83a 602 {
523526ec
MW
603 iterator->current(iterator, (void**)&next_payload);
604 payload->set_next_type(payload, next_payload->get_type(next_payload));
0f30f568 605 generator->generate_payload(generator, payload);
523526ec 606 payload = next_payload;
110dc83a 607 }
523526ec
MW
608 iterator->destroy(iterator);
609
f6039334 610 /* last payload has no next payload*/
523526ec 611 payload->set_next_type(payload, NO_PAYLOAD);
f890d8fe 612
0f30f568 613 generator->generate_payload(generator, payload);
f6039334 614
523526ec 615 ike_header->destroy(ike_header);
81796a52
MW
616
617 /* build packet */
523526ec
MW
618 if (this->packet->data.ptr != NULL)
619 {
f6039334 620 this->logger->log(this->logger, CONTROL | MOST, "Replace last generated packet data");
523526ec
MW
621 allocator_free(this->packet->data.ptr);
622 }
0f30f568 623 generator->write_to_chunk(generator, &(this->packet->data));
81796a52 624 generator->destroy(generator);
523526ec 625
f6039334 626 /* if last payload is of type encrypted, integrity checksum if necessary */
81796a52
MW
627 if (payload->get_type(payload) == ENCRYPTED)
628 {
f6039334 629 this->logger->log(this->logger, CONTROL | MORE, "Build signature on whole message");
81796a52
MW
630 encryption_payload_t *encryption_payload = (encryption_payload_t*)payload;
631 status = encryption_payload->build_signature(encryption_payload, this->packet->data);
632 if (status != SUCCESS)
633 {
634 return status;
635 }
636 }
e0d60939 637
df3c59d0
MW
638 /* clone packet for caller */
639 *packet = this->packet->clone(this->packet);
e0d60939 640
668f9fcb
MW
641 this->logger->log(this->logger, CONTROL, "Message of type %s generated successfully",
642 mapping_find(exchange_type_m,this->exchange_type));
110dc83a
JH
643 return SUCCESS;
644}
645
5534ee84
JH
646/**
647 * Implementation of message_t.get_packet.
648 */
649static packet_t *get_packet (private_message_t *this)
650{
651 return this->packet->clone(this->packet);
652}
653
8d68033e
JH
654/**
655 * Implementation of message_t.get_packet_data.
656 */
657static chunk_t get_packet_data (private_message_t *this)
658{
659 return allocator_clone_chunk(this->packet->data);
660}
661
91443667 662/**
f6039334 663 * Implementation of message_t.parse_header.
91443667 664 */
e0d60939 665static status_t parse_header(private_message_t *this)
91443667
JH
666{
667 ike_header_t *ike_header;
668 status_t status;
669
e0d60939 670
25c41f4d 671 this->logger->log(this->logger, CONTROL|MORE, "parsing Header of message");
e0d60939 672
91443667
JH
673 this->parser->reset_context(this->parser);
674 status = this->parser->parse_payload(this->parser,HEADER,(payload_t **) &ike_header);
675 if (status != SUCCESS)
676 {
f6039334 677 this->logger->log(this->logger, ERROR | MORE, "Header could not be parsed");
91443667
JH
678 return status;
679
680 }
2dbc3168
JH
681
682 /* verify payload */
683 status = ike_header->payload_interface.verify(&(ike_header->payload_interface));
684 if (status != SUCCESS)
685 {
f6039334 686 this->logger->log(this->logger, ERROR | MORE, "Header verification failed");
b6b83651 687 ike_header->destroy(ike_header);
2dbc3168
JH
688 return status;
689 }
690
28c734d7
JH
691 if (this->ike_sa_id != NULL)
692 {
693 this->ike_sa_id->destroy(this->ike_sa_id);
694 }
28c734d7 695
3a8f9f44
MW
696 this->ike_sa_id = ike_sa_id_create(ike_header->get_initiator_spi(ike_header),
697 ike_header->get_responder_spi(ike_header),
e0d60939 698 ike_header->get_initiator_flag(ike_header));
27e43205 699
28c734d7
JH
700 this->exchange_type = ike_header->get_exchange_type(ike_header);
701 this->message_id = ike_header->get_message_id(ike_header);
93a9a115 702 this->is_request = (!(ike_header->get_response_flag(ike_header)));
9da406cf
JH
703 this->major_version = ike_header->get_maj_version(ike_header);
704 this->minor_version = ike_header->get_min_version(ike_header);
705 this->first_payload = ike_header->payload_interface.get_next_type(&(ike_header->payload_interface));
706
668f9fcb
MW
707 this->logger->log(this->logger, CONTROL, "Parsed a %s %s",
708 mapping_find(exchange_type_m, this->exchange_type),
25c41f4d 709 this->is_request ? "request" : "response");
e0d60939 710
668f9fcb
MW
711 ike_header->destroy(ike_header);
712
713 /* get the rules for this messge */
714 status = this->set_message_rule(this);
715 if (status != SUCCESS)
716 {
717 this->logger->log(this->logger, ERROR, "No message rules specified for a %s %s",
718 mapping_find(exchange_type_m,this->exchange_type),
719 this->is_request ? "request" : "response");
720 }
721
722 return status;
9da406cf
JH
723}
724
725/**
f6039334 726 * Implementation of message_t.parse_body.
9da406cf 727 */
81796a52 728static status_t parse_body(private_message_t *this, crypter_t *crypter, signer_t *signer)
9da406cf 729{
daa1c00e 730 status_t status = SUCCESS;
668f9fcb
MW
731 payload_type_t current_payload_type;
732
733 current_payload_type = this->first_payload;
e0d60939 734
25c41f4d 735 this->logger->log(this->logger, CONTROL|MORE, "Parsing body of message, first payload %s",
f6039334 736 mapping_find(payload_type_m, current_payload_type));
d440fe6d 737
668f9fcb 738 /* parse payload for payload, while there are more available */
d440fe6d 739 while ((current_payload_type != NO_PAYLOAD))
28c734d7 740 {
9da406cf 741 payload_t *current_payload;
be230691 742
25c41f4d 743 this->logger->log(this->logger, CONTROL|MOST, "Start parsing payload of type %s",
e0d60939 744 mapping_find(payload_type_m, current_payload_type));
9da406cf 745
668f9fcb 746 /* parse current payload */
9da406cf 747 status = this->parser->parse_payload(this->parser,current_payload_type,(payload_t **) &current_payload);
93a9a115
JH
748 if (status != SUCCESS)
749 {
f6039334 750 this->logger->log(this->logger, ERROR, "Payload type %s could not be parsed",mapping_find(payload_type_m,current_payload_type));
81796a52 751 return status;
93a9a115 752 }
f6039334
JH
753
754 this->logger->log(this->logger, CONTROL|MOST, "Verify payload of type %s",
755 mapping_find(payload_type_m, current_payload_type));
9da406cf 756
668f9fcb 757 /* verify it, stop parsig if its invalid */
2dbc3168 758 status = current_payload->verify(current_payload);
93a9a115
JH
759 if (status != SUCCESS)
760 {
f6039334 761 this->logger->log(this->logger, ERROR, "Payload type %s could not be verified",mapping_find(payload_type_m,current_payload_type));
346af6f3 762 current_payload->destroy(current_payload);
2dbc3168 763 status = VERIFY_ERROR;
81796a52
MW
764 return status;
765 }
766
f6039334
JH
767 this->logger->log(this->logger, CONTROL|MOST, "Payload verified. Adding to payload list",
768 mapping_find(payload_type_m, current_payload_type));
d048df5c 769 this->payloads->insert_last(this->payloads,current_payload);
bc788302 770
668f9fcb 771 /* an encryption payload is the last one, so STOP here. decryption is done later */
bc788302
MW
772 if (current_payload_type == ENCRYPTED)
773 {
f6039334
JH
774 this->logger->log(this->logger, CONTROL|MOST, "Payload of type encrypted found. Stop parsing.",
775 mapping_find(payload_type_m, current_payload_type));
bc788302
MW
776 break;
777 }
778
779 /* get next payload type */
780 current_payload_type = current_payload->get_next_type(current_payload);
28c734d7 781 }
25c41f4d
MW
782
783 this->logger->log(this->logger, CONTROL, "Message a %s %s contains %d payloads",
784 mapping_find(exchange_type_m, this->exchange_type),
785 this->is_request ? "request" : "response",
786 this->payloads->get_count(this->payloads));
f6039334 787
668f9fcb
MW
788 /* */
789 if (current_payload_type == ENCRYPTED)
790 status = this->decrypt_payloads(this,crypter,signer);
d440fe6d
JH
791 if (status != SUCCESS)
792 {
668f9fcb 793 this->logger->log(this->logger, ERROR, "Could not decrypt payloads");
d440fe6d
JH
794 return status;
795 }
796
668f9fcb
MW
797 status = this->verify(this);
798 if (status != SUCCESS)
799 {
800 this->logger->log(this->logger, ERROR, "Verification of message failed");
801 }
802 return status;
81796a52
MW
803}
804
805/**
668f9fcb 806 * Implementation of private_message_t.verify.
81796a52
MW
807 */
808static status_t verify(private_message_t *this)
809{
81796a52 810 int i;
d440fe6d 811 iterator_t *iterator;
ae3012a0 812 size_t total_found_payloads = 0;
81796a52 813
f6039334 814 this->logger->log(this->logger, CONTROL|MORE, "Verifying message structure");
ae3012a0 815
a0753941 816 iterator = this->payloads->create_iterator(this->payloads,TRUE);
81796a52 817 /* check for payloads with wrong count*/
668f9fcb 818 for (i = 0; i < this->message_rule->payload_rule_count;i++)
81796a52 819 {
81796a52 820 size_t found_payloads = 0;
93a9a115 821
f6039334 822 /* check all payloads for specific rule */
81796a52 823 iterator->reset(iterator);
668f9fcb 824
81796a52
MW
825 while(iterator->has_next(iterator))
826 {
827 payload_t *current_payload;
668f9fcb
MW
828 payload_type_t current_payload_type;
829
27e43205 830 iterator->current(iterator,(void **)&current_payload);
668f9fcb 831 current_payload_type = current_payload->get_type(current_payload);
a0753941 832
668f9fcb
MW
833 if (current_payload_type == UNKNOWN_PAYLOAD)
834 {
835 /* unknown payloads are ignored, IF they are not critical */
836 unknown_payload_t *unknown_payload = (unknown_payload_t*)current_payload;
837 if (unknown_payload->is_critical(unknown_payload))
838 {
839 this->logger->log(this->logger, ERROR, "%s (%d) is not supported, but its critical!",
840 mapping_find(payload_type_m, current_payload_type), current_payload_type);
841 iterator->destroy(iterator);
842 return NOT_SUPPORTED;
843 }
844 }
845 else if (current_payload_type == this->message_rule->payload_rules[i].payload_type)
93a9a115 846 {
81796a52 847 found_payloads++;
ae3012a0 848 total_found_payloads++;
bc788302 849 this->logger->log(this->logger, CONTROL | MOST, "Found payload of type %s",
668f9fcb
MW
850 mapping_find(payload_type_m, this->message_rule->payload_rules[i].payload_type));
851
f6039334 852 /* as soon as ohe payload occures more then specified, the verification fails */
668f9fcb 853 if (found_payloads > this->message_rule->payload_rules[i].max_occurence)
81796a52
MW
854 {
855 this->logger->log(this->logger, ERROR, "Payload of type %s more than %d times (%d) occured in current message",
668f9fcb
MW
856 mapping_find(payload_type_m, current_payload_type),
857 this->message_rule->payload_rules[i].max_occurence, found_payloads);
93a9a115 858 iterator->destroy(iterator);
668f9fcb 859 return FAILED;
81796a52 860 }
93a9a115 861 }
93a9a115 862 }
668f9fcb
MW
863
864 if (found_payloads < this->message_rule->payload_rules[i].min_occurence)
81796a52 865 {
f6039334 866 this->logger->log(this->logger, ERROR, "Payload of type %s not occured %d times (%d)",
668f9fcb
MW
867 mapping_find(payload_type_m, this->message_rule->payload_rules[i].payload_type),
868 this->message_rule->payload_rules[i].min_occurence, found_payloads);
81796a52 869 iterator->destroy(iterator);
668f9fcb 870 return FAILED;
81796a52 871 }
668f9fcb 872 if ((this->message_rule->payload_rules[i].sufficient) && (this->payloads->get_count(this->payloads) == total_found_payloads))
ae3012a0
JH
873 {
874 iterator->destroy(iterator);
875 return SUCCESS;
876 }
93a9a115 877 }
81796a52 878 iterator->destroy(iterator);
81796a52 879 return SUCCESS;
91443667
JH
880}
881
882
f6039334
JH
883/**
884 * Implementation of private_message_t.decrypt_and_verify_payloads.
885 */
668f9fcb 886static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, signer_t* signer)
d440fe6d
JH
887{
888 bool current_payload_was_encrypted = FALSE;
668f9fcb 889 payload_t *previous_payload = NULL;
d440fe6d 890 int payload_number = 1;
f6039334
JH
891 iterator_t *iterator;
892 status_t status;
d440fe6d
JH
893
894 iterator = this->payloads->create_iterator(this->payloads,TRUE);
895
f6039334 896 /* process each payload and decrypt a encryption payload */
d440fe6d
JH
897 while(iterator->has_next(iterator))
898 {
668f9fcb 899 payload_rule_t *payload_rule;
bc788302 900 payload_type_t current_payload_type;
f6039334 901 payload_t *current_payload;
d440fe6d
JH
902
903 /* get current payload */
904 iterator->current(iterator,(void **)&current_payload);
905
f6039334 906 /* needed to check */
bc788302
MW
907 current_payload_type = current_payload->get_type(current_payload);
908
f6039334 909 this->logger->log(this->logger, CONTROL | MOST, "Process payload of type %s",mapping_find(payload_type_m,current_payload_type));
63bfd6cc 910
bc788302 911 if (current_payload_type == ENCRYPTED)
d440fe6d
JH
912 {
913 encryption_payload_t *encryption_payload;
d440fe6d 914 payload_t *current_encrypted_payload;
bc788302 915
668f9fcb 916 encryption_payload = (encryption_payload_t*)current_payload;
bc788302
MW
917
918 this->logger->log(this->logger, CONTROL | MORE, "Found an encryption payload");
668f9fcb 919
d440fe6d
JH
920 if (payload_number != this->payloads->get_count(this->payloads))
921 {
668f9fcb 922 /* encrypted payload is not last one */
f6039334 923 this->logger->log(this->logger, ERROR | MORE, "Encrypted payload is not last payload");
d440fe6d 924 iterator->destroy(iterator);
d440fe6d
JH
925 return FAILED;
926 }
668f9fcb 927 /* decrypt */
d440fe6d 928 encryption_payload->set_transforms(encryption_payload, crypter, signer);
f6039334 929 this->logger->log(this->logger, CONTROL | MORE, "Verify signature of encryption payload");
d440fe6d
JH
930 status = encryption_payload->verify_signature(encryption_payload, this->packet->data);
931 if (status != SUCCESS)
932 {
f6039334 933 this->logger->log(this->logger, ERROR | MORE, "encryption payload signature invalid");
d440fe6d
JH
934 iterator->destroy(iterator);
935 return status;
936 }
f6039334 937 this->logger->log(this->logger, CONTROL | MORE, "Decrypt content of encryption payload");
d440fe6d
JH
938 status = encryption_payload->decrypt(encryption_payload);
939 if (status != SUCCESS)
940 {
ccf783d2
MW
941 this->logger->log(this->logger, ERROR | MORE, "Encrypted payload could not be decrypted and parsed: %s",
942 mapping_find(status_m, status));
d440fe6d
JH
943 iterator->destroy(iterator);
944 return status;
945 }
946
668f9fcb 947 /* needed later to find out if a payload was encrypted */
d440fe6d 948 current_payload_was_encrypted = TRUE;
668f9fcb
MW
949
950 /* check if there are payloads contained in the encryption payload */
bc788302 951 if (encryption_payload->get_payload_count(encryption_payload) == 0)
d440fe6d 952 {
668f9fcb
MW
953 this->logger->log(this->logger, CONTROL | MOST, "Encrypted payload is empty");
954 /* remove the encryption payload, is not needed anymore */
d440fe6d 955 iterator->remove(iterator);
f6039334 956 /* encrypted payload contains no other payload */
bc788302 957 current_payload_type = NO_PAYLOAD;
d440fe6d 958 }
668f9fcb
MW
959 else
960 {
961 this->logger->log(this->logger, CONTROL | MOST, "Encrypted payload is not empty");
962 /* encryption_payload is replaced with first payload contained in encryption_payload */
963 encryption_payload->remove_first_payload(encryption_payload, &current_encrypted_payload);
964 iterator->replace(iterator,NULL,(void *) current_encrypted_payload);
965 current_payload_type = current_encrypted_payload->get_type(current_encrypted_payload);
966 }
bc788302 967
668f9fcb
MW
968 /* is the current paylad the first in the message? */
969 if (previous_payload == NULL)
bc788302 970 {
668f9fcb 971 /* yes, set the first payload type of the message to the current type */
bc788302
MW
972 this->first_payload = current_payload_type;
973 }
974 else
975 {
668f9fcb
MW
976 /* no, set the next_type of the previous payload to the current type */
977 previous_payload->set_next_type(previous_payload, current_payload_type);
bc788302 978 }
d440fe6d
JH
979
980 /* all encrypted payloads are added to the payload list */
bc788302 981 while (encryption_payload->get_payload_count(encryption_payload) > 0)
d440fe6d 982 {
bc788302 983 encryption_payload->remove_first_payload(encryption_payload, &current_encrypted_payload);
f8c6d7e4 984 this->logger->log(this->logger, CONTROL | MORE, "Insert unencrypted payload of type %s at end of list.",mapping_find(payload_type_m,current_encrypted_payload->get_type(current_encrypted_payload)));
d440fe6d
JH
985 this->payloads->insert_last(this->payloads,current_encrypted_payload);
986 }
987
668f9fcb
MW
988 /* encryption payload is processed, payloads are moved. Destroy it. */
989 encryption_payload->destroy(encryption_payload);
d440fe6d
JH
990 }
991
668f9fcb
MW
992 /* we allow unknown payloads of any type and don't bother if it was encrypted. Not our problem. */
993 if (current_payload_type != UNKNOWN_PAYLOAD)
d440fe6d 994 {
668f9fcb
MW
995 /* get the ruleset for found payload */
996 status = this->get_payload_rule(this, current_payload_type, &payload_rule);
997 if (status != SUCCESS)
998 {
999 /* payload is not allowed */
1000 this->logger->log(this->logger, ERROR | MORE, "Payload type %s not allowed",mapping_find(payload_type_m,current_payload_type));
1001 iterator->destroy(iterator);
1002 return status;
1003 }
1004
1005 /* check if the payload was encrypted, and if it should been have encrypted */
1006 if (payload_rule->encrypted != current_payload_was_encrypted)
1007 {
1008 /* payload was not encrypted, but should have been. or vice-versa */
1009 this->logger->log(this->logger, ERROR | MORE, "Payload type %s should be %s!",
1010 mapping_find(payload_type_m,current_payload_type),
1011 (payload_rule->encrypted) ? "encrypted": "not encrypted");
1012 iterator->destroy(iterator);
1013 return FAILED;
1014 }
d440fe6d 1015 }
668f9fcb 1016 /* advance to the next payload */
d440fe6d 1017 payload_number++;
f6039334 1018 /* is stored to set next payload in case of found encryption payload */
668f9fcb 1019 previous_payload = current_payload;
d440fe6d
JH
1020 }
1021 iterator->destroy(iterator);
668f9fcb 1022 return SUCCESS;
d440fe6d
JH
1023}
1024
f6039334
JH
1025/**
1026 * Implementation of private_message_t.encrypt_payloads.
1027 */
f890d8fe
JH
1028static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer)
1029{
f890d8fe 1030 encryption_payload_t *encryption_payload = NULL;
f6039334 1031 status_t status;
d440fe6d 1032 linked_list_t *all_payloads;
f890d8fe 1033
668f9fcb 1034 if (!this->message_rule->encrypted_content)
d440fe6d 1035 {
b09e85f9 1036 this->logger->log(this->logger, CONTROL | MORE, "Message doesn't have to be encrypted");
d440fe6d
JH
1037 /* message contains no content to encrypt */
1038 return SUCCESS;
1039 }
1040
f6039334 1041 this->logger->log(this->logger, CONTROL | MOST, "Copy all payloads to a temporary list");
d440fe6d
JH
1042 all_payloads = linked_list_create();
1043
f890d8fe
JH
1044 /* first copy all payloads in a temporary list */
1045 while (this->payloads->get_count(this->payloads) > 0)
1046 {
1047 void *current_payload;
1048 this->payloads->remove_first(this->payloads,&current_payload);
1049 all_payloads->insert_last(all_payloads,current_payload);
1050 }
f6039334
JH
1051
1052 this->logger->log(this->logger, CONTROL | MOST, "Check each payloads if they have to get encrypted");
f890d8fe
JH
1053 while (all_payloads->get_count(all_payloads) > 0)
1054 {
668f9fcb 1055 payload_rule_t *payload_rule;
f890d8fe
JH
1056 payload_t *current_payload;
1057 bool to_encrypt = FALSE;
1058
1059 all_payloads->remove_first(all_payloads,(void **)&current_payload);
f6039334 1060 this->logger->log(this->logger, CONTROL | MOST, "Get rule for payload %s", mapping_find(payload_type_m,current_payload->get_type(current_payload)));
f890d8fe 1061
668f9fcb 1062 status = this->get_payload_rule(this,current_payload->get_type(current_payload),&payload_rule);
d440fe6d
JH
1063 /* for payload types which are not found in supported payload list, it is presumed
1064 * that they don't have to be encrypted */
668f9fcb 1065 if ((status == SUCCESS) && (payload_rule->encrypted))
f890d8fe 1066 {
f6039334
JH
1067 this->logger->log(this->logger, CONTROL | MOST, "Payload %s has to get encrypted",
1068 mapping_find(payload_type_m,current_payload->get_type(current_payload)));
d440fe6d 1069 to_encrypt = TRUE;
f890d8fe 1070 }
f6039334
JH
1071 else if (status != SUCCESS)
1072 {
1073 this->logger->log(this->logger, CONTROL | MOST, "Payload %s not defined for exchange type %s. Handle it anyway",
1074 mapping_find(payload_type_m,current_payload->get_type(current_payload)),
1075 mapping_find(exchange_type_m,this->exchange_type));
1076 }
f890d8fe
JH
1077
1078 if (to_encrypt)
1079 {
1080 if (encryption_payload == NULL)
1081 {
1082 encryption_payload = encryption_payload_create();
1083 }
f6039334
JH
1084 this->logger->log(this->logger, CONTROL | MOST, "Insert payload %s to encryption payload",
1085 mapping_find(payload_type_m,current_payload->get_type(current_payload)));
1086
f890d8fe
JH
1087 encryption_payload->add_payload(encryption_payload,current_payload);
1088 }
1089 else
1090 {
f6039334
JH
1091 this->logger->log(this->logger, CONTROL | MOST, "Insert payload %s as payload wich does not have to be encrypted",
1092 mapping_find(payload_type_m,current_payload->get_type(current_payload)));
bc788302 1093 this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
f890d8fe
JH
1094 }
1095 }
1096
1097 status = SUCCESS;
1098 if (encryption_payload != NULL)
1099 {
f6039334 1100 this->logger->log(this->logger, CONTROL | MOST, "Set transforms for encryption payload ");
f890d8fe 1101 encryption_payload->set_transforms(encryption_payload,crypter,signer);
f6039334 1102 this->logger->log(this->logger, CONTROL | MORE, "Encrypt all payloads of encrypted payload");
f890d8fe 1103 status = encryption_payload->encrypt(encryption_payload);
f6039334 1104 this->logger->log(this->logger, CONTROL | MOST, "Add encrypted payload to payload list");
ee29afd4 1105 this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
f890d8fe
JH
1106 }
1107
1108 all_payloads->destroy(all_payloads);
1109
1110 return status;
1111}
1112
f6039334 1113
ca6dd4f6 1114/**
f6039334 1115 * Implementation of message_t.destroy.
ca6dd4f6 1116 */
27e43205 1117static void destroy (private_message_t *this)
ca6dd4f6 1118{
bdb141cb 1119 iterator_t *iterator;
523526ec 1120
668f9fcb 1121 this->logger->log(this->logger, CONTROL|ALL, "Going to destroy message_t object");
f6039334 1122
55f90b5d
JH
1123 this->packet->destroy(this->packet);
1124
525250c6
JH
1125 if (this->ike_sa_id != NULL)
1126 {
1127 this->ike_sa_id->destroy(this->ike_sa_id);
1128 }
523526ec 1129
a0753941 1130 iterator = this->payloads->create_iterator(this->payloads, TRUE);
523526ec
MW
1131 while (iterator->has_next(iterator))
1132 {
1133 payload_t *payload;
1134 iterator->current(iterator, (void**)&payload);
668f9fcb 1135 this->logger->log(this->logger, CONTROL|ALL, "Destroying payload of type %s",
e0d60939 1136 mapping_find(payload_type_m, payload->get_type(payload)));
523526ec
MW
1137 payload->destroy(payload);
1138 }
1139 iterator->destroy(iterator);
c64d7032 1140 this->payloads->destroy(this->payloads);
9da406cf 1141 this->parser->destroy(this->parser);
0e96f7d8 1142 charon->logger_manager->destroy_logger(charon->logger_manager, this->logger);
93a9a115 1143
31332efa 1144 allocator_free(this);
ca6dd4f6
JH
1145}
1146
1147/*
1148 * Described in Header-File
1149 */
c64d7032 1150message_t *message_create_from_packet(packet_t *packet)
ca6dd4f6 1151{
6c4b815f 1152 private_message_t *this = allocator_alloc_thing(private_message_t);
79538669 1153
c64d7032 1154 /* public functions */
27e43205 1155 this->public.set_major_version = (void(*)(message_t*, u_int8_t))set_major_version;
9da406cf 1156 this->public.get_major_version = (u_int8_t(*)(message_t*))get_major_version;
27e43205 1157 this->public.set_minor_version = (void(*)(message_t*, u_int8_t))set_minor_version;
9da406cf 1158 this->public.get_minor_version = (u_int8_t(*)(message_t*))get_minor_version;
27e43205 1159 this->public.set_message_id = (void(*)(message_t*, u_int32_t))set_message_id;
525250c6 1160 this->public.get_message_id = (u_int32_t(*)(message_t*))get_message_id;
21981473 1161 this->public.get_responder_spi = (u_int64_t(*)(message_t*))get_responder_spi;
27e43205 1162 this->public.set_ike_sa_id = (void(*)(message_t*, ike_sa_id_t *))set_ike_sa_id;
525250c6 1163 this->public.get_ike_sa_id = (status_t(*)(message_t*, ike_sa_id_t **))get_ike_sa_id;
27e43205 1164 this->public.set_exchange_type = (void(*)(message_t*, exchange_type_t))set_exchange_type;
110dc83a 1165 this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type;
27e43205 1166 this->public.set_request = (void(*)(message_t*, bool))set_request;
110dc83a 1167 this->public.get_request = (bool(*)(message_t*))get_request;
27e43205 1168 this->public.add_payload = (void(*)(message_t*,payload_t*))add_payload;
81796a52 1169 this->public.generate = (status_t (*) (message_t *,crypter_t*,signer_t*,packet_t**)) generate;
27e43205 1170 this->public.set_source = (void (*) (message_t*,host_t*)) set_source;
f6039334 1171 this->public.get_source = (host_t * (*) (message_t*)) get_source;
27e43205 1172 this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination;
f6039334 1173 this->public.get_destination = (host_t * (*) (message_t*)) get_destination;
a0753941 1174 this->public.get_payload_iterator = (iterator_t * (*) (message_t *)) get_payload_iterator;
81796a52
MW
1175 this->public.parse_header = (status_t (*) (message_t *)) parse_header;
1176 this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body;
5534ee84 1177 this->public.get_packet = (packet_t * (*) (message_t*)) get_packet;
8d68033e 1178 this->public.get_packet_data = (chunk_t (*) (message_t *this)) get_packet_data;
27e43205 1179 this->public.destroy = (void(*)(message_t*))destroy;
110dc83a 1180
f890d8fe 1181 /* private values */
523526ec 1182 this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
110dc83a 1183 this->is_request = TRUE;
525250c6 1184 this->ike_sa_id = NULL;
9da406cf 1185 this->first_payload = NO_PAYLOAD;
525250c6 1186 this->message_id = 0;
ca6dd4f6 1187
93a9a115 1188 /* private functions */
668f9fcb
MW
1189 this->set_message_rule = set_message_rule;
1190 this->get_payload_rule = get_payload_rule;
f890d8fe 1191 this->encrypt_payloads = encrypt_payloads;
668f9fcb
MW
1192 this->decrypt_payloads = decrypt_payloads;
1193 this->verify = verify;
93a9a115 1194
c64d7032 1195 /* private values */
523526ec
MW
1196 if (packet == NULL)
1197 {
1198 packet = packet_create();
1199 }
668f9fcb 1200 this->message_rule = NULL;
c64d7032
JH
1201 this->packet = packet;
1202 this->payloads = linked_list_create();
91443667
JH
1203
1204 /* parser is created from data of packet */
1205 this->parser = parser_create(this->packet->data);
523526ec 1206
0e96f7d8 1207 this->logger = charon->logger_manager->create_logger(charon->logger_manager, MESSAGE, NULL);
79538669
JH
1208
1209 return (&this->public);
ca6dd4f6 1210}
c64d7032
JH
1211
1212/*
f6039334 1213 * Described in Header.
c64d7032
JH
1214 */
1215message_t *message_create()
1216{
1217 return message_create_from_packet(NULL);
1218}
f6ba78c3
JH
1219
1220/*
1221 * Described in Header.
1222 */
1223message_t *message_create_notify_reply(host_t *source, host_t *destination, exchange_type_t exchange_type, bool original_initiator,ike_sa_id_t *ike_sa_id,notify_message_type_t notify_type)
1224{
1225 message_t *message = message_create_from_packet(NULL);
1226 notify_payload_t *payload;
1227
1228 message->set_source(message, source->clone(source));
1229 message->set_destination(message, destination->clone(destination));
1230 message->set_exchange_type(message, exchange_type);
1231 message->set_request(message, FALSE);
1232 message->set_message_id(message,0);
1233 message->set_ike_sa_id(message, ike_sa_id);
1234
1235 payload = notify_payload_create_from_protocol_and_type(IKE,notify_type);
1236 message->add_payload(message,(payload_t *) payload);
1237
1238 return message;
1239}