]>
Commit | Line | Data |
---|---|---|
a5a0bcaa MW |
1 | /* |
2 | * Copyright (C) 2009 Martin Willi | |
3 | * Hochschule fuer Technik Rapperswil | |
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 "ike_vendor.h" | |
17 | ||
18 | #include <daemon.h> | |
19 | #include <encoding/payloads/vendor_id_payload.h> | |
20 | ||
21 | typedef struct private_ike_vendor_t private_ike_vendor_t; | |
22 | ||
23 | /** | |
24 | * Private data of an ike_vendor_t object. | |
25 | */ | |
26 | struct private_ike_vendor_t { | |
27 | ||
28 | /** | |
29 | * Public ike_vendor_t interface. | |
30 | */ | |
31 | ike_vendor_t public; | |
32 | ||
33 | /** | |
34 | * Associated IKE_SA | |
35 | */ | |
36 | ike_sa_t *ike_sa; | |
37 | ||
38 | /** | |
39 | * Are we the inititator of this task | |
40 | */ | |
41 | bool initiator; | |
42 | }; | |
43 | ||
44 | /** | |
a8d8e631 | 45 | * Vendor ID database entry |
a5a0bcaa | 46 | */ |
a8d8e631 MW |
47 | typedef struct { |
48 | /* Description */ | |
49 | char *desc; | |
50 | /* extension flag negotiated with vendor ID, if any */ | |
51 | ike_extension_t extension; | |
52 | /* length of vendor ID string, 0 for NULL terminated */ | |
53 | int len; | |
54 | /* vendor ID string */ | |
55 | char *id; | |
56 | } vid_data_t; | |
57 | ||
58 | /** | |
59 | * Get the data of a vendor ID as a chunk | |
60 | */ | |
61 | static chunk_t get_vid_data(vid_data_t *data) | |
62 | { | |
63 | return chunk_create(data->id, data->len ?: strlen(data->id)); | |
64 | } | |
65 | ||
66 | /** | |
67 | * IKEv2 Vendor ID database entry | |
68 | */ | |
69 | static vid_data_t vids[] = { | |
70 | /* strongSwan MD5("strongSwan") */ | |
71 | { "strongSwan", EXT_STRONGSWAN, 16, | |
72 | "\x88\x2f\xe5\x6d\x6f\xd2\x0d\xbc\x22\x51\x61\x3b\x2e\xbe\x5b\xeb"}, | |
f84d1cb2 MW |
73 | { "Cisco Delete Reason", 0, 0, |
74 | "CISCO-DELETE-REASON" }, | |
2c6d204b MW |
75 | { "Cisco Copyright (c) 2009", 0, 0, |
76 | "CISCO(COPYRIGHT)&Copyright (c) 2009 Cisco Systems, Inc." }, | |
c7c2e24a MW |
77 | { "FRAGMENTATION", 0, 16, |
78 | "\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3"}, | |
c5a41c91 TB |
79 | { "MS NT5 ISAKMPOAKLEY v7", 0, 20, |
80 | "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x07"}, | |
81 | { "MS NT5 ISAKMPOAKLEY v8", 0, 20, | |
82 | "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x08"}, | |
83 | { "MS NT5 ISAKMPOAKLEY v9", 0, 20, | |
84 | "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x09"}, | |
85 | { "MS-Negotiation Discovery Capable", 0, 16, | |
86 | "\xfb\x1d\xe3\xcd\xf3\x41\xb7\xea\x16\xb7\xe5\xbe\x08\x55\xf1\x20"}, | |
87 | { "Vid-Initial-Contact", 0, 16, | |
88 | "\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19"}, | |
a8d8e631 | 89 | }; |
a5a0bcaa MW |
90 | |
91 | METHOD(task_t, build, status_t, | |
92 | private_ike_vendor_t *this, message_t *message) | |
93 | { | |
a8d8e631 MW |
94 | vendor_id_payload_t *vid; |
95 | bool strongswan; | |
96 | int i; | |
a5a0bcaa | 97 | |
a8d8e631 | 98 | strongswan = lib->settings->get_bool(lib->settings, |
d223fe80 | 99 | "%s.send_vendor_id", FALSE, lib->ns); |
a8d8e631 MW |
100 | for (i = 0; i < countof(vids); i++) |
101 | { | |
102 | if (vids[i].extension == EXT_STRONGSWAN && strongswan) | |
103 | { | |
104 | DBG2(DBG_IKE, "sending %s vendor ID", vids[i].desc); | |
3ecfc83c | 105 | vid = vendor_id_payload_create_data(PLV2_VENDOR_ID, |
a8d8e631 MW |
106 | chunk_clone(get_vid_data(&vids[i]))); |
107 | message->add_payload(message, &vid->payload_interface); | |
108 | } | |
a5a0bcaa MW |
109 | } |
110 | ||
111 | return this->initiator ? NEED_MORE : SUCCESS; | |
112 | } | |
113 | ||
114 | METHOD(task_t, process, status_t, | |
115 | private_ike_vendor_t *this, message_t *message) | |
116 | { | |
117 | enumerator_t *enumerator; | |
118 | payload_t *payload; | |
a8d8e631 | 119 | int i; |
a5a0bcaa MW |
120 | |
121 | enumerator = message->create_payload_enumerator(message); | |
122 | while (enumerator->enumerate(enumerator, &payload)) | |
123 | { | |
3ecfc83c | 124 | if (payload->get_type(payload) == PLV2_VENDOR_ID) |
a5a0bcaa MW |
125 | { |
126 | vendor_id_payload_t *vid; | |
127 | chunk_t data; | |
a8d8e631 | 128 | bool found = FALSE; |
a5a0bcaa MW |
129 | |
130 | vid = (vendor_id_payload_t*)payload; | |
131 | data = vid->get_data(vid); | |
132 | ||
a8d8e631 | 133 | for (i = 0; i < countof(vids); i++) |
a5a0bcaa | 134 | { |
a8d8e631 MW |
135 | if (chunk_equals(get_vid_data(&vids[i]), data)) |
136 | { | |
137 | DBG1(DBG_IKE, "received %s vendor ID", vids[i].desc); | |
138 | if (vids[i].extension) | |
139 | { | |
140 | this->ike_sa->enable_extension(this->ike_sa, | |
141 | vids[i].extension); | |
142 | } | |
143 | found = TRUE; | |
144 | break; | |
145 | } | |
a5a0bcaa | 146 | } |
a8d8e631 | 147 | if (!found) |
a5a0bcaa | 148 | { |
f7cd1cde | 149 | DBG1(DBG_ENC, "received unknown vendor ID: %#B", &data); |
a5a0bcaa MW |
150 | } |
151 | } | |
152 | } | |
153 | enumerator->destroy(enumerator); | |
154 | ||
155 | return this->initiator ? SUCCESS : NEED_MORE; | |
156 | } | |
157 | ||
158 | METHOD(task_t, migrate, void, | |
159 | private_ike_vendor_t *this, ike_sa_t *ike_sa) | |
160 | { | |
161 | this->ike_sa = ike_sa; | |
162 | } | |
163 | ||
164 | METHOD(task_t, get_type, task_type_t, | |
165 | private_ike_vendor_t *this) | |
166 | { | |
a09972df | 167 | return TASK_IKE_VENDOR; |
a5a0bcaa MW |
168 | } |
169 | ||
170 | METHOD(task_t, destroy, void, | |
171 | private_ike_vendor_t *this) | |
172 | { | |
173 | free(this); | |
174 | } | |
175 | ||
176 | /** | |
177 | * See header | |
178 | */ | |
179 | ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator) | |
180 | { | |
181 | private_ike_vendor_t *this; | |
182 | ||
183 | INIT(this, | |
ba31fe1f MW |
184 | .public = { |
185 | .task = { | |
186 | .build = _build, | |
187 | .process = _process, | |
188 | .migrate = _migrate, | |
189 | .get_type = _get_type, | |
190 | .destroy = _destroy, | |
191 | }, | |
a5a0bcaa MW |
192 | }, |
193 | .initiator = initiator, | |
194 | .ike_sa = ike_sa, | |
195 | ); | |
196 | ||
197 | return &this->public; | |
198 | } |