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