1 |
|
|
/* $OpenBSD: policy.c,v 1.97 2013/11/22 04:12:47 deraadt Exp $ */ |
2 |
|
|
/* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */ |
3 |
|
|
|
4 |
|
|
/* |
5 |
|
|
* Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved. |
6 |
|
|
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. |
7 |
|
|
* Copyright (c) 2001 Håkan Olsson. All rights reserved. |
8 |
|
|
* |
9 |
|
|
* Redistribution and use in source and binary forms, with or without |
10 |
|
|
* modification, are permitted provided that the following conditions |
11 |
|
|
* are met: |
12 |
|
|
* 1. Redistributions of source code must retain the above copyright |
13 |
|
|
* notice, this list of conditions and the following disclaimer. |
14 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
15 |
|
|
* notice, this list of conditions and the following disclaimer in the |
16 |
|
|
* documentation and/or other materials provided with the distribution. |
17 |
|
|
* |
18 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
19 |
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 |
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
21 |
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
22 |
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
23 |
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 |
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 |
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 |
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 |
|
|
*/ |
29 |
|
|
|
30 |
|
|
/* |
31 |
|
|
* This code was written under funding by Ericsson Radio Systems. |
32 |
|
|
*/ |
33 |
|
|
|
34 |
|
|
#include <sys/types.h> |
35 |
|
|
#include <sys/mman.h> |
36 |
|
|
#include <sys/queue.h> |
37 |
|
|
#include <sys/stat.h> |
38 |
|
|
#include <regex.h> |
39 |
|
|
#include <ctype.h> |
40 |
|
|
#include <fcntl.h> |
41 |
|
|
#include <stdio.h> |
42 |
|
|
#include <stdlib.h> |
43 |
|
|
#include <string.h> |
44 |
|
|
#include <unistd.h> |
45 |
|
|
#include <keynote.h> |
46 |
|
|
#include <sys/socket.h> |
47 |
|
|
#include <netinet/in.h> |
48 |
|
|
#include <arpa/inet.h> |
49 |
|
|
#include <errno.h> |
50 |
|
|
#include <openssl/ssl.h> |
51 |
|
|
#include <netdb.h> |
52 |
|
|
|
53 |
|
|
#include "conf.h" |
54 |
|
|
#include "exchange.h" |
55 |
|
|
#include "ipsec.h" |
56 |
|
|
#include "isakmp_doi.h" |
57 |
|
|
#include "sa.h" |
58 |
|
|
#include "transport.h" |
59 |
|
|
#include "log.h" |
60 |
|
|
#include "message.h" |
61 |
|
|
#include "monitor.h" |
62 |
|
|
#include "util.h" |
63 |
|
|
#include "policy.h" |
64 |
|
|
#include "x509.h" |
65 |
|
|
|
66 |
|
|
char **policy_asserts = NULL; |
67 |
|
|
int ignore_policy = 0; |
68 |
|
|
int policy_asserts_num = 0; |
69 |
|
|
struct exchange *policy_exchange = 0; |
70 |
|
|
struct sa *policy_sa = 0; |
71 |
|
|
struct sa *policy_isakmp_sa = 0; |
72 |
|
|
|
73 |
|
|
static const char hextab[] = { |
74 |
|
|
'0', '1', '2', '3', '4', '5', '6', '7', |
75 |
|
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' |
76 |
|
|
}; |
77 |
|
|
|
78 |
|
|
/* |
79 |
|
|
* Adaptation of Vixie's inet_ntop4 () |
80 |
|
|
*/ |
81 |
|
|
static const char * |
82 |
|
|
my_inet_ntop4(const in_addr_t *src, char *dst, size_t size, int normalize) |
83 |
|
|
{ |
84 |
|
|
static const char fmt[] = "%03u.%03u.%03u.%03u"; |
85 |
|
|
char tmp[sizeof "255.255.255.255"]; |
86 |
|
|
in_addr_t src2; |
87 |
|
|
int len; |
88 |
|
|
|
89 |
|
|
if (normalize) |
90 |
|
|
src2 = ntohl(*src); |
91 |
|
|
else |
92 |
|
|
src2 = *src; |
93 |
|
|
|
94 |
|
|
len = snprintf(tmp, sizeof tmp, fmt, ((u_int8_t *)&src2)[0], |
95 |
|
|
((u_int8_t *)&src2)[1], ((u_int8_t *)&src2)[2], |
96 |
|
|
((u_int8_t *)&src2)[3]); |
97 |
|
|
if (len == -1 || len > (int)size) { |
98 |
|
|
errno = ENOSPC; |
99 |
|
|
return 0; |
100 |
|
|
} |
101 |
|
|
strlcpy(dst, tmp, size); |
102 |
|
|
return dst; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
static const char * |
106 |
|
|
my_inet_ntop6(const unsigned char *src, char *dst, size_t size) |
107 |
|
|
{ |
108 |
|
|
static const char fmt[] = |
109 |
|
|
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"; |
110 |
|
|
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; |
111 |
|
|
int len; |
112 |
|
|
|
113 |
|
|
len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3], |
114 |
|
|
src[4], src[5], src[6], src[7], src[8], src[9], src[10], src[11], |
115 |
|
|
src[12], src[13], src[14], src[15]); |
116 |
|
|
if (len == -1 || len > (int)size) { |
117 |
|
|
errno = ENOSPC; |
118 |
|
|
return 0; |
119 |
|
|
} |
120 |
|
|
strlcpy(dst, tmp, size); |
121 |
|
|
return dst; |
122 |
|
|
} |
123 |
|
|
|
124 |
|
|
char * |
125 |
|
|
policy_callback(char *name) |
126 |
|
|
{ |
127 |
|
|
struct proto *proto; |
128 |
|
|
|
129 |
|
|
u_int8_t *attr, *value, *id, *idlocal, *idremote; |
130 |
|
|
size_t id_sz, idlocalsz, idremotesz; |
131 |
|
|
struct sockaddr *sin; |
132 |
|
|
struct ipsec_exch *ie; |
133 |
|
|
struct ipsec_sa *is; |
134 |
|
|
size_t i; |
135 |
|
|
int fmt, lifetype = 0; |
136 |
|
|
in_addr_t net, subnet; |
137 |
|
|
u_int16_t len, type; |
138 |
|
|
time_t tt; |
139 |
|
|
char *addr; |
140 |
|
|
static char mytimeofday[15]; |
141 |
|
|
|
142 |
|
|
/* We use all these as a cache. */ |
143 |
|
|
#define PMAX 32 |
144 |
|
|
static char *esp_present, *ah_present, *comp_present; |
145 |
|
|
static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg; |
146 |
|
|
static char *comp_alg, ah_life_kbytes[PMAX], ah_life_seconds[PMAX]; |
147 |
|
|
static char esp_life_kbytes[PMAX], esp_life_seconds[PMAX]; |
148 |
|
|
static char comp_life_kbytes[PMAX]; |
149 |
|
|
static char *ah_ecn, *esp_ecn, *comp_ecn; |
150 |
|
|
static char comp_life_seconds[PMAX], *ah_encapsulation; |
151 |
|
|
static char *esp_encapsulation, *comp_encapsulation; |
152 |
|
|
static char ah_key_length[PMAX], esp_key_length[PMAX]; |
153 |
|
|
static char ah_key_rounds[PMAX], esp_key_rounds[PMAX]; |
154 |
|
|
static char comp_dict_size[PMAX], comp_private_alg[PMAX]; |
155 |
|
|
static char *remote_filter_type, *local_filter_type; |
156 |
|
|
static char remote_filter_addr_upper[NI_MAXHOST]; |
157 |
|
|
static char remote_filter_addr_lower[NI_MAXHOST]; |
158 |
|
|
static char local_filter_addr_upper[NI_MAXHOST]; |
159 |
|
|
static char local_filter_addr_lower[NI_MAXHOST]; |
160 |
|
|
static char ah_group_desc[PMAX], esp_group_desc[PMAX]; |
161 |
|
|
static char comp_group_desc[PMAX], remote_ike_address[NI_MAXHOST]; |
162 |
|
|
static char local_ike_address[NI_MAXHOST]; |
163 |
|
|
static char *remote_id_type, remote_id_addr_upper[NI_MAXHOST]; |
164 |
|
|
static char *phase_1, remote_id_addr_lower[NI_MAXHOST]; |
165 |
|
|
static char *remote_id_proto, remote_id_port[PMAX]; |
166 |
|
|
static char remote_filter_port[PMAX], local_filter_port[PMAX]; |
167 |
|
|
static char *remote_filter_proto, *local_filter_proto, *pfs; |
168 |
|
|
static char *initiator, remote_filter_proto_num[3]; |
169 |
|
|
static char local_filter_proto_num[3], remote_id_proto_num[3]; |
170 |
|
|
static char phase1_group[PMAX]; |
171 |
|
|
|
172 |
|
|
/* Allocated. */ |
173 |
|
|
static char *remote_filter = 0, *local_filter = 0, *remote_id = 0; |
174 |
|
|
|
175 |
|
|
static int dirty = 1; |
176 |
|
|
|
177 |
|
|
/* We only need to set dirty at initialization time really. */ |
178 |
|
|
if (strcmp(name, KEYNOTE_CALLBACK_CLEANUP) == 0 || |
179 |
|
|
strcmp(name, KEYNOTE_CALLBACK_INITIALIZE) == 0) { |
180 |
|
|
esp_present = ah_present = comp_present = pfs = "no"; |
181 |
|
|
ah_hash_alg = ah_auth_alg = phase_1 = ""; |
182 |
|
|
esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = ""; |
183 |
|
|
ah_ecn = esp_ecn = comp_ecn = "no"; |
184 |
|
|
esp_encapsulation = comp_encapsulation = ""; |
185 |
|
|
remote_filter_type = ""; |
186 |
|
|
local_filter_type = remote_id_type = initiator = ""; |
187 |
|
|
remote_filter_proto = local_filter_proto = ""; |
188 |
|
|
remote_id_proto = ""; |
189 |
|
|
|
190 |
|
|
free(remote_filter); |
191 |
|
|
remote_filter = 0; |
192 |
|
|
free(local_filter); |
193 |
|
|
local_filter = 0; |
194 |
|
|
free(remote_id); |
195 |
|
|
remote_id = 0; |
196 |
|
|
|
197 |
|
|
bzero(remote_ike_address, sizeof remote_ike_address); |
198 |
|
|
bzero(local_ike_address, sizeof local_ike_address); |
199 |
|
|
bzero(ah_life_kbytes, sizeof ah_life_kbytes); |
200 |
|
|
bzero(ah_life_seconds, sizeof ah_life_seconds); |
201 |
|
|
bzero(esp_life_kbytes, sizeof esp_life_kbytes); |
202 |
|
|
bzero(esp_life_seconds, sizeof esp_life_seconds); |
203 |
|
|
bzero(comp_life_kbytes, sizeof comp_life_kbytes); |
204 |
|
|
bzero(comp_life_seconds, sizeof comp_life_seconds); |
205 |
|
|
bzero(ah_key_length, sizeof ah_key_length); |
206 |
|
|
bzero(ah_key_rounds, sizeof ah_key_rounds); |
207 |
|
|
bzero(esp_key_length, sizeof esp_key_length); |
208 |
|
|
bzero(esp_key_rounds, sizeof esp_key_rounds); |
209 |
|
|
bzero(comp_dict_size, sizeof comp_dict_size); |
210 |
|
|
bzero(comp_private_alg, sizeof comp_private_alg); |
211 |
|
|
bzero(remote_filter_addr_upper, |
212 |
|
|
sizeof remote_filter_addr_upper); |
213 |
|
|
bzero(remote_filter_addr_lower, |
214 |
|
|
sizeof remote_filter_addr_lower); |
215 |
|
|
bzero(local_filter_addr_upper, |
216 |
|
|
sizeof local_filter_addr_upper); |
217 |
|
|
bzero(local_filter_addr_lower, |
218 |
|
|
sizeof local_filter_addr_lower); |
219 |
|
|
bzero(remote_id_addr_upper, sizeof remote_id_addr_upper); |
220 |
|
|
bzero(remote_id_addr_lower, sizeof remote_id_addr_lower); |
221 |
|
|
bzero(ah_group_desc, sizeof ah_group_desc); |
222 |
|
|
bzero(esp_group_desc, sizeof esp_group_desc); |
223 |
|
|
bzero(remote_id_port, sizeof remote_id_port); |
224 |
|
|
bzero(remote_filter_port, sizeof remote_filter_port); |
225 |
|
|
bzero(local_filter_port, sizeof local_filter_port); |
226 |
|
|
bzero(phase1_group, sizeof phase1_group); |
227 |
|
|
|
228 |
|
|
dirty = 1; |
229 |
|
|
return ""; |
230 |
|
|
} |
231 |
|
|
/* |
232 |
|
|
* If dirty is set, this is the first request for an attribute, so |
233 |
|
|
* populate our value cache. |
234 |
|
|
*/ |
235 |
|
|
if (dirty) { |
236 |
|
|
ie = policy_exchange->data; |
237 |
|
|
|
238 |
|
|
if (ie->pfs) |
239 |
|
|
pfs = "yes"; |
240 |
|
|
|
241 |
|
|
is = policy_isakmp_sa->data; |
242 |
|
|
snprintf(phase1_group, sizeof phase1_group, "%u", |
243 |
|
|
is->group_desc); |
244 |
|
|
|
245 |
|
|
for (proto = TAILQ_FIRST(&policy_sa->protos); proto; |
246 |
|
|
proto = TAILQ_NEXT(proto, link)) { |
247 |
|
|
switch (proto->proto) { |
248 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
249 |
|
|
ah_present = "yes"; |
250 |
|
|
switch (proto->id) { |
251 |
|
|
case IPSEC_AH_MD5: |
252 |
|
|
ah_hash_alg = "md5"; |
253 |
|
|
break; |
254 |
|
|
|
255 |
|
|
case IPSEC_AH_SHA: |
256 |
|
|
ah_hash_alg = "sha"; |
257 |
|
|
break; |
258 |
|
|
|
259 |
|
|
case IPSEC_AH_RIPEMD: |
260 |
|
|
ah_hash_alg = "ripemd"; |
261 |
|
|
break; |
262 |
|
|
|
263 |
|
|
case IPSEC_AH_SHA2_256: |
264 |
|
|
ah_auth_alg = "sha2-256"; |
265 |
|
|
break; |
266 |
|
|
|
267 |
|
|
case IPSEC_AH_SHA2_384: |
268 |
|
|
ah_auth_alg = "sha2-384"; |
269 |
|
|
break; |
270 |
|
|
|
271 |
|
|
case IPSEC_AH_SHA2_512: |
272 |
|
|
ah_auth_alg = "sha2-512"; |
273 |
|
|
break; |
274 |
|
|
|
275 |
|
|
case IPSEC_AH_DES: |
276 |
|
|
ah_hash_alg = "des"; |
277 |
|
|
break; |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
break; |
281 |
|
|
|
282 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
283 |
|
|
esp_present = "yes"; |
284 |
|
|
switch (proto->id) { |
285 |
|
|
case IPSEC_ESP_DES_IV64: |
286 |
|
|
esp_enc_alg = "des-iv64"; |
287 |
|
|
break; |
288 |
|
|
|
289 |
|
|
case IPSEC_ESP_DES: |
290 |
|
|
esp_enc_alg = "des"; |
291 |
|
|
break; |
292 |
|
|
|
293 |
|
|
case IPSEC_ESP_3DES: |
294 |
|
|
esp_enc_alg = "3des"; |
295 |
|
|
break; |
296 |
|
|
|
297 |
|
|
case IPSEC_ESP_AES: |
298 |
|
|
case IPSEC_ESP_AES_CTR: |
299 |
|
|
case IPSEC_ESP_AES_GCM_16: |
300 |
|
|
case IPSEC_ESP_AES_GMAC: |
301 |
|
|
esp_enc_alg = "aes"; |
302 |
|
|
break; |
303 |
|
|
|
304 |
|
|
case IPSEC_ESP_RC5: |
305 |
|
|
esp_enc_alg = "rc5"; |
306 |
|
|
break; |
307 |
|
|
|
308 |
|
|
case IPSEC_ESP_IDEA: |
309 |
|
|
esp_enc_alg = "idea"; |
310 |
|
|
break; |
311 |
|
|
|
312 |
|
|
case IPSEC_ESP_CAST: |
313 |
|
|
esp_enc_alg = "cast"; |
314 |
|
|
break; |
315 |
|
|
|
316 |
|
|
case IPSEC_ESP_BLOWFISH: |
317 |
|
|
esp_enc_alg = "blowfish"; |
318 |
|
|
break; |
319 |
|
|
|
320 |
|
|
case IPSEC_ESP_3IDEA: |
321 |
|
|
esp_enc_alg = "3idea"; |
322 |
|
|
break; |
323 |
|
|
|
324 |
|
|
case IPSEC_ESP_DES_IV32: |
325 |
|
|
esp_enc_alg = "des-iv32"; |
326 |
|
|
break; |
327 |
|
|
|
328 |
|
|
case IPSEC_ESP_RC4: |
329 |
|
|
esp_enc_alg = "rc4"; |
330 |
|
|
break; |
331 |
|
|
|
332 |
|
|
case IPSEC_ESP_NULL: |
333 |
|
|
esp_enc_alg = "null"; |
334 |
|
|
break; |
335 |
|
|
} |
336 |
|
|
|
337 |
|
|
break; |
338 |
|
|
|
339 |
|
|
case IPSEC_PROTO_IPCOMP: |
340 |
|
|
comp_present = "yes"; |
341 |
|
|
switch (proto->id) { |
342 |
|
|
case IPSEC_IPCOMP_OUI: |
343 |
|
|
comp_alg = "oui"; |
344 |
|
|
break; |
345 |
|
|
|
346 |
|
|
case IPSEC_IPCOMP_DEFLATE: |
347 |
|
|
comp_alg = "deflate"; |
348 |
|
|
break; |
349 |
|
|
|
350 |
|
|
case IPSEC_IPCOMP_LZS: |
351 |
|
|
comp_alg = "lzs"; |
352 |
|
|
break; |
353 |
|
|
|
354 |
|
|
case IPSEC_IPCOMP_V42BIS: |
355 |
|
|
comp_alg = "v42bis"; |
356 |
|
|
break; |
357 |
|
|
} |
358 |
|
|
|
359 |
|
|
break; |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
for (attr = proto->chosen->p + |
363 |
|
|
ISAKMP_TRANSFORM_SA_ATTRS_OFF; |
364 |
|
|
attr < proto->chosen->p + |
365 |
|
|
GET_ISAKMP_GEN_LENGTH(proto->chosen->p); |
366 |
|
|
attr = value + len) { |
367 |
|
|
if (attr + ISAKMP_ATTR_VALUE_OFF > |
368 |
|
|
(proto->chosen->p + |
369 |
|
|
GET_ISAKMP_GEN_LENGTH(proto->chosen->p))) |
370 |
|
|
return ""; |
371 |
|
|
|
372 |
|
|
type = GET_ISAKMP_ATTR_TYPE(attr); |
373 |
|
|
fmt = ISAKMP_ATTR_FORMAT(type); |
374 |
|
|
type = ISAKMP_ATTR_TYPE(type); |
375 |
|
|
value = attr + (fmt ? |
376 |
|
|
ISAKMP_ATTR_LENGTH_VALUE_OFF : |
377 |
|
|
ISAKMP_ATTR_VALUE_OFF); |
378 |
|
|
len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN : |
379 |
|
|
GET_ISAKMP_ATTR_LENGTH_VALUE(attr)); |
380 |
|
|
|
381 |
|
|
if (value + len > proto->chosen->p + |
382 |
|
|
GET_ISAKMP_GEN_LENGTH(proto->chosen->p)) |
383 |
|
|
return ""; |
384 |
|
|
|
385 |
|
|
switch (type) { |
386 |
|
|
case IPSEC_ATTR_SA_LIFE_TYPE: |
387 |
|
|
lifetype = decode_16(value); |
388 |
|
|
break; |
389 |
|
|
|
390 |
|
|
case IPSEC_ATTR_SA_LIFE_DURATION: |
391 |
|
|
switch (proto->proto) { |
392 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
393 |
|
|
if (lifetype == IPSEC_DURATION_SECONDS) { |
394 |
|
|
if (len == 2) |
395 |
|
|
snprintf(ah_life_seconds, sizeof ah_life_seconds, |
396 |
|
|
"%u", decode_16(value)); |
397 |
|
|
else |
398 |
|
|
snprintf(ah_life_seconds, sizeof ah_life_seconds, |
399 |
|
|
"%u", decode_32(value)); |
400 |
|
|
} else { |
401 |
|
|
if (len == 2) |
402 |
|
|
snprintf(ah_life_kbytes, sizeof ah_life_kbytes, |
403 |
|
|
"%u", decode_16(value)); |
404 |
|
|
else |
405 |
|
|
snprintf(ah_life_kbytes, sizeof ah_life_kbytes, |
406 |
|
|
"%u", decode_32(value)); |
407 |
|
|
} |
408 |
|
|
|
409 |
|
|
break; |
410 |
|
|
|
411 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
412 |
|
|
if (lifetype == IPSEC_DURATION_SECONDS) { |
413 |
|
|
if (len == 2) |
414 |
|
|
snprintf(esp_life_seconds, |
415 |
|
|
sizeof esp_life_seconds, "%u", |
416 |
|
|
decode_16(value)); |
417 |
|
|
else |
418 |
|
|
snprintf(esp_life_seconds, |
419 |
|
|
sizeof esp_life_seconds, "%u", |
420 |
|
|
decode_32(value)); |
421 |
|
|
} else { |
422 |
|
|
if (len == 2) |
423 |
|
|
snprintf(esp_life_kbytes, |
424 |
|
|
sizeof esp_life_kbytes, "%u", |
425 |
|
|
decode_16(value)); |
426 |
|
|
else |
427 |
|
|
snprintf(esp_life_kbytes, |
428 |
|
|
sizeof esp_life_kbytes, "%u", |
429 |
|
|
decode_32(value)); |
430 |
|
|
} |
431 |
|
|
|
432 |
|
|
break; |
433 |
|
|
|
434 |
|
|
case IPSEC_PROTO_IPCOMP: |
435 |
|
|
if (lifetype == IPSEC_DURATION_SECONDS) { |
436 |
|
|
if (len == 2) |
437 |
|
|
snprintf(comp_life_seconds, |
438 |
|
|
sizeof comp_life_seconds, "%u", |
439 |
|
|
decode_16(value)); |
440 |
|
|
else |
441 |
|
|
snprintf(comp_life_seconds, |
442 |
|
|
sizeof comp_life_seconds, "%u", |
443 |
|
|
decode_32(value)); |
444 |
|
|
} else { |
445 |
|
|
if (len == 2) |
446 |
|
|
snprintf(comp_life_kbytes, |
447 |
|
|
sizeof comp_life_kbytes, "%u", |
448 |
|
|
decode_16(value)); |
449 |
|
|
else |
450 |
|
|
snprintf(comp_life_kbytes, |
451 |
|
|
sizeof comp_life_kbytes, "%u", |
452 |
|
|
decode_32(value)); |
453 |
|
|
} |
454 |
|
|
break; |
455 |
|
|
} |
456 |
|
|
break; |
457 |
|
|
|
458 |
|
|
case IPSEC_ATTR_GROUP_DESCRIPTION: |
459 |
|
|
switch (proto->proto) { |
460 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
461 |
|
|
snprintf(ah_group_desc, |
462 |
|
|
sizeof ah_group_desc, "%u", |
463 |
|
|
decode_16(value)); |
464 |
|
|
break; |
465 |
|
|
|
466 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
467 |
|
|
snprintf(esp_group_desc, |
468 |
|
|
sizeof esp_group_desc, "%u", |
469 |
|
|
decode_16(value)); |
470 |
|
|
break; |
471 |
|
|
|
472 |
|
|
case IPSEC_PROTO_IPCOMP: |
473 |
|
|
snprintf(comp_group_desc, |
474 |
|
|
sizeof comp_group_desc, "%u", |
475 |
|
|
decode_16(value)); |
476 |
|
|
break; |
477 |
|
|
} |
478 |
|
|
break; |
479 |
|
|
|
480 |
|
|
case IPSEC_ATTR_ECN_TUNNEL: |
481 |
|
|
if (decode_16(value)) |
482 |
|
|
switch (proto->proto) { |
483 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
484 |
|
|
ah_ecn = "yes"; |
485 |
|
|
break; |
486 |
|
|
|
487 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
488 |
|
|
esp_ecn = "yes"; |
489 |
|
|
break; |
490 |
|
|
|
491 |
|
|
case IPSEC_PROTO_IPCOMP: |
492 |
|
|
comp_ecn = "yes"; |
493 |
|
|
break; |
494 |
|
|
} |
495 |
|
|
|
496 |
|
|
case IPSEC_ATTR_ENCAPSULATION_MODE: |
497 |
|
|
if (decode_16(value) == IPSEC_ENCAP_TUNNEL) |
498 |
|
|
switch (proto->proto) { |
499 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
500 |
|
|
ah_encapsulation = "tunnel"; |
501 |
|
|
break; |
502 |
|
|
|
503 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
504 |
|
|
esp_encapsulation = "tunnel"; |
505 |
|
|
break; |
506 |
|
|
|
507 |
|
|
case IPSEC_PROTO_IPCOMP: |
508 |
|
|
comp_encapsulation = "tunnel"; |
509 |
|
|
break; |
510 |
|
|
} |
511 |
|
|
else if (decode_16(value) == |
512 |
|
|
IPSEC_ENCAP_UDP_ENCAP_TUNNEL || |
513 |
|
|
decode_16(value) == |
514 |
|
|
IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT) |
515 |
|
|
switch (proto->proto) { |
516 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
517 |
|
|
ah_encapsulation = "udp-encap-tunnel"; |
518 |
|
|
break; |
519 |
|
|
|
520 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
521 |
|
|
esp_encapsulation = "udp-encap-tunnel"; |
522 |
|
|
break; |
523 |
|
|
|
524 |
|
|
case IPSEC_PROTO_IPCOMP: |
525 |
|
|
comp_encapsulation = "udp-encap-tunnel"; |
526 |
|
|
break; |
527 |
|
|
} |
528 |
|
|
/* XXX IPSEC_ENCAP_UDP_ENCAP_TRANSPORT */ |
529 |
|
|
else |
530 |
|
|
switch (proto->proto) { |
531 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
532 |
|
|
ah_encapsulation = "transport"; |
533 |
|
|
break; |
534 |
|
|
|
535 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
536 |
|
|
esp_encapsulation = "transport"; |
537 |
|
|
break; |
538 |
|
|
|
539 |
|
|
case IPSEC_PROTO_IPCOMP: |
540 |
|
|
comp_encapsulation = "transport"; |
541 |
|
|
break; |
542 |
|
|
} |
543 |
|
|
break; |
544 |
|
|
|
545 |
|
|
case IPSEC_ATTR_AUTHENTICATION_ALGORITHM: |
546 |
|
|
switch (proto->proto) { |
547 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
548 |
|
|
switch (decode_16(value)) { |
549 |
|
|
case IPSEC_AUTH_HMAC_MD5: |
550 |
|
|
ah_auth_alg = "hmac-md5"; |
551 |
|
|
break; |
552 |
|
|
|
553 |
|
|
case IPSEC_AUTH_HMAC_SHA: |
554 |
|
|
ah_auth_alg = "hmac-sha"; |
555 |
|
|
break; |
556 |
|
|
|
557 |
|
|
case IPSEC_AUTH_HMAC_RIPEMD: |
558 |
|
|
ah_auth_alg = "hmac-ripemd"; |
559 |
|
|
break; |
560 |
|
|
|
561 |
|
|
case IPSEC_AUTH_HMAC_SHA2_256: |
562 |
|
|
ah_auth_alg = "hmac-sha2-256"; |
563 |
|
|
break; |
564 |
|
|
|
565 |
|
|
case IPSEC_AUTH_HMAC_SHA2_384: |
566 |
|
|
ah_auth_alg = "hmac-sha2-384"; |
567 |
|
|
break; |
568 |
|
|
|
569 |
|
|
case IPSEC_AUTH_HMAC_SHA2_512: |
570 |
|
|
ah_auth_alg = "hmac-sha2-512"; |
571 |
|
|
break; |
572 |
|
|
|
573 |
|
|
case IPSEC_AUTH_DES_MAC: |
574 |
|
|
ah_auth_alg = "des-mac"; |
575 |
|
|
break; |
576 |
|
|
|
577 |
|
|
case IPSEC_AUTH_KPDK: |
578 |
|
|
ah_auth_alg = "kpdk"; |
579 |
|
|
break; |
580 |
|
|
} |
581 |
|
|
break; |
582 |
|
|
|
583 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
584 |
|
|
switch (decode_16(value)) { |
585 |
|
|
case IPSEC_AUTH_HMAC_MD5: |
586 |
|
|
esp_auth_alg = "hmac-md5"; |
587 |
|
|
break; |
588 |
|
|
|
589 |
|
|
case IPSEC_AUTH_HMAC_SHA: |
590 |
|
|
esp_auth_alg = "hmac-sha"; |
591 |
|
|
break; |
592 |
|
|
|
593 |
|
|
case IPSEC_AUTH_HMAC_RIPEMD: |
594 |
|
|
esp_auth_alg = "hmac-ripemd"; |
595 |
|
|
break; |
596 |
|
|
|
597 |
|
|
case IPSEC_AUTH_HMAC_SHA2_256: |
598 |
|
|
esp_auth_alg = "hmac-sha2-256"; |
599 |
|
|
break; |
600 |
|
|
|
601 |
|
|
case IPSEC_AUTH_HMAC_SHA2_384: |
602 |
|
|
esp_auth_alg = "hmac-sha2-384"; |
603 |
|
|
break; |
604 |
|
|
|
605 |
|
|
case IPSEC_AUTH_HMAC_SHA2_512: |
606 |
|
|
esp_auth_alg = "hmac-sha2-512"; |
607 |
|
|
break; |
608 |
|
|
|
609 |
|
|
case IPSEC_AUTH_DES_MAC: |
610 |
|
|
esp_auth_alg = "des-mac"; |
611 |
|
|
break; |
612 |
|
|
|
613 |
|
|
case IPSEC_AUTH_KPDK: |
614 |
|
|
esp_auth_alg = "kpdk"; |
615 |
|
|
break; |
616 |
|
|
} |
617 |
|
|
break; |
618 |
|
|
} |
619 |
|
|
break; |
620 |
|
|
|
621 |
|
|
case IPSEC_ATTR_KEY_LENGTH: |
622 |
|
|
switch (proto->proto) { |
623 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
624 |
|
|
snprintf(ah_key_length, |
625 |
|
|
sizeof ah_key_length, "%u", |
626 |
|
|
decode_16(value)); |
627 |
|
|
break; |
628 |
|
|
|
629 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
630 |
|
|
snprintf(esp_key_length, |
631 |
|
|
sizeof esp_key_length, "%u", |
632 |
|
|
decode_16(value)); |
633 |
|
|
break; |
634 |
|
|
} |
635 |
|
|
break; |
636 |
|
|
|
637 |
|
|
case IPSEC_ATTR_KEY_ROUNDS: |
638 |
|
|
switch (proto->proto) { |
639 |
|
|
case IPSEC_PROTO_IPSEC_AH: |
640 |
|
|
snprintf(ah_key_rounds, |
641 |
|
|
sizeof ah_key_rounds, "%u", |
642 |
|
|
decode_16(value)); |
643 |
|
|
break; |
644 |
|
|
|
645 |
|
|
case IPSEC_PROTO_IPSEC_ESP: |
646 |
|
|
snprintf(esp_key_rounds, |
647 |
|
|
sizeof esp_key_rounds, "%u", |
648 |
|
|
decode_16(value)); |
649 |
|
|
break; |
650 |
|
|
} |
651 |
|
|
break; |
652 |
|
|
|
653 |
|
|
case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE: |
654 |
|
|
snprintf(comp_dict_size, |
655 |
|
|
sizeof comp_dict_size, "%u", |
656 |
|
|
decode_16(value)); |
657 |
|
|
break; |
658 |
|
|
|
659 |
|
|
case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM: |
660 |
|
|
snprintf(comp_private_alg, |
661 |
|
|
sizeof comp_private_alg, "%u", |
662 |
|
|
decode_16(value)); |
663 |
|
|
break; |
664 |
|
|
} |
665 |
|
|
} |
666 |
|
|
} |
667 |
|
|
|
668 |
|
|
policy_sa->transport->vtbl->get_src(policy_sa->transport, |
669 |
|
|
&sin); |
670 |
|
|
if (sockaddr2text(sin, &addr, 1)) { |
671 |
|
|
log_error("policy_callback: sockaddr2text failed"); |
672 |
|
|
goto bad; |
673 |
|
|
} |
674 |
|
|
strlcpy(local_ike_address, addr, sizeof local_ike_address); |
675 |
|
|
free(addr); |
676 |
|
|
|
677 |
|
|
policy_sa->transport->vtbl->get_dst(policy_sa->transport, |
678 |
|
|
&sin); |
679 |
|
|
if (sockaddr2text(sin, &addr, 1)) { |
680 |
|
|
log_error("policy_callback: sockaddr2text failed"); |
681 |
|
|
goto bad; |
682 |
|
|
} |
683 |
|
|
strlcpy(remote_ike_address, addr, sizeof remote_ike_address); |
684 |
|
|
free(addr); |
685 |
|
|
|
686 |
|
|
switch (policy_isakmp_sa->exch_type) { |
687 |
|
|
case ISAKMP_EXCH_AGGRESSIVE: |
688 |
|
|
phase_1 = "aggressive"; |
689 |
|
|
break; |
690 |
|
|
|
691 |
|
|
case ISAKMP_EXCH_ID_PROT: |
692 |
|
|
phase_1 = "main"; |
693 |
|
|
break; |
694 |
|
|
} |
695 |
|
|
|
696 |
|
|
if (policy_isakmp_sa->initiator) { |
697 |
|
|
id = policy_isakmp_sa->id_r; |
698 |
|
|
id_sz = policy_isakmp_sa->id_r_len; |
699 |
|
|
} else { |
700 |
|
|
id = policy_isakmp_sa->id_i; |
701 |
|
|
id_sz = policy_isakmp_sa->id_i_len; |
702 |
|
|
} |
703 |
|
|
|
704 |
|
|
switch (id[0]) { |
705 |
|
|
case IPSEC_ID_IPV4_ADDR: |
706 |
|
|
remote_id_type = "IPv4 address"; |
707 |
|
|
|
708 |
|
|
net = decode_32(id + ISAKMP_ID_DATA_OFF - |
709 |
|
|
ISAKMP_GEN_SZ); |
710 |
|
|
my_inet_ntop4(&net, remote_id_addr_upper, |
711 |
|
|
sizeof remote_id_addr_upper - 1, 1); |
712 |
|
|
my_inet_ntop4(&net, remote_id_addr_lower, |
713 |
|
|
sizeof remote_id_addr_lower - 1, 1); |
714 |
|
|
remote_id = strdup(remote_id_addr_upper); |
715 |
|
|
if (!remote_id) { |
716 |
|
|
log_error("policy_callback: " |
717 |
|
|
"strdup (\"%s\") failed", |
718 |
|
|
remote_id_addr_upper); |
719 |
|
|
goto bad; |
720 |
|
|
} |
721 |
|
|
break; |
722 |
|
|
|
723 |
|
|
case IPSEC_ID_IPV4_RANGE: |
724 |
|
|
remote_id_type = "IPv4 range"; |
725 |
|
|
|
726 |
|
|
net = decode_32(id + ISAKMP_ID_DATA_OFF - |
727 |
|
|
ISAKMP_GEN_SZ); |
728 |
|
|
my_inet_ntop4(&net, remote_id_addr_lower, |
729 |
|
|
sizeof remote_id_addr_lower - 1, 1); |
730 |
|
|
net = decode_32(id + ISAKMP_ID_DATA_OFF - |
731 |
|
|
ISAKMP_GEN_SZ + 4); |
732 |
|
|
my_inet_ntop4(&net, remote_id_addr_upper, |
733 |
|
|
sizeof remote_id_addr_upper - 1, 1); |
734 |
|
|
len = strlen(remote_id_addr_upper) + |
735 |
|
|
strlen(remote_id_addr_lower) + 2; |
736 |
|
|
remote_id = calloc(len, sizeof(char)); |
737 |
|
|
if (!remote_id) { |
738 |
|
|
log_error("policy_callback: " |
739 |
|
|
"calloc (%d, %lu) failed", len, |
740 |
|
|
(unsigned long)sizeof(char)); |
741 |
|
|
goto bad; |
742 |
|
|
} |
743 |
|
|
strlcpy(remote_id, remote_id_addr_lower, len); |
744 |
|
|
strlcat(remote_id, "-", len); |
745 |
|
|
strlcat(remote_id, remote_id_addr_upper, len); |
746 |
|
|
break; |
747 |
|
|
|
748 |
|
|
case IPSEC_ID_IPV4_ADDR_SUBNET: |
749 |
|
|
remote_id_type = "IPv4 subnet"; |
750 |
|
|
|
751 |
|
|
net = decode_32(id + ISAKMP_ID_DATA_OFF - |
752 |
|
|
ISAKMP_GEN_SZ); |
753 |
|
|
subnet = decode_32(id + ISAKMP_ID_DATA_OFF - |
754 |
|
|
ISAKMP_GEN_SZ + 4); |
755 |
|
|
net &= subnet; |
756 |
|
|
my_inet_ntop4(&net, remote_id_addr_lower, |
757 |
|
|
sizeof remote_id_addr_lower - 1, 1); |
758 |
|
|
net |= ~subnet; |
759 |
|
|
my_inet_ntop4(&net, remote_id_addr_upper, |
760 |
|
|
sizeof remote_id_addr_upper - 1, 1); |
761 |
|
|
len = strlen(remote_id_addr_upper) + |
762 |
|
|
strlen(remote_id_addr_lower) + 2; |
763 |
|
|
remote_id = calloc(len, sizeof(char)); |
764 |
|
|
if (!remote_id) { |
765 |
|
|
log_error("policy_callback: " |
766 |
|
|
"calloc (%d, %lu) failed", len, |
767 |
|
|
(unsigned long)sizeof(char)); |
768 |
|
|
goto bad; |
769 |
|
|
} |
770 |
|
|
strlcpy(remote_id, remote_id_addr_lower, len); |
771 |
|
|
strlcat(remote_id, "-", len); |
772 |
|
|
strlcat(remote_id, remote_id_addr_upper, len); |
773 |
|
|
break; |
774 |
|
|
|
775 |
|
|
case IPSEC_ID_IPV6_ADDR: |
776 |
|
|
remote_id_type = "IPv6 address"; |
777 |
|
|
my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, |
778 |
|
|
remote_id_addr_upper, sizeof remote_id_addr_upper); |
779 |
|
|
strlcpy(remote_id_addr_lower, remote_id_addr_upper, |
780 |
|
|
sizeof remote_id_addr_lower); |
781 |
|
|
remote_id = strdup(remote_id_addr_upper); |
782 |
|
|
if (!remote_id) { |
783 |
|
|
log_error("policy_callback: " |
784 |
|
|
"strdup (\"%s\") failed", |
785 |
|
|
remote_id_addr_upper); |
786 |
|
|
goto bad; |
787 |
|
|
} |
788 |
|
|
break; |
789 |
|
|
|
790 |
|
|
case IPSEC_ID_IPV6_RANGE: |
791 |
|
|
remote_id_type = "IPv6 range"; |
792 |
|
|
|
793 |
|
|
my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, |
794 |
|
|
remote_id_addr_lower, |
795 |
|
|
sizeof remote_id_addr_lower - 1); |
796 |
|
|
|
797 |
|
|
my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - |
798 |
|
|
ISAKMP_GEN_SZ + 16, remote_id_addr_upper, |
799 |
|
|
sizeof remote_id_addr_upper - 1); |
800 |
|
|
|
801 |
|
|
len = strlen(remote_id_addr_upper) + |
802 |
|
|
strlen(remote_id_addr_lower) + 2; |
803 |
|
|
remote_id = calloc(len, sizeof(char)); |
804 |
|
|
if (!remote_id) { |
805 |
|
|
log_error("policy_callback: " |
806 |
|
|
"calloc (%d, %lu) failed", len, |
807 |
|
|
(unsigned long)sizeof(char)); |
808 |
|
|
goto bad; |
809 |
|
|
} |
810 |
|
|
strlcpy(remote_id, remote_id_addr_lower, len); |
811 |
|
|
strlcat(remote_id, "-", len); |
812 |
|
|
strlcat(remote_id, remote_id_addr_upper, len); |
813 |
|
|
break; |
814 |
|
|
|
815 |
|
|
case IPSEC_ID_IPV6_ADDR_SUBNET: |
816 |
|
|
{ |
817 |
|
|
struct in6_addr net, mask; |
818 |
|
|
|
819 |
|
|
remote_id_type = "IPv6 subnet"; |
820 |
|
|
|
821 |
|
|
bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, &net, |
822 |
|
|
sizeof(net)); |
823 |
|
|
bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16, |
824 |
|
|
&mask, sizeof(mask)); |
825 |
|
|
|
826 |
|
|
for (i = 0; i < 16; i++) |
827 |
|
|
net.s6_addr[i] &= mask.s6_addr[i]; |
828 |
|
|
|
829 |
|
|
my_inet_ntop6((unsigned char *)&net, |
830 |
|
|
remote_id_addr_lower, |
831 |
|
|
sizeof remote_id_addr_lower - 1); |
832 |
|
|
|
833 |
|
|
for (i = 0; i < 16; i++) |
834 |
|
|
net.s6_addr[i] |= ~mask.s6_addr[i]; |
835 |
|
|
|
836 |
|
|
my_inet_ntop6((unsigned char *)&net, |
837 |
|
|
remote_id_addr_upper, |
838 |
|
|
sizeof remote_id_addr_upper - 1); |
839 |
|
|
|
840 |
|
|
len = strlen(remote_id_addr_upper) + |
841 |
|
|
strlen(remote_id_addr_lower) + 2; |
842 |
|
|
remote_id = calloc(len, sizeof(char)); |
843 |
|
|
if (!remote_id) { |
844 |
|
|
log_error("policy_callback: " |
845 |
|
|
"calloc (%d, %lu) failed", len, |
846 |
|
|
(unsigned long)sizeof(char)); |
847 |
|
|
goto bad; |
848 |
|
|
} |
849 |
|
|
strlcpy(remote_id, remote_id_addr_lower, len); |
850 |
|
|
strlcat(remote_id, "-", len); |
851 |
|
|
strlcat(remote_id, remote_id_addr_upper, len); |
852 |
|
|
break; |
853 |
|
|
} |
854 |
|
|
|
855 |
|
|
case IPSEC_ID_FQDN: |
856 |
|
|
remote_id_type = "FQDN"; |
857 |
|
|
remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF + |
858 |
|
|
ISAKMP_GEN_SZ + 1, sizeof(char)); |
859 |
|
|
if (!remote_id) { |
860 |
|
|
log_error("policy_callback: " |
861 |
|
|
"calloc (%lu, %lu) failed", |
862 |
|
|
(unsigned long)id_sz - ISAKMP_ID_DATA_OFF + |
863 |
|
|
ISAKMP_GEN_SZ + 1, |
864 |
|
|
(unsigned long)sizeof(char)); |
865 |
|
|
goto bad; |
866 |
|
|
} |
867 |
|
|
memcpy(remote_id, |
868 |
|
|
id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, |
869 |
|
|
id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ); |
870 |
|
|
break; |
871 |
|
|
|
872 |
|
|
case IPSEC_ID_USER_FQDN: |
873 |
|
|
remote_id_type = "User FQDN"; |
874 |
|
|
remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF + |
875 |
|
|
ISAKMP_GEN_SZ + 1, sizeof(char)); |
876 |
|
|
if (!remote_id) { |
877 |
|
|
log_error("policy_callback: " |
878 |
|
|
"calloc (%lu, %lu) failed", |
879 |
|
|
(unsigned long)id_sz - ISAKMP_ID_DATA_OFF + |
880 |
|
|
ISAKMP_GEN_SZ + 1, |
881 |
|
|
(unsigned long)sizeof(char)); |
882 |
|
|
goto bad; |
883 |
|
|
} |
884 |
|
|
memcpy(remote_id, |
885 |
|
|
id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, |
886 |
|
|
id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ); |
887 |
|
|
break; |
888 |
|
|
|
889 |
|
|
case IPSEC_ID_DER_ASN1_DN: |
890 |
|
|
remote_id_type = "ASN1 DN"; |
891 |
|
|
|
892 |
|
|
remote_id = x509_DN_string(id + ISAKMP_ID_DATA_OFF - |
893 |
|
|
ISAKMP_GEN_SZ, |
894 |
|
|
id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ); |
895 |
|
|
if (!remote_id) { |
896 |
|
|
LOG_DBG((LOG_POLICY, 50, |
897 |
|
|
"policy_callback: failed to decode name")); |
898 |
|
|
goto bad; |
899 |
|
|
} |
900 |
|
|
break; |
901 |
|
|
|
902 |
|
|
case IPSEC_ID_DER_ASN1_GN: /* XXX */ |
903 |
|
|
remote_id_type = "ASN1 GN"; |
904 |
|
|
break; |
905 |
|
|
|
906 |
|
|
case IPSEC_ID_KEY_ID: |
907 |
|
|
remote_id_type = "Key ID"; |
908 |
|
|
remote_id = calloc(2 * (id_sz - ISAKMP_ID_DATA_OFF + |
909 |
|
|
ISAKMP_GEN_SZ) + 1, sizeof(char)); |
910 |
|
|
if (!remote_id) { |
911 |
|
|
log_error("policy_callback: " |
912 |
|
|
"calloc (%lu, %lu) failed", |
913 |
|
|
2 * ((unsigned long)id_sz - |
914 |
|
|
ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1, |
915 |
|
|
(unsigned long)sizeof(char)); |
916 |
|
|
goto bad; |
917 |
|
|
} |
918 |
|
|
/* Does it contain any non-printable characters ? */ |
919 |
|
|
for (i = 0; |
920 |
|
|
i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; |
921 |
|
|
i++) |
922 |
|
|
if (!isprint((unsigned char)*(id + ISAKMP_ID_DATA_OFF - |
923 |
|
|
ISAKMP_GEN_SZ + i))) |
924 |
|
|
break; |
925 |
|
|
if (i >= id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) { |
926 |
|
|
memcpy(remote_id, id + ISAKMP_ID_DATA_OFF - |
927 |
|
|
ISAKMP_GEN_SZ, |
928 |
|
|
id_sz - ISAKMP_ID_DATA_OFF + |
929 |
|
|
ISAKMP_GEN_SZ); |
930 |
|
|
break; |
931 |
|
|
} |
932 |
|
|
/* Non-printable characters, convert to hex */ |
933 |
|
|
for (i = 0; |
934 |
|
|
i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; |
935 |
|
|
i++) { |
936 |
|
|
remote_id[2 * i] = hextab[*(id + |
937 |
|
|
ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4]; |
938 |
|
|
remote_id[2 * i + 1] = hextab[*(id + |
939 |
|
|
ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF]; |
940 |
|
|
} |
941 |
|
|
break; |
942 |
|
|
|
943 |
|
|
default: |
944 |
|
|
log_print("policy_callback: " |
945 |
|
|
"unknown remote ID type %u", id[0]); |
946 |
|
|
goto bad; |
947 |
|
|
} |
948 |
|
|
|
949 |
|
|
switch (id[1]) { |
950 |
|
|
case IPPROTO_TCP: |
951 |
|
|
remote_id_proto = "tcp"; |
952 |
|
|
break; |
953 |
|
|
|
954 |
|
|
case IPPROTO_UDP: |
955 |
|
|
remote_id_proto = "udp"; |
956 |
|
|
break; |
957 |
|
|
|
958 |
|
|
case IPPROTO_ETHERIP: |
959 |
|
|
remote_id_proto = "etherip"; |
960 |
|
|
break; |
961 |
|
|
|
962 |
|
|
default: |
963 |
|
|
snprintf(remote_id_proto_num, |
964 |
|
|
sizeof remote_id_proto_num, "%d", |
965 |
|
|
id[1]); |
966 |
|
|
remote_id_proto = remote_id_proto_num; |
967 |
|
|
break; |
968 |
|
|
} |
969 |
|
|
|
970 |
|
|
snprintf(remote_id_port, sizeof remote_id_port, "%u", |
971 |
|
|
decode_16(id + 2)); |
972 |
|
|
|
973 |
|
|
if (policy_exchange->initiator) { |
974 |
|
|
initiator = "yes"; |
975 |
|
|
idlocal = ie->id_ci; |
976 |
|
|
idremote = ie->id_cr; |
977 |
|
|
idlocalsz = ie->id_ci_sz; |
978 |
|
|
idremotesz = ie->id_cr_sz; |
979 |
|
|
} else { |
980 |
|
|
initiator = "no"; |
981 |
|
|
idlocal = ie->id_cr; |
982 |
|
|
idremote = ie->id_ci; |
983 |
|
|
idlocalsz = ie->id_cr_sz; |
984 |
|
|
idremotesz = ie->id_ci_sz; |
985 |
|
|
} |
986 |
|
|
|
987 |
|
|
/* Initialize the ID variables. */ |
988 |
|
|
if (idremote) { |
989 |
|
|
switch (GET_ISAKMP_ID_TYPE(idremote)) { |
990 |
|
|
case IPSEC_ID_IPV4_ADDR: |
991 |
|
|
remote_filter_type = "IPv4 address"; |
992 |
|
|
|
993 |
|
|
net = decode_32(idremote + ISAKMP_ID_DATA_OFF); |
994 |
|
|
my_inet_ntop4(&net, remote_filter_addr_upper, |
995 |
|
|
sizeof remote_filter_addr_upper - 1, 1); |
996 |
|
|
my_inet_ntop4(&net, remote_filter_addr_lower, |
997 |
|
|
sizeof remote_filter_addr_lower - 1, 1); |
998 |
|
|
remote_filter = |
999 |
|
|
strdup(remote_filter_addr_upper); |
1000 |
|
|
if (!remote_filter) { |
1001 |
|
|
log_error("policy_callback: strdup " |
1002 |
|
|
"(\"%s\") failed", |
1003 |
|
|
remote_filter_addr_upper); |
1004 |
|
|
goto bad; |
1005 |
|
|
} |
1006 |
|
|
break; |
1007 |
|
|
|
1008 |
|
|
case IPSEC_ID_IPV4_RANGE: |
1009 |
|
|
remote_filter_type = "IPv4 range"; |
1010 |
|
|
|
1011 |
|
|
net = decode_32(idremote + ISAKMP_ID_DATA_OFF); |
1012 |
|
|
my_inet_ntop4(&net, remote_filter_addr_lower, |
1013 |
|
|
sizeof remote_filter_addr_lower - 1, 1); |
1014 |
|
|
net = decode_32(idremote + ISAKMP_ID_DATA_OFF + |
1015 |
|
|
4); |
1016 |
|
|
my_inet_ntop4(&net, remote_filter_addr_upper, |
1017 |
|
|
sizeof remote_filter_addr_upper - 1, 1); |
1018 |
|
|
len = strlen(remote_filter_addr_upper) + |
1019 |
|
|
strlen(remote_filter_addr_lower) + 2; |
1020 |
|
|
remote_filter = calloc(len, sizeof(char)); |
1021 |
|
|
if (!remote_filter) { |
1022 |
|
|
log_error("policy_callback: calloc " |
1023 |
|
|
"(%d, %lu) failed", len, |
1024 |
|
|
(unsigned long)sizeof(char)); |
1025 |
|
|
goto bad; |
1026 |
|
|
} |
1027 |
|
|
strlcpy(remote_filter, |
1028 |
|
|
remote_filter_addr_lower, len); |
1029 |
|
|
strlcat(remote_filter, "-", len); |
1030 |
|
|
strlcat(remote_filter, |
1031 |
|
|
remote_filter_addr_upper, len); |
1032 |
|
|
break; |
1033 |
|
|
|
1034 |
|
|
case IPSEC_ID_IPV4_ADDR_SUBNET: |
1035 |
|
|
remote_filter_type = "IPv4 subnet"; |
1036 |
|
|
|
1037 |
|
|
net = decode_32(idremote + ISAKMP_ID_DATA_OFF); |
1038 |
|
|
subnet = decode_32(idremote + |
1039 |
|
|
ISAKMP_ID_DATA_OFF + 4); |
1040 |
|
|
net &= subnet; |
1041 |
|
|
my_inet_ntop4(&net, remote_filter_addr_lower, |
1042 |
|
|
sizeof remote_filter_addr_lower - 1, 1); |
1043 |
|
|
net |= ~subnet; |
1044 |
|
|
my_inet_ntop4(&net, remote_filter_addr_upper, |
1045 |
|
|
sizeof remote_filter_addr_upper - 1, 1); |
1046 |
|
|
len = strlen(remote_filter_addr_upper) + |
1047 |
|
|
strlen(remote_filter_addr_lower) + 2; |
1048 |
|
|
remote_filter = calloc(len, sizeof(char)); |
1049 |
|
|
if (!remote_filter) { |
1050 |
|
|
log_error("policy_callback: calloc " |
1051 |
|
|
"(%d, %lu) failed", len, |
1052 |
|
|
(unsigned long)sizeof(char)); |
1053 |
|
|
goto bad; |
1054 |
|
|
} |
1055 |
|
|
strlcpy(remote_filter, |
1056 |
|
|
remote_filter_addr_lower, len); |
1057 |
|
|
strlcat(remote_filter, "-", len); |
1058 |
|
|
strlcat(remote_filter, |
1059 |
|
|
remote_filter_addr_upper, len); |
1060 |
|
|
break; |
1061 |
|
|
|
1062 |
|
|
case IPSEC_ID_IPV6_ADDR: |
1063 |
|
|
remote_filter_type = "IPv6 address"; |
1064 |
|
|
my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF, |
1065 |
|
|
remote_filter_addr_upper, |
1066 |
|
|
sizeof remote_filter_addr_upper - 1); |
1067 |
|
|
strlcpy(remote_filter_addr_lower, |
1068 |
|
|
remote_filter_addr_upper, |
1069 |
|
|
sizeof remote_filter_addr_lower); |
1070 |
|
|
remote_filter = |
1071 |
|
|
strdup(remote_filter_addr_upper); |
1072 |
|
|
if (!remote_filter) { |
1073 |
|
|
log_error("policy_callback: strdup " |
1074 |
|
|
"(\"%s\") failed", |
1075 |
|
|
remote_filter_addr_upper); |
1076 |
|
|
goto bad; |
1077 |
|
|
} |
1078 |
|
|
break; |
1079 |
|
|
|
1080 |
|
|
case IPSEC_ID_IPV6_RANGE: |
1081 |
|
|
remote_filter_type = "IPv6 range"; |
1082 |
|
|
|
1083 |
|
|
my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF, |
1084 |
|
|
remote_filter_addr_lower, |
1085 |
|
|
sizeof remote_filter_addr_lower - 1); |
1086 |
|
|
|
1087 |
|
|
my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF + |
1088 |
|
|
16, remote_filter_addr_upper, |
1089 |
|
|
sizeof remote_filter_addr_upper - 1); |
1090 |
|
|
|
1091 |
|
|
len = strlen(remote_filter_addr_upper) + |
1092 |
|
|
strlen(remote_filter_addr_lower) + 2; |
1093 |
|
|
remote_filter = calloc(len, sizeof(char)); |
1094 |
|
|
if (!remote_filter) { |
1095 |
|
|
log_error("policy_callback: calloc " |
1096 |
|
|
"(%d, %lu) failed", len, |
1097 |
|
|
(unsigned long)sizeof(char)); |
1098 |
|
|
goto bad; |
1099 |
|
|
} |
1100 |
|
|
strlcpy(remote_filter, |
1101 |
|
|
remote_filter_addr_lower, len); |
1102 |
|
|
strlcat(remote_filter, "-", len); |
1103 |
|
|
strlcat(remote_filter, |
1104 |
|
|
remote_filter_addr_upper, len); |
1105 |
|
|
break; |
1106 |
|
|
|
1107 |
|
|
case IPSEC_ID_IPV6_ADDR_SUBNET: |
1108 |
|
|
{ |
1109 |
|
|
struct in6_addr net, mask; |
1110 |
|
|
|
1111 |
|
|
remote_filter_type = "IPv6 subnet"; |
1112 |
|
|
|
1113 |
|
|
bcopy(idremote + ISAKMP_ID_DATA_OFF, |
1114 |
|
|
&net, sizeof(net)); |
1115 |
|
|
bcopy(idremote + ISAKMP_ID_DATA_OFF + |
1116 |
|
|
16, &mask, sizeof(mask)); |
1117 |
|
|
|
1118 |
|
|
for (i = 0; i < 16; i++) |
1119 |
|
|
net.s6_addr[i] &= |
1120 |
|
|
mask.s6_addr[i]; |
1121 |
|
|
|
1122 |
|
|
my_inet_ntop6((unsigned char *)&net, |
1123 |
|
|
remote_filter_addr_lower, |
1124 |
|
|
sizeof remote_filter_addr_lower - 1); |
1125 |
|
|
|
1126 |
|
|
for (i = 0; i < 16; i++) |
1127 |
|
|
net.s6_addr[i] |= |
1128 |
|
|
~mask.s6_addr[i]; |
1129 |
|
|
|
1130 |
|
|
my_inet_ntop6((unsigned char *)&net, |
1131 |
|
|
remote_filter_addr_upper, |
1132 |
|
|
sizeof remote_filter_addr_upper - 1); |
1133 |
|
|
|
1134 |
|
|
len = strlen(remote_filter_addr_upper) |
1135 |
|
|
+ strlen(remote_filter_addr_lower) + 2; |
1136 |
|
|
remote_filter = calloc(len, |
1137 |
|
|
sizeof(char)); |
1138 |
|
|
if (!remote_filter) { |
1139 |
|
|
log_error("policy_callback: " |
1140 |
|
|
"calloc (%d, %lu) failed", |
1141 |
|
|
len, |
1142 |
|
|
(unsigned long)sizeof(char)); |
1143 |
|
|
goto bad; |
1144 |
|
|
} |
1145 |
|
|
strlcpy(remote_filter, |
1146 |
|
|
remote_filter_addr_lower, len); |
1147 |
|
|
strlcat(remote_filter, "-", len); |
1148 |
|
|
strlcat(remote_filter, |
1149 |
|
|
remote_filter_addr_upper, len); |
1150 |
|
|
break; |
1151 |
|
|
} |
1152 |
|
|
|
1153 |
|
|
case IPSEC_ID_FQDN: |
1154 |
|
|
remote_filter_type = "FQDN"; |
1155 |
|
|
remote_filter = malloc(idremotesz - |
1156 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1157 |
|
|
if (!remote_filter) { |
1158 |
|
|
log_error("policy_callback: " |
1159 |
|
|
"malloc (%lu) failed", |
1160 |
|
|
(unsigned long)idremotesz - |
1161 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1162 |
|
|
goto bad; |
1163 |
|
|
} |
1164 |
|
|
memcpy(remote_filter, |
1165 |
|
|
idremote + ISAKMP_ID_DATA_OFF, |
1166 |
|
|
idremotesz - ISAKMP_ID_DATA_OFF); |
1167 |
|
|
remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] |
1168 |
|
|
= '\0'; |
1169 |
|
|
break; |
1170 |
|
|
|
1171 |
|
|
case IPSEC_ID_USER_FQDN: |
1172 |
|
|
remote_filter_type = "User FQDN"; |
1173 |
|
|
remote_filter = malloc(idremotesz - |
1174 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1175 |
|
|
if (!remote_filter) { |
1176 |
|
|
log_error("policy_callback: " |
1177 |
|
|
"malloc (%lu) failed", |
1178 |
|
|
(unsigned long)idremotesz - |
1179 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1180 |
|
|
goto bad; |
1181 |
|
|
} |
1182 |
|
|
memcpy(remote_filter, |
1183 |
|
|
idremote + ISAKMP_ID_DATA_OFF, |
1184 |
|
|
idremotesz - ISAKMP_ID_DATA_OFF); |
1185 |
|
|
remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] |
1186 |
|
|
= '\0'; |
1187 |
|
|
break; |
1188 |
|
|
|
1189 |
|
|
case IPSEC_ID_DER_ASN1_DN: |
1190 |
|
|
remote_filter_type = "ASN1 DN"; |
1191 |
|
|
|
1192 |
|
|
remote_filter = x509_DN_string(idremote + |
1193 |
|
|
ISAKMP_ID_DATA_OFF, |
1194 |
|
|
idremotesz - ISAKMP_ID_DATA_OFF); |
1195 |
|
|
if (!remote_filter) { |
1196 |
|
|
LOG_DBG((LOG_POLICY, 50, |
1197 |
|
|
"policy_callback: " |
1198 |
|
|
"failed to decode name")); |
1199 |
|
|
goto bad; |
1200 |
|
|
} |
1201 |
|
|
break; |
1202 |
|
|
|
1203 |
|
|
case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure |
1204 |
|
|
* what's in this. */ |
1205 |
|
|
remote_filter_type = "ASN1 GN"; |
1206 |
|
|
break; |
1207 |
|
|
|
1208 |
|
|
case IPSEC_ID_KEY_ID: |
1209 |
|
|
remote_filter_type = "Key ID"; |
1210 |
|
|
remote_filter |
1211 |
|
|
= calloc(2 * (idremotesz - |
1212 |
|
|
ISAKMP_ID_DATA_OFF) + 1, |
1213 |
|
|
sizeof(char)); |
1214 |
|
|
if (!remote_filter) { |
1215 |
|
|
log_error("policy_callback: " |
1216 |
|
|
"calloc (%lu, %lu) failed", |
1217 |
|
|
2 * ((unsigned long)idremotesz - |
1218 |
|
|
ISAKMP_ID_DATA_OFF) + 1, |
1219 |
|
|
(unsigned long)sizeof(char)); |
1220 |
|
|
goto bad; |
1221 |
|
|
} |
1222 |
|
|
/* |
1223 |
|
|
* Does it contain any non-printable |
1224 |
|
|
* characters ? |
1225 |
|
|
*/ |
1226 |
|
|
for (i = 0; |
1227 |
|
|
i < idremotesz - ISAKMP_ID_DATA_OFF; i++) |
1228 |
|
|
if (!isprint((unsigned char)*(idremote + |
1229 |
|
|
ISAKMP_ID_DATA_OFF + i))) |
1230 |
|
|
break; |
1231 |
|
|
if (i >= idremotesz - ISAKMP_ID_DATA_OFF) { |
1232 |
|
|
memcpy(remote_filter, |
1233 |
|
|
idremote + ISAKMP_ID_DATA_OFF, |
1234 |
|
|
idremotesz - ISAKMP_ID_DATA_OFF); |
1235 |
|
|
break; |
1236 |
|
|
} |
1237 |
|
|
/* Non-printable characters, convert to hex */ |
1238 |
|
|
for (i = 0; |
1239 |
|
|
i < idremotesz - ISAKMP_ID_DATA_OFF; |
1240 |
|
|
i++) { |
1241 |
|
|
remote_filter[2 * i] |
1242 |
|
|
= hextab[*(idremote + |
1243 |
|
|
ISAKMP_ID_DATA_OFF) >> 4]; |
1244 |
|
|
remote_filter[2 * i + 1] |
1245 |
|
|
= hextab[*(idremote + |
1246 |
|
|
ISAKMP_ID_DATA_OFF) & 0xF]; |
1247 |
|
|
} |
1248 |
|
|
break; |
1249 |
|
|
|
1250 |
|
|
default: |
1251 |
|
|
log_print("policy_callback: " |
1252 |
|
|
"unknown Remote ID type %u", |
1253 |
|
|
GET_ISAKMP_ID_TYPE(idremote)); |
1254 |
|
|
goto bad; |
1255 |
|
|
} |
1256 |
|
|
|
1257 |
|
|
switch (idremote[ISAKMP_GEN_SZ + 1]) { |
1258 |
|
|
case IPPROTO_TCP: |
1259 |
|
|
remote_filter_proto = "tcp"; |
1260 |
|
|
break; |
1261 |
|
|
|
1262 |
|
|
case IPPROTO_UDP: |
1263 |
|
|
remote_filter_proto = "udp"; |
1264 |
|
|
break; |
1265 |
|
|
|
1266 |
|
|
case IPPROTO_ETHERIP: |
1267 |
|
|
remote_filter_proto = "etherip"; |
1268 |
|
|
break; |
1269 |
|
|
|
1270 |
|
|
default: |
1271 |
|
|
snprintf(remote_filter_proto_num, |
1272 |
|
|
sizeof remote_filter_proto_num, "%d", |
1273 |
|
|
idremote[ISAKMP_GEN_SZ + 1]); |
1274 |
|
|
remote_filter_proto = remote_filter_proto_num; |
1275 |
|
|
break; |
1276 |
|
|
} |
1277 |
|
|
|
1278 |
|
|
snprintf(remote_filter_port, sizeof remote_filter_port, |
1279 |
|
|
"%u", decode_16(idremote + ISAKMP_GEN_SZ + 2)); |
1280 |
|
|
} else { |
1281 |
|
|
policy_sa->transport->vtbl->get_dst(policy_sa->transport, &sin); |
1282 |
|
|
switch (sin->sa_family) { |
1283 |
|
|
case AF_INET: |
1284 |
|
|
remote_filter_type = "IPv4 address"; |
1285 |
|
|
break; |
1286 |
|
|
case AF_INET6: |
1287 |
|
|
remote_filter_type = "IPv6 address"; |
1288 |
|
|
break; |
1289 |
|
|
default: |
1290 |
|
|
log_print("policy_callback: " |
1291 |
|
|
"unsupported protocol family %d", |
1292 |
|
|
sin->sa_family); |
1293 |
|
|
goto bad; |
1294 |
|
|
} |
1295 |
|
|
if (sockaddr2text(sin, &addr, 1)) { |
1296 |
|
|
log_error("policy_callback: " |
1297 |
|
|
"sockaddr2text failed"); |
1298 |
|
|
goto bad; |
1299 |
|
|
} |
1300 |
|
|
memcpy(remote_filter_addr_upper, addr, |
1301 |
|
|
sizeof remote_filter_addr_upper); |
1302 |
|
|
memcpy(remote_filter_addr_lower, addr, |
1303 |
|
|
sizeof remote_filter_addr_lower); |
1304 |
|
|
free(addr); |
1305 |
|
|
remote_filter = strdup(remote_filter_addr_upper); |
1306 |
|
|
if (!remote_filter) { |
1307 |
|
|
log_error("policy_callback: " |
1308 |
|
|
"strdup (\"%s\") failed", |
1309 |
|
|
remote_filter_addr_upper); |
1310 |
|
|
goto bad; |
1311 |
|
|
} |
1312 |
|
|
} |
1313 |
|
|
|
1314 |
|
|
if (idlocal) { |
1315 |
|
|
switch (GET_ISAKMP_ID_TYPE(idlocal)) { |
1316 |
|
|
case IPSEC_ID_IPV4_ADDR: |
1317 |
|
|
local_filter_type = "IPv4 address"; |
1318 |
|
|
|
1319 |
|
|
net = decode_32(idlocal + ISAKMP_ID_DATA_OFF); |
1320 |
|
|
my_inet_ntop4(&net, local_filter_addr_upper, |
1321 |
|
|
sizeof local_filter_addr_upper - 1, 1); |
1322 |
|
|
my_inet_ntop4(&net, local_filter_addr_lower, |
1323 |
|
|
sizeof local_filter_addr_upper - 1, 1); |
1324 |
|
|
local_filter = strdup(local_filter_addr_upper); |
1325 |
|
|
if (!local_filter) { |
1326 |
|
|
log_error("policy_callback: " |
1327 |
|
|
"strdup (\"%s\") failed", |
1328 |
|
|
local_filter_addr_upper); |
1329 |
|
|
goto bad; |
1330 |
|
|
} |
1331 |
|
|
break; |
1332 |
|
|
|
1333 |
|
|
case IPSEC_ID_IPV4_RANGE: |
1334 |
|
|
local_filter_type = "IPv4 range"; |
1335 |
|
|
|
1336 |
|
|
net = decode_32(idlocal + ISAKMP_ID_DATA_OFF); |
1337 |
|
|
my_inet_ntop4(&net, local_filter_addr_lower, |
1338 |
|
|
sizeof local_filter_addr_lower - 1, 1); |
1339 |
|
|
net = decode_32(idlocal + ISAKMP_ID_DATA_OFF + |
1340 |
|
|
4); |
1341 |
|
|
my_inet_ntop4(&net, local_filter_addr_upper, |
1342 |
|
|
sizeof local_filter_addr_upper - 1, 1); |
1343 |
|
|
len = strlen(local_filter_addr_upper) |
1344 |
|
|
+ strlen(local_filter_addr_lower) + 2; |
1345 |
|
|
local_filter = calloc(len, sizeof(char)); |
1346 |
|
|
if (!local_filter) { |
1347 |
|
|
log_error("policy_callback: " |
1348 |
|
|
"calloc (%d, %lu) failed", len, |
1349 |
|
|
(unsigned long)sizeof(char)); |
1350 |
|
|
goto bad; |
1351 |
|
|
} |
1352 |
|
|
strlcpy(local_filter, local_filter_addr_lower, |
1353 |
|
|
len); |
1354 |
|
|
strlcat(local_filter, "-", len); |
1355 |
|
|
strlcat(local_filter, local_filter_addr_upper, |
1356 |
|
|
len); |
1357 |
|
|
break; |
1358 |
|
|
|
1359 |
|
|
case IPSEC_ID_IPV4_ADDR_SUBNET: |
1360 |
|
|
local_filter_type = "IPv4 subnet"; |
1361 |
|
|
|
1362 |
|
|
net = decode_32(idlocal + ISAKMP_ID_DATA_OFF); |
1363 |
|
|
subnet = decode_32(idlocal + |
1364 |
|
|
ISAKMP_ID_DATA_OFF + 4); |
1365 |
|
|
net &= subnet; |
1366 |
|
|
my_inet_ntop4(&net, local_filter_addr_lower, |
1367 |
|
|
sizeof local_filter_addr_lower - 1, 1); |
1368 |
|
|
net |= ~subnet; |
1369 |
|
|
my_inet_ntop4(&net, local_filter_addr_upper, |
1370 |
|
|
sizeof local_filter_addr_upper - 1, 1); |
1371 |
|
|
len = strlen(local_filter_addr_upper) + |
1372 |
|
|
strlen(local_filter_addr_lower) + 2; |
1373 |
|
|
local_filter = calloc(len, sizeof(char)); |
1374 |
|
|
if (!local_filter) { |
1375 |
|
|
log_error("policy_callback: " |
1376 |
|
|
"calloc (%d, %lu) failed", len, |
1377 |
|
|
(unsigned long)sizeof(char)); |
1378 |
|
|
goto bad; |
1379 |
|
|
} |
1380 |
|
|
strlcpy(local_filter, local_filter_addr_lower, |
1381 |
|
|
len); |
1382 |
|
|
strlcat(local_filter, "-", len); |
1383 |
|
|
strlcat(local_filter, local_filter_addr_upper, |
1384 |
|
|
len); |
1385 |
|
|
break; |
1386 |
|
|
|
1387 |
|
|
case IPSEC_ID_IPV6_ADDR: |
1388 |
|
|
local_filter_type = "IPv6 address"; |
1389 |
|
|
my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF, |
1390 |
|
|
local_filter_addr_upper, |
1391 |
|
|
sizeof local_filter_addr_upper - 1); |
1392 |
|
|
strlcpy(local_filter_addr_lower, |
1393 |
|
|
local_filter_addr_upper, |
1394 |
|
|
sizeof local_filter_addr_lower); |
1395 |
|
|
local_filter = strdup(local_filter_addr_upper); |
1396 |
|
|
if (!local_filter) { |
1397 |
|
|
log_error("policy_callback: " |
1398 |
|
|
"strdup (\"%s\") failed", |
1399 |
|
|
local_filter_addr_upper); |
1400 |
|
|
goto bad; |
1401 |
|
|
} |
1402 |
|
|
break; |
1403 |
|
|
|
1404 |
|
|
case IPSEC_ID_IPV6_RANGE: |
1405 |
|
|
local_filter_type = "IPv6 range"; |
1406 |
|
|
|
1407 |
|
|
my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF, |
1408 |
|
|
local_filter_addr_lower, |
1409 |
|
|
sizeof local_filter_addr_lower - 1); |
1410 |
|
|
|
1411 |
|
|
my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF + |
1412 |
|
|
16, local_filter_addr_upper, |
1413 |
|
|
sizeof local_filter_addr_upper - 1); |
1414 |
|
|
|
1415 |
|
|
len = strlen(local_filter_addr_upper) |
1416 |
|
|
+ strlen(local_filter_addr_lower) + 2; |
1417 |
|
|
local_filter = calloc(len, sizeof(char)); |
1418 |
|
|
if (!local_filter) { |
1419 |
|
|
log_error("policy_callback: " |
1420 |
|
|
"calloc (%d, %lu) failed", len, |
1421 |
|
|
(unsigned long)sizeof(char)); |
1422 |
|
|
goto bad; |
1423 |
|
|
} |
1424 |
|
|
strlcpy(local_filter, local_filter_addr_lower, |
1425 |
|
|
len); |
1426 |
|
|
strlcat(local_filter, "-", len); |
1427 |
|
|
strlcat(local_filter, local_filter_addr_upper, |
1428 |
|
|
len); |
1429 |
|
|
break; |
1430 |
|
|
|
1431 |
|
|
case IPSEC_ID_IPV6_ADDR_SUBNET: |
1432 |
|
|
{ |
1433 |
|
|
struct in6_addr net, mask; |
1434 |
|
|
|
1435 |
|
|
local_filter_type = "IPv6 subnet"; |
1436 |
|
|
|
1437 |
|
|
bcopy(idlocal + ISAKMP_ID_DATA_OFF, |
1438 |
|
|
&net, sizeof(net)); |
1439 |
|
|
bcopy(idlocal + ISAKMP_ID_DATA_OFF + |
1440 |
|
|
16, &mask, sizeof(mask)); |
1441 |
|
|
|
1442 |
|
|
for (i = 0; i < 16; i++) |
1443 |
|
|
net.s6_addr[i] &= |
1444 |
|
|
mask.s6_addr[i]; |
1445 |
|
|
|
1446 |
|
|
my_inet_ntop6((unsigned char *)&net, |
1447 |
|
|
local_filter_addr_lower, |
1448 |
|
|
sizeof local_filter_addr_lower - 1); |
1449 |
|
|
|
1450 |
|
|
for (i = 0; i < 16; i++) |
1451 |
|
|
net.s6_addr[i] |= |
1452 |
|
|
~mask.s6_addr[i]; |
1453 |
|
|
|
1454 |
|
|
my_inet_ntop6((unsigned char *)&net, |
1455 |
|
|
local_filter_addr_upper, |
1456 |
|
|
sizeof local_filter_addr_upper - |
1457 |
|
|
1); |
1458 |
|
|
|
1459 |
|
|
len = strlen(local_filter_addr_upper) |
1460 |
|
|
+ strlen(local_filter_addr_lower) |
1461 |
|
|
+ 2; |
1462 |
|
|
local_filter = calloc(len, |
1463 |
|
|
sizeof(char)); |
1464 |
|
|
if (!local_filter) { |
1465 |
|
|
log_error("policy_callback: " |
1466 |
|
|
"calloc (%d, %lu) failed", |
1467 |
|
|
len, |
1468 |
|
|
(unsigned long)sizeof(char)); |
1469 |
|
|
goto bad; |
1470 |
|
|
} |
1471 |
|
|
strlcpy(local_filter, |
1472 |
|
|
local_filter_addr_lower, len); |
1473 |
|
|
strlcat(local_filter, "-", len); |
1474 |
|
|
strlcat(local_filter, |
1475 |
|
|
local_filter_addr_upper, len); |
1476 |
|
|
break; |
1477 |
|
|
} |
1478 |
|
|
|
1479 |
|
|
case IPSEC_ID_FQDN: |
1480 |
|
|
local_filter_type = "FQDN"; |
1481 |
|
|
local_filter = malloc(idlocalsz - |
1482 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1483 |
|
|
if (!local_filter) { |
1484 |
|
|
log_error("policy_callback: " |
1485 |
|
|
"malloc (%lu) failed", |
1486 |
|
|
(unsigned long)idlocalsz - |
1487 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1488 |
|
|
goto bad; |
1489 |
|
|
} |
1490 |
|
|
memcpy(local_filter, |
1491 |
|
|
idlocal + ISAKMP_ID_DATA_OFF, |
1492 |
|
|
idlocalsz - ISAKMP_ID_DATA_OFF); |
1493 |
|
|
local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0'; |
1494 |
|
|
break; |
1495 |
|
|
|
1496 |
|
|
case IPSEC_ID_USER_FQDN: |
1497 |
|
|
local_filter_type = "User FQDN"; |
1498 |
|
|
local_filter = malloc(idlocalsz - |
1499 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1500 |
|
|
if (!local_filter) { |
1501 |
|
|
log_error("policy_callback: " |
1502 |
|
|
"malloc (%lu) failed", |
1503 |
|
|
(unsigned long)idlocalsz - |
1504 |
|
|
ISAKMP_ID_DATA_OFF + 1); |
1505 |
|
|
goto bad; |
1506 |
|
|
} |
1507 |
|
|
memcpy(local_filter, |
1508 |
|
|
idlocal + ISAKMP_ID_DATA_OFF, |
1509 |
|
|
idlocalsz - ISAKMP_ID_DATA_OFF); |
1510 |
|
|
local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0'; |
1511 |
|
|
break; |
1512 |
|
|
|
1513 |
|
|
case IPSEC_ID_DER_ASN1_DN: |
1514 |
|
|
local_filter_type = "ASN1 DN"; |
1515 |
|
|
|
1516 |
|
|
local_filter = x509_DN_string(idlocal + |
1517 |
|
|
ISAKMP_ID_DATA_OFF, |
1518 |
|
|
idlocalsz - ISAKMP_ID_DATA_OFF); |
1519 |
|
|
if (!local_filter) { |
1520 |
|
|
LOG_DBG((LOG_POLICY, 50, |
1521 |
|
|
"policy_callback: failed to decode" |
1522 |
|
|
" name")); |
1523 |
|
|
goto bad; |
1524 |
|
|
} |
1525 |
|
|
break; |
1526 |
|
|
|
1527 |
|
|
case IPSEC_ID_DER_ASN1_GN: |
1528 |
|
|
/* XXX -- not sure what's in this. */ |
1529 |
|
|
local_filter_type = "ASN1 GN"; |
1530 |
|
|
break; |
1531 |
|
|
|
1532 |
|
|
case IPSEC_ID_KEY_ID: |
1533 |
|
|
local_filter_type = "Key ID"; |
1534 |
|
|
local_filter = calloc(2 * (idlocalsz - |
1535 |
|
|
ISAKMP_ID_DATA_OFF) + 1, |
1536 |
|
|
sizeof(char)); |
1537 |
|
|
if (!local_filter) { |
1538 |
|
|
log_error("policy_callback: " |
1539 |
|
|
"calloc (%lu, %lu) failed", |
1540 |
|
|
2 * ((unsigned long)idlocalsz - |
1541 |
|
|
ISAKMP_ID_DATA_OFF) + 1, |
1542 |
|
|
(unsigned long)sizeof(char)); |
1543 |
|
|
goto bad; |
1544 |
|
|
} |
1545 |
|
|
/* |
1546 |
|
|
* Does it contain any non-printable |
1547 |
|
|
* characters ? |
1548 |
|
|
*/ |
1549 |
|
|
for (i = 0; |
1550 |
|
|
i < idlocalsz - ISAKMP_ID_DATA_OFF; i++) |
1551 |
|
|
if (!isprint((unsigned char)*(idlocal + |
1552 |
|
|
ISAKMP_ID_DATA_OFF + i))) |
1553 |
|
|
break; |
1554 |
|
|
if (i >= idlocalsz - ISAKMP_ID_DATA_OFF) { |
1555 |
|
|
memcpy(local_filter, idlocal + |
1556 |
|
|
ISAKMP_ID_DATA_OFF, |
1557 |
|
|
idlocalsz - ISAKMP_ID_DATA_OFF); |
1558 |
|
|
break; |
1559 |
|
|
} |
1560 |
|
|
/* Non-printable characters, convert to hex */ |
1561 |
|
|
for (i = 0; |
1562 |
|
|
i < idlocalsz - ISAKMP_ID_DATA_OFF; i++) { |
1563 |
|
|
local_filter[2 * i] = |
1564 |
|
|
hextab[*(idlocal + |
1565 |
|
|
ISAKMP_ID_DATA_OFF) >> 4]; |
1566 |
|
|
local_filter[2 * i + 1] = |
1567 |
|
|
hextab[*(idlocal + |
1568 |
|
|
ISAKMP_ID_DATA_OFF) & 0xF]; |
1569 |
|
|
} |
1570 |
|
|
break; |
1571 |
|
|
|
1572 |
|
|
default: |
1573 |
|
|
log_print("policy_callback: " |
1574 |
|
|
"unknown Local ID type %u", |
1575 |
|
|
GET_ISAKMP_ID_TYPE(idlocal)); |
1576 |
|
|
goto bad; |
1577 |
|
|
} |
1578 |
|
|
|
1579 |
|
|
switch (idlocal[ISAKMP_GEN_SZ + 1]) { |
1580 |
|
|
case IPPROTO_TCP: |
1581 |
|
|
local_filter_proto = "tcp"; |
1582 |
|
|
break; |
1583 |
|
|
|
1584 |
|
|
case IPPROTO_UDP: |
1585 |
|
|
local_filter_proto = "udp"; |
1586 |
|
|
break; |
1587 |
|
|
|
1588 |
|
|
case IPPROTO_ETHERIP: |
1589 |
|
|
local_filter_proto = "etherip"; |
1590 |
|
|
break; |
1591 |
|
|
|
1592 |
|
|
default: |
1593 |
|
|
snprintf(local_filter_proto_num, |
1594 |
|
|
sizeof local_filter_proto_num, |
1595 |
|
|
"%d", idlocal[ISAKMP_GEN_SZ + 1]); |
1596 |
|
|
local_filter_proto = local_filter_proto_num; |
1597 |
|
|
break; |
1598 |
|
|
} |
1599 |
|
|
|
1600 |
|
|
snprintf(local_filter_port, sizeof local_filter_port, |
1601 |
|
|
"%u", decode_16(idlocal + ISAKMP_GEN_SZ + 2)); |
1602 |
|
|
} else { |
1603 |
|
|
policy_sa->transport->vtbl->get_src(policy_sa->transport, |
1604 |
|
|
(struct sockaddr **)&sin); |
1605 |
|
|
switch (sin->sa_family) { |
1606 |
|
|
case AF_INET: |
1607 |
|
|
local_filter_type = "IPv4 address"; |
1608 |
|
|
break; |
1609 |
|
|
case AF_INET6: |
1610 |
|
|
local_filter_type = "IPv6 address"; |
1611 |
|
|
break; |
1612 |
|
|
default: |
1613 |
|
|
log_print("policy_callback: " |
1614 |
|
|
"unsupported protocol family %d", |
1615 |
|
|
sin->sa_family); |
1616 |
|
|
goto bad; |
1617 |
|
|
} |
1618 |
|
|
|
1619 |
|
|
if (sockaddr2text(sin, &addr, 1)) { |
1620 |
|
|
log_error("policy_callback: " |
1621 |
|
|
"sockaddr2text failed"); |
1622 |
|
|
goto bad; |
1623 |
|
|
} |
1624 |
|
|
memcpy(local_filter_addr_upper, addr, |
1625 |
|
|
sizeof local_filter_addr_upper); |
1626 |
|
|
memcpy(local_filter_addr_lower, addr, |
1627 |
|
|
sizeof local_filter_addr_lower); |
1628 |
|
|
free(addr); |
1629 |
|
|
local_filter = strdup(local_filter_addr_upper); |
1630 |
|
|
if (!local_filter) { |
1631 |
|
|
log_error("policy_callback: " |
1632 |
|
|
"strdup (\"%s\") failed", |
1633 |
|
|
local_filter_addr_upper); |
1634 |
|
|
goto bad; |
1635 |
|
|
} |
1636 |
|
|
} |
1637 |
|
|
|
1638 |
|
|
LOG_DBG((LOG_POLICY, 80, |
1639 |
|
|
"Policy context (action attributes):")); |
1640 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_present == %s", esp_present)); |
1641 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_present == %s", ah_present)); |
1642 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_present == %s", comp_present)); |
1643 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg)); |
1644 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg)); |
1645 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_alg == %s", comp_alg)); |
1646 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg)); |
1647 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg)); |
1648 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_life_seconds == %s", |
1649 |
|
|
ah_life_seconds)); |
1650 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_life_kbytes == %s", |
1651 |
|
|
ah_life_kbytes)); |
1652 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_life_seconds == %s", |
1653 |
|
|
esp_life_seconds)); |
1654 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_life_kbytes == %s", |
1655 |
|
|
esp_life_kbytes)); |
1656 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_life_seconds == %s", |
1657 |
|
|
comp_life_seconds)); |
1658 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_life_kbytes == %s", |
1659 |
|
|
comp_life_kbytes)); |
1660 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_encapsulation == %s", |
1661 |
|
|
ah_encapsulation)); |
1662 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_encapsulation == %s", |
1663 |
|
|
esp_encapsulation)); |
1664 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_encapsulation == %s", |
1665 |
|
|
comp_encapsulation)); |
1666 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_dict_size == %s", |
1667 |
|
|
comp_dict_size)); |
1668 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_private_alg == %s", |
1669 |
|
|
comp_private_alg)); |
1670 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_key_length == %s", |
1671 |
|
|
ah_key_length)); |
1672 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_key_rounds == %s", |
1673 |
|
|
ah_key_rounds)); |
1674 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_key_length == %s", |
1675 |
|
|
esp_key_length)); |
1676 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_key_rounds == %s", |
1677 |
|
|
esp_key_rounds)); |
1678 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_group_desc == %s", |
1679 |
|
|
ah_group_desc)); |
1680 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_group_desc == %s", |
1681 |
|
|
esp_group_desc)); |
1682 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_group_desc == %s", |
1683 |
|
|
comp_group_desc)); |
1684 |
|
|
LOG_DBG((LOG_POLICY, 80, "ah_ecn == %s", ah_ecn)); |
1685 |
|
|
LOG_DBG((LOG_POLICY, 80, "esp_ecn == %s", esp_ecn)); |
1686 |
|
|
LOG_DBG((LOG_POLICY, 80, "comp_ecn == %s", comp_ecn)); |
1687 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter_type == %s", |
1688 |
|
|
remote_filter_type)); |
1689 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_upper == %s", |
1690 |
|
|
remote_filter_addr_upper)); |
1691 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_lower == %s", |
1692 |
|
|
remote_filter_addr_lower)); |
1693 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter == %s", |
1694 |
|
|
(remote_filter ? remote_filter : ""))); |
1695 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter_port == %s", |
1696 |
|
|
remote_filter_port)); |
1697 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_filter_proto == %s", |
1698 |
|
|
remote_filter_proto)); |
1699 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter_type == %s", |
1700 |
|
|
local_filter_type)); |
1701 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter_addr_upper == %s", |
1702 |
|
|
local_filter_addr_upper)); |
1703 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter_addr_lower == %s", |
1704 |
|
|
local_filter_addr_lower)); |
1705 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter == %s", |
1706 |
|
|
(local_filter ? local_filter : ""))); |
1707 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter_port == %s", |
1708 |
|
|
local_filter_port)); |
1709 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_filter_proto == %s", |
1710 |
|
|
local_filter_proto)); |
1711 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id_type == %s", |
1712 |
|
|
remote_id_type)); |
1713 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id_addr_upper == %s", |
1714 |
|
|
remote_id_addr_upper)); |
1715 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id_addr_lower == %s", |
1716 |
|
|
remote_id_addr_lower)); |
1717 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id == %s", |
1718 |
|
|
(remote_id ? remote_id : ""))); |
1719 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id_port == %s", |
1720 |
|
|
remote_id_port)); |
1721 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_id_proto == %s", |
1722 |
|
|
remote_id_proto)); |
1723 |
|
|
LOG_DBG((LOG_POLICY, 80, "remote_negotiation_address == %s", |
1724 |
|
|
remote_ike_address)); |
1725 |
|
|
LOG_DBG((LOG_POLICY, 80, "local_negotiation_address == %s", |
1726 |
|
|
local_ike_address)); |
1727 |
|
|
LOG_DBG((LOG_POLICY, 80, "pfs == %s", pfs)); |
1728 |
|
|
LOG_DBG((LOG_POLICY, 80, "initiator == %s", initiator)); |
1729 |
|
|
LOG_DBG((LOG_POLICY, 80, "phase1_group_desc == %s", |
1730 |
|
|
phase1_group)); |
1731 |
|
|
|
1732 |
|
|
/* Unset dirty now. */ |
1733 |
|
|
dirty = 0; |
1734 |
|
|
} |
1735 |
|
|
if (strcmp(name, "phase_1") == 0) |
1736 |
|
|
return phase_1; |
1737 |
|
|
|
1738 |
|
|
if (strcmp(name, "GMTTimeOfDay") == 0) { |
1739 |
|
|
tt = time(NULL); |
1740 |
|
|
strftime(mytimeofday, 14, "%Y%m%d%H%M%S", gmtime(&tt)); |
1741 |
|
|
return mytimeofday; |
1742 |
|
|
} |
1743 |
|
|
if (strcmp(name, "LocalTimeOfDay") == 0) { |
1744 |
|
|
tt = time(NULL); |
1745 |
|
|
strftime(mytimeofday, 14, "%Y%m%d%H%M%S", localtime(&tt)); |
1746 |
|
|
return mytimeofday; |
1747 |
|
|
} |
1748 |
|
|
if (strcmp(name, "initiator") == 0) |
1749 |
|
|
return initiator; |
1750 |
|
|
|
1751 |
|
|
if (strcmp(name, "pfs") == 0) |
1752 |
|
|
return pfs; |
1753 |
|
|
|
1754 |
|
|
if (strcmp(name, "app_domain") == 0) |
1755 |
|
|
return "IPsec policy"; |
1756 |
|
|
|
1757 |
|
|
if (strcmp(name, "doi") == 0) |
1758 |
|
|
return "ipsec"; |
1759 |
|
|
|
1760 |
|
|
if (strcmp(name, "esp_present") == 0) |
1761 |
|
|
return esp_present; |
1762 |
|
|
|
1763 |
|
|
if (strcmp(name, "ah_present") == 0) |
1764 |
|
|
return ah_present; |
1765 |
|
|
|
1766 |
|
|
if (strcmp(name, "comp_present") == 0) |
1767 |
|
|
return comp_present; |
1768 |
|
|
|
1769 |
|
|
if (strcmp(name, "ah_hash_alg") == 0) |
1770 |
|
|
return ah_hash_alg; |
1771 |
|
|
|
1772 |
|
|
if (strcmp(name, "ah_auth_alg") == 0) |
1773 |
|
|
return ah_auth_alg; |
1774 |
|
|
|
1775 |
|
|
if (strcmp(name, "esp_auth_alg") == 0) |
1776 |
|
|
return esp_auth_alg; |
1777 |
|
|
|
1778 |
|
|
if (strcmp(name, "esp_enc_alg") == 0) |
1779 |
|
|
return esp_enc_alg; |
1780 |
|
|
|
1781 |
|
|
if (strcmp(name, "comp_alg") == 0) |
1782 |
|
|
return comp_alg; |
1783 |
|
|
|
1784 |
|
|
if (strcmp(name, "ah_life_kbytes") == 0) |
1785 |
|
|
return ah_life_kbytes; |
1786 |
|
|
|
1787 |
|
|
if (strcmp(name, "ah_life_seconds") == 0) |
1788 |
|
|
return ah_life_seconds; |
1789 |
|
|
|
1790 |
|
|
if (strcmp(name, "esp_life_kbytes") == 0) |
1791 |
|
|
return esp_life_kbytes; |
1792 |
|
|
|
1793 |
|
|
if (strcmp(name, "esp_life_seconds") == 0) |
1794 |
|
|
return esp_life_seconds; |
1795 |
|
|
|
1796 |
|
|
if (strcmp(name, "comp_life_kbytes") == 0) |
1797 |
|
|
return comp_life_kbytes; |
1798 |
|
|
|
1799 |
|
|
if (strcmp(name, "comp_life_seconds") == 0) |
1800 |
|
|
return comp_life_seconds; |
1801 |
|
|
|
1802 |
|
|
if (strcmp(name, "ah_encapsulation") == 0) |
1803 |
|
|
return ah_encapsulation; |
1804 |
|
|
|
1805 |
|
|
if (strcmp(name, "esp_encapsulation") == 0) |
1806 |
|
|
return esp_encapsulation; |
1807 |
|
|
|
1808 |
|
|
if (strcmp(name, "comp_encapsulation") == 0) |
1809 |
|
|
return comp_encapsulation; |
1810 |
|
|
|
1811 |
|
|
if (strcmp(name, "ah_key_length") == 0) |
1812 |
|
|
return ah_key_length; |
1813 |
|
|
|
1814 |
|
|
if (strcmp(name, "ah_key_rounds") == 0) |
1815 |
|
|
return ah_key_rounds; |
1816 |
|
|
|
1817 |
|
|
if (strcmp(name, "esp_key_length") == 0) |
1818 |
|
|
return esp_key_length; |
1819 |
|
|
|
1820 |
|
|
if (strcmp(name, "esp_key_rounds") == 0) |
1821 |
|
|
return esp_key_rounds; |
1822 |
|
|
|
1823 |
|
|
if (strcmp(name, "comp_dict_size") == 0) |
1824 |
|
|
return comp_dict_size; |
1825 |
|
|
|
1826 |
|
|
if (strcmp(name, "comp_private_alg") == 0) |
1827 |
|
|
return comp_private_alg; |
1828 |
|
|
|
1829 |
|
|
if (strcmp(name, "remote_filter_type") == 0) |
1830 |
|
|
return remote_filter_type; |
1831 |
|
|
|
1832 |
|
|
if (strcmp(name, "remote_filter") == 0) |
1833 |
|
|
return (remote_filter ? remote_filter : ""); |
1834 |
|
|
|
1835 |
|
|
if (strcmp(name, "remote_filter_addr_upper") == 0) |
1836 |
|
|
return remote_filter_addr_upper; |
1837 |
|
|
|
1838 |
|
|
if (strcmp(name, "remote_filter_addr_lower") == 0) |
1839 |
|
|
return remote_filter_addr_lower; |
1840 |
|
|
|
1841 |
|
|
if (strcmp(name, "remote_filter_port") == 0) |
1842 |
|
|
return remote_filter_port; |
1843 |
|
|
|
1844 |
|
|
if (strcmp(name, "remote_filter_proto") == 0) |
1845 |
|
|
return remote_filter_proto; |
1846 |
|
|
|
1847 |
|
|
if (strcmp(name, "local_filter_type") == 0) |
1848 |
|
|
return local_filter_type; |
1849 |
|
|
|
1850 |
|
|
if (strcmp(name, "local_filter") == 0) |
1851 |
|
|
return (local_filter ? local_filter : ""); |
1852 |
|
|
|
1853 |
|
|
if (strcmp(name, "local_filter_addr_upper") == 0) |
1854 |
|
|
return local_filter_addr_upper; |
1855 |
|
|
|
1856 |
|
|
if (strcmp(name, "local_filter_addr_lower") == 0) |
1857 |
|
|
return local_filter_addr_lower; |
1858 |
|
|
|
1859 |
|
|
if (strcmp(name, "local_filter_port") == 0) |
1860 |
|
|
return local_filter_port; |
1861 |
|
|
|
1862 |
|
|
if (strcmp(name, "local_filter_proto") == 0) |
1863 |
|
|
return local_filter_proto; |
1864 |
|
|
|
1865 |
|
|
if (strcmp(name, "remote_ike_address") == 0) |
1866 |
|
|
return remote_ike_address; |
1867 |
|
|
|
1868 |
|
|
if (strcmp(name, "remote_negotiation_address") == 0) |
1869 |
|
|
return remote_ike_address; |
1870 |
|
|
|
1871 |
|
|
if (strcmp(name, "local_ike_address") == 0) |
1872 |
|
|
return local_ike_address; |
1873 |
|
|
|
1874 |
|
|
if (strcmp(name, "local_negotiation_address") == 0) |
1875 |
|
|
return local_ike_address; |
1876 |
|
|
|
1877 |
|
|
if (strcmp(name, "remote_id_type") == 0) |
1878 |
|
|
return remote_id_type; |
1879 |
|
|
|
1880 |
|
|
if (strcmp(name, "remote_id") == 0) |
1881 |
|
|
return (remote_id ? remote_id : ""); |
1882 |
|
|
|
1883 |
|
|
if (strcmp(name, "remote_id_addr_upper") == 0) |
1884 |
|
|
return remote_id_addr_upper; |
1885 |
|
|
|
1886 |
|
|
if (strcmp(name, "remote_id_addr_lower") == 0) |
1887 |
|
|
return remote_id_addr_lower; |
1888 |
|
|
|
1889 |
|
|
if (strcmp(name, "remote_id_port") == 0) |
1890 |
|
|
return remote_id_port; |
1891 |
|
|
|
1892 |
|
|
if (strcmp(name, "remote_id_proto") == 0) |
1893 |
|
|
return remote_id_proto; |
1894 |
|
|
|
1895 |
|
|
if (strcmp(name, "phase1_group_desc") == 0) |
1896 |
|
|
return phase1_group; |
1897 |
|
|
|
1898 |
|
|
if (strcmp(name, "esp_group_desc") == 0) |
1899 |
|
|
return esp_group_desc; |
1900 |
|
|
|
1901 |
|
|
if (strcmp(name, "ah_group_desc") == 0) |
1902 |
|
|
return ah_group_desc; |
1903 |
|
|
|
1904 |
|
|
if (strcmp(name, "comp_group_desc") == 0) |
1905 |
|
|
return comp_group_desc; |
1906 |
|
|
|
1907 |
|
|
if (strcmp(name, "comp_ecn") == 0) |
1908 |
|
|
return comp_ecn; |
1909 |
|
|
|
1910 |
|
|
if (strcmp(name, "ah_ecn") == 0) |
1911 |
|
|
return ah_ecn; |
1912 |
|
|
|
1913 |
|
|
if (strcmp(name, "esp_ecn") == 0) |
1914 |
|
|
return esp_ecn; |
1915 |
|
|
|
1916 |
|
|
return ""; |
1917 |
|
|
|
1918 |
|
|
bad: |
1919 |
|
|
policy_callback(KEYNOTE_CALLBACK_INITIALIZE); |
1920 |
|
|
return ""; |
1921 |
|
|
} |
1922 |
|
|
|
1923 |
|
|
void |
1924 |
|
|
policy_init(void) |
1925 |
|
|
{ |
1926 |
|
|
char *ptr, *policy_file; |
1927 |
|
|
char **asserts; |
1928 |
|
|
size_t sz, len; |
1929 |
|
|
int fd, i; |
1930 |
|
|
|
1931 |
|
|
LOG_DBG((LOG_POLICY, 30, "policy_init: initializing")); |
1932 |
|
|
|
1933 |
|
|
/* Do we want to use the policy modules? */ |
1934 |
|
|
if (ignore_policy || |
1935 |
|
|
strncmp("yes", conf_get_str("General", "Use-Keynote"), 3)) |
1936 |
|
|
return; |
1937 |
|
|
|
1938 |
|
|
/* Get policy file from configuration. */ |
1939 |
|
|
policy_file = conf_get_str("General", "Policy-file"); |
1940 |
|
|
if (!policy_file) |
1941 |
|
|
policy_file = CONF_DFLT_POLICY_FILE; |
1942 |
|
|
|
1943 |
|
|
/* Open policy file. */ |
1944 |
|
|
fd = monitor_open(policy_file, O_RDONLY, 0); |
1945 |
|
|
if (fd == -1) |
1946 |
|
|
log_fatal("policy_init: open (\"%s\", O_RDONLY) failed", |
1947 |
|
|
policy_file); |
1948 |
|
|
|
1949 |
|
|
/* Check file modes and collect file size */ |
1950 |
|
|
if (check_file_secrecy_fd(fd, policy_file, &sz)) { |
1951 |
|
|
close(fd); |
1952 |
|
|
log_fatal("policy_init: cannot read %s", policy_file); |
1953 |
|
|
} |
1954 |
|
|
|
1955 |
|
|
/* Allocate memory to keep policies. */ |
1956 |
|
|
ptr = calloc(sz + 1, sizeof(char)); |
1957 |
|
|
if (!ptr) |
1958 |
|
|
log_fatal("policy_init: calloc (%lu, %lu) failed", |
1959 |
|
|
(unsigned long)sz + 1, (unsigned long)sizeof(char)); |
1960 |
|
|
|
1961 |
|
|
/* Just in case there are short reads... */ |
1962 |
|
|
for (len = 0; len < sz; len += i) { |
1963 |
|
|
i = read(fd, ptr + len, sz - len); |
1964 |
|
|
if (i == -1) |
1965 |
|
|
log_fatal("policy_init: read (%d, %p, %lu) failed", fd, |
1966 |
|
|
ptr + len, (unsigned long)(sz - len)); |
1967 |
|
|
} |
1968 |
|
|
|
1969 |
|
|
/* We're done with this. */ |
1970 |
|
|
close(fd); |
1971 |
|
|
|
1972 |
|
|
/* Parse buffer, break up into individual policies. */ |
1973 |
|
|
asserts = kn_read_asserts(ptr, sz, &i); |
1974 |
|
|
|
1975 |
|
|
/* Begone! */ |
1976 |
|
|
free(ptr); |
1977 |
|
|
|
1978 |
|
|
if (asserts == (char **)NULL) |
1979 |
|
|
log_print("policy_init: all policies flushed"); |
1980 |
|
|
|
1981 |
|
|
/* Cleanup */ |
1982 |
|
|
if (policy_asserts) { |
1983 |
|
|
for (fd = 0; fd < policy_asserts_num; fd++) |
1984 |
|
|
if (policy_asserts) |
1985 |
|
|
free(policy_asserts[fd]); |
1986 |
|
|
|
1987 |
|
|
free(policy_asserts); |
1988 |
|
|
} |
1989 |
|
|
policy_asserts = asserts; |
1990 |
|
|
policy_asserts_num = i; |
1991 |
|
|
} |
1992 |
|
|
|
1993 |
|
|
/* Nothing needed for initialization */ |
1994 |
|
|
int |
1995 |
|
|
keynote_cert_init(void) |
1996 |
|
|
{ |
1997 |
|
|
return 1; |
1998 |
|
|
} |
1999 |
|
|
|
2000 |
|
|
/* Just copy and return. */ |
2001 |
|
|
void * |
2002 |
|
|
keynote_cert_get(u_int8_t *data, u_int32_t len) |
2003 |
|
|
{ |
2004 |
|
|
char *foo = malloc(len + 1); |
2005 |
|
|
|
2006 |
|
|
if (foo == NULL) |
2007 |
|
|
return NULL; |
2008 |
|
|
|
2009 |
|
|
memcpy(foo, data, len); |
2010 |
|
|
foo[len] = '\0'; |
2011 |
|
|
return foo; |
2012 |
|
|
} |
2013 |
|
|
|
2014 |
|
|
/* |
2015 |
|
|
* We just verify the signature on the credentials. |
2016 |
|
|
* On signature failure, just drop the whole payload. |
2017 |
|
|
*/ |
2018 |
|
|
int |
2019 |
|
|
keynote_cert_validate(void *scert) |
2020 |
|
|
{ |
2021 |
|
|
char **foo; |
2022 |
|
|
int num, i; |
2023 |
|
|
|
2024 |
|
|
if (scert == NULL) |
2025 |
|
|
return 0; |
2026 |
|
|
|
2027 |
|
|
foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num); |
2028 |
|
|
if (foo == NULL) |
2029 |
|
|
return 0; |
2030 |
|
|
|
2031 |
|
|
for (i = 0; i < num; i++) { |
2032 |
|
|
if (kn_verify_assertion(scert, strlen((char *)scert)) |
2033 |
|
|
!= SIGRESULT_TRUE) { |
2034 |
|
|
for (; i < num; i++) |
2035 |
|
|
free(foo[i]); |
2036 |
|
|
free(foo); |
2037 |
|
|
return 0; |
2038 |
|
|
} |
2039 |
|
|
free(foo[i]); |
2040 |
|
|
} |
2041 |
|
|
|
2042 |
|
|
free(foo); |
2043 |
|
|
return 1; |
2044 |
|
|
} |
2045 |
|
|
|
2046 |
|
|
/* Add received credentials. */ |
2047 |
|
|
int |
2048 |
|
|
keynote_cert_insert(int sid, void *scert) |
2049 |
|
|
{ |
2050 |
|
|
char **foo; |
2051 |
|
|
int num; |
2052 |
|
|
|
2053 |
|
|
if (scert == NULL) |
2054 |
|
|
return 0; |
2055 |
|
|
|
2056 |
|
|
foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num); |
2057 |
|
|
if (foo == NULL) |
2058 |
|
|
return 0; |
2059 |
|
|
|
2060 |
|
|
while (num--) |
2061 |
|
|
kn_add_assertion(sid, foo[num], strlen(foo[num]), 0); |
2062 |
|
|
|
2063 |
|
|
return 1; |
2064 |
|
|
} |
2065 |
|
|
|
2066 |
|
|
/* Just regular memory free. */ |
2067 |
|
|
void |
2068 |
|
|
keynote_cert_free(void *cert) |
2069 |
|
|
{ |
2070 |
|
|
free(cert); |
2071 |
|
|
} |
2072 |
|
|
|
2073 |
|
|
/* Verify that the key given to us is valid. */ |
2074 |
|
|
int |
2075 |
|
|
keynote_certreq_validate(u_int8_t *data, u_int32_t len) |
2076 |
|
|
{ |
2077 |
|
|
struct keynote_deckey dc; |
2078 |
|
|
int err = 1; |
2079 |
|
|
char *dat; |
2080 |
|
|
|
2081 |
|
|
dat = calloc(len + 1, sizeof(char)); |
2082 |
|
|
if (!dat) { |
2083 |
|
|
log_error("keynote_certreq_validate: calloc (%d, %lu) failed", |
2084 |
|
|
len + 1, (unsigned long)sizeof(char)); |
2085 |
|
|
return 0; |
2086 |
|
|
} |
2087 |
|
|
memcpy(dat, data, len); |
2088 |
|
|
|
2089 |
|
|
if (kn_decode_key(&dc, dat, KEYNOTE_PUBLIC_KEY) != 0) |
2090 |
|
|
err = 0; |
2091 |
|
|
else |
2092 |
|
|
kn_free_key(&dc); |
2093 |
|
|
|
2094 |
|
|
free(dat); |
2095 |
|
|
|
2096 |
|
|
return err; |
2097 |
|
|
} |
2098 |
|
|
|
2099 |
|
|
/* Beats me what we should be doing with this. */ |
2100 |
|
|
int |
2101 |
|
|
keynote_certreq_decode(void **pdata, u_int8_t *data, u_int32_t len) |
2102 |
|
|
{ |
2103 |
|
|
/* XXX */ |
2104 |
|
|
return 0; |
2105 |
|
|
} |
2106 |
|
|
|
2107 |
|
|
void |
2108 |
|
|
keynote_free_aca(void *blob) |
2109 |
|
|
{ |
2110 |
|
|
/* XXX */ |
2111 |
|
|
} |
2112 |
|
|
|
2113 |
|
|
int |
2114 |
|
|
keynote_cert_obtain(u_int8_t *id, size_t id_len, void *data, u_int8_t **cert, |
2115 |
|
|
u_int32_t *certlen) |
2116 |
|
|
{ |
2117 |
|
|
char *dirname, *file, *addr_str; |
2118 |
|
|
struct stat sb; |
2119 |
|
|
size_t size; |
2120 |
|
|
int idtype, fd, len; |
2121 |
|
|
|
2122 |
|
|
if (!id) { |
2123 |
|
|
log_print("keynote_cert_obtain: ID is missing"); |
2124 |
|
|
return 0; |
2125 |
|
|
} |
2126 |
|
|
/* Get type of ID. */ |
2127 |
|
|
idtype = id[0]; |
2128 |
|
|
id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ; |
2129 |
|
|
id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ; |
2130 |
|
|
|
2131 |
|
|
dirname = conf_get_str("KeyNote", "Credential-directory"); |
2132 |
|
|
if (!dirname) { |
2133 |
|
|
LOG_DBG((LOG_POLICY, 30, |
2134 |
|
|
"keynote_cert_obtain: no Credential-directory")); |
2135 |
|
|
return 0; |
2136 |
|
|
} |
2137 |
|
|
len = strlen(dirname) + strlen(CREDENTIAL_FILE) + 3; |
2138 |
|
|
|
2139 |
|
|
switch (idtype) { |
2140 |
|
|
case IPSEC_ID_IPV4_ADDR: |
2141 |
|
|
case IPSEC_ID_IPV6_ADDR: |
2142 |
|
|
util_ntoa(&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? |
2143 |
|
|
AF_INET : AF_INET6, id); |
2144 |
|
|
if (addr_str == 0) |
2145 |
|
|
return 0; |
2146 |
|
|
|
2147 |
|
|
if (asprintf(&file, "%s/%s/%s", dirname, |
2148 |
|
|
addr_str, CREDENTIAL_FILE) == -1) { |
2149 |
|
|
log_error("keynote_cert_obtain: failed to allocate " |
2150 |
|
|
"%lu bytes", (unsigned long)len + |
2151 |
|
|
strlen(addr_str)); |
2152 |
|
|
free(addr_str); |
2153 |
|
|
return 0; |
2154 |
|
|
} |
2155 |
|
|
free(addr_str); |
2156 |
|
|
break; |
2157 |
|
|
|
2158 |
|
|
case IPSEC_ID_FQDN: |
2159 |
|
|
case IPSEC_ID_USER_FQDN: |
2160 |
|
|
file = calloc(len + id_len, sizeof(char)); |
2161 |
|
|
if (file == NULL) { |
2162 |
|
|
log_error("keynote_cert_obtain: " |
2163 |
|
|
"failed to allocate %lu bytes", |
2164 |
|
|
(unsigned long)len + id_len); |
2165 |
|
|
return 0; |
2166 |
|
|
} |
2167 |
|
|
snprintf(file, len + id_len, "%s/", dirname); |
2168 |
|
|
memcpy(file + strlen(dirname) + 1, id, id_len); |
2169 |
|
|
snprintf(file + strlen(dirname) + 1 + id_len, |
2170 |
|
|
len - strlen(dirname) - 1, "/%s", CREDENTIAL_FILE); |
2171 |
|
|
break; |
2172 |
|
|
|
2173 |
|
|
default: |
2174 |
|
|
return 0; |
2175 |
|
|
} |
2176 |
|
|
|
2177 |
|
|
fd = monitor_open(file, O_RDONLY, 0); |
2178 |
|
|
if (fd < 0) { |
2179 |
|
|
LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: " |
2180 |
|
|
"failed to open \"%s\"", file)); |
2181 |
|
|
free(file); |
2182 |
|
|
return 0; |
2183 |
|
|
} |
2184 |
|
|
|
2185 |
|
|
if (fstat(fd, &sb) < 0) { |
2186 |
|
|
LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: " |
2187 |
|
|
"failed to stat \"%s\"", file)); |
2188 |
|
|
free(file); |
2189 |
|
|
close(fd); |
2190 |
|
|
return 0; |
2191 |
|
|
} |
2192 |
|
|
size = (size_t)sb.st_size; |
2193 |
|
|
|
2194 |
|
|
*cert = calloc(size + 1, sizeof(char)); |
2195 |
|
|
if (*cert == NULL) { |
2196 |
|
|
log_error("keynote_cert_obtain: failed to allocate %lu bytes", |
2197 |
|
|
(unsigned long)size); |
2198 |
|
|
free(file); |
2199 |
|
|
close(fd); |
2200 |
|
|
return 0; |
2201 |
|
|
} |
2202 |
|
|
|
2203 |
|
|
if (read(fd, *cert, size) != (int)size) { |
2204 |
|
|
LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: " |
2205 |
|
|
"failed to read %lu bytes from \"%s\"", |
2206 |
|
|
(unsigned long)size, file)); |
2207 |
|
|
free(cert); |
2208 |
|
|
cert = NULL; |
2209 |
|
|
free(file); |
2210 |
|
|
close(fd); |
2211 |
|
|
return 0; |
2212 |
|
|
} |
2213 |
|
|
close(fd); |
2214 |
|
|
free(file); |
2215 |
|
|
*certlen = size; |
2216 |
|
|
return 1; |
2217 |
|
|
} |
2218 |
|
|
|
2219 |
|
|
/* This should never be called. */ |
2220 |
|
|
int |
2221 |
|
|
keynote_cert_get_subjects(void *scert, int *n, u_int8_t ***id, |
2222 |
|
|
u_int32_t **id_len) |
2223 |
|
|
{ |
2224 |
|
|
return 0; |
2225 |
|
|
} |
2226 |
|
|
|
2227 |
|
|
/* Get the authorizer key. */ |
2228 |
|
|
int |
2229 |
|
|
keynote_cert_get_key(void *scert, void *keyp) |
2230 |
|
|
{ |
2231 |
|
|
struct keynote_keylist *kl; |
2232 |
|
|
int sid, kid, num; |
2233 |
|
|
char **foo; |
2234 |
|
|
|
2235 |
|
|
foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num); |
2236 |
|
|
if (foo == NULL || num == 0) { |
2237 |
|
|
log_print("keynote_cert_get_key: " |
2238 |
|
|
"failed to decompose credentials"); |
2239 |
|
|
return 0; |
2240 |
|
|
} |
2241 |
|
|
kid = kn_init(); |
2242 |
|
|
if (kid == -1) { |
2243 |
|
|
log_print("keynote_cert_get_key: " |
2244 |
|
|
"failed to initialize new policy session"); |
2245 |
|
|
while (num--) |
2246 |
|
|
free(foo[num]); |
2247 |
|
|
free(foo); |
2248 |
|
|
return 0; |
2249 |
|
|
} |
2250 |
|
|
sid = kn_add_assertion(kid, foo[num - 1], strlen(foo[num - 1]), 0); |
2251 |
|
|
while (num--) |
2252 |
|
|
free(foo[num]); |
2253 |
|
|
free(foo); |
2254 |
|
|
|
2255 |
|
|
if (sid == -1) { |
2256 |
|
|
log_print("keynote_cert_get_key: failed to add assertion"); |
2257 |
|
|
kn_close(kid); |
2258 |
|
|
return 0; |
2259 |
|
|
} |
2260 |
|
|
*(RSA **)keyp = NULL; |
2261 |
|
|
|
2262 |
|
|
kl = kn_get_licensees(kid, sid); |
2263 |
|
|
while (kl) { |
2264 |
|
|
if (kl->key_alg == KEYNOTE_ALGORITHM_RSA || |
2265 |
|
|
kl->key_alg == KEYNOTE_ALGORITHM_X509) { |
2266 |
|
|
*(RSA **)keyp = RSAPublicKey_dup(kl->key_key); |
2267 |
|
|
break; |
2268 |
|
|
} |
2269 |
|
|
kl = kl->key_next; |
2270 |
|
|
} |
2271 |
|
|
|
2272 |
|
|
kn_remove_assertion(kid, sid); |
2273 |
|
|
kn_close(kid); |
2274 |
|
|
return *(RSA **)keyp == NULL ? 0 : 1; |
2275 |
|
|
} |
2276 |
|
|
|
2277 |
|
|
void * |
2278 |
|
|
keynote_cert_dup(void *cert) |
2279 |
|
|
{ |
2280 |
|
|
return strdup((char *)cert); |
2281 |
|
|
} |
2282 |
|
|
|
2283 |
|
|
void |
2284 |
|
|
keynote_serialize(void *cert, u_int8_t **data, u_int32_t *datalen) |
2285 |
|
|
{ |
2286 |
|
|
*datalen = strlen((char *)cert) + 1; |
2287 |
|
|
*data = (u_int8_t *)strdup(cert); /* i.e an extra character at |
2288 |
|
|
* the end... */ |
2289 |
|
|
if (*data == NULL) |
2290 |
|
|
log_error("keynote_serialize: malloc (%d) failed", *datalen); |
2291 |
|
|
} |
2292 |
|
|
|
2293 |
|
|
/* From cert to printable */ |
2294 |
|
|
char * |
2295 |
|
|
keynote_printable(void *cert) |
2296 |
|
|
{ |
2297 |
|
|
return strdup((char *)cert); |
2298 |
|
|
} |
2299 |
|
|
|
2300 |
|
|
/* From printable to cert */ |
2301 |
|
|
void * |
2302 |
|
|
keynote_from_printable(char *cert) |
2303 |
|
|
{ |
2304 |
|
|
return strdup(cert); |
2305 |
|
|
} |
2306 |
|
|
|
2307 |
|
|
/* Number of CAs we trust (currently this is x509 only) */ |
2308 |
|
|
int |
2309 |
|
|
keynote_ca_count(void) |
2310 |
|
|
{ |
2311 |
|
|
return 0; |
2312 |
|
|
} |