summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org>2001-07-05 08:38:37 +0000
committerJean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org>2001-07-05 08:38:37 +0000
commitffd704d3eaffdb1bf2e532b11f5877bfe01a8f50 (patch)
tree30b34877a1ffb216bc3cdc03f4cd2149c47ac82d
parent11e1afbd7661c488937f6121ecb5a3f28363aa4e (diff)
IPComp support. angelos@ ok.
-rw-r--r--sbin/ipsecadm/ipsecadm.831
-rw-r--r--sbin/ipsecadm/ipsecadm.c173
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))