Separated libcharon/sa directory with ikev1 and ikev2 subfolders
[strongswan.git] / src / conftest / hooks / unencrypted_notify.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 typedef struct private_unencrypted_notify_t private_unencrypted_notify_t;
19
20 /**
21 * Private data of an unencrypted_notify_t object.
22 */
23 struct private_unencrypted_notify_t {
24
25 /**
26 * Implements the hook_t interface.
27 */
28 hook_t hook;
29
30 /**
31 * ID of message send.
32 */
33 int id;
34
35 /**
36 * Notify type
37 */
38 char *type;
39
40 /**
41 * Notify data
42 */
43 char *data;
44
45 /**
46 * SPI of notify
47 */
48 int spi;
49
50 /**
51 * TRUE for a ESP protocol notify, FALSE for IKE
52 */
53 bool esp;
54 };
55
56 METHOD(listener_t, ike_updown, bool,
57 private_unencrypted_notify_t *this, ike_sa_t *ike_sa, bool up)
58 {
59 if (up)
60 {
61 message_t *message;
62 host_t *host;
63 notify_type_t type;
64 notify_payload_t *notify;
65 chunk_t data = chunk_empty;
66 packet_t *packet;
67
68 type = atoi(this->type);
69 if (!type)
70 {
71 type = enum_from_name(notify_type_names, this->type);
72 if (type == -1)
73 {
74 DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type);
75 return TRUE;
76 }
77 }
78 if (strncaseeq(this->data, "0x", 2))
79 {
80 data = chunk_skip(chunk_create(this->data, strlen(this->data)), 2);
81 data = chunk_from_hex(data, NULL);
82 }
83 else if (this->data && strlen(this->data))
84 {
85 data = chunk_clone(chunk_create(this->data, strlen(this->data)));
86 }
87 notify = notify_payload_create_from_protocol_and_type(NOTIFY,
88 this->esp ? PROTO_ESP : PROTO_IKE, type);
89 notify->set_spi(notify, this->spi);
90 if (data.len)
91 {
92 notify->set_notification_data(notify, data);
93 free(data.ptr);
94 }
95
96 DBG1(DBG_CFG, "injecting unencrypted INFORMATIONAL message");
97
98 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
99 message->set_message_id(message, this->id);
100 message->set_ike_sa_id(message, ike_sa->get_id(ike_sa));
101 message->set_exchange_type(message, INFORMATIONAL);
102 message->set_request(message, TRUE);
103 host = ike_sa->get_my_host(ike_sa);
104 message->set_source(message, host->clone(host));
105 host = ike_sa->get_other_host(ike_sa);
106 message->set_destination(message, host->clone(host));
107 message->add_payload(message, &notify->payload_interface);
108 if (message->generate(message, NULL, &packet) != SUCCESS)
109 {
110 DBG1(DBG_CFG, "generating message failed");
111 message->destroy(message);
112 return TRUE;
113 }
114 message->destroy(message);
115 charon->sender->send(charon->sender, packet);
116 }
117 return TRUE;
118 }
119
120 METHOD(hook_t, destroy, void,
121 private_unencrypted_notify_t *this)
122 {
123 free(this);
124 }
125
126 /**
127 * Create the IKE_AUTH fill hook
128 */
129 hook_t *unencrypted_notify_hook_create(char *name)
130 {
131 private_unencrypted_notify_t *this;
132
133 INIT(this,
134 .hook = {
135 .listener = {
136 .ike_updown = _ike_updown,
137 },
138 .destroy = _destroy,
139 },
140 .id = conftest->test->get_int(conftest->test,
141 "hooks.%s.id", 2, name),
142 .type = conftest->test->get_str(conftest->test,
143 "hooks.%s.type", "", name),
144 .data = conftest->test->get_str(conftest->test,
145 "hooks.%s.data", "", name),
146 .spi = conftest->test->get_int(conftest->test,
147 "hooks.%s.spi", 0, name),
148 .esp = conftest->test->get_bool(conftest->test,
149 "hooks.%s.esp", FALSE, name),
150 );
151
152 return &this->hook;
153 }