xref: /freebsd/sbin/setkey/test-pfkey.c (revision aa0a1e58)
1 /*	$FreeBSD$	*/
2 /*	$KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/socket.h>
36 #include <net/route.h>
37 #include <net/pfkeyv2.h>
38 #include <netinet/in.h>
39 #include <netipsec/keydb.h>
40 #include <netipsec/key_var.h>
41 #include <netipsec/key_debug.h>
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <limits.h>
46 #include <string.h>
47 #include <ctype.h>
48 #include <unistd.h>
49 #include <errno.h>
50 #include <netdb.h>
51 
52 u_char m_buf[BUFSIZ];
53 u_int m_len;
54 char *pname;
55 
56 void Usage(void);
57 int sendkeymsg(void);
58 void key_setsadbmsg(u_int);
59 void key_setsadbsens(void);
60 void key_setsadbprop(void);
61 void key_setsadbid(u_int, caddr_t);
62 void key_setsadblft(u_int, u_int);
63 void key_setspirange(void);
64 void key_setsadbkey(u_int, caddr_t);
65 void key_setsadbsa(void);
66 void key_setsadbaddr(u_int, u_int, caddr_t);
67 void key_setsadbextbuf(caddr_t, int, caddr_t, int, caddr_t, int);
68 
69 void
70 Usage()
71 {
72 	printf("Usage:\t%s number\n", pname);
73 	exit(0);
74 }
75 
76 int
77 main(ac, av)
78 	int ac;
79 	char **av;
80 {
81 	pname = *av;
82 
83 	if (ac == 1) Usage();
84 
85 	key_setsadbmsg(atoi(*(av+1)));
86 	sendkeymsg();
87 
88 	exit(0);
89 }
90 
91 /* %%% */
92 int
93 sendkeymsg()
94 {
95 	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */
96 	int so, len;
97 
98 	if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
99 		perror("socket(PF_KEY)");
100 		goto end;
101 	}
102 #if 0
103     {
104 #include <sys/time.h>
105 	struct timeval tv;
106 	tv.tv_sec = 1;
107 	tv.tv_usec = 0;
108 	if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
109 		perror("setsockopt");
110 		goto end;
111 	}
112     }
113 #endif
114 
115 	pfkey_sadump((struct sadb_msg *)m_buf);
116 
117 	if ((len = send(so, m_buf, m_len, 0)) < 0) {
118 		perror("send");
119 		goto end;
120 	}
121 
122 	if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
123 		perror("recv");
124 		goto end;
125 	}
126 
127 	pfkey_sadump((struct sadb_msg *)rbuf);
128 
129 end:
130 	(void)close(so);
131 	return(0);
132 }
133 
134 void
135 key_setsadbmsg(type)
136 	u_int type;
137 {
138 	struct sadb_msg m_msg;
139 
140 	memset(&m_msg, 0, sizeof(m_msg));
141 	m_msg.sadb_msg_version = PF_KEY_V2;
142 	m_msg.sadb_msg_type = type;
143 	m_msg.sadb_msg_errno = 0;
144 	m_msg.sadb_msg_satype = SADB_SATYPE_ESP;
145 #if 0
146 	m_msg.sadb_msg_reserved = 0;
147 #endif
148 	m_msg.sadb_msg_seq = 0;
149 	m_msg.sadb_msg_pid = getpid();
150 
151 	m_len = sizeof(struct sadb_msg);
152 	memcpy(m_buf, &m_msg, m_len);
153 
154 	switch (type) {
155 	case SADB_GETSPI:
156 		/*<base, address(SD), SPI range>*/
157 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4");
158 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1");
159 		key_setspirange();
160 		/*<base, SA(*), address(SD)>*/
161 		break;
162 
163 	case SADB_ADD:
164 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
165 		   key(AE), (identity(SD),) (sensitivity)> */
166 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
167 	case SADB_UPDATE:
168 		key_setsadbsa();
169 		key_setsadblft(SADB_EXT_LIFETIME_HARD, 10);
170 		key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5);
171 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
172 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
173 		/* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */
174 		key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678");
175 		key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678");
176 		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
177 		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
178 		key_setsadbsens();
179 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
180 		  (identity(SD),) (sensitivity)> */
181 		break;
182 
183 	case SADB_DELETE:
184 		/* <base, SA(*), address(SDP)> */
185 		key_setsadbsa();
186 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
187 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
188 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
189 		/* <base, SA(*), address(SDP)> */
190 		break;
191 
192 	case SADB_GET:
193 		/* <base, SA(*), address(SDP)> */
194 		key_setsadbsa();
195 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
196 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
197 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
198 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
199 		   key(AE), (identity(SD),) (sensitivity)> */
200 		break;
201 
202 	case SADB_ACQUIRE:
203 		/* <base, address(SD), (address(P),) (identity(SD),)
204 		   (sensitivity,) proposal> */
205 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
206 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
207 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
208 		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
209 		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
210 		key_setsadbsens();
211 		key_setsadbprop();
212 		/* <base, address(SD), (address(P),) (identity(SD),)
213 		   (sensitivity,) proposal> */
214 		break;
215 
216 	case SADB_REGISTER:
217 		/* <base> */
218 		/* <base, supported> */
219 		break;
220 
221 	case SADB_EXPIRE:
222 	case SADB_FLUSH:
223 		break;
224 
225 	case SADB_DUMP:
226 		break;
227 
228 	case SADB_X_PROMISC:
229 		/* <base> */
230 		/* <base, base(, others)> */
231 		break;
232 
233 	case SADB_X_PCHANGE:
234 		break;
235 
236 	/* for SPD management */
237 	case SADB_X_SPDFLUSH:
238 	case SADB_X_SPDDUMP:
239 		break;
240 
241 	case SADB_X_SPDADD:
242 #if 0
243 	    {
244 		struct sadb_x_policy m_policy;
245 
246 		m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy));
247 		m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
248 		m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC;
249 		m_policy.sadb_x_policy_esp_trans = 1;
250 		m_policy.sadb_x_policy_ah_trans = 2;
251 		m_policy.sadb_x_policy_esp_network = 3;
252 		m_policy.sadb_x_policy_ah_network = 4;
253 		m_policy.sadb_x_policy_reserved = 0;
254 
255 		memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy));
256 		m_len += sizeof(struct sadb_x_policy);
257 	    }
258 #endif
259 
260 	case SADB_X_SPDDELETE:
261 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
262 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
263 		break;
264 	}
265 
266 	((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
267 
268 	return;
269 }
270 
271 void
272 key_setsadbsens()
273 {
274 	struct sadb_sens m_sens;
275 	u_char buf[64];
276 	u_int s, i, slen, ilen, len;
277 
278 	/* make sens & integ */
279 	s = htonl(0x01234567);
280 	i = htonl(0x89abcdef);
281 	slen = sizeof(s);
282 	ilen = sizeof(i);
283 	memcpy(buf, &s, slen);
284 	memcpy(buf + slen, &i, ilen);
285 
286 	len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen);
287 	m_sens.sadb_sens_len = PFKEY_UNIT64(len);
288 	m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY;
289 	m_sens.sadb_sens_dpd = 1;
290 	m_sens.sadb_sens_sens_level = 2;
291 	m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen);
292 	m_sens.sadb_sens_integ_level = 3;
293 	m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen);
294 	m_sens.sadb_sens_reserved = 0;
295 
296 	key_setsadbextbuf(m_buf, m_len,
297 			(caddr_t)&m_sens, sizeof(struct sadb_sens),
298 			buf, slen + ilen);
299 	m_len += len;
300 
301 	return;
302 }
303 
304 void
305 key_setsadbprop()
306 {
307 	struct sadb_prop m_prop;
308 	struct sadb_comb *m_comb;
309 	u_char buf[256];
310 	u_int len = sizeof(m_prop) + sizeof(m_comb) * 2;
311 
312 	/* make prop & comb */
313 	m_prop.sadb_prop_len = PFKEY_UNIT64(len);
314 	m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL;
315 	m_prop.sadb_prop_replay = 0;
316 	m_prop.sadb_prop_reserved[0] = 0;
317 	m_prop.sadb_prop_reserved[1] = 0;
318 	m_prop.sadb_prop_reserved[2] = 0;
319 
320 	/* the 1st is ESP DES-CBC HMAC-MD5 */
321 	m_comb = (struct sadb_comb *)buf;
322 	m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
323 	m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
324 	m_comb->sadb_comb_flags = 0;
325 	m_comb->sadb_comb_auth_minbits = 8;
326 	m_comb->sadb_comb_auth_maxbits = 96;
327 	m_comb->sadb_comb_encrypt_minbits = 64;
328 	m_comb->sadb_comb_encrypt_maxbits = 64;
329 	m_comb->sadb_comb_reserved = 0;
330 	m_comb->sadb_comb_soft_allocations = 0;
331 	m_comb->sadb_comb_hard_allocations = 0;
332 	m_comb->sadb_comb_soft_bytes = 0;
333 	m_comb->sadb_comb_hard_bytes = 0;
334 	m_comb->sadb_comb_soft_addtime = 0;
335 	m_comb->sadb_comb_hard_addtime = 0;
336 	m_comb->sadb_comb_soft_usetime = 0;
337 	m_comb->sadb_comb_hard_usetime = 0;
338 
339 	/* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */
340 	m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb));
341 	m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
342 	m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
343 	m_comb->sadb_comb_flags = 0;
344 	m_comb->sadb_comb_auth_minbits = 8;
345 	m_comb->sadb_comb_auth_maxbits = 96;
346 	m_comb->sadb_comb_encrypt_minbits = 64;
347 	m_comb->sadb_comb_encrypt_maxbits = 64;
348 	m_comb->sadb_comb_reserved = 0;
349 	m_comb->sadb_comb_soft_allocations = 0;
350 	m_comb->sadb_comb_hard_allocations = 0;
351 	m_comb->sadb_comb_soft_bytes = 0;
352 	m_comb->sadb_comb_hard_bytes = 0;
353 	m_comb->sadb_comb_soft_addtime = 0;
354 	m_comb->sadb_comb_hard_addtime = 0;
355 	m_comb->sadb_comb_soft_usetime = 0;
356 	m_comb->sadb_comb_hard_usetime = 0;
357 
358 	key_setsadbextbuf(m_buf, m_len,
359 			(caddr_t)&m_prop, sizeof(struct sadb_prop),
360 			buf, sizeof(*m_comb) * 2);
361 	m_len += len;
362 
363 	return;
364 }
365 
366 void
367 key_setsadbid(ext, str)
368 	u_int ext;
369 	caddr_t str;
370 {
371 	struct sadb_ident m_id;
372 	u_int idlen = strlen(str), len;
373 
374 	len = sizeof(m_id) + PFKEY_ALIGN8(idlen);
375 	m_id.sadb_ident_len = PFKEY_UNIT64(len);
376 	m_id.sadb_ident_exttype = ext;
377 	m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
378 	m_id.sadb_ident_reserved = 0;
379 	m_id.sadb_ident_id = getpid();
380 
381 	key_setsadbextbuf(m_buf, m_len,
382 			(caddr_t)&m_id, sizeof(struct sadb_ident),
383 			str, idlen);
384 	m_len += len;
385 
386 	return;
387 }
388 
389 void
390 key_setsadblft(ext, time)
391 	u_int ext, time;
392 {
393 	struct sadb_lifetime m_lft;
394 
395 	m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft));
396 	m_lft.sadb_lifetime_exttype = ext;
397 	m_lft.sadb_lifetime_allocations = 0x2;
398 	m_lft.sadb_lifetime_bytes = 0x1000;
399 	m_lft.sadb_lifetime_addtime = time;
400 	m_lft.sadb_lifetime_usetime = 0x0020;
401 
402 	memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime));
403 	m_len += sizeof(struct sadb_lifetime);
404 
405 	return;
406 }
407 
408 void
409 key_setspirange()
410 {
411 	struct sadb_spirange m_spi;
412 
413 	m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi));
414 	m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
415 	m_spi.sadb_spirange_min = 0x00001000;
416 	m_spi.sadb_spirange_max = 0x00002000;
417 	m_spi.sadb_spirange_reserved = 0;
418 
419 	memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange));
420 	m_len += sizeof(struct sadb_spirange);
421 
422 	return;
423 }
424 
425 void
426 key_setsadbkey(ext, str)
427 	u_int ext;
428 	caddr_t str;
429 {
430 	struct sadb_key m_key;
431 	u_int keylen = strlen(str);
432 	u_int len;
433 
434 	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
435 	m_key.sadb_key_len = PFKEY_UNIT64(len);
436 	m_key.sadb_key_exttype = ext;
437 	m_key.sadb_key_bits = keylen * 8;
438 	m_key.sadb_key_reserved = 0;
439 
440 	key_setsadbextbuf(m_buf, m_len,
441 			(caddr_t)&m_key, sizeof(struct sadb_key),
442 			str, keylen);
443 	m_len += len;
444 
445 	return;
446 }
447 
448 void
449 key_setsadbsa()
450 {
451 	struct sadb_sa m_sa;
452 
453 	m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
454 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
455 	m_sa.sadb_sa_spi = htonl(0x12345678);
456 	m_sa.sadb_sa_replay = 4;
457 	m_sa.sadb_sa_state = 0;
458 	m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC;
459 	m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC;
460 	m_sa.sadb_sa_flags = 0;
461 
462 	memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa));
463 	m_len += sizeof(struct sadb_sa);
464 
465 	return;
466 }
467 
468 void
469 key_setsadbaddr(ext, af, str)
470 	u_int ext, af;
471 	caddr_t str;
472 {
473 	struct sadb_address m_addr;
474 	u_int len;
475 	struct addrinfo hints, *res;
476 	const char *serv;
477 	int plen;
478 
479 	switch (af) {
480 	case AF_INET:
481 		plen = sizeof(struct in_addr) << 3;
482 		break;
483 	case AF_INET6:
484 		plen = sizeof(struct in6_addr) << 3;
485 		break;
486 	default:
487 		/* XXX bark */
488 		exit(1);
489 	}
490 
491 	/* make sockaddr buffer */
492 	memset(&hints, 0, sizeof(hints));
493 	hints.ai_family = af;
494 	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
495 	hints.ai_flags = AI_NUMERICHOST;
496 	serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660");	/*0x1234*/
497 	if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) {
498 		/* XXX bark */
499 		exit(1);
500 	}
501 
502 	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen);
503 	m_addr.sadb_address_len = PFKEY_UNIT64(len);
504 	m_addr.sadb_address_exttype = ext;
505 	m_addr.sadb_address_proto =
506 		(ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP);
507 	m_addr.sadb_address_prefixlen = plen;
508 	m_addr.sadb_address_reserved = 0;
509 
510 	key_setsadbextbuf(m_buf, m_len,
511 			(caddr_t)&m_addr, sizeof(struct sadb_address),
512 			(caddr_t)res->ai_addr, res->ai_addrlen);
513 	m_len += len;
514 
515 	freeaddrinfo(res);
516 
517 	return;
518 }
519 
520 void
521 key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen)
522 	caddr_t dst, ebuf, vbuf;
523 	int off, elen, vlen;
524 {
525 	memset(dst + off, 0, elen + vlen);
526 	memcpy(dst + off, (caddr_t)ebuf, elen);
527 	memcpy(dst + off + elen, vbuf, vlen);
528 
529 	return;
530 }
531 
532