diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-05-26 04:03:00 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-05-26 04:03:00 +0000 |
commit | 58dd5b5b8aa404c30d78d7408ddfdfc17e5478d3 (patch) | |
tree | 8958ac9984fda1f82f8a1603b59e13b740abbe19 /sbin/ipsecadm/ipsecadm.c | |
parent | 9136cbc0bb5ea9a90e52d6fff4329a3f724c5a4a (diff) |
let us not talk about ipsecadm and vpn anymore; ok reyk
Diffstat (limited to 'sbin/ipsecadm/ipsecadm.c')
-rw-r--r-- | sbin/ipsecadm/ipsecadm.c | 1581 |
1 files changed, 0 insertions, 1581 deletions
diff --git a/sbin/ipsecadm/ipsecadm.c b/sbin/ipsecadm/ipsecadm.c deleted file mode 100644 index 7bacfe281e1..00000000000 --- a/sbin/ipsecadm/ipsecadm.c +++ /dev/null @@ -1,1581 +0,0 @@ -/* $OpenBSD: ipsecadm.c,v 1.86 2005/06/07 02:36:41 henning Exp $ */ -/* - * The authors of this code are John Ioannidis (ji@tla.org), - * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). - * - * This code was written by John Ioannidis for BSD/OS in Athens, Greece, - * in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis. - * - * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis - * and Niels Provos. - * - * Additional features in 1999 by Angelos D. Keromytis. - * - * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, - * Angelos D. Keromytis and Niels Provos. - * Copyright (c) 2001, Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software with or without fee - * is hereby granted, provided that this entire notice is included in - * all copies of any software which is or includes a copy or - * modification of this software. - * You may use this code under the GNU public license if you so wish. Please - * contribute changes back to the authors under this freer than GPL license - * so that we may further the use of strong encryption without limitations to - * all. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -#include <sys/param.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/mbuf.h> -#include <sys/sysctl.h> -#include <sys/uio.h> -#include <sys/stat.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/if_dl.h> -#include <netinet/in.h> -#include <net/pfkeyv2.h> -#include <netinet/ip_ipsp.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <netdb.h> -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <paths.h> -#include <err.h> - -#define KEYSIZE_LIMIT 1024 - -#define ESP_OLD 0x0001 -#define ESP_NEW 0x0002 -#define AH_OLD 0x0004 -#define AH_NEW 0x0008 - -#define XF_ENC 0x0100 -#define XF_AUTH 0x0200 -#define DEL_SPI 0x0300 -#define GRP_SPI 0x0400 -#define FLOW 0x0500 -#define FLUSH 0x0700 -#define XF_COMP 0x0900 -#define SHOW 0x0a00 -#define MONITOR 0x0b00 - -/* pseudo commands */ -#define IPCOMP 0x1000 -#define TCPMD5 0x2000 -#define ENC_IP 0x4000 - -#define CMD_MASK 0xff00 -#define XFORM_MASK 0x0f00 - -#define isencauth(x) ((x)&~CMD_MASK) -#define iscmd(x,y) (((x) & CMD_MASK) == (y)) - -typedef struct { - char *name; - int id, flags; -} transform; - -transform xf[] = { - { "null", SADB_EALG_NULL, XF_ENC | ESP_NEW }, - { "des", SADB_EALG_DESCBC, XF_ENC | ESP_OLD | ESP_NEW }, - { "3des", SADB_EALG_3DESCBC, XF_ENC | ESP_OLD | ESP_NEW }, - { "aes", SADB_X_EALG_AES, XF_ENC | ESP_NEW }, - { "aesctr", SADB_X_EALG_AESCTR, XF_ENC | ESP_NEW }, - { "blf", SADB_X_EALG_BLF, XF_ENC | ESP_NEW }, - { "cast", SADB_X_EALG_CAST, XF_ENC | ESP_NEW }, - { "skipjack", SADB_X_EALG_SKIPJACK, XF_ENC | ESP_NEW }, - { "md5", SADB_AALG_MD5HMAC, XF_AUTH | AH_NEW | ESP_NEW }, - { "sha1", SADB_AALG_SHA1HMAC, XF_AUTH | AH_NEW | ESP_NEW }, - { "sha2-256", SADB_X_AALG_SHA2_256, XF_AUTH | AH_NEW | ESP_NEW }, - { "sha2-384", SADB_X_AALG_SHA2_384, XF_AUTH | AH_NEW | ESP_NEW }, - { "sha2-512", SADB_X_AALG_SHA2_512, XF_AUTH | AH_NEW | ESP_NEW }, - { "md5", SADB_X_AALG_MD5, XF_AUTH | AH_OLD }, - { "sha1", SADB_X_AALG_SHA1, XF_AUTH | AH_OLD }, - { "rmd160", SADB_X_AALG_RIPEMD160HMAC, XF_AUTH | AH_NEW | ESP_NEW }, - { "deflate", SADB_X_CALG_DEFLATE, XF_COMP | IPCOMP }, - { "lzs", SADB_X_CALG_LZS, XF_COMP | IPCOMP }, -}; - -#define ROUNDUP(x) (((x) + sizeof(u_int64_t) - 1) & ~(sizeof(u_int64_t) - 1)) - -void ipsecadm_monitor(void); -void ipsecadm_show(u_int8_t); -int addrparse(const char *, struct sockaddr *, struct sockaddr *); -void xf_set(struct iovec *, int, int); -int x2i(u_char *); -int isvalid(char *, int, int); -__dead void usage(void); - -/* - * returns 0 if "str" represents an address, returns 1 if address/mask, - * returns -1 on failure. - */ -int -addrparse(const char *str, struct sockaddr *addr, struct sockaddr *mask) -{ - struct addrinfo hints, *res = NULL; - char *p = NULL, *sp, *ep; - u_long prefixlen = 0; - u_char *ap; - int bitlen; - - /* slash */ - if (mask && (p = strchr(str, '/')) != NULL) { - if (!p[1]) - return -1; - ep = NULL; - prefixlen = strtoul(p + 1, &ep, 10); - if (*ep) - return -1; - - sp = strdup(str); - if (!sp) - return -1; - sp[p - str] = '\0'; - str = sp; - } else - sp = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /* dummy */ - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = PF_UNSPEC; - if (getaddrinfo(str, "0", &hints, &res) != 0) - return -1; - if (res->ai_next) - goto fail; - - memcpy(addr, res->ai_addr, res->ai_addrlen); - - if (!p) { - freeaddrinfo(res); - if (sp) - free(sp); - return 0; - } - switch (res->ai_family) { - case AF_INET: - ap = (u_char *) & ((struct sockaddr_in *) mask)->sin_addr; - bitlen = 32; - break; - case AF_INET6: - ap = (u_char *) & ((struct sockaddr_in6 *) mask)->sin6_addr; - bitlen = 128; - break; - default: - goto fail; - } - - if (prefixlen > bitlen) - goto fail; - - memset(mask, 0, addr->sa_len); - mask->sa_len = addr->sa_len; - mask->sa_family = addr->sa_family; - memset(ap, 0xff, prefixlen / 8); - if (prefixlen % 8) - ap[prefixlen / 8] = (0xff00 >> (prefixlen % 8)) & 0xff; - - if (res) - freeaddrinfo(res); - if (sp) - free(sp); - return 1; - -fail: - if (res) - freeaddrinfo(res); - if (sp) - free(sp); - return -1; -} - -void -xf_set(struct iovec *iov, int cnt, int len) -{ - struct sadb_msg sm; - int sd; - - sd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (sd < 0) - errx(1, "socket: %s%s", strerror(errno), - errno == EPROTONOSUPPORT ? - "\nMake sure your kernel is compiled with option KEY" : ""); - if (writev(sd, iov, cnt) != len) - err(1, "write"); - if (read(sd, &sm, sizeof(sm)) != sizeof(sm)) - err(1, "read"); - if (sm.sadb_msg_errno != 0) { - /* XXX We need better error reporting than this */ - errno = sm.sadb_msg_errno; - err(1, "pfkey"); - } - close(sd); -} - -int -x2i(u_char *s) -{ - char ss[3]; - - ss[0] = s[0]; - ss[1] = s[1]; - ss[2] = 0; - - if (!isxdigit(s[0]) || !isxdigit(s[1])) - errx(1, "keys should be specified in hex digits"); - return strtoul(ss, NULL, 16); -} - -int -isvalid(char *option, int type, int mode) -{ - int i; - - for (i = sizeof(xf) / sizeof(transform) - 1; i >= 0; i--) - if (!strcmp(option, xf[i].name) && - (xf[i].flags & XFORM_MASK) == type && - (xf[i].flags & mode)) { - goto gotit; - } - return 0; -gotit: - if (!strcmp(option, "des") || !strcmp(option, "skipjack")) - warnx("warning: use of %s is strongly discouraged due to" - " cryptographic weaknesses", option); - return xf[i].id; -} - -void -usage(void) -{ - fprintf(stderr, "usage: ipsecadm command [modifier ...]\n" - "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4, ipcomp,\n" - "\t\t tcpmd5, flow, flush, show, monitor\n" - "\tPossible modifiers:\n" - "\t -enc <alg>\t\t\tencryption algorithm\n" - "\t -auth <alg>\t\t\tauthentication algorithm\n" - "\t -comp <alg>\t\t\tcompression algorithm\n" - "\t -src <ip>\t\t\tsource address to be used\n" - "\t -halfiv\t\t\tuse 4-byte IV in old ESP\n" - "\t -forcetunnel\t\t\tforce IP-in-IP encapsulation\n" - "\t -udpencap <port>\t\tenable ESP-in-UDP encapsulation\n" - "\t -dst <ip>\t\t\tdestination address to be used\n" - "\t -proto <val>\t\t\tsecurity protocol\n" - "\t -proxy <ip>\t\t\tproxy address to be used\n" - "\t -spi <val>\t\t\tSPI to be used\n" - "\t -cpi <val>\t\t\tCPI to be used\n" - "\t -key <val>\t\t\tkey material to be used\n" - "\t -keyfile <file>\t\tfile to read key material from\n" - "\t -authkey <val>\t\tkey material for auth in new esp\n" - "\t -authkeyfile <file>\t\tfile to read authkey material from\n" - "\t -sport <port>\t\t\tsource port for flow\n" - "\t -dport <port>\t\t\tdestination port for flow\n" - "\t -transport <val>\t\tprotocol number for flow\n" - "\t -addr <srcnet> <mask> <dstnet> <mask>\t\tsubnets for flow\n" - "\t -addr <srcnet/prefix> <dstnet/prefix>\t\tsame as above but in CIDR\n" - "\t -delete\t\t\tdelete specified flow\n" - "\t -bypass\t\t\tpermit a flow through without IPsec\n" - "\t -permit\t\t\tsame as bypass\n" - "\t -deny\t\t\t\tcreate a deny-packets flow\n" - "\t -use\t\t\t\tuse an SA for a flow if it exists\n" - "\t -acquire\t\t\tsend unprotected while acquiring SA\n" - "\t -require\t\t\trequire an SA for a flow, use key mgmt.\n" - "\t -dontacq\t\t\trequire, without using key mgmt.\n" - "\t -in\t\t\t\tspecify incoming-packet policy\n" - "\t -out\t\t\t\tspecify outgoing-packet policy\n" - "\t -[ah|esp|ip4|ipcomp|tcpmd5]\tflush a particular protocol\n" - "\t -srcid <id>\t\t\tsource identity for flows\n" - "\t -dstid <id>\t\t\tdestination identity for flows\n" - "\t -srcid_type <type>\t\tsource identity type\n" - "\t -dstid_type <type>\t\tdestination identity type\n" - "\talso: dst2, spi2, proto2\n" - ); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - int auth = 0, enc = 0, klen = 0, alen = 0, mode = ESP_NEW, i = 0; - int proto = IPPROTO_ESP, proto2 = IPPROTO_AH, sproto2 = SADB_SATYPE_AH; - int dport = -1, sport = -1, tproto = -1; - int srcset = 0, dstset = 0, dst2set = 0, proxyset = 0; - int cnt = 0, bypass = 0, deny = 0, ipsec = 0, comp = 0; - u_int32_t spi = SPI_LOCAL_USE, spi2 = SPI_LOCAL_USE; - u_int32_t cpi = SPI_LOCAL_USE; - union sockaddr_union *src, *dst, *dst2, *osrc, *odst, *osmask; - union sockaddr_union *odmask, *proxy; - u_char srcbuf[256], dstbuf[256], dst2buf[256], osrcbuf[256]; - u_char odstbuf[256], osmaskbuf[256], odmaskbuf[256], proxybuf[256]; - u_char *keyp = NULL, *authp = NULL; - u_char *srcid = NULL, *dstid = NULL; - struct protoent *tp; - struct servent *svp; - char *transportproto = NULL; - struct sadb_msg smsg; - struct sadb_sa sa, sa2; - struct sadb_address sad1, sad2, sad3; /* src, dst, proxy */ - struct sadb_address sad4, sad5; /* osrc, odst */ - struct sadb_address sad6, sad7, sad8; /* osmask, odmask, dst2 */ - struct sadb_ident sid1, sid2; - struct sadb_key skey1, skey2; - struct sadb_protocol sprotocol, sprotocol2; - struct sadb_x_udpencap udpencap; /* Peer UDP Port */ - u_char realkey[8192], realakey[8192]; - struct iovec iov[30]; - struct addrinfo hints, *res; - const char *errstr; - u_long ll; - char *ep; - - if (argc < 2) - usage(); - - /* Zero out */ - memset(&smsg, 0, sizeof(smsg)); - memset(&sa, 0, sizeof(sa)); - memset(&sa2, 0, sizeof(sa2)); - memset(&skey1, 0, sizeof(skey1)); - memset(&skey2, 0, sizeof(skey2)); - memset(&sad1, 0, sizeof(sad1)); - memset(&sad2, 0, sizeof(sad2)); - memset(&sad3, 0, sizeof(sad3)); - memset(&sad4, 0, sizeof(sad4)); - memset(&sad5, 0, sizeof(sad5)); - memset(&sad6, 0, sizeof(sad6)); - memset(&sad7, 0, sizeof(sad7)); - memset(&sad8, 0, sizeof(sad8)); - memset(&sprotocol, 0, sizeof(sprotocol)); - memset(&sprotocol2, 0, sizeof(sprotocol2)); - memset(iov, 0, sizeof(iov)); - memset(realkey, 0, sizeof(realkey)); - memset(realakey, 0, sizeof(realakey)); - memset(&sid1, 0, sizeof(sid1)); - memset(&sid2, 0, sizeof(sid2)); - memset(&udpencap, 0, sizeof(udpencap)); - - src = (union sockaddr_union *) srcbuf; - dst = (union sockaddr_union *) dstbuf; - dst2 = (union sockaddr_union *) dst2buf; - osrc = (union sockaddr_union *) osrcbuf; - odst = (union sockaddr_union *) odstbuf; - osmask = (union sockaddr_union *) osmaskbuf; - odmask = (union sockaddr_union *) odmaskbuf; - proxy = (union sockaddr_union *) proxybuf; - - memset(srcbuf, 0, sizeof(srcbuf)); - memset(dstbuf, 0, sizeof(dstbuf)); - memset(dst2buf, 0, sizeof(dst2buf)); - memset(osrcbuf, 0, sizeof(osrcbuf)); - memset(odstbuf, 0, sizeof(odstbuf)); - memset(osmaskbuf, 0, sizeof(osmaskbuf)); - memset(odmaskbuf, 0, sizeof(odmaskbuf)); - memset(proxybuf, 0, sizeof(proxybuf)); - - /* Initialize */ - smsg.sadb_msg_version = PF_KEY_V2; - smsg.sadb_msg_seq = 1; - smsg.sadb_msg_pid = getpid(); - smsg.sadb_msg_len = sizeof(smsg) / 8; - - /* Initialize */ - sa.sadb_sa_exttype = SADB_EXT_SA; - sa.sadb_sa_len = sizeof(sa) / 8; - sa.sadb_sa_replay = 0; - sa.sadb_sa_state = SADB_SASTATE_MATURE; - - sa2.sadb_sa_exttype = SADB_X_EXT_SA2; - sa2.sadb_sa_len = sizeof(sa) / 8; - sa2.sadb_sa_replay = 0; - sa2.sadb_sa_state = SADB_SASTATE_MATURE; - - sid1.sadb_ident_len = sizeof(sid1) / 8; - sid1.sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; - - sid2.sadb_ident_len = sizeof(sid2) / 8; - sid2.sadb_ident_exttype = SADB_EXT_IDENTITY_DST; - - sprotocol2.sadb_protocol_len = 1; - sprotocol2.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE; - sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_OUT; - sprotocol2.sadb_protocol_flags = SADB_X_POLICYFLAGS_POLICY; - sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; - sprotocol.sadb_protocol_len = 1; - - if (!strcmp(argv[1], "new") && argc > 3) { - if (!strcmp(argv[2], "esp")) { - mode = ESP_NEW; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - } else if (!strcmp(argv[2], "ah")) { - mode = AH_NEW; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_SATYPE_AH; - } else - errx(1, "unexpected identifier %s", argv[2]); - - i += 2; - } else if (!strcmp(argv[1], "old") && argc > 3) { - if (!strcmp(argv[2], "esp")) { - mode = ESP_OLD; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - sa.sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING; - sa.sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY; - } else if (!strcmp(argv[2], "ah")) { - mode = AH_OLD; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_SATYPE_AH; - sa.sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY; - } else - errx(1, "unexpected identifier %s", argv[2]); - - i += 2; - } else if (!strcmp(argv[1], "delspi")) { - smsg.sadb_msg_type = SADB_DELETE; - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - mode = DEL_SPI; - i++; - } else if (!strcmp(argv[1], "group")) { - smsg.sadb_msg_type = SADB_X_GRPSPIS; - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - mode = GRP_SPI; - i++; - } else if (!strcmp(argv[1], "flow")) { - /* It may not be ADDFLOW, but never mind that for now */ - smsg.sadb_msg_type = SADB_X_ADDFLOW; - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - mode = FLOW; - i++; - } else if (!strcmp(argv[1], "flush")) { - mode = FLUSH; - smsg.sadb_msg_type = SADB_FLUSH; - smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC; - i++; - } else if (!strcmp(argv[1], "ip4")) { - mode = ENC_IP; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; - i++; - } else if (!strcmp(argv[1], "tcpmd5")) { - mode = TCPMD5; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE; - i++; - } else if (!strcmp(argv[1], "ipcomp")) { - mode = IPCOMP; - smsg.sadb_msg_type = SADB_ADD; - smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; - i++; - } else if (!strcmp(argv[1], "monitor")) { - mode = MONITOR; - i++; - } else if (!strcmp(argv[1], "show")) { - mode = SHOW; - smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC; - i++; - } else { - warnx("unknown command: %s", argv[1]); - usage(); - } - - for (i++; i < argc; i++) { - if (argv[i][0] != '-') - errx(1, "expected option, got %s", argv[i]); - if (!strcmp(argv[i] + 1, "enc") && enc == 0 && (i + 1 < argc)) { - if ((enc = isvalid(argv[i + 1], XF_ENC, mode)) == 0) - errx(1, "invalid encryption algorithm %s", - argv[i + 1]); - skey1.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; - sa.sadb_sa_encrypt = enc; - i++; - continue; - } - if (!strcmp(argv[i] + 1, "auth") && auth == 0 && (i + 1 < argc)) { - if ((auth = isvalid(argv[i + 1], XF_AUTH, mode)) == 0) - errx(1, "invalid auth algorithm %s", argv[i + 1]); - skey2.sadb_key_exttype = SADB_EXT_KEY_AUTH; - sa.sadb_sa_auth = auth; - i++; - continue; - } - if (!strcmp(argv[i] + 1, "comp") && comp == 0 && (i + 1 < argc)) { - if ((comp = isvalid(argv[i + 1], XF_COMP, mode)) == 0) - errx(1, "invalid comp algorithm %s", argv[i + 1]); - /* - * Use encryption algo slot to store compression algo - * since we cannot modify sadb_sa - */ - sa.sadb_sa_encrypt = comp; - i++; - continue; - } - if (!strcmp(argv[i] + 1, "key") && keyp == NULL && - (i + 1 < argc)) { - if (mode & (AH_NEW | AH_OLD | TCPMD5)) { - authp = (u_char *)argv[++i]; - alen = strlen((char *)authp) / 2; - } else { - keyp = (u_char *)argv[++i]; - klen = strlen((char *)keyp) / 2; - } - continue; - } - if (!strcmp(argv[i] + 1, "keyfile") && keyp == NULL && - (i + 1 < argc)) { - struct stat sb; - u_char *pptr; - int fd; - - if (stat(argv[++i], &sb) < 0) - err(1, "stat"); - if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) - errx(1, "file %s is too %s " - "(must be between 1 and %d bytes)", - argv[i], sb.st_size ? "large" : "small", - KEYSIZE_LIMIT); - if ((pptr = malloc(sb.st_size)) == NULL) - err(1, "malloc"); - if ((fd = open(argv[i], O_RDONLY)) < 0) - err(1, "open"); - if (read(fd, pptr, sb.st_size) < sb.st_size) - err(1, "read"); - close(fd); - - if (mode & (AH_NEW | AH_OLD | TCPMD5)) { - authp = pptr; - alen = sb.st_size / 2; - } else { - keyp = pptr; - klen = sb.st_size / 2; - } - continue; - } - if (!strcmp(argv[i] + 1, "authkeyfile") && authp == NULL && - (i + 1 < argc)) { - struct stat sb; - int fd; - - if (!(mode & ESP_NEW)) - errx(1, "invalid option %s for selected mode", - argv[i]); - if (stat(argv[++i], &sb) < 0) - err(1, "stat"); - if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) - errx(1, "file %s is too %s " - "(must be between 1 and %d bytes)", - argv[i], sb.st_size ? "large" : "small", - KEYSIZE_LIMIT); - if ((authp = malloc(sb.st_size)) == NULL) - err(1, "malloc"); - if ((fd = open(argv[i], O_RDONLY)) < 0) - err(1, "open"); - if (read(fd, authp, sb.st_size) < sb.st_size) - err(1, "read"); - close(fd); - - alen = sb.st_size / 2; - continue; - } - if (!strcmp(argv[i] + 1, "authkey") && authp == NULL && - (i + 1 < argc)) { - if (!(mode & ESP_NEW)) - errx(1, "invalid option %s for selected mode", - argv[i]); - authp = (u_char *)argv[++i]; - alen = strlen((char *)authp) / 2; - continue; - } - if (!strcmp(argv[i] + 1, "iv") && (i + 1 < argc)) { - if (mode & (AH_OLD | AH_NEW)) - errx(1, "invalid option %s with auth", - argv[i]); - warnx("warning: option iv has been deprecated"); - - /* Horrible hack */ - if (mode & ESP_OLD) - if (strlen(argv[i + 2]) == 4) - sa.sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV; - - i++; - continue; - } - if ((iscmd(mode, FLUSH) || iscmd(mode, SHOW)) && - smsg.sadb_msg_satype == SADB_SATYPE_UNSPEC) { - if (!strcmp(argv[i] + 1, "esp")) - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - else if (!strcmp(argv[i] + 1, "ah")) - smsg.sadb_msg_satype = SADB_SATYPE_AH; - else if (!strcmp(argv[i] + 1, "ip4")) - smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; - else if (!strcmp(argv[i] + 1, "tcpmd5")) - smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE; - else if (!strcmp(argv[i] + 1, "ipcomp")) - smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; - else - errx(1, "invalid SA type %s", argv[i] + 1); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "spi") && iscmd(mode, FLOW)) { - warnx("use of flag \"-spi\" is deprecated with " - "flow creation or deletion"); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "spi") && spi == SPI_LOCAL_USE && - (i + 1 < argc) && !bypass && !deny) { - ll = strtoul(argv[i + 1], &ep, 16); - if ((argv[i + 1] == '\0' || *ep != '\0') || - (errno == ERANGE && ll == ULONG_MAX) || - (ll >= SPI_RESERVED_MIN && ll <= SPI_RESERVED_MAX)) - errx(1, "invalid spi %s", argv[i + 1]); - spi = ll; - sa.sadb_sa_spi = htonl(spi); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "spi2") && spi2 == SPI_LOCAL_USE && - iscmd(mode, GRP_SPI) && (i + 1 < argc)) { - ll = strtoul(argv[i + 1], &ep, 16); - if ((argv[i + 1] == '\0' || *ep != '\0') || - (errno == ERANGE && ll == ULONG_MAX) || - (ll >= SPI_RESERVED_MIN && ll <= SPI_RESERVED_MAX)) - errx(1, "invalid spi2 %s", argv[i + 1]); - spi2 = ll; - sa2.sadb_sa_spi = htonl(spi2); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "cpi") && cpi == SPI_LOCAL_USE && - (i + 1 < argc) && !bypass && !deny) { - ll = strtoul(argv[i + 1], &ep, 16); - if ((argv[i + 1] == '\0' || *ep != '\0') || - (errno == ERANGE && ll == ULONG_MAX) || - (ll >= CPI_RESERVED_MIN && ll <= CPI_RESERVED_MAX) || - (ll > USHRT_MAX)) - errx(1, "invalid cpi %s", argv[i + 1]); - cpi = ll; - sa.sadb_sa_spi = ntohl(cpi); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "dst2") && - iscmd(mode, GRP_SPI) && (i + 1 < argc)) { - sad8.sadb_address_exttype = SADB_X_EXT_DST2; - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_family = PF_UNSPEC; - if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0) - errx(1, "destination address2 %s is not valid", - argv[i + 1]); - - if (res->ai_next) - errx(1, "destination address2 %s resolves to " - "multiple addresses", argv[i + 1]); - - switch (res->ai_family) { - case AF_INET6: - if (res->ai_addrlen != sizeof(dst2->sin6)) - errx(1, "destination address2 %s resolves " - "to unexpected address", argv[i + 1]); - memcpy(&dst2->sin6, res->ai_addr, - sizeof(dst2->sin6)); - dst2set = 1; - break; - case AF_INET: - if (res->ai_addrlen != sizeof(dst2->sin)) - errx(1, "destination address2 %s resolves " - "to unexpected address", argv[i + 1]); - memcpy(&dst2->sin, res->ai_addr, - sizeof(dst2->sin)); - dst2set = 1; - break; - default: - errx(1, "destination address2 %s resolved to " - "unsupported address family", argv[i + 1]); - /* NOTREACHED */ - } - - freeaddrinfo(res); - - if (dst2set == 0) - errx(1, "destination address2 %s is not valid", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "src") && (i + 1 < argc)) { - sad1.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_family = PF_UNSPEC; - if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0) - errx(1, "source address %s is not valid", - argv[i + 1]); - - if (res->ai_next) - errx(1, "source address %s resolves to " - "multiple addresses", argv[i + 1]); - - switch (res->ai_family) { - case AF_INET6: - if (res->ai_addrlen != sizeof(src->sin6)) - errx(1, "source address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&src->sin6, res->ai_addr, - sizeof(src->sin6)); - srcset = 1; - sad1.sadb_address_len = (sizeof(sad1) + - ROUNDUP(sizeof(struct sockaddr_in6))) / 8; - break; - case AF_INET: - if (res->ai_addrlen != sizeof(src->sin)) - errx(1, "source address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&src->sin, res->ai_addr, - sizeof(src->sin)); - srcset = 1; - sad1.sadb_address_len = (sizeof(sad1) + - ROUNDUP(sizeof(struct sockaddr_in))) / 8; - break; - default: - errx(1, "source address %s resolved to " - "unsupported address family", argv[i + 1]); - /* NOTREACHED */ - } - - freeaddrinfo(res); - - if (srcset == 0) - errx(1, "source address %s is not valid", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "proxy") && (i + 1 < argc) && !deny && - !bypass && !ipsec) { - sad3.sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_family = PF_UNSPEC; - if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0) - errx(1, "proxy address %s is not valid", - argv[i + 1]); - - if (res->ai_next) - errx(1, "proxy address %s resolves to " - "multiple addresses", argv[i + 1]); - - switch (res->ai_family) { - case AF_INET6: - if (res->ai_addrlen != sizeof(proxy->sin6)) - errx(1, "proxy address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&proxy->sin6, res->ai_addr, - sizeof(proxy->sin6)); - proxyset = 1; - sad3.sadb_address_len = (sizeof(sad3) + - ROUNDUP(sizeof(struct sockaddr_in6))) / 8; - break; - case AF_INET: - if (res->ai_addrlen != sizeof(proxy->sin)) - errx(1, "proxy address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&proxy->sin, res->ai_addr, - sizeof(proxy->sin)); - proxyset = 1; - sad3.sadb_address_len = (sizeof(sad3) + - ROUNDUP(sizeof(struct sockaddr_in))) / 8; - break; - default: - errx(1, "proxy address %s resolved to " - "unsupported address family", argv[i + 1]); - /* NOTREACHED */ - } - - freeaddrinfo(res); - - if (proxyset == 0) - errx(1, "proxy address %s is not valid", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "newpadding")) { - warnx("warning: option newpadding has been deprecated"); - continue; - } - if (!strcmp(argv[i] + 1, "in") && iscmd(mode, FLOW)) { - sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_IN; - continue; - } - if (!strcmp(argv[i] + 1, "out") && iscmd(mode, FLOW)) { - sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_OUT; - continue; - } - if (!strcmp(argv[i] + 1, "forcetunnel") && isencauth(mode)) { - sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; - continue; - } - if (!strcmp(argv[i] + 1, "udpencap") && - udpencap.sadb_x_udpencap_port == 0 && (i + 1 < argc)) { - if (!(mode & ESP_NEW)) - errx(1, "option udpencap can " - "be used only with new ESP"); - sa.sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP; - udpencap.sadb_x_udpencap_exttype = SADB_X_EXT_UDPENCAP; - udpencap.sadb_x_udpencap_len = sizeof(udpencap) / 8; - udpencap.sadb_x_udpencap_port = - strtonum(argv[i + 1], 0, USHRT_MAX, &errstr); - if (errstr) - errx(1, "invalid port %s", argv[i + 1]); - udpencap.sadb_x_udpencap_port = - htons(udpencap.sadb_x_udpencap_port); - udpencap.sadb_x_udpencap_reserved = 0; - i++; - continue; - } - if (!strcmp(argv[i] + 1, "halfiv")) { - if (!(mode & ESP_OLD)) - errx(1, "option halfiv can be used only " - "with old ESP"); - sa.sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV; - continue; - } - if (!strcmp(argv[i] + 1, "delete") && iscmd(mode, FLOW)) { - smsg.sadb_msg_type = SADB_X_DELFLOW; - continue; - } - if (!strcmp(argv[i] + 1, "local") && iscmd(mode, FLOW)) { - warnx("warning: option local has been deprecated"); - continue; - } - if (!strcmp(argv[i] + 1, "tunnel") && - (isencauth(mode) || mode == ENC_IP) && (i + 2 < argc)) { - i += 2; - sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; - continue; - } - if (!strcmp(argv[i] + 1, "srcid") && (iscmd(mode, FLOW) || - isencauth(mode)) && (i + 1 < argc)) { - int len = ROUNDUP(strlen(argv[i + 1]) + 1); - - if (srcid != NULL) - errx(1, "srcid specified multiple times"); - if ((srcid = calloc(len, sizeof(char))) == NULL) - err(1, "calloc"); - strlcpy((char *)srcid, argv[i + 1], len); - sid1.sadb_ident_len += ROUNDUP(strlen((char *)srcid) + 1) / - sizeof(u_int64_t); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "dstid") && (iscmd(mode, FLOW) || - isencauth(mode)) && (i + 1 < argc)) { - int len = ROUNDUP(strlen(argv[i + 1]) + 1); - - if (dstid != NULL) - errx(1, "dstid specified multiple times"); - if ((dstid = calloc(len, sizeof(char))) == NULL) - err(1, "calloc"); - strlcpy((char *)dstid, argv[i + 1], len); - sid2.sadb_ident_len += ROUNDUP(strlen((char *)dstid) + 1) / - sizeof(u_int64_t); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "srcid_type") && (iscmd(mode, FLOW) || - isencauth(mode)) && (i + 1 < argc)) { - if (sid1.sadb_ident_type != 0) - errx(1, "srcid_type specified multiple times"); - if (!strcmp(argv[i + 1], "prefix")) - sid1.sadb_ident_type = SADB_IDENTTYPE_PREFIX; - else if (!strcmp(argv[i + 1], "fqdn")) - sid1.sadb_ident_type = SADB_IDENTTYPE_FQDN; - else if (!strcmp(argv[i + 1], "ufqdn")) - sid1.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; - else - errx(1, "unknown identity type \"%s\"", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "dstid_type") && (iscmd(mode, FLOW) || - isencauth(mode)) && (i + 1 < argc)) { - if (sid2.sadb_ident_type != 0) - errx(1, "dstid_type specified multiple times"); - if (!strcmp(argv[i + 1], "prefix")) - sid2.sadb_ident_type = SADB_IDENTTYPE_PREFIX; - else if (!strcmp(argv[i + 1], "fqdn")) - sid2.sadb_ident_type = SADB_IDENTTYPE_FQDN; - else if (!strcmp(argv[i + 1], "ufqdn")) - sid2.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; - else - errx(1, "unknown identity type \"%s\"", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "addr") && iscmd(mode, FLOW) && - (i + 1 < argc)) { - int advance; - - sad4.sadb_address_exttype = SADB_X_EXT_SRC_FLOW; - sad5.sadb_address_exttype = SADB_X_EXT_DST_FLOW; - sad6.sadb_address_exttype = SADB_X_EXT_SRC_MASK; - sad7.sadb_address_exttype = SADB_X_EXT_DST_MASK; - - switch (addrparse(argv[i + 1], &osrc->sa, &osmask->sa)) { - case 0: - advance = 4; - if (i + 4 >= argc) - errx(1, "-addr takes 4 arguments"); - if (addrparse(argv[i + 2], &osmask->sa, NULL) != 0 || - addrparse(argv[i + 3], &odst->sa, NULL) != 0 || - addrparse(argv[i + 4], &odmask->sa, NULL) != 0) - errx(1, "invalid address on -addr"); - break; - case 1: - advance = 2; - if (i + 2 >= argc) - errx(1, "-addr takes 2 arguments"); - if (addrparse(argv[i + 2], &odst->sa, - &odmask->sa) != 1) - errx(1, "invalid address on -addr"); - break; - default: - errx(1, "invalid address %s on -addr", argv[i + 1]); - /* NOTREACHED */ - } - if (osrc->sa.sa_family != odst->sa.sa_family) - errx(1, "mixed address families specified in addr"); - sad4.sadb_address_len = (sizeof(sad4) + - ROUNDUP(osrc->sa.sa_len)) / 8; - sad5.sadb_address_len = (sizeof(sad5) + - ROUNDUP(odst->sa.sa_len)) / 8; - sad6.sadb_address_len = (sizeof(sad6) + - ROUNDUP(osmask->sa.sa_len)) / 8; - sad7.sadb_address_len = (sizeof(sad7) + - ROUNDUP(odmask->sa.sa_len)) / 8; - - i += advance; - continue; - } - if ((!strcmp(argv[i] + 1, "bypass") || !strcmp(argv[i] + 1, "permit")) - && iscmd(mode, FLOW) && !deny && - !ipsec && !bypass) { - /* Setup everything for a bypass flow */ - bypass = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS; - continue; - } - if (!strcmp(argv[i] + 1, "deny") && iscmd(mode, FLOW) && !ipsec && - !deny && !bypass) { - /* Setup everything for a deny flow */ - deny = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY; - continue; - } - if (!strcmp(argv[i] + 1, "use") && iscmd(mode, FLOW) && !deny && - !bypass && !ipsec) { - ipsec = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE; - continue; - } - if (!strcmp(argv[i] + 1, "acquire") && iscmd(mode, FLOW) && !deny && - !bypass && !ipsec) { - ipsec = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE; - continue; - } - if (!strcmp(argv[i] + 1, "require") && iscmd(mode, FLOW) && !deny && - !bypass && !ipsec) { - ipsec = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; - continue; - } - if (!strcmp(argv[i] + 1, "dontacq") && iscmd(mode, FLOW) && !deny && - !bypass && !ipsec) { - ipsec = 1; - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ; - continue; - } - if (!strcmp(argv[i] + 1, "transport") && - iscmd(mode, FLOW) && (i + 1 < argc)) { - if (isalpha(argv[i + 1][0])) { - tp = getprotobyname(argv[i + 1]); - if (tp == NULL) - errx(1, "unknown protocol %s", - argv[i + 1]); - tproto = tp->p_proto; - transportproto = argv[i + 1]; - } else { - tproto = strtonum(argv[i + 1], 0, INT_MAX, - &errstr); - if (errstr) - errx(1, "bad protocol %s", - argv[i + 1]); - tp = getprotobynumber(tproto); - if (tp == NULL) - transportproto = "UNKNOWN"; - else - transportproto = tp->p_name; - } - - sprotocol.sadb_protocol_len = 1; - sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; - sprotocol.sadb_protocol_proto = tproto; - i++; - continue; - } - if (!strcmp(argv[i] + 1, "sport") && - iscmd(mode, FLOW) && (i + 1 < argc)) { - if (isalpha(argv[i + 1][0])) { - svp = getservbyname(argv[i + 1], transportproto); - if (svp == NULL) - errx(1, "unknown service port %s for " - "protocol %s", argv[i + 1], - transportproto); - sport = svp->s_port; - } else { - sport = strtonum(argv[i + 1], 0, USHRT_MAX, - &errstr); - if (errstr) - errx(1, "invalid port %s", argv[i + 1]); - sport = htons(sport); - } - i++; - continue; - } - if (!strcmp(argv[i] + 1, "dport") && - iscmd(mode, FLOW) && (i + 1 < argc)) { - if (isalpha(argv[i + 1][0])) { - svp = getservbyname(argv[i + 1], transportproto); - if (svp == NULL) - errx(1, "unknown service port %s for " - "protocol %s", argv[i + 1], - transportproto); - dport = svp->s_port; - } else { - dport = strtonum(argv[i + 1], 0, USHRT_MAX, - &errstr); - if (errstr) - errx(1, "invalid port %s", argv[i + 1]); - dport = htons(dport); - } - i++; - continue; - } - if (!strcmp(argv[i] + 1, "dst") && (i + 1 < argc) && !bypass && !deny) { - sad2.sadb_address_exttype = SADB_EXT_ADDRESS_DST; - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_family = PF_UNSPEC; - if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0) - errx(1, "destination address %s is not valid", - argv[i + 1]); - - if (res->ai_next) - errx(1, "destination address %s resolves to " - "multiple addresses", argv[i + 1]); - - switch (res->ai_family) { - case AF_INET6: - if (res->ai_addrlen != sizeof(dst->sin6)) - errx(1, "destination address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&dst->sin6, res->ai_addr, - sizeof(dst->sin6)); - dstset = 1; - sad2.sadb_address_len = (sizeof(sad2) + - ROUNDUP(sizeof(struct sockaddr_in6))) / 8; - break; - case AF_INET: - if (res->ai_addrlen != sizeof(dst->sin)) - errx(1, "destination address %s resolves to " - "unexpected address", argv[i + 1]); - memcpy(&dst->sin, res->ai_addr, - sizeof(dst->sin)); - dstset = 1; - sad2.sadb_address_len = (sizeof(sad2) + - ROUNDUP(sizeof(struct sockaddr_in))) / 8; - break; - default: - errx(1, "destination address %s resolved to " - "unsupported address family", argv[i + 1]); - /* NOTREACHED */ - } - - freeaddrinfo(res); - - if (dstset == 0) - errx(1, "destination address %s is not valid", - argv[i + 1]); - i++; - continue; - } - if (!strcmp(argv[i] + 1, "proto2") && - iscmd(mode, GRP_SPI) && (i + 1 < argc)) { - if (isalpha(argv[i + 1][0])) { - if (!strcasecmp(argv[i + 1], "esp")) { - sprotocol.sadb_protocol_proto = sproto2 = - SADB_SATYPE_ESP; - proto2 = IPPROTO_ESP; - } else if (!strcasecmp(argv[i + 1], "ah")) { - sprotocol.sadb_protocol_proto = sproto2 = - SADB_SATYPE_AH; - proto2 = IPPROTO_AH; - } else if (!strcasecmp(argv[i + 1], "ip4")) { - sprotocol.sadb_protocol_proto = sproto2 = - SADB_X_SATYPE_IPIP; - proto2 = IPPROTO_IPIP; - } else if (!strcasecmp(argv[i + 1], "ipcomp")) { - sprotocol.sadb_protocol_proto = sproto2 = - SADB_X_SATYPE_IPCOMP; - } else - errx(1, "unknown security protocol2 " - "type %s", argv[i + 1]); - } else { - proto2 = strtonum(argv[i + 1], 0, INT_MAX, - &errstr); - if (errstr || (proto2 != IPPROTO_ESP && - proto2 != IPPROTO_AH && - proto2 != IPPROTO_IPIP && - proto2 != IPPROTO_IPCOMP)) - errx(1, "unknown security protocol2 %s", - argv[i + 1]); - if (proto2 == IPPROTO_ESP) - sprotocol.sadb_protocol_proto = sproto2 = - SADB_SATYPE_ESP; - else if (proto2 == IPPROTO_AH) - sprotocol.sadb_protocol_proto = sproto2 = - SADB_SATYPE_AH; - else if (proto2 == IPPROTO_IPIP) - sprotocol.sadb_protocol_proto = sproto2 = - SADB_X_SATYPE_IPIP; - else if (proto2 == IPPROTO_IPCOMP) - sprotocol.sadb_protocol_proto = sproto2 = - SADB_X_SATYPE_IPCOMP; - } - i++; - continue; - } - if (!strcmp(argv[i] + 1, "proto") && (i + 1 < argc) && - ((iscmd(mode, FLOW) && !bypass && !deny) || iscmd(mode, DEL_SPI) || - iscmd(mode, GRP_SPI))) { - if (isalpha(argv[i + 1][0])) { - if (!strcasecmp(argv[i + 1], "esp")) { - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - proto = IPPROTO_ESP; - } else if (!strcasecmp(argv[i + 1], "ah")) { - smsg.sadb_msg_satype = SADB_SATYPE_AH; - proto = IPPROTO_AH; - } else if (!strcasecmp(argv[i + 1], "ip4")) { - smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; - proto = IPPROTO_IPIP; - } else if (!strcasecmp(argv[i + 1], "ipcomp")) { - smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; - proto = IPPROTO_IPCOMP; - } else if (!strcasecmp(argv[i + 1], "tcpmd5")) { - smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE; - proto = IPPROTO_TCP; - } else - errx(1, "unknown security protocol type %s", - argv[i + 1]); - } else { - proto = strtonum(argv[i + 1], 0, INT_MAX, - &errstr); - if (errstr || (proto != IPPROTO_ESP && - proto != IPPROTO_AH && - proto != IPPROTO_IPIP && - proto != IPPROTO_IPCOMP)) { - errx(1, "unknown security protocol %s", - argv[i + 1]); - } - if (proto == IPPROTO_ESP) - smsg.sadb_msg_satype = SADB_SATYPE_ESP; - else if (proto == IPPROTO_AH) - smsg.sadb_msg_satype = SADB_SATYPE_AH; - else if (proto == IPPROTO_IPIP) - smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; - else if (proto == IPPROTO_IPCOMP) - smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; - } - i++; - continue; - } - errx(1, "unknown option: %s", argv[i]); - } - - if (iscmd(mode, SHOW)) { - ipsecadm_show(smsg.sadb_msg_satype); - exit(0); - } else if (iscmd(mode, MONITOR)) { - ipsecadm_monitor(); - exit(0); - } - - /* Sanity checks */ - if ((mode & (ESP_NEW | ESP_OLD)) && enc == 0 && auth == 0) - errx(1, "no encryption or authentication algorithm specified"); - if (iscmd(mode, GRP_SPI) && spi2 == SPI_LOCAL_USE) - errx(1, "no SPI2 specified"); - if ((mode & (AH_NEW | AH_OLD)) && auth == 0) - errx(1, "no authentication algorithm specified"); - if (iscmd(mode, IPCOMP) && comp == 0) - errx(1, "no compression algorithm specified"); - if ((srcid != NULL) && (sid1.sadb_ident_type == 0)) - errx(1, "srcid_type not specified"); - if ((dstid != NULL) && (sid2.sadb_ident_type == 0)) - errx(1, "dstid_type not specified"); - if ((srcid == NULL) && (sid1.sadb_ident_type != 0)) - errx(1, "srcid_type specified, but no srcid given"); - if ((dstid == NULL) && (sid2.sadb_ident_type != 0)) - errx(1, "dstid_type specified, but no dstid given"); - if (((mode & (ESP_NEW | ESP_OLD)) && enc && keyp == NULL) || - ((mode & (AH_NEW | AH_OLD | TCPMD5)) && authp == NULL)) - errx(1, "no key material specified"); - if ((mode & ESP_NEW) && auth && authp == NULL) - errx(1, "no auth key material specified"); - if (spi == SPI_LOCAL_USE && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW) - && !iscmd(mode, IPCOMP)) - errx(1, "no SPI specified"); - if (iscmd(mode, IPCOMP) && cpi == SPI_LOCAL_USE) - errx(1, "no CPI specified"); - if ((isencauth(mode) || iscmd(mode, ENC_IP)) && !srcset) - errx(1, "no source address specified"); - if (!dstset && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW)) - errx(1, "no destination address for the SA specified"); - if (iscmd(mode, FLOW) && (sprotocol.sadb_protocol_proto == 0) && - (odst->sin.sin_port || osrc->sin.sin_port)) - errx(1, "no transport protocol supplied with" - " source/destination ports"); - if (iscmd(mode, GRP_SPI) && !dst2set) - errx(1, "no destination address2 specified"); - if ((klen > 2 * 8100) || (alen > 2 * 8100)) - errx(1, "key too long"); - if (iscmd(mode, FLOW) && proto == IPPROTO_IPCOMP) - sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE; - if (keyp != NULL) - for (i = 0; i < klen; i++) - realkey[i] = x2i(keyp + 2 * i); - if (authp != NULL) - for (i = 0; i < alen; i++) - realakey[i] = x2i(authp + 2 * i); - /* message header */ - iov[cnt].iov_base = &smsg; - iov[cnt++].iov_len = sizeof(smsg); - - if (isencauth(mode) || iscmd(mode, TCPMD5)) { /* XXX */ - /* SA header */ - iov[cnt].iov_base = &sa; - iov[cnt++].iov_len = sizeof(sa); - smsg.sadb_msg_len += sa.sadb_sa_len; - - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - - if (srcid) { - iov[cnt].iov_base = &sid1; - iov[cnt++].iov_len = sizeof(sid1); - /* SRC identity */ - iov[cnt].iov_base = srcid; - iov[cnt++].iov_len = ROUNDUP(strlen((char *)srcid) + 1); - smsg.sadb_msg_len += sid1.sadb_ident_len; - } - if (dstid) { - iov[cnt].iov_base = &sid2; - iov[cnt++].iov_len = sizeof(sid2); - /* DST identity */ - iov[cnt].iov_base = dstid; - iov[cnt++].iov_len = ROUNDUP(strlen((char *)dstid) + 1); - smsg.sadb_msg_len += sid2.sadb_ident_len; - } - if (sad1.sadb_address_exttype) { - /* Source address header */ - iov[cnt].iov_base = &sad1; - iov[cnt++].iov_len = sizeof(sad1); - /* Source address */ - iov[cnt].iov_base = src; - iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len); - smsg.sadb_msg_len += sad1.sadb_address_len; - } - if (proxy->sa.sa_len) { - /* Proxy address header */ - iov[cnt].iov_base = &sad3; - iov[cnt++].iov_len = sizeof(sad3); - /* Proxy address */ - iov[cnt].iov_base = proxy; - iov[cnt++].iov_len = ROUNDUP(proxy->sa.sa_len); - smsg.sadb_msg_len += sad3.sadb_address_len; - } - if (keyp) { - /* Key header */ - iov[cnt].iov_base = &skey1; - iov[cnt++].iov_len = sizeof(skey1); - /* Key */ - iov[cnt].iov_base = realkey; - iov[cnt++].iov_len = ((klen + 7) / 8) * 8; - skey1.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; - skey1.sadb_key_len = (sizeof(skey1) + ((klen + 7) / 8) * 8) / 8; - skey1.sadb_key_bits = 8 * klen; - smsg.sadb_msg_len += skey1.sadb_key_len; - } - if (authp) { - /* Auth key header */ - iov[cnt].iov_base = &skey2; - iov[cnt++].iov_len = sizeof(skey2); - /* Auth key */ - iov[cnt].iov_base = realakey; - iov[cnt++].iov_len = ((alen + 7) / 8) * 8; - skey2.sadb_key_exttype = SADB_EXT_KEY_AUTH; - skey2.sadb_key_len = (sizeof(skey2) + ((alen + 7) / 8) * 8) / 8; - skey2.sadb_key_bits = 8 * alen; - smsg.sadb_msg_len += skey2.sadb_key_len; - } - if (sa.sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP) { - iov[cnt].iov_base = &udpencap; - iov[cnt++].iov_len = sizeof(udpencap); - smsg.sadb_msg_len += udpencap.sadb_x_udpencap_len; - } - } else { - switch (mode & CMD_MASK) { - case GRP_SPI: - /* SA header */ - iov[cnt].iov_base = &sa; - iov[cnt++].iov_len = sizeof(sa); - smsg.sadb_msg_len += sa.sadb_sa_len; - - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - - /* SA header */ - iov[cnt].iov_base = &sa2; - iov[cnt++].iov_len = sizeof(sa2); - smsg.sadb_msg_len += sa2.sadb_sa_len; - - /* Destination2 address header */ - iov[cnt].iov_base = &sad8; - iov[cnt++].iov_len = sizeof(sad8); - /* Destination2 address */ - iov[cnt].iov_base = dst2; - iov[cnt++].iov_len = ROUNDUP(dst2->sa.sa_len); - smsg.sadb_msg_len += sad8.sadb_address_len; - - sprotocol.sadb_protocol_proto = sproto2; - - /* Protocol2 */ - iov[cnt].iov_base = &sprotocol; - iov[cnt++].iov_len = sizeof(sprotocol); - smsg.sadb_msg_len += sprotocol.sadb_protocol_len; - break; - - case DEL_SPI: - /* SA header */ - iov[cnt].iov_base = &sa; - iov[cnt++].iov_len = sizeof(sa); - smsg.sadb_msg_len += sa.sadb_sa_len; - - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - break; - - case ENC_IP: - /* SA header */ - iov[cnt].iov_base = &sa; - iov[cnt++].iov_len = sizeof(sa); - smsg.sadb_msg_len += sa.sadb_sa_len; - - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - - if (sad1.sadb_address_exttype) { - /* Source address header */ - iov[cnt].iov_base = &sad1; - iov[cnt++].iov_len = sizeof(sad1); - /* Source address */ - iov[cnt].iov_base = src; - iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len); - smsg.sadb_msg_len += sad1.sadb_address_len; - } - break; - - case IPCOMP: - /* SA header */ - iov[cnt].iov_base = &sa; - iov[cnt++].iov_len = sizeof(sa); - smsg.sadb_msg_len += sa.sadb_sa_len; - - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - - if (sad1.sadb_address_exttype) { - /* Source address header */ - iov[cnt].iov_base = &sad1; - iov[cnt++].iov_len = sizeof(sad1); - /* Source address */ - iov[cnt].iov_base = src; - iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len); - smsg.sadb_msg_len += sad1.sadb_address_len; - } - break; - - case FLOW: - if ((smsg.sadb_msg_type != SADB_X_DELFLOW) && - (sad2.sadb_address_exttype)) { - /* Destination address header */ - iov[cnt].iov_base = &sad2; - iov[cnt++].iov_len = sizeof(sad2); - /* Destination address */ - iov[cnt].iov_base = dst; - iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len); - smsg.sadb_msg_len += sad2.sadb_address_len; - } - if ((sad1.sadb_address_exttype) && - (smsg.sadb_msg_type != SADB_X_DELFLOW)) { - /* Source address header */ - iov[cnt].iov_base = &sad1; - iov[cnt++].iov_len = sizeof(sad1); - /* Source address */ - iov[cnt].iov_base = src; - iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len); - smsg.sadb_msg_len += sad1.sadb_address_len; - } - if (sprotocol.sadb_protocol_len) { - /* Transport protocol */ - iov[cnt].iov_base = &sprotocol; - iov[cnt++].iov_len = sizeof(sprotocol); - smsg.sadb_msg_len += sprotocol.sadb_protocol_len; - } - /* Flow type */ - iov[cnt].iov_base = &sprotocol2; - iov[cnt++].iov_len = sizeof(sprotocol2); - smsg.sadb_msg_len += sprotocol2.sadb_protocol_len; - - /* Flow source address header */ - if ((sport != -1) && (sport != 0)) { - if (osrc->sa.sa_family == AF_INET) { - osrc->sin.sin_port = sport; - osmask->sin.sin_port = 0xffff; - } else if (osrc->sa.sa_family == AF_INET6) { - osrc->sin6.sin6_port = sport; - osmask->sin6.sin6_port = 0xffff; - } - } - iov[cnt].iov_base = &sad4; - iov[cnt++].iov_len = sizeof(sad4); - /* Flow source address */ - iov[cnt].iov_base = osrc; - iov[cnt++].iov_len = ROUNDUP(osrc->sa.sa_len); - smsg.sadb_msg_len += sad4.sadb_address_len; - - /* Flow destination address header */ - iov[cnt].iov_base = &sad5; - iov[cnt++].iov_len = sizeof(sad5); - /* Flow destination address */ - if ((dport != -1) && (dport != 0)) { - if (odst->sa.sa_family == AF_INET) { - odst->sin.sin_port = dport; - odmask->sin.sin_port = 0xffff; - } else if (odst->sa.sa_family == AF_INET6) { - odst->sin6.sin6_port = dport; - odmask->sin6.sin6_port = 0xffff; - } - } - iov[cnt].iov_base = odst; - iov[cnt++].iov_len = ROUNDUP(odst->sa.sa_len); - smsg.sadb_msg_len += sad5.sadb_address_len; - - /* Flow source address mask header */ - iov[cnt].iov_base = &sad6; - iov[cnt++].iov_len = sizeof(sad6); - /* Flow source address mask */ - iov[cnt].iov_base = osmask; - iov[cnt++].iov_len = ROUNDUP(osmask->sa.sa_len); - smsg.sadb_msg_len += sad6.sadb_address_len; - - /* Flow destination address mask header */ - iov[cnt].iov_base = &sad7; - iov[cnt++].iov_len = sizeof(sad7); - /* Flow destination address mask */ - iov[cnt].iov_base = odmask; - iov[cnt++].iov_len = ROUNDUP(odmask->sa.sa_len); - smsg.sadb_msg_len += sad7.sadb_address_len; - - if (srcid && - (smsg.sadb_msg_type != SADB_X_DELFLOW)) { - iov[cnt].iov_base = &sid1; - iov[cnt++].iov_len = sizeof(sid1); - /* SRC identity */ - iov[cnt].iov_base = srcid; - iov[cnt++].iov_len = ROUNDUP(strlen((char *)srcid) + 1); - smsg.sadb_msg_len += sid1.sadb_ident_len; - } - if (dstid && - (smsg.sadb_msg_type != SADB_X_DELFLOW)) { - iov[cnt].iov_base = &sid2; - iov[cnt++].iov_len = sizeof(sid2); - /* DST identity */ - iov[cnt].iov_base = dstid; - iov[cnt++].iov_len = ROUNDUP(strlen((char *)dstid) + 1); - smsg.sadb_msg_len += sid2.sadb_ident_len; - } - break; - - case FLUSH: - /* No more work needed */ - break; - } - } - - xf_set(iov, cnt, smsg.sadb_msg_len * 8); - exit(0); -} |