Fix insertion of non hex encoded payload data
[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)
64 {
65 if (!incoming &&
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 type = enum_from_name(notify_type_names, this->type);
77 if (type == -1)
78 {
79 DBG1(DBG_CFG, "unknown notify: '%s', skipped", this->type);
80 return TRUE;
81 }
82 }
83 if (strncasecmp(this->data, "0x", 2) == 0)
84 {
85 data = chunk_skip(chunk_create(this->data, strlen(this->data)), 2);
86 data = chunk_from_hex(data, NULL);
87 }
88 else if (this->data && strlen(this->data))
89 {
90 data = chunk_clone(chunk_create(this->data, strlen(this->data)));
91 }
92 notify = notify_payload_create_from_protocol_and_type(
93 this->esp ? PROTO_ESP : PROTO_IKE, type);
94 notify->set_spi(notify, this->spi);
95 if (data.len)
96 {
97 notify->set_notification_data(notify, data);
98 free(data.ptr);
99 }
100 message->add_payload(message, &notify->payload_interface);
101 }
102 return TRUE;
103 }
104
105 METHOD(hook_t, destroy, void,
106 private_add_notify_t *this)
107 {
108 free(this);
109 }
110
111 /**
112 * Create the IKE_AUTH fill hook
113 */
114 hook_t *add_notify_hook_create(char *name)
115 {
116 private_add_notify_t *this;
117
118 INIT(this,
119 .hook = {
120 .listener = {
121 .message = _message,
122 },
123 .destroy = _destroy,
124 },
125 .req = conftest->test->get_bool(conftest->test,
126 "hooks.%s.request", TRUE, name),
127 .id = conftest->test->get_int(conftest->test,
128 "hooks.%s.id", 0, name),
129 .type = conftest->test->get_str(conftest->test,
130 "hooks.%s.type", "", name),
131 .data = conftest->test->get_str(conftest->test,
132 "hooks.%s.data", "", name),
133 .spi = conftest->test->get_int(conftest->test,
134 "hooks.%s.spi", 0, name),
135 .esp = conftest->test->get_bool(conftest->test,
136 "hooks.%s.esp", FALSE, name),
137 );
138
139 return &this->hook;
140 }