payload: Use common prefixes for all payload type identifiers
[strongswan.git] / src / conftest / hooks / force_cookie.c
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 <encoding/payloads/unknown_payload.h>
19
20 typedef struct private_force_cookie_t private_force_cookie_t;
21
22 /**
23 * Private data of an force_cookie_t object.
24 */
25 struct private_force_cookie_t {
26
27 /**
28 * Implements the hook_t interface.
29 */
30 hook_t hook;
31 };
32
33 METHOD(listener_t, message, bool,
34 private_force_cookie_t *this, ike_sa_t *ike_sa, message_t *message,
35 bool incoming, bool plain)
36 {
37 if (incoming && plain && message->get_request(message) &&
38 message->get_exchange_type(message) == IKE_SA_INIT)
39 {
40 enumerator_t *enumerator;
41 bool has_cookie = FALSE;
42 payload_t *payload;
43
44 enumerator = message->create_payload_enumerator(message);
45 while (enumerator->enumerate(enumerator, &payload))
46 {
47 if (payload->get_type(payload) == PLV2_NOTIFY)
48 {
49 notify_payload_t *notify = (notify_payload_t*)payload;
50 chunk_t data;
51
52 if (notify->get_notify_type(notify) == COOKIE)
53 {
54 data = notify->get_notification_data(notify);
55 DBG1(DBG_CFG, "received COOKIE: %#B", &data);
56 has_cookie = TRUE;
57 break;
58 }
59 }
60 }
61 enumerator->destroy(enumerator);
62 if (!has_cookie)
63 {
64 message_t *response;
65 host_t *src, *dst;
66 packet_t *packet;
67 ike_sa_id_t *ike_sa_id;
68 chunk_t data = chunk_from_thing("COOKIE test data");
69
70 DBG1(DBG_CFG, "sending COOKIE: %#B", &data);
71 response = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
72 dst = message->get_source(message);
73 src = message->get_destination(message);
74 response->set_source(response, src->clone(src));
75 response->set_destination(response, dst->clone(dst));
76 response->set_exchange_type(response, IKE_SA_INIT);
77 response->set_request(response, FALSE);
78 response->set_message_id(response, 0);
79 ike_sa_id = message->get_ike_sa_id(message);
80 ike_sa_id->switch_initiator(ike_sa_id);
81 response->set_ike_sa_id(response, ike_sa_id);
82 response->add_notify(response, FALSE, COOKIE, data);
83 if (response->generate(response, NULL, &packet) == SUCCESS)
84 {
85 charon->sender->send(charon->sender, packet);
86 response->destroy(response);
87 }
88 message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);
89 }
90 }
91 return TRUE;
92 }
93
94 METHOD(hook_t, destroy, void,
95 private_force_cookie_t *this)
96 {
97 free(this);
98 }
99
100 /**
101 * Create the IKE_AUTH fill hook
102 */
103 hook_t *force_cookie_hook_create(char *name)
104 {
105 private_force_cookie_t *this;
106
107 INIT(this,
108 .hook = {
109 .listener = {
110 .message = _message,
111 },
112 .destroy = _destroy,
113 },
114 );
115
116 return &this->hook;
117 }