test-pfkey.c revision 330897
1/*	$FreeBSD: stable/11/sbin/setkey/test-pfkey.c 330897 2018-03-14 03:19:51Z eadler $	*/
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
54u_char m_buf[BUFSIZ];
55u_int m_len;
56char *pname;
57
58void Usage(void);
59int sendkeymsg(void);
60void key_setsadbmsg(u_int);
61void key_setsadbsens(void);
62void key_setsadbprop(void);
63void key_setsadbid(u_int, caddr_t);
64void key_setsadblft(u_int, u_int);
65void key_setspirange(void);
66void key_setsadbkey(u_int, caddr_t);
67void key_setsadbsa(void);
68void key_setsadbaddr(u_int, u_int, caddr_t);
69void key_setsadbextbuf(caddr_t, int, caddr_t, int, caddr_t, int);
70
71void
72Usage()
73{
74	printf("Usage:\t%s number\n", pname);
75	exit(0);
76}
77
78int
79main(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/* %%% */
94int
95sendkeymsg()
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
131end:
132	(void)close(so);
133	return(0);
134}
135
136void
137key_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
273void
274key_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
306void
307key_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
368void
369key_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
391void
392key_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
410void
411key_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
427void
428key_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
450void
451key_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
470void
471key_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
522void
523key_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