diff options
-rw-r--r-- | sbin/ipsecadm/ipsecadm.8 | 31 | ||||
-rw-r--r-- | sbin/ipsecadm/ipsecadm.c | 173 |
2 files changed, 171 insertions, 33 deletions
diff --git a/sbin/ipsecadm/ipsecadm.8 b/sbin/ipsecadm/ipsecadm.8 index 3121314eb95..f44ccaa2ffe 100644 --- a/sbin/ipsecadm/ipsecadm.8 +++ b/sbin/ipsecadm/ipsecadm.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ipsecadm.8,v 1.39 2001/06/27 03:31:38 angelos Exp $ +.\" $OpenBSD: ipsecadm.8,v 1.40 2001/07/05 08:38:36 jjbg Exp $ .\" .\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> .\" All rights reserved. @@ -46,11 +46,13 @@ Before can be used, IPsec must be enabled by setting one or more of the following .Xr sysctl 3 variables: -.Bl -tag -width xxxxxxxxxxxxxxxxxxxxx +.Bl -tag -width xxxxxxxxxxxxxxxxxxxxxx .It net.inet.esp.enable Enable the ESP IPsec protocol .It net.inet.ah.enable Enable the AH IPsec protocol +.It net.inet.ipcomp.enable +Enable the IPComp protocol .El .Pp To enable these operations across reboots, see @@ -280,10 +282,27 @@ Allowed modifiers are: .Fl esp , .Fl oldah , .Fl oldesp , +.Fl ip4 , and -.Fl ip4 . +.Fl ipcomp . Default action is to flush all types of security associations from the kernel. +.It ipcomp +Setup an IP Compression Association (IPCA) which will uses the IPcomp +transforms. Just like an SA, an IPCA consists of the destination +address, a Compression Parameter Index (CPI) and a protocol (which is +fixed to IPcomp). Compression algorithms are applied. Allowed +modifiers are: +.Fl dst , +.Fl src , +.Fl cpi , +.Fl comp , +and +.Fl forcetunnel . +To create an IPsec SA using compression, an IPCA and an SA must first +be created. After this a IPCA/SA bundle must be created using the +.Nm group +keyword. The IPCA must be applied first. .El .Pp If no command is given @@ -320,6 +339,8 @@ The Security Parameter Index (SPI), given as a hexadecimal number. .It Fl spi2 The second SPI used by .Nm group . +.It Fl cpi +The Compression Parameter Index (CPI), given as a hexadecimal number. .It Fl tunnel This option has been deprecated. The arguments are ignored, and it otherwise has the same effect as the @@ -381,6 +402,10 @@ for both old and new ah and also new esp. Also .Nm rmd160 for both new ah and esp. +.It Fl comp +The compression algorithm to be used with the IPCA. The only possible value +currently is: +.Nm deflate . .It Fl key The secret symmetric key used for encryption and authentication. The size for diff --git a/sbin/ipsecadm/ipsecadm.c b/sbin/ipsecadm/ipsecadm.c index bc92278e4b0..b71e6ba26cc 100644 --- a/sbin/ipsecadm/ipsecadm.c +++ b/sbin/ipsecadm/ipsecadm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsecadm.c,v 1.59 2001/06/26 21:10:28 itojun Exp $ */ +/* $OpenBSD: ipsecadm.c,v 1.60 2001/07/05 08:38:36 jjbg Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -71,6 +71,7 @@ #define ESP_NEW 0x02 #define AH_OLD 0x04 #define AH_NEW 0x08 +#define IPCOMP 0x10 #define XF_ENC 0x10 #define XF_AUTH 0x20 @@ -79,6 +80,7 @@ #define FLOW 0x50 #define FLUSH 0x70 #define ENC_IP 0x80 +#define XF_COMP 0x90 #define CMD_MASK 0xf0 @@ -102,6 +104,7 @@ transform xf[] = { {"md5", SADB_X_AALG_MD5, XF_AUTH|AH_OLD}, {"sha1", SADB_X_AALG_SHA1,XF_AUTH|AH_OLD}, {"rmd160", SADB_AALG_RIPEMD160HMAC, XF_AUTH|AH_NEW|ESP_NEW}, + {"deflate", SADB_X_CALG_DEFLATE, XF_COMP|IPCOMP}, }; #define ROUNDUP(x) (((x) + sizeof(u_int64_t) - 1) & ~(sizeof(u_int64_t) - 1)) @@ -271,11 +274,12 @@ void usage() { fprintf(stderr, "usage: ipsecadm [command] <modifier...>\n" - "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4,\n" + "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4, ipcomp,\n" "\t\t flow, flush\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" @@ -283,6 +287,7 @@ usage() "\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" @@ -301,7 +306,7 @@ usage() "\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]\t\t\tflush a particular protocol\n" + "\t -[ah|esp|ip4|ipcomp]\t\t\tflush a particular protocol\n" "\t -srcid\t\t\tsource identity for flows\n" "\t -dstid\t\t\tdestination identity for flows\n" "\t -srcid_type\t\t\tsource identity type\n" @@ -315,8 +320,10 @@ 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 comp = 0; int dport = -1, sport = -1, tproto = -1; 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]; @@ -518,13 +525,21 @@ main(int argc, char **argv) smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; i++; } - else - { - fprintf(stderr, "%s: unknown command: %s\n", argv[0], - argv[1]); - usage(); - exit(1); - } + else + if (!strcmp(argv[1], "ipcomp")) + { + mode = IPCOMP; + smsg.sadb_msg_type = SADB_ADD; + smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; + i++; + } + else + { + fprintf(stderr, "%s: unknown command: %s\n", argv[0], + argv[1]); + usage(); + exit(1); + } for (i++; i < argc; i++) { @@ -565,6 +580,24 @@ main(int argc, char **argv) continue; } + if (!strcmp(argv[i] + 1, "comp") && comp == 0 && (i + 1 < argc)) + { + if ((comp = isvalid(argv[i + 1], XF_COMP, mode)) == 0) + { + fprintf(stderr, "%s: invalid comp algorithm %s\n", + argv[0], argv[i + 1]); + exit(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)) { @@ -734,11 +767,14 @@ main(int argc, char **argv) if(!strcmp(argv[i] + 1, "ip4")) smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP; else - { - fprintf(stderr, "%s: invalid SA type %s\n", - argv[0], argv[i + 1]); - exit(1); - } + if(!strcmp(argv[i] + 1, "ipcomp")) + smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; + else + { + fprintf(stderr, "%s: invalid SA type %s\n", + argv[0], argv[i + 1]); + exit(1); + } i++; continue; } @@ -782,6 +818,21 @@ main(int argc, char **argv) continue; } + if (!strcmp(argv[i] + 1, "cpi") && cpi == SPI_LOCAL_USE && + (i + 1 < argc) && !bypass && !deny) + { + cpi = strtoul(argv[i + 1], NULL, 16); + if (cpi >= CPI_RESERVED_MIN && (cpi <= CPI_RESERVED_MAX || + cpi >= CPI_PRIVATE_MAX)) + { + fprintf(stderr, "%s: invalid cpi %s\n", argv[0], argv[i + 1]); + exit(1); + } + + sa.sadb_sa_spi = ntohl(cpi); + i++; + continue; + } if (!strcmp(argv[i] + 1, "dst2") && iscmd(mode, GRP_SPI) && (i + 1 < argc)) @@ -1301,19 +1352,24 @@ main(int argc, char **argv) proto2 = IPPROTO_IPIP; } else - { - fprintf(stderr, - "%s: unknown security protocol2 type %s\n", - argv[0], argv[i+1]); - exit(1); - } + if (!strcasecmp(argv[i + 1], "ipcomp")) + { + sprotocol.sadb_protocol_proto = sproto2 = SADB_X_SATYPE_IPCOMP; + } + else + { + fprintf(stderr, + "%s: unknown security protocol2 type %s\n", + argv[0], argv[i+1]); + exit(1); + } } else { proto2 = atoi(argv[i + 1]); if (proto2 != IPPROTO_ESP && proto2 != IPPROTO_AH && - proto2 != IPPROTO_IPIP) + proto2 != IPPROTO_IPIP && proto2 != IPPROTO_IPCOMP) { fprintf(stderr, "%s: unknown security protocol2 %d\n", @@ -1329,6 +1385,9 @@ main(int argc, char **argv) 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++; @@ -1359,18 +1418,24 @@ main(int argc, char **argv) proto = IPPROTO_IPIP; } else - { - fprintf(stderr, - "%s: unknown security protocol type %s\n", - argv[0], argv[i + 1]); - exit(1); - } + if (!strcasecmp(argv[i + 1], "ipcomp")) + { + smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; + proto = IPPROTO_IPCOMP; + } + else + { + fprintf(stderr, + "%s: unknown security protocol type %s\n", + argv[0], argv[i + 1]); + exit(1); + } } else { proto = atoi(argv[i + 1]); if (proto != IPPROTO_ESP && proto != IPPROTO_AH && - proto != IPPROTO_IPIP) + proto != IPPROTO_IPIP && proto != IPPROTO_IPCOMP) { fprintf(stderr, "%s: unknown security protocol %d\n", @@ -1386,6 +1451,9 @@ main(int argc, char **argv) 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++; @@ -1420,6 +1488,13 @@ argfail: exit(1); } + if (iscmd(mode, IPCOMP) && comp == 0) + { + fprintf(stderr, "%s: no compression algorithm specified\n", + argv[0]); + exit(1); + } + if ((srcid != NULL) && (sid1.sadb_ident_type == 0)) { fprintf(stderr, "%s: srcid_type not specified\n", argv[0]); @@ -1459,12 +1534,19 @@ argfail: exit(1); } - if (spi == SPI_LOCAL_USE && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW)) + if (spi == SPI_LOCAL_USE && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW) + && !iscmd(mode, IPCOMP)) { fprintf(stderr, "%s: no SPI specified\n", argv[0]); exit(1); } + if (iscmd(mode, IPCOMP) && cpi == SPI_LOCAL_USE) + { + fprintf(stderr, "%s: no CPI specified\n", argv[0]); + exit(1); + } + if ((isencauth(mode) || iscmd(mode, ENC_IP)) && !srcset) { fprintf(stderr, "%s: no source address specified\n", argv[0]); @@ -1497,6 +1579,11 @@ argfail: exit(1); } + 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++) @@ -1678,6 +1765,32 @@ argfail: } 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)) |