Version bump to 5.9.0
[strongswan.git] / src / conftest / hooks / add_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_add_notify_t private_add_notify_t;
19
20 /**
21 * Private data of an add_notify_t object.
22 */
23 struct private_add_notify_t {
24
25 /**
26 * Implements the hook_t interface.
27 */
28 hook_t hook;
29
30 /**
31 * Alter requests or responses?
32 */
33 bool req;
34
35 /**
36 * ID of message to alter.
37 */
38 int id;
39
40 /**
41 * Notify type
42 */
43 char *type;
44
45 /**
46 * Notify data
47 */
48 char *data;
49
50 /**
51 * SPI of notify
52 */
53 int spi;
54
55 /**
56 * TRUE for a ESP protocol notify, FALSE for IKE
57 */
58 bool esp;
59 };
60
61 METHOD(listener_t, message, bool,
62 private_add_notify_t *this, ike_sa_t *ike_sa, message_t *message,
63 bool incoming, bool plain)
64 {
65 if (!incoming && plain &&
66 message->get_request(message) == this->req &&
67 message->get_message_id(message) == this->id)
68 {
69 notify_type_t type;
70 notify_payload_t *notify;
71 chunk_t data = chunk_empty;
72
73 type = atoi(this->type);
74 if (!type)
75 {
76 if (!enum_from_name(notify_type_names, this->type, &type))
77 {
78 DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type);
79 return TRUE;
80 }
81 }
82 if (strncaseeq(this->data, "0x", 2))
83 {
84 data = chunk_skip(chunk_create(this->data, strlen(this->data)), 2);
85 data = chunk_from_hex(data, NULL);
86 }
87 else if (strlen(this->data))
88 {
89 data = chunk_clone(chunk_create(this->data, strlen(this->data)));
90 }
91 notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY,
92 this->esp ? PROTO_ESP : PROTO_IKE, type);
93 notify->set_spi(notify, this->spi);
94 if (data.len)
95 {
96 notify->set_notification_data(notify, data);
97 free(data.ptr);
98 }
99 message->add_payload(message, &notify->payload_interface);
100 }
101 return TRUE;
102 }
103
104 METHOD(hook_t, destroy, void,
105 private_add_notify_t *this)
106 {
107 free(this);
108 }
109
110 /**
111 * Create the IKE_AUTH fill hook
112 */
113 hook_t *add_notify_hook_create(char *name)
114 {
115 private_add_notify_t *this;
116
117 INIT(this,
118 .hook = {
119 .listener = {
120 .message = _message,
121 },
122 .destroy = _destroy,
123 },
124 .req = conftest->test->get_bool(conftest->test,
125 "hooks.%s.request", TRUE, name),
126 .id = conftest->test->get_int(conftest->test,
127 "hooks.%s.id", 0, name),
128 .type = conftest->test->get_str(conftest->test,
129 "hooks.%s.type", "", name),
130 .data = conftest->test->get_str(conftest->test,
131 "hooks.%s.data", "", name),
132 .spi = conftest->test->get_int(conftest->test,
133 "hooks.%s.spi", 0, name),
134 .esp = conftest->test->get_bool(conftest->test,
135 "hooks.%s.esp", FALSE, name),
136 );
137
138 return &this->hook;
139 }