payload: Use common prefixes for all payload type identifiers
[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 if (!enum_from_name(notify_type_names, this->type, &type))
72 {
73 DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type);
74 return TRUE;
75 }
76 }
77 if (strncaseeq(this->data, "0x", 2))
78 {
79 data = chunk_skip(chunk_create(this->data, strlen(this->data)), 2);
80 data = chunk_from_hex(data, NULL);
81 }
82 else if (strlen(this->data))
83 {
84 data = chunk_clone(chunk_create(this->data, strlen(this->data)));
85 }
86 notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY,
87 this->esp ? PROTO_ESP : PROTO_IKE, type);
88 notify->set_spi(notify, this->spi);
89 if (data.len)
90 {
91 notify->set_notification_data(notify, data);
92 free(data.ptr);
93 }
94
95 DBG1(DBG_CFG, "injecting unencrypted INFORMATIONAL message");
96
97 message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
98 message->set_message_id(message, this->id);
99 message->set_ike_sa_id(message, ike_sa->get_id(ike_sa));
100 message->set_exchange_type(message, INFORMATIONAL);
101 message->set_request(message, TRUE);
102 host = ike_sa->get_my_host(ike_sa);
103 message->set_source(message, host->clone(host));
104 host = ike_sa->get_other_host(ike_sa);
105 message->set_destination(message, host->clone(host));
106 message->add_payload(message, &notify->payload_interface);
107 if (message->generate(message, NULL, &packet) != SUCCESS)
108 {
109 DBG1(DBG_CFG, "generating message failed");
110 message->destroy(message);
111 return TRUE;
112 }
113 message->destroy(message);
114 charon->sender->send(charon->sender, packet);
115 }
116 return TRUE;
117 }
118
119 METHOD(hook_t, destroy, void,
120 private_unencrypted_notify_t *this)
121 {
122 free(this);
123 }
124
125 /**
126 * Create the IKE_AUTH fill hook
127 */
128 hook_t *unencrypted_notify_hook_create(char *name)
129 {
130 private_unencrypted_notify_t *this;
131
132 INIT(this,
133 .hook = {
134 .listener = {
135 .ike_updown = _ike_updown,
136 },
137 .destroy = _destroy,
138 },
139 .id = conftest->test->get_int(conftest->test,
140 "hooks.%s.id", 2, name),
141 .type = conftest->test->get_str(conftest->test,
142 "hooks.%s.type", "", name),
143 .data = conftest->test->get_str(conftest->test,
144 "hooks.%s.data", "", name),
145 .spi = conftest->test->get_int(conftest->test,
146 "hooks.%s.spi", 0, name),
147 .esp = conftest->test->get_bool(conftest->test,
148 "hooks.%s.esp", FALSE, name),
149 );
150
151 return &this->hook;
152 }