summaryrefslogtreecommitdiff
path: root/sbin/isakmpd
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/isakmpd')
-rw-r--r--sbin/isakmpd/app.c20
-rw-r--r--sbin/isakmpd/app.h16
-rw-r--r--sbin/isakmpd/attribute.c106
-rw-r--r--sbin/isakmpd/attribute.h23
-rw-r--r--sbin/isakmpd/cert.c150
-rw-r--r--sbin/isakmpd/cert.h62
-rw-r--r--sbin/isakmpd/conf.c1763
-rw-r--r--sbin/isakmpd/conf.h52
-rw-r--r--sbin/isakmpd/connection.c610
-rw-r--r--sbin/isakmpd/connection.h22
-rw-r--r--sbin/isakmpd/constants.c80
-rw-r--r--sbin/isakmpd/constants.h22
-rw-r--r--sbin/isakmpd/cookie.c38
-rw-r--r--sbin/isakmpd/cookie.h11
-rw-r--r--sbin/isakmpd/crypto.c487
-rw-r--r--sbin/isakmpd/crypto.h93
-rw-r--r--sbin/isakmpd/dh.c36
-rw-r--r--sbin/isakmpd/dh.h12
-rw-r--r--sbin/isakmpd/dnssec.c428
-rw-r--r--sbin/isakmpd/dnssec.h6
-rw-r--r--sbin/isakmpd/doi.c31
-rw-r--r--sbin/isakmpd/doi.h88
-rw-r--r--sbin/isakmpd/exchange.h362
-rw-r--r--sbin/isakmpd/field.c253
-rw-r--r--sbin/isakmpd/field.h30
-rw-r--r--sbin/isakmpd/genconstants.sh6
-rw-r--r--sbin/isakmpd/genfields.sh10
-rw-r--r--sbin/isakmpd/gmp_util.c64
-rw-r--r--sbin/isakmpd/gmp_util.h12
-rw-r--r--sbin/isakmpd/hash.c112
-rw-r--r--sbin/isakmpd/hash.h38
-rw-r--r--sbin/isakmpd/if.c149
-rw-r--r--sbin/isakmpd/if.h10
-rw-r--r--sbin/isakmpd/ike_aggressive.c122
-rw-r--r--sbin/isakmpd/ike_aggressive.h10
-rw-r--r--sbin/isakmpd/ike_auth.c2012
-rw-r--r--sbin/isakmpd/ike_auth.h16
-rw-r--r--sbin/isakmpd/ike_main_mode.c92
-rw-r--r--sbin/isakmpd/ike_main_mode.h10
-rw-r--r--sbin/isakmpd/ike_phase_1.c2267
-rw-r--r--sbin/isakmpd/ike_phase_1.h36
-rw-r--r--sbin/isakmpd/ike_quick_mode.c3443
-rw-r--r--sbin/isakmpd/ike_quick_mode.h10
-rw-r--r--sbin/isakmpd/init.c114
-rw-r--r--sbin/isakmpd/init.h10
-rw-r--r--sbin/isakmpd/ipsec.c3676
-rw-r--r--sbin/isakmpd/ipsec.h206
-rw-r--r--sbin/isakmpd/ipsec_doi.h6
-rw-r--r--sbin/isakmpd/isakmp.h6
-rw-r--r--sbin/isakmpd/isakmp_cfg.c1617
-rw-r--r--sbin/isakmpd/isakmp_cfg.h24
-rw-r--r--sbin/isakmpd/isakmp_doi.c262
-rw-r--r--sbin/isakmpd/isakmp_doi.h8
-rw-r--r--sbin/isakmpd/isakmpd.c665
-rw-r--r--sbin/isakmpd/key.c247
-rw-r--r--sbin/isakmpd/key.h14
-rw-r--r--sbin/isakmpd/libcrypto.c13
-rw-r--r--sbin/isakmpd/libcrypto.h10
-rw-r--r--sbin/isakmpd/log.c1030
-rw-r--r--sbin/isakmpd/log.h66
-rw-r--r--sbin/isakmpd/math_2n.c1649
-rw-r--r--sbin/isakmpd/math_2n.h86
-rw-r--r--sbin/isakmpd/math_ec2n.c558
-rw-r--r--sbin/isakmpd/math_ec2n.h38
-rw-r--r--sbin/isakmpd/math_group.c1250
-rw-r--r--sbin/isakmpd/math_group.h72
-rw-r--r--sbin/isakmpd/math_mp.h6
-rw-r--r--sbin/isakmpd/message.c3724
-rw-r--r--sbin/isakmpd/message.h208
-rw-r--r--sbin/isakmpd/monitor.c1701
-rw-r--r--sbin/isakmpd/monitor.h62
-rw-r--r--sbin/isakmpd/monitor_fdpass.c126
-rw-r--r--sbin/isakmpd/pf_key_v2.c7047
-rw-r--r--sbin/isakmpd/pf_key_v2.h33
-rw-r--r--sbin/isakmpd/policy.c3751
-rw-r--r--sbin/isakmpd/policy.h58
-rw-r--r--sbin/isakmpd/prf.c186
-rw-r--r--sbin/isakmpd/prf.h28
-rw-r--r--sbin/isakmpd/sa.c1742
-rw-r--r--sbin/isakmpd/sa.h314
-rw-r--r--sbin/isakmpd/sysdep.h41
-rw-r--r--sbin/isakmpd/sysdep/openbsd/keynote_compat.c16
-rw-r--r--sbin/isakmpd/sysdep/openbsd/sysdep.c250
-rw-r--r--sbin/isakmpd/timer.c150
-rw-r--r--sbin/isakmpd/timer.h30
-rw-r--r--sbin/isakmpd/transport.c465
-rw-r--r--sbin/isakmpd/transport.h140
-rw-r--r--sbin/isakmpd/udp.c1317
-rw-r--r--sbin/isakmpd/udp.h16
-rw-r--r--sbin/isakmpd/ui.c584
-rw-r--r--sbin/isakmpd/ui.h16
-rw-r--r--sbin/isakmpd/util.c613
-rw-r--r--sbin/isakmpd/util.h48
-rw-r--r--sbin/isakmpd/x509.c2383
-rw-r--r--sbin/isakmpd/x509.h58
95 files changed, 24054 insertions, 25906 deletions
diff --git a/sbin/isakmpd/app.c b/sbin/isakmpd/app.c
index af06b59bb9d..a04aa14a8e4 100644
--- a/sbin/isakmpd/app.c
+++ b/sbin/isakmpd/app.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: app.c,v 1.8 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: app.c,v 1.6 1999/05/01 20:21:06 niklas Exp $ */
+/* $OpenBSD: app.c,v 1.9 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: app.c,v 1.6 1999/05/01 20:21:06 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -47,17 +47,17 @@ int app_none = 0;
/* Initialize applications. */
void
-app_init (void)
+app_init(void)
{
- if (app_none)
- return;
- app_socket = sysdep_app_open ();
- if (app_socket == -1)
- log_fatal ("app_init: cannot open connection to application");
+ if (app_none)
+ return;
+ app_socket = sysdep_app_open();
+ if (app_socket == -1)
+ log_fatal("app_init: cannot open connection to application");
}
void
-app_handler (void)
+app_handler(void)
{
- sysdep_app_handler (app_socket);
+ sysdep_app_handler(app_socket);
}
diff --git a/sbin/isakmpd/app.h b/sbin/isakmpd/app.h
index 79c53c95486..96a2864e453 100644
--- a/sbin/isakmpd/app.h
+++ b/sbin/isakmpd/app.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: app.h,v 1.6 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: app.h,v 1.4 1999/04/02 00:58:16 niklas Exp $ */
+/* $OpenBSD: app.h,v 1.7 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: app.h,v 1.4 1999/04/02 00:58:16 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -32,11 +32,11 @@
#ifndef _APP_H_
#define _APP_H_
-extern int app_socket;
-extern int app_none;
+extern int app_socket;
+extern int app_none;
-extern void app_conf_init_hook (void);
-extern void app_handler (void);
-extern void app_init (void);
+extern void app_conf_init_hook(void);
+extern void app_handler(void);
+extern void app_init(void);
-#endif /* _APP_H_ */
+#endif /* _APP_H_ */
diff --git a/sbin/isakmpd/attribute.c b/sbin/isakmpd/attribute.c
index bfeb3cb9d3d..e1959290162 100644
--- a/sbin/isakmpd/attribute.c
+++ b/sbin/isakmpd/attribute.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: attribute.c,v 1.9 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: attribute.c,v 1.10 2000/02/20 19:58:36 niklas Exp $ */
+/* $OpenBSD: attribute.c,v 1.10 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: attribute.c,v 1.10 2000/02/20 19:58:36 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -40,22 +40,22 @@
#include "isakmp.h"
#include "util.h"
-u_int8_t *
-attribute_set_basic (u_int8_t *buf, u_int16_t type, u_int16_t value)
+u_int8_t *
+attribute_set_basic(u_int8_t * buf, u_int16_t type, u_int16_t value)
{
- SET_ISAKMP_ATTR_TYPE (buf, ISAKMP_ATTR_MAKE (1, type));
- SET_ISAKMP_ATTR_LENGTH_VALUE (buf, value);
- return buf + ISAKMP_ATTR_VALUE_OFF;
+ SET_ISAKMP_ATTR_TYPE(buf, ISAKMP_ATTR_MAKE(1, type));
+ SET_ISAKMP_ATTR_LENGTH_VALUE(buf, value);
+ return buf + ISAKMP_ATTR_VALUE_OFF;
}
-u_int8_t *
-attribute_set_var (u_int8_t *buf, u_int16_t type, u_int8_t *value,
- u_int16_t len)
+u_int8_t *
+attribute_set_var(u_int8_t * buf, u_int16_t type, u_int8_t * value,
+ u_int16_t len)
{
- SET_ISAKMP_ATTR_TYPE (buf, ISAKMP_ATTR_MAKE (0, type));
- SET_ISAKMP_ATTR_LENGTH_VALUE (buf, len);
- memcpy (buf + ISAKMP_ATTR_VALUE_OFF, value, len);
- return buf + ISAKMP_ATTR_VALUE_OFF + len;
+ SET_ISAKMP_ATTR_TYPE(buf, ISAKMP_ATTR_MAKE(0, type));
+ SET_ISAKMP_ATTR_LENGTH_VALUE(buf, len);
+ memcpy(buf + ISAKMP_ATTR_VALUE_OFF, value, len);
+ return buf + ISAKMP_ATTR_VALUE_OFF + len;
}
/*
@@ -65,51 +65,49 @@ attribute_set_var (u_int8_t *buf, u_int16_t type, u_int8_t *value,
* -1 return value. If all goes well return zero.
*/
int
-attribute_map (u_int8_t *buf, size_t sz,
- int (*func) (u_int16_t, u_int8_t *, u_int16_t, void *),
- void *arg)
+attribute_map(u_int8_t * buf, size_t sz,
+ int (*func) (u_int16_t, u_int8_t *, u_int16_t, void *),
+ void *arg)
{
- u_int8_t *attr;
- int fmt;
- u_int16_t type;
- u_int8_t *value;
- u_int16_t len;
+ u_int8_t *attr;
+ int fmt;
+ u_int16_t type;
+ u_int8_t *value;
+ u_int16_t len;
- for (attr = buf; attr < buf + sz; attr = value + len)
- {
- if (attr + ISAKMP_ATTR_VALUE_OFF > buf + sz)
- return -1;
- type = GET_ISAKMP_ATTR_TYPE (attr);
- fmt = ISAKMP_ATTR_FORMAT (type);
- type = ISAKMP_ATTR_TYPE (type);
- value
- = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF : ISAKMP_ATTR_VALUE_OFF);
- len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN
- : GET_ISAKMP_ATTR_LENGTH_VALUE (attr));
- if (value + len > buf + sz)
- return -1;
- if (func (type, value, len, arg))
- return -1;
- }
- return 0;
+ for (attr = buf; attr < buf + sz; attr = value + len) {
+ if (attr + ISAKMP_ATTR_VALUE_OFF > buf + sz)
+ return -1;
+ type = GET_ISAKMP_ATTR_TYPE(attr);
+ fmt = ISAKMP_ATTR_FORMAT(type);
+ type = ISAKMP_ATTR_TYPE(type);
+ value
+ = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF : ISAKMP_ATTR_VALUE_OFF);
+ len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN
+ : GET_ISAKMP_ATTR_LENGTH_VALUE(attr));
+ if (value + len > buf + sz)
+ return -1;
+ if (func(type, value, len, arg))
+ return -1;
+ }
+ return 0;
}
int
-attribute_set_constant (char *section, char *tag, struct constant_map *map,
- int attr_class, u_int8_t **attr)
+attribute_set_constant(char *section, char *tag, struct constant_map * map,
+ int attr_class, u_int8_t ** attr)
{
- char *name;
- int value;
+ char *name;
+ int value;
- name = conf_get_str (section, tag);
- if (!name)
- {
- LOG_DBG ((LOG_MISC, 70,
- "attribute_set_constant: no %s in the %s section", tag,
- section));
- return -1;
- }
- value = constant_value (map, name);
- *attr = attribute_set_basic (*attr, attr_class, value);
- return 0;
+ name = conf_get_str(section, tag);
+ if (!name) {
+ LOG_DBG((LOG_MISC, 70,
+ "attribute_set_constant: no %s in the %s section", tag,
+ section));
+ return -1;
+ }
+ value = constant_value(map, name);
+ *attr = attribute_set_basic(*attr, attr_class, value);
+ return 0;
}
diff --git a/sbin/isakmpd/attribute.h b/sbin/isakmpd/attribute.h
index 86ebbad456c..29de52fb769 100644
--- a/sbin/isakmpd/attribute.h
+++ b/sbin/isakmpd/attribute.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: attribute.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: attribute.h,v 1.2 1998/09/29 21:51:07 niklas Exp $ */
+/* $OpenBSD: attribute.h,v 1.5 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: attribute.h,v 1.2 1998/09/29 21:51:07 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -36,13 +36,14 @@
struct constant_map;
-extern int attribute_map (u_int8_t *, size_t,
- int (*) (u_int16_t, u_int8_t *, u_int16_t, void *),
- void *);
-extern u_int8_t *attribute_set_basic (u_int8_t *, u_int16_t, u_int16_t);
-extern int attribute_set_constant (char *, char *, struct constant_map *,
- int, u_int8_t **);
-extern u_int8_t *attribute_set_var (u_int8_t *, u_int16_t, u_int8_t *,
- u_int16_t);
+extern int
+attribute_map(u_int8_t *, size_t,
+ int (*) (u_int16_t, u_int8_t *, u_int16_t, void *),
+ void *);
+ extern u_int8_t *attribute_set_basic(u_int8_t *, u_int16_t, u_int16_t);
+ extern int attribute_set_constant(char *, char *, struct constant_map *,
+ int, u_int8_t **);
+ extern u_int8_t *attribute_set_var(u_int8_t *, u_int16_t, u_int8_t *,
+ u_int16_t);
-#endif /* _ATTRIBUTE_H_ */
+#endif /* _ATTRIBUTE_H_ */
diff --git a/sbin/isakmpd/cert.c b/sbin/isakmpd/cert.c
index dd77098fc9b..13124ecd8a7 100644
--- a/sbin/isakmpd/cert.c
+++ b/sbin/isakmpd/cert.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cert.c,v 1.25 2004/03/31 10:54:46 ho Exp $ */
-/* $EOM: cert.c,v 1.18 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: cert.c,v 1.26 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: cert.c,v 1.18 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -51,65 +51,64 @@
struct cert_handler cert_handler[] = {
#ifdef USE_X509
- {
- ISAKMP_CERTENC_X509_SIG,
- x509_cert_init, x509_crl_init, x509_cert_get, x509_cert_validate,
- x509_cert_insert, x509_cert_free,
- x509_certreq_validate, x509_certreq_decode, x509_free_aca,
- x509_cert_obtain, x509_cert_get_key, x509_cert_get_subjects,
- x509_cert_dup, x509_serialize, x509_printable, x509_from_printable
- },
+ {
+ ISAKMP_CERTENC_X509_SIG,
+ x509_cert_init, x509_crl_init, x509_cert_get, x509_cert_validate,
+ x509_cert_insert, x509_cert_free,
+ x509_certreq_validate, x509_certreq_decode, x509_free_aca,
+ x509_cert_obtain, x509_cert_get_key, x509_cert_get_subjects,
+ x509_cert_dup, x509_serialize, x509_printable, x509_from_printable
+ },
#endif
#ifdef USE_KEYNOTE
- {
- ISAKMP_CERTENC_KEYNOTE,
- keynote_cert_init, NULL, keynote_cert_get, keynote_cert_validate,
- keynote_cert_insert, keynote_cert_free,
- keynote_certreq_validate, keynote_certreq_decode, keynote_free_aca,
- keynote_cert_obtain, keynote_cert_get_key, keynote_cert_get_subjects,
- keynote_cert_dup, keynote_serialize, keynote_printable,
- keynote_from_printable
- },
+ {
+ ISAKMP_CERTENC_KEYNOTE,
+ keynote_cert_init, NULL, keynote_cert_get, keynote_cert_validate,
+ keynote_cert_insert, keynote_cert_free,
+ keynote_certreq_validate, keynote_certreq_decode, keynote_free_aca,
+ keynote_cert_obtain, keynote_cert_get_key, keynote_cert_get_subjects,
+ keynote_cert_dup, keynote_serialize, keynote_printable,
+ keynote_from_printable
+ },
#endif
};
/* Initialize all certificate handlers */
-
int
-cert_init (void)
+cert_init(void)
{
- size_t i;
- int err = 1;
+ size_t i;
+ int err = 1;
- for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
- if (cert_handler[i].cert_init && !(*cert_handler[i].cert_init) ())
- err = 0;
+ for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
+ if (cert_handler[i].cert_init && !(*cert_handler[i].cert_init) ())
+ err = 0;
- return err;
+ return err;
}
int
-crl_init (void)
+crl_init(void)
{
- size_t i;
- int err = 1;
+ size_t i;
+ int err = 1;
- for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
- if (cert_handler[i].crl_init && !(*cert_handler[i].crl_init) ())
- err = 0;
+ for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
+ if (cert_handler[i].crl_init && !(*cert_handler[i].crl_init) ())
+ err = 0;
- return err;
+ return err;
}
struct cert_handler *
-cert_get (u_int16_t id)
+cert_get(u_int16_t id)
{
- size_t i;
+ size_t i;
- for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
- if (id == cert_handler[i].id)
- return &cert_handler[i];
- return 0;
+ for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
+ if (id == cert_handler[i].id)
+ return &cert_handler[i];
+ return 0;
}
/*
@@ -118,48 +117,43 @@ cert_get (u_int16_t id)
* responsible for deallocating.
*/
struct certreq_aca *
-certreq_decode (u_int16_t type, u_int8_t *data, u_int32_t datalen)
+certreq_decode(u_int16_t type, u_int8_t *data, u_int32_t datalen)
{
- struct cert_handler *handler;
- struct certreq_aca aca, *ret;
-
- handler = cert_get (type);
- if (!handler)
- return 0;
-
- aca.id = type;
- aca.handler = handler;
-
- if (datalen > 0)
- {
- aca.data = handler->certreq_decode (data, datalen);
- if (!aca.data)
- return 0;
- }
- else
- aca.data = 0;
-
- ret = malloc (sizeof aca);
- if (!ret)
- {
- log_error ("certreq_decode: malloc (%lu) failed",
- (unsigned long)sizeof aca);
- handler->free_aca (aca.data);
- return 0;
- }
-
- memcpy (ret, &aca, sizeof aca);
-
- return ret;
+ struct cert_handler *handler;
+ struct certreq_aca aca, *ret;
+
+ handler = cert_get(type);
+ if (!handler)
+ return 0;
+
+ aca.id = type;
+ aca.handler = handler;
+
+ if (datalen > 0) {
+ aca.data = handler->certreq_decode(data, datalen);
+ if (!aca.data)
+ return 0;
+ } else
+ aca.data = 0;
+
+ ret = malloc(sizeof aca);
+ if (!ret) {
+ log_error("certreq_decode: malloc (%lu) failed",
+ (unsigned long) sizeof aca);
+ handler->free_aca(aca.data);
+ return 0;
+ }
+ memcpy(ret, &aca, sizeof aca);
+ return ret;
}
void
-cert_free_subjects (int n, u_int8_t **id, u_int32_t *len)
+cert_free_subjects(int n, u_int8_t **id, u_int32_t *len)
{
- int i;
+ int i;
- for (i = 0; i < n; i++)
- free (id[i]);
- free (id);
- free (len);
+ for (i = 0; i < n; i++)
+ free(id[i]);
+ free(id);
+ free(len);
}
diff --git a/sbin/isakmpd/cert.h b/sbin/isakmpd/cert.h
index dd19f0edb6d..ea9da823eb2 100644
--- a/sbin/isakmpd/cert.h
+++ b/sbin/isakmpd/cert.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: cert.h,v 1.12 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: cert.h,v 1.8 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: cert.h,v 1.13 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: cert.h,v 1.8 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -55,40 +55,42 @@
*/
struct cert_handler {
- u_int16_t id; /* ISAKMP Cert Encoding ID */
- int (*cert_init) (void);
- int (*crl_init) (void);
- void *(*cert_get) (u_int8_t *, u_int32_t);
- int (*cert_validate) (void *);
- int (*cert_insert) (int, void *);
- void (*cert_free) (void *);
- int (*certreq_validate) (u_int8_t *, u_int32_t);
- void *(*certreq_decode) (u_int8_t *, u_int32_t);
- void (*free_aca) (void *);
- int (*cert_obtain) (u_int8_t *, size_t, void *, u_int8_t **, u_int32_t *);
- int (*cert_get_key) (void *, void *);
- int (*cert_get_subjects) (void *, int *, u_int8_t ***, u_int32_t **);
- void *(*cert_dup) (void *);
- void (*cert_serialize) (void *, u_int8_t **, u_int32_t *);
- char *(*cert_printable) (void *);
- void *(*cert_from_printable) (char *);
+ u_int16_t id; /* ISAKMP Cert Encoding ID */
+ int (*cert_init) (void);
+ int (*crl_init) (void);
+ void *(*cert_get) (u_int8_t *, u_int32_t);
+ int (*cert_validate) (void *);
+ int (*cert_insert) (int, void *);
+ void (*cert_free) (void *);
+ int (*certreq_validate) (u_int8_t *, u_int32_t);
+ void *(*certreq_decode) (u_int8_t *, u_int32_t);
+ void (*free_aca) (void *);
+ int (*cert_obtain) (u_int8_t *, size_t, void *,
+ u_int8_t **, u_int32_t *);
+ int (*cert_get_key) (void *, void *);
+ int (*cert_get_subjects) (void *, int *, u_int8_t ***,
+ u_int32_t **);
+ void *(*cert_dup) (void *);
+ void (*cert_serialize) (void *, u_int8_t **, u_int32_t *);
+ char *(*cert_printable) (void *);
+ void *(*cert_from_printable) (char *);
};
/* The acceptable authority of cert request. */
struct certreq_aca {
- TAILQ_ENTRY (certreq_aca) link;
+ TAILQ_ENTRY(certreq_aca) link;
- u_int16_t id;
- struct cert_handler *handler;
+ u_int16_t id;
+ struct cert_handler *handler;
- /* If data is a null pointer, everything is acceptable. */
- void *data;
+ /* If data is a null pointer, everything is acceptable. */
+ void *data;
};
-struct certreq_aca *certreq_decode (u_int16_t, u_int8_t *, u_int32_t);
-void cert_free_subjects (int, u_int8_t **, u_int32_t *);
-struct cert_handler *cert_get (u_int16_t);
-int cert_init (void);
-int crl_init (void);
+struct certreq_aca *certreq_decode(u_int16_t, u_int8_t *, u_int32_t);
+void cert_free_subjects(int, u_int8_t **, u_int32_t *);
+struct cert_handler *cert_get(u_int16_t);
+int cert_init(void);
+int crl_init(void);
-#endif /* _CERT_H_ */
+#endif /* _CERT_H_ */
diff --git a/sbin/isakmpd/conf.c b/sbin/isakmpd/conf.c
index bb929315f38..7efd7fa5524 100644
--- a/sbin/isakmpd/conf.c
+++ b/sbin/isakmpd/conf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: conf.c,v 1.62 2004/03/19 14:04:43 hshoexer Exp $ */
-/* $EOM: conf.c,v 1.48 2000/12/04 02:04:29 angelos Exp $ */
+/* $OpenBSD: conf.c,v 1.63 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: conf.c,v 1.48 2000/12/04 02:04:29 angelos Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -53,126 +53,123 @@
#include "monitor.h"
#include "util.h"
-static char *conf_get_trans_str (int, char *, char *);
-static void conf_load_defaults (int);
+static char *conf_get_trans_str(int, char *, char *);
+static void conf_load_defaults(int);
#if 0
-static int conf_find_trans_xf (int, char *);
+static int conf_find_trans_xf(int, char *);
#endif
struct conf_trans {
- TAILQ_ENTRY (conf_trans) link;
- int trans;
- enum conf_op { CONF_SET, CONF_REMOVE, CONF_REMOVE_SECTION } op;
- char *section;
- char *tag;
- char *value;
- int override;
- int is_default;
+ TAILQ_ENTRY(conf_trans) link;
+ int trans;
+ enum conf_op {
+ CONF_SET, CONF_REMOVE, CONF_REMOVE_SECTION
+ } op;
+ char *section;
+ char *tag;
+ char *value;
+ int override;
+ int is_default;
};
-TAILQ_HEAD (conf_trans_head, conf_trans) conf_trans_queue;
+TAILQ_HEAD(conf_trans_head, conf_trans) conf_trans_queue;
/*
* Radix-64 Encoding.
*/
-const u_int8_t bin2asc[]
- = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const u_int8_t bin2asc[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-const u_int8_t asc2bin[] =
+ const u_int8_t asc2bin[] =
+ {
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 255, 255, 255, 255, 255, 255,
+ 255, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 255, 255, 255, 255, 255
+ };
+
+ struct conf_binding {
+ LIST_ENTRY(conf_binding) link;
+ char *section;
+ char *tag;
+ char *value;
+ int is_default;
+ };
+
+ char *conf_path = CONFIG_FILE;
+LIST_HEAD(conf_bindings, conf_binding) conf_bindings[256];
+
+ static char *conf_addr;
+
+ static __inline__ u_int8_t
+ conf_hash(char *s)
{
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 62, 255, 255, 255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 255, 255, 255, 255, 255, 255,
- 255, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 255, 255, 255, 255, 255,
- 255, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 255, 255, 255, 255, 255
-};
-
-struct conf_binding {
- LIST_ENTRY (conf_binding) link;
- char *section;
- char *tag;
- char *value;
- int is_default;
-};
+ u_int8_t hash = 0;
-char *conf_path = CONFIG_FILE;
-LIST_HEAD (conf_bindings, conf_binding) conf_bindings[256];
-
-static char *conf_addr;
-
-static __inline__ u_int8_t
-conf_hash (char *s)
-{
- u_int8_t hash = 0;
-
- while (*s)
- {
- hash = ((hash << 1) | (hash >> 7)) ^ tolower (*s);
- s++;
- }
- return hash;
+ while (*s) {
+ hash = ((hash << 1) | (hash >> 7)) ^ tolower(*s);
+ s++;
+ }
+ return hash;
}
/*
* Insert a tag-value combination from LINE (the equal sign is at POS)
*/
static int
-conf_remove_now (char *section, char *tag)
+conf_remove_now(char *section, char *tag)
{
- struct conf_binding *cb, *next;
-
- for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; cb = next)
- {
- next = LIST_NEXT (cb, link);
- if (strcasecmp (cb->section, section) == 0
- && strcasecmp (cb->tag, tag) == 0)
- {
- LIST_REMOVE (cb, link);
- LOG_DBG ((LOG_MISC, 95, "[%s]:%s->%s removed", section, tag,
- cb->value));
- free (cb->section);
- free (cb->tag);
- free (cb->value);
- free (cb);
- return 0;
+ struct conf_binding *cb, *next;
+
+ for (cb = LIST_FIRST(&conf_bindings[conf_hash(section)]); cb; cb = next) {
+ next = LIST_NEXT(cb, link);
+ if (strcasecmp(cb->section, section) == 0
+ && strcasecmp(cb->tag, tag) == 0) {
+ LIST_REMOVE(cb, link);
+ LOG_DBG((LOG_MISC, 95, "[%s]:%s->%s removed", section, tag,
+ cb->value));
+ free(cb->section);
+ free(cb->tag);
+ free(cb->value);
+ free(cb);
+ return 0;
+ }
}
- }
- return 1;
+ return 1;
}
static int
-conf_remove_section_now (char *section)
+conf_remove_section_now(char *section)
{
- struct conf_binding *cb, *next;
- int unseen = 1;
-
- for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; cb = next)
- {
- next = LIST_NEXT (cb, link);
- if (strcasecmp (cb->section, section) == 0)
- {
- unseen = 0;
- LIST_REMOVE (cb, link);
- LOG_DBG ((LOG_MISC, 95, "[%s]:%s->%s removed", section, cb->tag,
- cb->value));
- free (cb->section);
- free (cb->tag);
- free (cb->value);
- free (cb);
+ struct conf_binding *cb, *next;
+ int unseen = 1;
+
+ for (cb = LIST_FIRST(&conf_bindings[conf_hash(section)]); cb; cb = next) {
+ next = LIST_NEXT(cb, link);
+ if (strcasecmp(cb->section, section) == 0) {
+ unseen = 0;
+ LIST_REMOVE(cb, link);
+ LOG_DBG((LOG_MISC, 95, "[%s]:%s->%s removed", section, cb->tag,
+ cb->value));
+ free(cb->section);
+ free(cb->tag);
+ free(cb->value);
+ free(cb);
+ }
}
- }
- return unseen;
+ return unseen;
}
/*
@@ -180,37 +177,34 @@ conf_remove_section_now (char *section)
* into SECTION of our configuration database.
*/
static int
-conf_set_now (char *section, char *tag, char *value, int override,
- int is_default)
+conf_set_now(char *section, char *tag, char *value, int override,
+ int is_default)
{
- struct conf_binding *node = 0;
-
- if (override)
- conf_remove_now (section, tag);
- else if (conf_get_str (section, tag))
- {
- if (!is_default)
- log_print ("conf_set_now: duplicate tag [%s]:%s, ignoring...\n",
- section, tag);
- return 1;
- }
-
- node = calloc (1, sizeof *node);
- if (!node)
- {
- log_error ("conf_set_now: calloc (1, %lu) failed", (unsigned long)sizeof
- * node);
- return 1;
- }
- node->section = strdup (section);
- node->tag = strdup (tag);
- node->value = strdup (value);
- node->is_default = is_default;
-
- LIST_INSERT_HEAD (&conf_bindings[conf_hash (section)], node, link);
- LOG_DBG ((LOG_MISC, 95, "conf_set_now: [%s]:%s->%s", node->section, node->tag,
- node->value));
- return 0;
+ struct conf_binding *node = 0;
+
+ if (override)
+ conf_remove_now(section, tag);
+ else if (conf_get_str(section, tag)) {
+ if (!is_default)
+ log_print("conf_set_now: duplicate tag [%s]:%s, ignoring...\n",
+ section, tag);
+ return 1;
+ }
+ node = calloc(1, sizeof *node);
+ if (!node) {
+ log_error("conf_set_now: calloc (1, %lu) failed", (unsigned long) sizeof
+ *node);
+ return 1;
+ }
+ node->section = strdup(section);
+ node->tag = strdup(tag);
+ node->value = strdup(value);
+ node->is_default = is_default;
+
+ LIST_INSERT_HEAD(&conf_bindings[conf_hash(section)], node, link);
+ LOG_DBG((LOG_MISC, 95, "conf_set_now: [%s]:%s->%s", node->section, node->tag,
+ node->value));
+ return 0;
}
/*
@@ -218,102 +212,92 @@ conf_set_now (char *section, char *tag, char *value, int override,
* headers and feed tag-value pairs into our configuration database.
*/
static void
-conf_parse_line (int trans, char *line, size_t sz)
+conf_parse_line(int trans, char *line, size_t sz)
{
- char *val;
- size_t i;
- int j;
- static char *section = 0;
- static int ln = 0;
-
- ln++;
-
- /* Lines starting with '#' or ';' are comments. */
- if (*line == '#' || *line == ';')
- return;
-
- /* '[section]' parsing... */
- if (*line == '[')
- {
- for (i = 1; i < sz; i++)
- if (line[i] == ']')
- break;
- if (section)
- free (section);
- if (i == sz)
- {
- log_print ("conf_parse_line: %d:"
- "non-matched ']', ignoring until next section", ln);
- section = 0;
- return;
- }
- section = malloc (i);
- if (!section)
- {
- log_print ("conf_parse_line: %d: malloc (%lu) failed", ln,
- (unsigned long)i);
- return;
+ char *val;
+ size_t i;
+ int j;
+ static char *section = 0;
+ static int ln = 0;
+
+ ln++;
+
+ /* Lines starting with '#' or ';' are comments. */
+ if (*line == '#' || *line == ';')
+ return;
+
+ /* '[section]' parsing... */
+ if (*line == '[') {
+ for (i = 1; i < sz; i++)
+ if (line[i] == ']')
+ break;
+ if (section)
+ free(section);
+ if (i == sz) {
+ log_print("conf_parse_line: %d:"
+ "non-matched ']', ignoring until next section", ln);
+ section = 0;
+ return;
+ }
+ section = malloc(i);
+ if (!section) {
+ log_print("conf_parse_line: %d: malloc (%lu) failed", ln,
+ (unsigned long) i);
+ return;
+ }
+ strlcpy(section, line + 1, i);
+ return;
}
- strlcpy (section, line + 1, i);
- return;
- }
-
- /* Deal with assignments. */
- for (i = 0; i < sz; i++)
- if (line[i] == '=')
- {
- /* If no section, we are ignoring the lines. */
- if (!section)
- {
- log_print ("conf_parse_line: %d: ignoring line due to no section",
- ln);
- return;
- }
- line[strcspn (line, " \t=")] = '\0';
- val = line + i + 1 + strspn (line + i + 1, " \t");
- /* Skip trailing whitespace, if any */
- for (j = sz - (val - line) - 1; j > 0 && isspace (val[j]); j--)
- val[j] = '\0';
- /* XXX Perhaps should we not ignore errors? */
- conf_set (trans, section, line, val, 0, 0);
- return;
- }
-
- /* Other non-empty lines are weird. */
- i = strspn (line, " \t");
- if (line[i])
- log_print ("conf_parse_line: %d: syntax error", ln);
+ /* Deal with assignments. */
+ for (i = 0; i < sz; i++)
+ if (line[i] == '=') {
+ /* If no section, we are ignoring the lines. */
+ if (!section) {
+ log_print("conf_parse_line: %d: ignoring line due to no section",
+ ln);
+ return;
+ }
+ line[strcspn(line, " \t=")] = '\0';
+ val = line + i + 1 + strspn(line + i + 1, " \t");
+ /* Skip trailing whitespace, if any */
+ for (j = sz - (val - line) - 1; j > 0 && isspace(val[j]); j--)
+ val[j] = '\0';
+ /* XXX Perhaps should we not ignore errors? */
+ conf_set(trans, section, line, val, 0, 0);
+ return;
+ }
+ /* Other non-empty lines are weird. */
+ i = strspn(line, " \t");
+ if (line[i])
+ log_print("conf_parse_line: %d: syntax error", ln);
- return;
+ return;
}
/* Parse the mapped configuration file. */
static void
-conf_parse (int trans, char *buf, size_t sz)
+conf_parse(int trans, char *buf, size_t sz)
{
- char *cp = buf;
- char *bufend = buf + sz;
- char *line;
-
- line = cp;
- while (cp < bufend)
- {
- if (*cp == '\n')
- {
- /* Check for escaped newlines. */
- if (cp > buf && *(cp - 1) == '\\')
- *(cp - 1) = *cp = ' ';
- else
- {
- *cp = '\0';
- conf_parse_line (trans, line, cp - line);
- line = cp + 1;
- }
+ char *cp = buf;
+ char *bufend = buf + sz;
+ char *line;
+
+ line = cp;
+ while (cp < bufend) {
+ if (*cp == '\n') {
+ /* Check for escaped newlines. */
+ if (cp > buf && *(cp - 1) == '\\')
+ *(cp - 1) = *cp = ' ';
+ else {
+ *cp = '\0';
+ conf_parse_line(trans, line, cp - line);
+ line = cp + 1;
+ }
+ }
+ cp++;
}
- cp++;
- }
- if (cp != line)
- log_print ("conf_parse: last line non-terminated, ignored.");
+ if (cp != line)
+ log_print("conf_parse: last line non-terminated, ignored.");
}
/*
@@ -338,310 +322,328 @@ conf_parse (int trans, char *buf, size_t sz)
*/
/* Find the value for a section+tag in the transaction list. */
-static char *
-conf_get_trans_str (int trans, char *section, char *tag)
+static char *
+conf_get_trans_str(int trans, char *section, char *tag)
{
- struct conf_trans *node, *nf = 0;
-
- for (node = TAILQ_FIRST (&conf_trans_queue); node;
- node = TAILQ_NEXT (node, link))
- if (node->trans == trans && strcasecmp (section, node->section) == 0
- && strcasecmp (tag, node->tag) == 0)
- {
- if (!nf)
- nf = node;
- else if (node->override)
- nf = node;
- }
- return nf ? nf->value : 0;
+ struct conf_trans *node, *nf = 0;
+
+ for (node = TAILQ_FIRST(&conf_trans_queue); node;
+ node = TAILQ_NEXT(node, link))
+ if (node->trans == trans && strcasecmp(section, node->section) == 0
+ && strcasecmp(tag, node->tag) == 0) {
+ if (!nf)
+ nf = node;
+ else if (node->override)
+ nf = node;
+ }
+ return nf ? nf->value : 0;
}
#if 0
/* XXX Currently unused. */
static int
-conf_find_trans_xf (int phase, char *xf)
+conf_find_trans_xf(int phase, char *xf)
{
- struct conf_trans *node;
- char *p;
-
- /* Find the relevant transforms and suites, if any. */
- for (node = TAILQ_FIRST (&conf_trans_queue); node;
- node = TAILQ_NEXT (node, link))
- if ((phase == 1 && strcmp ("Transforms", node->tag) == 0) ||
- (phase == 2 && strcmp ("Suites", node->tag) == 0))
- {
- p = node->value;
- while ((p = strstr (p, xf)) != NULL)
- if (*(p + strlen (p)) && *(p + strlen (p)) != ',')
- p += strlen (p);
- else
- return 1;
- }
- return 0;
+ struct conf_trans *node;
+ char *p;
+
+ /* Find the relevant transforms and suites, if any. */
+ for (node = TAILQ_FIRST(&conf_trans_queue); node;
+ node = TAILQ_NEXT(node, link))
+ if ((phase == 1 && strcmp("Transforms", node->tag) == 0) ||
+ (phase == 2 && strcmp("Suites", node->tag) == 0)) {
+ p = node->value;
+ while ((p = strstr(p, xf)) != NULL)
+ if (*(p + strlen(p)) && *(p + strlen(p)) != ',')
+ p += strlen(p);
+ else
+ return 1;
+ }
+ return 0;
}
#endif
static void
-conf_load_defaults (int tr)
+conf_load_defaults(int tr)
{
#define CONF_MAX 256
- int enc, auth, hash, group, group_max, proto, mode, pfs;
- char sect[CONF_MAX], *dflt;
-
- char *mm_auth[] = { "PRE_SHARED", "DSS", "RSA_SIG", 0 };
- char *mm_hash[] = { "MD5", "SHA", 0 };
- char *mm_enc[] = { "DES_CBC", "BLOWFISH_CBC", "3DES_CBC",
- "CAST_CBC", "AES_CBC", 0 };
- char *dh_group[] = { "MODP_768", "MODP_1024", "MODP_1536", "MODP_2048", 0 };
- char *qm_enc[] = { "DES", "3DES", "CAST", "BLOWFISH", "AES", 0 };
- char *qm_hash[] = { "HMAC_MD5", "HMAC_SHA", "HMAC_RIPEMD",
- "HMAC_SHA2_256", "HMAC_SHA2_384", "HMAC_SHA2_512",
- "NONE", 0 };
-
- /* Abbreviations to make section names a bit shorter. */
- char *mm_auth_p[] = { "", "-DSS", "-RSA_SIG", 0 };
- char *mm_enc_p[] = { "DES", "BLF", "3DES", "CAST", "AES", 0 };
- char *dh_group_p[]= { "-GRP1", "-GRP2", "-GRP5", "-GRP14", "", 0 };
- char *qm_enc_p[] = { "-DES", "-3DES", "-CAST", "-BLF", "-AES", 0 };
- char *qm_hash_p[] = { "-MD5", "-SHA", "-RIPEMD",
- "-SHA2-256", "-SHA2-384", "-SHA2-512",
- "", 0 };
-
- /* Helper #defines, incl abbreviations. */
+ int enc, auth, hash, group, group_max, proto, mode,
+ pfs;
+ char sect[CONF_MAX], *dflt;
+
+ char *mm_auth[] = {"PRE_SHARED", "DSS", "RSA_SIG", 0};
+ char *mm_hash[] = {"MD5", "SHA", 0};
+ char *mm_enc[] = {"DES_CBC", "BLOWFISH_CBC", "3DES_CBC",
+ "CAST_CBC", "AES_CBC", 0};
+ char *dh_group[] = {"MODP_768", "MODP_1024", "MODP_1536", "MODP_2048", 0};
+ char *qm_enc[] = {"DES", "3DES", "CAST", "BLOWFISH", "AES", 0};
+ char *qm_hash[] = {"HMAC_MD5", "HMAC_SHA", "HMAC_RIPEMD",
+ "HMAC_SHA2_256", "HMAC_SHA2_384", "HMAC_SHA2_512",
+ "NONE", 0};
+
+ /* Abbreviations to make section names a bit shorter. */
+ char *mm_auth_p[] = {"", "-DSS", "-RSA_SIG", 0};
+ char *mm_enc_p[] = {"DES", "BLF", "3DES", "CAST", "AES", 0};
+ char *dh_group_p[] = {"-GRP1", "-GRP2", "-GRP5", "-GRP14", "", 0};
+ char *qm_enc_p[] = {"-DES", "-3DES", "-CAST", "-BLF", "-AES", 0};
+ char *qm_hash_p[] = {"-MD5", "-SHA", "-RIPEMD",
+ "-SHA2-256", "-SHA2-384", "-SHA2-512",
+ "", 0};
+
+ /* Helper #defines, incl abbreviations. */
#define PROTO(x) ((x) ? "AH" : "ESP")
#define PFS(x) ((x) ? "-PFS" : "")
#define MODE(x) ((x) ? "TRANSPORT" : "TUNNEL")
#define MODE_p(x) ((x) ? "-TRP" : "")
- group_max = sizeof dh_group / sizeof *dh_group - 1;
+ group_max = sizeof dh_group / sizeof *dh_group - 1;
- /* General and X509 defaults */
- conf_set (tr, "General", "Retransmits", CONF_DFLT_RETRANSMITS, 0, 1);
- conf_set (tr, "General", "Exchange-max-time", CONF_DFLT_EXCH_MAX_TIME, 0, 1);
- conf_set (tr, "General", "Policy-file", CONF_DFLT_POLICY_FILE, 0, 1);
- conf_set (tr, "General", "Pubkey-directory", CONF_DFLT_PUBKEY_DIR, 0, 1);
+ /* General and X509 defaults */
+ conf_set(tr, "General", "Retransmits", CONF_DFLT_RETRANSMITS, 0, 1);
+ conf_set(tr, "General", "Exchange-max-time", CONF_DFLT_EXCH_MAX_TIME, 0, 1);
+ conf_set(tr, "General", "Policy-file", CONF_DFLT_POLICY_FILE, 0, 1);
+ conf_set(tr, "General", "Pubkey-directory", CONF_DFLT_PUBKEY_DIR, 0, 1);
#ifdef USE_X509
- conf_set (tr, "X509-certificates", "CA-directory", CONF_DFLT_X509_CA_DIR, 0,
- 1);
- conf_set (tr, "X509-certificates", "Cert-directory", CONF_DFLT_X509_CERT_DIR,
- 0, 1);
- conf_set (tr, "X509-certificates", "Private-key", CONF_DFLT_X509_PRIVATE_KEY,
- 0, 1);
- conf_set (tr, "X509-certificates", "CRL-directory", CONF_DFLT_X509_CRL_DIR,
- 0, 1);
+ conf_set(tr, "X509-certificates", "CA-directory", CONF_DFLT_X509_CA_DIR, 0,
+ 1);
+ conf_set(tr, "X509-certificates", "Cert-directory", CONF_DFLT_X509_CERT_DIR,
+ 0, 1);
+ conf_set(tr, "X509-certificates", "Private-key", CONF_DFLT_X509_PRIVATE_KEY,
+ 0, 1);
+ conf_set(tr, "X509-certificates", "CRL-directory", CONF_DFLT_X509_CRL_DIR,
+ 0, 1);
#endif
#ifdef USE_KEYNOTE
- conf_set (tr, "KeyNote", "Credential-directory", CONF_DFLT_KEYNOTE_CRED_DIR,
- 0, 1);
+ conf_set(tr, "KeyNote", "Credential-directory", CONF_DFLT_KEYNOTE_CRED_DIR,
+ 0, 1);
#endif
- /* Lifetimes. XXX p1/p2 vs main/quick mode may be unclear. */
- dflt = conf_get_trans_str (tr, "General", "Default-phase-1-lifetime");
- conf_set (tr, CONF_DFLT_TAG_LIFE_MAIN_MODE, "LIFE_TYPE",
- CONF_DFLT_TYPE_LIFE_MAIN_MODE, 0, 1);
- conf_set (tr, CONF_DFLT_TAG_LIFE_MAIN_MODE, "LIFE_DURATION",
- (dflt ? dflt : CONF_DFLT_VAL_LIFE_MAIN_MODE), 0, 1);
-
- dflt = conf_get_trans_str (tr, "General", "Default-phase-2-lifetime");
- conf_set (tr, CONF_DFLT_TAG_LIFE_QUICK_MODE, "LIFE_TYPE",
- CONF_DFLT_TYPE_LIFE_QUICK_MODE, 0, 1);
- conf_set (tr, CONF_DFLT_TAG_LIFE_QUICK_MODE, "LIFE_DURATION",
- (dflt ? dflt : CONF_DFLT_VAL_LIFE_QUICK_MODE), 0, 1);
-
- /* Default Phase-1 Configuration section */
- conf_set (tr, CONF_DFLT_TAG_PHASE1_CONFIG, "EXCHANGE_TYPE",
- CONF_DFLT_PHASE1_EXCH_TYPE, 0, 1);
- conf_set (tr, CONF_DFLT_TAG_PHASE1_CONFIG, "Transforms",
- CONF_DFLT_PHASE1_TRANSFORMS, 0, 1);
-
- /* Main modes */
- for (enc = 0; mm_enc[enc]; enc ++)
- for (hash = 0; mm_hash[hash]; hash ++)
- for (auth = 0; mm_auth[auth]; auth ++)
- for (group = 0; dh_group_p[group]; group ++) /* special */
- {
- snprintf (sect, sizeof sect, "%s-%s%s%s", mm_enc_p[enc],
- mm_hash[hash], dh_group_p[group], mm_auth_p[auth]);
+ /* Lifetimes. XXX p1/p2 vs main/quick mode may be unclear. */
+ dflt = conf_get_trans_str(tr, "General", "Default-phase-1-lifetime");
+ conf_set(tr, CONF_DFLT_TAG_LIFE_MAIN_MODE, "LIFE_TYPE",
+ CONF_DFLT_TYPE_LIFE_MAIN_MODE, 0, 1);
+ conf_set(tr, CONF_DFLT_TAG_LIFE_MAIN_MODE, "LIFE_DURATION",
+ (dflt ? dflt : CONF_DFLT_VAL_LIFE_MAIN_MODE), 0, 1);
+
+ dflt = conf_get_trans_str(tr, "General", "Default-phase-2-lifetime");
+ conf_set(tr, CONF_DFLT_TAG_LIFE_QUICK_MODE, "LIFE_TYPE",
+ CONF_DFLT_TYPE_LIFE_QUICK_MODE, 0, 1);
+ conf_set(tr, CONF_DFLT_TAG_LIFE_QUICK_MODE, "LIFE_DURATION",
+ (dflt ? dflt : CONF_DFLT_VAL_LIFE_QUICK_MODE), 0, 1);
+
+ /* Default Phase-1 Configuration section */
+ conf_set(tr, CONF_DFLT_TAG_PHASE1_CONFIG, "EXCHANGE_TYPE",
+ CONF_DFLT_PHASE1_EXCH_TYPE, 0, 1);
+ conf_set(tr, CONF_DFLT_TAG_PHASE1_CONFIG, "Transforms",
+ CONF_DFLT_PHASE1_TRANSFORMS, 0, 1);
+
+ /* Main modes */
+ for (enc = 0; mm_enc[enc]; enc++)
+ for (hash = 0; mm_hash[hash]; hash++)
+ for (auth = 0; mm_auth[auth]; auth++)
+ for (group = 0; dh_group_p[group]; group++) { /* special */
+ snprintf(sect, sizeof sect, "%s-%s%s%s", mm_enc_p[enc],
+ mm_hash[hash], dh_group_p[group], mm_auth_p[auth]);
#if 0
- if (!conf_find_trans_xf (1, sect))
- continue;
+ if (!conf_find_trans_xf(1, sect))
+ continue;
#endif
- LOG_DBG ((LOG_MISC, 90, "conf_load_defaults : main mode %s",
- sect));
-
- conf_set (tr, sect, "ENCRYPTION_ALGORITHM", mm_enc[enc], 0, 1);
- if (strcmp (mm_enc[enc], "BLOWFISH_CBC") == 0)
- conf_set (tr, sect, "KEY_LENGTH", CONF_DFLT_VAL_BLF_KEYLEN, 0,
- 1);
-
- conf_set (tr, sect, "HASH_ALGORITHM", mm_hash[hash], 0, 1);
- conf_set (tr, sect, "AUTHENTICATION_METHOD", mm_auth[auth], 0, 1);
-
- /* XXX Always DH group 2 (MODP_1024) */
- conf_set (tr, sect, "GROUP_DESCRIPTION",
- dh_group[group < group_max ? group : 1], 0, 1);
-
- conf_set (tr, sect, "Life", CONF_DFLT_TAG_LIFE_MAIN_MODE, 0, 1);
- }
-
- /* Setup a default Phase 1 entry */
- conf_set (tr, "Phase 1", "Default", "Default-phase-1", 0, 1);
-
- conf_set (tr, "Default-phase-1", "Phase", "1", 0, 1);
- conf_set (tr, "Default-phase-1", "Configuration",
- "Default-phase-1-configuration", 0, 1);
- dflt = conf_get_trans_str (tr, "General", "Default-phase-1-ID");
- if (dflt)
- conf_set (tr, "Default-phase-1", "ID", dflt, 0, 1);
-
- /* Quick modes */
- for (enc = 0; qm_enc[enc]; enc ++)
- for (proto = 0; proto < 2; proto ++)
- for (mode = 0; mode < 2; mode ++)
- for (pfs = 0; pfs < 2; pfs ++)
- for (hash = 0; qm_hash[hash]; hash ++)
- for (group = 0; dh_group_p[group]; group ++)
- if ((proto == 1 && strcmp (qm_hash[hash], "NONE") == 0)) /* AH */
- continue;
- else
- {
- char tmp[CONF_MAX];
-
- snprintf (tmp, sizeof tmp, "QM-%s%s%s%s%s%s", PROTO (proto),
- MODE_p (mode), qm_enc_p[enc], qm_hash_p[hash],
- PFS (pfs), dh_group_p[group]);
-
- strlcpy (sect, tmp, CONF_MAX);
- strlcat (sect, "-SUITE", CONF_MAX);
+ LOG_DBG((LOG_MISC, 90, "conf_load_defaults : main mode %s",
+ sect));
+
+ conf_set(tr, sect, "ENCRYPTION_ALGORITHM", mm_enc[enc], 0, 1);
+ if (strcmp(mm_enc[enc], "BLOWFISH_CBC") == 0)
+ conf_set(tr, sect, "KEY_LENGTH", CONF_DFLT_VAL_BLF_KEYLEN, 0,
+ 1);
+
+ conf_set(tr, sect, "HASH_ALGORITHM", mm_hash[hash], 0, 1);
+ conf_set(tr, sect, "AUTHENTICATION_METHOD", mm_auth[auth], 0, 1);
+
+ /* XXX Always DH group 2 (MODP_1024) */
+ conf_set(tr, sect, "GROUP_DESCRIPTION",
+ dh_group[group < group_max ? group : 1], 0, 1);
+
+ conf_set(tr, sect, "Life", CONF_DFLT_TAG_LIFE_MAIN_MODE, 0, 1);
+ }
+
+ /* Setup a default Phase 1 entry */
+ conf_set(tr, "Phase 1", "Default", "Default-phase-1", 0, 1);
+
+ conf_set(tr, "Default-phase-1", "Phase", "1", 0, 1);
+ conf_set(tr, "Default-phase-1", "Configuration",
+ "Default-phase-1-configuration", 0, 1);
+ dflt = conf_get_trans_str(tr, "General", "Default-phase-1-ID");
+ if (dflt)
+ conf_set(tr, "Default-phase-1", "ID", dflt, 0, 1);
+
+ /* Quick modes */
+ for (enc = 0; qm_enc[enc]; enc++)
+ for (proto = 0; proto < 2; proto++)
+ for (mode = 0; mode < 2; mode++)
+ for (pfs = 0; pfs < 2; pfs++)
+ for (hash = 0; qm_hash[hash]; hash++)
+ for (group = 0; dh_group_p[group]; group++)
+ if ((proto == 1 && strcmp(qm_hash[hash], "NONE") == 0)) /* AH */
+ continue;
+ else {
+ char tmp[CONF_MAX];
+
+ snprintf(tmp, sizeof tmp, "QM-%s%s%s%s%s%s", PROTO(proto),
+ MODE_p(mode), qm_enc_p[enc], qm_hash_p[hash],
+ PFS(pfs), dh_group_p[group]);
+
+ strlcpy(sect, tmp, CONF_MAX);
+ strlcat(sect, "-SUITE", CONF_MAX);
#if 0
- if (!conf_find_trans_xf (2, sect))
- continue;
+ if (!conf_find_trans_xf(2, sect))
+ continue;
#endif
- LOG_DBG ((LOG_MISC, 90, "conf_load_defaults : quick mode %s",
- sect));
-
- conf_set (tr, sect, "Protocols", tmp, 0, 1);
-
- snprintf (sect, sizeof sect, "IPSEC_%s", PROTO (proto));
- conf_set (tr, tmp, "PROTOCOL_ID", sect, 0, 1);
-
- strlcpy (sect, tmp, CONF_MAX);
- strlcat (sect, "-XF", CONF_MAX);
- conf_set (tr, tmp, "Transforms", sect, 0, 1);
-
- /* XXX For now, defaults contain one xf per protocol. */
-
- conf_set (tr, sect, "TRANSFORM_ID", qm_enc[enc], 0, 1);
-
- if (strcmp (qm_enc[enc], "BLOWFISH") == 0)
- conf_set (tr, sect, "KEY_LENGTH", CONF_DFLT_VAL_BLF_KEYLEN,
- 0, 1);
-
- conf_set (tr, sect, "ENCAPSULATION_MODE", MODE (mode), 0, 1);
-
- if (strcmp (qm_hash[hash], "NONE"))
- {
- conf_set (tr, sect, "AUTHENTICATION_ALGORITHM",
- qm_hash[hash], 0, 1);
-
- /* XXX Another shortcut -- to keep length down. */
- if (pfs)
- conf_set (tr, sect, "GROUP_DESCRIPTION",
- dh_group[group < group_max ? group : 1], 0,
- 1);
- }
-
- /* XXX Lifetimes depending on enc/auth strength? */
- conf_set (tr, sect, "Life", CONF_DFLT_TAG_LIFE_QUICK_MODE, 0,
- 1);
- }
- return;
+ LOG_DBG((LOG_MISC, 90, "conf_load_defaults : quick mode %s",
+ sect));
+
+ conf_set(tr, sect, "Protocols", tmp, 0, 1);
+
+ snprintf(sect, sizeof sect, "IPSEC_%s", PROTO(proto));
+ conf_set(tr, tmp, "PROTOCOL_ID", sect, 0, 1);
+
+ strlcpy(sect, tmp, CONF_MAX);
+ strlcat(sect, "-XF", CONF_MAX);
+ conf_set(tr, tmp, "Transforms", sect, 0, 1);
+
+ /*
+ * XXX For
+ * now,
+ * defaults
+ * contain
+ * one xf per
+ * protocol.
+ */
+
+ conf_set(tr, sect, "TRANSFORM_ID", qm_enc[enc], 0, 1);
+
+ if (strcmp(qm_enc[enc], "BLOWFISH") == 0)
+ conf_set(tr, sect, "KEY_LENGTH", CONF_DFLT_VAL_BLF_KEYLEN,
+ 0, 1);
+
+ conf_set(tr, sect, "ENCAPSULATION_MODE", MODE(mode), 0, 1);
+
+ if (strcmp(qm_hash[hash], "NONE")) {
+ conf_set(tr, sect, "AUTHENTICATION_ALGORITHM",
+ qm_hash[hash], 0, 1);
+
+ /*
+ * XXX
+ *
+ * Ano
+ * the
+ * r
+ * sho
+ * rtc
+ * ut
+ * --
+ * to
+ * kee
+ * p
+ * len
+ * gth
+ *
+ * dow
+ * n.
+ */
+ if (pfs)
+ conf_set(tr, sect, "GROUP_DESCRIPTION",
+ dh_group[group < group_max ? group : 1], 0,
+ 1);
+ }
+ /*
+ * XXX
+ * Lifetimes
+ * depending
+ * on
+ * enc/auth
+ * strength?
+ */
+ conf_set(tr, sect, "Life", CONF_DFLT_TAG_LIFE_QUICK_MODE, 0,
+ 1);
+ }
+ return;
}
void
-conf_init (void)
+conf_init(void)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
- LIST_INIT (&conf_bindings[i]);
- TAILQ_INIT (&conf_trans_queue);
- conf_reinit ();
+ for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
+ LIST_INIT(&conf_bindings[i]);
+ TAILQ_INIT(&conf_trans_queue);
+ conf_reinit();
}
/* Open the config file and map it into our address space, then parse it. */
void
-conf_reinit (void)
+conf_reinit(void)
{
- struct conf_binding *cb = 0;
- int fd, trans;
- unsigned int i;
- size_t sz;
- char *new_conf_addr = 0;
- struct stat sb;
-
- if ((monitor_stat (conf_path, &sb) == 0) || (errno != ENOENT))
- {
- if (check_file_secrecy (conf_path, &sz))
- return;
-
- fd = monitor_open (conf_path, O_RDONLY, 0);
- if (fd == -1)
- {
- log_error ("conf_reinit: open (\"%s\", O_RDONLY) failed", conf_path);
- return;
- }
-
- new_conf_addr = malloc (sz);
- if (!new_conf_addr)
- {
- log_error ("conf_reinit: malloc (%lu) failed", (unsigned long)sz);
- goto fail;
+ struct conf_binding *cb = 0;
+ int fd, trans;
+ unsigned int i;
+ size_t sz;
+ char *new_conf_addr = 0;
+ struct stat sb;
+
+ if ((monitor_stat(conf_path, &sb) == 0) || (errno != ENOENT)) {
+ if (check_file_secrecy(conf_path, &sz))
+ return;
+
+ fd = monitor_open(conf_path, O_RDONLY, 0);
+ if (fd == -1) {
+ log_error("conf_reinit: open (\"%s\", O_RDONLY) failed", conf_path);
+ return;
+ }
+ new_conf_addr = malloc(sz);
+ if (!new_conf_addr) {
+ log_error("conf_reinit: malloc (%lu) failed", (unsigned long) sz);
+ goto fail;
+ }
+ /* XXX I assume short reads won't happen here. */
+ if (read(fd, new_conf_addr, sz) != (int) sz) {
+ log_error("conf_reinit: read (%d, %p, %lu) failed",
+ fd, new_conf_addr, (unsigned long) sz);
+ goto fail;
+ }
+ close(fd);
+
+ trans = conf_begin();
+
+ /* XXX Should we not care about errors and rollback? */
+ conf_parse(trans, new_conf_addr, sz);
+ } else
+ trans = conf_begin();
+
+ /* Load default configuration values. */
+ conf_load_defaults(trans);
+
+ /* Free potential existing configuration. */
+ if (conf_addr) {
+ for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
+ for (cb = LIST_FIRST(&conf_bindings[i]); cb;
+ cb = LIST_FIRST(&conf_bindings[i]))
+ conf_remove_now(cb->section, cb->tag);
+ free(conf_addr);
}
+ conf_end(trans, 1);
+ conf_addr = new_conf_addr;
+ return;
- /* XXX I assume short reads won't happen here. */
- if (read (fd, new_conf_addr, sz) != (int)sz)
- {
- log_error ("conf_reinit: read (%d, %p, %lu) failed",
- fd, new_conf_addr, (unsigned long)sz);
- goto fail;
- }
- close (fd);
-
- trans = conf_begin ();
-
- /* XXX Should we not care about errors and rollback? */
- conf_parse (trans, new_conf_addr, sz);
- }
- else
- trans = conf_begin ();
-
- /* Load default configuration values. */
- conf_load_defaults (trans);
-
- /* Free potential existing configuration. */
- if (conf_addr)
- {
- for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
- for (cb = LIST_FIRST (&conf_bindings[i]); cb;
- cb = LIST_FIRST (&conf_bindings[i]))
- conf_remove_now (cb->section, cb->tag);
- free (conf_addr);
- }
-
- conf_end (trans, 1);
- conf_addr = new_conf_addr;
- return;
-
- fail:
- if (new_conf_addr)
- free (new_conf_addr);
- close (fd);
+fail:
+ if (new_conf_addr)
+ free(new_conf_addr);
+ close(fd);
}
/*
@@ -649,13 +651,13 @@ conf_reinit (void)
* if that tag does not exist.
*/
int
-conf_get_num (char *section, char *tag, int def)
+conf_get_num(char *section, char *tag, int def)
{
- char *value = conf_get_str (section, tag);
+ char *value = conf_get_str(section, tag);
- if (value)
- return atoi (value);
- return def;
+ if (value)
+ return atoi(value);
+ return def;
}
/*
@@ -664,64 +666,62 @@ conf_get_num (char *section, char *tag, int def)
* this structure when it is finished with it.
*/
struct sockaddr *
-conf_get_address (char *section, char *tag)
+conf_get_address(char *section, char *tag)
{
- char *value = conf_get_str (section, tag);
- struct sockaddr *sa;
-
- if (!value)
- return 0;
- if (text2sockaddr (value, 0, &sa) == -1)
- return 0;
- return sa;
+ char *value = conf_get_str(section, tag);
+ struct sockaddr *sa;
+
+ if (!value)
+ return 0;
+ if (text2sockaddr(value, 0, &sa) == -1)
+ return 0;
+ return sa;
}
/* Validate X according to the range denoted by TAG in section SECTION. */
int
-conf_match_num (char *section, char *tag, int x)
+conf_match_num(char *section, char *tag, int x)
{
- char *value = conf_get_str (section, tag);
- int val, min, max, n;
-
- if (!value)
- return 0;
- n = sscanf (value, "%d,%d:%d", &val, &min, &max);
- switch (n)
- {
- case 1:
- LOG_DBG ((LOG_MISC, 90, "conf_match_num: %s:%s %d==%d?", section, tag,
- val, x));
- return x == val;
- case 3:
- LOG_DBG ((LOG_MISC, 90, "conf_match_num: %s:%s %d<=%d<=%d?", section,
- tag, min, x, max));
- return min <= x && max >= x;
- default:
- log_error ("conf_match_num: section %s tag %s: invalid number spec %s",
- section, tag, value);
- }
- return 0;
+ char *value = conf_get_str(section, tag);
+ int val, min, max, n;
+
+ if (!value)
+ return 0;
+ n = sscanf(value, "%d,%d:%d", &val, &min, &max);
+ switch (n) {
+ case 1:
+ LOG_DBG((LOG_MISC, 90, "conf_match_num: %s:%s %d==%d?", section, tag,
+ val, x));
+ return x == val;
+ case 3:
+ LOG_DBG((LOG_MISC, 90, "conf_match_num: %s:%s %d<=%d<=%d?", section,
+ tag, min, x, max));
+ return min <= x && max >= x;
+ default:
+ log_error("conf_match_num: section %s tag %s: invalid number spec %s",
+ section, tag, value);
+ }
+ return 0;
}
/* Return the string value denoted by TAG in section SECTION. */
-char *
-conf_get_str (char *section, char *tag)
+char *
+conf_get_str(char *section, char *tag)
{
- struct conf_binding *cb;
-
- for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb;
- cb = LIST_NEXT (cb, link))
- if (strcasecmp (section, cb->section) == 0
- && strcasecmp (tag, cb->tag) == 0)
- {
- LOG_DBG ((LOG_MISC, 95, "conf_get_str: [%s]:%s->%s", section,
- tag, cb->value));
- return cb->value;
- }
- LOG_DBG ((LOG_MISC, 95,
- "conf_get_str: configuration value not found [%s]:%s", section,
- tag));
- return 0;
+ struct conf_binding *cb;
+
+ for (cb = LIST_FIRST(&conf_bindings[conf_hash(section)]); cb;
+ cb = LIST_NEXT(cb, link))
+ if (strcasecmp(section, cb->section) == 0
+ && strcasecmp(tag, cb->tag) == 0) {
+ LOG_DBG((LOG_MISC, 95, "conf_get_str: [%s]:%s->%s", section,
+ tag, cb->value));
+ return cb->value;
+ }
+ LOG_DBG((LOG_MISC, 95,
+ "conf_get_str: configuration value not found [%s]:%s", section,
+ tag));
+ return 0;
}
/*
@@ -729,332 +729,312 @@ conf_get_str (char *section, char *tag)
* TAG in SECTION.
*/
struct conf_list *
-conf_get_list (char *section, char *tag)
+conf_get_list(char *section, char *tag)
{
- char *liststr = 0, *p, *field, *t;
- struct conf_list *list = 0;
- struct conf_list_node *node;
-
- list = malloc (sizeof *list);
- if (!list)
- goto cleanup;
- TAILQ_INIT (&list->fields);
- list->cnt = 0;
- liststr = conf_get_str (section, tag);
- if (!liststr)
- goto cleanup;
- liststr = strdup (liststr);
- if (!liststr)
- goto cleanup;
- p = liststr;
- while ((field = strsep (&p, ",")) != NULL)
- {
- /* Skip leading whitespace */
- while (isspace (*field))
- field++;
- /* Skip trailing whitespace */
- if (p)
- for (t = p - 1; t > field && isspace (*t); t--)
- *t = '\0';
- if (*field == '\0')
- {
- log_print ("conf_get_list: empty field, ignoring...");
- continue;
+ char *liststr = 0, *p, *field, *t;
+ struct conf_list *list = 0;
+ struct conf_list_node *node;
+
+ list = malloc(sizeof *list);
+ if (!list)
+ goto cleanup;
+ TAILQ_INIT(&list->fields);
+ list->cnt = 0;
+ liststr = conf_get_str(section, tag);
+ if (!liststr)
+ goto cleanup;
+ liststr = strdup(liststr);
+ if (!liststr)
+ goto cleanup;
+ p = liststr;
+ while ((field = strsep(&p, ",")) != NULL) {
+ /* Skip leading whitespace */
+ while (isspace(*field))
+ field++;
+ /* Skip trailing whitespace */
+ if (p)
+ for (t = p - 1; t > field && isspace(*t); t--)
+ *t = '\0';
+ if (*field == '\0') {
+ log_print("conf_get_list: empty field, ignoring...");
+ continue;
+ }
+ list->cnt++;
+ node = calloc(1, sizeof *node);
+ if (!node)
+ goto cleanup;
+ node->field = strdup(field);
+ if (!node->field)
+ goto cleanup;
+ TAILQ_INSERT_TAIL(&list->fields, node, link);
}
- list->cnt++;
- node = calloc (1, sizeof *node);
- if (!node)
- goto cleanup;
- node->field = strdup (field);
- if (!node->field)
- goto cleanup;
- TAILQ_INSERT_TAIL (&list->fields, node, link);
- }
- free (liststr);
- return list;
-
- cleanup:
- if (list)
- conf_free_list (list);
- if (liststr)
- free (liststr);
- return 0;
+ free(liststr);
+ return list;
+
+cleanup:
+ if (list)
+ conf_free_list(list);
+ if (liststr)
+ free(liststr);
+ return 0;
}
struct conf_list *
-conf_get_tag_list (char *section)
+conf_get_tag_list(char *section)
{
- struct conf_list *list = 0;
- struct conf_list_node *node;
- struct conf_binding *cb;
-
- list = malloc (sizeof *list);
- if (!list)
- goto cleanup;
- TAILQ_INIT (&list->fields);
- list->cnt = 0;
- for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb;
- cb = LIST_NEXT (cb, link))
- if (strcasecmp (section, cb->section) == 0)
- {
- list->cnt++;
- node = calloc (1, sizeof *node);
- if (!node)
- goto cleanup;
- node->field = strdup (cb->tag);
- if (!node->field)
- goto cleanup;
- TAILQ_INSERT_TAIL (&list->fields, node, link);
- }
- return list;
-
- cleanup:
- if (list)
- conf_free_list (list);
- return 0;
+ struct conf_list *list = 0;
+ struct conf_list_node *node;
+ struct conf_binding *cb;
+
+ list = malloc(sizeof *list);
+ if (!list)
+ goto cleanup;
+ TAILQ_INIT(&list->fields);
+ list->cnt = 0;
+ for (cb = LIST_FIRST(&conf_bindings[conf_hash(section)]); cb;
+ cb = LIST_NEXT(cb, link))
+ if (strcasecmp(section, cb->section) == 0) {
+ list->cnt++;
+ node = calloc(1, sizeof *node);
+ if (!node)
+ goto cleanup;
+ node->field = strdup(cb->tag);
+ if (!node->field)
+ goto cleanup;
+ TAILQ_INSERT_TAIL(&list->fields, node, link);
+ }
+ return list;
+
+cleanup:
+ if (list)
+ conf_free_list(list);
+ return 0;
}
/* Decode a PEM encoded buffer. */
int
-conf_decode_base64 (u_int8_t *out, u_int32_t *len, u_char *buf)
+conf_decode_base64(u_int8_t * out, u_int32_t * len, u_char * buf)
{
- u_int32_t c = 0;
- u_int8_t c1, c2, c3, c4;
-
- while (*buf)
- {
- if (*buf > 127 || (c1 = asc2bin[*buf]) == 255)
- return 0;
- buf++;
-
- if (*buf > 127 || (c2 = asc2bin[*buf]) == 255)
- return 0;
- buf++;
-
- if (*buf == '=')
- {
- c3 = c4 = 0;
- c++;
-
- /* Check last four bit */
- if (c2 & 0xF)
- return 0;
-
- if (strcmp ((char *)buf, "==") == 0)
- buf++;
- else
- return 0;
+ u_int32_t c = 0;
+ u_int8_t c1, c2, c3, c4;
+
+ while (*buf) {
+ if (*buf > 127 || (c1 = asc2bin[*buf]) == 255)
+ return 0;
+ buf++;
+
+ if (*buf > 127 || (c2 = asc2bin[*buf]) == 255)
+ return 0;
+ buf++;
+
+ if (*buf == '=') {
+ c3 = c4 = 0;
+ c++;
+
+ /* Check last four bit */
+ if (c2 & 0xF)
+ return 0;
+
+ if (strcmp((char *) buf, "==") == 0)
+ buf++;
+ else
+ return 0;
+ } else if (*buf > 127 || (c3 = asc2bin[*buf]) == 255)
+ return 0;
+ else {
+ if (*++buf == '=') {
+ c4 = 0;
+ c += 2;
+
+ /* Check last two bit */
+ if (c3 & 3)
+ return 0;
+
+ if (strcmp((char *) buf, "="))
+ return 0;
+
+ } else if (*buf > 127 || (c4 = asc2bin[*buf]) == 255)
+ return 0;
+ else
+ c += 3;
+ }
+
+ buf++;
+ *out++ = (c1 << 2) | (c2 >> 4);
+ *out++ = (c2 << 4) | (c3 >> 2);
+ *out++ = (c3 << 6) | c4;
}
- else if (*buf > 127 || (c3 = asc2bin[*buf]) == 255)
- return 0;
- else
- {
- if (*++buf == '=')
- {
- c4 = 0;
- c += 2;
- /* Check last two bit */
- if (c3 & 3)
- return 0;
-
- if (strcmp ((char *)buf, "="))
- return 0;
-
- }
- else if (*buf > 127 || (c4 = asc2bin[*buf]) == 255)
- return 0;
- else
- c += 3;
- }
-
- buf++;
- *out++ = (c1 << 2) | (c2 >> 4);
- *out++ = (c2 << 4) | (c3 >> 2);
- *out++ = (c3 << 6) | c4;
- }
-
- *len = c;
- return 1;
+ *len = c;
+ return 1;
}
void
-conf_free_list (struct conf_list *list)
+conf_free_list(struct conf_list * list)
{
- struct conf_list_node *node = TAILQ_FIRST (&list->fields);
-
- while (node)
- {
- TAILQ_REMOVE (&list->fields, node, link);
- if (node->field)
- free (node->field);
- free (node);
- node = TAILQ_FIRST (&list->fields);
- }
- free (list);
+ struct conf_list_node *node = TAILQ_FIRST(&list->fields);
+
+ while (node) {
+ TAILQ_REMOVE(&list->fields, node, link);
+ if (node->field)
+ free(node->field);
+ free(node);
+ node = TAILQ_FIRST(&list->fields);
+ }
+ free(list);
}
int
-conf_begin (void)
+conf_begin(void)
{
- static int seq = 0;
+ static int seq = 0;
- return ++seq;
+ return ++seq;
}
static struct conf_trans *
-conf_trans_node (int transaction, enum conf_op op)
+conf_trans_node(int transaction, enum conf_op op)
{
- struct conf_trans *node;
-
- node = calloc (1, sizeof *node);
- if (!node)
- {
- log_error ("conf_trans_node: calloc (1, %lu) failed",
- (unsigned long)sizeof *node);
- return 0;
- }
- node->trans = transaction;
- node->op = op;
- TAILQ_INSERT_TAIL (&conf_trans_queue, node, link);
- return node;
+ struct conf_trans *node;
+
+ node = calloc(1, sizeof *node);
+ if (!node) {
+ log_error("conf_trans_node: calloc (1, %lu) failed",
+ (unsigned long) sizeof *node);
+ return 0;
+ }
+ node->trans = transaction;
+ node->op = op;
+ TAILQ_INSERT_TAIL(&conf_trans_queue, node, link);
+ return node;
}
/* Queue a set operation. */
int
-conf_set (int transaction, char *section, char *tag, char *value, int override,
- int is_default)
+conf_set(int transaction, char *section, char *tag, char *value, int override,
+ int is_default)
{
- struct conf_trans *node;
-
- node = conf_trans_node (transaction, CONF_SET);
- if (!node)
- return 1;
- node->section = strdup (section);
- if (!node->section)
- {
- log_error ("conf_set: strdup (\"%s\") failed", section);
- goto fail;
- }
- node->tag = strdup (tag);
- if (!node->tag)
- {
- log_error ("conf_set: strdup (\"%s\") failed", tag);
- goto fail;
- }
- node->value = strdup (value);
- if (!node->value)
- {
- log_error ("conf_set: strdup (\"%s\") failed", value);
- goto fail;
- }
- node->override = override;
- node->is_default = is_default;
- return 0;
-
- fail:
- if (node->tag)
- free (node->tag);
- if (node->section)
- free (node->section);
- if (node)
- free (node);
- return 1;
+ struct conf_trans *node;
+
+ node = conf_trans_node(transaction, CONF_SET);
+ if (!node)
+ return 1;
+ node->section = strdup(section);
+ if (!node->section) {
+ log_error("conf_set: strdup (\"%s\") failed", section);
+ goto fail;
+ }
+ node->tag = strdup(tag);
+ if (!node->tag) {
+ log_error("conf_set: strdup (\"%s\") failed", tag);
+ goto fail;
+ }
+ node->value = strdup(value);
+ if (!node->value) {
+ log_error("conf_set: strdup (\"%s\") failed", value);
+ goto fail;
+ }
+ node->override = override;
+ node->is_default = is_default;
+ return 0;
+
+fail:
+ if (node->tag)
+ free(node->tag);
+ if (node->section)
+ free(node->section);
+ if (node)
+ free(node);
+ return 1;
}
/* Queue a remove operation. */
int
-conf_remove (int transaction, char *section, char *tag)
+conf_remove(int transaction, char *section, char *tag)
{
- struct conf_trans *node;
-
- node = conf_trans_node (transaction, CONF_REMOVE);
- if (!node)
- goto fail;
- node->section = strdup (section);
- if (!node->section)
- {
- log_error ("conf_remove: strdup (\"%s\") failed", section);
- goto fail;
- }
- node->tag = strdup (tag);
- if (!node->tag)
- {
- log_error ("conf_remove: strdup (\"%s\") failed", tag);
- goto fail;
- }
- return 0;
-
- fail:
- if (node->section)
- free (node->section);
- if (node)
- free (node);
- return 1;
+ struct conf_trans *node;
+
+ node = conf_trans_node(transaction, CONF_REMOVE);
+ if (!node)
+ goto fail;
+ node->section = strdup(section);
+ if (!node->section) {
+ log_error("conf_remove: strdup (\"%s\") failed", section);
+ goto fail;
+ }
+ node->tag = strdup(tag);
+ if (!node->tag) {
+ log_error("conf_remove: strdup (\"%s\") failed", tag);
+ goto fail;
+ }
+ return 0;
+
+fail:
+ if (node->section)
+ free(node->section);
+ if (node)
+ free(node);
+ return 1;
}
/* Queue a remove section operation. */
int
-conf_remove_section (int transaction, char *section)
+conf_remove_section(int transaction, char *section)
{
- struct conf_trans *node;
-
- node = conf_trans_node (transaction, CONF_REMOVE_SECTION);
- if (!node)
- goto fail;
- node->section = strdup (section);
- if (!node->section)
- {
- log_error ("conf_remove_section: strdup (\"%s\") failed", section);
- goto fail;
- }
- return 0;
-
- fail:
- if (node)
- free (node);
- return 1;
+ struct conf_trans *node;
+
+ node = conf_trans_node(transaction, CONF_REMOVE_SECTION);
+ if (!node)
+ goto fail;
+ node->section = strdup(section);
+ if (!node->section) {
+ log_error("conf_remove_section: strdup (\"%s\") failed", section);
+ goto fail;
+ }
+ return 0;
+
+fail:
+ if (node)
+ free(node);
+ return 1;
}
/* Execute all queued operations for this transaction. Cleanup. */
int
-conf_end (int transaction, int commit)
+conf_end(int transaction, int commit)
{
- struct conf_trans *node, *next;
-
- for (node = TAILQ_FIRST (&conf_trans_queue); node; node = next)
- {
- next = TAILQ_NEXT (node, link);
- if (node->trans == transaction)
- {
- if (commit)
- switch (node->op)
- {
- case CONF_SET:
- conf_set_now (node->section, node->tag, node->value,
- node->override, node->is_default);
- break;
- case CONF_REMOVE:
- conf_remove_now (node->section, node->tag);
- break;
- case CONF_REMOVE_SECTION:
- conf_remove_section_now (node->section);
- break;
- default:
- log_print ("conf_end: unknown operation: %d", node->op);
- }
- TAILQ_REMOVE (&conf_trans_queue, node, link);
- if (node->section)
- free (node->section);
- if (node->tag)
- free (node->tag);
- if (node->value)
- free (node->value);
- free (node);
+ struct conf_trans *node, *next;
+
+ for (node = TAILQ_FIRST(&conf_trans_queue); node; node = next) {
+ next = TAILQ_NEXT(node, link);
+ if (node->trans == transaction) {
+ if (commit)
+ switch (node->op) {
+ case CONF_SET:
+ conf_set_now(node->section, node->tag, node->value,
+ node->override, node->is_default);
+ break;
+ case CONF_REMOVE:
+ conf_remove_now(node->section, node->tag);
+ break;
+ case CONF_REMOVE_SECTION:
+ conf_remove_section_now(node->section);
+ break;
+ default:
+ log_print("conf_end: unknown operation: %d", node->op);
+ }
+ TAILQ_REMOVE(&conf_trans_queue, node, link);
+ if (node->section)
+ free(node->section);
+ if (node->tag)
+ free(node->tag);
+ if (node->value)
+ free(node->value);
+ free(node);
+ }
}
- }
- return 0;
+ return 0;
}
/*
@@ -1062,107 +1042,98 @@ conf_end (int transaction, int commit)
* Configuration is "stored in reverse order", so reverse it again.
*/
struct dumper {
- char *s, *v;
- struct dumper *next;
+ char *s, *v;
+ struct dumper *next;
};
static void
-conf_report_dump (struct dumper *node)
+conf_report_dump(struct dumper * node)
{
- /* Recursive, cleanup when we're done. */
-
- if (node->next)
- conf_report_dump (node->next);
+ /* Recursive, cleanup when we're done. */
- if (node->v)
- LOG_DBG ((LOG_REPORT, 0, "%s=\t%s", node->s, node->v));
- else if (node->s)
- {
- LOG_DBG ((LOG_REPORT, 0, "%s", node->s));
- if (strlen (node->s) > 0)
- free (node->s);
- }
+ if (node->next)
+ conf_report_dump(node->next);
- free (node);
+ if (node->v)
+ LOG_DBG((LOG_REPORT, 0, "%s=\t%s", node->s, node->v));
+ else if (node->s) {
+ LOG_DBG((LOG_REPORT, 0, "%s", node->s));
+ if (strlen(node->s) > 0)
+ free(node->s);
+ }
+ free(node);
}
void
-conf_report (void)
+conf_report(void)
{
- struct conf_binding *cb, *last = 0;
- unsigned int i, len;
- char *current_section = (char *)0;
- struct dumper *dumper, *dnode;
-
- dumper = dnode = (struct dumper *)calloc (1, sizeof *dumper);
- if (!dumper)
- goto mem_fail;
-
- LOG_DBG ((LOG_REPORT, 0, "conf_report: dumping running configuration"));
-
- for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
- for (cb = LIST_FIRST (&conf_bindings[i]); cb;
- cb = LIST_NEXT (cb, link))
- {
- if (!cb->is_default)
- {
- /* Dump this entry. */
- if (!current_section || strcmp (cb->section, current_section))
- {
- if (current_section)
- {
- len = strlen (current_section) + 3;
- dnode->s = malloc (len);
- if (!dnode->s)
- goto mem_fail;
-
- snprintf (dnode->s, len, "[%s]", current_section);
- dnode->next
- = (struct dumper *)calloc (1, sizeof (struct dumper));
- dnode = dnode->next;
- if (!dnode)
- goto mem_fail;
-
- dnode->s = "";
- dnode->next
- = (struct dumper *)calloc (1, sizeof (struct dumper));
- dnode = dnode->next;
- if (!dnode)
- goto mem_fail;
- }
- current_section = cb->section;
- }
- dnode->s = cb->tag;
- dnode->v = cb->value;
- dnode->next = (struct dumper *)calloc (1, sizeof (struct dumper));
- dnode = dnode->next;
- if (!dnode)
- goto mem_fail;
- last = cb;
- }
- }
-
- if (last)
- {
- len = strlen (last->section) + 3;
- dnode->s = malloc (len);
- if (!dnode->s)
- goto mem_fail;
- snprintf (dnode->s, len, "[%s]", last->section);
- }
-
- conf_report_dump (dumper);
-
- return;
-
- mem_fail:
- log_error ("conf_report: malloc/calloc failed");
- while ((dnode = dumper) != 0)
- {
- dumper = dumper->next;
- if (dnode->s)
- free (dnode->s);
- free (dnode);
- }
- return;
+ struct conf_binding *cb, *last = 0;
+ unsigned int i, len;
+ char *current_section = (char *) 0;
+ struct dumper *dumper, *dnode;
+
+ dumper = dnode = (struct dumper *) calloc(1, sizeof *dumper);
+ if (!dumper)
+ goto mem_fail;
+
+ LOG_DBG((LOG_REPORT, 0, "conf_report: dumping running configuration"));
+
+ for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
+ for (cb = LIST_FIRST(&conf_bindings[i]); cb;
+ cb = LIST_NEXT(cb, link)) {
+ if (!cb->is_default) {
+ /* Dump this entry. */
+ if (!current_section || strcmp(cb->section, current_section)) {
+ if (current_section) {
+ len = strlen(current_section) + 3;
+ dnode->s = malloc(len);
+ if (!dnode->s)
+ goto mem_fail;
+
+ snprintf(dnode->s, len, "[%s]", current_section);
+ dnode->next
+ = (struct dumper *) calloc(1, sizeof(struct dumper));
+ dnode = dnode->next;
+ if (!dnode)
+ goto mem_fail;
+
+ dnode->s = "";
+ dnode->next
+ = (struct dumper *) calloc(1, sizeof(struct dumper));
+ dnode = dnode->next;
+ if (!dnode)
+ goto mem_fail;
+ }
+ current_section = cb->section;
+ }
+ dnode->s = cb->tag;
+ dnode->v = cb->value;
+ dnode->next = (struct dumper *) calloc(1, sizeof(struct dumper));
+ dnode = dnode->next;
+ if (!dnode)
+ goto mem_fail;
+ last = cb;
+ }
+ }
+
+ if (last) {
+ len = strlen(last->section) + 3;
+ dnode->s = malloc(len);
+ if (!dnode->s)
+ goto mem_fail;
+ snprintf(dnode->s, len, "[%s]", last->section);
+ }
+ conf_report_dump(dumper);
+
+ return;
+
+mem_fail:
+ log_error("conf_report: malloc/calloc failed");
+ while ((dnode = dumper) != 0) {
+ dumper = dumper->next;
+ if (dnode->s)
+ free(dnode->s);
+ free(dnode);
+ }
+ return;
}
diff --git a/sbin/isakmpd/conf.h b/sbin/isakmpd/conf.h
index cac8d139141..b45d896ab60 100644
--- a/sbin/isakmpd/conf.h
+++ b/sbin/isakmpd/conf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: conf.h,v 1.26 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: conf.h,v 1.13 2000/09/18 00:01:47 ho Exp $ */
+/* $OpenBSD: conf.h,v 1.27 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: conf.h,v 1.13 2000/09/18 00:01:47 ho Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -70,32 +70,32 @@
#define CONF_DFLT_PHASE1_TRANSFORMS "3DES-SHA-RSA_SIG"
struct conf_list_node {
- TAILQ_ENTRY (conf_list_node) link;
- char *field;
+ TAILQ_ENTRY(conf_list_node) link;
+ char *field;
};
struct conf_list {
- size_t cnt;
- TAILQ_HEAD (conf_list_fields_head, conf_list_node) fields;
+ size_t cnt;
+ TAILQ_HEAD(conf_list_fields_head, conf_list_node) fields;
};
-extern char *conf_path;
-
-extern int conf_begin (void);
-extern int conf_decode_base64 (u_int8_t *out, u_int32_t *len, u_char *buf);
-extern int conf_end (int, int);
-extern void conf_free_list (struct conf_list *);
-extern struct sockaddr *conf_get_address (char *, char *);
-extern struct conf_list *conf_get_list (char *, char *);
-extern struct conf_list *conf_get_tag_list (char *);
-extern int conf_get_num (char *, char *, int);
-extern char *conf_get_str (char *, char *);
-extern void conf_init (void);
-extern int conf_match_num (char *, char *, int);
-extern void conf_reinit (void);
-extern int conf_remove (int, char *, char *);
-extern int conf_remove_section (int, char *);
-extern int conf_set (int, char *, char *, char *, int, int);
-extern void conf_report (void);
-
-#endif /* _CONF_H_ */
+extern char *conf_path;
+
+extern int conf_begin(void);
+extern int conf_decode_base64(u_int8_t * out, u_int32_t * len, u_char * buf);
+extern int conf_end(int, int);
+extern void conf_free_list(struct conf_list *);
+extern struct sockaddr *conf_get_address(char *, char *);
+extern struct conf_list *conf_get_list(char *, char *);
+extern struct conf_list *conf_get_tag_list(char *);
+extern int conf_get_num(char *, char *, int);
+extern char *conf_get_str(char *, char *);
+extern void conf_init(void);
+extern int conf_match_num(char *, char *, int);
+extern void conf_reinit(void);
+extern int conf_remove(int, char *, char *);
+extern int conf_remove_section(int, char *);
+extern int conf_set(int, char *, char *, char *, int, int);
+extern void conf_report(void);
+
+#endif /* _CONF_H_ */
diff --git a/sbin/isakmpd/connection.c b/sbin/isakmpd/connection.c
index 05236c70df6..d855ed66509 100644
--- a/sbin/isakmpd/connection.c
+++ b/sbin/isakmpd/connection.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: connection.c,v 1.25 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: connection.c,v 1.28 2000/11/23 12:21:18 niklas Exp $ */
+/* $OpenBSD: connection.c,v 1.26 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: connection.c,v 1.28 2000/11/23 12:21:18 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -53,143 +53,137 @@
/* How often should we check that connections we require to be up, are up? */
#define CHECK_INTERVAL 60
-static void connection_passive_teardown (char *);
+static void connection_passive_teardown(char *);
-struct connection
-{
- TAILQ_ENTRY (connection) link;
- char *name;
- struct event *ev;
+struct connection {
+ TAILQ_ENTRY(connection) link;
+ char *name;
+ struct event *ev;
};
-struct connection_passive
-{
- TAILQ_ENTRY (connection_passive) link;
- char *name;
- u_int8_t *local_id, *remote_id;
- size_t local_sz, remote_sz;
+struct connection_passive {
+ TAILQ_ENTRY(connection_passive) link;
+ char *name;
+ u_int8_t *local_id, *remote_id;
+ size_t local_sz, remote_sz;
#if 0
- /* XXX Potential additions to 'connection_passive'. */
- char *isakmp_peer;
- struct sa *sa; /* XXX "Soft" ref to active sa? */
- struct timeval sa_expiration; /* XXX *sa may expire. */
+ /* XXX Potential additions to 'connection_passive'. */
+ char *isakmp_peer;
+ struct sa *sa; /* XXX "Soft" ref to active sa? */
+ struct timeval sa_expiration; /* XXX *sa may expire. */
#endif
};
-TAILQ_HEAD (connection_head, connection) connections;
-TAILQ_HEAD (passive_head, connection_passive) connections_passive;
+TAILQ_HEAD(connection_head, connection) connections;
+TAILQ_HEAD(passive_head, connection_passive) connections_passive;
/*
* This is where we setup all the connections we want there right from the
* start.
*/
void
-connection_init (void)
+connection_init(void)
{
- struct conf_list *conns, *attrs;
- struct conf_list_node *conn, *attr = NULL;
-
- /*
- * Passive connections normally include: all "active" connections that
- * are not flagged "Active-Only", plus all connections listed in
- * the 'Passive-Connections' list.
- */
-
- TAILQ_INIT (&connections);
- TAILQ_INIT (&connections_passive);
-
- conns = conf_get_list ("Phase 2", "Connections");
- if (conns)
- {
- for (conn = TAILQ_FIRST (&conns->fields); conn;
- conn = TAILQ_NEXT (conn, link))
- {
- if (connection_setup (conn->field))
- log_print ("connection_init: could not setup \"%s\"", conn->field);
-
- /* XXX Break/abort here if connection_setup failed? */
-
- /*
- * XXX This code (i.e. the attribute lookup) seems like a
- * likely candidate for factoring out into a function of its
- * own.
- */
- attrs = conf_get_list (conn->field, "Flags");
- if (attrs)
- for (attr = TAILQ_FIRST (&attrs->fields); attr;
- attr = TAILQ_NEXT (attr, link))
- if (strcasecmp ("active-only", attr->field) == 0)
- break;
- if (!attrs || (attrs && !attr))
- if (connection_record_passive (conn->field))
- log_print ("connection_init: could not record "
- "connection \"%s\"", conn->field);
- if (attrs)
- conf_free_list (attrs);
-
+ struct conf_list *conns, *attrs;
+ struct conf_list_node *conn, *attr = NULL;
+
+ /*
+ * Passive connections normally include: all "active" connections that
+ * are not flagged "Active-Only", plus all connections listed in
+ * the 'Passive-Connections' list.
+ */
+ TAILQ_INIT(&connections);
+ TAILQ_INIT(&connections_passive);
+
+ conns = conf_get_list("Phase 2", "Connections");
+ if (conns) {
+ for (conn = TAILQ_FIRST(&conns->fields); conn;
+ conn = TAILQ_NEXT(conn, link)) {
+ if (connection_setup(conn->field))
+ log_print("connection_init: could not setup \"%s\"",
+ conn->field);
+
+ /* XXX Break/abort here if connection_setup failed? */
+
+ /*
+ * XXX This code (i.e. the attribute lookup) seems like a
+ * likely candidate for factoring out into a function of its
+ * own.
+ */
+ attrs = conf_get_list(conn->field, "Flags");
+ if (attrs)
+ for (attr = TAILQ_FIRST(&attrs->fields); attr;
+ attr = TAILQ_NEXT(attr, link))
+ if (strcasecmp("active-only", attr->field) == 0)
+ break;
+ if (!attrs || (attrs && !attr))
+ if (connection_record_passive(conn->field))
+ log_print("connection_init: could not record "
+ "connection \"%s\"", conn->field);
+ if (attrs)
+ conf_free_list(attrs);
+
+ }
+ conf_free_list(conns);
+ }
+ conns = conf_get_list("Phase 2", "Passive-Connections");
+ if (conns) {
+ for (conn = TAILQ_FIRST(&conns->fields); conn;
+ conn = TAILQ_NEXT(conn, link))
+ if (connection_record_passive(conn->field))
+ log_print("connection_init: could not record passive "
+ "connection \"%s\"", conn->field);
+ conf_free_list(conns);
}
- conf_free_list (conns);
- }
-
- conns = conf_get_list ("Phase 2", "Passive-Connections");
- if (conns)
- {
- for (conn = TAILQ_FIRST (&conns->fields); conn;
- conn = TAILQ_NEXT (conn, link))
- if (connection_record_passive (conn->field))
- log_print ("connection_init: could not record passive "
- "connection \"%s\"", conn->field);
- conf_free_list (conns);
- }
}
/* Check the connection in VCONN and schedule another check later. */
static void
-connection_checker (void *vconn)
+connection_checker(void *vconn)
{
- struct timeval now;
- struct connection *conn = vconn;
-
- gettimeofday (&now, 0);
- now.tv_sec += conf_get_num ("General", "check-interval", CHECK_INTERVAL);
- conn->ev
- = timer_add_event ("connection_checker", connection_checker, conn, &now);
- if (!conn->ev)
- log_print ("connection_checker: could not add timer event");
- sysdep_connection_check (conn->name);
+ struct timeval now;
+ struct connection *conn = vconn;
+
+ gettimeofday(&now, 0);
+ now.tv_sec += conf_get_num("General", "check-interval", CHECK_INTERVAL);
+ conn->ev = timer_add_event("connection_checker",
+ connection_checker, conn, &now);
+ if (!conn->ev)
+ log_print("connection_checker: could not add timer event");
+ sysdep_connection_check(conn->name);
}
/* Find the connection named NAME. */
static struct connection *
-connection_lookup (char *name)
+connection_lookup(char *name)
{
- struct connection *conn;
+ struct connection *conn;
- for (conn = TAILQ_FIRST (&connections); conn; conn = TAILQ_NEXT (conn, link))
- if (strcasecmp (conn->name, name) == 0)
- return conn;
- return 0;
+ for (conn = TAILQ_FIRST(&connections); conn; conn = TAILQ_NEXT(conn, link))
+ if (strcasecmp(conn->name, name) == 0)
+ return conn;
+ return 0;
}
/* Does the connection named NAME exist? */
int
-connection_exist (char *name)
+connection_exist(char *name)
{
- return (connection_lookup (name) != 0);
+ return (connection_lookup(name) != 0);
}
/* Find the passive connection named NAME. */
static struct connection_passive *
-connection_passive_lookup_by_name (char *name)
+connection_passive_lookup_by_name(char *name)
{
- struct connection_passive *conn;
+ struct connection_passive *conn;
- for (conn = TAILQ_FIRST (&connections_passive); conn;
- conn = TAILQ_NEXT (conn, link))
- if (strcasecmp (conn->name, name) == 0)
- return conn;
- return 0;
+ for (conn = TAILQ_FIRST(&connections_passive); conn;
+ conn = TAILQ_NEXT(conn, link))
+ if (strcasecmp(conn->name, name) == 0)
+ return conn;
+ return 0;
}
/*
@@ -197,67 +191,63 @@ connection_passive_lookup_by_name (char *name)
* XXX Rename to ipsec_compare_id, and move to ipsec.c ?
*/
static int
-compare_ids (u_int8_t *id1, u_int8_t *id2, size_t idlen)
+compare_ids(u_int8_t *id1, u_int8_t *id2, size_t idlen)
{
- int id1_type, id2_type;
+ int id1_type, id2_type;
- id1_type = GET_ISAKMP_ID_TYPE (id1);
- id2_type = GET_ISAKMP_ID_TYPE (id2);
+ id1_type = GET_ISAKMP_ID_TYPE(id1);
+ id2_type = GET_ISAKMP_ID_TYPE(id2);
- return id1_type == id2_type
- ? memcmp (id1 + ISAKMP_ID_DATA_OFF, id2 + ISAKMP_ID_DATA_OFF,
- idlen - ISAKMP_ID_DATA_OFF) : -1;
+ return id1_type == id2_type ? memcmp(id1 + ISAKMP_ID_DATA_OFF,
+ id2 + ISAKMP_ID_DATA_OFF, idlen - ISAKMP_ID_DATA_OFF) : -1;
}
/* Find the connection named with matching IDs. */
char *
-connection_passive_lookup_by_ids (u_int8_t *id1, u_int8_t *id2)
+connection_passive_lookup_by_ids(u_int8_t *id1, u_int8_t *id2)
{
- struct connection_passive *conn;
-
- for (conn = TAILQ_FIRST (&connections_passive); conn;
- conn = TAILQ_NEXT (conn, link))
- {
- if (!conn->remote_id)
- continue;
-
- /*
- * If both IDs match what we have saved, return the name. Don't bother
- * in which order they are.
- */
- if ((compare_ids (id1, conn->local_id, conn->local_sz) == 0
- && compare_ids (id2, conn->remote_id, conn->remote_sz) == 0)
- || (compare_ids (id1, conn->remote_id, conn->remote_sz) == 0
- && compare_ids (id2, conn->local_id, conn->local_sz) == 0))
- {
- LOG_DBG ((LOG_MISC, 60,
- "connection_passive_lookup_by_ids: returned \"%s\"",
- conn->name));
- return conn->name;
+ struct connection_passive *conn;
+
+ for (conn = TAILQ_FIRST(&connections_passive); conn;
+ conn = TAILQ_NEXT(conn, link)) {
+ if (!conn->remote_id)
+ continue;
+
+ /*
+ * If both IDs match what we have saved, return the name. Don't bother
+ * in which order they are.
+ */
+ if ((compare_ids(id1, conn->local_id, conn->local_sz) == 0 &&
+ compare_ids(id2, conn->remote_id, conn->remote_sz) == 0) ||
+ (compare_ids(id1, conn->remote_id, conn->remote_sz) == 0 &&
+ compare_ids(id2, conn->local_id, conn->local_sz) == 0)) {
+ LOG_DBG((LOG_MISC, 60,
+ "connection_passive_lookup_by_ids: returned \"%s\"",
+ conn->name));
+ return conn->name;
+ }
}
- }
-
- /* In the road warrior case, we do not know the remote ID. In that
- * case we will just match against the local ID.
- */
- for (conn = TAILQ_FIRST (&connections_passive); conn;
- conn = TAILQ_NEXT (conn, link))
- {
- if (!conn->remote_id)
- continue;
-
- if (compare_ids (id1, conn->local_id, conn->local_sz) == 0
- || compare_ids (id2, conn->local_id, conn->local_sz) == 0)
- {
- LOG_DBG ((LOG_MISC, 60,
- "connection passive_lookup_by_ids: returned \"%s\""
- " only matched local id", conn->name));
- return conn->name;
+
+ /*
+ * In the road warrior case, we do not know the remote ID. In that
+ * case we will just match against the local ID.
+ */
+ for (conn = TAILQ_FIRST(&connections_passive); conn;
+ conn = TAILQ_NEXT(conn, link)) {
+ if (!conn->remote_id)
+ continue;
+
+ if (compare_ids(id1, conn->local_id, conn->local_sz) == 0 ||
+ compare_ids(id2, conn->local_id, conn->local_sz) == 0) {
+ LOG_DBG((LOG_MISC, 60,
+ "connection passive_lookup_by_ids: returned \"%s\""
+ " only matched local id", conn->name));
+ return conn->name;
+ }
}
- }
- LOG_DBG ((LOG_MISC, 60,
+ LOG_DBG((LOG_MISC, 60,
"connection_passive_lookup_by_ids: no match"));
- return 0;
+ return 0;
}
/*
@@ -266,210 +256,188 @@ connection_passive_lookup_by_ids (u_int8_t *id1, u_int8_t *id2)
* again.
*/
int
-connection_setup (char *name)
+connection_setup(char *name)
{
- struct connection *conn = 0;
- struct timeval now;
-
- /* Check for trials to add duplicate connections. */
- if (connection_lookup (name))
- {
- LOG_DBG ((LOG_MISC, 10, "connection_setup: cannot add \"%s\" twice",
- name));
- return 0;
- }
-
- conn = calloc (1, sizeof *conn);
- if (!conn)
- {
- log_error ("connection_setup: calloc (1, %lu) failed",
- (unsigned long)sizeof *conn);
- goto fail;
- }
-
- conn->name = strdup (name);
- if (!conn->name)
- {
- log_error ("connection_setup: strdup (\"%s\") failed", name);
- goto fail;
- }
-
- gettimeofday (&now, 0);
- conn->ev
- = timer_add_event ("connection_checker", connection_checker, conn, &now);
- if (!conn->ev)
- {
- log_print ("connection_setup: could not add timer event");
- goto fail;
- }
-
- TAILQ_INSERT_TAIL (&connections, conn, link);
- return 0;
-
- fail:
- if (conn)
- {
- if (conn->name)
- free (conn->name);
- free (conn);
- }
- return -1;
+ struct connection *conn = 0;
+ struct timeval now;
+
+ /* Check for trials to add duplicate connections. */
+ if (connection_lookup(name)) {
+ LOG_DBG((LOG_MISC, 10, "connection_setup: cannot add \"%s\" twice",
+ name));
+ return 0;
+ }
+ conn = calloc(1, sizeof *conn);
+ if (!conn) {
+ log_error("connection_setup: calloc (1, %lu) failed",
+ (unsigned long) sizeof *conn);
+ goto fail;
+ }
+ conn->name = strdup(name);
+ if (!conn->name) {
+ log_error("connection_setup: strdup (\"%s\") failed", name);
+ goto fail;
+ }
+ gettimeofday(&now, 0);
+ conn->ev = timer_add_event("connection_checker",
+ connection_checker, conn, &now);
+ if (!conn->ev) {
+ log_print("connection_setup: could not add timer event");
+ goto fail;
+ }
+ TAILQ_INSERT_TAIL(&connections, conn, link);
+ return 0;
+
+fail:
+ if (conn) {
+ if (conn->name)
+ free(conn->name);
+ free(conn);
+ }
+ return -1;
}
int
-connection_record_passive (char *name)
+connection_record_passive(char *name)
{
- struct connection_passive *conn;
- char *local_id, *remote_id;
-
- if (connection_passive_lookup_by_name (name))
- {
- LOG_DBG ((LOG_MISC, 10,
- "connection_record_passive: cannot add \"%s\" twice",
- name));
- return 0;
- }
-
- local_id = conf_get_str (name, "Local-ID");
- if (!local_id)
- {
- log_print ("connection_record_passive: "
- "\"Local-ID\" is missing from section [%s]",
- name);
- return -1;
- }
-
- /* If the remote id lookup fails we defer it to later */
- remote_id = conf_get_str (name, "Remote-ID");
-
- conn = calloc (1, sizeof *conn);
- if (!conn)
- {
- log_error ("connection_record_passive: calloc (1, %lu) failed",
- (unsigned long)sizeof *conn);
- return -1;
- }
-
- conn->name = strdup (name);
- if (!conn->name)
- {
- log_error ("connection_record_passive: strdup (\"%s\") failed", name);
- goto fail;
- }
-
- /* XXX IPsec DOI-specific. */
- conn->local_id = ipsec_build_id (local_id, &conn->local_sz);
- if (!conn->local_id)
- goto fail;
-
- if (remote_id)
- {
- conn->remote_id = ipsec_build_id (remote_id, &conn->remote_sz);
- if (!conn->remote_id)
- goto fail;
- }
- else
- conn->remote_id = 0;
-
- TAILQ_INSERT_TAIL (&connections_passive, conn, link);
-
- LOG_DBG ((LOG_MISC, 60,
- "connection_record_passive: passive connection \"%s\" "
- "added", conn->name));
- return 0;
-
- fail:
- if (conn->local_id)
- free (conn->local_id);
- if (conn->name)
- free (conn->name);
- free (conn);
- return -1;
+ struct connection_passive *conn;
+ char *local_id, *remote_id;
+
+ if (connection_passive_lookup_by_name(name)) {
+ LOG_DBG((LOG_MISC, 10,
+ "connection_record_passive: cannot add \"%s\" twice",
+ name));
+ return 0;
+ }
+ local_id = conf_get_str(name, "Local-ID");
+ if (!local_id) {
+ log_print("connection_record_passive: "
+ "\"Local-ID\" is missing from section [%s]", name);
+ return -1;
+ }
+ /* If the remote id lookup fails we defer it to later */
+ remote_id = conf_get_str(name, "Remote-ID");
+
+ conn = calloc(1, sizeof *conn);
+ if (!conn) {
+ log_error("connection_record_passive: calloc (1, %lu) failed",
+ (unsigned long) sizeof *conn);
+ return -1;
+ }
+ conn->name = strdup(name);
+ if (!conn->name) {
+ log_error("connection_record_passive: strdup (\"%s\") failed", name);
+ goto fail;
+ }
+ /* XXX IPsec DOI-specific. */
+ conn->local_id = ipsec_build_id(local_id, &conn->local_sz);
+ if (!conn->local_id)
+ goto fail;
+
+ if (remote_id) {
+ conn->remote_id = ipsec_build_id(remote_id, &conn->remote_sz);
+ if (!conn->remote_id)
+ goto fail;
+ } else
+ conn->remote_id = 0;
+
+ TAILQ_INSERT_TAIL(&connections_passive, conn, link);
+
+ LOG_DBG((LOG_MISC, 60,
+ "connection_record_passive: passive connection \"%s\" added",
+ conn->name));
+ return 0;
+
+fail:
+ if (conn->local_id)
+ free(conn->local_id);
+ if (conn->name)
+ free(conn->name);
+ free(conn);
+ return -1;
}
/* Remove the connection named NAME. */
void
-connection_teardown (char *name)
+connection_teardown(char *name)
{
- struct connection *conn;
+ struct connection *conn;
- conn = connection_lookup (name);
- if (!conn)
- return;
+ conn = connection_lookup(name);
+ if (!conn)
+ return;
- TAILQ_REMOVE (&connections, conn, link);
- timer_remove_event (conn->ev);
- free (conn->name);
- free (conn);
+ TAILQ_REMOVE(&connections, conn, link);
+ timer_remove_event(conn->ev);
+ free(conn->name);
+ free(conn);
}
/* Remove the passive connection named NAME. */
static void
-connection_passive_teardown (char *name)
+connection_passive_teardown(char *name)
{
- struct connection_passive *conn;
+ struct connection_passive *conn;
- conn = connection_passive_lookup_by_name (name);
- if (!conn)
- return;
+ conn = connection_passive_lookup_by_name(name);
+ if (!conn)
+ return;
- TAILQ_REMOVE (&connections_passive, conn, link);
- free (conn->name);
- free (conn->local_id);
- free (conn->remote_id);
- free (conn);
+ TAILQ_REMOVE(&connections_passive, conn, link);
+ free(conn->name);
+ free(conn->local_id);
+ free(conn->remote_id);
+ free(conn);
}
void
-connection_report (void)
+connection_report(void)
{
- struct connection *conn;
- struct timeval now;
+ struct connection *conn;
+ struct timeval now;
#ifdef USE_DEBUG
- struct connection_passive *pconn;
- struct doi *doi = doi_lookup (ISAKMP_DOI_ISAKMP);
+ struct connection_passive *pconn;
+ struct doi *doi = doi_lookup(ISAKMP_DOI_ISAKMP);
#endif
- gettimeofday (&now, 0);
- for (conn = TAILQ_FIRST (&connections); conn; conn = TAILQ_NEXT (conn, link))
- LOG_DBG ((LOG_REPORT, 0,
- "connection_report: connection %s next check %ld seconds",
- (conn->name ? conn->name : "<unnamed>"),
- conn->ev->expiration.tv_sec - now.tv_sec));
+ gettimeofday(&now, 0);
+ for (conn = TAILQ_FIRST(&connections); conn; conn = TAILQ_NEXT(conn, link))
+ LOG_DBG((LOG_REPORT, 0,
+ "connection_report: connection %s next check %ld seconds",
+ (conn->name ? conn->name : "<unnamed>"),
+ conn->ev->expiration.tv_sec - now.tv_sec));
#ifdef USE_DEBUG
- for (pconn = TAILQ_FIRST (&connections_passive); pconn;
- pconn = TAILQ_NEXT (pconn, link))
- LOG_DBG ((LOG_REPORT, 0,
- "connection_report: passive connection %s %s", pconn->name,
- doi->decode_ids ("local_id: %s, remote_id: %s",
- pconn->local_id, pconn->local_sz,
- pconn->remote_id, pconn->remote_sz, 1)));
+ for (pconn = TAILQ_FIRST(&connections_passive); pconn;
+ pconn = TAILQ_NEXT(pconn, link))
+ LOG_DBG((LOG_REPORT, 0,
+ "connection_report: passive connection %s %s", pconn->name,
+ doi->decode_ids("local_id: %s, remote_id: %s",
+ pconn->local_id, pconn->local_sz,
+ pconn->remote_id, pconn->remote_sz, 1)));
#endif
}
/* Reinitialize all connections (SIGHUP handling). */
void
-connection_reinit (void)
+connection_reinit(void)
{
- struct connection *conn, *next;
- struct connection_passive *pconn, *pnext;
+ struct connection *conn, *next;
+ struct connection_passive *pconn, *pnext;
- LOG_DBG ((LOG_MISC, 30,
+ LOG_DBG((LOG_MISC, 30,
"connection_reinit: reinitializing connection list"));
- /* Remove all present connections. */
- for (conn = TAILQ_FIRST (&connections); conn; conn = next)
- {
- next = TAILQ_NEXT (conn, link);
- connection_teardown (conn->name);
- }
-
- for (pconn = TAILQ_FIRST (&connections_passive); pconn; pconn = pnext)
- {
- pnext = TAILQ_NEXT (pconn, link);
- connection_passive_teardown (pconn->name);
- }
-
- /* Setup new connections, as the (new) config directs. */
- connection_init ();
+ /* Remove all present connections. */
+ for (conn = TAILQ_FIRST(&connections); conn; conn = next) {
+ next = TAILQ_NEXT(conn, link);
+ connection_teardown(conn->name);
+ }
+
+ for (pconn = TAILQ_FIRST(&connections_passive); pconn; pconn = pnext) {
+ pnext = TAILQ_NEXT(pconn, link);
+ connection_passive_teardown(pconn->name);
+ }
+
+ /* Setup new connections, as the (new) config directs. */
+ connection_init();
}
diff --git a/sbin/isakmpd/connection.h b/sbin/isakmpd/connection.h
index 1e34c732dca..41ee53327e7 100644
--- a/sbin/isakmpd/connection.h
+++ b/sbin/isakmpd/connection.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: connection.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: connection.h,v 1.6 1999/06/07 00:10:48 ho Exp $ */
+/* $OpenBSD: connection.h,v 1.5 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: connection.h,v 1.6 1999/06/07 00:10:48 ho Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -39,13 +39,13 @@
#include <sys/types.h>
-extern int connection_exist (char *);
-extern void connection_init (void);
-extern char *connection_passive_lookup_by_ids (u_int8_t *, u_int8_t *);
-extern void connection_reinit (void);
-extern void connection_report (void);
-extern int connection_setup (char *);
-extern int connection_record_passive (char *);
-extern void connection_teardown (char *);
+extern int connection_exist(char *);
+extern void connection_init(void);
+extern char *connection_passive_lookup_by_ids(u_int8_t *, u_int8_t *);
+extern void connection_reinit(void);
+extern void connection_report(void);
+extern int connection_setup(char *);
+extern int connection_record_passive(char *);
+extern void connection_teardown(char *);
-#endif /* _CONNECTION_H_ */
+#endif /* _CONNECTION_H_ */
diff --git a/sbin/isakmpd/constants.c b/sbin/isakmpd/constants.c
index 0a2883e1831..ec0d0f4b7bd 100644
--- a/sbin/isakmpd/constants.c
+++ b/sbin/isakmpd/constants.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: constants.c,v 1.8 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: constants.c,v 1.7 1999/04/02 00:57:31 niklas Exp $ */
+/* $OpenBSD: constants.c,v 1.9 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: constants.c,v 1.7 1999/04/02 00:57:31 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -37,65 +37,63 @@
#include "constants.h"
int
-constant_value (struct constant_map *map, char *name)
+constant_value(struct constant_map *map, char *name)
{
- struct constant_map *entry = map;
+ struct constant_map *entry = map;
- for (entry = map; entry->name; entry++)
- if (strcasecmp (entry->name, name) == 0)
- return entry->value;
- return 0;
+ for (entry = map; entry->name; entry++)
+ if (strcasecmp(entry->name, name) == 0)
+ return entry->value;
+ return 0;
}
char *
-constant_lookup (struct constant_map *map, int value)
+constant_lookup(struct constant_map *map, int value)
{
- struct constant_map *entry = map;
+ struct constant_map *entry = map;
- for (entry = map; entry->name; entry++)
- if (entry->value == value)
- return entry->name;
- return 0;
+ for (entry = map; entry->name; entry++)
+ if (entry->value == value)
+ return entry->name;
+ return 0;
}
struct constant_map *
-constant_link_lookup (struct constant_map *map, int value)
+constant_link_lookup(struct constant_map *map, int value)
{
- struct constant_map *entry = map;
+ struct constant_map *entry = map;
- for (entry = map; entry->name; entry++)
- if (entry->value == value)
- return entry->link;
- return 0;
+ for (entry = map; entry->name; entry++)
+ if (entry->value == value)
+ return entry->link;
+ return 0;
}
char *
-constant_name (struct constant_map *map, int value)
+constant_name(struct constant_map *map, int value)
{
- static char tmp[32]; /* XXX Ugly, I know. */
- char *retval = constant_lookup (map, value);
+ static char tmp[32];/* XXX Ugly, I know. */
+ char *retval = constant_lookup(map, value);
- if (!retval)
- {
- snprintf (tmp, sizeof tmp, "<Unknown %d>", value);
- return tmp;
- }
- return retval;
+ if (!retval) {
+ snprintf(tmp, sizeof tmp, "<Unknown %d>", value);
+ return tmp;
+ }
+ return retval;
}
char *
-constant_name_maps (struct constant_map **maps, int value)
+constant_name_maps(struct constant_map **maps, int value)
{
- static char tmp[32]; /* XXX Ugly, I know. */
- char *retval;
- struct constant_map **map;
+ static char tmp[32];/* XXX Ugly, I know. */
+ char *retval;
+ struct constant_map **map;
- for (map = maps; *map; map++)
- {
- retval = constant_lookup (*map, value);
- if (retval)
- return retval;
- }
- snprintf (tmp, sizeof tmp, "<Unknown %d>", value);
- return tmp;
+ for (map = maps; *map; map++) {
+ retval = constant_lookup(*map, value);
+ if (retval)
+ return retval;
+ }
+ snprintf(tmp, sizeof tmp, "<Unknown %d>", value);
+ return tmp;
}
diff --git a/sbin/isakmpd/constants.h b/sbin/isakmpd/constants.h
index 91bd0e2e89e..e3dd439e363 100644
--- a/sbin/isakmpd/constants.h
+++ b/sbin/isakmpd/constants.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: constants.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: constants.h,v 1.5 1998/11/20 07:17:01 niklas Exp $ */
+/* $OpenBSD: constants.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: constants.h,v 1.5 1998/11/20 07:17:01 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -33,15 +33,15 @@
#define _CONSTANTS_H_
struct constant_map {
- int value;
- char *name;
- struct constant_map *link;
+ int value;
+ char *name;
+ struct constant_map *link;
};
-struct constant_map *constant_link_lookup (struct constant_map *, int);
-extern char *constant_lookup (struct constant_map *, int);
-extern char *constant_name (struct constant_map *, int);
-extern char *constant_name_maps (struct constant_map **, int);
-extern int constant_value (struct constant_map *, char *);
+struct constant_map *constant_link_lookup(struct constant_map *, int);
+extern char *constant_lookup(struct constant_map *, int);
+extern char *constant_name(struct constant_map *, int);
+extern char *constant_name_maps(struct constant_map **, int);
+extern int constant_value(struct constant_map *, char *);
-#endif /* _CONSTANTS_H_ */
+#endif /* _CONSTANTS_H_ */
diff --git a/sbin/isakmpd/cookie.c b/sbin/isakmpd/cookie.c
index ad9021316a1..56e6ae734b6 100644
--- a/sbin/isakmpd/cookie.c
+++ b/sbin/isakmpd/cookie.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cookie.c,v 1.12 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: cookie.c,v 1.21 1999/08/05 15:00:04 niklas Exp $ */
+/* $OpenBSD: cookie.c,v 1.13 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: cookie.c,v 1.21 1999/08/05 15:00:04 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -52,23 +52,23 @@
* EXCHANGE.
*/
void
-cookie_gen (struct transport *t, struct exchange *exchange, u_int8_t *buf,
- size_t len)
+cookie_gen(struct transport *t, struct exchange *exchange, u_int8_t *buf,
+ size_t len)
{
- struct hash* hash = hash_get (HASH_SHA1);
- struct sockaddr *name;
- u_int8_t tmpsecret[COOKIE_SECRET_SIZE];
+ struct hash *hash = hash_get(HASH_SHA1);
+ u_int8_t tmpsecret[COOKIE_SECRET_SIZE];
+ struct sockaddr *name;
- hash->Init (hash->ctx);
- (*t->vtbl->get_dst) (t, &name);
- hash->Update (hash->ctx, (u_int8_t *)name, sysdep_sa_len (name));
- (*t->vtbl->get_src) (t, &name);
- hash->Update (hash->ctx, (u_int8_t *)name, sysdep_sa_len (name));
- if (exchange->initiator == 0)
- hash->Update (hash->ctx, exchange->cookies + ISAKMP_HDR_ICOOKIE_OFF,
- ISAKMP_HDR_ICOOKIE_LEN);
- getrandom (tmpsecret, COOKIE_SECRET_SIZE);
- hash->Update (hash->ctx, tmpsecret, COOKIE_SECRET_SIZE);
- hash->Final (hash->digest, hash->ctx);
- memcpy (buf, hash->digest, len);
+ hash->Init(hash->ctx);
+ (*t->vtbl->get_dst) (t, &name);
+ hash->Update(hash->ctx, (u_int8_t *) name, sysdep_sa_len(name));
+ (*t->vtbl->get_src) (t, &name);
+ hash->Update(hash->ctx, (u_int8_t *) name, sysdep_sa_len(name));
+ if (exchange->initiator == 0)
+ hash->Update(hash->ctx, exchange->cookies + ISAKMP_HDR_ICOOKIE_OFF,
+ ISAKMP_HDR_ICOOKIE_LEN);
+ getrandom(tmpsecret, COOKIE_SECRET_SIZE);
+ hash->Update(hash->ctx, tmpsecret, COOKIE_SECRET_SIZE);
+ hash->Final(hash->digest, hash->ctx);
+ memcpy(buf, hash->digest, len);
}
diff --git a/sbin/isakmpd/cookie.h b/sbin/isakmpd/cookie.h
index 7fa1ffd05e3..ed5a8ba9768 100644
--- a/sbin/isakmpd/cookie.h
+++ b/sbin/isakmpd/cookie.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: cookie.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: cookie.h,v 1.5 1998/08/05 09:21:43 niklas Exp $ */
+/* $OpenBSD: cookie.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: cookie.h,v 1.5 1998/08/05 09:21:43 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -38,7 +38,8 @@
struct exchange;
struct transport;
-extern void cookie_gen (struct transport *, struct exchange *, u_int8_t *,
- size_t);
+extern void
+cookie_gen(struct transport *, struct exchange *, u_int8_t *,
+ size_t);
-#endif /* _COOKIE_H_ */
+#endif /* _COOKIE_H_ */
diff --git a/sbin/isakmpd/crypto.c b/sbin/isakmpd/crypto.c
index 964cb4e5f55..f53f9dfc194 100644
--- a/sbin/isakmpd/crypto.c
+++ b/sbin/isakmpd/crypto.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: crypto.c,v 1.19 2004/03/31 10:54:46 ho Exp $ */
-/* $EOM: crypto.c,v 1.32 2000/03/07 20:08:51 niklas Exp $ */
+/* $OpenBSD: crypto.c,v 1.20 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: crypto.c,v 1.32 2000/03/07 20:08:51 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -39,57 +39,57 @@
#include "crypto.h"
#include "log.h"
-enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t);
-enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t);
-enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t);
-enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t);
-enum cryptoerr aes_init (struct keystate *, u_int8_t *, u_int16_t);
-void des1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-void des1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
-void des3_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-void des3_decrypt (struct keystate *, u_int8_t *, u_int16_t);
-void blf_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-void blf_decrypt (struct keystate *, u_int8_t *, u_int16_t);
-void cast1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-void cast1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
-void aes_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-void aes_decrypt (struct keystate *, u_int8_t *, u_int16_t);
+enum cryptoerr des1_init(struct keystate *, u_int8_t *, u_int16_t);
+enum cryptoerr des3_init(struct keystate *, u_int8_t *, u_int16_t);
+enum cryptoerr blf_init(struct keystate *, u_int8_t *, u_int16_t);
+enum cryptoerr cast_init(struct keystate *, u_int8_t *, u_int16_t);
+enum cryptoerr aes_init(struct keystate *, u_int8_t *, u_int16_t);
+void des1_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+void des1_decrypt(struct keystate *, u_int8_t *, u_int16_t);
+void des3_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+void des3_decrypt(struct keystate *, u_int8_t *, u_int16_t);
+void blf_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+void blf_decrypt(struct keystate *, u_int8_t *, u_int16_t);
+void cast1_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+void cast1_decrypt(struct keystate *, u_int8_t *, u_int16_t);
+void aes_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+void aes_decrypt(struct keystate *, u_int8_t *, u_int16_t);
struct crypto_xf transforms[] = {
#ifdef USE_DES
- {
- DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0,
- des1_init,
- des1_encrypt, des1_decrypt
- },
+ {
+ DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0,
+ des1_init,
+ des1_encrypt, des1_decrypt
+ },
#endif
#ifdef USE_TRIPLEDES
- {
- TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0,
- des3_init,
- des3_encrypt, des3_decrypt
- },
+ {
+ TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0,
+ des3_init,
+ des3_encrypt, des3_decrypt
+ },
#endif
#ifdef USE_BLOWFISH
- {
- BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0,
- blf_init,
- blf_encrypt, blf_decrypt
- },
+ {
+ BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0,
+ blf_init,
+ blf_encrypt, blf_decrypt
+ },
#endif
#ifdef USE_CAST
- {
- CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0,
- cast_init,
- cast1_encrypt, cast1_decrypt
- },
+ {
+ CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0,
+ cast_init,
+ cast1_encrypt, cast1_decrypt
+ },
#endif
#ifdef USE_AES
- {
- AES_CBC, "AES (CBC-Mode)", 16, 32, AES_BLOCK_SIZE, 0,
- aes_init,
- aes_encrypt, aes_decrypt
- },
+ {
+ AES_CBC, "AES (CBC-Mode)", 16, 32, AES_BLOCK_SIZE, 0,
+ aes_init,
+ aes_encrypt, aes_decrypt
+ },
#endif
};
@@ -101,318 +101,303 @@ struct crypto_xf transforms[] = {
#endif
enum cryptoerr
-des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
+des1_init(struct keystate * ks, u_int8_t * key, u_int16_t len)
{
- /* des_set_key returns -1 for parity problems, and -2 for weak keys */
- des_set_odd_parity (DC key);
- switch (des_set_key (DC key, ks->ks_des[0]))
- {
- case -2:
- return EWEAKKEY;
- default:
- return EOKAY;
- }
+ /* des_set_key returns -1 for parity problems, and -2 for weak keys */
+ des_set_odd_parity(DC key);
+ switch (des_set_key(DC key, ks->ks_des[0])) {
+ case -2:
+ return EWEAKKEY;
+ default:
+ return EOKAY;
+ }
}
void
-des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
+des1_encrypt(struct keystate * ks, u_int8_t * d, u_int16_t len)
{
- des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT);
+ des_cbc_encrypt(DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT);
}
void
-des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
+des1_decrypt(struct keystate * ks, u_int8_t * d, u_int16_t len)
{
- des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT);
+ des_cbc_encrypt(DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT);
}
#ifdef USE_TRIPLEDES
enum cryptoerr
-des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
+des3_init(struct keystate * ks, u_int8_t * key, u_int16_t len)
{
- des_set_odd_parity (DC key);
- des_set_odd_parity (DC (key + 8));
- des_set_odd_parity (DC (key + 16));
+ des_set_odd_parity(DC key);
+ des_set_odd_parity(DC(key + 8));
+ des_set_odd_parity(DC(key + 16));
- /* As of the draft Tripe-DES does not check for weak keys */
- des_set_key (DC key, ks->ks_des[0]);
- des_set_key (DC (key + 8), ks->ks_des[1]);
- des_set_key (DC (key + 16), ks->ks_des[2]);
+ /* As of the draft Tripe-DES does not check for weak keys */
+ des_set_key(DC key, ks->ks_des[0]);
+ des_set_key(DC(key + 8), ks->ks_des[1]);
+ des_set_key(DC(key + 16), ks->ks_des[2]);
- return EOKAY;
+ return EOKAY;
}
void
-des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+des3_encrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int8_t iv[MAXBLK];
+ u_int8_t iv[MAXBLK];
- memcpy (iv, ks->riv, ks->xf->blocksize);
- des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
- ks->ks_des[2], DC iv, DES_ENCRYPT);
+ memcpy(iv, ks->riv, ks->xf->blocksize);
+ des_ede3_cbc_encrypt(DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
+ ks->ks_des[2], DC iv, DES_ENCRYPT);
}
void
-des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+des3_decrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int8_t iv[MAXBLK];
+ u_int8_t iv[MAXBLK];
- memcpy (iv, ks->riv, ks->xf->blocksize);
- des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
- ks->ks_des[2], DC iv, DES_DECRYPT);
+ memcpy(iv, ks->riv, ks->xf->blocksize);
+ des_ede3_cbc_encrypt(DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
+ ks->ks_des[2], DC iv, DES_DECRYPT);
}
#undef DC
-#endif /* USE_TRIPLEDES */
+#endif /* USE_TRIPLEDES */
#ifdef USE_BLOWFISH
enum cryptoerr
-blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
+blf_init(struct keystate * ks, u_int8_t * key, u_int16_t len)
{
- blf_key (&ks->ks_blf, key, len);
+ blf_key(&ks->ks_blf, key, len);
- return EOKAY;
+ return EOKAY;
}
void
-blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+blf_encrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int16_t i, blocksize = ks->xf->blocksize;
- u_int8_t *iv = ks->liv;
- u_int32_t xl, xr;
-
- memcpy (iv, ks->riv, blocksize);
-
- for (i = 0; i < len; data += blocksize, i += blocksize)
- {
- XOR64 (data, iv);
- xl = GET_32BIT_BIG (data);
- xr = GET_32BIT_BIG (data + 4);
- Blowfish_encipher (&ks->ks_blf, &xl, &xr);
- SET_32BIT_BIG (data, xl);
- SET_32BIT_BIG (data + 4, xr);
- SET64 (iv, data);
- }
+ u_int16_t i, blocksize = ks->xf->blocksize;
+ u_int8_t *iv = ks->liv;
+ u_int32_t xl, xr;
+
+ memcpy(iv, ks->riv, blocksize);
+
+ for (i = 0; i < len; data += blocksize, i += blocksize) {
+ XOR64(data, iv);
+ xl = GET_32BIT_BIG(data);
+ xr = GET_32BIT_BIG(data + 4);
+ Blowfish_encipher(&ks->ks_blf, &xl, &xr);
+ SET_32BIT_BIG(data, xl);
+ SET_32BIT_BIG(data + 4, xr);
+ SET64(iv, data);
+ }
}
void
-blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+blf_decrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int16_t i, blocksize = ks->xf->blocksize;
- u_int32_t xl, xr;
-
- data += len - blocksize;
- for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
- {
- xl = GET_32BIT_BIG (data);
- xr = GET_32BIT_BIG (data + 4);
- Blowfish_decipher (&ks->ks_blf, &xl, &xr);
- SET_32BIT_BIG (data, xl);
- SET_32BIT_BIG (data + 4, xr);
- XOR64 (data, data - blocksize);
-
- }
- xl = GET_32BIT_BIG (data);
- xr = GET_32BIT_BIG (data + 4);
- Blowfish_decipher (&ks->ks_blf, &xl, &xr);
- SET_32BIT_BIG (data, xl);
- SET_32BIT_BIG (data + 4, xr);
- XOR64 (data, ks->riv);
+ u_int16_t i, blocksize = ks->xf->blocksize;
+ u_int32_t xl, xr;
+
+ data += len - blocksize;
+ for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) {
+ xl = GET_32BIT_BIG(data);
+ xr = GET_32BIT_BIG(data + 4);
+ Blowfish_decipher(&ks->ks_blf, &xl, &xr);
+ SET_32BIT_BIG(data, xl);
+ SET_32BIT_BIG(data + 4, xr);
+ XOR64(data, data - blocksize);
+
+ }
+ xl = GET_32BIT_BIG(data);
+ xr = GET_32BIT_BIG(data + 4);
+ Blowfish_decipher(&ks->ks_blf, &xl, &xr);
+ SET_32BIT_BIG(data, xl);
+ SET_32BIT_BIG(data + 4, xr);
+ XOR64(data, ks->riv);
}
-#endif /* USE_BLOWFISH */
+#endif /* USE_BLOWFISH */
#ifdef USE_CAST
enum cryptoerr
-cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
+cast_init(struct keystate * ks, u_int8_t * key, u_int16_t len)
{
- cast_setkey (&ks->ks_cast, key, len);
- return EOKAY;
+ cast_setkey(&ks->ks_cast, key, len);
+ return EOKAY;
}
void
-cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+cast1_encrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int16_t i, blocksize = ks->xf->blocksize;
- u_int8_t *iv = ks->liv;
+ u_int16_t i, blocksize = ks->xf->blocksize;
+ u_int8_t *iv = ks->liv;
- memcpy (iv, ks->riv, blocksize);
+ memcpy(iv, ks->riv, blocksize);
- for (i = 0; i < len; data += blocksize, i += blocksize)
- {
- XOR64 (data, iv);
- cast_encrypt (&ks->ks_cast, data, data);
- SET64 (iv, data);
- }
+ for (i = 0; i < len; data += blocksize, i += blocksize) {
+ XOR64(data, iv);
+ cast_encrypt(&ks->ks_cast, data, data);
+ SET64(iv, data);
+ }
}
void
-cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+cast1_decrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int16_t i, blocksize = ks->xf->blocksize;
-
- data += len - blocksize;
- for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
- {
- cast_decrypt (&ks->ks_cast, data, data);
- XOR64 (data, data - blocksize);
- }
- cast_decrypt (&ks->ks_cast, data, data);
- XOR64 (data, ks->riv);
+ u_int16_t i, blocksize = ks->xf->blocksize;
+
+ data += len - blocksize;
+ for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) {
+ cast_decrypt(&ks->ks_cast, data, data);
+ XOR64(data, data - blocksize);
+ }
+ cast_decrypt(&ks->ks_cast, data, data);
+ XOR64(data, ks->riv);
}
-#endif /* USE_CAST */
+#endif /* USE_CAST */
#ifdef USE_AES
enum cryptoerr
-aes_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
+aes_init(struct keystate * ks, u_int8_t * key, u_int16_t len)
{
- AES_set_encrypt_key (key, len << 3, &ks->ks_aes[0]);
- AES_set_decrypt_key (key, len << 3, &ks->ks_aes[1]);
- return EOKAY;
+ AES_set_encrypt_key(key, len << 3, &ks->ks_aes[0]);
+ AES_set_decrypt_key(key, len << 3, &ks->ks_aes[1]);
+ return EOKAY;
}
void
-aes_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+aes_encrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int8_t iv[MAXBLK];
+ u_int8_t iv[MAXBLK];
- memcpy (iv, ks->riv, ks->xf->blocksize);
- AES_cbc_encrypt (data, data, len, &ks->ks_aes[0], iv, AES_ENCRYPT);
+ memcpy(iv, ks->riv, ks->xf->blocksize);
+ AES_cbc_encrypt(data, data, len, &ks->ks_aes[0], iv, AES_ENCRYPT);
}
void
-aes_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
+aes_decrypt(struct keystate * ks, u_int8_t * data, u_int16_t len)
{
- u_int8_t iv[MAXBLK];
+ u_int8_t iv[MAXBLK];
- memcpy (iv, ks->riv, ks->xf->blocksize);
- AES_cbc_encrypt (data, data, len, &ks->ks_aes[1], iv, AES_DECRYPT);
+ memcpy(iv, ks->riv, ks->xf->blocksize);
+ AES_cbc_encrypt(data, data, len, &ks->ks_aes[1], iv, AES_DECRYPT);
}
-#endif /* USE_AES */
+#endif /* USE_AES */
struct crypto_xf *
-crypto_get (enum transform id)
+crypto_get(enum transform id)
{
- size_t i;
+ size_t i;
- for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
- if (id == transforms[i].id)
- return &transforms[i];
+ for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
+ if (id == transforms[i].id)
+ return &transforms[i];
- return 0;
+ return 0;
}
struct keystate *
-crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len,
- enum cryptoerr *err)
+crypto_init(struct crypto_xf * xf, u_int8_t * key, u_int16_t len,
+ enum cryptoerr * err)
{
- struct keystate *ks;
-
- if (len < xf->keymin || len > xf->keymax)
- {
- LOG_DBG ((LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len));
- *err = EKEYLEN;
- return 0;
- }
-
- ks = calloc (1, sizeof *ks);
- if (!ks)
- {
- log_error ("crypto_init: calloc (1, %lu) failed",
- (unsigned long)sizeof *ks);
- *err = ENOCRYPTO;
- return 0;
- }
-
- ks->xf = xf;
-
- /* Setup the IV. */
- ks->riv = ks->iv;
- ks->liv = ks->iv2;
-
- LOG_DBG_BUF ((LOG_CRYPTO, 40, "crypto_init: key", key, len));
-
- *err = xf->init (ks, key, len);
- if (*err != EOKAY)
- {
- LOG_DBG ((LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
- xf->name));
- free (ks);
- return 0;
- }
-
- return ks;
+ struct keystate *ks;
+
+ if (len < xf->keymin || len > xf->keymax) {
+ LOG_DBG((LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len));
+ *err = EKEYLEN;
+ return 0;
+ }
+ ks = calloc(1, sizeof *ks);
+ if (!ks) {
+ log_error("crypto_init: calloc (1, %lu) failed",
+ (unsigned long) sizeof *ks);
+ *err = ENOCRYPTO;
+ return 0;
+ }
+ ks->xf = xf;
+
+ /* Setup the IV. */
+ ks->riv = ks->iv;
+ ks->liv = ks->iv2;
+
+ LOG_DBG_BUF((LOG_CRYPTO, 40, "crypto_init: key", key, len));
+
+ *err = xf->init(ks, key, len);
+ if (*err != EOKAY) {
+ LOG_DBG((LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
+ xf->name));
+ free(ks);
+ return 0;
+ }
+ return ks;
}
void
-crypto_update_iv (struct keystate *ks)
+crypto_update_iv(struct keystate * ks)
{
- u_int8_t *tmp;
+ u_int8_t *tmp;
- tmp = ks->riv;
- ks->riv = ks->liv;
- ks->liv = tmp;
+ tmp = ks->riv;
+ ks->riv = ks->liv;
+ ks->liv = tmp;
- LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
- ks->xf->blocksize));
+ LOG_DBG_BUF((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
+ ks->xf->blocksize));
}
void
-crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len)
+crypto_init_iv(struct keystate * ks, u_int8_t * buf, size_t len)
{
- memcpy (ks->riv, buf, len);
+ memcpy(ks->riv, buf, len);
- LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_init_iv: initialized IV", ks->riv,
- len));
+ LOG_DBG_BUF((LOG_CRYPTO, 50, "crypto_init_iv: initialized IV", ks->riv,
+ len));
}
void
-crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
+crypto_encrypt(struct keystate * ks, u_int8_t * buf, u_int16_t len)
{
- LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
- len));
- ks->xf->encrypt (ks, buf, len);
- memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
- LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
- len));
+ LOG_DBG_BUF((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
+ len));
+ ks->xf->encrypt(ks, buf, len);
+ memcpy(ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
+ LOG_DBG_BUF((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
+ len));
}
void
-crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
+crypto_decrypt(struct keystate * ks, u_int8_t * buf, u_int16_t len)
{
- LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
- len));
- /*
- * XXX There is controversy about the correctness of updating the IV
- * like this.
- */
- memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
- ks->xf->decrypt (ks, buf, len);
- LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
- len));
+ LOG_DBG_BUF((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
+ len));
+ /*
+ * XXX There is controversy about the correctness of updating the IV
+ * like this.
+ */
+ memcpy(ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
+ ks->xf->decrypt(ks, buf, len);
+ LOG_DBG_BUF((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
+ len));
}
/* Make a copy of the keystate pointed to by OKS. */
struct keystate *
-crypto_clone_keystate (struct keystate *oks)
+crypto_clone_keystate(struct keystate * oks)
{
- struct keystate *ks;
-
- ks = malloc (sizeof *ks);
- if (!ks)
- {
- log_error ("crypto_clone_keystate: malloc (%lu) failed",
- (unsigned long)sizeof *ks);
- return 0;
- }
- memcpy (ks, oks, sizeof *ks);
- if (oks->riv == oks->iv)
- {
- ks->riv = ks->iv;
- ks->liv = ks->iv2;
- }
- else
- {
- ks->riv = ks->iv2;
- ks->liv = ks->iv;
- }
- return ks;
+ struct keystate *ks;
+
+ ks = malloc(sizeof *ks);
+ if (!ks) {
+ log_error("crypto_clone_keystate: malloc (%lu) failed",
+ (unsigned long) sizeof *ks);
+ return 0;
+ }
+ memcpy(ks, oks, sizeof *ks);
+ if (oks->riv == oks->iv) {
+ ks->riv = ks->iv;
+ ks->liv = ks->iv2;
+ } else {
+ ks->riv = ks->iv2;
+ ks->liv = ks->iv;
+ }
+ return ks;
}
diff --git a/sbin/isakmpd/crypto.h b/sbin/isakmpd/crypto.h
index 13c799b3e20..7354e03ad2f 100644
--- a/sbin/isakmpd/crypto.h
+++ b/sbin/isakmpd/crypto.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: crypto.h,v 1.12 2003/12/22 18:13:58 markus Exp $ */
-/* $EOM: crypto.h,v 1.12 2000/10/15 21:56:41 niklas Exp $ */
+/* $OpenBSD: crypto.h,v 1.13 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: crypto.h,v 1.12 2000/10/15 21:56:41 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -52,7 +52,7 @@
#include <cast.h>
#endif
-#endif /* __APPLE__ */
+#endif /* __APPLE__ */
#ifdef USE_AES
#include <openssl/aes.h>
@@ -80,7 +80,7 @@
#define SET64(x,y) SET8(x,y,0); SET8(x,y,1); SET8(x,y,2); SET8(x,y,3); \
SET8(x,y,4); SET8(x,y,5); SET8(x,y,6); SET8(x,y,7);
-#endif /* USE_64BIT */
+#endif /* USE_64BIT */
#define SET_32BIT_BIG(x,y) (x)[3]= (y); (x)[2]= (y) >> 8; \
(x)[1] = (y) >> 16; (x)[0]= (y) >> 24;
@@ -100,25 +100,25 @@
#endif
struct keystate {
- struct crypto_xf *xf; /* Back pointer */
- u_int16_t ebytes; /* Number of encrypted bytes */
- u_int16_t dbytes; /* Number of decrypted bytes */
- time_t life; /* Creation time */
- u_int8_t iv[MAXBLK]; /* Next IV to use */
- u_int8_t iv2[MAXBLK];
- u_int8_t *riv, *liv;
- union {
- des_key_schedule desks[3];
+ struct crypto_xf *xf; /* Back pointer */
+ u_int16_t ebytes; /* Number of encrypted bytes */
+ u_int16_t dbytes; /* Number of decrypted bytes */
+ time_t life; /* Creation time */
+ u_int8_t iv[MAXBLK]; /* Next IV to use */
+ u_int8_t iv2[MAXBLK];
+ u_int8_t *riv, *liv;
+ union {
+ des_key_schedule desks[3];
#ifdef USE_BLOWFISH
- blf_ctx blfks;
+ blf_ctx blfks;
#endif
#ifdef USE_CAST
- cast_key castks;
+ cast_key castks;
#endif
#ifdef USE_AES
- AES_KEY aesks[2];
+ AES_KEY aesks[2];
#endif
- } keydata;
+ } keydata;
};
#define ks_des keydata.desks
@@ -136,40 +136,41 @@ struct keystate {
* only anyhow, and we already have defines for that in ipsec_doi.h.
*/
enum transform {
- DES_CBC=1, /* This is a MUST */
- IDEA_CBC=2, /* Licensed, DONT use */
- BLOWFISH_CBC=3,
- RC5_R16_B64_CBC=4, /* Licensed, DONT use */
- TRIPLEDES_CBC=5, /* This is a SHOULD */
- CAST_CBC=6,
- AES_CBC=7
+ DES_CBC = 1, /* This is a MUST */
+ IDEA_CBC = 2, /* Licensed, DONT use */
+ BLOWFISH_CBC = 3,
+ RC5_R16_B64_CBC = 4, /* Licensed, DONT use */
+ TRIPLEDES_CBC = 5, /* This is a SHOULD */
+ CAST_CBC = 6,
+ AES_CBC = 7
};
enum cryptoerr {
- EOKAY, /* No error */
- ENOCRYPTO, /* A none crypto related error, see errno */
- EWEAKKEY, /* A weak key was found in key setup */
- EKEYLEN /* The key length was invalid for the cipher */
+ EOKAY, /* No error */
+ ENOCRYPTO, /* A none crypto related error, see errno */
+ EWEAKKEY, /* A weak key was found in key setup */
+ EKEYLEN /* The key length was invalid for the cipher */
};
struct crypto_xf {
- enum transform id; /* Oakley ID */
- char *name; /* Transform Name */
- u_int16_t keymin, keymax; /* Possible Keying Bytes */
- u_int16_t blocksize; /* Need to keep IV in the state */
- struct keystate *state; /* Key information, can also be passed sep. */
- enum cryptoerr (*init) (struct keystate *, u_int8_t *, u_int16_t);
- void (*encrypt) (struct keystate *, u_int8_t *, u_int16_t);
- void (*decrypt) (struct keystate *, u_int8_t *, u_int16_t);
+ enum transform id; /* Oakley ID */
+ char *name; /* Transform Name */
+ u_int16_t keymin, keymax; /* Possible Keying Bytes */
+ u_int16_t blocksize; /* Need to keep IV in the state */
+ struct keystate *state; /* Key information, can also be passed sep. */
+ enum cryptoerr (*init) (struct keystate *, u_int8_t *, u_int16_t);
+ void (*encrypt) (struct keystate *, u_int8_t *, u_int16_t);
+ void (*decrypt) (struct keystate *, u_int8_t *, u_int16_t);
};
-extern struct keystate *crypto_clone_keystate (struct keystate *);
-extern void crypto_decrypt (struct keystate *, u_int8_t *, u_int16_t);
-extern void crypto_encrypt (struct keystate *, u_int8_t *, u_int16_t);
-extern struct crypto_xf *crypto_get (enum transform);
-extern struct keystate *crypto_init (struct crypto_xf *, u_int8_t *,
- u_int16_t, enum cryptoerr *);
-extern void crypto_init_iv (struct keystate *, u_int8_t *, size_t);
-extern void crypto_update_iv (struct keystate *);
-
-#endif /* _CRYPTO_H_ */
+extern struct keystate *crypto_clone_keystate(struct keystate *);
+extern void crypto_decrypt(struct keystate *, u_int8_t *, u_int16_t);
+extern void crypto_encrypt(struct keystate *, u_int8_t *, u_int16_t);
+extern struct crypto_xf *crypto_get(enum transform);
+extern struct keystate *
+crypto_init(struct crypto_xf *, u_int8_t *,
+ u_int16_t, enum cryptoerr *);
+extern void crypto_init_iv(struct keystate *, u_int8_t *, size_t);
+extern void crypto_update_iv(struct keystate *);
+
+#endif /* _CRYPTO_H_ */
diff --git a/sbin/isakmpd/dh.c b/sbin/isakmpd/dh.c
index c2ba993cd72..afb41baf2c2 100644
--- a/sbin/isakmpd/dh.c
+++ b/sbin/isakmpd/dh.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dh.c,v 1.8 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: dh.c,v 1.5 1999/04/17 23:20:22 niklas Exp $ */
+/* $OpenBSD: dh.c,v 1.9 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: dh.c,v 1.5 1999/04/17 23:20:22 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -43,9 +43,9 @@
*/
int
-dh_getlen (struct group *group)
+dh_getlen(struct group *group)
{
- return group->getlen (group);
+ return group->getlen(group);
}
/*
@@ -55,14 +55,14 @@ dh_getlen (struct group *group)
* dh_create_exchange should only be called once.
*/
int
-dh_create_exchange (struct group *group, u_int8_t *buf)
+dh_create_exchange(struct group *group, u_int8_t *buf)
{
- if (group->setrandom (group, group->c))
- return -1;
- if (group->operation (group, group->a, group->gen, group->c))
- return -1;
- group->getraw (group, group->a, buf);
- return 0;
+ if (group->setrandom(group, group->c))
+ return -1;
+ if (group->operation(group, group->a, group->gen, group->c))
+ return -1;
+ group->getraw(group, group->a, buf);
+ return 0;
}
/*
@@ -71,12 +71,12 @@ dh_create_exchange (struct group *group, u_int8_t *buf)
* is done for the value, the application has to do that.
*/
int
-dh_create_shared (struct group *group, u_int8_t *secret, u_int8_t *exchange)
+dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
{
- if (group->setraw (group, group->b, exchange, group->getlen (group)))
- return -1;
- if (group->operation (group, group->a, group->b, group->c))
- return -1;
- group->getraw (group, group->a, secret);
- return 0;
+ if (group->setraw(group, group->b, exchange, group->getlen(group)))
+ return -1;
+ if (group->operation(group, group->a, group->b, group->c))
+ return -1;
+ group->getraw(group, group->a, secret);
+ return 0;
}
diff --git a/sbin/isakmpd/dh.h b/sbin/isakmpd/dh.h
index 0da058e3c34..96c30d2cfd5 100644
--- a/sbin/isakmpd/dh.h
+++ b/sbin/isakmpd/dh.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dh.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: dh.h,v 1.4 1999/04/17 23:20:24 niklas Exp $ */
+/* $OpenBSD: dh.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: dh.h,v 1.4 1999/04/17 23:20:24 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -36,8 +36,8 @@
struct group;
-int dh_getlen (struct group *);
-int dh_create_exchange (struct group *, u_int8_t *);
-int dh_create_shared (struct group *, u_int8_t *, u_int8_t *);
+int dh_getlen(struct group *);
+int dh_create_exchange(struct group *, u_int8_t *);
+int dh_create_shared(struct group *, u_int8_t *, u_int8_t *);
-#endif /* _DH_H_ */
+#endif /* _DH_H_ */
diff --git a/sbin/isakmpd/dnssec.c b/sbin/isakmpd/dnssec.c
index 85dfed006d8..9fc4b0c6e09 100644
--- a/sbin/isakmpd/dnssec.c
+++ b/sbin/isakmpd/dnssec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dnssec.c,v 1.17 2003/11/06 16:12:07 ho Exp $ */
+/* $OpenBSD: dnssec.c,v 1.18 2004/04/15 18:39:25 deraadt Exp $ */
/*
* Copyright (c) 2001 Håkan Olsson. All rights reserved.
@@ -56,260 +56,230 @@
/* adapted from <dns/rdatastruct.h> / RFC 2535 */
struct dns_rdata_key {
- u_int16_t flags;
- u_int8_t protocol;
- u_int8_t algorithm;
- u_int16_t datalen;
- unsigned char *data;
+ u_int16_t flags;
+ u_int8_t protocol;
+ u_int8_t algorithm;
+ u_int16_t datalen;
+ unsigned char *data;
};
-void *
-dns_get_key (int type, struct message *msg, int *keylen)
+void *
+dns_get_key(int type, struct message * msg, int *keylen)
{
- struct exchange *exchange = msg->exchange;
- struct rrsetinfo *rr;
- struct dns_rdata_key key_rr;
- char name[MAXHOSTNAMELEN];
- in_addr_t ip4;
- u_int8_t algorithm;
- u_int8_t *id, *umark;
- size_t id_len;
- int ret, i;
-
- switch (type)
- {
- case IKE_AUTH_RSA_SIG:
- algorithm = DNS_KEYALG_RSA;
- break;
-
- case IKE_AUTH_RSA_ENC:
- case IKE_AUTH_RSA_ENC_REV:
- /* XXX Not yet. */
- /* algorithm = DNS_KEYALG_RSA; */
- return 0;
-
- case IKE_AUTH_DSS:
- /* XXX Not yet. */
- /* algorithm = DNS_KEYALG_DSS; */
- return 0;
-
- case IKE_AUTH_PRE_SHARED:
- default:
- return 0;
- }
-
- id = exchange->initiator ? exchange->id_r : exchange->id_i;
- id_len = exchange->initiator ? exchange->id_r_len : exchange->id_i_len;
- memset (name, 0, sizeof name);
-
- if (!id || id_len == 0)
- {
- log_print ("dns_get_key: ID is missing");
- return 0;
- }
-
- /* Exchanges (and SAs) don't carry the ID in ISAKMP form */
- id -= ISAKMP_GEN_SZ;
- id_len += ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF;
-
- switch (GET_ISAKMP_ID_TYPE (id))
- {
- case IPSEC_ID_IPV4_ADDR:
- /* We want to lookup a KEY RR in the reverse zone. */
- if (id_len < sizeof ip4)
- return 0;
- memcpy (&ip4, id + ISAKMP_ID_DATA_OFF, sizeof ip4);
- snprintf (name, sizeof name, "%d.%d.%d.%d.in-addr.arpa.", ip4 >> 24,
- (ip4 >> 16) & 0xFF, (ip4 >> 8) & 0xFF, ip4 & 0xFF);
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- /* XXX Not yet. */
- return 0;
- break;
-
- case IPSEC_ID_FQDN:
- if ((id_len + 1) >= sizeof name)
- return 0;
- /* ID is not NULL-terminated. Add trailing dot and terminate. */
- memcpy (name, id + ISAKMP_ID_DATA_OFF, id_len);
- *(name + id_len) = '.';
- *(name + id_len + 1) = '\0';
- break;
-
- case IPSEC_ID_USER_FQDN:
- /*
- * Some special handling here. We want to convert the ID
- * 'user@host.domain' string into 'user._ipsec.host.domain.'.
- */
- if ((id_len + sizeof (DNS_UFQDN_SEPARATOR)) >= sizeof name)
- return 0;
- /* Look for the '@' separator. */
- for (umark = id + ISAKMP_ID_DATA_OFF; (umark - id) < id_len; umark++)
- if (*umark == '@')
- break;
- if (*umark != '@')
- {
- LOG_DBG ((LOG_MISC, 50, "dns_get_key: bad UFQDN ID"));
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct rrsetinfo *rr;
+ struct dns_rdata_key key_rr;
+ char name[MAXHOSTNAMELEN];
+ in_addr_t ip4;
+ u_int8_t algorithm, *id, *umark;
+ size_t id_len;
+ int ret, i;
+
+ switch (type) {
+ case IKE_AUTH_RSA_SIG:
+ algorithm = DNS_KEYALG_RSA;
+ break;
+
+ case IKE_AUTH_RSA_ENC:
+ case IKE_AUTH_RSA_ENC_REV:
+ /* XXX Not yet. */
+ /* algorithm = DNS_KEYALG_RSA; */
+ return 0;
+
+ case IKE_AUTH_DSS:
+ /* XXX Not yet. */
+ /* algorithm = DNS_KEYALG_DSS; */
+ return 0;
+
+ case IKE_AUTH_PRE_SHARED:
+ default:
+ return 0;
}
- *umark++ = '\0';
- /* id is now terminated. 'umark', however, is not. */
- snprintf (name, sizeof name, "%s%s", id + ISAKMP_ID_DATA_OFF,
- DNS_UFQDN_SEPARATOR);
- memcpy (name + strlen (name), umark, id_len - strlen (id) - 1);
- *(name + id_len + sizeof (DNS_UFQDN_SEPARATOR) - 2) = '.';
- *(name + id_len + sizeof (DNS_UFQDN_SEPARATOR) - 1) = '\0';
- break;
-
- default:
- return 0;
- }
-
- LOG_DBG ((LOG_MISC, 50, "dns_get_key: trying KEY RR for %s", name));
- ret = getrrsetbyname (name, C_IN, T_KEY, 0, &rr);
-
- if (ret)
- {
- LOG_DBG ((LOG_MISC, 30, "dns_get_key: no DNS responses (error %d)",
- ret));
- return 0;
- }
-
- LOG_DBG ((LOG_MISC, 80,
- "dns_get_key: rrset class %d type %d ttl %d nrdatas %d nrsigs %d",
- rr->rri_rdclass, rr->rri_rdtype, rr->rri_ttl, rr->rri_nrdatas,
- rr->rri_nsigs));
- /* We don't accept unvalidated data. */
- if (!(rr->rri_flags & RRSET_VALIDATED))
- {
- LOG_DBG ((LOG_MISC, 10, "dns_get_key: got unvalidated response"));
- freerrset (rr);
- return 0;
- }
-
- /* Sanity. */
- if (rr->rri_nrdatas == 0 || rr->rri_rdtype != T_KEY)
- {
- LOG_DBG ((LOG_MISC, 30, "dns_get_key: no KEY RRs received"));
- freerrset (rr);
- return 0;
- }
-
- memset (&key_rr, 0, sizeof key_rr);
-
- /*
- * Find a key with the wanted algorithm, if any.
- * XXX If there are several keys present, we currently only find the first.
- */
- for (i = 0; i < rr->rri_nrdatas && key_rr.datalen == 0; i++)
- {
- key_rr.flags = ntohs ((u_int16_t) *rr->rri_rdatas[i].rdi_data);
- key_rr.protocol = *(rr->rri_rdatas[i].rdi_data + 2);
- key_rr.algorithm = *(rr->rri_rdatas[i].rdi_data + 3);
-
- if (key_rr.protocol != DNS_KEYPROTO_IPSEC)
- {
- LOG_DBG ((LOG_MISC, 50, "dns_get_key: ignored non-IPsec key"));
- continue;
- }
+ id = exchange->initiator ? exchange->id_r : exchange->id_i;
+ id_len = exchange->initiator ? exchange->id_r_len : exchange->id_i_len;
+ memset(name, 0, sizeof name);
- if (key_rr.algorithm != algorithm)
- {
- LOG_DBG ((LOG_MISC, 50, "dns_get_key: ignored key with other alg"));
- continue;
+ if (!id || id_len == 0) {
+ log_print("dns_get_key: ID is missing");
+ return 0;
+ }
+ /* Exchanges (and SAs) don't carry the ID in ISAKMP form */
+ id -= ISAKMP_GEN_SZ;
+ id_len += ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF;
+
+ switch (GET_ISAKMP_ID_TYPE(id)) {
+ case IPSEC_ID_IPV4_ADDR:
+ /* We want to lookup a KEY RR in the reverse zone. */
+ if (id_len < sizeof ip4)
+ return 0;
+ memcpy(&ip4, id + ISAKMP_ID_DATA_OFF, sizeof ip4);
+ snprintf(name, sizeof name, "%d.%d.%d.%d.in-addr.arpa.", ip4 >> 24,
+ (ip4 >> 16) & 0xFF, (ip4 >> 8) & 0xFF, ip4 & 0xFF);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ /* XXX Not yet. */
+ return 0;
+ break;
+
+ case IPSEC_ID_FQDN:
+ if ((id_len + 1) >= sizeof name)
+ return 0;
+ /* ID is not NULL-terminated. Add trailing dot and terminate. */
+ memcpy(name, id + ISAKMP_ID_DATA_OFF, id_len);
+ *(name + id_len) = '.';
+ *(name + id_len + 1) = '\0';
+ break;
+
+ case IPSEC_ID_USER_FQDN:
+ /*
+ * Some special handling here. We want to convert the ID
+ * 'user@host.domain' string into 'user._ipsec.host.domain.'.
+ */
+ if ((id_len + sizeof(DNS_UFQDN_SEPARATOR)) >= sizeof name)
+ return 0;
+ /* Look for the '@' separator. */
+ for (umark = id + ISAKMP_ID_DATA_OFF; (umark - id) < id_len; umark++)
+ if (*umark == '@')
+ break;
+ if (*umark != '@') {
+ LOG_DBG((LOG_MISC, 50, "dns_get_key: bad UFQDN ID"));
+ return 0;
+ }
+ *umark++ = '\0';
+ /* id is now terminated. 'umark', however, is not. */
+ snprintf(name, sizeof name, "%s%s", id + ISAKMP_ID_DATA_OFF,
+ DNS_UFQDN_SEPARATOR);
+ memcpy(name + strlen(name), umark, id_len - strlen(id) - 1);
+ *(name + id_len + sizeof(DNS_UFQDN_SEPARATOR) - 2) = '.';
+ *(name + id_len + sizeof(DNS_UFQDN_SEPARATOR) - 1) = '\0';
+ break;
+
+ default:
+ return 0;
}
- key_rr.datalen = rr->rri_rdatas[i].rdi_length - 4;
- if (key_rr.datalen <= 0)
- {
- LOG_DBG ((LOG_MISC, 50, "dns_get_key: ignored bad key"));
- key_rr.datalen = 0;
- continue;
+ LOG_DBG((LOG_MISC, 50, "dns_get_key: trying KEY RR for %s", name));
+ ret = getrrsetbyname(name, C_IN, T_KEY, 0, &rr);
+
+ if (ret) {
+ LOG_DBG((LOG_MISC, 30, "dns_get_key: no DNS responses (error %d)",
+ ret));
+ return 0;
}
+ LOG_DBG((LOG_MISC, 80,
+ "dns_get_key: rrset class %d type %d ttl %d nrdatas %d nrsigs %d",
+ rr->rri_rdclass, rr->rri_rdtype, rr->rri_ttl, rr->rri_nrdatas,
+ rr->rri_nsigs));
- /* This key seems to fit our requirements... */
- key_rr.data = (char *)malloc (key_rr.datalen);
- if (!key_rr.data)
- {
- log_error ("dns_get_key: malloc (%d) failed", key_rr.datalen);
- freerrset (rr);
- return 0;
+ /* We don't accept unvalidated data. */
+ if (!(rr->rri_flags & RRSET_VALIDATED)) {
+ LOG_DBG((LOG_MISC, 10, "dns_get_key: got unvalidated response"));
+ freerrset(rr);
+ return 0;
+ }
+ /* Sanity. */
+ if (rr->rri_nrdatas == 0 || rr->rri_rdtype != T_KEY) {
+ LOG_DBG((LOG_MISC, 30, "dns_get_key: no KEY RRs received"));
+ freerrset(rr);
+ return 0;
+ }
+ memset(&key_rr, 0, sizeof key_rr);
+
+ /*
+ * Find a key with the wanted algorithm, if any.
+ * XXX If there are several keys present, we currently only find the first.
+ */
+ for (i = 0; i < rr->rri_nrdatas && key_rr.datalen == 0; i++) {
+ key_rr.flags = ntohs((u_int16_t) * rr->rri_rdatas[i].rdi_data);
+ key_rr.protocol = *(rr->rri_rdatas[i].rdi_data + 2);
+ key_rr.algorithm = *(rr->rri_rdatas[i].rdi_data + 3);
+
+ if (key_rr.protocol != DNS_KEYPROTO_IPSEC) {
+ LOG_DBG((LOG_MISC, 50, "dns_get_key: ignored non-IPsec key"));
+ continue;
+ }
+ if (key_rr.algorithm != algorithm) {
+ LOG_DBG((LOG_MISC, 50, "dns_get_key: ignored "
+ "key with other alg"));
+ continue;
+ }
+ key_rr.datalen = rr->rri_rdatas[i].rdi_length - 4;
+ if (key_rr.datalen <= 0) {
+ LOG_DBG((LOG_MISC, 50, "dns_get_key: ignored bad key"));
+ key_rr.datalen = 0;
+ continue;
+ }
+ /* This key seems to fit our requirements... */
+ key_rr.data = (char *) malloc(key_rr.datalen);
+ if (!key_rr.data) {
+ log_error("dns_get_key: malloc (%d) failed", key_rr.datalen);
+ freerrset(rr);
+ return 0;
+ }
+ memcpy(key_rr.data, rr->rri_rdatas[i].rdi_data + 4, key_rr.datalen);
+ *keylen = key_rr.datalen;
}
- memcpy (key_rr.data, rr->rri_rdatas[i].rdi_data + 4, key_rr.datalen);
- *keylen = key_rr.datalen;
- }
- freerrset (rr);
+ freerrset(rr);
- if (key_rr.datalen)
- return key_rr.data;
- else
- return 0;
+ if (key_rr.datalen)
+ return key_rr.data;
+ return 0;
}
int
-dns_RSA_dns_to_x509 (u_int8_t *key, int keylen, RSA **rsa_key)
+dns_RSA_dns_to_x509(u_int8_t * key, int keylen, RSA ** rsa_key)
{
- RSA *rsa;
- int key_offset;
- u_int8_t e_len;
-
- if (!key || keylen <= 0)
- {
- log_print ("dns_RSA_dns_to_x509: invalid public key");
- return -1;
- }
-
- rsa = RSA_new ();
- if (rsa == NULL)
- {
- log_error ("dns_RSA_dns_to_x509: failed to allocate new RSA struct");
- return -1;
- }
-
- e_len = *key;
- key_offset = 1;
-
- if (e_len == 0)
- {
- if (keylen < 3)
- {
- log_print ("dns_RSA_dns_to_x509: invalid public key");
- RSA_free (rsa);
- return -1;
- }
- e_len = *(key + key_offset++) << 8;
- e_len += *(key + key_offset++);
- }
-
- if (e_len > (keylen - key_offset))
- {
- log_print ("dns_RSA_dns_to_x509: invalid public key");
- RSA_free (rsa);
- return -1;
- }
-
- rsa->e = BN_bin2bn (key + key_offset, e_len, NULL);
- key_offset += e_len;
+ RSA *rsa;
+ int key_offset;
+ u_int8_t e_len;
- /* XXX if (keylen <= key_offset) -> "invalid public key" ? */
+ if (!key || keylen <= 0) {
+ log_print("dns_RSA_dns_to_x509: invalid public key");
+ return -1;
+ }
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ log_error("dns_RSA_dns_to_x509: failed to allocate new RSA struct");
+ return -1;
+ }
+ e_len = *key;
+ key_offset = 1;
+
+ if (e_len == 0) {
+ if (keylen < 3) {
+ log_print("dns_RSA_dns_to_x509: invalid public key");
+ RSA_free(rsa);
+ return -1;
+ }
+ e_len = *(key + key_offset++) << 8;
+ e_len += *(key + key_offset++);
+ }
+ if (e_len > (keylen - key_offset)) {
+ log_print("dns_RSA_dns_to_x509: invalid public key");
+ RSA_free(rsa);
+ return -1;
+ }
+ rsa->e = BN_bin2bn(key + key_offset, e_len, NULL);
+ key_offset += e_len;
- rsa->n = BN_bin2bn (key + key_offset, keylen - key_offset, NULL);
+ /* XXX if (keylen <= key_offset) -> "invalid public key" ? */
- *rsa_key = rsa;
+ rsa->n = BN_bin2bn(key + key_offset, keylen - key_offset, NULL);
- LOG_DBG ((LOG_MISC, 30, "dns_RSA_dns_to_x509: got %d bits RSA key",
- BN_num_bits (rsa->n)));
+ *rsa_key = rsa;
- return 0;
+ LOG_DBG((LOG_MISC, 30, "dns_RSA_dns_to_x509: got %d bits RSA key",
+ BN_num_bits(rsa->n)));
+ return 0;
}
#if notyet
int
-dns_RSA_x509_to_dns (RSA *rsa_key, u_int8_t *key, int *keylen)
+dns_RSA_x509_to_dns(RSA * rsa_key, u_int8_t * key, int *keylen)
{
- return 0;
+ return 0;
}
#endif
diff --git a/sbin/isakmpd/dnssec.h b/sbin/isakmpd/dnssec.h
index 9c579ce0fc2..8eb8d384e86 100644
--- a/sbin/isakmpd/dnssec.h
+++ b/sbin/isakmpd/dnssec.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dnssec.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
+/* $OpenBSD: dnssec.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
/*
* Copyright (c) 2001 Håkan Olsson. All rights reserved.
@@ -27,8 +27,8 @@
#include "libcrypto.h"
#include "message.h"
-void *dns_get_key (int, struct message *, int *);
-int dns_RSA_dns_to_x509 (u_int8_t *, int, RSA **);
+void *dns_get_key(int, struct message *, int *);
+int dns_RSA_dns_to_x509(u_int8_t *, int, RSA **);
#ifndef DNS_KEYALG_RSA
#define DNS_KEYALG_RSA 1
diff --git a/sbin/isakmpd/doi.c b/sbin/isakmpd/doi.c
index d67d493527e..8185d9fada1 100644
--- a/sbin/isakmpd/doi.c
+++ b/sbin/isakmpd/doi.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: doi.c,v 1.6 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: doi.c,v 1.4 1999/04/02 00:57:36 niklas Exp $ */
+/* $OpenBSD: doi.c,v 1.7 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: doi.c,v 1.4 1999/04/02 00:57:36 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -35,28 +35,27 @@
#include "doi.h"
-static LIST_HEAD (doi_list, doi) doi_tab;
+static
+LIST_HEAD(doi_list, doi) doi_tab;
-void
-doi_init ()
+ void
+ doi_init()
{
- LIST_INIT (&doi_tab);
+ LIST_INIT(&doi_tab);
}
-struct doi *
-doi_lookup (u_int8_t doi_id)
+struct doi *
+doi_lookup(u_int8_t doi_id)
{
- struct doi *doi;
+ struct doi *doi;
- for (doi = LIST_FIRST (&doi_tab); doi && doi->id != doi_id;
- doi = LIST_NEXT (doi, link))
- ;
- return doi;
+ for (doi = LIST_FIRST(&doi_tab); doi && doi->id != doi_id;
+ doi = LIST_NEXT(doi, link));
+ return doi;
}
void
-doi_register (struct doi *doi)
+doi_register(struct doi * doi)
{
- LIST_INSERT_HEAD (&doi_tab, doi, link);
+ LIST_INSERT_HEAD(&doi_tab, doi, link);
}
-
diff --git a/sbin/isakmpd/doi.h b/sbin/isakmpd/doi.h
index bf5b4b69b2c..adf7ddeef58 100644
--- a/sbin/isakmpd/doi.h
+++ b/sbin/isakmpd/doi.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: doi.h,v 1.12 2004/03/10 23:08:48 hshoexer Exp $ */
-/* $EOM: doi.h,v 1.29 2000/07/02 18:47:15 provos Exp $ */
+/* $OpenBSD: doi.h,v 1.13 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: doi.h,v 1.29 2000/07/02 18:47:15 provos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -44,54 +44,54 @@ struct sa;
/* XXX This structure needs per-field commenting. */
struct doi {
- LIST_ENTRY (doi) link;
- u_int8_t id;
+ LIST_ENTRY(doi) link;
+ u_int8_t id;
- /* Size of DOI-specific exchange data. */
- size_t exchange_size;
+ /* Size of DOI-specific exchange data. */
+ size_t exchange_size;
- /* Size of DOI-specific security association data. */
- size_t sa_size;
+ /* Size of DOI-specific security association data. */
+ size_t sa_size;
- /* Size of DOI-specific protocol data. */
- size_t proto_size;
+ /* Size of DOI-specific protocol data. */
+ size_t proto_size;
#ifdef USE_DEBUG
- int (*debug_attribute) (u_int16_t, u_int8_t *, u_int16_t, void *);
+ int (*debug_attribute) (u_int16_t, u_int8_t *, u_int16_t, void *);
#endif
- void (*delete_spi) (struct sa *, struct proto *, int);
- int16_t *(*exchange_script) (u_int8_t);
- void (*finalize_exchange) (struct message *);
- void (*free_exchange_data) (void *);
- void (*free_proto_data) (void *);
- void (*free_sa_data) (void *);
- struct keystate *(*get_keystate) (struct message *);
- u_int8_t *(*get_spi) (size_t *, u_int8_t, struct message *);
- int (*handle_leftover_payload) (struct message *, u_int8_t,
- struct payload *);
- int (*informational_post_hook) (struct message *);
- int (*informational_pre_hook) (struct message *);
- int (*is_attribute_incompatible) (u_int16_t, u_int8_t *, u_int16_t, void *);
- void (*proto_init) (struct proto *, char *);
- void (*setup_situation) (u_int8_t *);
- size_t (*situation_size) (void);
- u_int8_t (*spi_size) (u_int8_t);
- int (*validate_attribute) (u_int16_t, u_int8_t *, u_int16_t, void *);
- int (*validate_exchange) (u_int8_t);
- int (*validate_id_information) (u_int8_t, u_int8_t *, u_int8_t *, size_t,
- struct exchange *);
- int (*validate_key_information) (u_int8_t *, size_t);
- int (*validate_notification) (u_int16_t);
- int (*validate_proto) (u_int8_t);
- int (*validate_situation) (u_int8_t *, size_t *, size_t);
- int (*validate_transform_id) (u_int8_t, u_int8_t);
- int (*initiator) (struct message *msg);
- int (*responder) (struct message *msg);
- char *(*decode_ids) (char *, u_int8_t *, size_t, u_int8_t *, size_t, int);
+ void (*delete_spi) (struct sa *, struct proto *, int);
+ int16_t *(*exchange_script) (u_int8_t);
+ void (*finalize_exchange) (struct message *);
+ void (*free_exchange_data) (void *);
+ void (*free_proto_data) (void *);
+ void (*free_sa_data) (void *);
+ struct keystate *(*get_keystate) (struct message *);
+ u_int8_t *(*get_spi) (size_t *, u_int8_t, struct message *);
+ int (*handle_leftover_payload) (struct message *, u_int8_t,
+ struct payload *);
+ int (*informational_post_hook) (struct message *);
+ int (*informational_pre_hook) (struct message *);
+ int (*is_attribute_incompatible) (u_int16_t, u_int8_t *, u_int16_t, void *);
+ void (*proto_init) (struct proto *, char *);
+ void (*setup_situation) (u_int8_t *);
+ size_t(*situation_size) (void);
+ u_int8_t(*spi_size) (u_int8_t);
+ int (*validate_attribute) (u_int16_t, u_int8_t *, u_int16_t, void *);
+ int (*validate_exchange) (u_int8_t);
+ int (*validate_id_information) (u_int8_t, u_int8_t *, u_int8_t *, size_t,
+ struct exchange *);
+ int (*validate_key_information) (u_int8_t *, size_t);
+ int (*validate_notification) (u_int16_t);
+ int (*validate_proto) (u_int8_t);
+ int (*validate_situation) (u_int8_t *, size_t *, size_t);
+ int (*validate_transform_id) (u_int8_t, u_int8_t);
+ int (*initiator) (struct message * msg);
+ int (*responder) (struct message * msg);
+ char *(*decode_ids) (char *, u_int8_t *, size_t, u_int8_t *, size_t, int);
};
-extern void doi_init (void);
-extern struct doi *doi_lookup (u_int8_t);
-extern void doi_register (struct doi *);
+extern void doi_init(void);
+extern struct doi *doi_lookup(u_int8_t);
+extern void doi_register(struct doi *);
-#endif /* _DOI_H_ */
+#endif /* _DOI_H_ */
diff --git a/sbin/isakmpd/exchange.h b/sbin/isakmpd/exchange.h
index 333eb864482..d4cd76dd9c6 100644
--- a/sbin/isakmpd/exchange.h
+++ b/sbin/isakmpd/exchange.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: exchange.h,v 1.24 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: exchange.h,v 1.28 2000/09/28 12:54:28 niklas Exp $ */
+/* $OpenBSD: exchange.h,v 1.25 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: exchange.h,v 1.28 2000/09/28 12:54:28 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -53,149 +53,162 @@ struct transport;
struct sa;
struct exchange {
- /* Link to exchanges with the same hash value. */
- LIST_ENTRY (exchange) link;
-
- /* A name of the SAs this exchange will result in. XXX non unique? */
- char *name;
-
- /* A name of the major policy deciding offers and acceptable proposals. */
- char *policy;
-
- /*
- * A function with a polymorphic argument called after the exchange
- * has been run to its end, successfully. The 2nd argument is true
- * if the finalization hook is called due to the exchange not running
- * to its end normally.
- */
- void (*finalize) (struct exchange *, void *, int);
- void *finalize_arg;
-
- /* When several SA's are being negotiated we keep them here. */
- TAILQ_HEAD (sa_head, sa) sa_list;
-
- /*
- * The event that will occur when it has taken too long time to try to
- * run the exchange and which will trigger auto-destruction.
- */
- struct event *death;
-
- /*
- * Both initiator and responder cookies.
- * XXX For code clarity we might split this into two fields.
- */
- u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
-
- /* The message ID signifying phase 2 exchanges. */
- u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
-
- /* The exchange type we are using. */
- u_int8_t type;
-
- /* Phase is 1 for ISAKMP SA exchanges, and 2 for application ones. */
- u_int8_t phase;
-
- /* The "step counter" of the exchange, starting from zero. */
- u_int8_t step;
-
- /* 1 if we are the initiator, 0 if we are the responder. */
- u_int8_t initiator;
-
- /* Various flags, look below for descriptions. */
- u_int32_t flags;
-
- /* The DOI that is to handle DOI-specific issues for this exchange. */
- struct doi *doi;
-
- /*
- * A "program counter" into the script that validate message contents for
- * this exchange.
- */
- int16_t *exch_pc;
-
- /* The last message received, used for checking for duplicates. */
- struct message *last_received;
-
- /* The last message sent, to be acked when something new is received. */
- struct message *last_sent;
-
- /*
- * If some message is queued up for sending, we want to be able to remove
- * it from the queue, when the exchange is deleted.
- */
- struct message *in_transit;
-
- /*
- * Initiator's & responder's nonces respectively, with lengths.
- * XXX Should this be in the DOI-specific parts instead?
- */
- u_int8_t *nonce_i;
- size_t nonce_i_len;
- u_int8_t *nonce_r;
- size_t nonce_r_len;
-
- /* The ID payload contents for the initiator & responder, respectively. */
- u_int8_t *id_i;
- size_t id_i_len;
- u_int8_t *id_r;
- size_t id_r_len;
-
- /* Policy session identifier, where applicable. */
- int policy_id;
-
- /* Crypto info needed to encrypt/decrypt packets in this exchange. */
- struct crypto_xf *crypto;
- size_t key_length;
- struct keystate *keystate;
-
- /* Used only by KeyNote, to cache the key used to authenticate Phase 1 */
- char *keynote_key; /* printable format */
-
- /*
- * Received certificate - used to verify signatures on packet,
- * stored here for later policy processing.
- *
- * The rules for the recv_* and sent_* fields are:
- * - recv_cert stores the credential (if any) received from the peer;
- * the kernel may pass us one, but we ignore it. We pass it to the
- * kernel so processes can peek at it. When doing passphrase
- * authentication in Phase 1, this is empty.
- * - recv_key stores the key (public or private) used by the peer
- * to authenticate. Otherwise, same properties as recv_cert except
- * that we don't tell the kernel about passphrases (so we don't
- * reveal system-wide passphrases). Processes that used passphrase
- * authentication already know the passphrase! We ignore it if/when
- * received from the kernel (meaningless).
- * - sent_cert stores the credential, if any, we used to authenticate
- * with the peer. It may be passed to us by the kernel, or we may
- * have found it in our certificate storage. In either case, there's
- * no point passing it to the kernel, so we don't.
- * - sent key stores the private key we used for authentication with
- * the peer (private key or passphrase). This may have been received
- * from the kernel, or may be a system-wide setting. In either case,
- * we don't pass it to the kernel, to avoid revealing such information
- * to processes (processes either already know it, or have no business
- * knowing it).
- */
- int recv_certtype, recv_keytype;
- void *recv_cert; /* Certificate received from peer, native format */
- void *recv_key; /* Key peer used to authenticate, native format */
-
- /* Likewise, for certificates/keys we use. */
- int sent_certtype, sent_keytype;
- void *sent_cert; /* Certificate (to be) sent to peer, native format */
- void *sent_key; /* Key we'll use to authenticate to peer, native format */
-
- /* ACQUIRE sequence number. */
- u_int32_t seq;
-
- /* XXX This is no longer necessary, it is covered by policy. */
-
- /* Acceptable authorities for cert requests. */
- TAILQ_HEAD (aca_head, certreq_aca) aca_list;
-
- /* DOI-specific opaque data. */
- void *data;
+ /* Link to exchanges with the same hash value. */
+ LIST_ENTRY(exchange) link;
+
+ /* A name of the SAs this exchange will result in. XXX non unique? */
+ char *name;
+
+ /*
+ * A name of the major policy deciding offers and acceptable
+ * proposals.
+ */
+ char *policy;
+
+ /*
+ * A function with a polymorphic argument called after the exchange
+ * has been run to its end, successfully. The 2nd argument is true
+ * if the finalization hook is called due to the exchange not running
+ * to its end normally.
+ */
+ void (*finalize) (struct exchange *, void *, int);
+ void *finalize_arg;
+
+ /* When several SA's are being negotiated we keep them here. */
+ TAILQ_HEAD(sa_head, sa) sa_list;
+
+ /*
+ * The event that will occur when it has taken too long time to try to
+ * run the exchange and which will trigger auto-destruction.
+ */
+ struct event *death;
+
+ /*
+ * Both initiator and responder cookies.
+ * XXX For code clarity we might split this into two fields.
+ */
+ u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
+
+ /* The message ID signifying phase 2 exchanges. */
+ u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
+
+ /* The exchange type we are using. */
+ u_int8_t type;
+
+ /* Phase is 1 for ISAKMP SA exchanges, and 2 for application ones. */
+ u_int8_t phase;
+
+ /* The "step counter" of the exchange, starting from zero. */
+ u_int8_t step;
+
+ /* 1 if we are the initiator, 0 if we are the responder. */
+ u_int8_t initiator;
+
+ /* Various flags, look below for descriptions. */
+ u_int32_t flags;
+
+ /* The DOI that is to handle DOI-specific issues for this exchange. */
+ struct doi *doi;
+
+ /*
+ * A "program counter" into the script that validate message contents for
+ * this exchange.
+ */
+ int16_t *exch_pc;
+
+ /* The last message received, used for checking for duplicates. */
+ struct message *last_received;
+
+ /* The last message sent, to be acked when something new is received. */
+ struct message *last_sent;
+
+ /*
+ * If some message is queued up for sending, we want to be able to remove
+ * it from the queue, when the exchange is deleted.
+ */
+ struct message *in_transit;
+
+ /*
+ * Initiator's & responder's nonces respectively, with lengths.
+ * XXX Should this be in the DOI-specific parts instead?
+ */
+ u_int8_t *nonce_i;
+ size_t nonce_i_len;
+ u_int8_t *nonce_r;
+ size_t nonce_r_len;
+
+ /*
+ * The ID payload contents for the initiator & responder,
+ * respectively.
+ */
+ u_int8_t *id_i;
+ size_t id_i_len;
+ u_int8_t *id_r;
+ size_t id_r_len;
+
+ /* Policy session identifier, where applicable. */
+ int policy_id;
+
+ /* Crypto info needed to encrypt/decrypt packets in this exchange. */
+ struct crypto_xf *crypto;
+ size_t key_length;
+ struct keystate *keystate;
+
+ /*
+ * Used only by KeyNote, to cache the key used to authenticate Phase
+ * 1
+ */
+ char *keynote_key; /* printable format */
+
+ /*
+ * Received certificate - used to verify signatures on packet,
+ * stored here for later policy processing.
+ *
+ * The rules for the recv_* and sent_* fields are:
+ * - recv_cert stores the credential (if any) received from the peer;
+ * the kernel may pass us one, but we ignore it. We pass it to the
+ * kernel so processes can peek at it. When doing passphrase
+ * authentication in Phase 1, this is empty.
+ * - recv_key stores the key (public or private) used by the peer
+ * to authenticate. Otherwise, same properties as recv_cert except
+ * that we don't tell the kernel about passphrases (so we don't
+ * reveal system-wide passphrases). Processes that used passphrase
+ * authentication already know the passphrase! We ignore it if/when
+ * received from the kernel (meaningless).
+ * - sent_cert stores the credential, if any, we used to authenticate
+ * with the peer. It may be passed to us by the kernel, or we may
+ * have found it in our certificate storage. In either case, there's
+ * no point passing it to the kernel, so we don't.
+ * - sent key stores the private key we used for authentication with
+ * the peer (private key or passphrase). This may have been received
+ * from the kernel, or may be a system-wide setting. In either case,
+ * we don't pass it to the kernel, to avoid revealing such information
+ * to processes (processes either already know it, or have no business
+ * knowing it).
+ */
+ int recv_certtype, recv_keytype;
+ void *recv_cert; /* Certificate received from peer,
+ * native format */
+ void *recv_key; /* Key peer used to authenticate,
+ * native format */
+
+ /* Likewise, for certificates/keys we use. */
+ int sent_certtype, sent_keytype;
+ void *sent_cert; /* Certificate (to be) sent to peer,
+ * native format */
+ void *sent_key; /* Key we'll use to authenticate to
+ * peer, native format */
+
+ /* ACQUIRE sequence number. */
+ u_int32_t seq;
+
+ /* XXX This is no longer necessary, it is covered by policy. */
+
+ /* Acceptable authorities for cert requests. */
+ TAILQ_HEAD(aca_head, certreq_aca) aca_list;
+
+ /* DOI-specific opaque data. */
+ void *data;
};
/* The flag bits. */
@@ -205,32 +218,33 @@ struct exchange {
| EXCHANGE_FLAG_HE_COMMITTED)
#define EXCHANGE_FLAG_ENCRYPT 4
-extern int exchange_add_certs (struct message *);
-extern void exchange_finalize (struct message *);
-extern void exchange_free (struct exchange *);
-extern void exchange_free_aca_list (struct exchange *);
-extern void exchange_establish (char *name,
- void (*) (struct exchange *, void *, int),
- void *);
-extern void exchange_establish_p1 (struct transport *, u_int8_t, u_int32_t,
- char *, void *,
- void (*) (struct exchange *, void *, int),
- void *);
-extern void exchange_establish_p2 (struct sa *, u_int8_t, char *, void *,
- void (*) (struct exchange *, void *, int),
- void *);
-extern int exchange_gen_nonce (struct message *, size_t);
-extern void exchange_init (void);
-extern struct exchange *exchange_lookup (u_int8_t *, int);
-extern struct exchange *exchange_lookup_by_name (char *, int);
-extern struct exchange *exchange_lookup_from_icookie (u_int8_t *);
-extern void exchange_report (void);
-extern void exchange_run (struct message *);
-extern int exchange_save_nonce (struct message *);
-extern int exchange_save_certreq (struct message *);
-extern int16_t *exchange_script (struct exchange *);
-extern struct exchange *exchange_setup_p1 (struct message *, u_int32_t);
-extern struct exchange *exchange_setup_p2 (struct message *, u_int8_t);
-extern void exchange_upgrade_p1 (struct message *);
-
-#endif /* _EXCHANGE_H_ */
+extern int exchange_add_certs(struct message *);
+extern void exchange_finalize(struct message *);
+extern void exchange_free(struct exchange *);
+extern void exchange_free_aca_list(struct exchange *);
+extern void
+exchange_establish(char *name,
+ void (*) (struct exchange *, void *, int),
+ void *);
+ extern void exchange_establish_p1(struct transport *, u_int8_t, u_int32_t,
+ char *, void *,
+ void (*) (struct exchange *, void *, int),
+ void *);
+ extern void exchange_establish_p2(struct sa *, u_int8_t, char *, void *,
+ void (*) (struct exchange *, void *, int),
+ void *);
+ extern int exchange_gen_nonce(struct message *, size_t);
+ extern void exchange_init(void);
+ extern struct exchange *exchange_lookup(u_int8_t *, int);
+ extern struct exchange *exchange_lookup_by_name(char *, int);
+ extern struct exchange *exchange_lookup_from_icookie(u_int8_t *);
+ extern void exchange_report(void);
+ extern void exchange_run(struct message *);
+ extern int exchange_save_nonce(struct message *);
+ extern int exchange_save_certreq(struct message *);
+ extern int16_t *exchange_script(struct exchange *);
+ extern struct exchange *exchange_setup_p1(struct message *, u_int32_t);
+ extern struct exchange *exchange_setup_p2(struct message *, u_int8_t);
+ extern void exchange_upgrade_p1(struct message *);
+
+#endif /* _EXCHANGE_H_ */
diff --git a/sbin/isakmpd/field.c b/sbin/isakmpd/field.c
index 9217487f4ab..2f54a1db74d 100644
--- a/sbin/isakmpd/field.c
+++ b/sbin/isakmpd/field.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: field.c,v 1.13 2003/11/06 16:12:07 ho Exp $ */
-/* $EOM: field.c,v 1.11 2000/02/20 19:58:37 niklas Exp $ */
+/* $OpenBSD: field.c,v 1.14 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: field.c,v 1.11 2000/02/20 19:58:37 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -40,19 +40,19 @@
#include "log.h"
#include "util.h"
-static char *field_debug_raw (u_int8_t *, size_t, struct constant_map **);
-static char *field_debug_num (u_int8_t *, size_t, struct constant_map **);
-static char *field_debug_mask (u_int8_t *, size_t, struct constant_map **);
-static char *field_debug_ign (u_int8_t *, size_t, struct constant_map **);
-static char *field_debug_cst (u_int8_t *, size_t, struct constant_map **);
+static char *field_debug_raw(u_int8_t *, size_t, struct constant_map **);
+static char *field_debug_num(u_int8_t *, size_t, struct constant_map **);
+static char *field_debug_mask(u_int8_t *, size_t, struct constant_map **);
+static char *field_debug_ign(u_int8_t *, size_t, struct constant_map **);
+static char *field_debug_cst(u_int8_t *, size_t, struct constant_map **);
/* Contents must match the enum in struct field. */
-static char *(*decode_field[]) (u_int8_t *, size_t, struct constant_map **) = {
- field_debug_raw,
- field_debug_num,
- field_debug_mask,
- field_debug_ign,
- field_debug_cst
+static char *(*decode_field[]) (u_int8_t *, size_t, struct constant_map **) = {
+ field_debug_raw,
+ field_debug_num,
+ field_debug_mask,
+ field_debug_ign,
+ field_debug_cst
};
/*
@@ -60,23 +60,22 @@ static char *(*decode_field[]) (u_int8_t *, size_t, struct constant_map **) = {
* BUF. MAPS should be zero and is only here because the API requires it.
*/
static char *
-field_debug_raw (u_int8_t *buf, size_t len, struct constant_map **maps)
+field_debug_raw(u_int8_t *buf, size_t len, struct constant_map **maps)
{
- char *retval, *p;
-
- if (len == 0)
- return 0;
- retval = malloc (3 + len * 2);
- if (!retval)
- return 0;
- strlcpy (retval, "0x", 3 + len * 2);
- p = retval + 2;
- for (; len > 0; len--)
- {
- snprintf (p, 1 + len * 2, "%02x", *buf++);
- p += 2;
- }
- return retval;
+ char *retval, *p;
+
+ if (len == 0)
+ return 0;
+ retval = malloc(3 + len * 2);
+ if (!retval)
+ return 0;
+ strlcpy(retval, "0x", 3 + len * 2);
+ p = retval + 2;
+ for (; len > 0; len--) {
+ snprintf(p, 1 + len * 2, "%02x", *buf++);
+ p += 2;
+ }
+ return retval;
}
/*
@@ -84,23 +83,22 @@ field_debug_raw (u_int8_t *buf, size_t len, struct constant_map **maps)
* 32-bit unsigned integer of host byteorder pointed to by VAL.
*/
static int
-extract_val (u_int8_t *buf, size_t len, u_int32_t *val)
+extract_val(u_int8_t *buf, size_t len, u_int32_t *val)
{
- switch (len)
- {
- case 1:
- *val = *buf;
- break;
- case 2:
- *val = decode_16 (buf);
- break;
- case 4:
- *val = decode_32 (buf);
- break;
- default:
- return -1;
- }
- return 0;
+ switch (len) {
+ case 1:
+ *val = *buf;
+ break;
+ case 2:
+ *val = decode_16(buf);
+ break;
+ case 4:
+ *val = decode_32(buf);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
}
/*
@@ -109,17 +107,17 @@ extract_val (u_int8_t *buf, size_t len, u_int32_t *val)
* the API requires it.
*/
static char *
-field_debug_num (u_int8_t *buf, size_t len, struct constant_map **maps)
+field_debug_num(u_int8_t *buf, size_t len, struct constant_map **maps)
{
- char *retval;
- u_int32_t val;
-
- if (extract_val (buf, len, &val))
- return 0;
- /* 3 decimal digits are enough to represent each byte. */
- retval = malloc (3 * len);
- snprintf (retval, 3 * len, "%u", val);
- return retval;
+ char *retval;
+ u_int32_t val;
+
+ if (extract_val(buf, len, &val))
+ return 0;
+ /* 3 decimal digits are enough to represent each byte. */
+ retval = malloc(3 * len);
+ snprintf(retval, 3 * len, "%u", val);
+ return retval;
}
/*
@@ -127,42 +125,39 @@ field_debug_num (u_int8_t *buf, size_t len, struct constant_map **maps)
* octets long, using the constant maps MAPS.
*/
static char *
-field_debug_mask (u_int8_t *buf, size_t len, struct constant_map **maps)
+field_debug_mask(u_int8_t *buf, size_t len, struct constant_map **maps)
{
- u_int32_t val;
- u_int32_t bit;
- char *retval, *new_buf, *name;
- size_t buf_sz;
-
- if (extract_val (buf, len, &val))
- return 0;
-
- /* Size for brackets, two spaces and a NUL terminator. */
- buf_sz = 4;
- retval = malloc (buf_sz);
- if (!retval)
- return 0;
-
- strlcpy (retval, "[ ", buf_sz);
- for (bit = 1; bit; bit <<= 1)
- {
- if (val & bit)
- {
- name = constant_name_maps (maps, bit);
- buf_sz += strlen (name) + 1;
- new_buf = realloc (retval, buf_sz);
- if (!new_buf)
- {
- free (retval);
- return 0;
- }
- retval = new_buf;
- strlcat (retval, name, buf_sz);
- strlcat (retval, " ", buf_sz);
+ u_int32_t val;
+ u_int32_t bit;
+ char *retval, *new_buf, *name;
+ size_t buf_sz;
+
+ if (extract_val(buf, len, &val))
+ return 0;
+
+ /* Size for brackets, two spaces and a NUL terminator. */
+ buf_sz = 4;
+ retval = malloc(buf_sz);
+ if (!retval)
+ return 0;
+
+ strlcpy(retval, "[ ", buf_sz);
+ for (bit = 1; bit; bit <<= 1) {
+ if (val & bit) {
+ name = constant_name_maps(maps, bit);
+ buf_sz += strlen(name) + 1;
+ new_buf = realloc(retval, buf_sz);
+ if (!new_buf) {
+ free(retval);
+ return 0;
+ }
+ retval = new_buf;
+ strlcat(retval, name, buf_sz);
+ strlcat(retval, " ", buf_sz);
+ }
}
- }
- strlcat (retval, "]", buf_sz);
- return retval;
+ strlcat(retval, "]", buf_sz);
+ return retval;
}
/*
@@ -170,9 +165,9 @@ field_debug_mask (u_int8_t *buf, size_t len, struct constant_map **maps)
* should be zero and is only here because the API requires it.
*/
static char *
-field_debug_ign (u_int8_t *buf, size_t len, struct constant_map **maps)
+field_debug_ign(u_int8_t *buf, size_t len, struct constant_map **maps)
{
- return 0;
+ return 0;
}
/*
@@ -180,79 +175,77 @@ field_debug_ign (u_int8_t *buf, size_t len, struct constant_map **maps)
* octets long, using the constant maps MAPS.
*/
static char *
-field_debug_cst (u_int8_t *buf, size_t len, struct constant_map **maps)
+field_debug_cst(u_int8_t *buf, size_t len, struct constant_map **maps)
{
- u_int32_t val;
+ u_int32_t val;
- if (extract_val (buf, len, &val))
- return 0;
+ if (extract_val(buf, len, &val))
+ return 0;
- return strdup (constant_name_maps (maps, val));
+ return strdup(constant_name_maps(maps, val));
}
/* Pretty-print a field from BUF as described by F. */
void
-field_dump_field (struct field *f, u_int8_t *buf)
+field_dump_field(struct field *f, u_int8_t *buf)
{
- char *value;
+ char *value;
- value = decode_field[(int)f->type] (buf + f->offset, f->len, f->maps);
- if (value)
- {
- LOG_DBG ((LOG_MESSAGE, 70, "%s: %s", f->name, value));
- free (value);
- }
+ value = decode_field[(int) f->type] (buf + f->offset, f->len, f->maps);
+ if (value) {
+ LOG_DBG((LOG_MESSAGE, 70, "%s: %s", f->name, value));
+ free(value);
+ }
}
/* Pretty-print all the fields of BUF as described in FIELDS. */
void
-field_dump_payload (struct field *fields, u_int8_t *buf)
+field_dump_payload(struct field *fields, u_int8_t *buf)
{
- struct field *field;
+ struct field *field;
- for (field = fields; field->name; field++)
- field_dump_field (field, buf);
+ for (field = fields; field->name; field++)
+ field_dump_field(field, buf);
}
/* Return the numeric value of the field F of BUF. */
u_int32_t
-field_get_num (struct field *f, u_int8_t *buf)
+field_get_num(struct field *f, u_int8_t *buf)
{
- u_int32_t val;
+ u_int32_t val;
- if (extract_val (buf + f->offset, f->len, &val))
- return 0;
- return val;
+ if (extract_val(buf + f->offset, f->len, &val))
+ return 0;
+ return val;
}
/* Stash the number VAL into BUF's field F. */
void
-field_set_num (struct field *f, u_int8_t *buf, u_int32_t val)
+field_set_num(struct field *f, u_int8_t *buf, u_int32_t val)
{
- switch (f->len)
- {
- case 1:
- buf[f->offset] = val;
- break;
- case 2:
- encode_16 (buf + f->offset, val);
- break;
- case 4:
- encode_32 (buf + f->offset, val);
- break;
- }
+ switch (f->len) {
+ case 1:
+ buf[f->offset] = val;
+ break;
+ case 2:
+ encode_16(buf + f->offset, val);
+ break;
+ case 4:
+ encode_32(buf + f->offset, val);
+ break;
+ }
}
/* Stash BUF's raw field F into VAL. */
void
-field_get_raw (struct field *f, u_int8_t *buf, u_int8_t *val)
+field_get_raw(struct field * f, u_int8_t * buf, u_int8_t * val)
{
- memcpy (val, buf + f->offset, f->len);
+ memcpy(val, buf + f->offset, f->len);
}
/* Stash the buffer VAL into BUF's field F. */
void
-field_set_raw (struct field *f, u_int8_t *buf, u_int8_t *val)
+field_set_raw(struct field * f, u_int8_t * buf, u_int8_t * val)
{
- memcpy (buf + f->offset, val, f->len);
+ memcpy(buf + f->offset, val, f->len);
}
diff --git a/sbin/isakmpd/field.h b/sbin/isakmpd/field.h
index cd8933bd2c6..9021ba3693c 100644
--- a/sbin/isakmpd/field.h
+++ b/sbin/isakmpd/field.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: field.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: field.h,v 1.3 1998/08/02 20:25:01 niklas Exp $ */
+/* $OpenBSD: field.h,v 1.5 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: field.h,v 1.3 1998/08/02 20:25:01 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -35,18 +35,20 @@
#include <sys/types.h>
struct field {
- char *name;
- int offset;
- size_t len;
- enum { raw, num, mask, ign, cst } type;
- struct constant_map **maps;
+ char *name;
+ int offset;
+ size_t len;
+ enum {
+ raw, num, mask, ign, cst
+ } type;
+ struct constant_map **maps;
};
-extern void field_dump_field (struct field *, u_int8_t *);
-extern void field_dump_payload (struct field *, u_int8_t *);
-extern u_int32_t field_get_num (struct field *, u_int8_t *);
-extern void field_get_raw (struct field *, u_int8_t *, u_int8_t *);
-extern void field_set_num (struct field *, u_int8_t *, u_int32_t);
-extern void field_set_raw (struct field *, u_int8_t *, u_int8_t *);
+extern void field_dump_field(struct field *, u_int8_t *);
+extern void field_dump_payload(struct field *, u_int8_t *);
+extern u_int32_t field_get_num(struct field *, u_int8_t *);
+extern void field_get_raw(struct field *, u_int8_t *, u_int8_t *);
+extern void field_set_num(struct field *, u_int8_t *, u_int32_t);
+extern void field_set_raw(struct field *, u_int8_t *, u_int8_t *);
-#endif /* _FIELD_H_ */
+#endif /* _FIELD_H_ */
diff --git a/sbin/isakmpd/genconstants.sh b/sbin/isakmpd/genconstants.sh
index 10217f25210..8332209f3a4 100644
--- a/sbin/isakmpd/genconstants.sh
+++ b/sbin/isakmpd/genconstants.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: genconstants.sh,v 1.11 2003/06/03 14:28:16 ho Exp $
+# $OpenBSD: genconstants.sh,v 1.12 2004/04/15 18:39:25 deraadt Exp $
# $EOM: genconstants.sh,v 1.6 1999/04/02 01:15:53 niklas Exp $
#
@@ -92,7 +92,7 @@ BEGIN {
}
/^\./ {
- print " { 0, 0 }\n};\n"
+ print " { 0, 0 }\n};\n"
next
}
@@ -103,7 +103,7 @@ BEGIN {
}
/^[ ]/ && $1 {
- printf (" { %s_%s, \"%s\", %s }, \n", prefix, $1, $1,
+ printf (" { %s_%s, \"%s\", %s },\n", prefix, $1, $1,
($3 && substr($3,1,1) != "#") ? $3 : 0)
next
}
diff --git a/sbin/isakmpd/genfields.sh b/sbin/isakmpd/genfields.sh
index e2d79942624..74909e1f14b 100644
--- a/sbin/isakmpd/genfields.sh
+++ b/sbin/isakmpd/genfields.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: genfields.sh,v 1.8 2003/06/03 14:28:16 ho Exp $
+# $OpenBSD: genfields.sh,v 1.9 2004/04/15 18:39:25 deraadt Exp $
# $EOM: genfields.sh,v 1.5 1999/04/02 01:15:55 niklas Exp $
#
@@ -138,13 +138,13 @@ BEGIN {
}
/^\./ {
- print " { 0, 0, 0, 0, 0 }\n};\n"
+ print " { 0, 0, 0, 0, 0 }\n};\n"
size[prefix] = off
for (map in maps)
{
- printf ("struct constant_map *%s_%s_maps[] = { ", locase(prefix),
+ printf ("struct constant_map *%s_%s_maps[] = {\n", locase(prefix),
locase(map))
- printf ("%s,0 };\n", maps[map])
+ printf (" %s, 0\n};\n", maps[map])
}
next
}
@@ -174,7 +174,7 @@ BEGIN {
{
maps_name = "0"
}
- printf (" { \"%s\", %d, %d, %s, %s }, \n", $1, off, $3, $2, maps_name)
+ printf (" { \"%s\", %d, %d, %s, %s },\n", $1, off, $3, $2, maps_name)
off += $3
next
}
diff --git a/sbin/isakmpd/gmp_util.c b/sbin/isakmpd/gmp_util.c
index f8a759affe4..2a338d266df 100644
--- a/sbin/isakmpd/gmp_util.c
+++ b/sbin/isakmpd/gmp_util.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: gmp_util.c,v 1.10 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: gmp_util.c,v 1.7 2000/09/18 00:01:47 ho Exp $ */
+/* $OpenBSD: gmp_util.c,v 1.11 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: gmp_util.c,v 1.7 2000/09/18 00:01:47 ho Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -41,67 +41,65 @@
/* Various utility functions for gmp, used in more than one module */
u_int32_t
-mpz_sizeinoctets (math_mp_t a)
+mpz_sizeinoctets(math_mp_t a)
{
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- return (7 + mpz_sizeinbase (a, 2)) >> 3;
+ return (7 + mpz_sizeinbase(a, 2)) >> 3;
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- return BN_num_bytes (a);
+ return BN_num_bytes(a);
#endif
}
void
-mpz_getraw (u_int8_t *raw, math_mp_t v, u_int32_t len)
+mpz_getraw(u_int8_t *raw, math_mp_t v, u_int32_t len)
{
- math_mp_t a;
+ math_mp_t a;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- math_mp_t tmp;
+ math_mp_t tmp;
- /* XXX mpz_get_str (raw, BASE, v); ? */
- mpz_init_set (a, v);
- mpz_init (tmp);
+ /* XXX mpz_get_str (raw, BASE, v); ? */
+ mpz_init_set(a, v);
+ mpz_init(tmp);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- /* XXX bn2bin? */
- a = BN_dup (v);
+ /* XXX bn2bin? */
+ a = BN_dup(v);
#endif
- while (len-- > 0)
+ while (len-- > 0)
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- raw[len] = mpz_fdiv_qr_ui (a, tmp, a, 256);
+ raw[len] = mpz_fdiv_qr_ui(a, tmp, a, 256);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- raw[len] = BN_div_word (a, 256);
+ raw[len] = BN_div_word(a, 256);
#endif
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_clear (a);
- mpz_clear (tmp);
+ mpz_clear(a);
+ mpz_clear(tmp);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_clear_free (a);
+ BN_clear_free(a);
#endif
}
void
-mpz_setraw (math_mp_t d, u_int8_t *s, u_int32_t l)
+mpz_setraw(math_mp_t d, u_int8_t *s, u_int32_t l)
{
- u_int32_t i;
+ u_int32_t i;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- /* XXX mpz_set_str (d, s, 0); */
- mpz_set_si (d, 0);
+ /* XXX mpz_set_str (d, s, 0); */
+ mpz_set_si(d, 0);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- /* XXX bin2bn? */
- BN_set_word (d, 0);
+ /* XXX bin2bn? */
+ BN_set_word(d, 0);
#endif
- for (i = 0; i < l; i++)
- {
+ for (i = 0; i < l; i++) {
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_mul_ui (d, d, 256);
- mpz_add_ui (d, d, s[i]);
+ mpz_mul_ui(d, d, 256);
+ mpz_add_ui(d, d, s[i]);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_mul_word (d, 256);
- BN_add_word (d, s[i]);
+ BN_mul_word(d, 256);
+ BN_add_word(d, s[i]);
#endif
- }
+ }
}
-
diff --git a/sbin/isakmpd/gmp_util.h b/sbin/isakmpd/gmp_util.h
index 44a4e00ad76..826c6cab354 100644
--- a/sbin/isakmpd/gmp_util.h
+++ b/sbin/isakmpd/gmp_util.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: gmp_util.h,v 1.7 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: gmp_util.h,v 1.4 2000/05/08 13:42:11 ho Exp $ */
+/* $OpenBSD: gmp_util.h,v 1.8 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: gmp_util.h,v 1.4 2000/05/08 13:42:11 ho Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -35,8 +35,8 @@
#include "math_mp.h"
-u_int32_t mpz_sizeinoctets (math_mp_t);
-void mpz_getraw (u_int8_t *, math_mp_t, u_int32_t);
-void mpz_setraw (math_mp_t, u_int8_t *, u_int32_t);
+u_int32_t mpz_sizeinoctets(math_mp_t);
+void mpz_getraw(u_int8_t *, math_mp_t, u_int32_t);
+void mpz_setraw(math_mp_t, u_int8_t *, u_int32_t);
-#endif /* _GMP_UTIL_H_ */
+#endif /* _GMP_UTIL_H_ */
diff --git a/sbin/isakmpd/hash.c b/sbin/isakmpd/hash.c
index 978857eaba9..bf77af07836 100644
--- a/sbin/isakmpd/hash.c
+++ b/sbin/isakmpd/hash.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: hash.c,v 1.14 2004/03/31 10:54:46 ho Exp $ */
-/* $EOM: hash.c,v 1.10 1999/04/17 23:20:34 niklas Exp $ */
+/* $OpenBSD: hash.c,v 1.15 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: hash.c,v 1.10 1999/04/17 23:20:34 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -38,20 +38,20 @@
#else
#include <md5.h>
#include <sha1.h>
-#endif /* __APPLE__ */
+#endif /* __APPLE__ */
#include "sysdep.h"
#include "hash.h"
#include "log.h"
-void hmac_init (struct hash *, unsigned char *, unsigned int);
-void hmac_final (unsigned char *, struct hash *);
+void hmac_init(struct hash *, unsigned char *, unsigned int);
+void hmac_final(unsigned char *, struct hash *);
/* Temporary hash contexts. */
static union {
- MD5_CTX md5ctx;
- SHA1_CTX sha1ctx;
+ MD5_CTX md5ctx;
+ SHA1_CTX sha1ctx;
} Ctx, Ctx2;
/* Temporary hash digest. */
@@ -60,32 +60,37 @@ static unsigned char digest[HASH_MAX];
/* Encapsulation of hash functions. */
static struct hash hashes[] = {
- { HASH_MD5, 5, MD5_SIZE, (void *)&Ctx.md5ctx, digest,
- sizeof (MD5_CTX), (void *)&Ctx2.md5ctx,
- (void (*) (void *))MD5Init,
- (void (*) (void *, unsigned char *, unsigned int))MD5Update,
- (void (*) (unsigned char *, void *))MD5Final,
- hmac_init, hmac_final },
- { HASH_SHA1, 6, SHA1_SIZE, (void *)&Ctx.sha1ctx, digest,
- sizeof (SHA1_CTX), (void *)&Ctx2.sha1ctx,
- (void (*) (void *))SHA1Init,
- (void (*) (void *, unsigned char *, unsigned int))SHA1Update,
- (void (*) (unsigned char *, void *))SHA1Final,
- hmac_init, hmac_final },
+ {
+ HASH_MD5, 5, MD5_SIZE, (void *) &Ctx.md5ctx, digest,
+ sizeof(MD5_CTX), (void *) &Ctx2.md5ctx,
+ (void (*) (void *)) MD5Init,
+ (void (*) (void *, unsigned char *, unsigned int)) MD5Update,
+ (void (*) (unsigned char *, void *)) MD5Final,
+ hmac_init,
+ hmac_final
+ }, {
+ HASH_SHA1, 6, SHA1_SIZE, (void *) &Ctx.sha1ctx, digest,
+ sizeof(SHA1_CTX), (void *) &Ctx2.sha1ctx,
+ (void (*) (void *)) SHA1Init,
+ (void (*) (void *, unsigned char *, unsigned int)) SHA1Update,
+ (void (*) (unsigned char *, void *)) SHA1Final,
+ hmac_init,
+ hmac_final
+ },
};
struct hash *
-hash_get (enum hashes hashtype)
+hash_get(enum hashes hashtype)
{
- size_t i;
+ size_t i;
- LOG_DBG ((LOG_CRYPTO, 60, "hash_get: requested algorithm %d", hashtype));
+ LOG_DBG((LOG_CRYPTO, 60, "hash_get: requested algorithm %d", hashtype));
- for (i = 0; i < sizeof hashes / sizeof hashes[0]; i++)
- if (hashtype == hashes[i].type)
- return &hashes[i];
+ for (i = 0; i < sizeof hashes / sizeof hashes[0]; i++)
+ if (hashtype == hashes[i].type)
+ return &hashes[i];
- return 0;
+ return 0;
}
/*
@@ -95,38 +100,35 @@ hash_get (enum hashes hashtype)
*/
void
-hmac_init (struct hash *hash, unsigned char *okey, unsigned int len)
+hmac_init(struct hash *hash, unsigned char *okey, unsigned int len)
{
- unsigned int i, blocklen = HMAC_BLOCKLEN;
- unsigned char key[HMAC_BLOCKLEN];
+ unsigned int i, blocklen = HMAC_BLOCKLEN;
+ unsigned char key[HMAC_BLOCKLEN];
- memset (key, 0, blocklen);
- if (len > blocklen)
- {
- /* Truncate key down to blocklen */
- hash->Init (hash->ctx);
- hash->Update (hash->ctx, okey, len);
- hash->Final (key, hash->ctx);
- }
- else
- {
- memcpy (key, okey, len);
- }
+ memset(key, 0, blocklen);
+ if (len > blocklen) {
+ /* Truncate key down to blocklen */
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, okey, len);
+ hash->Final(key, hash->ctx);
+ } else {
+ memcpy(key, okey, len);
+ }
- /* HMAC I and O pad computation */
- for (i = 0; i < blocklen; i++)
- key[i] ^= HMAC_IPAD_VAL;
+ /* HMAC I and O pad computation */
+ for (i = 0; i < blocklen; i++)
+ key[i] ^= HMAC_IPAD_VAL;
- hash->Init (hash->ctx);
- hash->Update (hash->ctx, key, blocklen);
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, key, blocklen);
- for (i = 0; i < blocklen; i++)
- key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+ for (i = 0; i < blocklen; i++)
+ key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
- hash->Init (hash->ctx2);
- hash->Update (hash->ctx2, key, blocklen);
+ hash->Init(hash->ctx2);
+ hash->Update(hash->ctx2, key, blocklen);
- memset (key, 0, blocklen);
+ memset(key, 0, blocklen);
}
/*
@@ -134,9 +136,9 @@ hmac_init (struct hash *hash, unsigned char *okey, unsigned int len)
*/
void
-hmac_final (unsigned char *dgst, struct hash *hash)
+hmac_final(unsigned char *dgst, struct hash *hash)
{
- hash->Final (dgst, hash->ctx);
- hash->Update (hash->ctx2, dgst, hash->hashsize);
- hash->Final (dgst, hash->ctx2);
+ hash->Final(dgst, hash->ctx);
+ hash->Update(hash->ctx2, dgst, hash->hashsize);
+ hash->Final(dgst, hash->ctx2);
}
diff --git a/sbin/isakmpd/hash.h b/sbin/isakmpd/hash.h
index 900601ea8c3..3af23508138 100644
--- a/sbin/isakmpd/hash.h
+++ b/sbin/isakmpd/hash.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: hash.h,v 1.6 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: hash.h,v 1.6 1998/07/25 22:04:36 niklas Exp $ */
+/* $OpenBSD: hash.h,v 1.7 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: hash.h,v 1.6 1998/07/25 22:04:36 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -39,23 +39,23 @@
#define HASH_MAX SHA1_SIZE
enum hashes {
- HASH_MD5 = 0,
- HASH_SHA1
+ HASH_MD5 = 0,
+ HASH_SHA1
};
struct hash {
- enum hashes type;
- int id; /* ISAKMP/Oakley ID */
- u_int8_t hashsize; /* Size of the hash */
- void *ctx; /* Pointer to a context, for HMAC ictx */
- unsigned char *digest; /* Pointer to a digest */
- int ctxsize;
- void *ctx2; /* Pointer to a 2nd context, for HMAC octx */
- void (*Init) (void *);
- void (*Update) (void *, unsigned char *, unsigned int);
- void (*Final) (unsigned char *, void *);
- void (*HMACInit) (struct hash *, unsigned char *, unsigned int);
- void (*HMACFinal) (unsigned char *, struct hash *);
+ enum hashes type;
+ int id; /* ISAKMP/Oakley ID */
+ u_int8_t hashsize; /* Size of the hash */
+ void *ctx; /* Pointer to a context, for HMAC ictx */
+ unsigned char *digest; /* Pointer to a digest */
+ int ctxsize;
+ void *ctx2; /* Pointer to a 2nd context, for HMAC octx */
+ void (*Init) (void *);
+ void (*Update) (void *, unsigned char *, unsigned int);
+ void (*Final) (unsigned char *, void *);
+ void (*HMACInit) (struct hash *, unsigned char *, unsigned int);
+ void (*HMACFinal) (unsigned char *, struct hash *);
};
/* HMAC Hash Encapsulation */
@@ -64,7 +64,7 @@ struct hash {
#define HMAC_OPAD_VAL 0x5C
#define HMAC_BLOCKLEN 64
-extern struct hash *hash_get (enum hashes);
-extern void hmac_init (struct hash *, unsigned char *, unsigned int);
+extern struct hash *hash_get(enum hashes);
+extern void hmac_init(struct hash *, unsigned char *, unsigned int);
-#endif /* _HASH_H_ */
+#endif /* _HASH_H_ */
diff --git a/sbin/isakmpd/if.c b/sbin/isakmpd/if.c
index ab6cd66bcc2..52bd4ec1905 100644
--- a/sbin/isakmpd/if.c
+++ b/sbin/isakmpd/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.18 2004/04/13 21:48:15 hshoexer Exp $ */
+/* $OpenBSD: if.c,v 1.19 2004/04/15 18:39:25 deraadt Exp $ */
/* $EOM: if.c,v 1.12 1999/10/01 13:45:20 niklas Exp $ */
/*
@@ -59,96 +59,89 @@
* Return 0 if successful, -1 otherwise.
*/
int
-siocgifconf (struct ifconf *ifcp)
+siocgifconf(struct ifconf *ifcp)
{
- int s;
- int len;
- caddr_t buf, new_buf;
-
- /* Get a socket to ask for the network interface configurations. */
- s = monitor_socket (AF_INET, SOCK_DGRAM, 0);
- if (s == -1)
- {
- log_error ("siocgifconf: socket (AF_INET, SOCK_DGRAM, 0) failed");
- return -1;
- }
-
- len = sizeof (struct ifreq) * INITIAL_IFREQ_COUNT;
- buf = 0;
- while (1)
- {
- /*
- * Allocate a larger buffer each time around the loop and get the
- * network interfaces configurations into it.
- */
- new_buf = realloc (buf, len);
- if (!new_buf)
- {
- log_error ("siocgifconf: realloc (%p, %d) failed", buf, len);
- goto err;
+ caddr_t buf, new_buf;
+ int s, len;
+
+ /* Get a socket to ask for the network interface configurations. */
+ s = monitor_socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ log_error("siocgifconf: socket (AF_INET, SOCK_DGRAM, 0) failed");
+ return -1;
}
- ifcp->ifc_len = len;
- ifcp->ifc_buf = buf = new_buf;
- if (ioctl (s, SIOCGIFCONF, ifcp) == -1)
- {
- log_error ("siocgifconf: ioctl (%d, SIOCGIFCONF, ...) failed", s);
- goto err;
+ len = sizeof(struct ifreq) * INITIAL_IFREQ_COUNT;
+ buf = 0;
+ while (1) {
+ /*
+ * Allocate a larger buffer each time around the loop and get the
+ * network interfaces configurations into it.
+ */
+ new_buf = realloc(buf, len);
+ if (!new_buf) {
+ log_error("siocgifconf: realloc (%p, %d) failed", buf, len);
+ goto err;
+ }
+ ifcp->ifc_len = len;
+ ifcp->ifc_buf = buf = new_buf;
+ if (ioctl(s, SIOCGIFCONF, ifcp) == -1) {
+ log_error("siocgifconf: ioctl (%d, SIOCGIFCONF, ...) failed", s);
+ goto err;
+ }
+ /*
+ * If there is place for another ifreq we can be sure that the buffer
+ * was big enough, otherwise double the size and try again.
+ */
+ if (len - ifcp->ifc_len >= sizeof(struct ifreq))
+ break;
+ len *= 2;
}
-
- /*
- * If there is place for another ifreq we can be sure that the buffer
- * was big enough, otherwise double the size and try again.
- */
- if (len - ifcp->ifc_len >= sizeof (struct ifreq))
- break;
- len *= 2;
- }
- close (s);
- return 0;
+ close(s);
+ return 0;
err:
- if (buf)
- free (buf);
- ifcp->ifc_len = 0;
- ifcp->ifc_buf = 0;
- close (s);
- return -1;
+ if (buf)
+ free(buf);
+ ifcp->ifc_len = 0;
+ ifcp->ifc_buf = 0;
+ close(s);
+ return -1;
}
#endif
int
-if_map (int (*func) (char *, struct sockaddr *, void *), void *arg)
+if_map(int (*func)(char *, struct sockaddr *, void *), void *arg)
{
- int err = 0;
+ int err = 0;
+
#ifdef HAVE_GETIFADDRS
- struct ifaddrs *ifap, *ifa;
+ struct ifaddrs *ifap, *ifa;
- if (getifaddrs (&ifap) < 0)
- return -1;
+ if (getifaddrs(&ifap) < 0)
+ return -1;
- for (ifa = ifap; ifa; ifa = ifa->ifa_next)
- if ((*func) (ifa->ifa_name, ifa->ifa_addr, arg) == -1)
- err = -1;
- freeifaddrs (ifap);
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next)
+ if ((*func) (ifa->ifa_name, ifa->ifa_addr, arg) == -1)
+ err = -1;
+ freeifaddrs(ifap);
#else
- struct ifconf ifc;
- struct ifreq *ifrp;
- caddr_t limit, p;
- size_t len;
-
- if (siocgifconf (&ifc))
- return -1;
-
- limit = ifc.ifc_buf + ifc.ifc_len;
- for (p = ifc.ifc_buf; p < limit; p += len)
- {
- ifrp = (struct ifreq *)p;
- if ((*func) (ifrp->ifr_name, &ifrp->ifr_addr, arg) == -1)
- err = -1;
- len = sizeof ifrp->ifr_name
- + MAX (sysdep_sa_len (&ifrp->ifr_addr), sizeof ifrp->ifr_addr);
- }
- free (ifc.ifc_buf);
+ struct ifconf ifc;
+ struct ifreq *ifrp;
+ caddr_t limit, p;
+ size_t len;
+
+ if (siocgifconf(&ifc))
+ return -1;
+
+ limit = ifc.ifc_buf + ifc.ifc_len;
+ for (p = ifc.ifc_buf; p < limit; p += len) {
+ ifrp = (struct ifreq *) p;
+ if ((*func) (ifrp->ifr_name, &ifrp->ifr_addr, arg) == -1)
+ err = -1;
+ len = sizeof ifrp->ifr_name +
+ MAX(sysdep_sa_len(&ifrp->ifr_addr), sizeof ifrp->ifr_addr);
+ }
+ free(ifc.ifc_buf);
#endif
- return err;
+ return err;
}
diff --git a/sbin/isakmpd/if.h b/sbin/isakmpd/if.h
index 8054dd44b6b..82d574d96dc 100644
--- a/sbin/isakmpd/if.h
+++ b/sbin/isakmpd/if.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: if.h,v 1.6 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: if.h,v 1.2 1998/07/07 23:35:58 niklas Exp $ */
+/* $OpenBSD: if.h,v 1.7 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: if.h,v 1.2 1998/07/07 23:35:58 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -37,7 +37,7 @@
struct ifreq;
struct ifconf;
-extern int if_map (int (*) (char *, struct sockaddr *, void *), void *);
-extern int siocgifconf (struct ifconf *);
+extern int if_map(int (*) (char *, struct sockaddr *, void *), void *);
+extern int siocgifconf(struct ifconf *);
-#endif /* _IF_H_ */
+#endif /* _IF_H_ */
diff --git a/sbin/isakmpd/ike_aggressive.c b/sbin/isakmpd/ike_aggressive.c
index 6dbc34580b6..a7d58fc3b9e 100644
--- a/sbin/isakmpd/ike_aggressive.c
+++ b/sbin/isakmpd/ike_aggressive.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_aggressive.c,v 1.5 2003/06/04 07:31:16 ho Exp $ */
-/* $EOM: ike_aggressive.c,v 1.4 2000/01/31 22:33:45 niklas Exp $ */
+/* $OpenBSD: ike_aggressive.c,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_aggressive.c,v 1.4 2000/01/31 22:33:45 niklas Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -59,69 +59,69 @@
#include "transport.h"
#include "util.h"
-static int initiator_recv_SA_KE_NONCE_ID_AUTH (struct message *);
-static int initiator_send_SA_KE_NONCE_ID (struct message *);
-static int initiator_send_AUTH (struct message *);
-static int responder_recv_SA_KE_NONCE_ID (struct message *);
-static int responder_send_SA_KE_NONCE_ID_AUTH (struct message *);
+static int initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *);
+static int initiator_send_SA_KE_NONCE_ID(struct message *);
+static int initiator_send_AUTH(struct message *);
+static int responder_recv_SA_KE_NONCE_ID(struct message *);
+static int responder_send_SA_KE_NONCE_ID_AUTH(struct message *);
-int (*ike_aggressive_initiator[]) (struct message *) = {
- initiator_send_SA_KE_NONCE_ID,
- initiator_recv_SA_KE_NONCE_ID_AUTH,
- initiator_send_AUTH
+int (*ike_aggressive_initiator[]) (struct message *) = {
+ initiator_send_SA_KE_NONCE_ID,
+ initiator_recv_SA_KE_NONCE_ID_AUTH,
+ initiator_send_AUTH
};
-int (*ike_aggressive_responder[]) (struct message *) = {
- responder_recv_SA_KE_NONCE_ID,
- responder_send_SA_KE_NONCE_ID_AUTH,
- ike_phase_1_recv_AUTH
+int (*ike_aggressive_responder[]) (struct message *) = {
+ responder_recv_SA_KE_NONCE_ID,
+ responder_send_SA_KE_NONCE_ID_AUTH,
+ ike_phase_1_recv_AUTH
};
/* Offer a set of transforms to the responder in the MSG message. */
static int
-initiator_send_SA_KE_NONCE_ID (struct message *msg)
+initiator_send_SA_KE_NONCE_ID(struct message * msg)
{
- if (ike_phase_1_initiator_send_SA (msg))
- return -1;
+ if (ike_phase_1_initiator_send_SA(msg))
+ return -1;
- if (ike_phase_1_initiator_send_KE_NONCE (msg))
- return -1;
+ if (ike_phase_1_initiator_send_KE_NONCE(msg))
+ return -1;
- return ike_phase_1_send_ID (msg);
+ return ike_phase_1_send_ID(msg);
}
/* Figure out what transform the responder chose. */
static int
-initiator_recv_SA_KE_NONCE_ID_AUTH (struct message *msg)
+initiator_recv_SA_KE_NONCE_ID_AUTH(struct message * msg)
{
- if (ike_phase_1_initiator_recv_SA (msg))
- return -1;
+ if (ike_phase_1_initiator_recv_SA(msg))
+ return -1;
- if (ike_phase_1_initiator_recv_KE_NONCE (msg))
- return -1;
+ if (ike_phase_1_initiator_recv_KE_NONCE(msg))
+ return -1;
- return ike_phase_1_recv_ID_AUTH (msg);
+ return ike_phase_1_recv_ID_AUTH(msg);
}
static int
-initiator_send_AUTH (struct message *msg)
+initiator_send_AUTH(struct message * msg)
{
- msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
-
- if (ike_phase_1_send_AUTH (msg))
- return -1;
-
- /*
- * RFC 2407 4.6.3 says that, among others, INITIAL-CONTACT MUST NOT
- * be sent in Aggressive Mode. This leaves us with the choice of
- * doing it in an informational exchange of its own with no delivery
- * guarantee or in the first Quick Mode, or not at all.
- * draft-jenkins-ipsec-rekeying-01.txt has some text that requires
- * INITIAL-CONTACT in phase 1, thus contradicting what we learned
- * above. I will bring this up in the IPsec list. For now we don't
- * do INITIAL-CONTACT at all when using aggressive mode.
- */
- return 0;
+ msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+
+ if (ike_phase_1_send_AUTH(msg))
+ return -1;
+
+ /*
+ * RFC 2407 4.6.3 says that, among others, INITIAL-CONTACT MUST NOT
+ * be sent in Aggressive Mode. This leaves us with the choice of
+ * doing it in an informational exchange of its own with no delivery
+ * guarantee or in the first Quick Mode, or not at all.
+ * draft-jenkins-ipsec-rekeying-01.txt has some text that requires
+ * INITIAL-CONTACT in phase 1, thus contradicting what we learned
+ * above. I will bring this up in the IPsec list. For now we don't
+ * do INITIAL-CONTACT at all when using aggressive mode.
+ */
+ return 0;
}
/*
@@ -129,15 +129,15 @@ initiator_send_AUTH (struct message *msg)
* handle. Also accept initiator's public DH value, nonce and ID.
*/
static int
-responder_recv_SA_KE_NONCE_ID (struct message *msg)
+responder_recv_SA_KE_NONCE_ID(struct message * msg)
{
- if (ike_phase_1_responder_recv_SA (msg))
- return -1;
+ if (ike_phase_1_responder_recv_SA(msg))
+ return -1;
- if (ike_phase_1_recv_ID (msg))
- return -1;
+ if (ike_phase_1_recv_ID(msg))
+ return -1;
- return ike_phase_1_recv_KE_NONCE (msg);
+ return ike_phase_1_recv_KE_NONCE(msg);
}
/*
@@ -145,19 +145,19 @@ responder_recv_SA_KE_NONCE_ID (struct message *msg)
* to the initiator.
*/
static int
-responder_send_SA_KE_NONCE_ID_AUTH (struct message *msg)
+responder_send_SA_KE_NONCE_ID_AUTH(struct message * msg)
{
- /* Add the SA payload with the transform that was chosen. */
- if (ike_phase_1_responder_send_SA (msg))
- return -1;
+ /* Add the SA payload with the transform that was chosen. */
+ if (ike_phase_1_responder_send_SA(msg))
+ return -1;
- /* XXX Should we really just use the initiator's nonce size? */
- if (ike_phase_1_send_KE_NONCE (msg, msg->exchange->nonce_i_len))
- return -1;
+ /* XXX Should we really just use the initiator's nonce size? */
+ if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
+ return -1;
- if (ike_phase_1_post_exchange_KE_NONCE (msg))
- return -1;
+ if (ike_phase_1_post_exchange_KE_NONCE(msg))
+ return -1;
- return ike_phase_1_responder_send_ID_AUTH (msg);
- return -1;
+ return ike_phase_1_responder_send_ID_AUTH(msg);
+ return -1;
}
diff --git a/sbin/isakmpd/ike_aggressive.h b/sbin/isakmpd/ike_aggressive.h
index 44f3cd0fbb0..4356cdeac57 100644
--- a/sbin/isakmpd/ike_aggressive.h
+++ b/sbin/isakmpd/ike_aggressive.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_aggressive.h,v 1.3 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ike_aggressive.h,v 1.1 1999/04/16 21:24:43 niklas Exp $ */
+/* $OpenBSD: ike_aggressive.h,v 1.4 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_aggressive.h,v 1.1 1999/04/16 21:24:43 niklas Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -34,7 +34,7 @@
struct message;
-extern int (*ike_aggressive_initiator[]) (struct message *msg);
-extern int (*ike_aggressive_responder[]) (struct message *msg);
+extern int (*ike_aggressive_initiator[]) (struct message * msg);
+extern int (*ike_aggressive_responder[]) (struct message * msg);
-#endif /* _IKE_AGGRESSIVE_H_ */
+#endif /* _IKE_AGGRESSIVE_H_ */
diff --git a/sbin/isakmpd/ike_auth.c b/sbin/isakmpd/ike_auth.c
index 4133c50e41f..b5901acdf0f 100644
--- a/sbin/isakmpd/ike_auth.c
+++ b/sbin/isakmpd/ike_auth.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_auth.c,v 1.85 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */
+/* $OpenBSD: ike_auth.c,v 1.86 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -73,63 +73,63 @@
#endif
#ifdef notyet
-static u_int8_t *enc_gen_skeyid (struct exchange *, size_t *);
+static u_int8_t *enc_gen_skeyid(struct exchange *, size_t *);
#endif
-static u_int8_t *pre_shared_gen_skeyid (struct exchange *, size_t *);
+static u_int8_t *pre_shared_gen_skeyid(struct exchange *, size_t *);
-static int pre_shared_decode_hash (struct message *);
-static int pre_shared_encode_hash (struct message *);
+static int pre_shared_decode_hash(struct message *);
+static int pre_shared_encode_hash(struct message *);
#if defined (USE_X509) || defined (USE_KEYNOTE)
-static u_int8_t *sig_gen_skeyid (struct exchange *, size_t *);
-static int rsa_sig_decode_hash (struct message *);
-static int rsa_sig_encode_hash (struct message *);
+static u_int8_t *sig_gen_skeyid(struct exchange *, size_t *);
+static int rsa_sig_decode_hash(struct message *);
+static int rsa_sig_encode_hash(struct message *);
#endif
#if defined (USE_RAWKEY)
-static int get_raw_key_from_file (int, u_int8_t *, size_t, RSA **);
+static int get_raw_key_from_file(int, u_int8_t *, size_t, RSA **);
#endif
-static int ike_auth_hash (struct exchange *, u_int8_t *);
+static int ike_auth_hash(struct exchange *, u_int8_t *);
static struct ike_auth ike_auth[] = {
- {
- IKE_AUTH_PRE_SHARED, pre_shared_gen_skeyid, pre_shared_decode_hash,
- pre_shared_encode_hash
- },
+ {
+ IKE_AUTH_PRE_SHARED, pre_shared_gen_skeyid, pre_shared_decode_hash,
+ pre_shared_encode_hash
+ },
#ifdef notdef
- {
- IKE_AUTH_DSS, sig_gen_skeyid, pre_shared_decode_hash,
- pre_shared_encode_hash
- },
+ {
+ IKE_AUTH_DSS, sig_gen_skeyid, pre_shared_decode_hash,
+ pre_shared_encode_hash
+ },
#endif
#if defined (USE_X509) || defined (USE_KEYNOTE)
- {
- IKE_AUTH_RSA_SIG, sig_gen_skeyid, rsa_sig_decode_hash,
- rsa_sig_encode_hash
- },
+ {
+ IKE_AUTH_RSA_SIG, sig_gen_skeyid, rsa_sig_decode_hash,
+ rsa_sig_encode_hash
+ },
#endif
#ifdef notdef
- {
- IKE_AUTH_RSA_ENC, enc_gen_skeyid, pre_shared_decode_hash,
- pre_shared_encode_hash
- },
- {
- IKE_AUTH_RSA_ENC_REV, enc_gen_skeyid, pre_shared_decode_hash,
- pre_shared_encode_hash
- },
+ {
+ IKE_AUTH_RSA_ENC, enc_gen_skeyid, pre_shared_decode_hash,
+ pre_shared_encode_hash
+ },
+ {
+ IKE_AUTH_RSA_ENC_REV, enc_gen_skeyid, pre_shared_decode_hash,
+ pre_shared_encode_hash
+ },
#endif
};
struct ike_auth *
-ike_auth_get (u_int16_t id)
+ike_auth_get(u_int16_t id)
{
- size_t i;
+ size_t i;
- for (i = 0; i < sizeof ike_auth / sizeof ike_auth[0]; i++)
- if (id == ike_auth[i].id)
- return &ike_auth[i];
- return 0;
+ for (i = 0; i < sizeof ike_auth / sizeof ike_auth[0]; i++)
+ if (id == ike_auth[i].id)
+ return &ike_auth[i];
+ return 0;
}
/*
@@ -137,378 +137,337 @@ ike_auth_get (u_int16_t id)
* peer denoted by ID. Stash the len in KEYLEN.
*/
static void *
-ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen)
+ike_auth_get_key(int type, char *id, char *local_id, size_t *keylen)
{
- char *key, *buf;
+ char *key, *buf;
#if defined (USE_X509) || defined (USE_KEYNOTE)
- char *keyfile;
+ char *keyfile;
#if defined (USE_X509)
#if defined (USE_PRIVSEP)
- FILE *keyfp;
+ FILE *keyfp;
#else
- BIO *keyh;
+ BIO *keyh;
#endif
- RSA *rsakey;
- size_t fsize;
+ RSA *rsakey;
+ size_t fsize;
#endif
#endif
- switch (type)
- {
- case IKE_AUTH_PRE_SHARED:
- /* Get the pre-shared key for our peer. */
- key = conf_get_str (id, "Authentication");
- if (!key && local_id)
- key = conf_get_str (local_id, "Authentication");
-
- if (!key)
- {
- log_print ("ike_auth_get_key: "
- "no key found for peer \"%s\" or local ID \"%s\"",
- id, local_id);
- return 0;
- }
-
- /* If the key starts with 0x it is in hex format. */
- if (strncasecmp (key, "0x", 2) == 0)
- {
- *keylen = (strlen (key) - 1) / 2;
- buf = malloc (*keylen);
- if (!buf)
- {
- log_error ("ike_auth_get_key: malloc (%lu) failed",
- (unsigned long)*keylen);
- return 0;
- }
- if (hex2raw (key + 2, (unsigned char *)buf, *keylen))
- {
- free (buf);
- log_print ("ike_auth_get_key: invalid hex key %s", key);
- return 0;
- }
- key = buf;
- }
- else
- {
- buf = key;
- key = strdup (buf);
- if (!key)
- {
- log_error ("ike_auth_get_key: strdup() failed");
- return 0;
- }
- *keylen = strlen (key);
- }
- break;
+ switch (type) {
+ case IKE_AUTH_PRE_SHARED:
+ /* Get the pre-shared key for our peer. */
+ key = conf_get_str(id, "Authentication");
+ if (!key && local_id)
+ key = conf_get_str(local_id, "Authentication");
+
+ if (!key) {
+ log_print("ike_auth_get_key: "
+ "no key found for peer \"%s\" or local ID \"%s\"",
+ id, local_id);
+ return 0;
+ }
+ /* If the key starts with 0x it is in hex format. */
+ if (strncasecmp(key, "0x", 2) == 0) {
+ *keylen = (strlen(key) - 1) / 2;
+ buf = malloc(*keylen);
+ if (!buf) {
+ log_error("ike_auth_get_key: malloc (%lu) failed",
+ (unsigned long) *keylen);
+ return 0;
+ }
+ if (hex2raw(key + 2, (unsigned char *) buf, *keylen)) {
+ free(buf);
+ log_print("ike_auth_get_key: invalid hex key %s",
+ key);
+ return 0;
+ }
+ key = buf;
+ } else {
+ buf = key;
+ key = strdup(buf);
+ if (!key) {
+ log_error("ike_auth_get_key: strdup() failed");
+ return 0;
+ }
+ *keylen = strlen(key);
+ }
+ break;
- case IKE_AUTH_RSA_SIG:
+ case IKE_AUTH_RSA_SIG:
#if defined (USE_X509) || defined (USE_KEYNOTE)
#if defined (USE_KEYNOTE)
- if (local_id &&
- (keyfile = conf_get_str ("KeyNote", "Credential-directory")) != 0)
- {
- struct stat sb;
- struct keynote_deckey dc;
- char *privkeyfile, *buf2;
- int fd, pkflen;
- size_t size;
-
- pkflen = strlen (keyfile) + strlen (local_id) +
- sizeof PRIVATE_KEY_FILE + sizeof "//" - 1;
- privkeyfile = calloc (pkflen, sizeof (char));
- if (!privkeyfile)
- {
- log_print ("ike_auth_get_key: failed to allocate %d bytes",
- pkflen);
- return 0;
- }
-
- snprintf (privkeyfile, pkflen, "%s/%s/%s", keyfile, local_id,
- PRIVATE_KEY_FILE);
- keyfile = privkeyfile;
-
- if (monitor_stat (keyfile, &sb) < 0)
- {
- free (keyfile);
- goto ignorekeynote;
- }
- size = (size_t)sb.st_size;
-
- fd = monitor_open (keyfile, O_RDONLY, 0);
- if (fd < 0)
- {
- log_print ("ike_auth_get_key: failed opening \"%s\"", keyfile);
- free (keyfile);
- return 0;
- }
-
- buf = calloc (size + 1, sizeof (char));
- if (!buf)
- {
- log_print ("ike_auth_get_key: failed allocating %lu bytes",
- (unsigned long)size + 1);
- free (keyfile);
- return 0;
- }
-
- if (read (fd, buf, size) != (ssize_t)size)
- {
- free (buf);
- log_print ("ike_auth_get_key: "
- "failed reading %lu bytes from \"%s\"",
- (unsigned long)size, keyfile);
- free (keyfile);
- return 0;
- }
-
- close (fd);
-
- /* Parse private key string */
- buf2 = kn_get_string (buf);
- free (buf);
-
- if (kn_decode_key (&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1)
- {
- free (buf2);
- log_print ("ike_auth_get_key: failed decoding key in \"%s\"",
- keyfile);
- free (keyfile);
- return 0;
- }
-
- free (buf2);
-
- if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA)
- {
- log_print ("ike_auth_get_key: wrong algorithm type %d in \"%s\"",
- dc.dec_algorithm, keyfile);
- free (keyfile);
- kn_free_key (&dc);
- return 0;
- }
-
- free (keyfile);
- return dc.dec_key;
- }
-
- ignorekeynote:
-#endif /* USE_KEYNOTE */
+ if (local_id &&
+ (keyfile = conf_get_str("KeyNote", "Credential-directory")) != 0) {
+ struct stat sb;
+ struct keynote_deckey dc;
+ char *privkeyfile, *buf2;
+ int fd, pkflen;
+ size_t size;
+
+ pkflen = strlen(keyfile) + strlen(local_id) +
+ sizeof PRIVATE_KEY_FILE + sizeof "//" - 1;
+ privkeyfile = calloc(pkflen, sizeof(char));
+ if (!privkeyfile) {
+ log_print("ike_auth_get_key: failed to allocate %d bytes",
+ pkflen);
+ return 0;
+ }
+ snprintf(privkeyfile, pkflen, "%s/%s/%s", keyfile, local_id,
+ PRIVATE_KEY_FILE);
+ keyfile = privkeyfile;
+
+ if (monitor_stat(keyfile, &sb) < 0) {
+ free(keyfile);
+ goto ignorekeynote;
+ }
+ size = (size_t) sb.st_size;
+
+ fd = monitor_open(keyfile, O_RDONLY, 0);
+ if (fd < 0) {
+ log_print("ike_auth_get_key: failed opening \"%s\"",
+ keyfile);
+ free(keyfile);
+ return 0;
+ }
+ buf = calloc(size + 1, sizeof(char));
+ if (!buf) {
+ log_print("ike_auth_get_key: failed allocating %lu bytes",
+ (unsigned long) size + 1);
+ free(keyfile);
+ return 0;
+ }
+ if (read(fd, buf, size) != (ssize_t) size) {
+ free(buf);
+ log_print("ike_auth_get_key: "
+ "failed reading %lu bytes from \"%s\"",
+ (unsigned long) size, keyfile);
+ free(keyfile);
+ return 0;
+ }
+ close(fd);
+
+ /* Parse private key string */
+ buf2 = kn_get_string(buf);
+ free(buf);
+
+ if (kn_decode_key(&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1) {
+ free(buf2);
+ log_print("ike_auth_get_key: failed decoding key in \"%s\"",
+ keyfile);
+ free(keyfile);
+ return 0;
+ }
+ free(buf2);
+
+ if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA) {
+ log_print("ike_auth_get_key: wrong algorithm type %d in \"%s\"",
+ dc.dec_algorithm, keyfile);
+ free(keyfile);
+ kn_free_key(&dc);
+ return 0;
+ }
+ free(keyfile);
+ return dc.dec_key;
+ }
+ignorekeynote:
+#endif /* USE_KEYNOTE */
#ifdef USE_X509
- /* Otherwise, try X.509 */
- keyfile = conf_get_str ("X509-certificates", "Private-key");
+ /* Otherwise, try X.509 */
+ keyfile = conf_get_str("X509-certificates", "Private-key");
- if (check_file_secrecy (keyfile, &fsize))
- return 0;
+ if (check_file_secrecy(keyfile, &fsize))
+ return 0;
#if defined (USE_PRIVSEP)
- keyfp = monitor_fopen (keyfile, "r");
- if (!keyfp)
- {
- log_print ("ike_auth_get_key: failed opening \"%s\"", keyfile);
- return 0;
- }
+ keyfp = monitor_fopen(keyfile, "r");
+ if (!keyfp) {
+ log_print("ike_auth_get_key: failed opening \"%s\"", keyfile);
+ return 0;
+ }
#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- rsakey = PEM_read_RSAPrivateKey (keyfp, NULL, NULL, NULL);
+ rsakey = PEM_read_RSAPrivateKey(keyfp, NULL, NULL, NULL);
#else
- rsakey = PEM_read_RSAPrivateKey (keyfp, NULL, NULL);
+ rsakey = PEM_read_RSAPrivateKey(keyfp, NULL, NULL);
#endif
- fclose (keyfp);
+ fclose(keyfp);
#else
- keyh = BIO_new (BIO_s_file ());
- if (keyh == NULL)
- {
- log_print ("ike_auth_get_key: "
- "BIO_new (BIO_s_file ()) failed");
- return 0;
- }
- if (BIO_read_filename (keyh, keyfile) == -1)
- {
- log_print ("ike_auth_get_key: "
- "BIO_read_filename (keyh, \"%s\") failed",
- keyfile);
- BIO_free (keyh);
- return 0;
- }
-
+ keyh = BIO_new(BIO_s_file());
+ if (keyh == NULL) {
+ log_print("ike_auth_get_key: "
+ "BIO_new (BIO_s_file ()) failed");
+ return 0;
+ }
+ if (BIO_read_filename(keyh, keyfile) == -1) {
+ log_print("ike_auth_get_key: "
+ "BIO_read_filename (keyh, \"%s\") failed",
+ keyfile);
+ BIO_free(keyh);
+ return 0;
+ }
#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL);
+ rsakey = PEM_read_bio_RSAPrivateKey(keyh, NULL, NULL, NULL);
#else
- rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL);
+ rsakey = PEM_read_bio_RSAPrivateKey(keyh, NULL, NULL);
#endif
- BIO_free (keyh);
-#endif /* USE_PRIVSEP */
+ BIO_free(keyh);
+#endif /* USE_PRIVSEP */
- if (!rsakey)
- {
- log_print ("ike_auth_get_key: PEM_read_bio_RSAPrivateKey failed");
- return 0;
- }
-
- return rsakey;
+ if (!rsakey) {
+ log_print("ike_auth_get_key: PEM_read_bio_RSAPrivateKey failed");
+ return 0;
+ }
+ return rsakey;
#endif /* USE_X509 */
#endif /* USE_X509 || USE_KEYNOTE */
- default:
- log_print ("ike_auth_get_key: unknown key type %d", type);
- return 0;
- }
+ default:
+ log_print("ike_auth_get_key: unknown key type %d", type);
+ return 0;
+ }
- return key;
+ return key;
}
static u_int8_t *
-pre_shared_gen_skeyid (struct exchange *exchange, size_t *sz)
+pre_shared_gen_skeyid(struct exchange *exchange, size_t *sz)
{
- struct prf *prf;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t *skeyid;
- u_int8_t *buf = 0;
- unsigned char *key;
- size_t keylen;
-
- /*
- * If we're the responder and have the initiator's ID (which is the
- * case in Aggressive mode), try to find the preshared key in the
- * section of the initiator's Phase 1 ID. This allows us to do
- * mobile user support with preshared keys.
- */
- if (!exchange->initiator && exchange->id_i)
- {
- switch (exchange->id_i[0])
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- util_ntoa ((char **)&buf,
- exchange->id_i[0] == IPSEC_ID_IPV4_ADDR
- ? AF_INET : AF_INET6,
- exchange->id_i + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- if (!buf)
- return 0;
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- buf = calloc (exchange->id_i_len - ISAKMP_ID_DATA_OFF
- + ISAKMP_GEN_SZ + 1, sizeof (char));
- if (!buf)
- {
- log_print ("pre_shared_gen_skeyid: malloc (%lu) failed",
- (unsigned long)exchange->id_i_len - ISAKMP_ID_DATA_OFF
- + ISAKMP_GEN_SZ + 1);
- return 0;
- }
- memcpy (buf, exchange->id_i + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- exchange->id_i_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
-
- /* XXX Support more ID types ? */
- default:
- break;
+ struct prf *prf;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t *skeyid, *buf = 0;
+ unsigned char *key;
+ size_t keylen;
+
+ /*
+ * If we're the responder and have the initiator's ID (which is the
+ * case in Aggressive mode), try to find the preshared key in the
+ * section of the initiator's Phase 1 ID. This allows us to do
+ * mobile user support with preshared keys.
+ */
+ if (!exchange->initiator && exchange->id_i) {
+ switch (exchange->id_i[0]) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa((char **) &buf,
+ exchange->id_i[0] == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
+ exchange->id_i + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ if (!buf)
+ return 0;
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ buf = calloc(exchange->id_i_len - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1, sizeof(char));
+ if (!buf) {
+ log_print("pre_shared_gen_skeyid: malloc (%lu) failed",
+ (unsigned long) exchange->id_i_len -
+ ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1);
+ return 0;
+ }
+ memcpy(buf,
+ exchange->id_i + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ exchange->id_i_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
+ break;
+
+ /* XXX Support more ID types ? */
+ default:
+ break;
+ }
+ }
+ /*
+ * Get the pre-shared key for our peer. This will work even if the key
+ * has been passed to us through a mechanism like PFKEYv2.
+ */
+ key = ike_auth_get_key(IKE_AUTH_PRE_SHARED, exchange->name,
+ (char *) buf, &keylen);
+ if (buf)
+ free(buf);
+
+ /* Fail if no key could be found. */
+ if (!key)
+ return 0;
+
+ /* Store the secret key for later policy processing. */
+ exchange->recv_key = calloc(keylen + 1, sizeof(char));
+ exchange->recv_keytype = ISAKMP_KEY_PASSPHRASE;
+ if (!exchange->recv_key) {
+ log_error("pre_shared_gen_skeyid: malloc (%lu) failed",
+ (unsigned long) keylen);
+ free(key);
+ return 0;
}
- }
-
- /*
- * Get the pre-shared key for our peer. This will work even if the key
- * has been passed to us through a mechanism like PFKEYv2.
- */
- key = ike_auth_get_key (IKE_AUTH_PRE_SHARED, exchange->name, (char *)buf,
- &keylen);
- if (buf)
- free (buf);
-
- /* Fail if no key could be found. */
- if (!key)
- return 0;
-
- /* Store the secret key for later policy processing. */
- exchange->recv_key = calloc (keylen + 1, sizeof (char));
- exchange->recv_keytype = ISAKMP_KEY_PASSPHRASE;
- if (!exchange->recv_key)
- {
- log_error ("pre_shared_gen_skeyid: malloc (%lu) failed",
- (unsigned long)keylen);
- free (key);
- return 0;
- }
- memcpy (exchange->recv_key, key, keylen);
- exchange->recv_certtype = ISAKMP_CERTENC_NONE;
- free (key);
-
- prf = prf_alloc (ie->prf_type, ie->hash->type, exchange->recv_key, keylen);
- if (!prf)
- return 0;
-
- *sz = prf->blocksize;
- skeyid = malloc (*sz);
- if (!skeyid)
- {
- log_error ("pre_shared_gen_skeyid: malloc (%lu) failed",
- (unsigned long)*sz);
- prf_free (prf);
- return 0;
- }
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
- prf->Update (prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
- prf->Final (skeyid, prf->prfctx);
- prf_free (prf);
-
- return skeyid;
+ memcpy(exchange->recv_key, key, keylen);
+ exchange->recv_certtype = ISAKMP_CERTENC_NONE;
+ free(key);
+
+ prf = prf_alloc(ie->prf_type, ie->hash->type, exchange->recv_key, keylen);
+ if (!prf)
+ return 0;
+
+ *sz = prf->blocksize;
+ skeyid = malloc(*sz);
+ if (!skeyid) {
+ log_error("pre_shared_gen_skeyid: malloc (%lu) failed",
+ (unsigned long) *sz);
+ prf_free(prf);
+ return 0;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
+ prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
+ prf->Final(skeyid, prf->prfctx);
+ prf_free(prf);
+ return skeyid;
}
#if defined (USE_X509) || defined (USE_KEYNOTE)
/* Both DSS & RSA signature authentication use this algorithm. */
static u_int8_t *
-sig_gen_skeyid (struct exchange *exchange, size_t *sz)
+sig_gen_skeyid(struct exchange *exchange, size_t *sz)
{
- struct prf *prf;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t *skeyid;
- unsigned char *key;
-
- key = malloc (exchange->nonce_i_len + exchange->nonce_r_len);
- if (!key)
- return 0;
- memcpy (key, exchange->nonce_i, exchange->nonce_i_len);
- memcpy (key + exchange->nonce_i_len, exchange->nonce_r,
- exchange->nonce_r_len);
-
- LOG_DBG ((LOG_NEGOTIATION, 80, "sig_gen_skeyid: PRF type %d, hash %d",
+ struct prf *prf;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t *skeyid;
+ unsigned char *key;
+
+ key = malloc(exchange->nonce_i_len + exchange->nonce_r_len);
+ if (!key)
+ return 0;
+ memcpy(key, exchange->nonce_i, exchange->nonce_i_len);
+ memcpy(key + exchange->nonce_i_len, exchange->nonce_r,
+ exchange->nonce_r_len);
+
+ LOG_DBG((LOG_NEGOTIATION, 80, "sig_gen_skeyid: PRF type %d, hash %d",
ie->prf_type, ie->hash->type));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID initialized with",
- (u_int8_t *)key,
- exchange->nonce_i_len + exchange->nonce_r_len));
-
- prf = prf_alloc (ie->prf_type, ie->hash->type, key,
- exchange->nonce_i_len + exchange->nonce_r_len);
- free (key);
- if (!prf)
- return 0;
-
- *sz = prf->blocksize;
- skeyid = malloc (*sz);
- if (!skeyid)
- {
- log_error ("sig_gen_skeyid: malloc (%lu) failed",
- (unsigned long)*sz);
- prf_free (prf);
- return 0;
- }
-
- LOG_DBG ((LOG_NEGOTIATION, 80, "sig_gen_skeyid: g^xy length %lu",
- (unsigned long)ie->g_x_len));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID fed with g^xy",
- ie->g_xy, ie->g_x_len));
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
- prf->Final (skeyid, prf->prfctx);
- prf_free (prf);
-
- return skeyid;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID initialized with",
+ (u_int8_t *) key, exchange->nonce_i_len + exchange->nonce_r_len));
+
+ prf = prf_alloc(ie->prf_type, ie->hash->type, key,
+ exchange->nonce_i_len + exchange->nonce_r_len);
+ free(key);
+ if (!prf)
+ return 0;
+
+ *sz = prf->blocksize;
+ skeyid = malloc(*sz);
+ if (!skeyid) {
+ log_error("sig_gen_skeyid: malloc (%lu) failed",
+ (unsigned long) *sz);
+ prf_free(prf);
+ return 0;
+ }
+ LOG_DBG((LOG_NEGOTIATION, 80, "sig_gen_skeyid: g^xy length %lu",
+ (unsigned long) ie->g_x_len));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID fed with g^xy",
+ ie->g_xy, ie->g_x_len));
+
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, ie->g_xy, ie->g_x_len);
+ prf->Final(skeyid, prf->prfctx);
+ prf_free(prf);
+ return skeyid;
}
-#endif /* USE_X509 || USE_KEYNOTE */
+#endif /* USE_X509 || USE_KEYNOTE */
#ifdef notdef
/*
@@ -516,797 +475,688 @@ sig_gen_skeyid (struct exchange *exchange, size_t *sz)
* computation.
*/
static u_int8_t *
-enc_gen_skeyid (struct exchange *exchange, size_t *sz)
+enc_gen_skeyid(struct exchange *exchange, size_t *sz)
{
- struct prf *prf;
- struct ipsec_exch *ie = exchange->data;
- struct hash *hash = ie->hash;
- u_int8_t *skeyid;
-
- hash->Init (hash->ctx);
- hash->Update (hash->ctx, exchange->nonce_i, exchange->nonce_i_len);
- hash->Update (hash->ctx, exchange->nonce_r, exchange->nonce_r_len);
- hash->Final (hash->digest, hash->ctx);
- prf = prf_alloc (ie->prf_type, hash->type, hash->digest, *sz);
- if (!prf)
- return 0;
-
- *sz = prf->blocksize;
- skeyid = malloc (*sz);
- if (!skeyid)
- {
- log_error ("enc_gen_skeyid: malloc (%d) failed", *sz);
- prf_free (prf);
- return 0;
- }
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
- prf->Final (skeyid, prf->prfctx);
- prf_free (prf);
-
- return skeyid;
+ struct prf *prf;
+ struct ipsec_exch *ie = exchange->data;
+ struct hash *hash = ie->hash;
+ u_int8_t *skeyid;
+
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, exchange->nonce_i, exchange->nonce_i_len);
+ hash->Update(hash->ctx, exchange->nonce_r, exchange->nonce_r_len);
+ hash->Final(hash->digest, hash->ctx);
+ prf = prf_alloc(ie->prf_type, hash->type, hash->digest, *sz);
+ if (!prf)
+ return 0;
+
+ *sz = prf->blocksize;
+ skeyid = malloc(*sz);
+ if (!skeyid) {
+ log_error("enc_gen_skeyid: malloc (%d) failed", *sz);
+ prf_free(prf);
+ return 0;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
+ prf->Final(skeyid, prf->prfctx);
+ prf_free(prf);
+ return skeyid;
}
-#endif /* notdef */
+#endif /* notdef */
static int
-pre_shared_decode_hash (struct message *msg)
+pre_shared_decode_hash(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct payload *payload;
- size_t hashsize = ie->hash->hashsize;
- char header[80];
- int initiator = exchange->initiator;
- u_int8_t **hash_p;
-
- /* Choose the right fields to fill-in. */
- hash_p = initiator ? &ie->hash_r : &ie->hash_i;
-
- payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- if (!payload)
- {
- log_print ("pre_shared_decode_hash: no HASH payload found");
- return -1;
- }
-
- /* Check that the hash is of the correct size. */
- if (GET_ISAKMP_GEN_LENGTH (payload->p) - ISAKMP_GEN_SZ != hashsize)
- return -1;
-
- /* XXX Need this hash be in the SA? */
- *hash_p = malloc (hashsize);
- if (!*hash_p)
- {
- log_error ("pre_shared_decode_hash: malloc (%lu) failed",
- (unsigned long)hashsize);
- return -1;
- }
-
- memcpy (*hash_p, payload->p + ISAKMP_HASH_DATA_OFF, hashsize);
- snprintf (header, sizeof header, "pre_shared_decode_hash: HASH_%c",
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct payload *payload;
+ size_t hashsize = ie->hash->hashsize;
+ char header[80];
+ int initiator = exchange->initiator;
+ u_int8_t **hash_p;
+
+ /* Choose the right fields to fill-in. */
+ hash_p = initiator ? &ie->hash_r : &ie->hash_i;
+
+ payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ if (!payload) {
+ log_print("pre_shared_decode_hash: no HASH payload found");
+ return -1;
+ }
+ /* Check that the hash is of the correct size. */
+ if (GET_ISAKMP_GEN_LENGTH(payload->p) - ISAKMP_GEN_SZ != hashsize)
+ return -1;
+
+ /* XXX Need this hash be in the SA? */
+ *hash_p = malloc(hashsize);
+ if (!*hash_p) {
+ log_error("pre_shared_decode_hash: malloc (%lu) failed",
+ (unsigned long) hashsize);
+ return -1;
+ }
+ memcpy(*hash_p, payload->p + ISAKMP_HASH_DATA_OFF, hashsize);
+ snprintf(header, sizeof header, "pre_shared_decode_hash: HASH_%c",
initiator ? 'R' : 'I');
- LOG_DBG_BUF ((LOG_MISC, 80, header, *hash_p, hashsize));
+ LOG_DBG_BUF((LOG_MISC, 80, header, *hash_p, hashsize));
- payload->flags |= PL_MARK;
-
- return 0;
+ payload->flags |= PL_MARK;
+ return 0;
}
#if defined (USE_X509) || defined (USE_KEYNOTE)
/* Decrypt the HASH in SIG, we already need a parsed ID payload. */
static int
-rsa_sig_decode_hash (struct message *msg)
+rsa_sig_decode_hash(struct message *msg)
{
- struct cert_handler *handler;
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct payload *p;
- void *cert = 0;
- u_int8_t *rawcert = 0;
- u_int32_t rawcertlen;
- RSA *key = 0;
- size_t hashsize = ie->hash->hashsize;
- char header[80];
- int len;
- int initiator = exchange->initiator;
- u_int8_t **hash_p, **id_cert, *id;
- u_int32_t *id_cert_len;
- size_t id_len;
- int found = 0, n, i, id_found;
+ struct cert_handler *handler;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct payload *p;
+ void *cert = 0;
+ u_int8_t *rawcert = 0, **hash_p, **id_cert, *id;
+ u_int32_t rawcertlen, *id_cert_len;
+ RSA *key = 0;
+ size_t hashsize = ie->hash->hashsize, id_len;
+ char header[80];
+ int len, initiator = exchange->initiator;
+ int found = 0, n, i, id_found;
#if defined (USE_DNSSEC)
- u_int8_t *rawkey = 0;
- u_int32_t rawkeylen;
+ u_int8_t *rawkey = 0;
+ u_int32_t rawkeylen;
#endif
- /* Choose the right fields to fill-in. */
- hash_p = initiator ? &ie->hash_r : &ie->hash_i;
- id = initiator ? exchange->id_r : exchange->id_i;
- id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
-
- if (!id || id_len == 0)
- {
- log_print ("rsa_sig_decode_hash: ID is missing");
- return -1;
- }
-
- /*
- * XXX Assume we should use the same kind of certification as the remote...
- * moreover, just use the first CERT payload to decide what to use.
- */
- p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_CERT]);
- if (!p)
- handler = cert_get (ISAKMP_CERTENC_KEYNOTE);
- else
- handler = cert_get (GET_ISAKMP_CERT_ENCODING (p->p));
- if (!handler)
- {
- log_print ("rsa_sig_decode_hash: cert_get (%d) failed",
- p ? GET_ISAKMP_CERT_ENCODING (p->p) : -1);
- return -1;
- }
+ /* Choose the right fields to fill-in. */
+ hash_p = initiator ? &ie->hash_r : &ie->hash_i;
+ id = initiator ? exchange->id_r : exchange->id_i;
+ id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
-#if defined (USE_POLICY) || defined (USE_KEYNOTE)
- /*
- * We need the policy session initialized now, so we can add
- * credentials etc.
- */
- exchange->policy_id = kn_init ();
- if (exchange->policy_id == -1)
- {
- log_print ("rsa_sig_decode_hash: failed to initialize policy session");
- return -1;
- }
-#endif /* USE_POLICY || USE_KEYNOTE */
-
- /* Obtain a certificate from our certificate storage. */
- if (handler->cert_obtain (id, id_len, 0, &rawcert, &rawcertlen))
- {
- if (handler->id == ISAKMP_CERTENC_X509_SIG)
- {
- cert = handler->cert_get (rawcert, rawcertlen);
- if (!cert)
- LOG_DBG ((LOG_CRYPTO, 50,
- "rsa_sig_decode_hash: certificate malformed"));
- else
- {
- if (!handler->cert_get_key (cert, &key))
- {
- log_print ("rsa_sig_decode_hash: "
- "decoding certificate failed");
- handler->cert_free (cert);
- }
- else
- {
- found++;
- LOG_DBG ((LOG_CRYPTO, 40,
- "rsa_sig_decode_hash: using cert of type %d",
- handler->id));
- exchange->recv_cert = cert;
- exchange->recv_certtype = handler->id;
-#if defined (USE_POLICY)
- x509_generate_kn (exchange->policy_id, cert);
-#endif /* USE_POLICY */
- }
- }
+ if (!id || id_len == 0) {
+ log_print("rsa_sig_decode_hash: ID is missing");
+ return -1;
}
- else if (handler->id == ISAKMP_CERTENC_KEYNOTE)
- handler->cert_insert (exchange->policy_id, rawcert);
- free (rawcert);
- }
-
- /*
- * Walk over potential CERT payloads in this message.
- * XXX I believe this is the wrong spot for this. CERTs can appear
- * anytime.
- */
- for (p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_CERT]); p;
- p = TAILQ_NEXT (p, link))
- {
- p->flags |= PL_MARK;
-
- /* When we have found a key, just walk over the rest, marking them. */
- if (found)
- continue;
-
- handler = cert_get (GET_ISAKMP_CERT_ENCODING (p->p));
- if (!handler)
- {
- LOG_DBG ((LOG_MISC, 30,
- "rsa_sig_decode_hash: no handler for %s CERT encoding",
- constant_name (isakmp_certenc_cst,
- GET_ISAKMP_CERT_ENCODING (p->p))));
- continue;
- }
-
- cert = handler->cert_get (p->p + ISAKMP_CERT_DATA_OFF,
- GET_ISAKMP_GEN_LENGTH (p->p)
- - ISAKMP_CERT_DATA_OFF);
- if (!cert)
- {
- log_print ("rsa_sig_decode_hash: can not get data from CERT");
- continue;
+ /*
+ * XXX Assume we should use the same kind of certification as the remote...
+ * moreover, just use the first CERT payload to decide what to use.
+ */
+ p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT]);
+ if (!p)
+ handler = cert_get(ISAKMP_CERTENC_KEYNOTE);
+ else
+ handler = cert_get(GET_ISAKMP_CERT_ENCODING(p->p));
+ if (!handler) {
+ log_print("rsa_sig_decode_hash: cert_get (%d) failed",
+ p ? GET_ISAKMP_CERT_ENCODING(p->p) : -1);
+ return -1;
}
-
- if (!handler->cert_validate (cert))
- {
- handler->cert_free (cert);
- log_print ("rsa_sig_decode_hash: received CERT can't be validated");
- continue;
- }
-
- if (GET_ISAKMP_CERT_ENCODING (p->p) == ISAKMP_CERTENC_X509_SIG)
- {
- if (!handler->cert_get_subjects (cert, &n, &id_cert, &id_cert_len))
- {
- handler->cert_free (cert);
- log_print ("rsa_sig_decode_hash: can not get subject from CERT");
- continue;
- }
-
- id_found = 0;
- for (i = 0; i < n; i++)
- if (id_cert_len[i] == id_len
- && id[0] == id_cert[i][0]
- && memcmp (id + 4, id_cert[i] + 4, id_len - 4) == 0)
- {
- id_found++;
- break;
- }
- if (!id_found)
- {
- handler->cert_free (cert);
- log_print ("rsa_sig_decode_hash: no CERT subject match the ID");
- free (id_cert);
- continue;
- }
-
- cert_free_subjects (n, id_cert, id_cert_len);
+#if defined (USE_POLICY) || defined (USE_KEYNOTE)
+ /*
+ * We need the policy session initialized now, so we can add
+ * credentials etc.
+ */
+ exchange->policy_id = kn_init();
+ if (exchange->policy_id == -1) {
+ log_print("rsa_sig_decode_hash: failed to initialize policy session");
+ return -1;
}
-
- if (!handler->cert_get_key (cert, &key))
- {
- handler->cert_free (cert);
- log_print ("rsa_sig_decode_hash: decoding payload CERT failed");
- continue;
+#endif /* USE_POLICY || USE_KEYNOTE */
+
+ /* Obtain a certificate from our certificate storage. */
+ if (handler->cert_obtain(id, id_len, 0, &rawcert, &rawcertlen)) {
+ if (handler->id == ISAKMP_CERTENC_X509_SIG) {
+ cert = handler->cert_get(rawcert, rawcertlen);
+ if (!cert)
+ LOG_DBG((LOG_CRYPTO, 50,
+ "rsa_sig_decode_hash: certificate malformed"));
+ else {
+ if (!handler->cert_get_key(cert, &key)) {
+ log_print("rsa_sig_decode_hash: "
+ "decoding certificate failed");
+ handler->cert_free(cert);
+ } else {
+ found++;
+ LOG_DBG((LOG_CRYPTO, 40,
+ "rsa_sig_decode_hash: using cert of type %d",
+ handler->id));
+ exchange->recv_cert = cert;
+ exchange->recv_certtype = handler->id;
+#if defined (USE_POLICY)
+ x509_generate_kn(exchange->policy_id, cert);
+#endif /* USE_POLICY */
+ }
+ }
+ } else if (handler->id == ISAKMP_CERTENC_KEYNOTE)
+ handler->cert_insert(exchange->policy_id, rawcert);
+ free(rawcert);
}
+ /*
+ * Walk over potential CERT payloads in this message.
+ * XXX I believe this is the wrong spot for this. CERTs can appear
+ * anytime.
+ */
+ for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT]); p;
+ p = TAILQ_NEXT(p, link)) {
+ p->flags |= PL_MARK;
+
+ /*
+ * When we have found a key, just walk over the rest, marking
+ * them.
+ */
+ if (found)
+ continue;
+
+ handler = cert_get(GET_ISAKMP_CERT_ENCODING(p->p));
+ if (!handler) {
+ LOG_DBG((LOG_MISC, 30,
+ "rsa_sig_decode_hash: no handler for %s CERT encoding",
+ constant_name(isakmp_certenc_cst,
+ GET_ISAKMP_CERT_ENCODING(p->p))));
+ continue;
+ }
+ cert = handler->cert_get(p->p + ISAKMP_CERT_DATA_OFF,
+ GET_ISAKMP_GEN_LENGTH(p->p) - ISAKMP_CERT_DATA_OFF);
+ if (!cert) {
+ log_print("rsa_sig_decode_hash: can not get data from CERT");
+ continue;
+ }
+ if (!handler->cert_validate(cert)) {
+ handler->cert_free(cert);
+ log_print("rsa_sig_decode_hash: received CERT can't be validated");
+ continue;
+ }
+ if (GET_ISAKMP_CERT_ENCODING(p->p) == ISAKMP_CERTENC_X509_SIG) {
+ if (!handler->cert_get_subjects(cert, &n, &id_cert,
+ &id_cert_len)) {
+ handler->cert_free(cert);
+ log_print("rsa_sig_decode_hash: can not get subject from CERT");
+ continue;
+ }
+ id_found = 0;
+ for (i = 0; i < n; i++)
+ if (id_cert_len[i] == id_len &&
+ id[0] == id_cert[i][0] &&
+ memcmp(id + 4, id_cert[i] + 4, id_len - 4) == 0) {
+ id_found++;
+ break;
+ }
+ if (!id_found) {
+ handler->cert_free(cert);
+ log_print("rsa_sig_decode_hash: no CERT subject match the ID");
+ free(id_cert);
+ continue;
+ }
+ cert_free_subjects(n, id_cert, id_cert_len);
+ }
+ if (!handler->cert_get_key(cert, &key)) {
+ handler->cert_free(cert);
+ log_print("rsa_sig_decode_hash: decoding payload CERT failed");
+ continue;
+ }
+ /* We validated the cert, cache it for later use. */
+ handler->cert_insert(exchange->policy_id, cert);
- /* We validated the cert, cache it for later use. */
- handler->cert_insert (exchange->policy_id, cert);
-
- exchange->recv_cert = cert;
- exchange->recv_certtype = GET_ISAKMP_CERT_ENCODING (p->p);
+ exchange->recv_cert = cert;
+ exchange->recv_certtype = GET_ISAKMP_CERT_ENCODING(p->p);
#if defined (USE_POLICY) || defined (USE_KEYNOTE)
- if (exchange->recv_certtype == ISAKMP_CERTENC_KEYNOTE)
- {
- struct keynote_deckey dc;
- char *pp;
- int dclen;
-
- dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
- dc.dec_key = key;
-
- pp = kn_encode_key (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
- KEYNOTE_PUBLIC_KEY);
- if (pp == NULL)
- {
- kn_free_key (&dc);
- log_print ("rsa_sig_decode_hash: failed to ASCII-encode key");
- return -1;
- }
-
- dclen = strlen (pp) + sizeof "rsa-hex:";
- exchange->keynote_key = calloc (dclen, sizeof (char));
- if (!exchange->keynote_key)
- {
- free (pp);
- kn_free_key (&dc);
- log_print ("rsa_sig_decode_hash: failed to allocate %d bytes",
- dclen);
- return -1;
- }
-
- snprintf (exchange->keynote_key, dclen, "rsa-hex:%s", pp);
- free (pp);
- }
+ if (exchange->recv_certtype == ISAKMP_CERTENC_KEYNOTE) {
+ struct keynote_deckey dc;
+ char *pp;
+ int dclen;
+
+ dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
+ dc.dec_key = key;
+
+ pp = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
+ KEYNOTE_PUBLIC_KEY);
+ if (pp == NULL) {
+ kn_free_key(&dc);
+ log_print("rsa_sig_decode_hash: failed to ASCII-encode key");
+ return -1;
+ }
+ dclen = strlen(pp) + sizeof "rsa-hex:";
+ exchange->keynote_key = calloc(dclen, sizeof(char));
+ if (!exchange->keynote_key) {
+ free(pp);
+ kn_free_key(&dc);
+ log_print("rsa_sig_decode_hash: failed to allocate %d bytes",
+ dclen);
+ return -1;
+ }
+ snprintf(exchange->keynote_key, dclen, "rsa-hex:%s", pp);
+ free(pp);
+ }
#endif
- found++;
- }
+ found++;
+ }
#if defined (USE_DNSSEC)
- /* If no certificate provided a key, try to find a validated DNSSEC KEY. */
- if (!found)
- {
- rawkey = dns_get_key (IKE_AUTH_RSA_SIG, msg, &rawkeylen);
-
- /* We need to convert 'void *rawkey' into 'RSA *key'. */
- if (dns_RSA_dns_to_x509 (rawkey, rawkeylen, &key) == 0)
- found++;
- else
- log_print ("rsa_sig_decode_hash: KEY to RSA key conversion failed");
-
- if (rawkey)
- free (rawkey);
- }
-#endif /* USE_DNSSEC */
+ /*
+ * If no certificate provided a key, try to find a validated DNSSEC
+ * KEY.
+ */
+ if (!found) {
+ rawkey = dns_get_key(IKE_AUTH_RSA_SIG, msg, &rawkeylen);
+
+ /* We need to convert 'void *rawkey' into 'RSA *key'. */
+ if (dns_RSA_dns_to_x509(rawkey, rawkeylen, &key) == 0)
+ found++;
+ else
+ log_print("rsa_sig_decode_hash: KEY to RSA key conversion failed");
+
+ if (rawkey)
+ free(rawkey);
+ }
+#endif /* USE_DNSSEC */
#if defined (USE_RAWKEY)
- /* If we still have not found a key, try to read it from a file. */
- if (!found)
- if (get_raw_key_from_file (IKE_AUTH_RSA_SIG, id, id_len, &key) != -1)
- found++;
+ /* If we still have not found a key, try to read it from a file. */
+ if (!found)
+ if (get_raw_key_from_file(IKE_AUTH_RSA_SIG, id, id_len, &key) != -1)
+ found++;
#endif
- if (!found)
- {
- log_print ("rsa_sig_decode_hash: no public key found");
- return -1;
- }
-
- p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SIG]);
- if (!p)
- {
- log_print ("rsa_sig_decode_hash: missing signature payload");
- RSA_free (key);
- return -1;
- }
-
- /* Check that the sig is of the correct size. */
- len = GET_ISAKMP_GEN_LENGTH (p->p) - ISAKMP_SIG_SZ;
- if (len != RSA_size (key))
- {
- RSA_free (key);
- log_print ("rsa_sig_decode_hash: "
- "SIG payload length does not match public key");
- return -1;
- }
-
- *hash_p = malloc (len);
- if (!*hash_p)
- {
- RSA_free (key);
- log_error ("rsa_sig_decode_hash: malloc (%d) failed", len);
- return -1;
- }
-
- len = RSA_public_decrypt (len, p->p + ISAKMP_SIG_DATA_OFF, *hash_p, key,
- RSA_PKCS1_PADDING);
- if (len == -1)
- {
- RSA_free (key);
- log_print ("rsa_sig_decode_hash: RSA_public_decrypt () failed");
- return -1;
- }
-
- /* Store key for later use */
- exchange->recv_key = key;
- exchange->recv_keytype = ISAKMP_KEY_RSA;
-
- if (len != (int)hashsize)
- {
- free (*hash_p);
- *hash_p = 0;
- log_print ("rsa_sig_decode_hash: len %lu != hashsize %lu",
- (unsigned long)len, (unsigned long)hashsize);
- return -1;
- }
-
- snprintf (header, sizeof header, "rsa_sig_decode_hash: HASH_%c",
+ if (!found) {
+ log_print("rsa_sig_decode_hash: no public key found");
+ return -1;
+ }
+ p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SIG]);
+ if (!p) {
+ log_print("rsa_sig_decode_hash: missing signature payload");
+ RSA_free(key);
+ return -1;
+ }
+ /* Check that the sig is of the correct size. */
+ len = GET_ISAKMP_GEN_LENGTH(p->p) - ISAKMP_SIG_SZ;
+ if (len != RSA_size(key)) {
+ RSA_free(key);
+ log_print("rsa_sig_decode_hash: "
+ "SIG payload length does not match public key");
+ return -1;
+ }
+ *hash_p = malloc(len);
+ if (!*hash_p) {
+ RSA_free(key);
+ log_error("rsa_sig_decode_hash: malloc (%d) failed", len);
+ return -1;
+ }
+ len = RSA_public_decrypt(len, p->p + ISAKMP_SIG_DATA_OFF, *hash_p, key,
+ RSA_PKCS1_PADDING);
+ if (len == -1) {
+ RSA_free(key);
+ log_print("rsa_sig_decode_hash: RSA_public_decrypt () failed");
+ return -1;
+ }
+ /* Store key for later use */
+ exchange->recv_key = key;
+ exchange->recv_keytype = ISAKMP_KEY_RSA;
+
+ if (len != (int) hashsize) {
+ free(*hash_p);
+ *hash_p = 0;
+ log_print("rsa_sig_decode_hash: len %lu != hashsize %lu",
+ (unsigned long) len, (unsigned long) hashsize);
+ return -1;
+ }
+ snprintf(header, sizeof header, "rsa_sig_decode_hash: HASH_%c",
initiator ? 'R' : 'I');
- LOG_DBG_BUF ((LOG_MISC, 80, header, *hash_p, hashsize));
+ LOG_DBG_BUF((LOG_MISC, 80, header, *hash_p, hashsize));
- p->flags |= PL_MARK;
-
- return 0;
+ p->flags |= PL_MARK;
+ return 0;
}
-#endif /* USE_X509 || USE_KEYNOTE */
+#endif /* USE_X509 || USE_KEYNOTE */
static int
-pre_shared_encode_hash (struct message *msg)
+pre_shared_encode_hash(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- size_t hashsize = ie->hash->hashsize;
- char header[80];
- int initiator = exchange->initiator;
- u_int8_t *buf;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ size_t hashsize = ie->hash->hashsize;
+ char header[80];
+ int initiator = exchange->initiator;
+ u_int8_t *buf;
- buf = ipsec_add_hash_payload (msg, hashsize);
- if (!buf)
- return -1;
+ buf = ipsec_add_hash_payload(msg, hashsize);
+ if (!buf)
+ return -1;
- if (ike_auth_hash (exchange, buf + ISAKMP_HASH_DATA_OFF) == -1)
- return -1;
+ if (ike_auth_hash(exchange, buf + ISAKMP_HASH_DATA_OFF) == -1)
+ return -1;
- snprintf (header, sizeof header, "pre_shared_encode_hash: HASH_%c",
+ snprintf(header, sizeof header, "pre_shared_encode_hash: HASH_%c",
initiator ? 'I' : 'R');
- LOG_DBG_BUF ((LOG_MISC, 80, header, buf + ISAKMP_HASH_DATA_OFF, hashsize));
- return 0;
+ LOG_DBG_BUF((LOG_MISC, 80, header, buf + ISAKMP_HASH_DATA_OFF, hashsize));
+ return 0;
}
#if defined (USE_X509) || defined (USE_KEYNOTE)
/* Encrypt the HASH into a SIG type. */
static int
-rsa_sig_encode_hash (struct message *msg)
+rsa_sig_encode_hash(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- size_t hashsize = ie->hash->hashsize;
- struct cert_handler *handler;
- char header[80];
- int initiator = exchange->initiator;
- u_int8_t *buf, *data, *buf2;
- u_int32_t datalen;
- u_int8_t *id;
- size_t id_len;
- int idtype;
- int32_t sigsize;
- void *sent_key;
-
- id = initiator ? exchange->id_i : exchange->id_r;
- id_len = initiator ? exchange->id_i_len : exchange->id_r_len;
-
- /* We may have been provided these by the kernel */
- buf = (u_int8_t *)conf_get_str (exchange->name, "Credentials");
- if (buf
- && (idtype = conf_get_num (exchange->name, "Credential_Type", -1) != -1))
- {
- exchange->sent_certtype = idtype;
- handler = cert_get (idtype);
- if (!handler)
- {
- log_print ("rsa_sig_encode_hash: cert_get (%d) failed", idtype);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ size_t hashsize = ie->hash->hashsize, id_len;
+ struct cert_handler *handler;
+ char header[80];
+ int initiator = exchange->initiator, idtype;
+ u_int8_t *buf, *data, *buf2, *id;
+ u_int32_t datalen;
+ int32_t sigsize;
+ void *sent_key;
+
+ id = initiator ? exchange->id_i : exchange->id_r;
+ id_len = initiator ? exchange->id_i_len : exchange->id_r_len;
+
+ /* We may have been provided these by the kernel */
+ buf = (u_int8_t *) conf_get_str(exchange->name, "Credentials");
+ if (buf &&
+ (idtype = conf_get_num(exchange->name, "Credential_Type", -1) != -1)) {
+ exchange->sent_certtype = idtype;
+ handler = cert_get(idtype);
+ if (!handler) {
+ log_print("rsa_sig_encode_hash: cert_get (%d) failed", idtype);
+ return -1;
+ }
+ exchange->sent_cert = handler->cert_from_printable((char *) buf);
+ if (!exchange->sent_cert) {
+ log_print("rsa_sig_encode_hash: failed to retrieve certificate");
+ return -1;
+ }
+ handler->cert_serialize(exchange->sent_cert, &data, &datalen);
+ if (!data) {
+ log_print("rsa_sig_encode_hash: cert serialization failed");
+ return -1;
+ }
+ goto aftercert; /* Skip all the certificate discovery */
}
-
- exchange->sent_cert = handler->cert_from_printable ((char *)buf);
- if (!exchange->sent_cert)
- {
- log_print ("rsa_sig_encode_hash: failed to retrieve certificate");
- return -1;
+ /* XXX This needs to be configurable. */
+ idtype = ISAKMP_CERTENC_KEYNOTE;
+
+ /* Find a certificate with subjectAltName = id. */
+ handler = cert_get(idtype);
+ if (!handler) {
+ idtype = ISAKMP_CERTENC_X509_SIG;
+ handler = cert_get(idtype);
+ if (!handler) {
+ log_print("rsa_sig_encode_hash: cert_get(%d) failed", idtype);
+ return -1;
+ }
}
-
- handler->cert_serialize (exchange->sent_cert, &data, &datalen);
- if (!data)
- {
- log_print ("rsa_sig_encode_hash: cert serialization failed");
- return -1;
+ if (handler->cert_obtain(id, id_len, 0, &data, &datalen) == 0) {
+ if (idtype == ISAKMP_CERTENC_KEYNOTE) {
+ idtype = ISAKMP_CERTENC_X509_SIG;
+ handler = cert_get(idtype);
+ if (!handler) {
+ log_print("rsa_sig_encode_hash: cert_get(%d) failed",
+ idtype);
+ return -1;
+ }
+ if (handler->cert_obtain(id, id_len, 0, &data, &datalen) == 0) {
+ LOG_DBG((LOG_MISC, 10,
+ "rsa_sig_encode_hash: no certificate to send"));
+ goto skipcert;
+ }
+ } else {
+ LOG_DBG((LOG_MISC, 10,
+ "rsa_sig_encode_hash: no certificate to send"));
+ goto skipcert;
+ }
}
+ /* Let's store the certificate we are going to use */
+ exchange->sent_certtype = idtype;
+ exchange->sent_cert = handler->cert_get(data, datalen);
+ if (!exchange->sent_cert) {
+ free(data);
+ log_print("rsa_sig_encode_hash: failed to get certificate from wire "
+ "encoding");
+ return -1;
+ }
+aftercert:
+
+ buf = realloc(data, ISAKMP_CERT_SZ + datalen);
+ if (!buf) {
+ log_error("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
+ ISAKMP_CERT_SZ + datalen);
+ free(data);
+ return -1;
+ }
+ memmove(buf + ISAKMP_CERT_SZ, buf, datalen);
+ SET_ISAKMP_CERT_ENCODING(buf, idtype);
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT, buf,
+ ISAKMP_CERT_SZ + datalen, 1)) {
+ free(buf);
+ return -1;
+ }
+skipcert:
+
+ /* Again, we may have these from the kernel */
+ buf = (u_int8_t *) conf_get_str(exchange->name, "PKAuthentication");
+ if (buf) {
+ key_from_printable(ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, (char *) buf,
+ &data, &datalen);
+ if (!data) {
+ log_print("rsa_sig_encode_hash: badly formatted RSA private key");
+ return 0;
+ }
+ sent_key = key_internalize(ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE,
+ data, datalen);
+ if (!sent_key) {
+ log_print("rsa_sig_encode_hash: bad RSA private key from dynamic "
+ "SA acquisition subsystem");
+ return 0;
+ }
+ } else {
+ /* Try through the regular means. */
+ switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ]) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa((char **) &buf2,
+ id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] ==
+ IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
+ id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ if (!buf2)
+ return 0;
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ buf2 = calloc(id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
+ sizeof(char));
+ if (!buf2) {
+ log_print("rsa_sig_encode_hash: malloc (%lu) failed",
+ (unsigned long) id_len - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1);
+ return 0;
+ }
+ memcpy(buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
+ break;
+
+ /* XXX Support more ID types? */
+ default:
+ buf2 = 0;
+ return 0;
+ }
- goto aftercert; /* Skip all the certificate discovery */
- }
-
- /* XXX This needs to be configurable. */
- idtype = ISAKMP_CERTENC_KEYNOTE;
+ sent_key = ike_auth_get_key(IKE_AUTH_RSA_SIG, exchange->name,
+ (char *) buf2, 0);
+ free(buf2);
- /* Find a certificate with subjectAltName = id. */
- handler = cert_get (idtype);
- if (!handler)
- {
- idtype = ISAKMP_CERTENC_X509_SIG;
- handler = cert_get (idtype);
- if (!handler)
- {
- log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype);
- return -1;
+ /* Did we find a key? */
+ if (!sent_key) {
+ log_print("rsa_sig_encode_hash: could not get private key");
+ return -1;
+ }
}
- }
- if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0)
- {
- if (idtype == ISAKMP_CERTENC_KEYNOTE)
- {
- idtype = ISAKMP_CERTENC_X509_SIG;
- handler = cert_get (idtype);
- if (!handler)
- {
- log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype);
- return -1;
- }
-
- if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0)
- {
- LOG_DBG ((LOG_MISC, 10,
- "rsa_sig_encode_hash: no certificate to send"));
- goto skipcert;
- }
+ /* Enable RSA blinding. */
+ if (RSA_blinding_on(sent_key, NULL) != 1) {
+ log_error("rsa_sig_encode_hash: RSA_blinding_on () failed.");
+ return -1;
}
- else
- {
- LOG_DBG ((LOG_MISC, 10,
- "rsa_sig_encode_hash: no certificate to send"));
- goto skipcert;
+ /* XXX hashsize is not necessarily prf->blocksize. */
+ buf = malloc(hashsize);
+ if (!buf) {
+ log_error("rsa_sig_encode_hash: malloc (%lu) failed",
+ (unsigned long) hashsize);
+ return -1;
}
- }
-
- /* Let's store the certificate we are going to use */
- exchange->sent_certtype = idtype;
- exchange->sent_cert = handler->cert_get (data, datalen);
- if (!exchange->sent_cert)
- {
- free (data);
- log_print ("rsa_sig_encode_hash: failed to get certificate from wire "
- "encoding");
- return -1;
- }
-
- aftercert:
-
- buf = realloc (data, ISAKMP_CERT_SZ + datalen);
- if (!buf)
- {
- log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
- ISAKMP_CERT_SZ + datalen);
- free (data);
- return -1;
- }
- memmove (buf + ISAKMP_CERT_SZ, buf, datalen);
- SET_ISAKMP_CERT_ENCODING (buf, idtype);
- if (message_add_payload (msg, ISAKMP_PAYLOAD_CERT, buf,
- ISAKMP_CERT_SZ + datalen, 1))
- {
- free (buf);
- return -1;
- }
-
- skipcert:
-
- /* Again, we may have these from the kernel */
- buf = (u_int8_t *)conf_get_str (exchange->name, "PKAuthentication");
- if (buf)
- {
- key_from_printable (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, (char *)buf,
- &data, &datalen);
- if (!data)
- {
- log_print ("rsa_sig_encode_hash: badly formatted RSA private key");
- return 0;
+ if (ike_auth_hash(exchange, buf) == -1) {
+ free(buf);
+ return -1;
}
+ snprintf(header, sizeof header, "rsa_sig_encode_hash: HASH_%c",
+ initiator ? 'I' : 'R');
+ LOG_DBG_BUF((LOG_MISC, 80, header, buf, hashsize));
- sent_key = key_internalize (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, data,
- datalen);
- if (!sent_key)
- {
- log_print ("rsa_sig_encode_hash: bad RSA private key from dynamic "
- "SA acquisition subsystem");
- return 0;
+ data = malloc(RSA_size(sent_key));
+ if (!data) {
+ log_error("rsa_sig_encode_hash: malloc (%d) failed",
+ RSA_size(sent_key));
+ return -1;
}
- }
- else /* Try through the regular means. */
- {
- switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ])
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- util_ntoa ((char **)&buf2,
- id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] == IPSEC_ID_IPV4_ADDR
- ? AF_INET : AF_INET6,
- id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- if (!buf2)
- return 0;
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- buf2 = calloc (id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- sizeof (char));
- if (!buf2)
- {
- log_print ("rsa_sig_encode_hash: malloc (%lu) failed",
- (unsigned long)id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1);
- return 0;
- }
- memcpy (buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
-
- /* XXX Support more ID types? */
- default:
- buf2 = 0;
- return 0;
+ sigsize = RSA_private_encrypt(hashsize, buf, data, sent_key,
+ RSA_PKCS1_PADDING);
+ if (sigsize == -1) {
+ log_print("rsa_sig_encode_hash: RSA_private_encrypt () failed");
+ if (data)
+ free(data);
+ free(buf);
+ RSA_free(sent_key);
+ return -1;
}
+ datalen = (u_int32_t) sigsize;
- sent_key = ike_auth_get_key (IKE_AUTH_RSA_SIG, exchange->name,
- (char *)buf2, 0);
- free (buf2);
+ free(buf);
- /* Did we find a key? */
- if (!sent_key)
- {
- log_print ("rsa_sig_encode_hash: could not get private key");
- return -1;
+ buf = realloc(data, ISAKMP_SIG_SZ + datalen);
+ if (!buf) {
+ log_error("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
+ ISAKMP_SIG_SZ + datalen);
+ free(data);
+ return -1;
}
- }
-
- /* Enable RSA blinding. */
- if (RSA_blinding_on (sent_key, NULL) != 1)
- {
- log_error ("rsa_sig_encode_hash: RSA_blinding_on () failed.");
- return -1;
- }
-
- /* XXX hashsize is not necessarily prf->blocksize. */
- buf = malloc (hashsize);
- if (!buf)
- {
- log_error ("rsa_sig_encode_hash: malloc (%lu) failed",
- (unsigned long)hashsize);
- return -1;
- }
-
- if (ike_auth_hash (exchange, buf) == -1)
- {
- free (buf);
- return -1;
- }
-
- snprintf (header, sizeof header, "rsa_sig_encode_hash: HASH_%c",
- initiator ? 'I' : 'R');
- LOG_DBG_BUF ((LOG_MISC, 80, header, buf, hashsize));
-
- data = malloc (RSA_size (sent_key));
- if (!data)
- {
- log_error ("rsa_sig_encode_hash: malloc (%d) failed",
- RSA_size (sent_key));
- return -1;
- }
-
- sigsize = RSA_private_encrypt (hashsize, buf, data, sent_key,
- RSA_PKCS1_PADDING);
- if (sigsize == -1)
- {
- log_print ("rsa_sig_encode_hash: RSA_private_encrypt () failed");
- if (data)
- free (data);
- free (buf);
- RSA_free (sent_key);
- return -1;
- }
- datalen = (u_int32_t)sigsize;
-
- free (buf);
-
- buf = realloc (data, ISAKMP_SIG_SZ + datalen);
- if (!buf)
- {
- log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
- ISAKMP_SIG_SZ + datalen);
- free (data);
- return -1;
- }
- memmove (buf + ISAKMP_SIG_SZ, buf, datalen);
-
- snprintf (header, sizeof header, "rsa_sig_encode_hash: SIG_%c",
+ memmove(buf + ISAKMP_SIG_SZ, buf, datalen);
+
+ snprintf(header, sizeof header, "rsa_sig_encode_hash: SIG_%c",
initiator ? 'I' : 'R');
- LOG_DBG_BUF ((LOG_MISC, 80, header, buf + ISAKMP_SIG_DATA_OFF, datalen));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_SIG, buf,
- ISAKMP_SIG_SZ + datalen, 1))
- {
- free (buf);
- return -1;
- }
- return 0;
+ LOG_DBG_BUF((LOG_MISC, 80, header, buf + ISAKMP_SIG_DATA_OFF, datalen));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_SIG, buf,
+ ISAKMP_SIG_SZ + datalen, 1)) {
+ free(buf);
+ return -1;
+ }
+ return 0;
}
-#endif /* USE_X509 || USE_KEYNOTE */
+#endif /* USE_X509 || USE_KEYNOTE */
int
-ike_auth_hash (struct exchange *exchange, u_int8_t *buf)
+ike_auth_hash(struct exchange *exchange, u_int8_t *buf)
{
- struct ipsec_exch *ie = exchange->data;
- struct prf *prf;
- struct hash *hash = ie->hash;
- int initiator = exchange->initiator;
- u_int8_t *id;
- size_t id_len;
-
- /* Choose the right fields to fill-in. */
- id = initiator ? exchange->id_i : exchange->id_r;
- id_len = initiator ? exchange->id_i_len : exchange->id_r_len;
-
- /* Allocate the prf and start calculating our HASH. */
- prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
- if (!prf)
- return -1;
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
- prf->Update (prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
- prf->Update (prf->prfctx,
- exchange->cookies
- + (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF),
- ISAKMP_HDR_ICOOKIE_LEN);
- prf->Update (prf->prfctx,
- exchange->cookies
- + (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF),
- ISAKMP_HDR_ICOOKIE_LEN);
- prf->Update (prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
- prf->Update (prf->prfctx, id, id_len);
- prf->Final (buf, prf->prfctx);
- prf_free (prf);
-
- return 0;
+ struct ipsec_exch *ie = exchange->data;
+ struct prf *prf;
+ struct hash *hash = ie->hash;
+ int initiator = exchange->initiator;
+ u_int8_t *id;
+ size_t id_len;
+
+ /* Choose the right fields to fill-in. */
+ id = initiator ? exchange->id_i : exchange->id_r;
+ id_len = initiator ? exchange->id_i_len : exchange->id_r_len;
+
+ /* Allocate the prf and start calculating our HASH. */
+ prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
+ if (!prf)
+ return -1;
+
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
+ prf->Update(prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
+ prf->Update(prf->prfctx, exchange->cookies +
+ (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF),
+ ISAKMP_HDR_ICOOKIE_LEN);
+ prf->Update(prf->prfctx, exchange->cookies +
+ (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF),
+ ISAKMP_HDR_ICOOKIE_LEN);
+ prf->Update(prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
+ prf->Update(prf->prfctx, id, id_len);
+ prf->Final(buf, prf->prfctx);
+ prf_free(prf);
+ return 0;
}
#if defined (USE_RAWKEY)
static int
-get_raw_key_from_file (int type, u_int8_t *id, size_t id_len, RSA **rsa)
+get_raw_key_from_file(int type, u_int8_t *id, size_t id_len, RSA **rsa)
{
- char filename[FILENAME_MAX];
- char *fstr;
- struct stat st;
+ char filename[FILENAME_MAX];
+ char *fstr;
+ struct stat st;
#if defined (USE_PRIVSEP)
- FILE *keyfp;
+ FILE *keyfp;
#else
- BIO *bio;
+ BIO *bio;
#endif
- if (type != IKE_AUTH_RSA_SIG) /* XXX More types? */
- {
- LOG_DBG ((LOG_NEGOTIATION, 20, "get_raw_key_from_file: "
- "invalid auth type %d\n", type));
- return -1;
- }
-
- *rsa = 0;
-
- fstr = conf_get_str ("General", "Pubkey-directory");
- if (!fstr)
- fstr = CONF_DFLT_PUBKEY_DIR;
-
- if (snprintf (filename, sizeof filename, "%s/", fstr)
- > (int)sizeof filename - 1)
- return -1;
-
- fstr = ipsec_id_string (id, id_len);
- if (!fstr)
- {
- LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: "
- "ipsec_id_string failed"));
- return -1;
- }
- strlcat (filename, fstr, sizeof filename - strlen (filename));
- free (fstr);
-
- /* If the file does not exist, fail silently. */
- if (monitor_stat (filename, &st) == 0)
- {
-#if defined (USE_PRIVSEP)
- keyfp = monitor_fopen (filename, "r");
- if (!keyfp)
- {
- log_error ("get_raw_key_from_file: monitor_fopen (\"%s\", \"r\") "
- "failed", filename);
- return -1;
- }
- *rsa = PEM_read_RSA_PUBKEY (keyfp, NULL, NULL, NULL);
- fclose (keyfp);
-#else
- bio = BIO_new (BIO_s_file ());
- if (!bio)
- {
- log_error ("get_raw_key_from_file: could not initialize BIO");
- return -1;
+ if (type != IKE_AUTH_RSA_SIG) { /* XXX More types? */
+ LOG_DBG((LOG_NEGOTIATION, 20, "get_raw_key_from_file: "
+ "invalid auth type %d\n", type));
+ return -1;
}
- if (BIO_read_filename (bio, filename) <= 0)
- {
- LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: "
- "BIO_read_filename(bio, \"%s\") failed", filename));
- BIO_free (bio);
- return -1;
+ *rsa = 0;
+
+ fstr = conf_get_str("General", "Pubkey-directory");
+ if (!fstr)
+ fstr = CONF_DFLT_PUBKEY_DIR;
+
+ if (snprintf(filename, sizeof filename, "%s/", fstr) >
+ (int) sizeof filename - 1)
+ return -1;
+
+ fstr = ipsec_id_string(id, id_len);
+ if (!fstr) {
+ LOG_DBG((LOG_NEGOTIATION, 50, "get_raw_key_from_file: "
+ "ipsec_id_string failed"));
+ return -1;
}
- LOG_DBG ((LOG_NEGOTIATION, 80, "get_raw_key_from_file: reading file %s",
- filename));
- *rsa = PEM_read_bio_RSA_PUBKEY (bio, NULL, NULL, NULL);
- BIO_free (bio);
-#endif /* USE_PRIVSEP */
- }
- else
- LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: file %s not found",
- filename));
-
- return (*rsa ? 0 : -1);
+ strlcat(filename, fstr, sizeof filename - strlen(filename));
+ free(fstr);
+
+ /* If the file does not exist, fail silently. */
+ if (monitor_stat(filename, &st) == 0) {
+#if defined (USE_PRIVSEP)
+ keyfp = monitor_fopen(filename, "r");
+ if (!keyfp) {
+ log_error("get_raw_key_from_file: monitor_fopen (\"%s\", \"r\") "
+ "failed", filename);
+ return -1;
+ }
+ *rsa = PEM_read_RSA_PUBKEY(keyfp, NULL, NULL, NULL);
+ fclose(keyfp);
+#else
+ bio = BIO_new(BIO_s_file());
+ if (!bio) {
+ log_error("get_raw_key_from_file: could not initialize BIO");
+ return -1;
+ }
+ if (BIO_read_filename(bio, filename) <= 0) {
+ LOG_DBG((LOG_NEGOTIATION, 50, "get_raw_key_from_file: "
+ "BIO_read_filename(bio, \"%s\") failed", filename));
+ BIO_free(bio);
+ return -1;
+ }
+ LOG_DBG((LOG_NEGOTIATION, 80,
+ "get_raw_key_from_file: reading file %s", filename));
+ *rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+#endif /* USE_PRIVSEP */
+ } else
+ LOG_DBG((LOG_NEGOTIATION, 50,
+ "get_raw_key_from_file: file %s not found", filename));
+
+ return (*rsa ? 0 : -1);
}
-#endif /* USE_RAWKEY */
+#endif /* USE_RAWKEY */
diff --git a/sbin/isakmpd/ike_auth.h b/sbin/isakmpd/ike_auth.h
index 968bc19b018..39b09230a37 100644
--- a/sbin/isakmpd/ike_auth.h
+++ b/sbin/isakmpd/ike_auth.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_auth.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ike_auth.h,v 1.5 1998/08/16 19:55:24 provos Exp $ */
+/* $OpenBSD: ike_auth.h,v 1.5 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_auth.h,v 1.5 1998/08/16 19:55:24 provos Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -37,12 +37,12 @@
struct exchange;
struct ike_auth {
- u_int16_t id;
- u_int8_t *(*gen_skeyid) (struct exchange *, size_t *);
- int (*decode_hash) (struct message *);
- int (*encode_hash) (struct message *);
+ u_int16_t id;
+ u_int8_t *(*gen_skeyid) (struct exchange *, size_t *);
+ int (*decode_hash) (struct message *);
+ int (*encode_hash) (struct message *);
};
-extern struct ike_auth *ike_auth_get (u_int16_t);
+extern struct ike_auth *ike_auth_get(u_int16_t);
-#endif /* _IKE_AUTH_H_ */
+#endif /* _IKE_AUTH_H_ */
diff --git a/sbin/isakmpd/ike_main_mode.c b/sbin/isakmpd/ike_main_mode.c
index aab8049c655..cff96457079 100644
--- a/sbin/isakmpd/ike_main_mode.c
+++ b/sbin/isakmpd/ike_main_mode.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_main_mode.c,v 1.12 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ike_main_mode.c,v 1.77 1999/04/25 22:12:34 niklas Exp $ */
+/* $OpenBSD: ike_main_mode.c,v 1.13 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_main_mode.c,v 1.77 1999/04/25 22:12:34 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -58,68 +58,68 @@
#include "transport.h"
#include "util.h"
-static int initiator_send_ID_AUTH (struct message *);
-static int responder_send_ID_AUTH (struct message *);
-static int responder_send_KE_NONCE (struct message *);
-
-int (*ike_main_mode_initiator[]) (struct message *) = {
- ike_phase_1_initiator_send_SA,
- ike_phase_1_initiator_recv_SA,
- ike_phase_1_initiator_send_KE_NONCE,
- ike_phase_1_initiator_recv_KE_NONCE,
- initiator_send_ID_AUTH,
- ike_phase_1_recv_ID_AUTH
+static int initiator_send_ID_AUTH(struct message *);
+static int responder_send_ID_AUTH(struct message *);
+static int responder_send_KE_NONCE(struct message *);
+
+int (*ike_main_mode_initiator[]) (struct message *) = {
+ ike_phase_1_initiator_send_SA,
+ ike_phase_1_initiator_recv_SA,
+ ike_phase_1_initiator_send_KE_NONCE,
+ ike_phase_1_initiator_recv_KE_NONCE,
+ initiator_send_ID_AUTH,
+ ike_phase_1_recv_ID_AUTH
};
-int (*ike_main_mode_responder[]) (struct message *) = {
- ike_phase_1_responder_recv_SA,
- ike_phase_1_responder_send_SA,
- ike_phase_1_recv_KE_NONCE,
- responder_send_KE_NONCE,
- ike_phase_1_recv_ID_AUTH,
- responder_send_ID_AUTH
+int (*ike_main_mode_responder[]) (struct message *) = {
+ ike_phase_1_responder_recv_SA,
+ ike_phase_1_responder_send_SA,
+ ike_phase_1_recv_KE_NONCE,
+ responder_send_KE_NONCE,
+ ike_phase_1_recv_ID_AUTH,
+ responder_send_ID_AUTH
};
static int
-initiator_send_ID_AUTH (struct message *msg)
+initiator_send_ID_AUTH(struct message * msg)
{
- msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+ msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
- if (ike_phase_1_send_ID (msg))
- return -1;
+ if (ike_phase_1_send_ID(msg))
+ return -1;
- if (ike_phase_1_send_AUTH (msg))
- return -1;
+ if (ike_phase_1_send_AUTH(msg))
+ return -1;
- return ipsec_initial_contact (msg);
+ return ipsec_initial_contact(msg);
}
/* Send our public DH value and a nonce to the initiator. */
int
-responder_send_KE_NONCE (struct message *msg)
+responder_send_KE_NONCE(struct message * msg)
{
- /* XXX Should we really just use the initiator's nonce size? */
- if (ike_phase_1_send_KE_NONCE (msg, msg->exchange->nonce_i_len))
- return -1;
-
- /*
- * Calculate DH values & key material in parallel with the message going
- * on a roundtrip over the wire.
- */
- message_register_post_send (msg,
- (void (*) (struct message *))
- ike_phase_1_post_exchange_KE_NONCE);
-
- return 0;
+ /* XXX Should we really just use the initiator's nonce size? */
+ if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
+ return -1;
+
+ /*
+ * Calculate DH values & key material in parallel with the message going
+ * on a roundtrip over the wire.
+ */
+ message_register_post_send(msg,
+ (void (*) (struct message *))
+ ike_phase_1_post_exchange_KE_NONCE);
+
+ return 0;
}
static int
-responder_send_ID_AUTH (struct message *msg)
+responder_send_ID_AUTH(struct message * msg)
{
- msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+ msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
- if (ike_phase_1_responder_send_ID_AUTH (msg))
- return -1;
+ if (ike_phase_1_responder_send_ID_AUTH(msg))
+ return -1;
- return ipsec_initial_contact (msg);
+ return ipsec_initial_contact(msg);
}
diff --git a/sbin/isakmpd/ike_main_mode.h b/sbin/isakmpd/ike_main_mode.h
index 72be932325e..0ad9e532f97 100644
--- a/sbin/isakmpd/ike_main_mode.h
+++ b/sbin/isakmpd/ike_main_mode.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_main_mode.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ike_main_mode.h,v 1.1 1998/07/25 11:22:07 niklas Exp $ */
+/* $OpenBSD: ike_main_mode.h,v 1.5 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_main_mode.h,v 1.1 1998/07/25 11:22:07 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -34,7 +34,7 @@
struct message;
-extern int (*ike_main_mode_initiator[]) (struct message *msg);
-extern int (*ike_main_mode_responder[]) (struct message *msg);
+extern int (*ike_main_mode_initiator[]) (struct message * msg);
+extern int (*ike_main_mode_responder[]) (struct message * msg);
-#endif /* _IKE_MAIN_MODE_H_ */
+#endif /* _IKE_MAIN_MODE_H_ */
diff --git a/sbin/isakmpd/ike_phase_1.c b/sbin/isakmpd/ike_phase_1.c
index eaec3956272..a2c2b953643 100644
--- a/sbin/isakmpd/ike_phase_1.c
+++ b/sbin/isakmpd/ike_phase_1.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_phase_1.c,v 1.45 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */
+/* $OpenBSD: ike_phase_1.c,v 1.46 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */
/*
* Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -60,402 +60,372 @@
#include "transport.h"
#include "util.h"
-static int attribute_unacceptable (u_int16_t, u_int8_t *, u_int16_t, void *);
-static int ike_phase_1_validate_prop (struct exchange *, struct sa *,
- struct sa *);
+static int attribute_unacceptable(u_int16_t, u_int8_t *, u_int16_t, void *);
+static int ike_phase_1_validate_prop(struct exchange *, struct sa *,
+ struct sa *);
/* Offer a set of transforms to the responder in the MSG message. */
int
-ike_phase_1_initiator_send_SA (struct message *msg)
+ike_phase_1_initiator_send_SA(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr;
- u_int8_t **transform = 0;
- size_t transforms_len = 0, proposal_len, sa_len;
- size_t *transform_len = 0;
- struct conf_list *conf, *life_conf;
- struct conf_list_node *xf, *life;
- int value, update_nextp;
- size_t i;
- struct payload *p;
- struct proto *proto;
- struct proto_attr *pa;
- int group_desc = -1, new_group_desc;
-
- /* Get the list of transforms. */
- conf = conf_get_list (exchange->policy, "Transforms");
- if (!conf)
- return -1;
-
- transform = calloc (conf->cnt, sizeof *transform);
- if (!transform)
- {
- log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed",
- conf->cnt, (unsigned long)sizeof *transform);
- goto bail_out;
- }
-
- transform_len = calloc (conf->cnt, sizeof *transform_len);
- if (!transform_len)
- {
- log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed",
- conf->cnt, (unsigned long)sizeof *transform_len);
- goto bail_out;
- }
-
- for (xf = TAILQ_FIRST (&conf->fields), i = 0; i < conf->cnt;
- i++, xf = TAILQ_NEXT (xf, link))
- {
- /* XXX The sizing needs to be dynamic. */
- transform[i]
- = malloc (ISAKMP_TRANSFORM_SA_ATTRS_OFF + 16 * ISAKMP_ATTR_VALUE_OFF);
- if (!transform[i])
- {
- log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed",
- ISAKMP_TRANSFORM_SA_ATTRS_OFF
- + 16 * ISAKMP_ATTR_VALUE_OFF);
- goto bail_out;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr;
+ u_int8_t **transform = 0;
+ size_t transforms_len = 0, proposal_len, sa_len;
+ size_t *transform_len = 0;
+ struct conf_list *conf, *life_conf;
+ struct conf_list_node *xf, *life;
+ int value, update_nextp;
+ size_t i;
+ struct payload *p;
+ struct proto *proto;
+ struct proto_attr *pa;
+ int group_desc = -1, new_group_desc;
+
+ /* Get the list of transforms. */
+ conf = conf_get_list(exchange->policy, "Transforms");
+ if (!conf)
+ return -1;
+
+ transform = calloc(conf->cnt, sizeof *transform);
+ if (!transform) {
+ log_error("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed",
+ conf->cnt, (unsigned long) sizeof *transform);
+ goto bail_out;
}
-
- SET_ISAKMP_TRANSFORM_NO (transform[i], i);
- SET_ISAKMP_TRANSFORM_ID (transform[i], IPSEC_TRANSFORM_KEY_IKE);
- SET_ISAKMP_TRANSFORM_RESERVED (transform[i], 0);
-
- attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
-
- if (attribute_set_constant (xf->field, "ENCRYPTION_ALGORITHM",
- ike_encrypt_cst,
- IKE_ATTR_ENCRYPTION_ALGORITHM, &attr))
- goto bail_out;
-
- if (attribute_set_constant (xf->field, "HASH_ALGORITHM", ike_hash_cst,
- IKE_ATTR_HASH_ALGORITHM, &attr))
- goto bail_out;
-
- if (attribute_set_constant (xf->field, "AUTHENTICATION_METHOD",
- ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD,
- &attr))
- goto bail_out;
-
- if (attribute_set_constant (xf->field, "GROUP_DESCRIPTION",
- ike_group_desc_cst,
- IKE_ATTR_GROUP_DESCRIPTION, &attr))
- {
- /*
- * If no group description exists, try looking for a user-defined
- * one.
- */
- if (attribute_set_constant (xf->field, "GROUP_TYPE", ike_group_cst,
- IKE_ATTR_GROUP_TYPE, &attr))
- goto bail_out;
+ transform_len = calloc(conf->cnt, sizeof *transform_len);
+ if (!transform_len) {
+ log_error("ike_phase_1_initiator_send_SA: calloc (%d, %lu) failed",
+ conf->cnt, (unsigned long) sizeof *transform_len);
+ goto bail_out;
+ }
+ for (xf = TAILQ_FIRST(&conf->fields), i = 0; i < conf->cnt;
+ i++, xf = TAILQ_NEXT(xf, link)) {
+ /* XXX The sizing needs to be dynamic. */
+ transform[i] = malloc(ISAKMP_TRANSFORM_SA_ATTRS_OFF +
+ 16 * ISAKMP_ATTR_VALUE_OFF);
+ if (!transform[i]) {
+ log_error("ike_phase_1_initiator_send_SA: malloc (%d) failed",
+ ISAKMP_TRANSFORM_SA_ATTRS_OFF +
+ 16 * ISAKMP_ATTR_VALUE_OFF);
+ goto bail_out;
+ }
+ SET_ISAKMP_TRANSFORM_NO(transform[i], i);
+ SET_ISAKMP_TRANSFORM_ID(transform[i], IPSEC_TRANSFORM_KEY_IKE);
+ SET_ISAKMP_TRANSFORM_RESERVED(transform[i], 0);
+
+ attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
+
+ if (attribute_set_constant(xf->field, "ENCRYPTION_ALGORITHM",
+ ike_encrypt_cst, IKE_ATTR_ENCRYPTION_ALGORITHM, &attr))
+ goto bail_out;
+
+ if (attribute_set_constant(xf->field, "HASH_ALGORITHM",
+ ike_hash_cst, IKE_ATTR_HASH_ALGORITHM, &attr))
+ goto bail_out;
+
+ if (attribute_set_constant(xf->field, "AUTHENTICATION_METHOD",
+ ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD, &attr))
+ goto bail_out;
+
+ if (attribute_set_constant(xf->field, "GROUP_DESCRIPTION",
+ ike_group_desc_cst, IKE_ATTR_GROUP_DESCRIPTION, &attr)) {
+ /*
+ * If no group description exists, try looking for
+ * a user-defined one.
+ */
+ if (attribute_set_constant(xf->field, "GROUP_TYPE",
+ ike_group_cst, IKE_ATTR_GROUP_TYPE, &attr))
+ goto bail_out;
#if 0
- if (attribute_set_bignum (xf->field, "GROUP_PRIME",
- IKE_ATTR_GROUP_PRIME, &attr))
- goto bail_out;
+ if (attribute_set_bignum(xf->field, "GROUP_PRIME",
+ IKE_ATTR_GROUP_PRIME, &attr))
+ goto bail_out;
- if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2",
- IKE_ATTR_GROUP_GENERATOR_2, &attr))
- goto bail_out;
+ if (attribute_set_bignum(xf->field, "GROUP_GENERATOR_2",
+ IKE_ATTR_GROUP_GENERATOR_2, &attr))
+ goto bail_out;
- if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2",
- IKE_ATTR_GROUP_GENERATOR_2, &attr))
- goto bail_out;
+ if (attribute_set_bignum(xf->field, "GROUP_GENERATOR_2",
+ IKE_ATTR_GROUP_GENERATOR_2, &attr))
+ goto bail_out;
- if (attribute_set_bignum (xf->field, "GROUP_CURVE_A",
- IKE_ATTR_GROUP_CURVE_A, &attr))
- goto bail_out;
+ if (attribute_set_bignum(xf->field, "GROUP_CURVE_A",
+ IKE_ATTR_GROUP_CURVE_A, &attr))
+ goto bail_out;
- if (attribute_set_bignum (xf->field, "GROUP_CURVE_B",
- IKE_ATTR_GROUP_CURVE_B, &attr))
- goto bail_out;
+ if (attribute_set_bignum(xf->field, "GROUP_CURVE_B",
+ IKE_ATTR_GROUP_CURVE_B, &attr))
+ goto bail_out;
#endif
+ }
+ /*
+ * Life durations are special, we should be able to specify
+ * several, one per type.
+ */
+ life_conf = conf_get_list(xf->field, "Life");
+ if (life_conf) {
+ for (life = TAILQ_FIRST(&life_conf->fields); life;
+ life = TAILQ_NEXT(life, link)) {
+ attribute_set_constant(life->field, "LIFE_TYPE",
+ ike_duration_cst, IKE_ATTR_LIFE_TYPE, &attr);
+
+ /*
+ * XXX Deals with 16 and 32 bit lifetimes
+ * only
+ */
+ value = conf_get_num(life->field, "LIFE_DURATION", 0);
+ if (value) {
+ if (value <= 0xffff)
+ attr = attribute_set_basic(attr,
+ IKE_ATTR_LIFE_DURATION, value);
+ else {
+ value = htonl(value);
+ attr = attribute_set_var(attr,
+ IKE_ATTR_LIFE_DURATION,
+ (u_int8_t *)&value,
+ sizeof value);
+ }
+ }
+ }
+ conf_free_list(life_conf);
+ }
+ attribute_set_constant(xf->field, "PRF", ike_prf_cst,
+ IKE_ATTR_PRF, &attr);
+
+ value = conf_get_num(xf->field, "KEY_LENGTH", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IKE_ATTR_KEY_LENGTH, value);
+
+ value = conf_get_num(xf->field, "FIELD_SIZE", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IKE_ATTR_FIELD_SIZE, value);
+
+ value = conf_get_num(xf->field, "GROUP_ORDER", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IKE_ATTR_GROUP_ORDER, value);
+
+ /* Record the real transform size. */
+ transforms_len += transform_len[i] = attr - transform[i];
+
+ /* XXX I don't like exchange-specific stuff in here. */
+ if (exchange->type == ISAKMP_EXCH_AGGRESSIVE) {
+ /*
+ * Make sure that if a group description is specified, it is
+ * specified for all transforms equally.
+ */
+ attr = (u_int8_t *) conf_get_str(xf->field, "GROUP_DESCRIPTION");
+ new_group_desc = attr ? constant_value(ike_group_desc_cst,
+ (char *) attr) : 0;
+ if (group_desc == -1)
+ group_desc = new_group_desc;
+ else if (group_desc != new_group_desc) {
+ log_print("ike_phase_1_initiator_send_SA: "
+ "differing group descriptions in a proposal");
+ goto bail_out;
+ }
+ }
+ /*
+ * We need to check that we actually support our
+ * configuration.
+ */
+ if (attribute_map(transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ exchange->doi->is_attribute_incompatible, msg)) {
+ log_print("ike_phase_1_initiator_send_SA: "
+ "section [%s] has unsupported attribute(s)",
+ xf->field);
+ goto bail_out;
+ }
}
- /*
- * Life durations are special, we should be able to specify
- * several, one per type.
- */
- life_conf = conf_get_list (xf->field, "Life");
- if (life_conf)
- {
- for (life = TAILQ_FIRST (&life_conf->fields); life;
- life = TAILQ_NEXT (life, link))
- {
- attribute_set_constant (life->field, "LIFE_TYPE",
- ike_duration_cst, IKE_ATTR_LIFE_TYPE,
- &attr);
-
- /* XXX Deals with 16 and 32 bit lifetimes only */
- value = conf_get_num (life->field, "LIFE_DURATION", 0);
- if (value)
- {
- if (value <= 0xffff)
- attr = attribute_set_basic (attr, IKE_ATTR_LIFE_DURATION,
- value);
- else
- {
- value = htonl (value);
- attr = attribute_set_var (attr, IKE_ATTR_LIFE_DURATION,
- (u_int8_t *)&value,
- sizeof value);
- }
- }
- }
- conf_free_list (life_conf);
- }
+ /* XXX I don't like exchange-specific stuff in here. */
+ if (exchange->type == ISAKMP_EXCH_AGGRESSIVE)
+ ie->group = group_get(group_desc);
- attribute_set_constant (xf->field, "PRF", ike_prf_cst, IKE_ATTR_PRF,
- &attr);
-
- value = conf_get_num (xf->field, "KEY_LENGTH", 0);
- if (value)
- attr = attribute_set_basic (attr, IKE_ATTR_KEY_LENGTH, value);
-
- value = conf_get_num (xf->field, "FIELD_SIZE", 0);
- if (value)
- attr = attribute_set_basic (attr, IKE_ATTR_FIELD_SIZE, value);
-
- value = conf_get_num (xf->field, "GROUP_ORDER", 0);
- if (value)
- attr = attribute_set_basic (attr, IKE_ATTR_GROUP_ORDER, value);
-
- /* Record the real transform size. */
- transforms_len += transform_len[i] = attr - transform[i];
-
- /* XXX I don't like exchange-specific stuff in here. */
- if (exchange->type == ISAKMP_EXCH_AGGRESSIVE)
- {
- /*
- * Make sure that if a group description is specified, it is
- * specified for all transforms equally.
- */
- attr = (u_int8_t *)conf_get_str (xf->field, "GROUP_DESCRIPTION");
- new_group_desc
- = attr ? constant_value (ike_group_desc_cst, (char *)attr) : 0;
- if (group_desc == -1)
- group_desc = new_group_desc;
- else if (group_desc != new_group_desc)
- {
- log_print ("ike_phase_1_initiator_send_SA: "
- "differing group descriptions in a proposal");
- goto bail_out;
- }
+ proposal_len = ISAKMP_PROP_SPI_OFF;
+ proposal = malloc(proposal_len);
+ if (!proposal) {
+ log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
+ (unsigned long) proposal_len);
+ goto bail_out;
}
-
- /* We need to check that we actually support our configuration. */
- if (attribute_map (transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- exchange->doi->is_attribute_incompatible, msg))
- {
- log_print ("ike_phase_1_initiator_send_SA: "
- "section [%s] has unsupported attribute(s)",
- xf->field);
- goto bail_out;
+ SET_ISAKMP_PROP_NO(proposal, 1);
+ SET_ISAKMP_PROP_PROTO(proposal, ISAKMP_PROTO_ISAKMP);
+ SET_ISAKMP_PROP_SPI_SZ(proposal, 0);
+ SET_ISAKMP_PROP_NTRANSFORMS(proposal, conf->cnt);
+
+ /* XXX I would like to see this factored out. */
+ proto = calloc(1, sizeof *proto);
+ if (!proto) {
+ log_error("ike_phase_1_initiator_send_SA: calloc (1, %lu) failed",
+ (unsigned long) sizeof *proto);
+ goto bail_out;
}
- }
-
- /* XXX I don't like exchange-specific stuff in here. */
- if (exchange->type == ISAKMP_EXCH_AGGRESSIVE)
- ie->group = group_get (group_desc);
-
- proposal_len = ISAKMP_PROP_SPI_OFF;
- proposal = malloc (proposal_len);
- if (!proposal)
- {
- log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
- (unsigned long)proposal_len);
- goto bail_out;
- }
-
- SET_ISAKMP_PROP_NO (proposal, 1);
- SET_ISAKMP_PROP_PROTO (proposal, ISAKMP_PROTO_ISAKMP);
- SET_ISAKMP_PROP_SPI_SZ (proposal, 0);
- SET_ISAKMP_PROP_NTRANSFORMS (proposal, conf->cnt);
-
- /* XXX I would like to see this factored out. */
- proto = calloc (1, sizeof *proto);
- if (!proto)
- {
- log_error ("ike_phase_1_initiator_send_SA: calloc (1, %lu) failed",
- (unsigned long)sizeof *proto);
- goto bail_out;
- }
-
- proto->no = 1;
- proto->proto = ISAKMP_PROTO_ISAKMP;
- proto->sa = TAILQ_FIRST (&exchange->sa_list);
- proto->xf_cnt = conf->cnt;
- TAILQ_INIT (&proto->xfs);
- for (i = 0; i < proto->xf_cnt; i++)
- {
- pa = (struct proto_attr *)calloc (1, sizeof *pa);
- if (!pa)
- goto bail_out;
- pa->len = transform_len[i];
- pa->attrs = (u_int8_t *)malloc (pa->len);
- if (!pa->attrs)
- {
- free (pa);
- goto bail_out;
+ proto->no = 1;
+ proto->proto = ISAKMP_PROTO_ISAKMP;
+ proto->sa = TAILQ_FIRST(&exchange->sa_list);
+ proto->xf_cnt = conf->cnt;
+ TAILQ_INIT(&proto->xfs);
+ for (i = 0; i < proto->xf_cnt; i++) {
+ pa = (struct proto_attr *) calloc(1, sizeof *pa);
+ if (!pa)
+ goto bail_out;
+ pa->len = transform_len[i];
+ pa->attrs = (u_int8_t *) malloc(pa->len);
+ if (!pa->attrs) {
+ free(pa);
+ goto bail_out;
+ }
+ memcpy(pa->attrs, transform[i], pa->len);
+ TAILQ_INSERT_TAIL(&proto->xfs, pa, next);
+ }
+ TAILQ_INSERT_TAIL(&TAILQ_FIRST(&exchange->sa_list)->protos, proto, link);
+
+ sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN;
+ sa_buf = malloc(sa_len);
+ if (!sa_buf) {
+ log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
+ (unsigned long) sa_len);
+ goto bail_out;
+ }
+ SET_ISAKMP_SA_DOI(sa_buf, IPSEC_DOI_IPSEC);
+ SET_IPSEC_SIT_SIT(sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
+
+ /*
+ * Add the payloads. As this is a SA, we need to recompute the
+ * lengths of the payloads containing others.
+ */
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
+ goto bail_out;
+ SET_ISAKMP_GEN_LENGTH(sa_buf,
+ sa_len + proposal_len + transforms_len);
+ sa_buf = 0;
+
+ saved_nextp = msg->nextp;
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL, proposal,
+ proposal_len, 0))
+ goto bail_out;
+ SET_ISAKMP_GEN_LENGTH(proposal, proposal_len + transforms_len);
+ proposal = 0;
+
+ update_nextp = 0;
+ for (i = 0; i < conf->cnt; i++) {
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM, transform[i],
+ transform_len[i], update_nextp))
+ goto bail_out;
+ update_nextp = 1;
+ transform[i] = 0;
+ }
+ msg->nextp = saved_nextp;
+
+ /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. */
+ ie->sa_i_b_len = sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ;
+ ie->sa_i_b = malloc(ie->sa_i_b_len);
+ if (!ie->sa_i_b) {
+ log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
+ (unsigned long) ie->sa_i_b_len);
+ goto bail_out;
}
- memcpy (pa->attrs, transform[i], pa->len);
- TAILQ_INSERT_TAIL (&proto->xfs, pa, next);
- }
- TAILQ_INSERT_TAIL (&TAILQ_FIRST (&exchange->sa_list)->protos, proto, link);
-
- sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN;
- sa_buf = malloc (sa_len);
- if (!sa_buf)
- {
- log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
- (unsigned long)sa_len);
- goto bail_out;
- }
-
- SET_ISAKMP_SA_DOI (sa_buf, IPSEC_DOI_IPSEC);
- SET_IPSEC_SIT_SIT (sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
-
- /*
- * Add the payloads. As this is a SA, we need to recompute the
- * lengths of the payloads containing others.
- */
- if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
- goto bail_out;
- SET_ISAKMP_GEN_LENGTH (sa_buf,
- sa_len + proposal_len + transforms_len);
- sa_buf = 0;
-
- saved_nextp = msg->nextp;
- if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposal,
- proposal_len, 0))
- goto bail_out;
- SET_ISAKMP_GEN_LENGTH (proposal, proposal_len + transforms_len);
- proposal = 0;
-
- update_nextp = 0;
- for (i = 0; i < conf->cnt; i++)
- {
- if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM, transform[i],
- transform_len[i], update_nextp))
- goto bail_out;
- update_nextp = 1;
- transform[i] = 0;
- }
- msg->nextp = saved_nextp;
-
- /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. */
- ie->sa_i_b_len = sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ;
- ie->sa_i_b = malloc (ie->sa_i_b_len);
- if (!ie->sa_i_b)
- {
- log_error ("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
- (unsigned long)ie->sa_i_b_len);
- goto bail_out;
- }
- memcpy (ie->sa_i_b,
- TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ,
- sa_len - ISAKMP_GEN_SZ);
- memcpy (ie->sa_i_b + sa_len - ISAKMP_GEN_SZ,
- TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p,
- proposal_len);
- transforms_len = 0;
- for (i = 0, p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
- i < conf->cnt; i++, p = TAILQ_NEXT (p, link))
- {
- memcpy (ie->sa_i_b + sa_len + proposal_len + transforms_len
- - ISAKMP_GEN_SZ,
- p->p, transform_len[i]);
- transforms_len += transform_len[i];
- }
-
- conf_free_list (conf);
- free (transform);
- free (transform_len);
- return 0;
-
- bail_out:
- if (sa_buf)
- free (sa_buf);
- if (proposal)
- free (proposal);
- if (transform)
- {
- for (i = 0; i < conf->cnt; i++)
- if (transform[i])
- free (transform[i]);
- free (transform);
- }
- if (transform_len)
- free (transform_len);
- conf_free_list (conf);
- return -1;
+ memcpy(ie->sa_i_b,
+ TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ,
+ sa_len - ISAKMP_GEN_SZ);
+ memcpy(ie->sa_i_b + sa_len - ISAKMP_GEN_SZ,
+ TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p,
+ proposal_len);
+ transforms_len = 0;
+ for (i = 0, p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
+ i < conf->cnt; i++, p = TAILQ_NEXT(p, link)) {
+ memcpy(ie->sa_i_b + sa_len + proposal_len + transforms_len -
+ ISAKMP_GEN_SZ, p->p, transform_len[i]);
+ transforms_len += transform_len[i];
+ }
+
+ conf_free_list(conf);
+ free(transform);
+ free(transform_len);
+ return 0;
+
+bail_out:
+ if (sa_buf)
+ free(sa_buf);
+ if (proposal)
+ free(proposal);
+ if (transform) {
+ for (i = 0; i < conf->cnt; i++)
+ if (transform[i])
+ free(transform[i]);
+ free(transform);
+ }
+ if (transform_len)
+ free(transform_len);
+ conf_free_list(conf);
+ return -1;
}
/* Figure out what transform the responder chose. */
int
-ike_phase_1_initiator_recv_SA (struct message *msg)
+ike_phase_1_initiator_recv_SA(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct sa *sa = TAILQ_FIRST (&exchange->sa_list);
- struct ipsec_exch *ie = exchange->data;
- struct ipsec_sa *isa = sa->data;
- struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]);
- struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
- struct payload *xf = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
-
- /*
- * IKE requires that only one SA with only one proposal exists and since
- * we are getting an answer on our transform offer, only one transform.
- */
- if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link)
- || TAILQ_NEXT (xf, link))
- {
- log_print ("ike_phase_1_initiator_recv_SA: "
- "multiple SA, proposal or transform payloads in phase 1");
- /* XXX Is there a better notification type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- /* Check that the chosen transform matches an offer. */
- if (message_negotiate_sa (msg, ike_phase_1_validate_prop)
- || !TAILQ_FIRST (&sa->protos))
- return -1;
-
- ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos), xf->p);
-
- /* XXX I don't like exchange-specific stuff in here. */
- if (exchange->type != ISAKMP_EXCH_AGGRESSIVE)
- ie->group = group_get (isa->group_desc);
-
- /* Mark the SA as handled. */
- sa_p->flags |= PL_MARK;
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct sa *sa = TAILQ_FIRST(&exchange->sa_list);
+ struct ipsec_exch *ie = exchange->data;
+ struct ipsec_sa *isa = sa->data;
+ struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]);
+ struct payload *prop = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
+ struct payload *xf = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
+
+ /*
+ * IKE requires that only one SA with only one proposal exists and since
+ * we are getting an answer on our transform offer, only one transform.
+ */
+ if (TAILQ_NEXT(sa_p, link) || TAILQ_NEXT(prop, link) ||
+ TAILQ_NEXT(xf, link)) {
+ log_print("ike_phase_1_initiator_recv_SA: "
+ "multiple SA, proposal or transform payloads in phase 1");
+ /* XXX Is there a better notification type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ /* Check that the chosen transform matches an offer. */
+ if (message_negotiate_sa(msg, ike_phase_1_validate_prop) ||
+ !TAILQ_FIRST(&sa->protos))
+ return -1;
+
+ ipsec_decode_transform(msg, sa, TAILQ_FIRST(&sa->protos), xf->p);
+
+ /* XXX I don't like exchange-specific stuff in here. */
+ if (exchange->type != ISAKMP_EXCH_AGGRESSIVE)
+ ie->group = group_get(isa->group_desc);
+
+ /* Mark the SA as handled. */
+ sa_p->flags |= PL_MARK;
+
+ return 0;
}
/* Send our public DH value and a nonce to the responder. */
int
-ike_phase_1_initiator_send_KE_NONCE (struct message *msg)
+ike_phase_1_initiator_send_KE_NONCE(struct message * msg)
{
- struct ipsec_exch *ie = msg->exchange->data;
+ struct ipsec_exch *ie = msg->exchange->data;
- ie->g_x_len = dh_getlen (ie->group);
+ ie->g_x_len = dh_getlen(ie->group);
- /* XXX I want a better way to specify the nonce's size. */
- return ike_phase_1_send_KE_NONCE (msg, 16);
+ /* XXX I want a better way to specify the nonce's size. */
+ return ike_phase_1_send_KE_NONCE(msg, 16);
}
/* Accept responder's public DH value and nonce. */
int
-ike_phase_1_initiator_recv_KE_NONCE (struct message *msg)
+ike_phase_1_initiator_recv_KE_NONCE(struct message * msg)
{
- if (ike_phase_1_recv_KE_NONCE (msg))
- return -1;
+ if (ike_phase_1_recv_KE_NONCE(msg))
+ return -1;
- return ike_phase_1_post_exchange_KE_NONCE (msg);
+ return ike_phase_1_post_exchange_KE_NONCE(msg);
}
/*
@@ -463,126 +433,108 @@ ike_phase_1_initiator_recv_KE_NONCE (struct message *msg)
* handle.
*/
int
-ike_phase_1_responder_recv_SA (struct message *msg)
+ike_phase_1_responder_recv_SA(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct sa *sa = TAILQ_FIRST (&exchange->sa_list);
- struct ipsec_sa *isa = sa->data;
- struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]);
- struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
- struct ipsec_exch *ie = exchange->data;
-
- /* Mark the SA as handled. */
- sa_p->flags |= PL_MARK;
-
- /* IKE requires that only one SA with only one proposal exists. */
- if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link))
- {
- log_print ("ike_phase_1_responder_recv_SA: "
- "multiple SA or proposal payloads in phase 1");
- /* XXX Is there a better notification type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- /* Chose a transform from the SA. */
- if (message_negotiate_sa (msg, ike_phase_1_validate_prop)
- || !TAILQ_FIRST (&sa->protos))
- return -1;
-
- /* XXX Move into message_negotiate_sa? */
- ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos),
- TAILQ_FIRST (&sa->protos)->chosen->p);
-
- ie->group = group_get (isa->group_desc);
-
- /*
- * Check that the mandatory attributes: encryption, hash, authentication
- * method and Diffie-Hellman group description, has been supplied.
- */
- if (!exchange->crypto || !ie->hash || !ie->ike_auth || !ie->group)
- {
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- /* Save the body for later hash computation. */
- ie->sa_i_b_len = GET_ISAKMP_GEN_LENGTH (sa_p->p) - ISAKMP_GEN_SZ;
- ie->sa_i_b = malloc (ie->sa_i_b_len);
- if (!ie->sa_i_b)
- {
- /* XXX How to notify peer? */
- log_error ("ike_phase_1_responder_recv_SA: malloc (%lu) failed",
- (unsigned long)ie->sa_i_b_len);
- return -1;
- }
- memcpy (ie->sa_i_b, sa_p->p + ISAKMP_GEN_SZ, ie->sa_i_b_len);
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct sa *sa = TAILQ_FIRST(&exchange->sa_list);
+ struct ipsec_sa *isa = sa->data;
+ struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]);
+ struct payload *prop = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
+ struct ipsec_exch *ie = exchange->data;
+
+ /* Mark the SA as handled. */
+ sa_p->flags |= PL_MARK;
+
+ /* IKE requires that only one SA with only one proposal exists. */
+ if (TAILQ_NEXT(sa_p, link) || TAILQ_NEXT(prop, link)) {
+ log_print("ike_phase_1_responder_recv_SA: "
+ "multiple SA or proposal payloads in phase 1");
+ /* XXX Is there a better notification type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ /* Chose a transform from the SA. */
+ if (message_negotiate_sa(msg, ike_phase_1_validate_prop) ||
+ !TAILQ_FIRST(&sa->protos))
+ return -1;
+
+ /* XXX Move into message_negotiate_sa? */
+ ipsec_decode_transform(msg, sa, TAILQ_FIRST(&sa->protos),
+ TAILQ_FIRST(&sa->protos)->chosen->p);
+
+ ie->group = group_get(isa->group_desc);
+
+ /*
+ * Check that the mandatory attributes: encryption, hash, authentication
+ * method and Diffie-Hellman group description, has been supplied.
+ */
+ if (!exchange->crypto || !ie->hash || !ie->ike_auth || !ie->group) {
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ /* Save the body for later hash computation. */
+ ie->sa_i_b_len = GET_ISAKMP_GEN_LENGTH(sa_p->p) - ISAKMP_GEN_SZ;
+ ie->sa_i_b = malloc(ie->sa_i_b_len);
+ if (!ie->sa_i_b) {
+ /* XXX How to notify peer? */
+ log_error("ike_phase_1_responder_recv_SA: malloc (%lu) failed",
+ (unsigned long) ie->sa_i_b_len);
+ return -1;
+ }
+ memcpy(ie->sa_i_b, sa_p->p + ISAKMP_GEN_SZ, ie->sa_i_b_len);
+ return 0;
}
/* Reply with the transform we chose. */
int
-ike_phase_1_responder_send_SA (struct message *msg)
+ike_phase_1_responder_send_SA(struct message * msg)
{
- /* Add the SA payload with the transform that was chosen. */
- return message_add_sa_payload (msg);
+ /* Add the SA payload with the transform that was chosen. */
+ return message_add_sa_payload(msg);
}
/* Send our public DH value and a nonce to the peer. */
int
-ike_phase_1_send_KE_NONCE (struct message *msg, size_t nonce_sz)
+ike_phase_1_send_KE_NONCE(struct message * msg, size_t nonce_sz)
{
- /* Public DH key. */
- if (ipsec_gen_g_x (msg))
- {
- /* XXX How to log and notify peer? */
- return -1;
- }
-
- /* Generate a nonce, and add it to the message. */
- if (exchange_gen_nonce (msg, nonce_sz))
- {
- /* XXX Log? */
- return -1;
- }
-
- /* Try to add certificates which are acceptable for the CERTREQs */
- if (exchange_add_certs (msg))
- {
- /* XXX Log? */
- return -1;
- }
-
- return 0;
+ /* Public DH key. */
+ if (ipsec_gen_g_x(msg)) {
+ /* XXX How to log and notify peer? */
+ return -1;
+ }
+ /* Generate a nonce, and add it to the message. */
+ if (exchange_gen_nonce(msg, nonce_sz)) {
+ /* XXX Log? */
+ return -1;
+ }
+ /* Try to add certificates which are acceptable for the CERTREQs */
+ if (exchange_add_certs(msg)) {
+ /* XXX Log? */
+ return -1;
+ }
+ return 0;
}
/* Receive our peer's public DH value and nonce. */
int
-ike_phase_1_recv_KE_NONCE (struct message *msg)
+ike_phase_1_recv_KE_NONCE(struct message * msg)
{
- /* Copy out the initiator's DH public value. */
- if (ipsec_save_g_x (msg))
- {
- /* XXX How to log and notify peer? */
- return -1;
- }
-
- /* Copy out the initiator's nonce. */
- if (exchange_save_nonce (msg))
- {
- /* XXX How to log and notify peer? */
- return -1;
- }
-
- /* Copy out the initiator's cert requests. */
- if (exchange_save_certreq (msg))
- {
- /* XXX How to log and notify peer? */
- return -1;
- }
-
- return 0;
+ /* Copy out the initiator's DH public value. */
+ if (ipsec_save_g_x(msg)) {
+ /* XXX How to log and notify peer? */
+ return -1;
+ }
+ /* Copy out the initiator's nonce. */
+ if (exchange_save_nonce(msg)) {
+ /* XXX How to log and notify peer? */
+ return -1;
+ }
+ /* Copy out the initiator's cert requests. */
+ if (exchange_save_certreq(msg)) {
+ /* XXX How to log and notify peer? */
+ return -1;
+ }
+ return 0;
}
/*
@@ -591,626 +543,568 @@ ike_phase_1_recv_KE_NONCE (struct message *msg)
* thus speeding up exchanges.
*/
int
-ike_phase_1_post_exchange_KE_NONCE (struct message *msg)
+ike_phase_1_post_exchange_KE_NONCE(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct prf *prf;
- struct hash *hash = ie->hash;
- enum cryptoerr err;
-
- /* Compute Diffie-Hellman shared value. */
- ie->g_xy = malloc (ie->g_x_len);
- if (!ie->g_xy)
- {
- /* XXX How to notify peer? */
- log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
- (unsigned long)ie->g_x_len);
- return -1;
- }
- if (dh_create_shared (ie->group, ie->g_xy,
- exchange->initiator ? ie->g_xr : ie->g_xi))
- {
- log_print ("ike_phase_1_post_exchange_KE_NONCE: "
- "dh_create_shared failed");
- return -1;
- }
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "ike_phase_1_post_exchange_KE_NONCE: g^xy", ie->g_xy,
- ie->g_x_len));
-
- /* Compute the SKEYID depending on the authentication method. */
- ie->skeyid = ie->ike_auth->gen_skeyid (exchange, &ie->skeyid_len);
- if (!ie->skeyid)
- {
- /* XXX Log and teardown? */
- return -1;
- }
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "ike_phase_1_post_exchange_KE_NONCE: SKEYID", ie->skeyid,
- ie->skeyid_len));
-
- /* SKEYID_d. */
- ie->skeyid_d = malloc (ie->skeyid_len);
- if (!ie->skeyid_d)
- {
- /* XXX How to notify peer? */
- log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
- (unsigned long)ie->skeyid_len);
- return -1;
- }
- prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
- if (!prf)
- {
- /* XXX Log and teardown? */
- return -1;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
- prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
- prf->Update (prf->prfctx, (unsigned char *)"\0", 1);
- prf->Final (ie->skeyid_d, prf->prfctx);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d", ie->skeyid_d,
- ie->skeyid_len));
-
- /* SKEYID_a. */
- ie->skeyid_a = malloc (ie->skeyid_len);
- if (!ie->skeyid_a)
- {
- log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
- (unsigned long)ie->skeyid_len);
- prf_free (prf);
- return -1;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, ie->skeyid_d, ie->skeyid_len);
- prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
- prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
- prf->Update (prf->prfctx, (unsigned char *)"\1", 1);
- prf->Final (ie->skeyid_a, prf->prfctx);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a", ie->skeyid_a,
- ie->skeyid_len));
-
- /* SKEYID_e. */
- ie->skeyid_e = malloc (ie->skeyid_len);
- if (!ie->skeyid_e)
- {
- /* XXX How to notify peer? */
- log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
- (unsigned long)ie->skeyid_len);
- prf_free (prf);
- return -1;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, ie->skeyid_a, ie->skeyid_len);
- prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
- prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
- prf->Update (prf->prfctx, (unsigned char *)"\2", 1);
- prf->Final (ie->skeyid_e, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e", ie->skeyid_e,
- ie->skeyid_len));
-
- /* Key length determination. */
- if (!exchange->key_length)
- exchange->key_length = exchange->crypto->keymax;
-
- /* Derive a longer key from skeyid_e */
- if (ie->skeyid_len < exchange->key_length)
- {
- u_int16_t len, keylen;
- u_int8_t *key, *p;
-
- prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid_e, ie->skeyid_len);
- if (!prf)
- {
- /* XXX - notify peer */
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct prf *prf;
+ struct hash *hash = ie->hash;
+ enum cryptoerr err;
+
+ /* Compute Diffie-Hellman shared value. */
+ ie->g_xy = malloc(ie->g_x_len);
+ if (!ie->g_xy) {
+ /* XXX How to notify peer? */
+ log_error("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->g_x_len);
+ return -1;
}
-
- /* Make keylen a multiple of prf->blocksize */
- keylen = exchange->key_length;
- if (keylen % prf->blocksize)
- keylen += prf->blocksize - (keylen % prf->blocksize);
-
- key = malloc (keylen);
- if (!key)
- {
- /* XXX - Notify peer. */
- log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
- keylen);
- return -1;
+ if (dh_create_shared(ie->group, ie->g_xy,
+ exchange->initiator ? ie->g_xr : ie->g_xi)) {
+ log_print("ike_phase_1_post_exchange_KE_NONCE: "
+ "dh_create_shared failed");
+ return -1;
}
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "ike_phase_1_post_exchange_KE_NONCE: g^xy", ie->g_xy,
+ ie->g_x_len));
+
+ /* Compute the SKEYID depending on the authentication method. */
+ ie->skeyid = ie->ike_auth->gen_skeyid(exchange, &ie->skeyid_len);
+ if (!ie->skeyid) {
+ /* XXX Log and teardown? */
+ return -1;
+ }
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "ike_phase_1_post_exchange_KE_NONCE: SKEYID", ie->skeyid,
+ ie->skeyid_len));
+
+ /* SKEYID_d. */
+ ie->skeyid_d = malloc(ie->skeyid_len);
+ if (!ie->skeyid_d) {
+ /* XXX How to notify peer? */
+ log_error("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->skeyid_len);
+ return -1;
+ }
+ prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
+ if (!prf) {
+ /* XXX Log and teardown? */
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, ie->g_xy, ie->g_x_len);
+ prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
+ prf->Update(prf->prfctx, (unsigned char *) "\0", 1);
+ prf->Final(ie->skeyid_d, prf->prfctx);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d", ie->skeyid_d,
+ ie->skeyid_len));
+
+ /* SKEYID_a. */
+ ie->skeyid_a = malloc(ie->skeyid_len);
+ if (!ie->skeyid_a) {
+ log_error("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->skeyid_len);
+ prf_free(prf);
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, ie->skeyid_d, ie->skeyid_len);
+ prf->Update(prf->prfctx, ie->g_xy, ie->g_x_len);
+ prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
+ prf->Update(prf->prfctx, (unsigned char *) "\1", 1);
+ prf->Final(ie->skeyid_a, prf->prfctx);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a", ie->skeyid_a,
+ ie->skeyid_len));
+
+ /* SKEYID_e. */
+ ie->skeyid_e = malloc(ie->skeyid_len);
+ if (!ie->skeyid_e) {
+ /* XXX How to notify peer? */
+ log_error("ike_phase_1_post_exchange_KE_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->skeyid_len);
+ prf_free(prf);
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, ie->skeyid_a, ie->skeyid_len);
+ prf->Update(prf->prfctx, ie->g_xy, ie->g_x_len);
+ prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
+ prf->Update(prf->prfctx, (unsigned char *) "\2", 1);
+ prf->Final(ie->skeyid_e, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e", ie->skeyid_e,
+ ie->skeyid_len));
+
+ /* Key length determination. */
+ if (!exchange->key_length)
+ exchange->key_length = exchange->crypto->keymax;
+
+ /* Derive a longer key from skeyid_e */
+ if (ie->skeyid_len < exchange->key_length) {
+ u_int16_t len, keylen;
+ u_int8_t *key, *p;
+
+ prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid_e, ie->skeyid_len);
+ if (!prf) {
+ /* XXX - notify peer */
+ return -1;
+ }
+ /* Make keylen a multiple of prf->blocksize */
+ keylen = exchange->key_length;
+ if (keylen % prf->blocksize)
+ keylen += prf->blocksize - (keylen % prf->blocksize);
+
+ key = malloc(keylen);
+ if (!key) {
+ /* XXX - Notify peer. */
+ log_error("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
+ keylen);
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, (unsigned char *) "\0", 1);
+ prf->Final(key, prf->prfctx);
+
+ for (len = prf->blocksize, p = key; len < exchange->key_length;
+ len += prf->blocksize, p += prf->blocksize) {
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, p, prf->blocksize);
+ prf->Final(p + prf->blocksize, prf->prfctx);
+ }
+ prf_free(prf);
+
+ /* Setup our keystate using the derived encryption key. */
+ exchange->keystate = crypto_init(exchange->crypto, key,
+ exchange->key_length, &err);
+
+ free(key);
+ } else
+ /* Setup our keystate using the raw skeyid_e. */
+ exchange->keystate = crypto_init(exchange->crypto, ie->skeyid_e,
+ exchange->key_length, &err);
+
+ /* Special handling for DES weak keys. */
+ if (!exchange->keystate && err == EWEAKKEY &&
+ (exchange->key_length << 1) <= ie->skeyid_len) {
+ log_print("ike_phase_1_post_exchange_KE_NONCE: "
+ "weak key, trying subseq. skeyid_e");
+ exchange->keystate = crypto_init(exchange->crypto,
+ ie->skeyid_e + exchange->key_length,
+ exchange->key_length, &err);
+ }
+ if (!exchange->keystate) {
+ log_print("ike_phase_1_post_exchange_KE_NONCE: "
+ "exchange->crypto->init () failed: %d", err);
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, (unsigned char *)"\0", 1);
- prf->Final (key, prf->prfctx);
-
- for (len = prf->blocksize, p = key; len < exchange->key_length;
- len += prf->blocksize, p += prf->blocksize)
- {
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, p, prf->blocksize);
- prf->Final (p + prf->blocksize, prf->prfctx);
+ /*
+ * XXX We really need to know if problems are of transient nature
+ * or fatal (like failed assertions etc.)
+ */
+ return -1;
}
- prf_free (prf);
-
- /* Setup our keystate using the derived encryption key. */
- exchange->keystate
- = crypto_init (exchange->crypto, key, exchange->key_length, &err);
-
- free (key);
- }
- else
- /* Setup our keystate using the raw skeyid_e. */
- exchange->keystate = crypto_init (exchange->crypto, ie->skeyid_e,
- exchange->key_length, &err);
-
- /* Special handling for DES weak keys. */
- if (!exchange->keystate && err == EWEAKKEY
- && (exchange->key_length << 1) <= ie->skeyid_len)
- {
- log_print ("ike_phase_1_post_exchange_KE_NONCE: "
- "weak key, trying subseq. skeyid_e");
- exchange->keystate
- = crypto_init (exchange->crypto, ie->skeyid_e + exchange->key_length,
- exchange->key_length, &err);
- }
-
- if (!exchange->keystate)
- {
- log_print ("ike_phase_1_post_exchange_KE_NONCE: "
- "exchange->crypto->init () failed: %d", err);
-
- /*
- * XXX We really need to know if problems are of transient nature
- * or fatal (like failed assertions etc.)
- */
- return -1;
- }
-
- /* Setup IV. XXX Only for CBC transforms, no? */
- hash->Init (hash->ctx);
- hash->Update (hash->ctx, ie->g_xi, ie->g_x_len);
- hash->Update (hash->ctx, ie->g_xr, ie->g_x_len);
- hash->Final (hash->digest, hash->ctx);
- crypto_init_iv (exchange->keystate, hash->digest,
- exchange->crypto->blocksize);
-
- return 0;
+ /* Setup IV. XXX Only for CBC transforms, no? */
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, ie->g_xi, ie->g_x_len);
+ hash->Update(hash->ctx, ie->g_xr, ie->g_x_len);
+ hash->Final(hash->digest, hash->ctx);
+ crypto_init_iv(exchange->keystate, hash->digest,
+ exchange->crypto->blocksize);
+ return 0;
}
int
-ike_phase_1_responder_send_ID_AUTH (struct message *msg)
+ike_phase_1_responder_send_ID_AUTH(struct message * msg)
{
- if (ike_phase_1_send_ID (msg))
- return -1;
+ if (ike_phase_1_send_ID(msg))
+ return -1;
- return ike_phase_1_send_AUTH (msg);
+ return ike_phase_1_send_AUTH(msg);
}
int
-ike_phase_1_send_ID (struct message *msg)
+ike_phase_1_send_ID(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- u_int8_t *buf;
- char header[80];
- ssize_t sz;
- struct sockaddr *src;
- int initiator = exchange->initiator;
- u_int8_t **id;
- size_t *id_len;
- char *my_id = 0;
- u_int8_t id_type;
-
- /* Choose the right fields to fill-in. */
- id = initiator ? &exchange->id_i : &exchange->id_r;
- id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len;
-
- if (exchange->name)
- my_id = conf_get_str (exchange->name, "ID");
-
- if (!my_id)
- my_id = conf_get_str ("General", "Default-phase-1-ID");
-
- msg->transport->vtbl->get_src (msg->transport, &src);
- sz = my_id ? ipsec_id_size (my_id, &id_type) : sockaddr_addrlen (src);
- if (sz == -1)
- return -1;
-
- sz += ISAKMP_ID_DATA_OFF;
- buf = malloc (sz);
- if (!buf)
- {
- log_error ("ike_phase_1_send_ID: malloc (%lu) failed",
- (unsigned long)sz);
- return -1;
- }
-
- SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- if (my_id)
- {
- SET_ISAKMP_ID_TYPE (buf, id_type);
- switch (id_type)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- /* Already in network byteorder. */
- memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
- sockaddr_addrlen (src));
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- case IPSEC_ID_KEY_ID:
- memcpy (buf + ISAKMP_ID_DATA_OFF, conf_get_str (my_id, "Name"),
- sz - ISAKMP_ID_DATA_OFF);
- break;
-
- default:
- log_print ("ike_phase_1_send_ID: unsupported ID type %d", id_type);
- free (buf);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ u_int8_t *buf;
+ char header[80];
+ ssize_t sz;
+ struct sockaddr *src;
+ int initiator = exchange->initiator;
+ u_int8_t **id;
+ size_t *id_len;
+ char *my_id = 0;
+ u_int8_t id_type;
+
+ /* Choose the right fields to fill-in. */
+ id = initiator ? &exchange->id_i : &exchange->id_r;
+ id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len;
+
+ if (exchange->name)
+ my_id = conf_get_str(exchange->name, "ID");
+
+ if (!my_id)
+ my_id = conf_get_str("General", "Default-phase-1-ID");
+
+ msg->transport->vtbl->get_src(msg->transport, &src);
+ sz = my_id ? ipsec_id_size(my_id, &id_type) : sockaddr_addrlen(src);
+ if (sz == -1)
+ return -1;
+
+ sz += ISAKMP_ID_DATA_OFF;
+ buf = malloc(sz);
+ if (!buf) {
+ log_error("ike_phase_1_send_ID: malloc (%lu) failed",
+ (unsigned long) sz);
+ return -1;
}
- }
- else
- {
- switch (src->sa_family)
- {
- case AF_INET:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
- break;
- case AF_INET6:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV6_ADDR);
- break;
+ SET_IPSEC_ID_PROTO(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ SET_IPSEC_ID_PORT(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ if (my_id) {
+ SET_ISAKMP_ID_TYPE(buf, id_type);
+ switch (id_type) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ /* Already in network byteorder. */
+ memcpy(buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src),
+ sockaddr_addrlen(src));
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ case IPSEC_ID_KEY_ID:
+ memcpy(buf + ISAKMP_ID_DATA_OFF, conf_get_str(my_id, "Name"),
+ sz - ISAKMP_ID_DATA_OFF);
+ break;
+
+ default:
+ log_print("ike_phase_1_send_ID: unsupported ID type %d",
+ id_type);
+ free(buf);
+ return -1;
+ }
+ } else {
+ switch (src->sa_family) {
+ case AF_INET:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV4_ADDR);
+ break;
+ case AF_INET6:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV6_ADDR);
+ break;
+ }
+ /* Already in network byteorder. */
+ memcpy(buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src),
+ sockaddr_addrlen(src));
+ }
+
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, buf, sz, 1)) {
+ free(buf);
+ return -1;
}
- /* Already in network byteorder. */
- memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
- sockaddr_addrlen (src));
- }
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, buf, sz, 1))
- {
- free (buf);
- return -1;
- }
- *id_len = sz - ISAKMP_GEN_SZ;
- *id = malloc (*id_len);
- if (!*id)
- {
- log_error ("ike_phase_1_send_ID: malloc (%lu) failed",
- (unsigned long)*id_len);
- return -1;
- }
- memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len);
- snprintf (header, sizeof header, "ike_phase_1_send_ID: %s",
- constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (buf)));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 40, header, buf + ISAKMP_ID_DATA_OFF,
- sz - ISAKMP_ID_DATA_OFF));
-
- return 0;
+ *id_len = sz - ISAKMP_GEN_SZ;
+ *id = malloc(*id_len);
+ if (!*id) {
+ log_error("ike_phase_1_send_ID: malloc (%lu) failed",
+ (unsigned long) *id_len);
+ return -1;
+ }
+ memcpy(*id, buf + ISAKMP_GEN_SZ, *id_len);
+ snprintf(header, sizeof header, "ike_phase_1_send_ID: %s",
+ constant_name(ipsec_id_cst, GET_ISAKMP_ID_TYPE(buf)));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 40, header, buf + ISAKMP_ID_DATA_OFF,
+ sz - ISAKMP_ID_DATA_OFF));
+ return 0;
}
int
-ike_phase_1_send_AUTH (struct message *msg)
+ike_phase_1_send_AUTH(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
-
- if (ie->ike_auth->encode_hash (msg))
- {
- /* XXX Log? */
- return -1;
- }
-
- /*
- * XXX Many people say the COMMIT flag is just junk, especially in Phase 1.
- */
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+
+ if (ie->ike_auth->encode_hash(msg)) {
+ /* XXX Log? */
+ return -1;
+ }
+ /*
+ * XXX Many people say the COMMIT flag is just junk, especially in Phase 1.
+ */
#ifdef notyet
- if ((exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0)
- exchange->flags |= EXCHANGE_FLAG_I_COMMITTED;
+ if ((exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0)
+ exchange->flags |= EXCHANGE_FLAG_I_COMMITTED;
#endif
- return 0;
+ return 0;
}
/* Receive ID and HASH and check that the exchange has been consistent. */
int
-ike_phase_1_recv_ID_AUTH (struct message *msg)
+ike_phase_1_recv_ID_AUTH(struct message * msg)
{
- if (ike_phase_1_recv_ID (msg))
- return -1;
+ if (ike_phase_1_recv_ID(msg))
+ return -1;
- return ike_phase_1_recv_AUTH (msg);
+ return ike_phase_1_recv_AUTH(msg);
}
/* Receive ID. */
int
-ike_phase_1_recv_ID (struct message *msg)
+ike_phase_1_recv_ID(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct payload *payload;
- char header[80], *rs = 0, *rid = 0, *p;
- int initiator = exchange->initiator;
- u_int8_t **id, id_type;
- size_t *id_len;
- ssize_t sz;
- struct sockaddr *sa;
-
- payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]);
-
- if (exchange->name)
- rs = conf_get_str (exchange->name, "Remote-ID");
-
- if (rs)
- {
- sz = ipsec_id_size (rs, &id_type);
- if (sz == -1)
- {
- log_print ("ike_phase_1_recv_ID: could not handle specified "
- "Remote-ID [%s]", rs);
- return -1;
- }
-
- rid = malloc (sz);
- if (!rid)
- {
- log_error ("ike_phase_1_recv_ID: malloc (%lu) failed",
- (unsigned long)sz);
- return -1;
- }
+ struct exchange *exchange = msg->exchange;
+ struct payload *payload;
+ char header[80], *rs = 0, *rid = 0, *p;
+ int initiator = exchange->initiator;
+ u_int8_t **id, id_type;
+ size_t *id_len;
+ ssize_t sz;
+ struct sockaddr *sa;
+
+ payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]);
+
+ if (exchange->name)
+ rs = conf_get_str(exchange->name, "Remote-ID");
+
+ if (rs) {
+ sz = ipsec_id_size(rs, &id_type);
+ if (sz == -1) {
+ log_print("ike_phase_1_recv_ID: could not handle specified "
+ "Remote-ID [%s]", rs);
+ return -1;
+ }
+ rid = malloc(sz);
+ if (!rid) {
+ log_error("ike_phase_1_recv_ID: malloc (%lu) failed",
+ (unsigned long) sz);
+ return -1;
+ }
+ switch (id_type) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ p = conf_get_str(rs, "Address");
+ if (!p) {
+ log_print("ike_phase_1_recv_ID: "
+ "failed to get Address in Remote-ID section [%s]",
+ rs);
+ free(rid);
+ return -1;
+ }
+ if (text2sockaddr(p, 0, &sa) == -1) {
+ log_print("ike_phase_1_recv_ID: failed to parse address %s", p);
+ free(rid);
+ return -1;
+ }
+ if ((id_type == IPSEC_ID_IPV4_ADDR &&
+ sa->sa_family != AF_INET) ||
+ (id_type == IPSEC_ID_IPV6_ADDR &&
+ sa->sa_family != AF_INET6)) {
+ log_print("ike_phase_1_recv_ID: "
+ "address %s not of expected family", p);
+ free(rid);
+ free(sa);
+ return -1;
+ }
+ memcpy(rid, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
+ free(sa);
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ case IPSEC_ID_KEY_ID:
+ p = conf_get_str(rs, "Name");
+ if (!p) {
+ log_print("ike_phase_1_recv_ID: "
+ "failed to get Name in Remote-ID section [%s]", rs);
+ free(rid);
+ return -1;
+ }
+ memcpy(rid, p, sz);
+ break;
+
+ default:
+ log_print("ike_phase_1_recv_ID: unsupported ID type %d",
+ id_type);
+ free(rid);
+ return -1;
+ }
- switch (id_type)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- p = conf_get_str (rs, "Address");
- if (!p)
- {
- log_print ("ike_phase_1_recv_ID: "
- "failed to get Address in Remote-ID section [%s]",
- rs);
- free (rid);
- return -1;
- }
-
- if (text2sockaddr (p, 0, &sa) == -1)
- {
- log_print ("ike_phase_1_recv_ID: failed to parse address %s", p);
- free (rid);
- return -1;
- }
-
- if ((id_type == IPSEC_ID_IPV4_ADDR && sa->sa_family != AF_INET)
- || (id_type == IPSEC_ID_IPV6_ADDR && sa->sa_family != AF_INET6))
- {
- log_print ("ike_phase_1_recv_ID: "
- "address %s not of expected family", p);
- free (rid);
- free (sa);
- return -1;
- }
-
- memcpy (rid, sockaddr_addrdata (sa), sockaddr_addrlen (sa));
- free (sa);
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- case IPSEC_ID_KEY_ID:
- p = conf_get_str (rs, "Name");
- if (!p)
- {
- log_print ("ike_phase_1_recv_ID: "
- "failed to get Name in Remote-ID section [%s]", rs);
- free (rid);
- return -1;
- }
-
- memcpy (rid, p, sz);
- break;
-
- default:
- log_print ("ike_phase_1_recv_ID: unsupported ID type %d", id_type);
- free (rid);
- return -1;
+ /* Compare expected/desired and received remote ID */
+ if (bcmp(rid, payload->p + ISAKMP_ID_DATA_OFF, sz)) {
+ free(rid);
+ log_print("ike_phase_1_recv_ID: "
+ "received remote ID other than expected %s", p);
+ return -1;
+ }
+ free(rid);
}
-
- /* Compare expected/desired and received remote ID */
- if (bcmp (rid, payload->p + ISAKMP_ID_DATA_OFF, sz))
- {
- free (rid);
- log_print ("ike_phase_1_recv_ID: "
- "received remote ID other than expected %s", p);
- return -1;
+ /* Choose the right fields to fill in */
+ id = initiator ? &exchange->id_r : &exchange->id_i;
+ id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len;
+
+ *id_len = GET_ISAKMP_GEN_LENGTH(payload->p) - ISAKMP_GEN_SZ;
+ *id = malloc(*id_len);
+ if (!*id) {
+ log_error("ike_phase_1_recv_ID: malloc (%lu) failed",
+ (unsigned long) *id_len);
+ return -1;
}
-
- free (rid);
- }
-
- /* Choose the right fields to fill in */
- id = initiator ? &exchange->id_r : &exchange->id_i;
- id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len;
-
- *id_len = GET_ISAKMP_GEN_LENGTH (payload->p) - ISAKMP_GEN_SZ;
- *id = malloc (*id_len);
- if (!*id)
- {
- log_error ("ike_phase_1_recv_ID: malloc (%lu) failed",
- (unsigned long)*id_len);
- return -1;
- }
- memcpy (*id, payload->p + ISAKMP_GEN_SZ, *id_len);
- snprintf (header, sizeof header, "ike_phase_1_recv_ID: %s",
- constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (payload->p)));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 40, header, payload->p + ISAKMP_ID_DATA_OFF,
- *id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF));
- payload->flags |= PL_MARK;
-
- return 0;
+ memcpy(*id, payload->p + ISAKMP_GEN_SZ, *id_len);
+ snprintf(header, sizeof header, "ike_phase_1_recv_ID: %s",
+ constant_name(ipsec_id_cst, GET_ISAKMP_ID_TYPE(payload->p)));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 40, header, payload->p + ISAKMP_ID_DATA_OFF,
+ *id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF));
+ payload->flags |= PL_MARK;
+ return 0;
}
/* Receive HASH and check that the exchange has been consistent. */
int
-ike_phase_1_recv_AUTH (struct message *msg)
+ike_phase_1_recv_AUTH(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct prf *prf;
- struct hash *hash = ie->hash;
- char header[80];
- size_t hashsize = hash->hashsize;
- int initiator = exchange->initiator;
- u_int8_t **hash_p, *id;
- size_t id_len;
-
- /* Choose the right fields to fill in */
- hash_p = initiator ? &ie->hash_r : &ie->hash_i;
- id = initiator ? exchange->id_r : exchange->id_i;
- id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
-
- /* The decoded hash will be in ie->hash_r or ie->hash_i */
- if (ie->ike_auth->decode_hash (msg))
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 0);
- return -1;
- }
-
- /* Allocate the prf and start calculating his HASH. */
- prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
- if (!prf)
- {
- /* XXX Log? */
- return -1;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
- prf->Update (prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
- prf->Update (prf->prfctx,
- exchange->cookies
- + (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF),
- ISAKMP_HDR_ICOOKIE_LEN);
- prf->Update (prf->prfctx,
- exchange->cookies
- + (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF),
- ISAKMP_HDR_ICOOKIE_LEN);
- prf->Update (prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
- prf->Update (prf->prfctx, id, id_len);
- prf->Final (hash->digest, prf->prfctx);
- prf_free (prf);
- snprintf (header, sizeof header, "ike_phase_1_recv_AUTH: computed HASH_%c",
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct prf *prf;
+ struct hash *hash = ie->hash;
+ char header[80];
+ size_t hashsize = hash->hashsize;
+ int initiator = exchange->initiator;
+ u_int8_t **hash_p, *id;
+ size_t id_len;
+
+ /* Choose the right fields to fill in */
+ hash_p = initiator ? &ie->hash_r : &ie->hash_i;
+ id = initiator ? exchange->id_r : exchange->id_i;
+ id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
+
+ /* The decoded hash will be in ie->hash_r or ie->hash_i */
+ if (ie->ike_auth->decode_hash(msg)) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 0);
+ return -1;
+ }
+ /* Allocate the prf and start calculating his HASH. */
+ prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
+ if (!prf) {
+ /* XXX Log? */
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
+ prf->Update(prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
+ prf->Update(prf->prfctx, exchange->cookies +
+ (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF),
+ ISAKMP_HDR_ICOOKIE_LEN);
+ prf->Update(prf->prfctx, exchange->cookies +
+ (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF),
+ ISAKMP_HDR_ICOOKIE_LEN);
+ prf->Update(prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
+ prf->Update(prf->prfctx, id, id_len);
+ prf->Final(hash->digest, prf->prfctx);
+ prf_free(prf);
+ snprintf(header, sizeof header, "ike_phase_1_recv_AUTH: computed HASH_%c",
initiator ? 'R' : 'I');
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80, header, hash->digest, hashsize));
-
- /* Check that the hash we got matches the one we computed. */
- if (memcmp (*hash_p, hash->digest, hashsize) != 0)
- {
- /* XXX Log? */
- return -1;
- }
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, hash->digest, hashsize));
- return 0;
+ /* Check that the hash we got matches the one we computed. */
+ if (memcmp(*hash_p, hash->digest, hashsize) != 0) {
+ /* XXX Log? */
+ return -1;
+ }
+ return 0;
}
struct attr_node {
- LIST_ENTRY (attr_node) link;
- u_int16_t type;
+ LIST_ENTRY(attr_node) link;
+ u_int16_t type;
};
struct validation_state {
- struct conf_list_node *xf;
- LIST_HEAD (attr_head, attr_node) attrs;
- char *life;
+ struct conf_list_node *xf;
+ LIST_HEAD(attr_head, attr_node) attrs;
+ char *life;
};
/* Validate a proposal inside SA according to EXCHANGE's policy. */
static int
-ike_phase_1_validate_prop (struct exchange *exchange, struct sa *sa,
- struct sa *isakmp_sa)
+ike_phase_1_validate_prop(struct exchange *exchange, struct sa *sa,
+ struct sa *isakmp_sa)
{
- struct conf_list *conf, *tags;
- struct conf_list_node *xf, *tag;
- struct proto *proto;
- struct validation_state vs;
- struct attr_node *node, *next_node;
-
- /* Get the list of transforms. */
- conf = conf_get_list (exchange->policy, "Transforms");
- if (!conf)
- return 0;
-
- for (xf = TAILQ_FIRST (&conf->fields); xf; xf = TAILQ_NEXT (xf, link))
- {
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- /* Mark all attributes in our policy as unseen. */
- LIST_INIT (&vs.attrs);
- vs.xf = xf;
- vs.life = 0;
- if (attribute_map (proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (proto->chosen->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- attribute_unacceptable, &vs))
- goto try_next;
-
- /* Sweep over unseen tags in this section. */
- tags = conf_get_tag_list (xf->field);
- if (tags)
- {
- for (tag = TAILQ_FIRST (&tags->fields); tag;
- tag = TAILQ_NEXT (tag, link))
- /*
- * XXX Should we care about attributes we have, they do not
- * provide?
- */
- for (node = LIST_FIRST (&vs.attrs); node;
- node = next_node)
- {
- next_node = LIST_NEXT (node, link);
- if (node->type
- == constant_value (ike_attr_cst, tag->field))
- {
- LIST_REMOVE (node, link);
- free (node);
- }
- }
- conf_free_list (tags);
- }
-
- /* Are there leftover tags in this section? */
- node = LIST_FIRST (&vs.attrs);
- if (node)
- goto try_next;
- }
+ struct conf_list *conf, *tags;
+ struct conf_list_node *xf, *tag;
+ struct proto *proto;
+ struct validation_state vs;
+ struct attr_node *node, *next_node;
+
+ /* Get the list of transforms. */
+ conf = conf_get_list(exchange->policy, "Transforms");
+ if (!conf)
+ return 0;
+
+ for (xf = TAILQ_FIRST(&conf->fields); xf; xf = TAILQ_NEXT(xf, link)) {
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ /* Mark all attributes in our policy as unseen. */
+ LIST_INIT(&vs.attrs);
+ vs.xf = xf;
+ vs.life = 0;
+ if (attribute_map(proto->chosen->p +
+ ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(proto->chosen->p) -
+ ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ attribute_unacceptable, &vs))
+ goto try_next;
+
+ /* Sweep over unseen tags in this section. */
+ tags = conf_get_tag_list(xf->field);
+ if (tags) {
+ for (tag = TAILQ_FIRST(&tags->fields); tag;
+ tag = TAILQ_NEXT(tag, link))
+ /*
+ * XXX Should we care about attributes
+ * we have, they do not provide?
+ */
+ for (node = LIST_FIRST(&vs.attrs); node;
+ node = next_node) {
+ next_node = LIST_NEXT(node, link);
+ if (node->type ==
+ constant_value(ike_attr_cst,
+ tag->field)) {
+ LIST_REMOVE(node, link);
+ free(node);
+ }
+ }
+ conf_free_list(tags);
+ }
+ /* Are there leftover tags in this section? */
+ node = LIST_FIRST(&vs.attrs);
+ if (node)
+ goto try_next;
+ }
- /* All protocols were OK, we succeeded. */
- LOG_DBG ((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: success"));
- conf_free_list (conf);
- if (vs.life)
- free (vs.life);
- return 1;
-
- try_next:
- /* Are there leftover tags in this section? */
- node = LIST_FIRST (&vs.attrs);
- while (node)
- {
- LIST_REMOVE (node, link);
- free (node);
- node = LIST_FIRST (&vs.attrs);
+ /* All protocols were OK, we succeeded. */
+ LOG_DBG((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: success"));
+ conf_free_list(conf);
+ if (vs.life)
+ free(vs.life);
+ return 1;
+
+try_next:
+ /* Are there leftover tags in this section? */
+ node = LIST_FIRST(&vs.attrs);
+ while (node) {
+ LIST_REMOVE(node, link);
+ free(node);
+ node = LIST_FIRST(&vs.attrs);
+ }
+ if (vs.life)
+ free(vs.life);
}
- if (vs.life)
- free (vs.life);
- }
- LOG_DBG ((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: failure"));
- conf_free_list (conf);
- return 0;
+ LOG_DBG((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: failure"));
+ conf_free_list(conf);
+ return 0;
}
/*
@@ -1219,179 +1113,162 @@ ike_phase_1_validate_prop (struct exchange *exchange, struct sa *sa,
* If the attribute is unacceptable to use, return non-zero, otherwise zero.
*/
static int
-attribute_unacceptable (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vvs)
+attribute_unacceptable(u_int16_t type, u_int8_t *value, u_int16_t len,
+ void *vvs)
{
- struct validation_state *vs = vvs;
- struct conf_list *life_conf;
- struct conf_list_node *xf = vs->xf, *life;
- char *tag = constant_lookup (ike_attr_cst, type);
- char *str;
- struct constant_map *map;
- struct attr_node *node;
- int rv;
-
- if (!tag)
- {
- LOG_DBG ((LOG_NEGOTIATION, 60,
- "attribute_unacceptable: attribute type %d not known", type));
- return 1;
- }
-
- switch (type)
- {
- case IKE_ATTR_ENCRYPTION_ALGORITHM:
- case IKE_ATTR_HASH_ALGORITHM:
- case IKE_ATTR_AUTHENTICATION_METHOD:
- case IKE_ATTR_GROUP_DESCRIPTION:
- case IKE_ATTR_GROUP_TYPE:
- case IKE_ATTR_PRF:
- str = conf_get_str (xf->field, tag);
- if (!str)
- {
- /* This attribute does not exist in this policy. */
- LOG_DBG ((LOG_NEGOTIATION, 70,
- "attribute_unacceptable: attr %s does not exist in %s",
- tag, xf->field));
- return 1;
+ struct validation_state *vs = vvs;
+ struct conf_list *life_conf;
+ struct conf_list_node *xf = vs->xf, *life;
+ char *tag = constant_lookup(ike_attr_cst, type);
+ char *str;
+ struct constant_map *map;
+ struct attr_node *node;
+ int rv;
+
+ if (!tag) {
+ LOG_DBG((LOG_NEGOTIATION, 60,
+ "attribute_unacceptable: attribute type %d not known", type));
+ return 1;
}
-
- map = constant_link_lookup (ike_attr_cst, type);
- if (!map)
- return 1;
-
- if ((constant_value (map, str) == decode_16 (value)) ||
- (!strcmp (str, "ANY")))
- {
- /* Mark this attribute as seen. */
- node = malloc (sizeof *node);
- if (!node)
- {
- log_error ("attribute_unacceptable: malloc (%lu) failed",
- (unsigned long)sizeof *node);
- return 1;
- }
- node->type = type;
- LIST_INSERT_HEAD (&vs->attrs, node, link);
- return 0;
- }
- LOG_DBG ((LOG_NEGOTIATION, 70,
- "attribute_unacceptable: %s: got %s, expected %s", tag,
- constant_name (map, decode_16 (value)), str));
- return 1;
-
- case IKE_ATTR_GROUP_PRIME:
- case IKE_ATTR_GROUP_GENERATOR_1:
- case IKE_ATTR_GROUP_GENERATOR_2:
- case IKE_ATTR_GROUP_CURVE_A:
- case IKE_ATTR_GROUP_CURVE_B:
- /* XXX Bignums not handled yet. */
- return 1;
-
- case IKE_ATTR_LIFE_TYPE:
- case IKE_ATTR_LIFE_DURATION:
- life_conf = conf_get_list (xf->field, "Life");
- if (life_conf && !strcmp (conf_get_str (xf->field, "Life"), "ANY"))
- return 0;
-
- rv = 1;
- if (!life_conf)
- {
- /* Life attributes given, but not in our policy. */
- LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
- "received unexpected life attribute"));
- return 1;
- }
-
- /*
- * Each lifetime type must match, otherwise we turn the proposal down.
- * In order to do this we need to find the specific section of our
- * policy's "Life" list and match its duration
- */
- switch (type)
- {
- case IKE_ATTR_LIFE_TYPE:
- for (life = TAILQ_FIRST (&life_conf->fields); life;
- life = TAILQ_NEXT (life, link))
- {
- str = conf_get_str (life->field, "LIFE_TYPE");
- if (!str)
- {
- LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
- "section [%s] has no LIFE_TYPE", life->field));
- continue;
+ switch (type) {
+ case IKE_ATTR_ENCRYPTION_ALGORITHM:
+ case IKE_ATTR_HASH_ALGORITHM:
+ case IKE_ATTR_AUTHENTICATION_METHOD:
+ case IKE_ATTR_GROUP_DESCRIPTION:
+ case IKE_ATTR_GROUP_TYPE:
+ case IKE_ATTR_PRF:
+ str = conf_get_str(xf->field, tag);
+ if (!str) {
+ /* This attribute does not exist in this policy. */
+ LOG_DBG((LOG_NEGOTIATION, 70,
+ "attribute_unacceptable: attr %s does not exist in %s",
+ tag, xf->field));
+ return 1;
}
-
- /*
- * If this is the type we are looking at, save a pointer
- * to this section in vs->life.
- */
- if (constant_value (ike_duration_cst, str) == decode_16 (value))
- {
- vs->life = strdup (life->field);
- rv = 0;
- goto bail_out;
+ map = constant_link_lookup(ike_attr_cst, type);
+ if (!map)
+ return 1;
+
+ if ((constant_value(map, str) == decode_16(value)) ||
+ (!strcmp(str, "ANY"))) {
+ /* Mark this attribute as seen. */
+ node = malloc(sizeof *node);
+ if (!node) {
+ log_error("attribute_unacceptable: malloc (%lu) failed",
+ (unsigned long) sizeof *node);
+ return 1;
+ }
+ node->type = type;
+ LIST_INSERT_HEAD(&vs->attrs, node, link);
+ return 0;
}
- }
- LOG_DBG ((LOG_NEGOTIATION, 70,
- "attribute_unacceptable: unrecognized LIFE_TYPE %d",
- decode_16 (value)));
- vs->life = 0;
- break;
+ LOG_DBG((LOG_NEGOTIATION, 70,
+ "attribute_unacceptable: %s: got %s, expected %s", tag,
+ constant_name(map, decode_16(value)), str));
+ return 1;
+
+ case IKE_ATTR_GROUP_PRIME:
+ case IKE_ATTR_GROUP_GENERATOR_1:
+ case IKE_ATTR_GROUP_GENERATOR_2:
+ case IKE_ATTR_GROUP_CURVE_A:
+ case IKE_ATTR_GROUP_CURVE_B:
+ /* XXX Bignums not handled yet. */
+ return 1;
+ case IKE_ATTR_LIFE_TYPE:
case IKE_ATTR_LIFE_DURATION:
- if (!vs->life)
- {
- LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
- "LIFE_DURATION without LIFE_TYPE"));
- rv = 1;
- goto bail_out;
- }
-
- str = conf_get_str (vs->life, "LIFE_DURATION");
- if (str)
- {
- if (!strcmp (str, "ANY"))
- rv = 0;
- else
- rv = !conf_match_num (vs->life, "LIFE_DURATION",
- len == 4 ? decode_32 (value) :
- decode_16 (value));
- }
- else
- {
- LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
- "section [%s] has no LIFE_DURATION", vs->life));
- rv = 1;
- }
-
- free (vs->life);
- vs->life = 0;
- break;
- }
+ life_conf = conf_get_list(xf->field, "Life");
+ if (life_conf && !strcmp(conf_get_str(xf->field, "Life"), "ANY"))
+ return 0;
+
+ rv = 1;
+ if (!life_conf) {
+ /* Life attributes given, but not in our policy. */
+ LOG_DBG((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
+ "received unexpected life attribute"));
+ return 1;
+ }
+ /*
+ * Each lifetime type must match, otherwise we turn the proposal down.
+ * In order to do this we need to find the specific section of our
+ * policy's "Life" list and match its duration
+ */
+ switch (type) {
+ case IKE_ATTR_LIFE_TYPE:
+ for (life = TAILQ_FIRST(&life_conf->fields); life;
+ life = TAILQ_NEXT(life, link)) {
+ str = conf_get_str(life->field, "LIFE_TYPE");
+ if (!str) {
+ LOG_DBG((LOG_NEGOTIATION, 70,
+ "attribute_unacceptable: "
+ "section [%s] has no LIFE_TYPE",
+ life->field));
+ continue;
+ }
+
+ /*
+ * If this is the type we are looking at,
+ * to save a pointer this section in vs->life.
+ */
+ if (constant_value(ike_duration_cst, str) ==
+ decode_16(value)) {
+ vs->life = strdup(life->field);
+ rv = 0;
+ goto bail_out;
+ }
+ }
+ LOG_DBG((LOG_NEGOTIATION, 70,
+ "attribute_unacceptable: unrecognized LIFE_TYPE %d",
+ decode_16(value)));
+ vs->life = 0;
+ break;
+
+ case IKE_ATTR_LIFE_DURATION:
+ if (!vs->life) {
+ LOG_DBG((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
+ "LIFE_DURATION without LIFE_TYPE"));
+ rv = 1;
+ goto bail_out;
+ }
+ str = conf_get_str(vs->life, "LIFE_DURATION");
+ if (str) {
+ if (!strcmp(str, "ANY"))
+ rv = 0;
+ else
+ rv = !conf_match_num(vs->life, "LIFE_DURATION",
+ len == 4 ? decode_32(value) :
+ decode_16(value));
+ } else {
+ LOG_DBG((LOG_NEGOTIATION, 70, "attribute_unacceptable: "
+ "section [%s] has no LIFE_DURATION", vs->life));
+ rv = 1;
+ }
+
+ free(vs->life);
+ vs->life = 0;
+ break;
+ }
- bail_out:
- conf_free_list (life_conf);
- return rv;
-
- case IKE_ATTR_KEY_LENGTH:
- case IKE_ATTR_FIELD_SIZE:
- case IKE_ATTR_GROUP_ORDER:
- if (conf_match_num (xf->field, tag, decode_16 (value)))
- {
- /* Mark this attribute as seen. */
- node = malloc (sizeof *node);
- if (!node)
- {
- log_error ("attribute_unacceptable: malloc (%lu) failed",
- (unsigned long)sizeof *node);
- return 1;
- }
- node->type = type;
- LIST_INSERT_HEAD (&vs->attrs, node, link);
- return 0;
+bail_out:
+ conf_free_list(life_conf);
+ return rv;
+
+ case IKE_ATTR_KEY_LENGTH:
+ case IKE_ATTR_FIELD_SIZE:
+ case IKE_ATTR_GROUP_ORDER:
+ if (conf_match_num(xf->field, tag, decode_16(value))) {
+ /* Mark this attribute as seen. */
+ node = malloc(sizeof *node);
+ if (!node) {
+ log_error("attribute_unacceptable: malloc (%lu) failed",
+ (unsigned long) sizeof *node);
+ return 1;
+ }
+ node->type = type;
+ LIST_INSERT_HEAD(&vs->attrs, node, link);
+ return 0;
+ }
+ return 1;
}
- return 1;
- }
- return 1;
+ return 1;
}
diff --git a/sbin/isakmpd/ike_phase_1.h b/sbin/isakmpd/ike_phase_1.h
index 3a0498abe40..1252664b7e3 100644
--- a/sbin/isakmpd/ike_phase_1.h
+++ b/sbin/isakmpd/ike_phase_1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ike_phase_1.h,v 1.3 2003/06/03 14:28:16 ho Exp $ */
+/* $OpenBSD: ike_phase_1.h,v 1.4 2004/04/15 18:39:25 deraadt Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -33,21 +33,21 @@
struct message;
-extern int ike_phase_1_initiator_recv_KE_NONCE (struct message *);
-extern int ike_phase_1_initiator_recv_SA (struct message *);
-extern int ike_phase_1_initiator_send_KE_NONCE (struct message *);
-extern int ike_phase_1_initiator_send_SA (struct message *);
-extern int ike_phase_1_post_exchange_KE_NONCE (struct message *);
-extern int ike_phase_1_recv_AUTH (struct message *);
-extern int ike_phase_1_recv_ID (struct message *);
-extern int ike_phase_1_recv_ID_AUTH (struct message *);
-extern int ike_phase_1_recv_KE_NONCE (struct message *);
-extern int ike_phase_1_responder_recv_SA (struct message *);
-extern int ike_phase_1_responder_send_SA (struct message *);
-extern int ike_phase_1_responder_send_ID_AUTH (struct message *);
-extern int ike_phase_1_send_AUTH (struct message *);
-extern int ike_phase_1_send_ID (struct message *);
-extern int ike_phase_1_send_ID_AUTH (struct message *);
-extern int ike_phase_1_send_KE_NONCE (struct message *, size_t);
+extern int ike_phase_1_initiator_recv_KE_NONCE(struct message *);
+extern int ike_phase_1_initiator_recv_SA(struct message *);
+extern int ike_phase_1_initiator_send_KE_NONCE(struct message *);
+extern int ike_phase_1_initiator_send_SA(struct message *);
+extern int ike_phase_1_post_exchange_KE_NONCE(struct message *);
+extern int ike_phase_1_recv_AUTH(struct message *);
+extern int ike_phase_1_recv_ID(struct message *);
+extern int ike_phase_1_recv_ID_AUTH(struct message *);
+extern int ike_phase_1_recv_KE_NONCE(struct message *);
+extern int ike_phase_1_responder_recv_SA(struct message *);
+extern int ike_phase_1_responder_send_SA(struct message *);
+extern int ike_phase_1_responder_send_ID_AUTH(struct message *);
+extern int ike_phase_1_send_AUTH(struct message *);
+extern int ike_phase_1_send_ID(struct message *);
+extern int ike_phase_1_send_ID_AUTH(struct message *);
+extern int ike_phase_1_send_KE_NONCE(struct message *, size_t);
-#endif /* _IKE_PHASE_1_H_ */
+#endif /* _IKE_PHASE_1_H_ */
diff --git a/sbin/isakmpd/ike_quick_mode.c b/sbin/isakmpd/ike_quick_mode.c
index 1b4f2c34e6a..bb92aaf2a0e 100644
--- a/sbin/isakmpd/ike_quick_mode.c
+++ b/sbin/isakmpd/ike_quick_mode.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_quick_mode.c,v 1.76 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: ike_quick_mode.c,v 1.139 2001/01/26 10:43:17 niklas Exp $ */
+/* $OpenBSD: ike_quick_mode.c,v 1.77 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_quick_mode.c,v 1.139 2001/01/26 10:43:17 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -65,29 +65,29 @@
#include "x509.h"
#endif
-static void gen_g_xy (struct message *);
-static int initiator_send_HASH_SA_NONCE (struct message *);
-static int initiator_recv_HASH_SA_NONCE (struct message *);
-static int initiator_send_HASH (struct message *);
-static void post_quick_mode (struct message *);
-static int responder_recv_HASH_SA_NONCE (struct message *);
-static int responder_send_HASH_SA_NONCE (struct message *);
-static int responder_recv_HASH (struct message *);
+static void gen_g_xy(struct message *);
+static int initiator_send_HASH_SA_NONCE(struct message *);
+static int initiator_recv_HASH_SA_NONCE(struct message *);
+static int initiator_send_HASH(struct message *);
+static void post_quick_mode(struct message *);
+static int responder_recv_HASH_SA_NONCE(struct message *);
+static int responder_send_HASH_SA_NONCE(struct message *);
+static int responder_recv_HASH(struct message *);
#ifdef USE_POLICY
-static int check_policy (struct exchange *, struct sa *, struct sa *);
+static int check_policy(struct exchange *, struct sa *, struct sa *);
#endif
-int (*ike_quick_mode_initiator[]) (struct message *) = {
- initiator_send_HASH_SA_NONCE,
- initiator_recv_HASH_SA_NONCE,
- initiator_send_HASH
+int (*ike_quick_mode_initiator[]) (struct message *) = {
+ initiator_send_HASH_SA_NONCE,
+ initiator_recv_HASH_SA_NONCE,
+ initiator_send_HASH
};
-int (*ike_quick_mode_responder[]) (struct message *) = {
- responder_recv_HASH_SA_NONCE,
- responder_send_HASH_SA_NONCE,
- responder_recv_HASH
+int (*ike_quick_mode_responder[]) (struct message *) = {
+ responder_recv_HASH_SA_NONCE,
+ responder_send_HASH_SA_NONCE,
+ responder_recv_HASH
};
#ifdef USE_POLICY
@@ -100,1369 +100,1262 @@ int (*ike_quick_mode_responder[]) (struct message *) = {
* acceptable.
*/
static int
-check_policy (struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa)
+check_policy(struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa)
{
- char *return_values[RETVALUES_NUM];
- char **principal = 0;
- int i, len, result = 0, nprinc = 0;
- int *x509_ids = 0, *keynote_ids = 0;
- unsigned char hashbuf[20]; /* Set to the largest digest result */
+ char *return_values[RETVALUES_NUM];
+ char **principal = 0;
+ int i, len, result = 0, nprinc = 0;
+ int *x509_ids = 0, *keynote_ids = 0;
+ unsigned char hashbuf[20]; /* Set to the largest digest result */
#ifdef USE_X509
- struct keynote_deckey dc;
- X509_NAME *subject;
+ struct keynote_deckey dc;
+ X509_NAME *subject;
#endif
- /* Initialize if necessary -- e.g., if pre-shared key auth was used */
- if (isakmp_sa->policy_id < 0)
- {
- if ((isakmp_sa->policy_id = kn_init ()) == -1)
- {
- log_print ("check_policy: failed to initialize policy session");
- return 0;
+ /* Initialize if necessary -- e.g., if pre-shared key auth was used */
+ if (isakmp_sa->policy_id < 0) {
+ if ((isakmp_sa->policy_id = kn_init()) == -1) {
+ log_print("check_policy: failed to initialize policy session");
+ return 0;
+ }
}
- }
-
- /* Add the callback that will handle attributes. */
- if (kn_add_action (isakmp_sa->policy_id, ".*", (char *) policy_callback,
- ENVIRONMENT_FLAG_FUNC | ENVIRONMENT_FLAG_REGEX) == -1)
- {
- log_print ("check_policy: "
- "kn_add_action (%d, \".*\", %p, FUNC | REGEX) failed",
- isakmp_sa->policy_id, policy_callback);
- kn_close (isakmp_sa->policy_id);
- isakmp_sa->policy_id = -1;
- return 0;
- }
-
- if (keynote_policy_asserts_num)
- {
- keynote_ids = calloc (keynote_policy_asserts_num, sizeof *keynote_ids);
- if (!keynote_ids)
- {
- log_error ("check_policy: calloc (%d, %lu) failed",
- keynote_policy_asserts_num, (unsigned long)sizeof *keynote_ids);
- return 0;
- }
- }
-
- /* Add the policy assertions */
- for (i = 0; i < keynote_policy_asserts_num; i++)
- keynote_ids[i] = kn_add_assertion (isakmp_sa->policy_id,
- keynote_policy_asserts[i],
- strlen (keynote_policy_asserts[i]),
- ASSERT_FLAG_LOCAL);
-
- /* Initialize -- we'll let the callback do all the work. */
- policy_exchange = exchange;
- policy_sa = sa;
- policy_isakmp_sa = isakmp_sa;
-
- /* Set the return values; true/false for now at least. */
- return_values[0] = "false"; /* Order of values in array is important. */
- return_values[1] = "true";
-
- /* Create a principal (authorizer) for the SA/ID request. */
- switch (isakmp_sa->recv_certtype)
- {
- case ISAKMP_CERTENC_NONE:
- /*
- * For shared keys, just duplicate the passphrase with the
- * appropriate prefix tag.
- */
- nprinc = 3;
- principal = calloc (nprinc, sizeof *principal);
- if (!principal)
- {
- log_error ("check_policy: calloc (%d, %lu) failed", nprinc,
- (unsigned long)sizeof *principal);
- goto policydone;
+ /* Add the callback that will handle attributes. */
+ if (kn_add_action(isakmp_sa->policy_id, ".*", (char *) policy_callback,
+ ENVIRONMENT_FLAG_FUNC | ENVIRONMENT_FLAG_REGEX) == -1) {
+ log_print("check_policy: "
+ "kn_add_action (%d, \".*\", %p, FUNC | REGEX) failed",
+ isakmp_sa->policy_id, policy_callback);
+ kn_close(isakmp_sa->policy_id);
+ isakmp_sa->policy_id = -1;
+ return 0;
}
-
- len = strlen (isakmp_sa->recv_key) + sizeof "passphrase:";
- principal[0] = calloc (len, sizeof (char));
- if (!principal[0])
- {
- log_error ("check_policy: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto policydone;
+ if (keynote_policy_asserts_num) {
+ keynote_ids = calloc(keynote_policy_asserts_num, sizeof *keynote_ids);
+ if (!keynote_ids) {
+ log_error("check_policy: calloc (%d, %lu) failed",
+ keynote_policy_asserts_num,
+ (unsigned long) sizeof *keynote_ids);
+ return 0;
+ }
}
+ /* Add the policy assertions */
+ for (i = 0; i < keynote_policy_asserts_num; i++)
+ keynote_ids[i] = kn_add_assertion(isakmp_sa->policy_id,
+ keynote_policy_asserts[i],
+ strlen(keynote_policy_asserts[i]), ASSERT_FLAG_LOCAL);
+
+ /* Initialize -- we'll let the callback do all the work. */
+ policy_exchange = exchange;
+ policy_sa = sa;
+ policy_isakmp_sa = isakmp_sa;
+
+ /* Set the return values; true/false for now at least. */
+ return_values[0] = "false"; /* Order of values in array is
+ * important. */
+ return_values[1] = "true";
+
+ /* Create a principal (authorizer) for the SA/ID request. */
+ switch (isakmp_sa->recv_certtype) {
+ case ISAKMP_CERTENC_NONE:
+ /*
+ * For shared keys, just duplicate the passphrase with the
+ * appropriate prefix tag.
+ */
+ nprinc = 3;
+ principal = calloc(nprinc, sizeof *principal);
+ if (!principal) {
+ log_error("check_policy: calloc (%d, %lu) failed", nprinc,
+ (unsigned long) sizeof *principal);
+ goto policydone;
+ }
+ len = strlen(isakmp_sa->recv_key) + sizeof "passphrase:";
+ principal[0] = calloc(len, sizeof(char));
+ if (!principal[0]) {
+ log_error("check_policy: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+ /*
+ * XXX Consider changing the magic hash lengths with
+ * constants.
+ */
+ strlcpy(principal[0], "passphrase:", len);
+ memcpy(principal[0] + sizeof "passphrase:" - 1, isakmp_sa->recv_key,
+ strlen(isakmp_sa->recv_key));
+
+ len = sizeof "passphrase-md5-hex:" + 2 * 16;
+ principal[1] = calloc(len, sizeof(char));
+ if (!principal[1]) {
+ log_error("check_policy: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+ strlcpy(principal[1], "passphrase-md5-hex:", len);
+ MD5(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key), hashbuf);
+ for (i = 0; i < 16; i++)
+ snprintf(principal[1] + 2 * i + sizeof "passphrase-md5-hex:" - 1,
+ 3, "%02x", hashbuf[i]);
+
+ len = sizeof "passphrase-sha1-hex:" + 2 * 20;
+ principal[2] = calloc(len, sizeof(char));
+ if (!principal[2]) {
+ log_error("check_policy: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+ strlcpy(principal[2], "passphrase-sha1-hex:", len);
+ SHA1(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key), hashbuf);
+ for (i = 0; i < 20; i++)
+ snprintf(principal[2] + 2 * i + sizeof "passphrase-sha1-hex:" - 1,
+ 3, "%02x", hashbuf[i]);
+ break;
+
+ case ISAKMP_CERTENC_KEYNOTE:
+#ifdef USE_KEYNOTE
+ nprinc = 1;
- /* XXX Consider changing the magic hash lengths with constants. */
- strlcpy (principal[0], "passphrase:", len);
- memcpy (principal[0] + sizeof "passphrase:" - 1, isakmp_sa->recv_key,
- strlen (isakmp_sa->recv_key));
-
- len = sizeof "passphrase-md5-hex:" + 2 * 16;
- principal[1] = calloc (len, sizeof (char));
- if (!principal[1])
- {
- log_error ("check_policy: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto policydone;
- }
+ principal = calloc(nprinc, sizeof *principal);
+ if (!principal) {
+ log_error("check_policy: calloc (%d, %lu) failed", nprinc,
+ (unsigned long) sizeof *principal);
+ goto policydone;
+ }
+ /* Dup the keys */
+ principal[0] = strdup(isakmp_sa->keynote_key);
+ if (!principal[0]) {
+ log_error("check_policy: calloc (%lu, %lu) failed",
+ (unsigned long) strlen(isakmp_sa->keynote_key),
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+#endif
+ break;
- strlcpy (principal[1], "passphrase-md5-hex:", len);
- MD5 (isakmp_sa->recv_key, strlen (isakmp_sa->recv_key), hashbuf);
- for (i = 0; i < 16; i++)
- snprintf (principal[1] + 2 * i + sizeof "passphrase-md5-hex:" - 1,
- 3, "%02x", hashbuf[i]);
-
- len = sizeof "passphrase-sha1-hex:" + 2 * 20;
- principal[2] = calloc (len, sizeof (char));
- if (!principal[2])
- {
- log_error ("check_policy: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto policydone;
- }
+ case ISAKMP_CERTENC_X509_SIG:
+#ifdef USE_X509
+ principal = calloc(2, sizeof *principal);
+ if (!principal) {
+ log_error("check_policy: calloc (2, %lu) failed",
+ (unsigned long) sizeof *principal);
+ goto policydone;
+ }
+ if (isakmp_sa->recv_keytype == ISAKMP_KEY_RSA)
+ dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
+ else {
+ log_error("check_policy: unknown/unsupported public key algorithm "
+ "%d", isakmp_sa->recv_keytype);
+ goto policydone;
+ }
- strlcpy (principal[2], "passphrase-sha1-hex:", len);
- SHA1 (isakmp_sa->recv_key, strlen (isakmp_sa->recv_key), hashbuf);
- for (i = 0; i < 20; i++)
- snprintf (principal[2] + 2 * i + sizeof "passphrase-sha1-hex:" - 1,
- 3, "%02x", hashbuf[i]);
- break;
+ dc.dec_key = isakmp_sa->recv_key;
+ principal[0] = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
+ KEYNOTE_PUBLIC_KEY);
+ if (keynote_errno == ERROR_MEMORY) {
+ log_print("check_policy: failed to get memory for public key");
+ goto policydone;
+ }
+ if (!principal[0]) {
+ log_print("check_policy: failed to allocate memory for principal");
+ goto policydone;
+ }
+ len = strlen(principal[0]) + sizeof "rsa-hex:";
+ principal[1] = calloc(len, sizeof(char));
+ if (!principal[1]) {
+ log_error("check_policy: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+ snprintf(principal[1], len, "rsa-hex:%s", principal[0]);
+ free(principal[0]);
+ principal[0] = principal[1];
+ principal[1] = 0;
+
+ /* Generate a "DN:" principal. */
+ subject = X509_get_subject_name(isakmp_sa->recv_cert);
+ if (subject) {
+ principal[1] = calloc(259, sizeof(char));
+ if (!principal[1]) {
+ log_error("check_policy: calloc (259, %lu) failed",
+ (unsigned long) sizeof(char));
+ goto policydone;
+ }
+ strlcpy(principal[1], "DN:", 259);
+ X509_NAME_oneline(subject, principal[1] + 3, 256);
+ nprinc = 2;
+ } else {
+ nprinc = 1;
+ }
+ break;
+#endif
- case ISAKMP_CERTENC_KEYNOTE:
-#ifdef USE_KEYNOTE
- nprinc = 1;
-
- principal = calloc (nprinc, sizeof *principal);
- if (!principal)
- {
- log_error ("check_policy: calloc (%d, %lu) failed", nprinc,
- (unsigned long)sizeof *principal);
- goto policydone;
+ /* XXX Eventually handle these. */
+ case ISAKMP_CERTENC_PKCS:
+ case ISAKMP_CERTENC_PGP:
+ case ISAKMP_CERTENC_DNS:
+ case ISAKMP_CERTENC_X509_KE:
+ case ISAKMP_CERTENC_KERBEROS:
+ case ISAKMP_CERTENC_CRL:
+ case ISAKMP_CERTENC_ARL:
+ case ISAKMP_CERTENC_SPKI:
+ case ISAKMP_CERTENC_X509_ATTR:
+ default:
+ log_print("check_policy: "
+ "unknown/unsupported certificate/authentication method %d",
+ isakmp_sa->recv_certtype);
+ goto policydone;
}
- /* Dup the keys */
- principal[0] = strdup (isakmp_sa->keynote_key);
- if (!principal[0])
- {
- log_error ("check_policy: calloc (%lu, %lu) failed",
- (unsigned long)strlen (isakmp_sa->keynote_key),
- (unsigned long)sizeof (char));
- goto policydone;
+ /*
+ * Add the authorizer (who is requesting the SA/ID);
+ * this may be a public or a secret key, depending on
+ * what mode of authentication we used in Phase 1.
+ */
+ for (i = 0; i < nprinc; i++) {
+ LOG_DBG((LOG_POLICY, 40, "check_policy: adding authorizer [%s]",
+ principal[i]));
+
+ if (kn_add_authorizer(isakmp_sa->policy_id, principal[i]) == -1) {
+ int j;
+
+ for (j = 0; j < i; j++)
+ kn_remove_authorizer(isakmp_sa->policy_id, principal[j]);
+ log_print("check_policy: kn_add_authorizer failed");
+ goto policydone;
+ }
}
-#endif
- break;
- case ISAKMP_CERTENC_X509_SIG:
-#ifdef USE_X509
- principal = calloc (2, sizeof *principal);
- if (!principal)
- {
- log_error ("check_policy: calloc (2, %lu) failed",
- (unsigned long)sizeof *principal);
- goto policydone;
- }
+ /* Ask policy */
+ result = kn_do_query(isakmp_sa->policy_id, return_values, RETVALUES_NUM);
+ LOG_DBG((LOG_POLICY, 40, "check_policy: kn_do_query returned %d", result));
- if (isakmp_sa->recv_keytype == ISAKMP_KEY_RSA)
- dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
- else
- {
- log_error ("check_policy: unknown/unsupported public key algorithm "
- "%d", isakmp_sa->recv_keytype);
- goto policydone;
- }
+ /* Cleanup environment */
+ kn_cleanup_action_environment(isakmp_sa->policy_id);
- dc.dec_key = isakmp_sa->recv_key;
- principal[0] = kn_encode_key (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
- KEYNOTE_PUBLIC_KEY);
- if (keynote_errno == ERROR_MEMORY)
- {
- log_print ("check_policy: failed to get memory for public key");
- goto policydone;
+ /* Remove authorizers from the session */
+ for (i = 0; i < nprinc; i++) {
+ kn_remove_authorizer(isakmp_sa->policy_id, principal[i]);
+ free(principal[i]);
}
- if (!principal[0])
- {
- log_print ("check_policy: failed to allocate memory for principal");
- goto policydone;
- }
+ free(principal);
+ principal = 0;
+ nprinc = 0;
- len = strlen (principal[0]) + sizeof "rsa-hex:";
- principal[1] = calloc (len, sizeof (char));
- if (!principal[1])
- {
- log_error ("check_policy: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto policydone;
+ /* Check what policy said. */
+ if (result < 0) {
+ LOG_DBG((LOG_POLICY, 40, "check_policy: proposal refused"));
+ result = 0;
+ goto policydone;
+ }
+policydone:
+ for (i = 0; i < nprinc; i++)
+ if (principal && principal[i])
+ free(principal[i]);
+
+ if (principal)
+ free(principal);
+
+ /* Remove the policies */
+ for (i = 0; i < keynote_policy_asserts_num; i++) {
+ if (keynote_ids[i] != -1)
+ kn_remove_assertion(isakmp_sa->policy_id, keynote_ids[i]);
}
- snprintf (principal[1], len, "rsa-hex:%s", principal[0]);
- free (principal[0]);
- principal[0] = principal[1];
- principal[1] = 0;
+ if (keynote_ids)
+ free(keynote_ids);
- /* Generate a "DN:" principal. */
- subject = X509_get_subject_name (isakmp_sa->recv_cert);
- if (subject)
- {
- principal[1] = calloc (259, sizeof (char));
- if (!principal[1])
- {
- log_error ("check_policy: calloc (259, %lu) failed",
- (unsigned long)sizeof (char));
- goto policydone;
- }
- strlcpy (principal[1], "DN:", 259);
- X509_NAME_oneline (subject, principal[1] + 3, 256);
- nprinc = 2;
- } else {
- nprinc = 1;
- }
- break;
-#endif
+ if (x509_ids)
+ free(x509_ids);
- /* XXX Eventually handle these. */
- case ISAKMP_CERTENC_PKCS:
- case ISAKMP_CERTENC_PGP:
- case ISAKMP_CERTENC_DNS:
- case ISAKMP_CERTENC_X509_KE:
- case ISAKMP_CERTENC_KERBEROS:
- case ISAKMP_CERTENC_CRL:
- case ISAKMP_CERTENC_ARL:
- case ISAKMP_CERTENC_SPKI:
- case ISAKMP_CERTENC_X509_ATTR:
- default:
- log_print ("check_policy: "
- "unknown/unsupported certificate/authentication method %d",
- isakmp_sa->recv_certtype);
- goto policydone;
- }
-
- /*
- * Add the authorizer (who is requesting the SA/ID);
- * this may be a public or a secret key, depending on
- * what mode of authentication we used in Phase 1.
- */
- for (i = 0; i < nprinc; i++)
- {
- LOG_DBG ((LOG_POLICY, 40, "check_policy: adding authorizer [%s]",
- principal[i]));
-
- if (kn_add_authorizer (isakmp_sa->policy_id, principal[i]) == -1)
- {
- int j;
-
- for (j = 0; j < i; j++)
- kn_remove_authorizer (isakmp_sa->policy_id, principal[j]);
- log_print ("check_policy: kn_add_authorizer failed");
- goto policydone;
- }
- }
-
- /* Ask policy */
- result = kn_do_query (isakmp_sa->policy_id, return_values, RETVALUES_NUM);
- LOG_DBG ((LOG_POLICY, 40, "check_policy: kn_do_query returned %d", result));
-
- /* Cleanup environment */
- kn_cleanup_action_environment (isakmp_sa->policy_id);
-
- /* Remove authorizers from the session */
- for (i = 0; i < nprinc; i++)
- {
- kn_remove_authorizer (isakmp_sa->policy_id, principal[i]);
- free (principal[i]);
- }
-
- free (principal);
- principal = 0;
- nprinc = 0;
-
- /* Check what policy said. */
- if (result < 0)
- {
- LOG_DBG ((LOG_POLICY, 40, "check_policy: proposal refused"));
- result = 0;
- goto policydone;
- }
-
- policydone:
- for (i = 0; i < nprinc; i++)
- if (principal && principal[i])
- free (principal[i]);
-
- if (principal)
- free (principal);
-
- /* Remove the policies */
- for (i = 0; i < keynote_policy_asserts_num; i++)
- {
- if (keynote_ids[i] != -1)
- kn_remove_assertion (isakmp_sa->policy_id, keynote_ids[i]);
- }
-
- if (keynote_ids)
- free (keynote_ids);
-
- if (x509_ids)
- free (x509_ids);
-
- /*
- * XXX Currently, check_policy() is only called from message_negotiate_sa(),
- * and so this log message reflects this. Change to something better?
- */
- if (result == 0)
- log_print ("check_policy: negotiated SA failed policy check");
-
- /*
- * Given that we have only 2 return values from policy (true/false)
- * we can just return the query result directly (no pre-processing needed).
- */
- return result;
+ /*
+ * XXX Currently, check_policy() is only called from message_negotiate_sa(),
+ * and so this log message reflects this. Change to something better?
+ */
+ if (result == 0)
+ log_print("check_policy: negotiated SA failed policy check");
+
+ /*
+ * Given that we have only 2 return values from policy (true/false)
+ * we can just return the query result directly (no pre-processing needed).
+ */
+ return result;
}
-#endif /* USE_POLICY */
+#endif /* USE_POLICY */
/*
* Offer several sets of transforms to the responder.
* XXX Split this huge function up and look for common code with main mode.
*/
static int
-initiator_send_HASH_SA_NONCE (struct message *msg)
+initiator_send_HASH_SA_NONCE(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct doi *doi = exchange->doi;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t ***transform = 0, ***new_transform;
- u_int8_t **proposal = 0, **new_proposal;
- u_int8_t *sa_buf = 0, *attr, *saved_nextp_sa, *saved_nextp_prop, *id, *spi;
- size_t spi_sz, sz;
- size_t proposal_len = 0, proposals_len = 0, sa_len;
- size_t **transform_len = 0, **new_transform_len;
- size_t *transforms_len = 0, *new_transforms_len;
- u_int32_t *transform_cnt = 0, *new_transform_cnt;
- u_int32_t suite_no, prop_no, prot_no, xf_no, prop_cnt = 0;
- u_int32_t i;
- int value, update_nextp, protocol_num, proto_id;
- struct proto *proto;
- struct conf_list *suite_conf, *prot_conf = 0, *xf_conf = 0, *life_conf;
- struct conf_list_node *suite, *prot, *xf, *life;
- struct constant_map *id_map;
- char *protocol_id, *transform_id;
- char *local_id, *remote_id;
- int group_desc = -1, new_group_desc;
- struct ipsec_sa *isa = msg->isakmp_sa->data;
- struct hash *hash = hash_get (isa->hash);
- struct sockaddr *src;
- struct proto_attr *pa;
-
- if (!ipsec_add_hash_payload (msg, hash->hashsize))
- return -1;
-
- /* Get the list of protocol suites. */
- suite_conf = conf_get_list (exchange->policy, "Suites");
- if (!suite_conf)
- return -1;
-
- for (suite = TAILQ_FIRST (&suite_conf->fields), suite_no = prop_no = 0;
- suite_no < suite_conf->cnt;
- suite_no++, suite = TAILQ_NEXT (suite, link))
- {
- /* Now get each protocol in this specific protocol suite. */
- prot_conf = conf_get_list (suite->field, "Protocols");
- if (!prot_conf)
- goto bail_out;
-
- for (prot = TAILQ_FIRST (&prot_conf->fields), prot_no = 0;
- prot_no < prot_conf->cnt;
- prot_no++, prot = TAILQ_NEXT (prot, link))
- {
- /* Make sure we have a proposal/transform vectors. */
- if (prop_no >= prop_cnt)
- {
- /* This resize algorithm is completely arbitrary. */
- prop_cnt = 2 * prop_cnt + 10;
- new_proposal = realloc (proposal, prop_cnt * sizeof *proposal);
- if (!new_proposal)
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "realloc (%p, %lu) failed",
- proposal,
- prop_cnt * (unsigned long)sizeof *proposal);
- goto bail_out;
- }
- proposal = new_proposal;
-
- new_transforms_len = realloc (transforms_len,
- prop_cnt * sizeof *transforms_len);
- if (!new_transforms_len)
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "realloc (%p, %lu) failed",
- transforms_len,
- prop_cnt * (unsigned long)sizeof *transforms_len);
- goto bail_out;
- }
- transforms_len = new_transforms_len;
-
- new_transform = realloc (transform,
- prop_cnt * sizeof *transform);
- if (!new_transform)
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "realloc (%p, %lu) failed",
- transform,
- prop_cnt * (unsigned long)sizeof *transform);
- goto bail_out;
- }
- transform = new_transform;
-
- new_transform_cnt = realloc (transform_cnt,
- prop_cnt * sizeof *transform_cnt);
- if (!new_transform_cnt)
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "realloc (%p, %lu) failed",
- transform_cnt,
- prop_cnt * (unsigned long)sizeof *transform_cnt);
- goto bail_out;
- }
- transform_cnt = new_transform_cnt;
-
- new_transform_len = realloc (transform_len,
- prop_cnt * sizeof *transform_len);
- if (!new_transform_len)
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "realloc (%p, %lu) failed",
- transform_len,
- prop_cnt * (unsigned long)sizeof *transform_len);
- goto bail_out;
- }
- transform_len = new_transform_len;
- }
-
- protocol_id = conf_get_str (prot->field, "PROTOCOL_ID");
- if (!protocol_id)
- goto bail_out;
-
- proto_id = constant_value (ipsec_proto_cst, protocol_id);
- switch (proto_id)
- {
- case IPSEC_PROTO_IPSEC_AH:
- id_map = ipsec_ah_cst;
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- id_map = ipsec_esp_cst;
- break;
-
- case IPSEC_PROTO_IPCOMP:
- id_map = ipsec_ipcomp_cst;
- break;
-
- default:
- {
- log_print ("initiator_send_HASH_SA_NONCE: invalid PROTCOL_ID: "
- "%s", protocol_id);
- goto bail_out;
- }
- }
-
- /* Now get each transform we offer for this protocol. */
- xf_conf = conf_get_list (prot->field, "Transforms");
- if (!xf_conf)
- goto bail_out;
- transform_cnt[prop_no] = xf_conf->cnt;
-
- transform[prop_no] = calloc (transform_cnt[prop_no],
- sizeof **transform);
- if (!transform[prop_no])
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "calloc (%d, %lu) failed",
- transform_cnt[prop_no],
- (unsigned long)sizeof **transform);
- goto bail_out;
- }
-
- transform_len[prop_no]
- = calloc (transform_cnt[prop_no], sizeof **transform_len);
- if (!transform_len[prop_no])
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "calloc (%d, %lu) failed",
- transform_cnt[prop_no],
- (unsigned long)sizeof **transform_len);
- goto bail_out;
- }
-
- transforms_len[prop_no] = 0;
- for (xf = TAILQ_FIRST (&xf_conf->fields), xf_no = 0;
- xf_no < transform_cnt[prop_no];
- xf_no++, xf = TAILQ_NEXT (xf, link))
- {
-
- /* XXX The sizing needs to be dynamic. */
- transform[prop_no][xf_no] = calloc (ISAKMP_TRANSFORM_SA_ATTRS_OFF
- + 9 * ISAKMP_ATTR_VALUE_OFF,
- 1);
- if (!transform[prop_no][xf_no])
- {
- log_error ("initiator_send_HASH_SA_NONCE: "
- "calloc (%d, 1) failed",
- ISAKMP_TRANSFORM_SA_ATTRS_OFF
- + 9 * ISAKMP_ATTR_VALUE_OFF);
- goto bail_out;
- }
+ struct exchange *exchange = msg->exchange;
+ struct doi *doi = exchange->doi;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t ***transform = 0, ***new_transform;
+ u_int8_t **proposal = 0, **new_proposal;
+ u_int8_t *sa_buf = 0, *attr, *saved_nextp_sa, *saved_nextp_prop,
+ *id, *spi;
+ size_t spi_sz, sz;
+ size_t proposal_len = 0, proposals_len = 0, sa_len;
+ size_t **transform_len = 0, **new_transform_len;
+ size_t *transforms_len = 0, *new_transforms_len;
+ u_int32_t *transform_cnt = 0, *new_transform_cnt;
+ u_int32_t suite_no, prop_no, prot_no, xf_no, prop_cnt = 0;
+ u_int32_t i;
+ int value, update_nextp, protocol_num, proto_id;
+ struct proto *proto;
+ struct conf_list *suite_conf, *prot_conf = 0, *xf_conf = 0, *life_conf;
+ struct conf_list_node *suite, *prot, *xf, *life;
+ struct constant_map *id_map;
+ char *protocol_id, *transform_id;
+ char *local_id, *remote_id;
+ int group_desc = -1, new_group_desc;
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct hash *hash = hash_get(isa->hash);
+ struct sockaddr *src;
+ struct proto_attr *pa;
+
+ if (!ipsec_add_hash_payload(msg, hash->hashsize))
+ return -1;
+
+ /* Get the list of protocol suites. */
+ suite_conf = conf_get_list(exchange->policy, "Suites");
+ if (!suite_conf)
+ return -1;
+
+ for (suite = TAILQ_FIRST(&suite_conf->fields), suite_no = prop_no = 0;
+ suite_no < suite_conf->cnt;
+ suite_no++, suite = TAILQ_NEXT(suite, link)) {
+ /* Now get each protocol in this specific protocol suite. */
+ prot_conf = conf_get_list(suite->field, "Protocols");
+ if (!prot_conf)
+ goto bail_out;
+
+ for (prot = TAILQ_FIRST(&prot_conf->fields), prot_no = 0;
+ prot_no < prot_conf->cnt;
+ prot_no++, prot = TAILQ_NEXT(prot, link)) {
+ /* Make sure we have a proposal/transform vectors. */
+ if (prop_no >= prop_cnt) {
+ /*
+ * This resize algorithm is completely
+ * arbitrary.
+ */
+ prop_cnt = 2 * prop_cnt + 10;
+ new_proposal = realloc(proposal,
+ prop_cnt * sizeof *proposal);
+ if (!new_proposal) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "realloc (%p, %lu) failed",
+ proposal,
+ prop_cnt * (unsigned long) sizeof *proposal);
+ goto bail_out;
+ }
+ proposal = new_proposal;
+
+ new_transforms_len = realloc(transforms_len,
+ prop_cnt * sizeof *transforms_len);
+ if (!new_transforms_len) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "realloc (%p, %lu) failed",
+ transforms_len,
+ prop_cnt * (unsigned long) sizeof *transforms_len);
+ goto bail_out;
+ }
+ transforms_len = new_transforms_len;
+
+ new_transform = realloc(transform,
+ prop_cnt * sizeof *transform);
+ if (!new_transform) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "realloc (%p, %lu) failed",
+ transform,
+ prop_cnt * (unsigned long) sizeof *transform);
+ goto bail_out;
+ }
+ transform = new_transform;
+
+ new_transform_cnt = realloc(transform_cnt,
+ prop_cnt * sizeof *transform_cnt);
+ if (!new_transform_cnt) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "realloc (%p, %lu) failed",
+ transform_cnt,
+ prop_cnt * (unsigned long) sizeof *transform_cnt);
+ goto bail_out;
+ }
+ transform_cnt = new_transform_cnt;
+
+ new_transform_len = realloc(transform_len,
+ prop_cnt * sizeof *transform_len);
+ if (!new_transform_len) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "realloc (%p, %lu) failed",
+ transform_len,
+ prop_cnt * (unsigned long) sizeof *transform_len);
+ goto bail_out;
+ }
+ transform_len = new_transform_len;
+ }
+ protocol_id = conf_get_str(prot->field, "PROTOCOL_ID");
+ if (!protocol_id)
+ goto bail_out;
+
+ proto_id = constant_value(ipsec_proto_cst, protocol_id);
+ switch (proto_id) {
+ case IPSEC_PROTO_IPSEC_AH:
+ id_map = ipsec_ah_cst;
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ id_map = ipsec_esp_cst;
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ id_map = ipsec_ipcomp_cst;
+ break;
+
+ default:
+ {
+ log_print("initiator_send_HASH_SA_NONCE: invalid PROTCOL_ID: "
+ "%s", protocol_id);
+ goto bail_out;
+ }
+ }
+
+ /* Now get each transform we offer for this protocol. */
+ xf_conf = conf_get_list(prot->field, "Transforms");
+ if (!xf_conf)
+ goto bail_out;
+ transform_cnt[prop_no] = xf_conf->cnt;
+
+ transform[prop_no] = calloc(transform_cnt[prop_no],
+ sizeof **transform);
+ if (!transform[prop_no]) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "calloc (%d, %lu) failed",
+ transform_cnt[prop_no],
+ (unsigned long) sizeof **transform);
+ goto bail_out;
+ }
+ transform_len[prop_no] = calloc(transform_cnt[prop_no],
+ sizeof **transform_len);
+ if (!transform_len[prop_no]) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "calloc (%d, %lu) failed",
+ transform_cnt[prop_no],
+ (unsigned long) sizeof **transform_len);
+ goto bail_out;
+ }
+ transforms_len[prop_no] = 0;
+ for (xf = TAILQ_FIRST(&xf_conf->fields), xf_no = 0;
+ xf_no < transform_cnt[prop_no];
+ xf_no++, xf = TAILQ_NEXT(xf, link)) {
+
+ /* XXX The sizing needs to be dynamic. */
+ transform[prop_no][xf_no] =
+ calloc(ISAKMP_TRANSFORM_SA_ATTRS_OFF +
+ 9 * ISAKMP_ATTR_VALUE_OFF, 1);
+ if (!transform[prop_no][xf_no]) {
+ log_error("initiator_send_HASH_SA_NONCE: "
+ "calloc (%d, 1) failed",
+ ISAKMP_TRANSFORM_SA_ATTRS_OFF +
+ 9 * ISAKMP_ATTR_VALUE_OFF);
+ goto bail_out;
+ }
+ SET_ISAKMP_TRANSFORM_NO(transform[prop_no][xf_no],
+ xf_no + 1);
+
+ transform_id = conf_get_str(xf->field, "TRANSFORM_ID");
+ if (!transform_id)
+ goto bail_out;
+ SET_ISAKMP_TRANSFORM_ID(transform[prop_no][xf_no],
+ constant_value(id_map, transform_id));
+ SET_ISAKMP_TRANSFORM_RESERVED(transform[prop_no][xf_no], 0);
+
+ attr = transform[prop_no][xf_no] + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
+
+ /*
+ * Life durations are special, we should be able to specify
+ * several, one per type.
+ */
+ life_conf = conf_get_list(xf->field, "Life");
+ if (life_conf) {
+ for (life = TAILQ_FIRST(&life_conf->fields); life;
+ life = TAILQ_NEXT(life, link)) {
+ attribute_set_constant(life->field, "LIFE_TYPE",
+ ipsec_duration_cst,
+ IPSEC_ATTR_SA_LIFE_TYPE, &attr);
+
+ /*
+ * XXX Deals with 16 and 32
+ * bit lifetimes only
+ */
+ value = conf_get_num(life->field, "LIFE_DURATION", 0);
+ if (value) {
+ if (value <= 0xffff)
+ attr =
+ attribute_set_basic(attr,
+ IPSEC_ATTR_SA_LIFE_DURATION,
+ value);
+ else {
+ value = htonl(value);
+ attr =
+ attribute_set_var(attr,
+ IPSEC_ATTR_SA_LIFE_DURATION,
+ (u_int8_t *) & value,
+ sizeof value);
+ }
+ }
+ }
+ conf_free_list(life_conf);
+ }
+ attribute_set_constant(xf->field, "ENCAPSULATION_MODE",
+ ipsec_encap_cst,
+ IPSEC_ATTR_ENCAPSULATION_MODE, &attr);
- SET_ISAKMP_TRANSFORM_NO (transform[prop_no][xf_no], xf_no + 1);
+ if (proto_id != IPSEC_PROTO_IPCOMP) {
+ attribute_set_constant(xf->field,
+ "AUTHENTICATION_ALGORITHM",
+ ipsec_auth_cst,
+ IPSEC_ATTR_AUTHENTICATION_ALGORITHM,
+ &attr);
+
+ attribute_set_constant(xf->field, "GROUP_DESCRIPTION",
+ ike_group_desc_cst,
+ IPSEC_ATTR_GROUP_DESCRIPTION, &attr);
+
+ value = conf_get_num(xf->field, "KEY_LENGTH", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IPSEC_ATTR_KEY_LENGTH,
+ value);
+
+ value = conf_get_num(xf->field, "KEY_ROUNDS", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IPSEC_ATTR_KEY_ROUNDS,
+ value);
+ } else {
+ value = conf_get_num(xf->field, "COMPRESS_DICTIONARY_SIZE",
+ 0);
+ if (value)
+ attr = attribute_set_basic(attr,
+ IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE,
+ value);
+
+ value = conf_get_num(xf->field,
+ "COMPRESS_PRIVATE_ALGORITHM", 0);
+ if (value)
+ attr = attribute_set_basic(attr,
+ IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM,
+ value);
+ }
+
+ value = conf_get_num(xf->field, "ECN_TUNNEL", 0);
+ if (value)
+ attr = attribute_set_basic(attr, IPSEC_ATTR_ECN_TUNNEL,
+ value);
+
+ /* Record the real transform size. */
+ transforms_len[prop_no] += (transform_len[prop_no][xf_no]
+ = attr - transform[prop_no][xf_no]);
+
+ if (proto_id != IPSEC_PROTO_IPCOMP) {
+ /*
+ * Make sure that if a group description is specified, it is
+ * specified for all transforms equally.
+ */
+ attr = (u_int8_t *) conf_get_str(xf->field,
+ "GROUP_DESCRIPTION");
+ new_group_desc
+ = attr ? constant_value(ike_group_desc_cst,
+ (char *) attr) : 0;
+ if (group_desc == -1)
+ group_desc = new_group_desc;
+ else if (group_desc != new_group_desc) {
+ log_print("initiator_send_HASH_SA_NONCE: "
+ "differing group descriptions in a proposal");
+ goto bail_out;
+ }
+ }
+ }
+ conf_free_list(xf_conf);
+ xf_conf = 0;
+
+ /*
+ * Get SPI from application.
+ * XXX Should we care about unknown constants?
+ */
+ protocol_num = constant_value(ipsec_proto_cst, protocol_id);
+ spi = doi->get_spi(&spi_sz, protocol_num, msg);
+ if (spi_sz && !spi) {
+ log_print("initiator_send_HASH_SA_NONCE: doi->get_spi failed");
+ goto bail_out;
+ }
+ proposal_len = ISAKMP_PROP_SPI_OFF + spi_sz;
+ proposals_len += proposal_len + transforms_len[prop_no];
+ proposal[prop_no] = malloc(proposal_len);
+ if (!proposal[prop_no]) {
+ log_error("initiator_send_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) proposal_len);
+ goto bail_out;
+ }
+ SET_ISAKMP_PROP_NO(proposal[prop_no], suite_no + 1);
+ SET_ISAKMP_PROP_PROTO(proposal[prop_no], protocol_num);
+
+ /* XXX I would like to see this factored out. */
+ proto = calloc(1, sizeof *proto);
+ if (!proto) {
+ log_error("initiator_send_HASH_SA_NONCE: calloc (1, %lu) "
+ "failed", (unsigned long) sizeof *proto);
+ goto bail_out;
+ }
+ if (doi->proto_size) {
+ proto->data = calloc(1, doi->proto_size);
+ if (!proto->data) {
+ log_error("initiator_send_HASH_SA_NONCE: calloc (1, %lu) "
+ "failed", (unsigned long) doi->proto_size);
+ goto bail_out;
+ }
+ }
+ proto->no = suite_no + 1;
+ proto->proto = protocol_num;
+ proto->sa = TAILQ_FIRST(&exchange->sa_list);
+ proto->xf_cnt = transform_cnt[prop_no];
+ TAILQ_INIT(&proto->xfs);
+ for (xf_no = 0; xf_no < proto->xf_cnt; xf_no++) {
+ pa = (struct proto_attr *) calloc(1, sizeof *pa);
+ if (!pa)
+ goto bail_out;
+ pa->len = transform_len[prop_no][xf_no];
+ pa->attrs = (u_int8_t *) malloc(pa->len);
+ if (!pa->attrs) {
+ free(pa);
+ goto bail_out;
+ }
+ memcpy(pa->attrs, transform[prop_no][xf_no], pa->len);
+ TAILQ_INSERT_TAIL(&proto->xfs, pa, next);
+ }
+ TAILQ_INSERT_TAIL(&TAILQ_FIRST(&exchange->sa_list)->protos, proto,
+ link);
+
+ /* Setup the incoming SPI. */
+ SET_ISAKMP_PROP_SPI_SZ(proposal[prop_no], spi_sz);
+ memcpy(proposal[prop_no] + ISAKMP_PROP_SPI_OFF, spi, spi_sz);
+ proto->spi_sz[1] = spi_sz;
+ proto->spi[1] = spi;
+
+ /*
+ * Let the DOI get at proto for initializing its own
+ * data.
+ */
+ if (doi->proto_init)
+ doi->proto_init(proto, prot->field);
+
+ SET_ISAKMP_PROP_NTRANSFORMS(proposal[prop_no],
+ transform_cnt[prop_no]);
+ prop_no++;
+ }
+ conf_free_list(prot_conf);
+ prot_conf = 0;
+ }
- transform_id = conf_get_str (xf->field, "TRANSFORM_ID");
- if (!transform_id)
+ sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN;
+ sa_buf = malloc(sa_len);
+ if (!sa_buf) {
+ log_error("initiator_send_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) sa_len);
+ goto bail_out;
+ }
+ SET_ISAKMP_SA_DOI(sa_buf, IPSEC_DOI_IPSEC);
+ SET_IPSEC_SIT_SIT(sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
+
+ /*
+ * Add the payloads. As this is a SA, we need to recompute the
+ * lengths of the payloads containing others. We also need to
+ * reset these payload's "next payload type" field.
+ */
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
goto bail_out;
- SET_ISAKMP_TRANSFORM_ID (transform[prop_no][xf_no],
- constant_value (id_map, transform_id));
- SET_ISAKMP_TRANSFORM_RESERVED (transform[prop_no][xf_no], 0);
-
- attr = transform[prop_no][xf_no] + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
-
- /*
- * Life durations are special, we should be able to specify
- * several, one per type.
- */
- life_conf = conf_get_list (xf->field, "Life");
- if (life_conf)
- {
- for (life = TAILQ_FIRST (&life_conf->fields); life;
- life = TAILQ_NEXT (life, link))
- {
- attribute_set_constant (life->field, "LIFE_TYPE",
- ipsec_duration_cst,
- IPSEC_ATTR_SA_LIFE_TYPE, &attr);
-
- /* XXX Deals with 16 and 32 bit lifetimes only */
- value = conf_get_num (life->field, "LIFE_DURATION", 0);
- if (value)
- {
- if (value <= 0xffff)
- attr =
- attribute_set_basic (attr,
- IPSEC_ATTR_SA_LIFE_DURATION,
- value);
- else
- {
- value = htonl (value);
- attr =
- attribute_set_var (attr,
- IPSEC_ATTR_SA_LIFE_DURATION,
- (u_int8_t *)&value,
- sizeof value);
- }
- }
- }
- conf_free_list (life_conf);
+ SET_ISAKMP_GEN_LENGTH(sa_buf, sa_len + proposals_len);
+ sa_buf = 0;
+
+ update_nextp = 0;
+ saved_nextp_sa = msg->nextp;
+ for (i = 0; i < prop_no; i++) {
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL, proposal[i],
+ proposal_len, update_nextp))
+ goto bail_out;
+ SET_ISAKMP_GEN_LENGTH(proposal[i], proposal_len + transforms_len[i]);
+ proposal[i] = 0;
+
+ update_nextp = 0;
+ saved_nextp_prop = msg->nextp;
+ for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++) {
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM,
+ transform[i][xf_no],
+ transform_len[i][xf_no], update_nextp))
+ goto bail_out;
+ update_nextp = 1;
+ transform[i][xf_no] = 0;
}
+ msg->nextp = saved_nextp_prop;
+ update_nextp = 1;
+ }
+ msg->nextp = saved_nextp_sa;
- attribute_set_constant (xf->field, "ENCAPSULATION_MODE",
- ipsec_encap_cst,
- IPSEC_ATTR_ENCAPSULATION_MODE, &attr);
-
- if (proto_id != IPSEC_PROTO_IPCOMP)
- {
- attribute_set_constant (xf->field,
- "AUTHENTICATION_ALGORITHM",
- ipsec_auth_cst,
- IPSEC_ATTR_AUTHENTICATION_ALGORITHM,
- &attr);
-
- attribute_set_constant (xf->field, "GROUP_DESCRIPTION",
- ike_group_desc_cst,
- IPSEC_ATTR_GROUP_DESCRIPTION, &attr);
-
- value = conf_get_num (xf->field, "KEY_LENGTH", 0);
- if (value)
- attr = attribute_set_basic (attr, IPSEC_ATTR_KEY_LENGTH,
- value);
-
- value = conf_get_num (xf->field, "KEY_ROUNDS", 0);
- if (value)
- attr = attribute_set_basic (attr, IPSEC_ATTR_KEY_ROUNDS,
- value);
- }
- else
- {
- value = conf_get_num (xf->field, "COMPRESS_DICTIONARY_SIZE",
- 0);
- if (value)
- attr = attribute_set_basic (attr,
- IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE,
- value);
-
- value = conf_get_num (xf->field,
- "COMPRESS_PRIVATE_ALGORITHM", 0);
- if (value)
- attr = attribute_set_basic (attr,
- IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM,
- value);
- }
+ /*
+ * Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len.
+ */
+ ie->sa_i_b = message_copy(msg, ISAKMP_GEN_SZ, &ie->sa_i_b_len);
+ if (!ie->sa_i_b)
+ goto bail_out;
- value = conf_get_num (xf->field, "ECN_TUNNEL", 0);
- if (value)
- attr = attribute_set_basic (attr, IPSEC_ATTR_ECN_TUNNEL,
- value);
-
- /* Record the real transform size. */
- transforms_len[prop_no] += (transform_len[prop_no][xf_no]
- = attr - transform[prop_no][xf_no]);
-
- if (proto_id != IPSEC_PROTO_IPCOMP)
- {
- /*
- * Make sure that if a group description is specified, it is
- * specified for all transforms equally.
- */
- attr = (u_int8_t *)conf_get_str (xf->field,
- "GROUP_DESCRIPTION");
- new_group_desc
- = attr ? constant_value (ike_group_desc_cst,
- (char *)attr) : 0;
- if (group_desc == -1)
- group_desc = new_group_desc;
- else if (group_desc != new_group_desc)
- {
- log_print ("initiator_send_HASH_SA_NONCE: "
- "differing group descriptions in a proposal");
- goto bail_out;
- }
+ /*
+ * Generate a nonce, and add it to the message.
+ * XXX I want a better way to specify the nonce's size.
+ */
+ if (exchange_gen_nonce(msg, 16))
+ return -1;
+
+ /* Generate optional KEY_EXCH payload. */
+ if (group_desc > 0) {
+ ie->group = group_get(group_desc);
+ ie->g_x_len = dh_getlen(ie->group);
+
+ if (ipsec_gen_g_x(msg)) {
+ group_free(ie->group);
+ ie->group = 0;
+ return -1;
}
- }
- conf_free_list (xf_conf);
- xf_conf = 0;
-
- /*
- * Get SPI from application.
- * XXX Should we care about unknown constants?
- */
- protocol_num = constant_value (ipsec_proto_cst, protocol_id);
- spi = doi->get_spi (&spi_sz, protocol_num, msg);
- if (spi_sz && !spi)
- {
- log_print ("initiator_send_HASH_SA_NONCE: doi->get_spi failed");
- goto bail_out;
- }
-
- proposal_len = ISAKMP_PROP_SPI_OFF + spi_sz;
- proposals_len += proposal_len + transforms_len[prop_no];
- proposal[prop_no] = malloc (proposal_len);
- if (!proposal[prop_no])
- {
- log_error ("initiator_send_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)proposal_len);
- goto bail_out;
- }
-
- SET_ISAKMP_PROP_NO (proposal[prop_no], suite_no + 1);
- SET_ISAKMP_PROP_PROTO (proposal[prop_no], protocol_num);
-
- /* XXX I would like to see this factored out. */
- proto = calloc (1, sizeof *proto);
- if (!proto)
- {
- log_error ("initiator_send_HASH_SA_NONCE: calloc (1, %lu) "
- "failed", (unsigned long)sizeof *proto);
- goto bail_out;
- }
-
- if (doi->proto_size)
- {
- proto->data = calloc (1, doi->proto_size);
- if (!proto->data)
- {
- log_error ("initiator_send_HASH_SA_NONCE: calloc (1, %lu) "
- "failed", (unsigned long)doi->proto_size);
- goto bail_out;
+ }
+ /* Generate optional client ID payloads. XXX Share with responder. */
+ local_id = conf_get_str(exchange->name, "Local-ID");
+ remote_id = conf_get_str(exchange->name, "Remote-ID");
+ if (local_id && remote_id) {
+ id = ipsec_build_id(local_id, &sz);
+ if (!id)
+ return -1;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
}
- }
-
- proto->no = suite_no + 1;
- proto->proto = protocol_num;
- proto->sa = TAILQ_FIRST (&exchange->sa_list);
- proto->xf_cnt = transform_cnt[prop_no];
- TAILQ_INIT (&proto->xfs);
- for (xf_no = 0; xf_no < proto->xf_cnt; xf_no++)
- {
- pa = (struct proto_attr *)calloc (1, sizeof *pa);
- if (!pa)
- goto bail_out;
- pa->len = transform_len[prop_no][xf_no];
- pa->attrs = (u_int8_t *)malloc (pa->len);
- if (!pa->attrs)
- {
- free (pa);
- goto bail_out;
+ id = ipsec_build_id(remote_id, &sz);
+ if (!id)
+ return -1;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
}
- memcpy (pa->attrs, transform[prop_no][xf_no], pa->len);
- TAILQ_INSERT_TAIL (&proto->xfs, pa, next);
- }
- TAILQ_INSERT_TAIL (&TAILQ_FIRST (&exchange->sa_list)->protos, proto,
- link);
-
- /* Setup the incoming SPI. */
- SET_ISAKMP_PROP_SPI_SZ (proposal[prop_no], spi_sz);
- memcpy (proposal[prop_no] + ISAKMP_PROP_SPI_OFF, spi, spi_sz);
- proto->spi_sz[1] = spi_sz;
- proto->spi[1] = spi;
-
- /* Let the DOI get at proto for initializing its own data. */
- if (doi->proto_init)
- doi->proto_init (proto, prot->field);
-
- SET_ISAKMP_PROP_NTRANSFORMS (proposal[prop_no],
- transform_cnt[prop_no]);
- prop_no++;
- }
- conf_free_list (prot_conf);
- prot_conf = 0;
- }
-
- sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN;
- sa_buf = malloc (sa_len);
- if (!sa_buf)
- {
- log_error ("initiator_send_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)sa_len);
- goto bail_out;
- }
- SET_ISAKMP_SA_DOI (sa_buf, IPSEC_DOI_IPSEC);
- SET_IPSEC_SIT_SIT (sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
-
- /*
- * Add the payloads. As this is a SA, we need to recompute the
- * lengths of the payloads containing others. We also need to
- * reset these payload's "next payload type" field.
- */
- if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
- goto bail_out;
- SET_ISAKMP_GEN_LENGTH (sa_buf, sa_len + proposals_len);
- sa_buf = 0;
-
- update_nextp = 0;
- saved_nextp_sa = msg->nextp;
- for (i = 0; i < prop_no; i++)
- {
- if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposal[i],
- proposal_len, update_nextp))
- goto bail_out;
- SET_ISAKMP_GEN_LENGTH (proposal[i], proposal_len + transforms_len[i]);
- proposal[i] = 0;
-
- update_nextp = 0;
- saved_nextp_prop = msg->nextp;
- for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++)
- {
- if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM,
- transform[i][xf_no],
- transform_len[i][xf_no], update_nextp))
- goto bail_out;
- update_nextp = 1;
- transform[i][xf_no] = 0;
- }
- msg->nextp = saved_nextp_prop;
- update_nextp = 1;
- }
- msg->nextp = saved_nextp_sa;
-
- /*
- * Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len.
- */
- ie->sa_i_b = message_copy (msg, ISAKMP_GEN_SZ, &ie->sa_i_b_len);
- if (!ie->sa_i_b)
- goto bail_out;
-
- /*
- * Generate a nonce, and add it to the message.
- * XXX I want a better way to specify the nonce's size.
- */
- if (exchange_gen_nonce (msg, 16))
- return -1;
-
- /* Generate optional KEY_EXCH payload. */
- if (group_desc > 0)
- {
- ie->group = group_get (group_desc);
- ie->g_x_len = dh_getlen (ie->group);
-
- if (ipsec_gen_g_x (msg))
- {
- group_free (ie->group);
- ie->group = 0;
- return -1;
- }
- }
-
- /* Generate optional client ID payloads. XXX Share with responder. */
- local_id = conf_get_str (exchange->name, "Local-ID");
- remote_id = conf_get_str (exchange->name, "Remote-ID");
- if (local_id && remote_id)
- {
- id = ipsec_build_id (local_id, &sz);
- if (!id)
- return -1;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
- }
-
- id = ipsec_build_id (remote_id, &sz);
- if (!id)
- return -1;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
}
- }
- /* XXX I do not judge these as errors, are they? */
- else if (local_id)
- log_print ("initiator_send_HASH_SA_NONCE: "
- "Local-ID given without Remote-ID for \"%s\"",
- exchange->name);
- else if (remote_id)
- /* This code supports the "road warrior" case, where the initiator doesn't
- * have a fixed IP address, but wants to specify a particular remote
- * network to talk to.
- * -- Adrian Close <adrian@esec.com.au>
- */
- {
- log_print ("initiator_send_HASH_SA_NONCE: "
- "Remote-ID given without Local-ID for \"%s\"",
- exchange->name);
-
- /* If we're here, then we are the initiator, so use initiator
- address for local ID */
- msg->transport->vtbl->get_src (msg->transport, &src);
- sz = ISAKMP_ID_SZ + sockaddr_addrlen (src);
-
- id = calloc (sz, sizeof (char));
- if (!id)
+ /* XXX I do not judge these as errors, are they? */
+ else if (local_id)
+ log_print("initiator_send_HASH_SA_NONCE: "
+ "Local-ID given without Remote-ID for \"%s\"",
+ exchange->name);
+ else if (remote_id)
+ /*
+ * This code supports the "road warrior" case, where the
+ * initiator doesn't have a fixed IP address, but wants to
+ * specify a particular remote network to talk to. -- Adrian
+ * Close <adrian@esec.com.au>
+ */
{
- log_error ("initiator_send_HASH_SA_NONCE: calloc (%lu, %lu) failed",
- (unsigned long)sz, (unsigned long)sizeof (char));
- return -1;
+ log_print("initiator_send_HASH_SA_NONCE: "
+ "Remote-ID given without Local-ID for \"%s\"",
+ exchange->name);
+
+ /*
+ * If we're here, then we are the initiator, so use initiator
+ * address for local ID
+ */
+ msg->transport->vtbl->get_src(msg->transport, &src);
+ sz = ISAKMP_ID_SZ + sockaddr_addrlen(src);
+
+ id = calloc(sz, sizeof(char));
+ if (!id) {
+ log_error("initiator_send_HASH_SA_NONCE: calloc (%lu, %lu) failed",
+ (unsigned long) sz, (unsigned long) sizeof(char));
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET6:
+ SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV6_ADDR);
+ break;
+ case AF_INET:
+ SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV4_ADDR);
+ break;
+ default:
+ log_error("initiator_send_HASH_SA_NONCE: unknown sa_family %d",
+ src->sa_family);
+ free(id);
+ return -1;
+ }
+ memcpy(id + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src),
+ sockaddr_addrlen(src));
+
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
+ }
+ /* Send supplied remote_id */
+ id = ipsec_build_id(remote_id, &sz);
+ if (!id)
+ return -1;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
+ }
}
+ if (ipsec_fill_in_hash(msg))
+ goto bail_out;
- switch (src->sa_family)
- {
- case AF_INET6:
- SET_ISAKMP_ID_TYPE (id, IPSEC_ID_IPV6_ADDR);
- break;
- case AF_INET:
- SET_ISAKMP_ID_TYPE (id, IPSEC_ID_IPV4_ADDR);
- break;
- default:
- log_error ("initiator_send_HASH_SA_NONCE: unknown sa_family %d",
- src->sa_family);
- free (id);
- return -1;
+ conf_free_list(suite_conf);
+ for (i = 0; i < prop_no; i++) {
+ free(transform[i]);
+ free(transform_len[i]);
}
- memcpy (id + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
- sockaddr_addrlen (src));
-
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
+ free(proposal);
+ free(transform);
+ free(transforms_len);
+ free(transform_len);
+ free(transform_cnt);
+ return 0;
+
+bail_out:
+ if (sa_buf)
+ free(sa_buf);
+ if (proposal) {
+ for (i = 0; i < prop_no; i++) {
+ if (proposal[i])
+ free(proposal[i]);
+ if (transform[i]) {
+ for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++)
+ if (transform[i][xf_no])
+ free(transform[i][xf_no]);
+ free(transform[i]);
+ }
+ if (transform_len[i])
+ free(transform_len[i]);
+ }
+ free(proposal);
+ free(transforms_len);
+ free(transform);
+ free(transform_len);
+ free(transform_cnt);
}
-
- /* Send supplied remote_id */
- id = ipsec_build_id (remote_id, &sz);
- if (!id)
+ if (xf_conf)
+ conf_free_list(xf_conf);
+ if (prot_conf)
+ conf_free_list(prot_conf);
+ conf_free_list(suite_conf);
return -1;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
- }
- }
-
- if (ipsec_fill_in_hash (msg))
- goto bail_out;
-
- conf_free_list (suite_conf);
- for (i = 0; i < prop_no; i++)
- {
- free (transform[i]);
- free (transform_len[i]);
- }
- free (proposal);
- free (transform);
- free (transforms_len);
- free (transform_len);
- free (transform_cnt);
- return 0;
-
- bail_out:
- if (sa_buf)
- free (sa_buf);
- if (proposal)
- {
- for (i = 0; i < prop_no; i++)
- {
- if (proposal[i])
- free (proposal[i]);
- if (transform[i])
- {
- for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++)
- if (transform[i][xf_no])
- free (transform[i][xf_no]);
- free (transform[i]);
- }
- if (transform_len[i])
- free (transform_len[i]);
- }
- free (proposal);
- free (transforms_len);
- free (transform);
- free (transform_len);
- free (transform_cnt);
- }
- if (xf_conf)
- conf_free_list (xf_conf);
- if (prot_conf)
- conf_free_list (prot_conf);
- conf_free_list (suite_conf);
- return -1;
}
/* Figure out what transform the responder chose. */
static int
-initiator_recv_HASH_SA_NONCE (struct message *msg)
+initiator_recv_HASH_SA_NONCE(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct sa *sa;
- struct proto *proto, *next_proto;
- struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]);
- struct payload *xf, *idp;
- struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- struct payload *kep = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
- struct prf *prf;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct hash *hash = hash_get (isa->hash);
- size_t hashsize = hash->hashsize;
- u_int8_t *rest;
- size_t rest_len;
- struct sockaddr *src, *dst;
-
- /* Allocate the prf and start calculating our HASH(1). XXX Share? */
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: SKEYID_a",
- (u_int8_t *)isa->skeyid_a, isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- return -1;
-
- prf->Init (prf->prfctx);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "initiator_recv_HASH_SA_NONCE: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: NONCE_I_b",
- exchange->nonce_i, exchange->nonce_i_len));
- prf->Update (prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
- rest = hashp->p + GET_ISAKMP_GEN_LENGTH (hashp->p);
- rest_len = (GET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base)
- - (rest - (u_int8_t*)msg->iov[0].iov_base));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)", rest,
- rest_len));
- prf->Update (prf->prfctx, rest, rest_len);
- prf->Final (hash->digest, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80,
- "initiator_recv_HASH_SA_NONCE: computed HASH(2)",
- hash->digest, hashsize));
- if (memcmp (hashp->p + ISAKMP_HASH_DATA_OFF, hash->digest, hashsize) != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- return -1;
- }
- /* Mark the HASH as handled. */
- hashp->flags |= PL_MARK;
-
- /*
- * As we are getting an answer on our transform offer, only one transform
- * should be given.
- *
- * XXX Currently we only support negotiating one SA per quick mode run.
- */
- if (TAILQ_NEXT (sa_p, link))
- {
- log_print ("initiator_recv_HASH_SA_NONCE: "
- "multiple SA payloads in quick mode not supported yet");
- return -1;
- }
-
- sa = TAILQ_FIRST (&exchange->sa_list);
-
- /* This is here for the policy check */
- if (kep)
- ie->pfs = 1;
-
- /* Handle optional client ID payloads. */
- idp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]);
- if (idp)
- {
- /* If IDci is there, IDcr must be too. */
- if (!TAILQ_NEXT (idp, link))
- {
- /* XXX Is this a good notify type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct sa *sa;
+ struct proto *proto, *next_proto;
+ struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]);
+ struct payload *xf, *idp;
+ struct payload *hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ struct payload *kep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
+ struct prf *prf;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct hash *hash = hash_get(isa->hash);
+ size_t hashsize = hash->hashsize;
+ u_int8_t *rest;
+ size_t rest_len;
+ struct sockaddr *src, *dst;
+
+ /* Allocate the prf and start calculating our HASH(1). XXX Share? */
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: SKEYID_a",
+ (u_int8_t *) isa->skeyid_a, isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+
+ prf->Init(prf->prfctx);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "initiator_recv_HASH_SA_NONCE: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: NONCE_I_b",
+ exchange->nonce_i, exchange->nonce_i_len));
+ prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
+ rest = hashp->p + GET_ISAKMP_GEN_LENGTH(hashp->p);
+ rest_len = (GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base)
+ - (rest - (u_int8_t *) msg->iov[0].iov_base));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)", rest,
+ rest_len));
+ prf->Update(prf->prfctx, rest, rest_len);
+ prf->Final(hash->digest, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80,
+ "initiator_recv_HASH_SA_NONCE: computed HASH(2)",
+ hash->digest, hashsize));
+ if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF, hash->digest, hashsize) != 0) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ return -1;
}
-
- /* XXX We should really compare, not override. */
- ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH (idp->p);
- ie->id_ci = malloc (ie->id_ci_sz);
- if (!ie->id_ci)
- {
- log_error ("initiator_recv_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)ie->id_ci_sz);
- return -1;
- }
- memcpy (ie->id_ci, idp->p, ie->id_ci_sz);
- idp->flags |= PL_MARK;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "initiator_recv_HASH_SA_NONCE: IDci",
- ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz
- - ISAKMP_GEN_SZ));
-
- idp = TAILQ_NEXT (idp, link);
- ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH (idp->p);
- ie->id_cr = malloc (ie->id_cr_sz);
- if (!ie->id_cr)
- {
- log_error ("initiator_recv_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)ie->id_cr_sz);
- return -1;
- }
- memcpy (ie->id_cr, idp->p, ie->id_cr_sz);
- idp->flags |= PL_MARK;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "initiator_recv_HASH_SA_NONCE: IDcr",
- ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz
- - ISAKMP_GEN_SZ));
- }
- else
- {
- /*
- * If client identifiers are not present in the exchange,
- * we fake them. RFC 2409 states:
- * The identities of the SAs negotiated in Quick Mode are
- * implicitly assumed to be the IP addresses of the ISAKMP
- * peers, without any constraints on the protocol or port
- * numbers allowed, unless client identifiers are specified
- * in Quick Mode.
- *
- * -- Michael Paddon (mwp@aba.net.au)
- */
-
- ie->flags = IPSEC_EXCH_FLAG_NO_ID;
-
- /* Get initiator and responder addresses. */
- msg->transport->vtbl->get_src (msg->transport, &src);
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen (src);
- ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen (dst);
- ie->id_ci = calloc (ie->id_ci_sz, sizeof (char));
- ie->id_cr = calloc (ie->id_cr_sz, sizeof (char));
-
- if (!ie->id_ci || !ie->id_cr)
- {
- log_error ("initiator_recv_HASH_SA_NONCE: calloc (%lu, %lu) failed",
- (unsigned long)ie->id_cr_sz, (unsigned long)sizeof (char));
- if (ie->id_ci)
- {
- free (ie->id_ci);
- ie->id_ci = 0;
- }
- if (ie->id_cr)
- {
- free (ie->id_cr);
- ie->id_cr = 0;
- }
- return -1;
+ /* Mark the HASH as handled. */
+ hashp->flags |= PL_MARK;
+
+ /*
+ * As we are getting an answer on our transform offer, only one transform
+ * should be given.
+ *
+ * XXX Currently we only support negotiating one SA per quick mode run.
+ */
+ if (TAILQ_NEXT(sa_p, link)) {
+ log_print("initiator_recv_HASH_SA_NONCE: "
+ "multiple SA payloads in quick mode not supported yet");
+ return -1;
}
-
- if (src->sa_family != dst->sa_family)
- {
- log_error ("initiator_recv_HASH_SA_NONCE: sa_family mismatch");
- free (ie->id_ci);
- ie->id_ci = 0;
- free (ie->id_cr);
- ie->id_cr = 0;
- return -1;
+ sa = TAILQ_FIRST(&exchange->sa_list);
+
+ /* This is here for the policy check */
+ if (kep)
+ ie->pfs = 1;
+
+ /* Handle optional client ID payloads. */
+ idp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]);
+ if (idp) {
+ /* If IDci is there, IDcr must be too. */
+ if (!TAILQ_NEXT(idp, link)) {
+ /* XXX Is this a good notify type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ /* XXX We should really compare, not override. */
+ ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p);
+ ie->id_ci = malloc(ie->id_ci_sz);
+ if (!ie->id_ci) {
+ log_error("initiator_recv_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->id_ci_sz);
+ return -1;
+ }
+ memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
+ idp->flags |= PL_MARK;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "initiator_recv_HASH_SA_NONCE: IDci",
+ ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz
+ - ISAKMP_GEN_SZ));
+
+ idp = TAILQ_NEXT(idp, link);
+ ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p);
+ ie->id_cr = malloc(ie->id_cr_sz);
+ if (!ie->id_cr) {
+ log_error("initiator_recv_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->id_cr_sz);
+ return -1;
+ }
+ memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
+ idp->flags |= PL_MARK;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "initiator_recv_HASH_SA_NONCE: IDcr",
+ ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz
+ - ISAKMP_GEN_SZ));
+ } else {
+ /*
+ * If client identifiers are not present in the exchange,
+ * we fake them. RFC 2409 states:
+ * The identities of the SAs negotiated in Quick Mode are
+ * implicitly assumed to be the IP addresses of the ISAKMP
+ * peers, without any constraints on the protocol or port
+ * numbers allowed, unless client identifiers are specified
+ * in Quick Mode.
+ *
+ * -- Michael Paddon (mwp@aba.net.au)
+ */
+
+ ie->flags = IPSEC_EXCH_FLAG_NO_ID;
+
+ /* Get initiator and responder addresses. */
+ msg->transport->vtbl->get_src(msg->transport, &src);
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(src);
+ ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(dst);
+ ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
+ ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
+
+ if (!ie->id_ci || !ie->id_cr) {
+ log_error("initiator_recv_HASH_SA_NONCE: calloc (%lu, %lu) failed",
+ (unsigned long) ie->id_cr_sz, (unsigned long) sizeof(char));
+ if (ie->id_ci) {
+ free(ie->id_ci);
+ ie->id_ci = 0;
+ }
+ if (ie->id_cr) {
+ free(ie->id_cr);
+ ie->id_cr = 0;
+ }
+ return -1;
+ }
+ if (src->sa_family != dst->sa_family) {
+ log_error("initiator_recv_HASH_SA_NONCE: sa_family mismatch");
+ free(ie->id_ci);
+ ie->id_ci = 0;
+ free(ie->id_cr);
+ ie->id_cr = 0;
+ return -1;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR);
+ SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR);
+ break;
+
+ case AF_INET6:
+ SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR);
+ SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR);
+ break;
+
+ default:
+ log_error("initiator_recv_HASH_SA_NONCE: unknown sa_family %d",
+ src->sa_family);
+ free(ie->id_ci);
+ ie->id_ci = 0;
+ free(ie->id_cr);
+ ie->id_cr = 0;
+ return -1;
+ }
+ memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src),
+ sockaddr_addrlen(src));
+ memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(dst),
+ sockaddr_addrlen(dst));
}
- switch (src->sa_family)
- {
- case AF_INET:
- SET_ISAKMP_ID_TYPE (ie->id_ci, IPSEC_ID_IPV4_ADDR);
- SET_ISAKMP_ID_TYPE (ie->id_cr, IPSEC_ID_IPV4_ADDR);
- break;
+ /* Build the protection suite in our SA. */
+ for (xf = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); xf;
+ xf = TAILQ_NEXT(xf, link)) {
- case AF_INET6:
- SET_ISAKMP_ID_TYPE (ie->id_ci, IPSEC_ID_IPV6_ADDR);
- SET_ISAKMP_ID_TYPE (ie->id_cr, IPSEC_ID_IPV6_ADDR);
- break;
+ /*
+ * XXX We could check that the proposal each transform belongs to
+ * is unique.
+ */
- default:
- log_error ("initiator_recv_HASH_SA_NONCE: unknown sa_family %d",
- src->sa_family);
- free (ie->id_ci);
- ie->id_ci = 0;
- free (ie->id_cr);
- ie->id_cr = 0;
- return -1;
- }
- memcpy (ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
- sockaddr_addrlen (src));
- memcpy (ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (dst),
- sockaddr_addrlen (dst));
- }
-
- /* Build the protection suite in our SA. */
- for (xf = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); xf;
- xf = TAILQ_NEXT (xf, link))
- {
-
- /*
- * XXX We could check that the proposal each transform belongs to
- * is unique.
- */
-
- if (sa_add_transform (sa, xf, exchange->initiator, &proto))
- return -1;
+ if (sa_add_transform(sa, xf, exchange->initiator, &proto))
+ return -1;
- /* XXX Check that the chosen transform matches an offer. */
+ /* XXX Check that the chosen transform matches an offer. */
- ipsec_decode_transform (msg, sa, proto, xf->p);
- }
+ ipsec_decode_transform(msg, sa, proto, xf->p);
+ }
- /* Now remove offers that we don't need anymore. */
- for (proto = TAILQ_FIRST (&sa->protos); proto; proto = next_proto)
- {
- next_proto = TAILQ_NEXT (proto, link);
- if (!proto->chosen)
- proto_free (proto);
- }
+ /* Now remove offers that we don't need anymore. */
+ for (proto = TAILQ_FIRST(&sa->protos); proto; proto = next_proto) {
+ next_proto = TAILQ_NEXT(proto, link);
+ if (!proto->chosen)
+ proto_free(proto);
+ }
#ifdef USE_POLICY
- if (!check_policy (exchange, sa, msg->isakmp_sa))
- {
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- log_print ("initiator_recv_HASH_SA_NONCE: policy check failed");
- return -1;
- }
+ if (!check_policy(exchange, sa, msg->isakmp_sa)) {
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ log_print("initiator_recv_HASH_SA_NONCE: policy check failed");
+ return -1;
+ }
#endif
- /* Mark the SA as handled. */
- sa_p->flags |= PL_MARK;
+ /* Mark the SA as handled. */
+ sa_p->flags |= PL_MARK;
- isa = sa->data;
- if ((isa->group_desc && (!ie->group || ie->group->id != isa->group_desc))
- || (!isa->group_desc && ie->group))
- {
- log_print ("initiator_recv_HASH_SA_NONCE: disagreement on PFS");
- return -1;
- }
-
- /* Copy out the initiator's nonce. */
- if (exchange_save_nonce (msg))
- return -1;
+ isa = sa->data;
+ if ((isa->group_desc && (!ie->group || ie->group->id != isa->group_desc))
+ || (!isa->group_desc && ie->group)) {
+ log_print("initiator_recv_HASH_SA_NONCE: disagreement on PFS");
+ return -1;
+ }
+ /* Copy out the initiator's nonce. */
+ if (exchange_save_nonce(msg))
+ return -1;
- /* Handle the optional KEY_EXCH payload. */
- if (kep && ipsec_save_g_x (msg))
- return -1;
+ /* Handle the optional KEY_EXCH payload. */
+ if (kep && ipsec_save_g_x(msg))
+ return -1;
- return 0;
+ return 0;
}
static int
-initiator_send_HASH (struct message *msg)
+initiator_send_HASH(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct prf *prf;
- u_int8_t *buf;
- struct hash *hash = hash_get (isa->hash);
- size_t hashsize = hash->hashsize;
-
- /* We want a HASH payload to start with. XXX Share with ike_main_mode.c? */
- buf = malloc (ISAKMP_HASH_SZ + hashsize);
- if (!buf)
- {
- log_error ("initiator_send_HASH: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hashsize);
- return -1;
- }
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, buf,
- ISAKMP_HASH_SZ + hashsize, 1))
- {
- free (buf);
- return -1;
- }
-
- /* Allocate the prf and start calculating our HASH(3). XXX Share? */
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a",
- isa->skeyid_a, isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- return -1;
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, (unsigned char *)"\0", 1);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b",
- exchange->nonce_i, exchange->nonce_i_len));
- prf->Update (prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b",
- exchange->nonce_r, exchange->nonce_r_len));
- prf->Update (prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
- prf->Final (buf + ISAKMP_GEN_SZ, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)",
- buf + ISAKMP_GEN_SZ, hashsize));
-
- if (ie->group)
- message_register_post_send (msg, gen_g_xy);
-
- message_register_post_send (msg, post_quick_mode);
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct prf *prf;
+ u_int8_t *buf;
+ struct hash *hash = hash_get(isa->hash);
+ size_t hashsize = hash->hashsize;
+
+ /*
+ * We want a HASH payload to start with. XXX Share with
+ * ike_main_mode.c?
+ */
+ buf = malloc(ISAKMP_HASH_SZ + hashsize);
+ if (!buf) {
+ log_error("initiator_send_HASH: malloc (%lu) failed",
+ ISAKMP_HASH_SZ + (unsigned long) hashsize);
+ return -1;
+ }
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, buf,
+ ISAKMP_HASH_SZ + hashsize, 1)) {
+ free(buf);
+ return -1;
+ }
+ /* Allocate the prf and start calculating our HASH(3). XXX Share? */
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a",
+ isa->skeyid_a, isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, (unsigned char *) "\0", 1);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b",
+ exchange->nonce_i, exchange->nonce_i_len));
+ prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b",
+ exchange->nonce_r, exchange->nonce_r_len));
+ prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
+ prf->Final(buf + ISAKMP_GEN_SZ, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)",
+ buf + ISAKMP_GEN_SZ, hashsize));
+
+ if (ie->group)
+ message_register_post_send(msg, gen_g_xy);
+
+ message_register_post_send(msg, post_quick_mode);
+
+ return 0;
}
static void
-post_quick_mode (struct message *msg)
+post_quick_mode(struct message * msg)
{
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct prf *prf;
- struct sa *sa;
- struct proto *proto;
- struct ipsec_proto *iproto;
- u_int8_t *keymat;
- int i;
-
- /*
- * Loop over all SA negotiations and do both an in- and an outgoing SA
- * per protocol.
- */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa; sa = TAILQ_NEXT (sa, next))
- {
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- if (proto->proto == IPSEC_PROTO_IPCOMP)
- continue;
-
- iproto = proto->data;
-
- /*
- * There are two SAs for each SA negotiation, incoming and outcoing.
- */
- for (i = 0; i < 2; i++)
- {
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_d,
- isa->skeyid_len);
- if (!prf)
- {
- /* XXX What to do? */
- continue;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct prf *prf;
+ struct sa *sa;
+ struct proto *proto;
+ struct ipsec_proto *iproto;
+ u_int8_t *keymat;
+ int i;
+
+ /*
+ * Loop over all SA negotiations and do both an in- and an outgoing SA
+ * per protocol.
+ */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = TAILQ_NEXT(sa, next)) {
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ if (proto->proto == IPSEC_PROTO_IPCOMP)
+ continue;
+
+ iproto = proto->data;
+
+ /*
+ * There are two SAs for each SA negotiation, incoming and outcoing.
+ */
+ for (i = 0; i < 2; i++) {
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_d,
+ isa->skeyid_len);
+ if (!prf) {
+ /* XXX What to do? */
+ continue;
+ }
+ ie->keymat_len = ipsec_keymat_length(proto);
+
+ /*
+ * We need to roundup the length of the key material buffer
+ * to a multiple of the PRF's blocksize as it is generated
+ * in chunks of that blocksize.
+ */
+ iproto->keymat[i]
+ = malloc(((ie->keymat_len + prf->blocksize - 1)
+ / prf->blocksize) * prf->blocksize);
+ if (!iproto->keymat[i]) {
+ log_error("post_quick_mode: malloc (%lu) failed",
+ (((unsigned long) ie->keymat_len +
+ prf->blocksize - 1) / prf->blocksize) *
+ prf->blocksize);
+ /* XXX What more to do? */
+ free(prf);
+ continue;
+ }
+ for (keymat = iproto->keymat[i];
+ keymat < iproto->keymat[i] + ie->keymat_len;
+ keymat += prf->blocksize) {
+ prf->Init(prf->prfctx);
+
+ if (keymat != iproto->keymat[i]) {
+ /*
+ * Hash in last round's
+ * KEYMAT.
+ */
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "post_quick_mode: last KEYMAT",
+ keymat - prf->blocksize,
+ prf->blocksize));
+ prf->Update(prf->prfctx, keymat - prf->blocksize,
+ prf->blocksize);
+ }
+ /* If PFS is used hash in g^xy. */
+ if (ie->g_xy) {
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "post_quick_mode: g^xy", ie->g_xy,
+ ie->g_x_len));
+ prf->Update(prf->prfctx, ie->g_xy, ie->g_x_len);
+ }
+ LOG_DBG((LOG_NEGOTIATION, 90,
+ "post_quick_mode: suite %d proto %d", proto->no,
+ proto->proto));
+ prf->Update(prf->prfctx, &proto->proto, 1);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "post_quick_mode: SPI",
+ proto->spi[i], proto->spi_sz[i]));
+ prf->Update(prf->prfctx, proto->spi[i], proto->spi_sz[i]);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b",
+ exchange->nonce_i, exchange->nonce_i_len));
+ prf->Update(prf->prfctx, exchange->nonce_i,
+ exchange->nonce_i_len);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b",
+ exchange->nonce_r, exchange->nonce_r_len));
+ prf->Update(prf->prfctx, exchange->nonce_r,
+ exchange->nonce_r_len);
+ prf->Final(keymat, prf->prfctx);
+ }
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT",
+ iproto->keymat[i], ie->keymat_len));
+ }
}
-
- ie->keymat_len = ipsec_keymat_length (proto);
-
- /*
- * We need to roundup the length of the key material buffer
- * to a multiple of the PRF's blocksize as it is generated
- * in chunks of that blocksize.
- */
- iproto->keymat[i]
- = malloc (((ie->keymat_len + prf->blocksize - 1)
- / prf->blocksize) * prf->blocksize);
- if (!iproto->keymat[i])
- {
- log_error ("post_quick_mode: malloc (%lu) failed",
- (((unsigned long)ie->keymat_len +
- prf->blocksize - 1) / prf->blocksize) *
- prf->blocksize);
- /* XXX What more to do? */
- free (prf);
- continue;
- }
-
- for (keymat = iproto->keymat[i];
- keymat < iproto->keymat[i] + ie->keymat_len;
- keymat += prf->blocksize)
- {
- prf->Init (prf->prfctx);
-
- if (keymat != iproto->keymat[i])
- {
- /* Hash in last round's KEYMAT. */
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "post_quick_mode: last KEYMAT",
- keymat - prf->blocksize,
- prf->blocksize));
- prf->Update (prf->prfctx, keymat - prf->blocksize,
- prf->blocksize);
- }
-
- /* If PFS is used hash in g^xy. */
- if (ie->g_xy)
- {
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "post_quick_mode: g^xy", ie->g_xy,
- ie->g_x_len));
- prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
- }
- LOG_DBG ((LOG_NEGOTIATION, 90,
- "post_quick_mode: suite %d proto %d", proto->no,
- proto->proto));
- prf->Update (prf->prfctx, &proto->proto, 1);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "post_quick_mode: SPI",
- proto->spi[i], proto->spi_sz[i]));
- prf->Update (prf->prfctx, proto->spi[i], proto->spi_sz[i]);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b",
- exchange->nonce_i, exchange->nonce_i_len));
- prf->Update (prf->prfctx, exchange->nonce_i,
- exchange->nonce_i_len);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b",
- exchange->nonce_r, exchange->nonce_r_len));
- prf->Update (prf->prfctx, exchange->nonce_r,
- exchange->nonce_r_len);
- prf->Final (keymat, prf->prfctx);
- }
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT",
- iproto->keymat[i], ie->keymat_len));
- }
}
- }
- log_verbose ("isakmpd: quick mode done: %s",
- !msg->isakmp_sa || !msg->isakmp_sa->transport
- ? "<no transport>"
- : msg->isakmp_sa->transport->vtbl->decode_ids
- (msg->isakmp_sa ->transport));
+ log_verbose("isakmpd: quick mode done: %s",
+ !msg->isakmp_sa || !msg->isakmp_sa->transport
+ ? "<no transport>"
+ : msg->isakmp_sa->transport->vtbl->decode_ids
+ (msg->isakmp_sa->transport));
}
/*
@@ -1471,533 +1364,497 @@ post_quick_mode (struct message *msg)
* XXX Describe in more detail.
*/
static int
-responder_recv_HASH_SA_NONCE (struct message *msg)
+responder_recv_HASH_SA_NONCE(struct message * msg)
{
- struct payload *hashp, *kep, *idp;
- struct sa *sa;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct prf *prf;
- u_int8_t *hash, *my_hash = 0;
- size_t hash_len;
- u_int8_t *pkt = msg->iov[0].iov_base;
- u_int8_t group_desc = 0;
- int retval = -1;
- struct proto *proto;
- struct sockaddr *src, *dst;
- char *name;
-
- hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- hash = hashp->p;
- hashp->flags |= PL_MARK;
-
- /* The HASH payload should be the first one. */
- if (hash != pkt + ISAKMP_HDR_SZ)
- {
- /* XXX Is there a better notification type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- goto cleanup;
- }
- hash_len = GET_ISAKMP_GEN_LENGTH (hash);
- my_hash = malloc (hash_len - ISAKMP_GEN_SZ);
- if (!my_hash)
- {
- log_error ("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)hash_len - ISAKMP_GEN_SZ);
- goto cleanup;
- }
-
- /*
- * Check the payload's integrity.
- * XXX Share with ipsec_fill_in_hash?
- */
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: SKEYID_a",
- isa->skeyid_a, isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- goto cleanup;
- prf->Init (prf->prfctx);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH_SA_NONCE: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH_SA_NONCE: message after HASH",
- hash + hash_len,
- msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len));
- prf->Update (prf->prfctx, hash + hash_len,
- msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
- prf->Final (my_hash, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH_SA_NONCE: computed HASH(1)", my_hash,
- hash_len - ISAKMP_GEN_SZ));
- if (memcmp (hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- goto cleanup;
- }
- free (my_hash);
- my_hash = 0;
-
- kep = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
- if (kep)
- ie->pfs = 1;
-
- /* Handle optional client ID payloads. */
- idp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]);
- if (idp)
- {
- /* If IDci is there, IDcr must be too. */
- if (!TAILQ_NEXT (idp, link))
- {
- /* XXX Is this a good notify type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- goto cleanup;
- }
-
- ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH (idp->p);
- ie->id_ci = malloc (ie->id_ci_sz);
- if (!ie->id_ci)
- {
- log_error ("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)ie->id_ci_sz);
- goto cleanup;
+ struct payload *hashp, *kep, *idp;
+ struct sa *sa;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct prf *prf;
+ u_int8_t *hash, *my_hash = 0;
+ size_t hash_len;
+ u_int8_t *pkt = msg->iov[0].iov_base;
+ u_int8_t group_desc = 0;
+ int retval = -1;
+ struct proto *proto;
+ struct sockaddr *src, *dst;
+ char *name;
+
+ hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ hash = hashp->p;
+ hashp->flags |= PL_MARK;
+
+ /* The HASH payload should be the first one. */
+ if (hash != pkt + ISAKMP_HDR_SZ) {
+ /* XXX Is there a better notification type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ goto cleanup;
}
- memcpy (ie->id_ci, idp->p, ie->id_ci_sz);
- idp->flags |= PL_MARK;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH_SA_NONCE: IDci",
- ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz
- - ISAKMP_GEN_SZ));
-
- idp = TAILQ_NEXT (idp, link);
- ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH (idp->p);
- ie->id_cr = malloc (ie->id_cr_sz);
- if (!ie->id_cr)
- {
- log_error ("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)ie->id_cr_sz);
- goto cleanup;
+ hash_len = GET_ISAKMP_GEN_LENGTH(hash);
+ my_hash = malloc(hash_len - ISAKMP_GEN_SZ);
+ if (!my_hash) {
+ log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) hash_len - ISAKMP_GEN_SZ);
+ goto cleanup;
}
- memcpy (ie->id_cr, idp->p, ie->id_cr_sz);
- idp->flags |= PL_MARK;
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH_SA_NONCE: IDcr",
- ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz
- - ISAKMP_GEN_SZ));
- }
- else
- {
- /*
- * If client identifiers are not present in the exchange,
- * we fake them. RFC 2409 states:
- * The identities of the SAs negotiated in Quick Mode are
- * implicitly assumed to be the IP addresses of the ISAKMP
- * peers, without any constraints on the protocol or port
- * numbers allowed, unless client identifiers are specified
- * in Quick Mode.
- *
- * -- Michael Paddon (mwp@aba.net.au)
- */
-
- ie->flags = IPSEC_EXCH_FLAG_NO_ID;
-
- /* Get initiator and responder addresses. */
- msg->transport->vtbl->get_src (msg->transport, &src);
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen (src);
- ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen (dst);
- ie->id_ci = calloc (ie->id_ci_sz, sizeof (char));
- ie->id_cr = calloc (ie->id_cr_sz, sizeof (char));
-
- if (!ie->id_ci || !ie->id_cr)
- {
- log_error ("responder_recv_HASH_SA_NONCE: calloc (%lu, %lu) failed",
- (unsigned long)ie->id_ci_sz, (unsigned long)sizeof (char));
- goto cleanup;
+ /*
+ * Check the payload's integrity.
+ * XXX Share with ipsec_fill_in_hash?
+ */
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: SKEYID_a",
+ isa->skeyid_a, isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ goto cleanup;
+ prf->Init(prf->prfctx);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH_SA_NONCE: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH_SA_NONCE: message after HASH",
+ hash + hash_len,
+ msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len));
+ prf->Update(prf->prfctx, hash + hash_len,
+ msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
+ prf->Final(my_hash, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH_SA_NONCE: computed HASH(1)", my_hash,
+ hash_len - ISAKMP_GEN_SZ));
+ if (memcmp(hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) != 0) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ goto cleanup;
}
+ free(my_hash);
+ my_hash = 0;
+
+ kep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
+ if (kep)
+ ie->pfs = 1;
+
+ /* Handle optional client ID payloads. */
+ idp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]);
+ if (idp) {
+ /* If IDci is there, IDcr must be too. */
+ if (!TAILQ_NEXT(idp, link)) {
+ /* XXX Is this a good notify type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ goto cleanup;
+ }
+ ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p);
+ ie->id_ci = malloc(ie->id_ci_sz);
+ if (!ie->id_ci) {
+ log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->id_ci_sz);
+ goto cleanup;
+ }
+ memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
+ idp->flags |= PL_MARK;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH_SA_NONCE: IDci",
+ ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz
+ - ISAKMP_GEN_SZ));
+
+ idp = TAILQ_NEXT(idp, link);
+ ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p);
+ ie->id_cr = malloc(ie->id_cr_sz);
+ if (!ie->id_cr) {
+ log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) ie->id_cr_sz);
+ goto cleanup;
+ }
+ memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
+ idp->flags |= PL_MARK;
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH_SA_NONCE: IDcr",
+ ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz
+ - ISAKMP_GEN_SZ));
+ } else {
+ /*
+ * If client identifiers are not present in the exchange,
+ * we fake them. RFC 2409 states:
+ * The identities of the SAs negotiated in Quick Mode are
+ * implicitly assumed to be the IP addresses of the ISAKMP
+ * peers, without any constraints on the protocol or port
+ * numbers allowed, unless client identifiers are specified
+ * in Quick Mode.
+ *
+ * -- Michael Paddon (mwp@aba.net.au)
+ */
+
+ ie->flags = IPSEC_EXCH_FLAG_NO_ID;
+
+ /* Get initiator and responder addresses. */
+ msg->transport->vtbl->get_src(msg->transport, &src);
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(src);
+ ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(dst);
+ ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
+ ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
+
+ if (!ie->id_ci || !ie->id_cr) {
+ log_error("responder_recv_HASH_SA_NONCE: calloc (%lu, %lu) failed",
+ (unsigned long) ie->id_ci_sz, (unsigned long) sizeof(char));
+ goto cleanup;
+ }
+ if (src->sa_family != dst->sa_family) {
+ log_error("initiator_recv_HASH_SA_NONCE: sa_family mismatch");
+ goto cleanup;
+ }
+ switch (src->sa_family) {
+ case AF_INET:
+ SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR);
+ SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR);
+ break;
+
+ case AF_INET6:
+ SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR);
+ SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR);
+ break;
+
+ default:
+ log_error("initiator_recv_HASH_SA_NONCE: unknown sa_family %d",
+ src->sa_family);
+ goto cleanup;
+ }
- if (src->sa_family != dst->sa_family)
- {
- log_error ("initiator_recv_HASH_SA_NONCE: sa_family mismatch");
- goto cleanup;
- }
-
- switch (src->sa_family)
- {
- case AF_INET:
- SET_ISAKMP_ID_TYPE (ie->id_ci, IPSEC_ID_IPV4_ADDR);
- SET_ISAKMP_ID_TYPE (ie->id_cr, IPSEC_ID_IPV4_ADDR);
- break;
-
- case AF_INET6:
- SET_ISAKMP_ID_TYPE (ie->id_ci, IPSEC_ID_IPV6_ADDR);
- SET_ISAKMP_ID_TYPE (ie->id_cr, IPSEC_ID_IPV6_ADDR);
- break;
-
- default:
- log_error ("initiator_recv_HASH_SA_NONCE: unknown sa_family %d",
- src->sa_family);
- goto cleanup;
+ memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src),
+ sockaddr_addrlen(src));
+ memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(dst),
+ sockaddr_addrlen(dst));
}
- memcpy (ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
- sockaddr_addrlen (src));
- memcpy (ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (dst),
- sockaddr_addrlen (dst));
- }
-
#ifdef USE_POLICY
#ifdef USE_KEYNOTE
- if (message_negotiate_sa (msg, check_policy))
- goto cleanup;
+ if (message_negotiate_sa(msg, check_policy))
+ goto cleanup;
#else
- if (message_negotiate_sa (msg, 0))
- goto cleanup;
+ if (message_negotiate_sa(msg, 0))
+ goto cleanup;
#endif
#else
- if (message_negotiate_sa (msg, 0))
- goto cleanup;
-#endif /* USE_POLICY */
-
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa; sa = TAILQ_NEXT (sa, next))
- {
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- /* XXX we need to have some attributes per proto, not all per SA. */
- ipsec_decode_transform (msg, sa, proto, proto->chosen->p);
- if (proto->proto == IPSEC_PROTO_IPSEC_AH
- && !((struct ipsec_proto *)proto->data)->auth)
- {
- log_print ("responder_recv_HASH_SA_NONCE: "
- "AH proposed without an algorithm attribute");
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- goto next_sa;
- }
- }
+ if (message_negotiate_sa(msg, 0))
+ goto cleanup;
+#endif /* USE_POLICY */
+
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = TAILQ_NEXT(sa, next)) {
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ /*
+ * XXX we need to have some attributes per proto, not
+ * all per SA.
+ */
+ ipsec_decode_transform(msg, sa, proto, proto->chosen->p);
+ if (proto->proto == IPSEC_PROTO_IPSEC_AH
+ && !((struct ipsec_proto *) proto->data)->auth) {
+ log_print("responder_recv_HASH_SA_NONCE: "
+ "AH proposed without an algorithm attribute");
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ goto next_sa;
+ }
+ }
- isa = sa->data;
+ isa = sa->data;
+
+ /*
+ * The group description is mandatory if we got a KEY_EXCH
+ * payload.
+ */
+ if (kep) {
+ if (!isa->group_desc) {
+ log_print("responder_recv_HASH_SA_NONCE: "
+ "KEY_EXCH payload without a group desc. attribute");
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ continue;
+ }
+ /* Also, all SAs must have equal groups. */
+ if (!group_desc)
+ group_desc = isa->group_desc;
+ else if (group_desc != isa->group_desc) {
+ log_print("responder_recv_HASH_SA_NONCE: "
+ "differing group descriptions in one QM");
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ continue;
+ }
+ }
+ /* At least one SA was accepted. */
+ retval = 0;
- /* The group description is mandatory if we got a KEY_EXCH payload. */
- if (kep)
- {
- if (!isa->group_desc)
- {
- log_print ("responder_recv_HASH_SA_NONCE: "
- "KEY_EXCH payload without a group desc. attribute");
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- continue;
- }
-
- /* Also, all SAs must have equal groups. */
- if (!group_desc)
- group_desc = isa->group_desc;
- else if (group_desc != isa->group_desc)
- {
- log_print ("responder_recv_HASH_SA_NONCE: "
- "differing group descriptions in one QM");
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- continue;
- }
+next_sa:
+ ; /* XXX gcc3 wants this. */
}
- /* At least one SA was accepted. */
- retval = 0;
-
- next_sa:
- ; /* XXX gcc3 wants this. */
- }
-
- if (kep)
- {
- ie->group = group_get (group_desc);
- if (!ie->group)
- {
- /*
- * XXX If the error was due to an out-of-range group description
- * we should notify our peer, but this should probably be done
- * by the attribute validation. Is it?
- */
- goto cleanup;
+ if (kep) {
+ ie->group = group_get(group_desc);
+ if (!ie->group) {
+ /*
+ * XXX If the error was due to an out-of-range group description
+ * we should notify our peer, but this should probably be done
+ * by the attribute validation. Is it?
+ */
+ goto cleanup;
+ }
}
- }
-
- /* Copy out the initiator's nonce. */
- if (exchange_save_nonce (msg))
- goto cleanup;
-
- /* Handle the optional KEY_EXCH payload. */
- if (kep && ipsec_save_g_x (msg))
- goto cleanup;
-
- /*
- * Try to find and set the connection name on the exchange.
- */
-
- /*
- * Check for accepted identities as well as lookup the connection
- * name and set it on the exchange.
- */
- name = connection_passive_lookup_by_ids (ie->id_ci, ie->id_cr);
- if (name)
- {
- exchange->name = strdup (name);
- if (!exchange->name)
- {
- log_error ("responder_recv_HASH_SA_NONCE: strdup (\"%s\") failed",
- name);
- goto cleanup;
+ /* Copy out the initiator's nonce. */
+ if (exchange_save_nonce(msg))
+ goto cleanup;
+
+ /* Handle the optional KEY_EXCH payload. */
+ if (kep && ipsec_save_g_x(msg))
+ goto cleanup;
+
+ /*
+ * Try to find and set the connection name on the exchange.
+ */
+
+ /*
+ * Check for accepted identities as well as lookup the connection
+ * name and set it on the exchange.
+ */
+ name = connection_passive_lookup_by_ids(ie->id_ci, ie->id_cr);
+ if (name) {
+ exchange->name = strdup(name);
+ if (!exchange->name) {
+ log_error("responder_recv_HASH_SA_NONCE: strdup (\"%s\") failed",
+ name);
+ goto cleanup;
+ }
}
- }
#if !defined (USE_POLICY) && !defined (USE_KEYNOTE)
- else
- {
- /*
- * This code is no longer necessary, as policy determines acceptance
- * of IDs/SAs. (angelos@openbsd.org)
- *
- * XXX Keep it if not USE_POLICY for now, though.
- */
-
- /* XXX Notify peer and log. */
- goto cleanup;
- }
-#endif /* !USE_POLICY && !USE_KEYNOTE */
-
- return retval;
+ else {
+ /*
+ * This code is no longer necessary, as policy determines acceptance
+ * of IDs/SAs. (angelos@openbsd.org)
+ *
+ * XXX Keep it if not USE_POLICY for now, though.
+ */
+
+ /* XXX Notify peer and log. */
+ goto cleanup;
+ }
+#endif /* !USE_POLICY && !USE_KEYNOTE */
+
+ return retval;
cleanup:
- /* Remove all potential protocols that have been added to the SAs. */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa; sa = TAILQ_NEXT (sa, next))
- while ((proto = TAILQ_FIRST (&sa->protos)) != 0)
- proto_free (proto);
- if (my_hash)
- free (my_hash);
- if (ie->id_ci)
- {
- free (ie->id_ci);
- ie->id_ci = 0;
- }
- if (ie->id_cr)
- {
- free (ie->id_cr);
- ie->id_cr = 0;
- }
- return -1;
+ /* Remove all potential protocols that have been added to the SAs. */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = TAILQ_NEXT(sa, next))
+ while ((proto = TAILQ_FIRST(&sa->protos)) != 0)
+ proto_free(proto);
+ if (my_hash)
+ free(my_hash);
+ if (ie->id_ci) {
+ free(ie->id_ci);
+ ie->id_ci = 0;
+ }
+ if (ie->id_cr) {
+ free(ie->id_cr);
+ ie->id_cr = 0;
+ }
+ return -1;
}
/* Reply with the transform we chose. */
static int
-responder_send_HASH_SA_NONCE (struct message *msg)
+responder_send_HASH_SA_NONCE(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct prf *prf;
- struct hash *hash = hash_get (isa->hash);
- size_t hashsize = hash->hashsize;
- size_t nonce_sz = exchange->nonce_i_len;
- u_int8_t *buf;
- int initiator = exchange->initiator;
- char header[80];
- u_int32_t i;
- u_int8_t *id;
- size_t sz;
-
- /* We want a HASH payload to start with. XXX Share with ike_main_mode.c? */
- buf = malloc (ISAKMP_HASH_SZ + hashsize);
- if (!buf)
- {
- log_error ("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hashsize);
- return -1;
- }
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, buf,
- ISAKMP_HASH_SZ + hashsize, 1))
- {
- free (buf);
- return -1;
- }
-
- /* Add the SA payload(s) with the transform(s) that was/were chosen. */
- if (message_add_sa_payload (msg))
- return -1;
-
- /* Generate a nonce, and add it to the message. */
- if (exchange_gen_nonce (msg, nonce_sz))
- return -1;
-
- /* Generate optional KEY_EXCH payload. This is known as PFS. */
- if (ie->group && ipsec_gen_g_x (msg))
- return -1;
-
- /* If the initiator client ID's were acceptable, just mirror them back. */
- if (!(ie->flags & IPSEC_EXCH_FLAG_NO_ID))
- {
- sz = ie->id_ci_sz;
- id = malloc (sz);
- if (!id)
- {
- log_error ("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)sz);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct prf *prf;
+ struct hash *hash = hash_get(isa->hash);
+ size_t hashsize = hash->hashsize;
+ size_t nonce_sz = exchange->nonce_i_len;
+ u_int8_t *buf;
+ int initiator = exchange->initiator;
+ char header[80];
+ u_int32_t i;
+ u_int8_t *id;
+ size_t sz;
+
+ /*
+ * We want a HASH payload to start with. XXX Share with
+ * ike_main_mode.c?
+ */
+ buf = malloc(ISAKMP_HASH_SZ + hashsize);
+ if (!buf) {
+ log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
+ ISAKMP_HASH_SZ + (unsigned long) hashsize);
+ return -1;
}
- memcpy (id, ie->id_ci, sz);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, buf,
+ ISAKMP_HASH_SZ + hashsize, 1)) {
+ free(buf);
+ return -1;
}
-
- sz = ie->id_cr_sz;
- id = malloc (sz);
- if (!id)
- {
- log_error ("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
- (unsigned long)sz);
- return -1;
+ /* Add the SA payload(s) with the transform(s) that was/were chosen. */
+ if (message_add_sa_payload(msg))
+ return -1;
+
+ /* Generate a nonce, and add it to the message. */
+ if (exchange_gen_nonce(msg, nonce_sz))
+ return -1;
+
+ /* Generate optional KEY_EXCH payload. This is known as PFS. */
+ if (ie->group && ipsec_gen_g_x(msg))
+ return -1;
+
+ /*
+ * If the initiator client ID's were acceptable, just mirror them
+ * back.
+ */
+ if (!(ie->flags & IPSEC_EXCH_FLAG_NO_ID)) {
+ sz = ie->id_ci_sz;
+ id = malloc(sz);
+ if (!id) {
+ log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) sz);
+ return -1;
+ }
+ memcpy(id, ie->id_ci, sz);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
+ }
+ sz = ie->id_cr_sz;
+ id = malloc(sz);
+ if (!id) {
+ log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
+ (unsigned long) sz);
+ return -1;
+ }
+ memcpy(id, ie->id_cr, sz);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc",
+ id, sz));
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) {
+ free(id);
+ return -1;
+ }
}
- memcpy (id, ie->id_cr, sz);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc",
- id, sz));
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, id, sz, 1))
- {
- free (id);
- return -1;
+ /* Allocate the prf and start calculating our HASH(2). XXX Share? */
+ LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: isakmp_sa %p isa %p",
+ isakmp_sa, isa));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: SKEYID_a",
+ isa->skeyid_a, isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+ prf->Init(prf->prfctx);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_send_HASH_SA_NONCE: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: NONCE_I_b",
+ exchange->nonce_i, exchange->nonce_i_len));
+ prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
+
+ /* Loop over all payloads after HASH(2). */
+ for (i = 2; i < msg->iovlen; i++) {
+ /* XXX Misleading payload type printouts. */
+ snprintf(header, sizeof header,
+ "responder_send_HASH_SA_NONCE: payload %d after HASH(2)",
+ i - 1);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base,
+ msg->iov[i].iov_len));
+ prf->Update(prf->prfctx, msg->iov[i].iov_base, msg->iov[i].iov_len);
}
- }
-
- /* Allocate the prf and start calculating our HASH(2). XXX Share? */
- LOG_DBG ((LOG_NEGOTIATION, 90, "responder_recv_HASH: isakmp_sa %p isa %p",
- isakmp_sa, isa));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: SKEYID_a",
- isa->skeyid_a, isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- return -1;
- prf->Init (prf->prfctx);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_send_HASH_SA_NONCE: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: NONCE_I_b",
- exchange->nonce_i, exchange->nonce_i_len));
- prf->Update (prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
-
- /* Loop over all payloads after HASH(2). */
- for (i = 2; i < msg->iovlen; i++)
- {
- /* XXX Misleading payload type printouts. */
- snprintf (header, sizeof header,
- "responder_send_HASH_SA_NONCE: payload %d after HASH(2)",
- i - 1);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base,
- msg->iov[i].iov_len));
- prf->Update (prf->prfctx, msg->iov[i].iov_base, msg->iov[i].iov_len);
- }
- prf->Final (buf + ISAKMP_HASH_DATA_OFF, prf->prfctx);
- prf_free (prf);
- snprintf (header, sizeof header, "responder_send_HASH_SA_NONCE: HASH_%c",
- initiator ? 'I' : 'R');
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80, header, buf + ISAKMP_HASH_DATA_OFF,
- hashsize));
-
- if (ie->group)
- message_register_post_send (msg, gen_g_xy);
-
- return 0;
+ prf->Final(buf + ISAKMP_HASH_DATA_OFF, prf->prfctx);
+ prf_free(prf);
+ snprintf(header, sizeof header, "responder_send_HASH_SA_NONCE: HASH_%c",
+ initiator ? 'I' : 'R');
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, buf + ISAKMP_HASH_DATA_OFF,
+ hashsize));
+
+ if (ie->group)
+ message_register_post_send(msg, gen_g_xy);
+
+ return 0;
}
static void
-gen_g_xy (struct message *msg)
+gen_g_xy(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
-
- /* Compute Diffie-Hellman shared value. */
- ie->g_xy = malloc (ie->g_x_len);
- if (!ie->g_xy)
- {
- log_error ("gen_g_xy: malloc (%lu) failed", (unsigned long)ie->g_x_len);
- return;
- }
- if (dh_create_shared (ie->group, ie->g_xy,
- exchange->initiator ? ie->g_xr : ie->g_xi))
- {
- log_print ("gen_g_xy: dh_create_shared failed");
- return;
- }
- LOG_DBG_BUF ((LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->g_xy, ie->g_x_len));
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+
+ /* Compute Diffie-Hellman shared value. */
+ ie->g_xy = malloc(ie->g_x_len);
+ if (!ie->g_xy) {
+ log_error("gen_g_xy: malloc (%lu) failed", (unsigned long) ie->g_x_len);
+ return;
+ }
+ if (dh_create_shared(ie->group, ie->g_xy,
+ exchange->initiator ? ie->g_xr : ie->g_xi)) {
+ log_print("gen_g_xy: dh_create_shared failed");
+ return;
+ }
+ LOG_DBG_BUF((LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->g_xy, ie->g_x_len));
}
static int
-responder_recv_HASH (struct message *msg)
+responder_recv_HASH(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct prf *prf;
- u_int8_t *hash, *my_hash = 0;
- size_t hash_len;
- struct payload *hashp;
-
- /* Find HASH(3) and create our own hash, just as big. */
- hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- hash = hashp->p;
- hashp->flags |= PL_MARK;
- hash_len = GET_ISAKMP_GEN_LENGTH (hash);
- my_hash = malloc (hash_len - ISAKMP_GEN_SZ);
- if (!my_hash)
- {
- log_error ("responder_recv_HASH: malloc (%lu) failed",
- (unsigned long)hash_len - ISAKMP_GEN_SZ);
- goto cleanup;
- }
-
- /* Allocate the prf and start calculating our HASH(3). XXX Share? */
- LOG_DBG ((LOG_NEGOTIATION, 90, "responder_recv_HASH: isakmp_sa %p isa %p",
- isakmp_sa, isa));
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a",
- isa->skeyid_a, isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- goto cleanup;
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, (unsigned char *)"\0", 1);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b",
- exchange->nonce_i, exchange->nonce_i_len));
- prf->Update (prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b",
- exchange->nonce_r, exchange->nonce_r_len));
- prf->Update (prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
- prf->Final (my_hash, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_NEGOTIATION, 90,
- "responder_recv_HASH: computed HASH(3)", my_hash,
- hash_len - ISAKMP_GEN_SZ));
- if (memcmp (hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- goto cleanup;
- }
- free (my_hash);
-
- post_quick_mode (msg);
-
- return 0;
-
- cleanup:
- if (my_hash)
- free (my_hash);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct prf *prf;
+ u_int8_t *hash, *my_hash = 0;
+ size_t hash_len;
+ struct payload *hashp;
+
+ /* Find HASH(3) and create our own hash, just as big. */
+ hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ hash = hashp->p;
+ hashp->flags |= PL_MARK;
+ hash_len = GET_ISAKMP_GEN_LENGTH(hash);
+ my_hash = malloc(hash_len - ISAKMP_GEN_SZ);
+ if (!my_hash) {
+ log_error("responder_recv_HASH: malloc (%lu) failed",
+ (unsigned long) hash_len - ISAKMP_GEN_SZ);
+ goto cleanup;
+ }
+ /* Allocate the prf and start calculating our HASH(3). XXX Share? */
+ LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: isakmp_sa %p isa %p",
+ isakmp_sa, isa));
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a",
+ isa->skeyid_a, isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ goto cleanup;
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, (unsigned char *) "\0", 1);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b",
+ exchange->nonce_i, exchange->nonce_i_len));
+ prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b",
+ exchange->nonce_r, exchange->nonce_r_len));
+ prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
+ prf->Final(my_hash, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_NEGOTIATION, 90,
+ "responder_recv_HASH: computed HASH(3)", my_hash,
+ hash_len - ISAKMP_GEN_SZ));
+ if (memcmp(hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) != 0) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ goto cleanup;
+ }
+ free(my_hash);
+
+ post_quick_mode(msg);
+
+ return 0;
+
+cleanup:
+ if (my_hash)
+ free(my_hash);
+ return -1;
}
diff --git a/sbin/isakmpd/ike_quick_mode.h b/sbin/isakmpd/ike_quick_mode.h
index afe1709d83d..32b1523ef01 100644
--- a/sbin/isakmpd/ike_quick_mode.h
+++ b/sbin/isakmpd/ike_quick_mode.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_quick_mode.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ike_quick_mode.h,v 1.1 1998/08/02 20:22:44 niklas Exp $ */
+/* $OpenBSD: ike_quick_mode.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ike_quick_mode.h,v 1.1 1998/08/02 20:22:44 niklas Exp $ */
/*
* Copyright (c) 1998, 2001 Niklas Hallqvist. All rights reserved.
@@ -34,7 +34,7 @@
struct message;
-extern int (*ike_quick_mode_initiator[]) (struct message *);
-extern int (*ike_quick_mode_responder[]) (struct message *);
+extern int (*ike_quick_mode_initiator[]) (struct message *);
+extern int (*ike_quick_mode_responder[]) (struct message *);
-#endif /* _IKE_QUICK_MODE_H_ */
+#endif /* _IKE_QUICK_MODE_H_ */
diff --git a/sbin/isakmpd/init.c b/sbin/isakmpd/init.c
index dcf1c69122a..929bf07d3e5 100644
--- a/sbin/isakmpd/init.c
+++ b/sbin/isakmpd/init.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: init.c,v 1.28 2004/04/08 10:05:54 hshoexer Exp $ */
-/* $EOM: init.c,v 1.25 2000/03/30 14:27:24 ho Exp $ */
+/* $OpenBSD: init.c,v 1.29 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: init.c,v 1.25 2000/03/30 14:27:24 ho Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -59,85 +59,85 @@
#endif
void
-init (void)
+init(void)
{
- app_init ();
- doi_init ();
- exchange_init ();
- group_init ();
- ipsec_init ();
- isakmp_doi_init ();
- libcrypto_init ();
+ app_init();
+ doi_init();
+ exchange_init();
+ group_init();
+ ipsec_init();
+ isakmp_doi_init();
+ libcrypto_init();
- timer_init ();
+ timer_init();
- /* The following group are depending on timer_init having run. */
- conf_init ();
- connection_init ();
+ /* The following group are depending on timer_init having run. */
+ conf_init();
+ connection_init();
- /* This depends on conf_init, thus check as soon as possible. */
- log_reinit ();
+ /* This depends on conf_init, thus check as soon as possible. */
+ log_reinit();
#ifdef USE_POLICY
- /* policy_init depends on conf_init having run. */
- policy_init ();
+ /* policy_init depends on conf_init having run. */
+ policy_init();
#endif
- /* Depends on conf_init and policy_init having run */
- cert_init ();
- crl_init ();
+ /* Depends on conf_init and policy_init having run */
+ cert_init();
+ crl_init();
- sa_init ();
- transport_init ();
- udp_init ();
- ui_init ();
+ sa_init();
+ transport_init();
+ udp_init();
+ ui_init();
}
/* Reinitialize, either after a SIGHUP reception or by FIFO UI cmd. */
void
-reinit (void)
+reinit(void)
{
- log_print ("isakmpd: reinitializing daemon");
+ log_print("isakmpd: reinitializing daemon");
- /*
- * XXX Remove all(/some?) pending exchange timers? - they may not be
- * possible to complete after we've re-read the config file.
- * User-initiated SIGHUP's maybe "authorizes" a wait until
- * next connection-check.
- * XXX This means we discard exchange->last_msg, is this really ok?
- */
+ /*
+ * XXX Remove all(/some?) pending exchange timers? - they may not be
+ * possible to complete after we've re-read the config file.
+ * User-initiated SIGHUP's maybe "authorizes" a wait until
+ * next connection-check.
+ * XXX This means we discard exchange->last_msg, is this really ok?
+ */
- /* Reinitialize PRNG if we are in deterministic mode. */
- if (regrand)
- srandom (seed);
+ /* Reinitialize PRNG if we are in deterministic mode. */
+ if (regrand)
+ srandom(seed);
- /* Reread config file. */
- conf_reinit ();
+ /* Reread config file. */
+ conf_reinit();
- log_reinit ();
+ log_reinit();
#ifdef USE_POLICY
- /* Reread the policies. */
- policy_init ();
+ /* Reread the policies. */
+ policy_init();
#endif
- /* Reinitialize certificates */
- cert_init ();
- crl_init ();
+ /* Reinitialize certificates */
+ cert_init();
+ crl_init();
- /* Reinitialize our connection list. */
- connection_reinit ();
+ /* Reinitialize our connection list. */
+ connection_reinit();
- /*
- * Rescan interfaces.
- */
- transport_reinit ();
+ /*
+ * Rescan interfaces.
+ */
+ transport_reinit();
- /*
- * XXX "These" (non-existent) reinitializations should not be done.
- * cookie_reinit ();
- * ui_reinit ();
- */
+ /*
+ * XXX "These" (non-existent) reinitializations should not be done.
+ * cookie_reinit ();
+ * ui_reinit ();
+ */
- sa_reinit ();
+ sa_reinit();
}
diff --git a/sbin/isakmpd/init.h b/sbin/isakmpd/init.h
index 5f653b0825c..cbcd46ab963 100644
--- a/sbin/isakmpd/init.h
+++ b/sbin/isakmpd/init.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: init.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: init.h,v 1.2 1998/07/07 23:36:00 niklas Exp $ */
+/* $OpenBSD: init.h,v 1.6 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: init.h,v 1.2 1998/07/07 23:36:00 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -32,7 +32,7 @@
#ifndef _INIT_H_
#define _INIT_H_
-extern void init (void);
-extern void reinit (void);
+extern void init(void);
+extern void reinit(void);
-#endif /* _INIT_H_ */
+#endif /* _INIT_H_ */
diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c
index 189c5a8fb31..d570759467b 100644
--- a/sbin/isakmpd/ipsec.c
+++ b/sbin/isakmpd/ipsec.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ipsec.c,v 1.88 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
+/* $OpenBSD: ipsec.c,v 1.89 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -78,115 +78,117 @@
#define DEFAULT_REPLAY_WINDOW 16
struct ipsec_decode_arg {
- struct message *msg;
- struct sa *sa;
- struct proto *proto;
+ struct message *msg;
+ struct sa *sa;
+ struct proto *proto;
};
/* These variables hold the contacted peers ADT state. */
struct contact {
- struct sockaddr *addr;
- socklen_t len;
-} *contacts = 0;
-int contact_cnt = 0, contact_limit = 0;
-
-static int addr_cmp (const void *, const void *);
-static int ipsec_add_contact (struct message *msg);
-static int ipsec_contacted (struct message *msg);
+ struct sockaddr *addr;
+ socklen_t len;
+} *contacts = 0;
+int contact_cnt = 0, contact_limit = 0;
+
+static int addr_cmp(const void *, const void *);
+static int ipsec_add_contact(struct message * msg);
+static int ipsec_contacted(struct message * msg);
#ifdef USE_DEBUG
-static int ipsec_debug_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
+static int ipsec_debug_attribute(u_int16_t, u_int8_t *, u_int16_t, void *);
#endif
-static void ipsec_delete_spi (struct sa *, struct proto *, int);
-static int16_t *ipsec_exchange_script (u_int8_t);
-static void ipsec_finalize_exchange (struct message *);
-static void ipsec_free_exchange_data (void *);
-static void ipsec_free_proto_data (void *);
-static void ipsec_free_sa_data (void *);
-static struct keystate *ipsec_get_keystate (struct message *);
-static u_int8_t *ipsec_get_spi (size_t *, u_int8_t, struct message *);
-static int ipsec_handle_leftover_payload (struct message *, u_int8_t,
- struct payload *);
-static int ipsec_informational_post_hook (struct message *);
-static int ipsec_informational_pre_hook (struct message *);
-static int ipsec_initiator (struct message *);
-static void ipsec_proto_init (struct proto *, char *);
-static int ipsec_responder (struct message *);
-static void ipsec_setup_situation (u_int8_t *);
-static int ipsec_set_network (u_int8_t *, u_int8_t *, struct ipsec_sa *);
-static size_t ipsec_situation_size (void);
-static u_int8_t ipsec_spi_size (u_int8_t);
-static int ipsec_validate_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
-static int ipsec_validate_exchange (u_int8_t);
-static int ipsec_validate_id_information (u_int8_t, u_int8_t *, u_int8_t *,
- size_t, struct exchange *);
-static int ipsec_validate_key_information (u_int8_t *, size_t);
-static int ipsec_validate_notification (u_int16_t);
-static int ipsec_validate_proto (u_int8_t);
-static int ipsec_validate_situation (u_int8_t *, size_t *, size_t);
-static int ipsec_validate_transform_id (u_int8_t, u_int8_t);
+static void ipsec_delete_spi(struct sa *, struct proto *, int);
+static int16_t *ipsec_exchange_script(u_int8_t);
+static void ipsec_finalize_exchange(struct message *);
+static void ipsec_free_exchange_data(void *);
+static void ipsec_free_proto_data(void *);
+static void ipsec_free_sa_data(void *);
+static struct keystate *ipsec_get_keystate(struct message *);
+static u_int8_t *ipsec_get_spi(size_t *, u_int8_t, struct message *);
+static int
+ipsec_handle_leftover_payload(struct message *, u_int8_t,
+ struct payload *);
+static int ipsec_informational_post_hook(struct message *);
+static int ipsec_informational_pre_hook(struct message *);
+static int ipsec_initiator(struct message *);
+static void ipsec_proto_init(struct proto *, char *);
+static int ipsec_responder(struct message *);
+static void ipsec_setup_situation(u_int8_t *);
+static int ipsec_set_network(u_int8_t *, u_int8_t *, struct ipsec_sa *);
+static size_t ipsec_situation_size(void);
+static u_int8_t ipsec_spi_size(u_int8_t);
+static int ipsec_validate_attribute(u_int16_t, u_int8_t *, u_int16_t, void *);
+static int ipsec_validate_exchange(u_int8_t);
+static int
+ipsec_validate_id_information(u_int8_t, u_int8_t *, u_int8_t *,
+ size_t, struct exchange *);
+static int ipsec_validate_key_information(u_int8_t *, size_t);
+static int ipsec_validate_notification(u_int16_t);
+static int ipsec_validate_proto(u_int8_t);
+static int ipsec_validate_situation(u_int8_t *, size_t *, size_t);
+static int ipsec_validate_transform_id(u_int8_t, u_int8_t);
static struct doi ipsec_doi = {
- { 0 }, IPSEC_DOI_IPSEC,
- sizeof (struct ipsec_exch), sizeof (struct ipsec_sa),
- sizeof (struct ipsec_proto),
+ {0}, IPSEC_DOI_IPSEC,
+ sizeof(struct ipsec_exch), sizeof(struct ipsec_sa),
+ sizeof(struct ipsec_proto),
#ifdef USE_DEBUG
- ipsec_debug_attribute,
+ ipsec_debug_attribute,
#endif
- ipsec_delete_spi,
- ipsec_exchange_script,
- ipsec_finalize_exchange,
- ipsec_free_exchange_data,
- ipsec_free_proto_data,
- ipsec_free_sa_data,
- ipsec_get_keystate,
- ipsec_get_spi,
- ipsec_handle_leftover_payload,
- ipsec_informational_post_hook,
- ipsec_informational_pre_hook,
- ipsec_is_attribute_incompatible,
- ipsec_proto_init,
- ipsec_setup_situation,
- ipsec_situation_size,
- ipsec_spi_size,
- ipsec_validate_attribute,
- ipsec_validate_exchange,
- ipsec_validate_id_information,
- ipsec_validate_key_information,
- ipsec_validate_notification,
- ipsec_validate_proto,
- ipsec_validate_situation,
- ipsec_validate_transform_id,
- ipsec_initiator,
- ipsec_responder,
- ipsec_decode_ids
+ ipsec_delete_spi,
+ ipsec_exchange_script,
+ ipsec_finalize_exchange,
+ ipsec_free_exchange_data,
+ ipsec_free_proto_data,
+ ipsec_free_sa_data,
+ ipsec_get_keystate,
+ ipsec_get_spi,
+ ipsec_handle_leftover_payload,
+ ipsec_informational_post_hook,
+ ipsec_informational_pre_hook,
+ ipsec_is_attribute_incompatible,
+ ipsec_proto_init,
+ ipsec_setup_situation,
+ ipsec_situation_size,
+ ipsec_spi_size,
+ ipsec_validate_attribute,
+ ipsec_validate_exchange,
+ ipsec_validate_id_information,
+ ipsec_validate_key_information,
+ ipsec_validate_notification,
+ ipsec_validate_proto,
+ ipsec_validate_situation,
+ ipsec_validate_transform_id,
+ ipsec_initiator,
+ ipsec_responder,
+ ipsec_decode_ids
};
-int16_t script_quick_mode[] = {
- ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_SA,
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_HASH, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_SA,
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_END
+int16_t script_quick_mode[] = {
+ ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_SA,
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_HASH, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_SA,
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_END
};
-int16_t script_new_group_mode[] = {
- ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_SA,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_HASH, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_SA,
- EXCHANGE_SCRIPT_END
+int16_t script_new_group_mode[] = {
+ ISAKMP_PAYLOAD_HASH, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_SA,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_HASH, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_SA,
+ EXCHANGE_SCRIPT_END
};
struct dst_spi_proto_arg {
- struct sockaddr *dst;
- u_int32_t spi;
- u_int8_t proto;
+ struct sockaddr *dst;
+ u_int32_t spi;
+ u_int8_t proto;
};
/*
@@ -195,49 +197,47 @@ struct dst_spi_proto_arg {
* if "proto" arg is 0, match any proto
*/
static int
-ipsec_sa_check (struct sa *sa, void *v_arg)
+ipsec_sa_check(struct sa *sa, void *v_arg)
{
- struct dst_spi_proto_arg *arg = v_arg;
- struct proto *proto;
- struct sockaddr *dst, *src;
- int incoming;
-
- if (sa->phase != 2 || !(sa->flags & SA_FLAG_READY))
- return 0;
-
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- if (memcmp (sockaddr_addrdata (dst), sockaddr_addrdata (arg->dst),
- sockaddr_addrlen (dst)) == 0)
- incoming = 0;
- else
- {
- sa->transport->vtbl->get_src (sa->transport, &src);
- if (memcmp (sockaddr_addrdata (src), sockaddr_addrdata (arg->dst),
- sockaddr_addrlen (src)) == 0)
- incoming = 1;
- else
+ struct dst_spi_proto_arg *arg = v_arg;
+ struct proto *proto;
+ struct sockaddr *dst, *src;
+ int incoming;
+
+ if (sa->phase != 2 || !(sa->flags & SA_FLAG_READY))
+ return 0;
+
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ if (memcmp(sockaddr_addrdata(dst), sockaddr_addrdata(arg->dst),
+ sockaddr_addrlen(dst)) == 0)
+ incoming = 0;
+ else {
+ sa->transport->vtbl->get_src(sa->transport, &src);
+ if (memcmp(sockaddr_addrdata(src), sockaddr_addrdata(arg->dst),
+ sockaddr_addrlen(src)) == 0)
+ incoming = 1;
+ else
+ return 0;
+ }
+
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link))
+ if ((arg->proto == 0 || proto->proto == arg->proto) &&
+ memcmp(proto->spi[incoming], &arg->spi, sizeof arg->spi) == 0)
+ return 1;
return 0;
- }
-
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- if ((arg->proto == 0 || proto->proto == arg->proto)
- && memcmp (proto->spi[incoming], &arg->spi, sizeof arg->spi) == 0)
- return 1;
- return 0;
}
/* Find an SA with a "name" of DST, SPI & PROTO. */
-struct sa *
-ipsec_sa_lookup (struct sockaddr *dst, u_int32_t spi, u_int8_t proto)
+struct sa *
+ipsec_sa_lookup(struct sockaddr * dst, u_int32_t spi, u_int8_t proto)
{
- struct dst_spi_proto_arg arg;
+ struct dst_spi_proto_arg arg;
- arg.dst = dst;
- arg.spi = spi;
- arg.proto = proto;
-
- return sa_find (ipsec_sa_check, &arg);
+ arg.dst = dst;
+ arg.spi = spi;
+ arg.proto = proto;
+ return sa_find(ipsec_sa_check, &arg);
}
/*
@@ -246,32 +246,32 @@ ipsec_sa_lookup (struct sockaddr *dst, u_int32_t spi, u_int8_t proto)
* XXX At some point other selectors will matter here too.
*/
static int
-ipsec_sa_check_flow (struct sa *sa, void *v_arg)
+ipsec_sa_check_flow(struct sa * sa, void *v_arg)
{
- struct sa *sa2 = v_arg;
- struct ipsec_sa *isa = sa->data, *isa2 = sa2->data;
-
- if (sa == sa2 || sa->phase != 2
- || (sa->flags & (SA_FLAG_READY | SA_FLAG_REPLACED)) != SA_FLAG_READY)
- return 0;
-
- if (isa->tproto != isa2->tproto || isa->sport != isa2->sport
- || isa->dport != isa2->dport)
- return 0;
-
- return isa->src_net->sa_family == isa2->src_net->sa_family
- && memcmp (sockaddr_addrdata (isa->src_net),
- sockaddr_addrdata (isa2->src_net),
- sockaddr_addrlen (isa->src_net)) == 0
- && memcmp (sockaddr_addrdata (isa->src_mask),
- sockaddr_addrdata (isa2->src_mask),
- sockaddr_addrlen (isa->src_mask)) == 0
- && memcmp (sockaddr_addrdata (isa->dst_net),
- sockaddr_addrdata (isa2->dst_net),
- sockaddr_addrlen (isa->dst_net)) == 0
- && memcmp (sockaddr_addrdata (isa->dst_mask),
- sockaddr_addrdata (isa2->dst_mask),
- sockaddr_addrlen (isa->dst_mask)) == 0;
+ struct sa *sa2 = v_arg;
+ struct ipsec_sa *isa = sa->data, *isa2 = sa2->data;
+
+ if (sa == sa2 || sa->phase != 2 ||
+ (sa->flags & (SA_FLAG_READY | SA_FLAG_REPLACED)) != SA_FLAG_READY)
+ return 0;
+
+ if (isa->tproto != isa2->tproto || isa->sport != isa2->sport ||
+ isa->dport != isa2->dport)
+ return 0;
+
+ return isa->src_net->sa_family == isa2->src_net->sa_family &&
+ memcmp(sockaddr_addrdata(isa->src_net),
+ sockaddr_addrdata(isa2->src_net),
+ sockaddr_addrlen(isa->src_net)) == 0 &&
+ memcmp(sockaddr_addrdata(isa->src_mask),
+ sockaddr_addrdata(isa2->src_mask),
+ sockaddr_addrlen(isa->src_mask)) == 0 &&
+ memcmp(sockaddr_addrdata(isa->dst_net),
+ sockaddr_addrdata(isa2->dst_net),
+ sockaddr_addrlen(isa->dst_net)) == 0 &&
+ memcmp(sockaddr_addrdata(isa->dst_mask),
+ sockaddr_addrdata(isa2->dst_mask),
+ sockaddr_addrlen(isa->dst_mask)) == 0;
}
/*
@@ -279,672 +279,663 @@ ipsec_sa_check_flow (struct sa *sa, void *v_arg)
* the final message.
*/
static void
-ipsec_finalize_exchange (struct message *msg)
+ipsec_finalize_exchange(struct message * msg)
{
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa;
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct sa *sa = 0, *old_sa;
- struct proto *proto, *last_proto = 0;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct sa *sa = 0, *old_sa;
+ struct proto *proto, *last_proto = 0;
#ifdef USE_DEBUG
- char *addr1, *addr2, *mask1, *mask2;
+ char *addr1, *addr2, *mask1, *mask2;
#endif
- switch (exchange->phase)
- {
- case 1:
- switch (exchange->type)
- {
- case ISAKMP_EXCH_ID_PROT:
- case ISAKMP_EXCH_AGGRESSIVE:
- isa = isakmp_sa->data;
- isa->hash = ie->hash->type;
- isa->prf_type = ie->prf_type;
- isa->skeyid_len = ie->skeyid_len;
- isa->skeyid_d = ie->skeyid_d;
- isa->skeyid_a = ie->skeyid_a;
- /* Prevents early free of SKEYID_*. */
- ie->skeyid_a = ie->skeyid_d = 0;
-
- /* If a lifetime was negotiated setup the expiration timers. */
- if (isakmp_sa->seconds)
- sa_setup_expirations (isakmp_sa);
- break;
- }
- break;
-
- case 2:
- switch (exchange->type)
- {
- case IKE_EXCH_QUICK_MODE:
- /*
- * Tell the application(s) about the SPIs and key material.
- */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa;
- sa = TAILQ_NEXT (sa, next))
- {
- isa = sa->data;
-
- if (exchange->initiator)
- {
- /* Initiator is source, responder is destination. */
- if (ipsec_set_network (ie->id_ci, ie->id_cr, isa))
- {
- log_print ("ipsec_finalize_exchange: "
- "ipsec_set_network failed");
- return;
- }
- }
- else
- {
- /* Responder is source, initiator is destination. */
- if (ipsec_set_network (ie->id_cr, ie->id_ci, isa))
- {
- log_print ("ipsec_finalize_exchange: "
- "ipsec_set_network failed");
- return;
- }
- }
-
- for (proto = TAILQ_FIRST (&sa->protos), last_proto = 0; proto;
- proto = TAILQ_NEXT (proto, link))
- {
- if (sysdep_ipsec_set_spi (sa, proto, 0, isakmp_sa)
- || (last_proto
- && sysdep_ipsec_group_spis (sa, last_proto, proto,
- 0))
- || sysdep_ipsec_set_spi (sa, proto, 1, isakmp_sa)
- || (last_proto
- && sysdep_ipsec_group_spis (sa, last_proto, proto,
- 1)))
- /* XXX Tear down this exchange. */
- return;
- last_proto = proto;
+ switch (exchange->phase) {
+ case 1:
+ switch (exchange->type) {
+ case ISAKMP_EXCH_ID_PROT:
+ case ISAKMP_EXCH_AGGRESSIVE:
+ isa = isakmp_sa->data;
+ isa->hash = ie->hash->type;
+ isa->prf_type = ie->prf_type;
+ isa->skeyid_len = ie->skeyid_len;
+ isa->skeyid_d = ie->skeyid_d;
+ isa->skeyid_a = ie->skeyid_a;
+ /* Prevents early free of SKEYID_*. */
+ ie->skeyid_a = ie->skeyid_d = 0;
+
+ /*
+ * If a lifetime was negotiated setup the expiration
+ * timers.
+ */
+ if (isakmp_sa->seconds)
+ sa_setup_expirations(isakmp_sa);
+ break;
}
+ break;
+
+ case 2:
+ switch (exchange->type) {
+ case IKE_EXCH_QUICK_MODE:
+ /*
+ * Tell the application(s) about the SPIs and key material.
+ */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa;
+ sa = TAILQ_NEXT(sa, next)) {
+ isa = sa->data;
+
+ if (exchange->initiator) {
+ /*
+ * Initiator is source, responder is
+ * destination.
+ */
+ if (ipsec_set_network(ie->id_ci,
+ ie->id_cr, isa)) {
+ log_print("ipsec_finalize_exchange: "
+ "ipsec_set_network failed");
+ return;
+ }
+ } else {
+ /*
+ * Responder is source, initiator is
+ * destination.
+ */
+ if (ipsec_set_network(ie->id_cr, ie->id_ci,
+ isa)) {
+ log_print("ipsec_finalize_exchange: "
+ "ipsec_set_network failed");
+ return;
+ }
+ }
+
+ for (proto = TAILQ_FIRST(&sa->protos),
+ last_proto = 0; proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ if (sysdep_ipsec_set_spi(sa, proto,
+ 0, isakmp_sa) ||
+ (last_proto && sysdep_ipsec_group_spis(sa,
+ last_proto, proto, 0)) ||
+ sysdep_ipsec_set_spi(sa, proto,
+ 1, isakmp_sa) ||
+ (last_proto && sysdep_ipsec_group_spis(sa,
+ last_proto, proto, 1)))
+ /*
+ * XXX Tear down this
+ * exchange.
+ */
+ return;
+ last_proto = proto;
+ }
#ifdef USE_DEBUG
- if (sockaddr2text (isa->src_net, &addr1, 0))
- addr1 = 0;
- if (sockaddr2text (isa->src_mask, &mask1, 0))
- mask1 = 0;
- if (sockaddr2text (isa->dst_net, &addr2, 0))
- addr2 = 0;
- if (sockaddr2text (isa->dst_mask, &mask2, 0))
- mask2 = 0;
-
- LOG_DBG ((LOG_EXCHANGE, 50,
- "ipsec_finalize_exchange: "
- "src %s %s dst %s %s tproto %u sport %u dport %u",
- addr1 ? addr1 : "<??\?>" , mask1 ? mask1 : "<??\?>",
- addr2 ? addr2 : "<??\?>" , mask2 ? mask2 : "<??\?>",
- isa->tproto, ntohs (isa->sport), ntohs (isa->dport)));
-
- if (addr1)
- free (addr1);
- if (mask1)
- free (mask1);
- if (addr2)
- free (addr2);
- if (mask2)
- free (mask2);
-
-#endif /* USE_DEBUG */
-
- /*
- * If this is not an SA acquired by the kernel, it needs
- * to have a SPD entry (a.k.a. flow) set up.
- */
- if (!(sa->flags & SA_FLAG_ONDEMAND)
- && sysdep_ipsec_enable_sa (sa, isakmp_sa))
- /* XXX Tear down this exchange. */
- return;
-
- /* Mark elder SAs with the same flow information as replaced. */
- while ((old_sa = sa_find (ipsec_sa_check_flow, sa)) != 0)
- sa_mark_replaced (old_sa);
- }
- break;
+ if (sockaddr2text(isa->src_net, &addr1, 0))
+ addr1 = 0;
+ if (sockaddr2text(isa->src_mask, &mask1, 0))
+ mask1 = 0;
+ if (sockaddr2text(isa->dst_net, &addr2, 0))
+ addr2 = 0;
+ if (sockaddr2text(isa->dst_mask, &mask2, 0))
+ mask2 = 0;
+
+ LOG_DBG((LOG_EXCHANGE, 50,
+ "ipsec_finalize_exchange: "
+ "src %s %s dst %s %s tproto %u sport %u dport %u",
+ addr1 ? addr1 : "<??\?>", mask1 ? mask1 : "<??\?>",
+ addr2 ? addr2 : "<??\?>", mask2 ? mask2 : "<??\?>",
+ isa->tproto, ntohs(isa->sport), ntohs(isa->dport)));
+
+ if (addr1)
+ free(addr1);
+ if (mask1)
+ free(mask1);
+ if (addr2)
+ free(addr2);
+ if (mask2)
+ free(mask2);
+
+#endif /* USE_DEBUG */
+
+ /*
+ * If this is not an SA acquired by the kernel, it needs
+ * to have a SPD entry (a.k.a. flow) set up.
+ */
+ if (!(sa->flags & SA_FLAG_ONDEMAND) &&
+ sysdep_ipsec_enable_sa(sa, isakmp_sa))
+ /* XXX Tear down this exchange. */
+ return;
+
+ /*
+ * Mark elder SAs with the same flow
+ * information as replaced.
+ */
+ while ((old_sa = sa_find(ipsec_sa_check_flow, sa)) != 0)
+ sa_mark_replaced(old_sa);
+ }
+ break;
+ }
}
- }
}
/* Set the client addresses in ISA from SRC_ID and DST_ID. */
static int
-ipsec_set_network (u_int8_t *src_id, u_int8_t *dst_id, struct ipsec_sa *isa)
+ipsec_set_network(u_int8_t *src_id, u_int8_t *dst_id, struct ipsec_sa *isa)
{
- int id;
-
- /* Set source address/mask. */
- id = GET_ISAKMP_ID_TYPE (src_id);
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- isa->src_net =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
- if (!isa->src_net)
- goto memfail;
- isa->src_net->sa_family = AF_INET;
+ int id;
+
+ /* Set source address/mask. */
+ id = GET_ISAKMP_ID_TYPE(src_id);
+ switch (id) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ isa->src_net = (struct sockaddr *) calloc(1,
+ sizeof(struct sockaddr_in));
+ if (!isa->src_net)
+ goto memfail;
+ isa->src_net->sa_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- isa->src_net->sa_len = sizeof (struct sockaddr_in);
+ isa->src_net->sa_len = sizeof(struct sockaddr_in);
#endif
- isa->src_mask =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
- if (!isa->src_mask)
- goto memfail;
- isa->src_mask->sa_family = AF_INET;
+ isa->src_mask = (struct sockaddr *) calloc(1,
+ sizeof(struct sockaddr_in));
+ if (!isa->src_mask)
+ goto memfail;
+ isa->src_mask->sa_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- isa->src_mask->sa_len = sizeof (struct sockaddr_in);
+ isa->src_mask->sa_len = sizeof(struct sockaddr_in);
#endif
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- isa->src_net =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
- if (!isa->src_net)
- goto memfail;
- isa->src_net->sa_family = AF_INET6;
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ isa->src_net = (struct sockaddr *) calloc(1,
+ sizeof(struct sockaddr_in6));
+ if (!isa->src_net)
+ goto memfail;
+ isa->src_net->sa_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- isa->src_net->sa_len = sizeof (struct sockaddr_in6);
+ isa->src_net->sa_len = sizeof(struct sockaddr_in6);
#endif
- isa->src_mask =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
- if (!isa->src_mask)
- goto memfail;
- isa->src_mask->sa_family = AF_INET6;
+ isa->src_mask = (struct sockaddr *) calloc(1,
+ sizeof(struct sockaddr_in6));
+ if (!isa->src_mask)
+ goto memfail;
+ isa->src_mask->sa_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- isa->src_mask->sa_len = sizeof (struct sockaddr_in6);
+ isa->src_mask->sa_len = sizeof(struct sockaddr_in6);
#endif
- break;
-
- case IPSEC_ID_IPV4_RANGE:
- case IPSEC_ID_IPV6_RANGE:
- case IPSEC_ID_DER_ASN1_DN:
- case IPSEC_ID_DER_ASN1_GN:
- case IPSEC_ID_KEY_ID:
- default:
- log_print ("ipsec_set_network: ID type %d (%s) not supported",
- id, constant_name (ipsec_id_cst, id));
- return -1;
- }
-
- /* Net */
- memcpy (sockaddr_addrdata (isa->src_net), src_id + ISAKMP_ID_DATA_OFF,
- sockaddr_addrlen (isa->src_net));
-
- /* Mask */
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- memset (sockaddr_addrdata (isa->src_mask), 0xff,
- sockaddr_addrlen (isa->src_mask));
- break;
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- memcpy (sockaddr_addrdata (isa->src_mask), src_id + ISAKMP_ID_DATA_OFF +
- sockaddr_addrlen (isa->src_net),
- sockaddr_addrlen (isa->src_mask));
- break;
- }
-
- memcpy (&isa->sport, src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
-
- /* Set destination address. */
- id = GET_ISAKMP_ID_TYPE (dst_id);
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- isa->dst_net =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
- if (!isa->dst_net)
- goto memfail;
- isa->dst_net->sa_family = AF_INET;
+ break;
+
+ case IPSEC_ID_IPV4_RANGE:
+ case IPSEC_ID_IPV6_RANGE:
+ case IPSEC_ID_DER_ASN1_DN:
+ case IPSEC_ID_DER_ASN1_GN:
+ case IPSEC_ID_KEY_ID:
+ default:
+ log_print("ipsec_set_network: ID type %d (%s) not supported",
+ id, constant_name(ipsec_id_cst, id));
+ return -1;
+ }
+
+ /* Net */
+ memcpy(sockaddr_addrdata(isa->src_net), src_id + ISAKMP_ID_DATA_OFF,
+ sockaddr_addrlen(isa->src_net));
+
+ /* Mask */
+ switch (id) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ memset(sockaddr_addrdata(isa->src_mask), 0xff,
+ sockaddr_addrlen(isa->src_mask));
+ break;
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ memcpy(sockaddr_addrdata(isa->src_mask), src_id + ISAKMP_ID_DATA_OFF +
+ sockaddr_addrlen(isa->src_net), sockaddr_addrlen(isa->src_mask));
+ break;
+ }
+
+ memcpy(&isa->sport, src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
+ IPSEC_ID_PORT_LEN);
+
+ /* Set destination address. */
+ id = GET_ISAKMP_ID_TYPE(dst_id);
+ switch (id) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ isa->dst_net =
+ (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in));
+ if (!isa->dst_net)
+ goto memfail;
+ isa->dst_net->sa_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- isa->dst_net->sa_len = sizeof (struct sockaddr_in);
+ isa->dst_net->sa_len = sizeof(struct sockaddr_in);
#endif
- isa->dst_mask =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
- if (!isa->dst_mask)
- goto memfail;
- isa->dst_mask->sa_family = AF_INET;
+ isa->dst_mask =
+ (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in));
+ if (!isa->dst_mask)
+ goto memfail;
+ isa->dst_mask->sa_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- isa->dst_mask->sa_len = sizeof (struct sockaddr_in);
+ isa->dst_mask->sa_len = sizeof(struct sockaddr_in);
#endif
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- isa->dst_net =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
- if (!isa->dst_net)
- goto memfail;
- isa->dst_net->sa_family = AF_INET6;
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ isa->dst_net =
+ (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in6));
+ if (!isa->dst_net)
+ goto memfail;
+ isa->dst_net->sa_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- isa->dst_net->sa_len = sizeof (struct sockaddr_in6);
+ isa->dst_net->sa_len = sizeof(struct sockaddr_in6);
#endif
- isa->dst_mask =
- (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
- if (!isa->dst_mask)
- goto memfail;
- isa->dst_mask->sa_family = AF_INET6;
+ isa->dst_mask =
+ (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in6));
+ if (!isa->dst_mask)
+ goto memfail;
+ isa->dst_mask->sa_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- isa->dst_mask->sa_len = sizeof (struct sockaddr_in6);
+ isa->dst_mask->sa_len = sizeof(struct sockaddr_in6);
#endif
- break;
- }
-
- /* Net */
- memcpy (sockaddr_addrdata (isa->dst_net), dst_id + ISAKMP_ID_DATA_OFF,
- sockaddr_addrlen (isa->dst_net));
-
- /* Mask */
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- memset (sockaddr_addrdata (isa->dst_mask), 0xff,
- sockaddr_addrlen (isa->dst_mask));
- break;
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- memcpy (sockaddr_addrdata (isa->dst_mask), dst_id + ISAKMP_ID_DATA_OFF +
- sockaddr_addrlen (isa->dst_net),
- sockaddr_addrlen (isa->dst_mask));
- break;
- }
-
- memcpy (&isa->tproto, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
- IPSEC_ID_PROTO_LEN);
- memcpy (&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
- return 0;
-
- memfail:
- log_error ("ipsec_set_network: calloc () failed");
- return -1;
+ break;
+ }
+
+ /* Net */
+ memcpy(sockaddr_addrdata(isa->dst_net), dst_id + ISAKMP_ID_DATA_OFF,
+ sockaddr_addrlen(isa->dst_net));
+
+ /* Mask */
+ switch (id) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ memset(sockaddr_addrdata(isa->dst_mask), 0xff,
+ sockaddr_addrlen(isa->dst_mask));
+ break;
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ memcpy(sockaddr_addrdata(isa->dst_mask), dst_id + ISAKMP_ID_DATA_OFF +
+ sockaddr_addrlen(isa->dst_net),
+ sockaddr_addrlen(isa->dst_mask));
+ break;
+ }
+
+ memcpy(&isa->tproto, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
+ IPSEC_ID_PROTO_LEN);
+ memcpy(&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
+ IPSEC_ID_PORT_LEN);
+ return 0;
+
+memfail:
+ log_error("ipsec_set_network: calloc () failed");
+ return -1;
}
/* Free the DOI-specific exchange data pointed to by VIE. */
static void
-ipsec_free_exchange_data (void *vie)
+ipsec_free_exchange_data(void *vie)
{
- struct ipsec_exch *ie = vie;
+ struct ipsec_exch *ie = vie;
#ifdef USE_ISAKMP_CFG
- struct isakmp_cfg_attr *attr;
+ struct isakmp_cfg_attr *attr;
#endif
- if (ie->sa_i_b)
- free (ie->sa_i_b);
- if (ie->id_ci)
- free (ie->id_ci);
- if (ie->id_cr)
- free (ie->id_cr);
- if (ie->g_xi)
- free (ie->g_xi);
- if (ie->g_xr)
- free (ie->g_xr);
- if (ie->g_xy)
- free (ie->g_xy);
- if (ie->skeyid)
- free (ie->skeyid);
- if (ie->skeyid_d)
- free (ie->skeyid_d);
- if (ie->skeyid_a)
- free (ie->skeyid_a);
- if (ie->skeyid_e)
- free (ie->skeyid_e);
- if (ie->hash_i)
- free (ie->hash_i);
- if (ie->hash_r)
- free (ie->hash_r);
- if (ie->group)
- group_free (ie->group);
+ if (ie->sa_i_b)
+ free(ie->sa_i_b);
+ if (ie->id_ci)
+ free(ie->id_ci);
+ if (ie->id_cr)
+ free(ie->id_cr);
+ if (ie->g_xi)
+ free(ie->g_xi);
+ if (ie->g_xr)
+ free(ie->g_xr);
+ if (ie->g_xy)
+ free(ie->g_xy);
+ if (ie->skeyid)
+ free(ie->skeyid);
+ if (ie->skeyid_d)
+ free(ie->skeyid_d);
+ if (ie->skeyid_a)
+ free(ie->skeyid_a);
+ if (ie->skeyid_e)
+ free(ie->skeyid_e);
+ if (ie->hash_i)
+ free(ie->hash_i);
+ if (ie->hash_r)
+ free(ie->hash_r);
+ if (ie->group)
+ group_free(ie->group);
#ifdef USE_ISAKMP_CFG
- for (attr = LIST_FIRST (&ie->attrs); attr; attr = LIST_FIRST (&ie->attrs))
- {
- LIST_REMOVE (attr, link);
- if (attr->length)
- free (attr->value);
- free (attr);
- }
+ for (attr = LIST_FIRST(&ie->attrs); attr; attr = LIST_FIRST(&ie->attrs)) {
+ LIST_REMOVE(attr, link);
+ if (attr->length)
+ free(attr->value);
+ free(attr);
+ }
#endif
}
/* Free the DOI-specific SA data pointed to by VISA. */
static void
-ipsec_free_sa_data (void *visa)
+ipsec_free_sa_data(void *visa)
{
- struct ipsec_sa *isa = visa;
-
- if (isa->src_net)
- free (isa->src_net);
- if (isa->src_mask)
- free (isa->src_mask);
- if (isa->dst_net)
- free (isa->dst_net);
- if (isa->dst_mask)
- free (isa->dst_mask);
- if (isa->skeyid_a)
- free (isa->skeyid_a);
- if (isa->skeyid_d)
- free (isa->skeyid_d);
+ struct ipsec_sa *isa = visa;
+
+ if (isa->src_net)
+ free(isa->src_net);
+ if (isa->src_mask)
+ free(isa->src_mask);
+ if (isa->dst_net)
+ free(isa->dst_net);
+ if (isa->dst_mask)
+ free(isa->dst_mask);
+ if (isa->skeyid_a)
+ free(isa->skeyid_a);
+ if (isa->skeyid_d)
+ free(isa->skeyid_d);
}
/* Free the DOI-specific protocol data of an SA pointed to by VIPROTO. */
static void
-ipsec_free_proto_data (void *viproto)
+ipsec_free_proto_data(void *viproto)
{
- struct ipsec_proto *iproto = viproto;
- int i;
+ struct ipsec_proto *iproto = viproto;
+ int i;
- for (i = 0; i < 2; i++)
- if (iproto->keymat[i])
- free (iproto->keymat[i]);
+ for (i = 0; i < 2; i++)
+ if (iproto->keymat[i])
+ free(iproto->keymat[i]);
}
/* Return exchange script based on TYPE. */
static int16_t *
-ipsec_exchange_script (u_int8_t type)
+ipsec_exchange_script(u_int8_t type)
{
- switch (type)
- {
+ switch (type) {
#ifdef USE_ISAKMP_CFG
- case ISAKMP_EXCH_TRANSACTION:
- return script_transaction;
+ case ISAKMP_EXCH_TRANSACTION:
+ return script_transaction;
#endif
- case IKE_EXCH_QUICK_MODE:
- return script_quick_mode;
- case IKE_EXCH_NEW_GROUP_MODE:
- return script_new_group_mode;
- }
- return 0;
+ case IKE_EXCH_QUICK_MODE:
+ return script_quick_mode;
+ case IKE_EXCH_NEW_GROUP_MODE:
+ return script_new_group_mode;
+ }
+ return 0;
}
/* Initialize this DOI, requires doi_init to already have been called. */
void
-ipsec_init (void)
+ipsec_init(void)
{
- doi_register (&ipsec_doi);
+ doi_register(&ipsec_doi);
}
/* Given a message MSG, return a suitable IV (or rather keystate). */
static struct keystate *
-ipsec_get_keystate (struct message *msg)
+ipsec_get_keystate(struct message * msg)
{
- struct keystate *ks;
- struct hash *hash;
-
- /* If we have already have an IV, use it. */
- if (msg->exchange && msg->exchange->keystate)
- {
- ks = malloc (sizeof *ks);
- if (!ks)
- {
- log_error ("ipsec_get_keystate: malloc (%lu) failed",
- (unsigned long)sizeof *ks);
- return 0;
+ struct keystate *ks;
+ struct hash *hash;
+
+ /* If we have already have an IV, use it. */
+ if (msg->exchange && msg->exchange->keystate) {
+ ks = malloc(sizeof *ks);
+ if (!ks) {
+ log_error("ipsec_get_keystate: malloc (%lu) failed",
+ (unsigned long) sizeof *ks);
+ return 0;
+ }
+ memcpy(ks, msg->exchange->keystate, sizeof *ks);
+ return ks;
}
- memcpy (ks, msg->exchange->keystate, sizeof *ks);
- return ks;
- }
-
- /*
- * For phase 2 when no SA yet is setup we need to hash the IV used by
- * the ISAKMP SA concatenated with the message ID, and use that as an
- * IV for further cryptographic operations.
- */
- if (!msg->isakmp_sa->keystate)
- {
- log_print ("ipsec_get_keystate: no keystate in ISAKMP SA %p",
- msg->isakmp_sa);
- return 0;
- }
- ks = crypto_clone_keystate (msg->isakmp_sa->keystate);
- if (!ks)
- return 0;
-
- hash = hash_get (((struct ipsec_sa *)msg->isakmp_sa->data)->hash);
- hash->Init (hash->ctx);
- LOG_DBG_BUF ((LOG_CRYPTO, 80, "ipsec_get_keystate: final phase 1 IV",
- ks->riv, ks->xf->blocksize));
- hash->Update (hash->ctx, ks->riv, ks->xf->blocksize);
- LOG_DBG_BUF ((LOG_CRYPTO, 80, "ipsec_get_keystate: message ID",
- ((u_int8_t *)msg->iov[0].iov_base)
- + ISAKMP_HDR_MESSAGE_ID_OFF,
- ISAKMP_HDR_MESSAGE_ID_LEN));
- hash->Update (hash->ctx,
- ((u_int8_t *)msg->iov[0].iov_base) + ISAKMP_HDR_MESSAGE_ID_OFF,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- hash->Final (hash->digest, hash->ctx);
- crypto_init_iv (ks, hash->digest, ks->xf->blocksize);
- LOG_DBG_BUF ((LOG_CRYPTO, 80, "ipsec_get_keystate: phase 2 IV",
- hash->digest, ks->xf->blocksize));
- return ks;
+ /*
+ * For phase 2 when no SA yet is setup we need to hash the IV used by
+ * the ISAKMP SA concatenated with the message ID, and use that as an
+ * IV for further cryptographic operations.
+ */
+ if (!msg->isakmp_sa->keystate) {
+ log_print("ipsec_get_keystate: no keystate in ISAKMP SA %p",
+ msg->isakmp_sa);
+ return 0;
+ }
+ ks = crypto_clone_keystate(msg->isakmp_sa->keystate);
+ if (!ks)
+ return 0;
+
+ hash = hash_get(((struct ipsec_sa *) msg->isakmp_sa->data)->hash);
+ hash->Init(hash->ctx);
+ LOG_DBG_BUF((LOG_CRYPTO, 80, "ipsec_get_keystate: final phase 1 IV",
+ ks->riv, ks->xf->blocksize));
+ hash->Update(hash->ctx, ks->riv, ks->xf->blocksize);
+ LOG_DBG_BUF((LOG_CRYPTO, 80, "ipsec_get_keystate: message ID",
+ ((u_int8_t *) msg->iov[0].iov_base)
+ + ISAKMP_HDR_MESSAGE_ID_OFF,
+ ISAKMP_HDR_MESSAGE_ID_LEN));
+ hash->Update(hash->ctx,
+ ((u_int8_t *) msg->iov[0].iov_base) + ISAKMP_HDR_MESSAGE_ID_OFF,
+ ISAKMP_HDR_MESSAGE_ID_LEN);
+ hash->Final(hash->digest, hash->ctx);
+ crypto_init_iv(ks, hash->digest, ks->xf->blocksize);
+ LOG_DBG_BUF((LOG_CRYPTO, 80, "ipsec_get_keystate: phase 2 IV",
+ hash->digest, ks->xf->blocksize));
+ return ks;
}
static void
-ipsec_setup_situation (u_int8_t *buf)
+ipsec_setup_situation(u_int8_t * buf)
{
- SET_IPSEC_SIT_SIT (buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
+ SET_IPSEC_SIT_SIT(buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
}
-static size_t
-ipsec_situation_size (void)
+static size_t
+ipsec_situation_size(void)
{
- return IPSEC_SIT_SIT_LEN;
+ return IPSEC_SIT_SIT_LEN;
}
-static u_int8_t
-ipsec_spi_size (u_int8_t proto)
+static u_int8_t
+ipsec_spi_size(u_int8_t proto)
{
- return IPSEC_SPI_SIZE;
+ return IPSEC_SPI_SIZE;
}
static int
-ipsec_validate_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vmsg)
+ipsec_validate_attribute(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *vmsg)
{
- struct message *msg = vmsg;
-
- if ((msg->exchange->phase == 1
- && (type < IKE_ATTR_ENCRYPTION_ALGORITHM
- || type > IKE_ATTR_GROUP_ORDER))
- || (msg->exchange->phase == 2
- && (type < IPSEC_ATTR_SA_LIFE_TYPE
- || type > IPSEC_ATTR_ECN_TUNNEL)))
- return -1;
- return 0;
+ struct message *msg = vmsg;
+
+ if ((msg->exchange->phase == 1
+ && (type < IKE_ATTR_ENCRYPTION_ALGORITHM
+ || type > IKE_ATTR_GROUP_ORDER))
+ || (msg->exchange->phase == 2
+ && (type < IPSEC_ATTR_SA_LIFE_TYPE
+ || type > IPSEC_ATTR_ECN_TUNNEL)))
+ return -1;
+ return 0;
}
static int
-ipsec_validate_exchange (u_int8_t exch)
+ipsec_validate_exchange(u_int8_t exch)
{
- return exch != IKE_EXCH_QUICK_MODE && exch != IKE_EXCH_NEW_GROUP_MODE;
+ return exch != IKE_EXCH_QUICK_MODE && exch != IKE_EXCH_NEW_GROUP_MODE;
}
static int
-ipsec_validate_id_information (u_int8_t type, u_int8_t *extra, u_int8_t *buf,
- size_t sz, struct exchange *exchange)
+ipsec_validate_id_information(u_int8_t type, u_int8_t * extra, u_int8_t * buf,
+ size_t sz, struct exchange * exchange)
{
- u_int8_t proto = GET_IPSEC_ID_PROTO (extra);
- u_int16_t port = GET_IPSEC_ID_PORT (extra);
-
- LOG_DBG ((LOG_MESSAGE, 40,
- "ipsec_validate_id_information: proto %d port %d type %d",
- proto, port, type));
- if (type < IPSEC_ID_IPV4_ADDR || type > IPSEC_ID_KEY_ID)
- return -1;
-
- switch (type)
- {
- case IPSEC_ID_IPV4_ADDR:
- LOG_DBG_BUF ((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv4",
- buf, sizeof (struct in_addr)));
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- LOG_DBG_BUF ((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv6",
- buf, sizeof (struct in6_addr)));
- break;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- LOG_DBG_BUF ((LOG_MESSAGE, 40,
- "ipsec_validate_id_information: IPv4 network/netmask",
- buf, 2 * sizeof (struct in_addr)));
- break;
-
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- LOG_DBG_BUF ((LOG_MESSAGE, 40,
- "ipsec_validate_id_information: IPv6 network/netmask",
- buf, 2 * sizeof (struct in6_addr)));
- break;
-
- default:
- break;
- }
-
- if (exchange->phase == 1
- && (proto != IPPROTO_UDP || port != UDP_DEFAULT_PORT)
- && (proto != 0 || port != 0))
- {
-/* XXX SSH's ISAKMP tester fails this test (proto 17 - port 0). */
+ u_int8_t proto = GET_IPSEC_ID_PROTO(extra);
+ u_int16_t port = GET_IPSEC_ID_PORT(extra);
+
+ LOG_DBG((LOG_MESSAGE, 40,
+ "ipsec_validate_id_information: proto %d port %d type %d",
+ proto, port, type));
+ if (type < IPSEC_ID_IPV4_ADDR || type > IPSEC_ID_KEY_ID)
+ return -1;
+
+ switch (type) {
+ case IPSEC_ID_IPV4_ADDR:
+ LOG_DBG_BUF((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv4",
+ buf, sizeof(struct in_addr)));
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ LOG_DBG_BUF((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv6",
+ buf, sizeof(struct in6_addr)));
+ break;
+
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ LOG_DBG_BUF((LOG_MESSAGE, 40,
+ "ipsec_validate_id_information: IPv4 network/netmask",
+ buf, 2 * sizeof(struct in_addr)));
+ break;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ LOG_DBG_BUF((LOG_MESSAGE, 40,
+ "ipsec_validate_id_information: IPv6 network/netmask",
+ buf, 2 * sizeof(struct in6_addr)));
+ break;
+
+ default:
+ break;
+ }
+
+ if (exchange->phase == 1
+ && (proto != IPPROTO_UDP || port != UDP_DEFAULT_PORT)
+ && (proto != 0 || port != 0)) {
+ /*
+ * XXX SSH's ISAKMP tester fails this test (proto 17 - port
+ * 0).
+ */
#ifdef notyet
- return -1;
+ return -1;
#else
- log_print ("ipsec_validate_id_information: "
- "dubious ID information accepted");
+ log_print("ipsec_validate_id_information: "
+ "dubious ID information accepted");
#endif
- }
-
- /* XXX More checks? */
+ }
+ /* XXX More checks? */
- return 0;
+ return 0;
}
static int
-ipsec_validate_key_information (u_int8_t *buf, size_t sz)
+ipsec_validate_key_information(u_int8_t * buf, size_t sz)
{
- /* XXX Not implemented yet. */
- return 0;
+ /* XXX Not implemented yet. */
+ return 0;
}
static int
-ipsec_validate_notification (u_int16_t type)
+ipsec_validate_notification(u_int16_t type)
{
- return type < IPSEC_NOTIFY_RESPONDER_LIFETIME
- || type > IPSEC_NOTIFY_INITIAL_CONTACT ? -1 : 0;
+ return type < IPSEC_NOTIFY_RESPONDER_LIFETIME
+ || type > IPSEC_NOTIFY_INITIAL_CONTACT ? -1 : 0;
}
static int
-ipsec_validate_proto (u_int8_t proto)
+ipsec_validate_proto(u_int8_t proto)
{
- return proto < IPSEC_PROTO_IPSEC_AH || proto > IPSEC_PROTO_IPCOMP ? -1 : 0;
+ return proto < IPSEC_PROTO_IPSEC_AH || proto > IPSEC_PROTO_IPCOMP ? -1 : 0;
}
static int
-ipsec_validate_situation (u_int8_t *buf, size_t *sz, size_t len)
+ipsec_validate_situation(u_int8_t * buf, size_t * sz, size_t len)
{
- if (len < IPSEC_SIT_SIT_OFF + IPSEC_SIT_SIT_LEN)
- {
- log_print ("ipsec_validate_situation: payload too short: %u",
- (unsigned int)len);
- return -1;
- }
-
- /* Currently only "identity only" situations are supported. */
- if (GET_IPSEC_SIT_SIT (buf) != IPSEC_SIT_IDENTITY_ONLY)
- return 1;
+ if (len < IPSEC_SIT_SIT_OFF + IPSEC_SIT_SIT_LEN) {
+ log_print("ipsec_validate_situation: payload too short: %u",
+ (unsigned int) len);
+ return -1;
+ }
+ /* Currently only "identity only" situations are supported. */
+ if (GET_IPSEC_SIT_SIT(buf) != IPSEC_SIT_IDENTITY_ONLY)
+ return 1;
- *sz = IPSEC_SIT_SIT_LEN;
+ *sz = IPSEC_SIT_SIT_LEN;
- return 0;
+ return 0;
}
static int
-ipsec_validate_transform_id (u_int8_t proto, u_int8_t transform_id)
+ipsec_validate_transform_id(u_int8_t proto, u_int8_t transform_id)
{
- switch (proto)
- {
- /*
- * As no unexpected protocols can occur, we just tie the default case
- * to the first case, in orer to silence a GCC warning.
- */
- default:
- case ISAKMP_PROTO_ISAKMP:
- return transform_id != IPSEC_TRANSFORM_KEY_IKE;
- case IPSEC_PROTO_IPSEC_AH:
- return
- transform_id < IPSEC_AH_MD5 || transform_id > IPSEC_AH_DES ? -1 : 0;
- case IPSEC_PROTO_IPSEC_ESP:
- return transform_id < IPSEC_ESP_DES_IV64
- || (transform_id > IPSEC_ESP_AES_128_CTR
- && transform_id < IPSEC_ESP_AES_MARS)
- || transform_id > IPSEC_ESP_AES_TWOFISH ? -1 : 0;
- case IPSEC_PROTO_IPCOMP:
- return transform_id < IPSEC_IPCOMP_OUI
- || transform_id > IPSEC_IPCOMP_V42BIS ? -1 : 0;
- }
+ switch (proto) {
+ /*
+ * As no unexpected protocols can occur, we just tie the default case
+ * to the first case, in orer to silence a GCC warning.
+ */
+ default:
+ case ISAKMP_PROTO_ISAKMP:
+ return transform_id != IPSEC_TRANSFORM_KEY_IKE;
+ case IPSEC_PROTO_IPSEC_AH:
+ return
+ transform_id < IPSEC_AH_MD5 || transform_id > IPSEC_AH_DES ? -1 : 0;
+ case IPSEC_PROTO_IPSEC_ESP:
+ return transform_id < IPSEC_ESP_DES_IV64
+ || (transform_id > IPSEC_ESP_AES_128_CTR
+ && transform_id < IPSEC_ESP_AES_MARS)
+ || transform_id > IPSEC_ESP_AES_TWOFISH ? -1 : 0;
+ case IPSEC_PROTO_IPCOMP:
+ return transform_id < IPSEC_IPCOMP_OUI
+ || transform_id > IPSEC_IPCOMP_V42BIS ? -1 : 0;
+ }
}
static int
-ipsec_initiator (struct message *msg)
+ipsec_initiator(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- int (**script) (struct message *) = 0;
-
- /* Check that the SA is coherent with the IKE rules. */
- if (exchange->type != ISAKMP_EXCH_TRANSACTION
- && ((exchange->phase == 1 && exchange->type != ISAKMP_EXCH_ID_PROT
- && exchange->type != ISAKMP_EXCH_AGGRESSIVE
- && exchange->type != ISAKMP_EXCH_INFO)
- || (exchange->phase == 2 && exchange->type != IKE_EXCH_QUICK_MODE
- && exchange->type != ISAKMP_EXCH_INFO)))
- {
- log_print ("ipsec_initiator: unsupported exchange type %d in phase %d",
- exchange->type, exchange->phase);
- return -1;
- }
-
- switch (exchange->type)
- {
- case ISAKMP_EXCH_ID_PROT:
- script = ike_main_mode_initiator;
- break;
+ struct exchange *exchange = msg->exchange;
+ int (**script) (struct message *) = 0;
+
+ /* Check that the SA is coherent with the IKE rules. */
+ if (exchange->type != ISAKMP_EXCH_TRANSACTION
+ && ((exchange->phase == 1 && exchange->type != ISAKMP_EXCH_ID_PROT
+ && exchange->type != ISAKMP_EXCH_AGGRESSIVE
+ && exchange->type != ISAKMP_EXCH_INFO)
+ || (exchange->phase == 2 && exchange->type != IKE_EXCH_QUICK_MODE
+ && exchange->type != ISAKMP_EXCH_INFO))) {
+ log_print("ipsec_initiator: unsupported exchange type %d in phase %d",
+ exchange->type, exchange->phase);
+ return -1;
+ }
+ switch (exchange->type) {
+ case ISAKMP_EXCH_ID_PROT:
+ script = ike_main_mode_initiator;
+ break;
#ifdef USE_AGGRESSIVE
- case ISAKMP_EXCH_AGGRESSIVE:
- script = ike_aggressive_initiator;
- break;
+ case ISAKMP_EXCH_AGGRESSIVE:
+ script = ike_aggressive_initiator;
+ break;
#endif
#ifdef USE_ISAKMP_CFG
- case ISAKMP_EXCH_TRANSACTION:
- script = isakmp_cfg_initiator;
- break;
+ case ISAKMP_EXCH_TRANSACTION:
+ script = isakmp_cfg_initiator;
+ break;
#endif
- case ISAKMP_EXCH_INFO:
- return message_send_info (msg);
- case IKE_EXCH_QUICK_MODE:
- script = ike_quick_mode_initiator;
- break;
- default:
- log_print ("ipsec_initiator: unsupported exchange type %d",
- exchange->type);
- return -1;
- }
-
- /* Run the script code for this step. */
- if (script)
- return script[exchange->step] (msg);
-
- return 0;
+ case ISAKMP_EXCH_INFO:
+ return message_send_info(msg);
+ case IKE_EXCH_QUICK_MODE:
+ script = ike_quick_mode_initiator;
+ break;
+ default:
+ log_print("ipsec_initiator: unsupported exchange type %d",
+ exchange->type);
+ return -1;
+ }
+
+ /* Run the script code for this step. */
+ if (script)
+ return script[exchange->step] (msg);
+
+ return 0;
}
/*
@@ -954,148 +945,138 @@ ipsec_initiator (struct message *msg)
* or 4-octet otherwise.
*/
static void
-ipsec_delete_spi_list (struct sockaddr *addr, u_int8_t proto,
- u_int8_t *spis, int nspis, char *type)
+ipsec_delete_spi_list(struct sockaddr * addr, u_int8_t proto,
+ u_int8_t * spis, int nspis, char *type)
{
- struct sa *sa;
- int i;
-
- for (i = 0; i < nspis; i++)
- {
- if (proto == ISAKMP_PROTO_ISAKMP)
- {
- u_int8_t *spi = spis + i * ISAKMP_HDR_COOKIES_LEN;
-
- /*
- * This really shouldn't happen in IPSEC DOI
- * code, but Cisco VPN 3000 sends ISAKMP DELETE's
- * this way.
- */
- sa = sa_lookup_isakmp_sa (addr, spi);
- }
- else
- {
- u_int32_t spi = ((u_int32_t *)spis)[i];
-
- sa = ipsec_sa_lookup (addr, spi, proto);
- }
-
- if (sa == NULL)
- {
- LOG_DBG ((LOG_SA, 30, "ipsec_delete_spi_list: "
- "could not locate SA (SPI %08x, proto %u)",
- ((u_int32_t *)spis)[i], proto));
- continue;
- }
+ struct sa *sa;
+ int i;
+
+ for (i = 0; i < nspis; i++) {
+ if (proto == ISAKMP_PROTO_ISAKMP) {
+ u_int8_t *spi = spis + i * ISAKMP_HDR_COOKIES_LEN;
+
+ /*
+ * This really shouldn't happen in IPSEC DOI
+ * code, but Cisco VPN 3000 sends ISAKMP DELETE's
+ * this way.
+ */
+ sa = sa_lookup_isakmp_sa(addr, spi);
+ } else {
+ u_int32_t spi = ((u_int32_t *) spis)[i];
+
+ sa = ipsec_sa_lookup(addr, spi, proto);
+ }
- /* Delete the SA and search for the next */
- LOG_DBG ((LOG_SA, 30, "ipsec_delete_spi_list: "
- "%s made us delete SA %p (%d references) for proto %d",
- type, sa, sa->refcnt, proto));
+ if (sa == NULL) {
+ LOG_DBG((LOG_SA, 30, "ipsec_delete_spi_list: "
+ "could not locate SA (SPI %08x, proto %u)",
+ ((u_int32_t *) spis)[i], proto));
+ continue;
+ }
+ /* Delete the SA and search for the next */
+ LOG_DBG((LOG_SA, 30, "ipsec_delete_spi_list: "
+ "%s made us delete SA %p (%d references) for proto %d",
+ type, sa, sa->refcnt, proto));
- sa_free (sa);
- }
+ sa_free(sa);
+ }
}
static int
-ipsec_responder (struct message *msg)
+ipsec_responder(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- int (**script) (struct message *) = 0;
- struct payload *p;
- u_int16_t type;
-
- /* Check that a new exchange is coherent with the IKE rules. */
- if (exchange->step == 0 && exchange->type != ISAKMP_EXCH_TRANSACTION
- && ((exchange->phase == 1 && exchange->type != ISAKMP_EXCH_ID_PROT
- && exchange->type != ISAKMP_EXCH_AGGRESSIVE
- && exchange->type != ISAKMP_EXCH_INFO)
- || (exchange->phase == 2 && exchange->type == ISAKMP_EXCH_ID_PROT)))
- {
- message_drop (msg, ISAKMP_NOTIFY_UNSUPPORTED_EXCHANGE_TYPE, 0, 1, 0);
- return -1;
- }
-
- LOG_DBG ((LOG_MISC, 30,
- "ipsec_responder: phase %d exchange %d step %d", exchange->phase,
- exchange->type, exchange->step));
- switch (exchange->type)
- {
- case ISAKMP_EXCH_ID_PROT:
- script = ike_main_mode_responder;
- break;
+ struct exchange *exchange = msg->exchange;
+ int (**script) (struct message *) = 0;
+ struct payload *p;
+ u_int16_t type;
+
+ /* Check that a new exchange is coherent with the IKE rules. */
+ if (exchange->step == 0 && exchange->type != ISAKMP_EXCH_TRANSACTION
+ && ((exchange->phase == 1 && exchange->type != ISAKMP_EXCH_ID_PROT
+ && exchange->type != ISAKMP_EXCH_AGGRESSIVE
+ && exchange->type != ISAKMP_EXCH_INFO)
+ || (exchange->phase == 2 && exchange->type == ISAKMP_EXCH_ID_PROT))) {
+ message_drop(msg, ISAKMP_NOTIFY_UNSUPPORTED_EXCHANGE_TYPE, 0, 1, 0);
+ return -1;
+ }
+ LOG_DBG((LOG_MISC, 30,
+ "ipsec_responder: phase %d exchange %d step %d", exchange->phase,
+ exchange->type, exchange->step));
+ switch (exchange->type) {
+ case ISAKMP_EXCH_ID_PROT:
+ script = ike_main_mode_responder;
+ break;
#ifdef USE_AGGRESSIVE
- case ISAKMP_EXCH_AGGRESSIVE:
- script = ike_aggressive_responder;
- break;
+ case ISAKMP_EXCH_AGGRESSIVE:
+ script = ike_aggressive_responder;
+ break;
#endif
#ifdef USE_ISAKMP_CFG
- case ISAKMP_EXCH_TRANSACTION:
- script = isakmp_cfg_responder;
- break;
+ case ISAKMP_EXCH_TRANSACTION:
+ script = isakmp_cfg_responder;
+ break;
#endif
- case ISAKMP_EXCH_INFO:
- for (p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p;
- p = TAILQ_NEXT (p, link))
- {
- type = GET_ISAKMP_NOTIFY_MSG_TYPE (p->p);
- LOG_DBG ((LOG_EXCHANGE, 10,
- "ipsec_responder: got NOTIFY of type %s",
- constant_name (isakmp_notify_cst, type)));
+ case ISAKMP_EXCH_INFO:
+ for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p;
+ p = TAILQ_NEXT(p, link)) {
+ type = GET_ISAKMP_NOTIFY_MSG_TYPE(p->p);
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "ipsec_responder: got NOTIFY of type %s",
+ constant_name(isakmp_notify_cst, type)));
- p->flags |= PL_MARK;
+ p->flags |= PL_MARK;
+ }
+
+ /*
+ * If any DELETEs are in here, let the logic of leftover payloads deal
+ * with them.
+ */
+
+ return 0;
+
+ case IKE_EXCH_QUICK_MODE:
+ script = ike_quick_mode_responder;
+ break;
+
+ default:
+ message_drop(msg, ISAKMP_NOTIFY_UNSUPPORTED_EXCHANGE_TYPE, 0, 1, 0);
+ return -1;
}
- /*
- * If any DELETEs are in here, let the logic of leftover payloads deal
- * with them.
- */
-
- return 0;
-
- case IKE_EXCH_QUICK_MODE:
- script = ike_quick_mode_responder;
- break;
-
- default:
- message_drop (msg, ISAKMP_NOTIFY_UNSUPPORTED_EXCHANGE_TYPE, 0, 1, 0);
- return -1;
- }
-
- /* Run the script code for this step. */
- if (script)
- return script[exchange->step] (msg);
-
- /*
- * XXX So far we don't accept any proposals for exchanges we don't support.
- */
- if (TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]))
- {
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- return -1;
- }
- return 0;
+ /* Run the script code for this step. */
+ if (script)
+ return script[exchange->step] (msg);
+
+ /*
+ * XXX So far we don't accept any proposals for exchanges we don't support.
+ */
+ if (TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])) {
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ return -1;
+ }
+ return 0;
}
-static enum hashes from_ike_hash (u_int16_t hash)
+static enum hashes
+from_ike_hash(u_int16_t hash)
{
- switch (hash)
- {
- case IKE_HASH_MD5:
- return HASH_MD5;
- case IKE_HASH_SHA:
- return HASH_SHA1;
- }
- return -1;
+ switch (hash) {
+ case IKE_HASH_MD5:
+ return HASH_MD5;
+ case IKE_HASH_SHA:
+ return HASH_SHA1;
+ }
+ return -1;
}
-static enum transform from_ike_crypto (u_int16_t crypto)
+static enum transform
+from_ike_crypto(u_int16_t crypto)
{
- /* Coincidentally this is the null operation :-) */
- return crypto;
+ /* Coincidentally this is the null operation :-) */
+ return crypto;
}
/*
@@ -1104,92 +1085,90 @@ static enum transform from_ike_crypto (u_int16_t crypto)
* VMSG is a pointer to the current message.
*/
int
-ipsec_is_attribute_incompatible (u_int16_t type, u_int8_t *value,
- u_int16_t len, void *vmsg)
+ipsec_is_attribute_incompatible(u_int16_t type, u_int8_t * value,
+ u_int16_t len, void *vmsg)
{
- struct message *msg = vmsg;
-
- if (msg->exchange->phase == 1)
- {
- switch (type)
- {
- case IKE_ATTR_ENCRYPTION_ALGORITHM:
- return !crypto_get (from_ike_crypto (decode_16 (value)));
- case IKE_ATTR_HASH_ALGORITHM:
- return !hash_get (from_ike_hash (decode_16 (value)));
- case IKE_ATTR_AUTHENTICATION_METHOD:
- return !ike_auth_get (decode_16 (value));
- case IKE_ATTR_GROUP_DESCRIPTION:
- return (decode_16 (value) < IKE_GROUP_DESC_MODP_768
- || decode_16 (value) > IKE_GROUP_DESC_MODP_1536)
- && (decode_16 (value) < IKE_GROUP_DESC_MODP_2048
- || decode_16 (value) > IKE_GROUP_DESC_MODP_8192);
- case IKE_ATTR_GROUP_TYPE:
- return 1;
- case IKE_ATTR_GROUP_PRIME:
- return 1;
- case IKE_ATTR_GROUP_GENERATOR_1:
- return 1;
- case IKE_ATTR_GROUP_GENERATOR_2:
- return 1;
- case IKE_ATTR_GROUP_CURVE_A:
- return 1;
- case IKE_ATTR_GROUP_CURVE_B:
- return 1;
- case IKE_ATTR_LIFE_TYPE:
- return decode_16 (value) < IKE_DURATION_SECONDS
- || decode_16 (value) > IKE_DURATION_KILOBYTES;
- case IKE_ATTR_LIFE_DURATION:
- return len != 2 && len != 4;
- case IKE_ATTR_PRF:
- return 1;
- case IKE_ATTR_KEY_LENGTH:
- /*
- * Our crypto routines only allows key-lengths which are multiples
- * of an octet.
- */
- return decode_16 (value) % 8 != 0;
- case IKE_ATTR_FIELD_SIZE:
- return 1;
- case IKE_ATTR_GROUP_ORDER:
- return 1;
- }
- }
- else
- {
- switch (type)
- {
- case IPSEC_ATTR_SA_LIFE_TYPE:
- return decode_16 (value) < IPSEC_DURATION_SECONDS
- || decode_16 (value) > IPSEC_DURATION_KILOBYTES;
- case IPSEC_ATTR_SA_LIFE_DURATION:
- return len != 2 && len != 4;
- case IPSEC_ATTR_GROUP_DESCRIPTION:
- return (decode_16 (value) < IKE_GROUP_DESC_MODP_768
- || decode_16 (value) > IKE_GROUP_DESC_MODP_1536)
- && (decode_16 (value) < IKE_GROUP_DESC_MODP_2048
- || IKE_GROUP_DESC_MODP_8192 < decode_16 (value));
- case IPSEC_ATTR_ENCAPSULATION_MODE:
- return decode_16 (value) < IPSEC_ENCAP_TUNNEL
- || decode_16 (value) > IPSEC_ENCAP_TRANSPORT;
- case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
- return decode_16 (value) < IPSEC_AUTH_HMAC_MD5
- || decode_16 (value) > IPSEC_AUTH_HMAC_RIPEMD;
- case IPSEC_ATTR_KEY_LENGTH:
- /* XXX Blowfish needs '0'. Others appear to disregard this attr? */
- return 0;
- case IPSEC_ATTR_KEY_ROUNDS:
- return 1;
- case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
- return 1;
- case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
- return 1;
- case IPSEC_ATTR_ECN_TUNNEL:
- return 1;
+ struct message *msg = vmsg;
+
+ if (msg->exchange->phase == 1) {
+ switch (type) {
+ case IKE_ATTR_ENCRYPTION_ALGORITHM:
+ return !crypto_get(from_ike_crypto(decode_16(value)));
+ case IKE_ATTR_HASH_ALGORITHM:
+ return !hash_get(from_ike_hash(decode_16(value)));
+ case IKE_ATTR_AUTHENTICATION_METHOD:
+ return !ike_auth_get(decode_16(value));
+ case IKE_ATTR_GROUP_DESCRIPTION:
+ return (decode_16(value) < IKE_GROUP_DESC_MODP_768
+ || decode_16(value) > IKE_GROUP_DESC_MODP_1536)
+ && (decode_16(value) < IKE_GROUP_DESC_MODP_2048
+ || decode_16(value) > IKE_GROUP_DESC_MODP_8192);
+ case IKE_ATTR_GROUP_TYPE:
+ return 1;
+ case IKE_ATTR_GROUP_PRIME:
+ return 1;
+ case IKE_ATTR_GROUP_GENERATOR_1:
+ return 1;
+ case IKE_ATTR_GROUP_GENERATOR_2:
+ return 1;
+ case IKE_ATTR_GROUP_CURVE_A:
+ return 1;
+ case IKE_ATTR_GROUP_CURVE_B:
+ return 1;
+ case IKE_ATTR_LIFE_TYPE:
+ return decode_16(value) < IKE_DURATION_SECONDS
+ || decode_16(value) > IKE_DURATION_KILOBYTES;
+ case IKE_ATTR_LIFE_DURATION:
+ return len != 2 && len != 4;
+ case IKE_ATTR_PRF:
+ return 1;
+ case IKE_ATTR_KEY_LENGTH:
+ /*
+ * Our crypto routines only allows key-lengths which are multiples
+ * of an octet.
+ */
+ return decode_16(value) % 8 != 0;
+ case IKE_ATTR_FIELD_SIZE:
+ return 1;
+ case IKE_ATTR_GROUP_ORDER:
+ return 1;
+ }
+ } else {
+ switch (type) {
+ case IPSEC_ATTR_SA_LIFE_TYPE:
+ return decode_16(value) < IPSEC_DURATION_SECONDS
+ || decode_16(value) > IPSEC_DURATION_KILOBYTES;
+ case IPSEC_ATTR_SA_LIFE_DURATION:
+ return len != 2 && len != 4;
+ case IPSEC_ATTR_GROUP_DESCRIPTION:
+ return (decode_16(value) < IKE_GROUP_DESC_MODP_768
+ || decode_16(value) > IKE_GROUP_DESC_MODP_1536)
+ && (decode_16(value) < IKE_GROUP_DESC_MODP_2048
+ || IKE_GROUP_DESC_MODP_8192 < decode_16(value));
+ case IPSEC_ATTR_ENCAPSULATION_MODE:
+ return decode_16(value) < IPSEC_ENCAP_TUNNEL
+ || decode_16(value) > IPSEC_ENCAP_TRANSPORT;
+ case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
+ return decode_16(value) < IPSEC_AUTH_HMAC_MD5
+ || decode_16(value) > IPSEC_AUTH_HMAC_RIPEMD;
+ case IPSEC_ATTR_KEY_LENGTH:
+ /*
+ * XXX Blowfish needs '0'. Others appear to disregard
+ * this attr?
+ */
+ return 0;
+ case IPSEC_ATTR_KEY_ROUNDS:
+ return 1;
+ case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
+ return 1;
+ case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
+ return 1;
+ case IPSEC_ATTR_ECN_TUNNEL:
+ return 1;
+ }
}
- }
- /* XXX Silence gcc. */
- return 1;
+ /* XXX Silence gcc. */
+ return 1;
}
#ifdef USE_DEBUG
@@ -1198,25 +1177,25 @@ ipsec_is_attribute_incompatible (u_int16_t type, u_int8_t *value,
* in human-readable form. VMSG is a pointer to the current message.
*/
int
-ipsec_debug_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vmsg)
+ipsec_debug_attribute(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *vmsg)
{
- struct message *msg = vmsg;
- char val[20];
-
- /* XXX Transient solution. */
- if (len == 2)
- snprintf (val, sizeof val, "%d", decode_16 (value));
- else if (len == 4)
- snprintf (val, sizeof val, "%d", decode_32 (value));
- else
- snprintf (val, sizeof val, "unrepresentable");
-
- LOG_DBG ((LOG_MESSAGE, 50, "Attribute %s value %s",
- constant_name (msg->exchange->phase == 1
- ? ike_attr_cst : ipsec_attr_cst, type),
- val));
- return 0;
+ struct message *msg = vmsg;
+ char val[20];
+
+ /* XXX Transient solution. */
+ if (len == 2)
+ snprintf(val, sizeof val, "%d", decode_16(value));
+ else if (len == 4)
+ snprintf(val, sizeof val, "%d", decode_32(value));
+ else
+ snprintf(val, sizeof val, "unrepresentable");
+
+ LOG_DBG((LOG_MESSAGE, 50, "Attribute %s value %s",
+ constant_name(msg->exchange->phase == 1
+ ? ike_attr_cst : ipsec_attr_cst, type),
+ val));
+ return 0;
}
#endif
@@ -1226,163 +1205,155 @@ ipsec_debug_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
* current message, SA and protocol.
*/
int
-ipsec_decode_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vida)
+ipsec_decode_attribute(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *vida)
{
- struct ipsec_decode_arg *ida = vida;
- struct message *msg = ida->msg;
- struct sa *sa = ida->sa;
- struct ipsec_sa *isa = sa->data;
- struct proto *proto = ida->proto;
- struct ipsec_proto *iproto = proto->data;
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- static int lifetype = 0;
-
- if (exchange->phase == 1)
- {
- switch (type)
- {
- case IKE_ATTR_ENCRYPTION_ALGORITHM:
- /* XXX Errors possible? */
- exchange->crypto = crypto_get (from_ike_crypto (decode_16 (value)));
- break;
- case IKE_ATTR_HASH_ALGORITHM:
- /* XXX Errors possible? */
- ie->hash = hash_get (from_ike_hash (decode_16 (value)));
- break;
- case IKE_ATTR_AUTHENTICATION_METHOD:
- /* XXX Errors possible? */
- ie->ike_auth = ike_auth_get (decode_16 (value));
- break;
- case IKE_ATTR_GROUP_DESCRIPTION:
- isa->group_desc = decode_16 (value);
- break;
- case IKE_ATTR_GROUP_TYPE:
- break;
- case IKE_ATTR_GROUP_PRIME:
- break;
- case IKE_ATTR_GROUP_GENERATOR_1:
- break;
- case IKE_ATTR_GROUP_GENERATOR_2:
- break;
- case IKE_ATTR_GROUP_CURVE_A:
- break;
- case IKE_ATTR_GROUP_CURVE_B:
- break;
- case IKE_ATTR_LIFE_TYPE:
- lifetype = decode_16 (value);
- return 0;
- case IKE_ATTR_LIFE_DURATION:
- switch (lifetype)
- {
- case IKE_DURATION_SECONDS:
- switch (len)
- {
- case 2:
- sa->seconds = decode_16 (value);
- break;
- case 4:
- sa->seconds = decode_32 (value);
- break;
- default:
- log_print ("ipsec_decode_attribute: unreasonable lifetime");
+ struct ipsec_decode_arg *ida = vida;
+ struct message *msg = ida->msg;
+ struct sa *sa = ida->sa;
+ struct ipsec_sa *isa = sa->data;
+ struct proto *proto = ida->proto;
+ struct ipsec_proto *iproto = proto->data;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ static int lifetype = 0;
+
+ if (exchange->phase == 1) {
+ switch (type) {
+ case IKE_ATTR_ENCRYPTION_ALGORITHM:
+ /* XXX Errors possible? */
+ exchange->crypto = crypto_get(from_ike_crypto(decode_16(value)));
+ break;
+ case IKE_ATTR_HASH_ALGORITHM:
+ /* XXX Errors possible? */
+ ie->hash = hash_get(from_ike_hash(decode_16(value)));
+ break;
+ case IKE_ATTR_AUTHENTICATION_METHOD:
+ /* XXX Errors possible? */
+ ie->ike_auth = ike_auth_get(decode_16(value));
+ break;
+ case IKE_ATTR_GROUP_DESCRIPTION:
+ isa->group_desc = decode_16(value);
+ break;
+ case IKE_ATTR_GROUP_TYPE:
+ break;
+ case IKE_ATTR_GROUP_PRIME:
+ break;
+ case IKE_ATTR_GROUP_GENERATOR_1:
+ break;
+ case IKE_ATTR_GROUP_GENERATOR_2:
+ break;
+ case IKE_ATTR_GROUP_CURVE_A:
+ break;
+ case IKE_ATTR_GROUP_CURVE_B:
+ break;
+ case IKE_ATTR_LIFE_TYPE:
+ lifetype = decode_16(value);
+ return 0;
+ case IKE_ATTR_LIFE_DURATION:
+ switch (lifetype) {
+ case IKE_DURATION_SECONDS:
+ switch (len) {
+ case 2:
+ sa->seconds = decode_16(value);
+ break;
+ case 4:
+ sa->seconds = decode_32(value);
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unreasonable lifetime");
+ }
+ break;
+ case IKE_DURATION_KILOBYTES:
+ switch (len) {
+ case 2:
+ sa->kilobytes = decode_16(value);
+ break;
+ case 4:
+ sa->kilobytes = decode_32(value);
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unreasonable lifetime");
+ }
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unknown lifetime type");
+ }
+ break;
+ case IKE_ATTR_PRF:
+ break;
+ case IKE_ATTR_KEY_LENGTH:
+ exchange->key_length = decode_16(value) / 8;
+ break;
+ case IKE_ATTR_FIELD_SIZE:
+ break;
+ case IKE_ATTR_GROUP_ORDER:
+ break;
}
- break;
- case IKE_DURATION_KILOBYTES:
- switch (len)
- {
- case 2:
- sa->kilobytes = decode_16 (value);
- break;
- case 4:
- sa->kilobytes = decode_32 (value);
- break;
- default:
- log_print ("ipsec_decode_attribute: unreasonable lifetime");
+ } else {
+ switch (type) {
+ case IPSEC_ATTR_SA_LIFE_TYPE:
+ lifetype = decode_16(value);
+ return 0;
+ case IPSEC_ATTR_SA_LIFE_DURATION:
+ switch (lifetype) {
+ case IPSEC_DURATION_SECONDS:
+ switch (len) {
+ case 2:
+ sa->seconds = decode_16(value);
+ break;
+ case 4:
+ sa->seconds = decode_32(value);
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unreasonable lifetime");
+ }
+ break;
+ case IPSEC_DURATION_KILOBYTES:
+ switch (len) {
+ case 2:
+ sa->kilobytes = decode_16(value);
+ break;
+ case 4:
+ sa->kilobytes = decode_32(value);
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unreasonable lifetime");
+ }
+ break;
+ default:
+ log_print("ipsec_decode_attribute: unknown lifetime type");
+ }
+ break;
+ case IPSEC_ATTR_GROUP_DESCRIPTION:
+ isa->group_desc = decode_16(value);
+ break;
+ case IPSEC_ATTR_ENCAPSULATION_MODE:
+ /*
+ * XXX Multiple protocols must have same
+ * encapsulation mode, no?
+ */
+ iproto->encap_mode = decode_16(value);
+ break;
+ case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
+ iproto->auth = decode_16(value);
+ break;
+ case IPSEC_ATTR_KEY_LENGTH:
+ iproto->keylen = decode_16(value);
+ break;
+ case IPSEC_ATTR_KEY_ROUNDS:
+ iproto->keyrounds = decode_16(value);
+ break;
+ case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
+ break;
+ case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
+ break;
+ case IPSEC_ATTR_ECN_TUNNEL:
+ break;
}
- break;
- default:
- log_print ("ipsec_decode_attribute: unknown lifetime type");
- }
- break;
- case IKE_ATTR_PRF:
- break;
- case IKE_ATTR_KEY_LENGTH:
- exchange->key_length = decode_16 (value) / 8;
- break;
- case IKE_ATTR_FIELD_SIZE:
- break;
- case IKE_ATTR_GROUP_ORDER:
- break;
}
- }
- else
- {
- switch (type)
- {
- case IPSEC_ATTR_SA_LIFE_TYPE:
- lifetype = decode_16 (value);
- return 0;
- case IPSEC_ATTR_SA_LIFE_DURATION:
- switch (lifetype)
- {
- case IPSEC_DURATION_SECONDS:
- switch (len)
- {
- case 2:
- sa->seconds = decode_16 (value);
- break;
- case 4:
- sa->seconds = decode_32 (value);
- break;
- default:
- log_print ("ipsec_decode_attribute: unreasonable lifetime");
- }
- break;
- case IPSEC_DURATION_KILOBYTES:
- switch (len)
- {
- case 2:
- sa->kilobytes = decode_16 (value);
- break;
- case 4:
- sa->kilobytes = decode_32 (value);
- break;
- default:
- log_print ("ipsec_decode_attribute: unreasonable lifetime");
- }
- break;
- default:
- log_print ("ipsec_decode_attribute: unknown lifetime type");
- }
- break;
- case IPSEC_ATTR_GROUP_DESCRIPTION:
- isa->group_desc = decode_16 (value);
- break;
- case IPSEC_ATTR_ENCAPSULATION_MODE:
- /* XXX Multiple protocols must have same encapsulation mode, no? */
- iproto->encap_mode = decode_16 (value);
- break;
- case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
- iproto->auth = decode_16 (value);
- break;
- case IPSEC_ATTR_KEY_LENGTH:
- iproto->keylen = decode_16 (value);
- break;
- case IPSEC_ATTR_KEY_ROUNDS:
- iproto->keyrounds = decode_16 (value);
- break;
- case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
- break;
- case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
- break;
- case IPSEC_ATTR_ECN_TUNNEL:
- break;
- }
- }
- lifetype = 0;
- return 0;
+ lifetype = 0;
+ return 0;
}
/*
@@ -1391,34 +1362,34 @@ ipsec_decode_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
* processed.
*/
void
-ipsec_decode_transform (struct message *msg, struct sa *sa,
- struct proto *proto, u_int8_t *buf)
+ipsec_decode_transform(struct message * msg, struct sa * sa,
+ struct proto * proto, u_int8_t * buf)
{
- struct ipsec_exch *ie = msg->exchange->data;
- struct ipsec_decode_arg ida;
-
- LOG_DBG ((LOG_MISC, 20, "ipsec_decode_transform: transform %d chosen",
- GET_ISAKMP_TRANSFORM_NO (buf)));
-
- ida.msg = msg;
- ida.sa = sa;
- ida.proto = proto;
-
- /* The default IKE lifetime is 8 hours. */
- if (sa->phase == 1)
- sa->seconds = 28800;
-
- /* Extract the attributes and stuff them into the SA. */
- attribute_map (buf + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (buf) - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- ipsec_decode_attribute, &ida);
-
- /*
- * If no pseudo-random function was negotiated, it's HMAC.
- * XXX As PRF_HMAC currently is zero, this is a no-op.
- */
- if (!ie->prf_type)
- ie->prf_type = PRF_HMAC;
+ struct ipsec_exch *ie = msg->exchange->data;
+ struct ipsec_decode_arg ida;
+
+ LOG_DBG((LOG_MISC, 20, "ipsec_decode_transform: transform %d chosen",
+ GET_ISAKMP_TRANSFORM_NO(buf)));
+
+ ida.msg = msg;
+ ida.sa = sa;
+ ida.proto = proto;
+
+ /* The default IKE lifetime is 8 hours. */
+ if (sa->phase == 1)
+ sa->seconds = 28800;
+
+ /* Extract the attributes and stuff them into the SA. */
+ attribute_map(buf + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(buf) - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ ipsec_decode_attribute, &ida);
+
+ /*
+ * If no pseudo-random function was negotiated, it's HMAC.
+ * XXX As PRF_HMAC currently is zero, this is a no-op.
+ */
+ if (!ie->prf_type)
+ ie->prf_type = PRF_HMAC;
}
/*
@@ -1426,12 +1397,12 @@ ipsec_decode_transform (struct message *msg, struct sa *sa,
* of the IKE security association SA.
*/
static void
-ipsec_delete_spi (struct sa *sa, struct proto *proto, int incoming)
+ipsec_delete_spi(struct sa * sa, struct proto * proto, int incoming)
{
- if (sa->phase == 1)
- return;
- /* XXX Error handling? Is it interesting? */
- sysdep_ipsec_delete_spi (sa, proto, incoming);
+ if (sa->phase == 1)
+ return;
+ /* XXX Error handling? Is it interesting? */
+ sysdep_ipsec_delete_spi(sa, proto, incoming);
}
/*
@@ -1439,80 +1410,72 @@ ipsec_delete_spi (struct sa *sa, struct proto *proto, int incoming)
* PEER is non-zero when the value is our peer's, and zero when it is ours.
*/
static int
-ipsec_g_x (struct message *msg, int peer, u_int8_t *buf)
+ipsec_g_x(struct message * msg, int peer, u_int8_t * buf)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t **g_x;
- int initiator = exchange->initiator ^ peer;
- char header[32];
-
- g_x = initiator ? &ie->g_xi : &ie->g_xr;
- *g_x = malloc (ie->g_x_len);
- if (!*g_x)
- {
- log_error ("ipsec_g_x: malloc (%lu) failed", (unsigned long)ie->g_x_len);
- return -1;
- }
- memcpy (*g_x, buf, ie->g_x_len);
- snprintf (header, sizeof header, "ipsec_g_x: g^x%c", initiator ? 'i' : 'r');
- LOG_DBG_BUF ((LOG_MISC, 80, header, *g_x, ie->g_x_len));
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t **g_x;
+ int initiator = exchange->initiator ^ peer;
+ char header[32];
+
+ g_x = initiator ? &ie->g_xi : &ie->g_xr;
+ *g_x = malloc(ie->g_x_len);
+ if (!*g_x) {
+ log_error("ipsec_g_x: malloc (%lu) failed", (unsigned long) ie->g_x_len);
+ return -1;
+ }
+ memcpy(*g_x, buf, ie->g_x_len);
+ snprintf(header, sizeof header, "ipsec_g_x: g^x%c", initiator ? 'i' : 'r');
+ LOG_DBG_BUF((LOG_MISC, 80, header, *g_x, ie->g_x_len));
+ return 0;
}
/* Generate our DH value. */
int
-ipsec_gen_g_x (struct message *msg)
+ipsec_gen_g_x(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- u_int8_t *buf;
-
- buf = malloc (ISAKMP_KE_SZ + ie->g_x_len);
- if (!buf)
- {
- log_error ("ipsec_gen_g_x: malloc (%lu) failed",
- ISAKMP_KE_SZ + (unsigned long)ie->g_x_len);
- return -1;
- }
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_KEY_EXCH, buf,
- ISAKMP_KE_SZ + ie->g_x_len, 1))
- {
- free (buf);
- return -1;
- }
-
- if (dh_create_exchange (ie->group, buf + ISAKMP_KE_DATA_OFF))
- {
- log_print ("ipsec_gen_g_x: dh_create_exchange failed");
- free (buf);
- return -1;
- }
- return ipsec_g_x (msg, 0, buf + ISAKMP_KE_DATA_OFF);
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ u_int8_t *buf;
+
+ buf = malloc(ISAKMP_KE_SZ + ie->g_x_len);
+ if (!buf) {
+ log_error("ipsec_gen_g_x: malloc (%lu) failed",
+ ISAKMP_KE_SZ + (unsigned long) ie->g_x_len);
+ return -1;
+ }
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_KEY_EXCH, buf,
+ ISAKMP_KE_SZ + ie->g_x_len, 1)) {
+ free(buf);
+ return -1;
+ }
+ if (dh_create_exchange(ie->group, buf + ISAKMP_KE_DATA_OFF)) {
+ log_print("ipsec_gen_g_x: dh_create_exchange failed");
+ free(buf);
+ return -1;
+ }
+ return ipsec_g_x(msg, 0, buf + ISAKMP_KE_DATA_OFF);
}
/* Save the peer's DH value. */
int
-ipsec_save_g_x (struct message *msg)
+ipsec_save_g_x(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
- struct payload *kep;
-
- kep = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
- kep->flags |= PL_MARK;
- ie->g_x_len = GET_ISAKMP_GEN_LENGTH (kep->p) - ISAKMP_KE_DATA_OFF;
-
- /* Check that the given length matches the group's expectancy. */
- if (ie->g_x_len != (size_t)dh_getlen (ie->group))
- {
- /* XXX Is this a good notify type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- return ipsec_g_x (msg, 1, kep->p + ISAKMP_KE_DATA_OFF);
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_exch *ie = exchange->data;
+ struct payload *kep;
+
+ kep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]);
+ kep->flags |= PL_MARK;
+ ie->g_x_len = GET_ISAKMP_GEN_LENGTH(kep->p) - ISAKMP_KE_DATA_OFF;
+
+ /* Check that the given length matches the group's expectancy. */
+ if (ie->g_x_len != (size_t) dh_getlen(ie->group)) {
+ /* XXX Is this a good notify type? */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ return ipsec_g_x(msg, 1, kep->p + ISAKMP_KE_DATA_OFF);
}
/*
@@ -1520,24 +1483,21 @@ ipsec_save_g_x (struct message *msg)
* size where SZ points. NB! A zero return is OK if *SZ is zero.
*/
static u_int8_t *
-ipsec_get_spi (size_t *sz, u_int8_t proto, struct message *msg)
+ipsec_get_spi(size_t * sz, u_int8_t proto, struct message * msg)
{
- struct sockaddr *dst, *src;
- struct transport *transport = msg->transport;
-
- if (msg->exchange->phase == 1)
- {
- *sz = 0;
- return 0;
- }
- else
- {
- /* We are the destination in the SA we want a SPI for. */
- transport->vtbl->get_src (transport, &dst);
- /* The peer is the source. */
- transport->vtbl->get_dst (transport, &src);
- return sysdep_ipsec_get_spi (sz, proto, src, dst, msg->exchange->seq);
- }
+ struct sockaddr *dst, *src;
+ struct transport *transport = msg->transport;
+
+ if (msg->exchange->phase == 1) {
+ *sz = 0;
+ return 0;
+ } else {
+ /* We are the destination in the SA we want a SPI for. */
+ transport->vtbl->get_src(transport, &dst);
+ /* The peer is the source. */
+ transport->vtbl->get_dst(transport, &src);
+ return sysdep_ipsec_get_spi(sz, proto, src, dst, msg->exchange->seq);
+ }
}
/*
@@ -1547,215 +1507,196 @@ ipsec_get_spi (size_t *sz, u_int8_t proto, struct message *msg)
* 0.
*/
int
-ipsec_handle_leftover_payload (struct message *msg, u_int8_t type,
- struct payload *payload)
+ipsec_handle_leftover_payload(struct message * msg, u_int8_t type,
+ struct payload * payload)
{
- u_int32_t spisz, nspis;
- struct sockaddr *dst;
- int reenter = 0;
- u_int8_t *spis, proto;
- struct sa *sa;
-
- switch (type)
- {
- case ISAKMP_PAYLOAD_DELETE:
- proto = GET_ISAKMP_DELETE_PROTO (payload->p);
- nspis = GET_ISAKMP_DELETE_NSPIS (payload->p);
- spisz = GET_ISAKMP_DELETE_SPI_SZ (payload->p);
-
- if (nspis == 0)
- {
- LOG_DBG ((LOG_SA, 60, "ipsec_handle_leftover_payload: message "
- "specified zero SPIs, ignoring"));
- return -1;
- }
-
- /* verify proper SPI size */
- if ((proto == ISAKMP_PROTO_ISAKMP && spisz != ISAKMP_HDR_COOKIES_LEN)
- || (proto != ISAKMP_PROTO_ISAKMP && spisz != sizeof (u_int32_t)))
- {
- log_print ("ipsec_handle_leftover_payload: "
- "invalid SPI size %d for proto %d in DELETE payload",
- spisz, proto);
- return -1;
- }
-
- spis = (u_int8_t *)malloc (nspis * spisz);
- if (!spis)
- {
- log_error ("ipsec_handle_leftover_payload: malloc (%d) failed",
- nspis * spisz);
- return -1;
- }
-
- /* extract SPI and get dst address */
- memcpy (spis, payload->p + ISAKMP_DELETE_SPI_OFF, nspis * spisz);
- msg->transport->vtbl->get_dst (msg->transport, &dst);
-
- ipsec_delete_spi_list (dst, proto, spis, nspis, "DELETE");
-
- free (spis);
- payload->flags |= PL_MARK;
- return 0;
-
- case ISAKMP_PAYLOAD_NOTIFY:
- switch (GET_ISAKMP_NOTIFY_MSG_TYPE (payload->p))
- {
- case IPSEC_NOTIFY_INITIAL_CONTACT:
- /*
- * Permit INITIAL-CONTACT if
- * - this is not an AGGRESSIVE mode exchange
- * - it is protected by an ISAKMP SA
- *
- * XXX Instead of the first condition above, we could permit this
- * XXX only for phase 2. In the last packet of main-mode, this
- * XXX payload, while encrypted, is not part of the hash digest.
- * XXX As we currently send our own INITIAL-CONTACTs at this point,
- * XXX this too would need to be changed.
- */
- if (msg->exchange->type == ISAKMP_EXCH_AGGRESSIVE)
- {
- log_print ("ipsec_handle_leftover_payload: got INITIAL-CONTACT "
- "in AGGRESSIVE mode");
- return -1;
- }
-
- if ((msg->exchange->flags & EXCHANGE_FLAG_ENCRYPT) == 0)
- {
- log_print ("ipsec_handle_leftover_payload: got INITIAL-CONTACT "
- "without ISAKMP SA");
- return -1;
- }
-
- /*
- * Find out who is sending this and then delete every SA that is
- * ready. Exchanges will timeout themselves and then the
- * non-ready SAs will disappear too.
- */
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- while ((sa = sa_lookup_by_peer (dst, sysdep_sa_len (dst))) != 0)
- {
- /*
- * Don't delete the current SA -- we received the notification
- * over it, so it's obviously still active. We temporarily need
- * to remove the SA from the list to avoid an endless loop,
- * but keep a reference so it won't disappear meanwhile.
- */
- if (sa == msg->isakmp_sa)
- {
- sa_reference (sa);
- sa_remove (sa);
- reenter = 1;
- continue;
+ u_int32_t spisz, nspis;
+ struct sockaddr *dst;
+ int reenter = 0;
+ u_int8_t *spis, proto;
+ struct sa *sa;
+
+ switch (type) {
+ case ISAKMP_PAYLOAD_DELETE:
+ proto = GET_ISAKMP_DELETE_PROTO(payload->p);
+ nspis = GET_ISAKMP_DELETE_NSPIS(payload->p);
+ spisz = GET_ISAKMP_DELETE_SPI_SZ(payload->p);
+
+ if (nspis == 0) {
+ LOG_DBG((LOG_SA, 60, "ipsec_handle_leftover_payload: message "
+ "specified zero SPIs, ignoring"));
+ return -1;
+ }
+ /* verify proper SPI size */
+ if ((proto == ISAKMP_PROTO_ISAKMP && spisz != ISAKMP_HDR_COOKIES_LEN)
+ || (proto != ISAKMP_PROTO_ISAKMP && spisz != sizeof(u_int32_t))) {
+ log_print("ipsec_handle_leftover_payload: "
+ "invalid SPI size %d for proto %d in DELETE payload",
+ spisz, proto);
+ return -1;
+ }
+ spis = (u_int8_t *) malloc(nspis * spisz);
+ if (!spis) {
+ log_error("ipsec_handle_leftover_payload: malloc (%d) failed",
+ nspis * spisz);
+ return -1;
+ }
+ /* extract SPI and get dst address */
+ memcpy(spis, payload->p + ISAKMP_DELETE_SPI_OFF, nspis * spisz);
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+
+ ipsec_delete_spi_list(dst, proto, spis, nspis, "DELETE");
+
+ free(spis);
+ payload->flags |= PL_MARK;
+ return 0;
+
+ case ISAKMP_PAYLOAD_NOTIFY:
+ switch (GET_ISAKMP_NOTIFY_MSG_TYPE(payload->p)) {
+ case IPSEC_NOTIFY_INITIAL_CONTACT:
+ /*
+ * Permit INITIAL-CONTACT if
+ * - this is not an AGGRESSIVE mode exchange
+ * - it is protected by an ISAKMP SA
+ *
+ * XXX Instead of the first condition above, we could permit this
+ * XXX only for phase 2. In the last packet of main-mode, this
+ * XXX payload, while encrypted, is not part of the hash digest.
+ * XXX As we currently send our own INITIAL-CONTACTs at this point,
+ * XXX this too would need to be changed.
+ */
+ if (msg->exchange->type == ISAKMP_EXCH_AGGRESSIVE) {
+ log_print("ipsec_handle_leftover_payload: got INITIAL-CONTACT "
+ "in AGGRESSIVE mode");
+ return -1;
+ }
+ if ((msg->exchange->flags & EXCHANGE_FLAG_ENCRYPT) == 0) {
+ log_print("ipsec_handle_leftover_payload: got INITIAL-CONTACT "
+ "without ISAKMP SA");
+ return -1;
+ }
+ /*
+ * Find out who is sending this and then delete every SA that is
+ * ready. Exchanges will timeout themselves and then the
+ * non-ready SAs will disappear too.
+ */
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ while ((sa = sa_lookup_by_peer(dst, sysdep_sa_len(dst))) != 0) {
+ /*
+ * Don't delete the current SA -- we received the
+ * notification over it, so it's obviously still
+ * active. We temporarily need to remove the SA
+ * from the list to avoid an endless loop, but
+ * keep a reference so it won't disappear meanwhile.
+ */
+ if (sa == msg->isakmp_sa) {
+ sa_reference(sa);
+ sa_remove(sa);
+ reenter = 1;
+ continue;
+ }
+ LOG_DBG((LOG_SA, 30,
+ "ipsec_handle_leftover_payload: "
+ "INITIAL-CONTACT made us delete SA %p",
+ sa));
+ sa_delete(sa, 0);
+ }
+
+ if (reenter) {
+ sa_enter(msg->isakmp_sa);
+ sa_release(msg->isakmp_sa);
+ }
+ payload->flags |= PL_MARK;
+ return 0;
}
-
- LOG_DBG ((LOG_SA, 30,
- "ipsec_handle_leftover_payload: "
- "INITIAL-CONTACT made us delete SA %p",
- sa));
- sa_delete (sa, 0);
- }
-
- if (reenter)
- {
- sa_enter (msg->isakmp_sa);
- sa_release (msg->isakmp_sa);
- }
- payload->flags |= PL_MARK;
- return 0;
}
- }
- return -1;
+ return -1;
}
/* Return the encryption keylength in octets of the ESP protocol PROTO. */
int
-ipsec_esp_enckeylength (struct proto *proto)
+ipsec_esp_enckeylength(struct proto * proto)
{
- struct ipsec_proto *iproto = proto->data;
-
- /* Compute the keylength to use. */
- switch (proto->id)
- {
- case IPSEC_ESP_DES:
- case IPSEC_ESP_DES_IV32:
- case IPSEC_ESP_DES_IV64:
- return 8;
- case IPSEC_ESP_3DES:
- return 24;
- case IPSEC_ESP_CAST:
- if (!iproto->keylen)
- return 16;
- return iproto->keylen / 8;
- case IPSEC_ESP_AES:
- case IPSEC_ESP_AES_128_CTR:
- if (!iproto->keylen)
- return 16;
- /* Fallthrough */
- default:
- return iproto->keylen / 8;
- }
+ struct ipsec_proto *iproto = proto->data;
+
+ /* Compute the keylength to use. */
+ switch (proto->id) {
+ case IPSEC_ESP_DES:
+ case IPSEC_ESP_DES_IV32:
+ case IPSEC_ESP_DES_IV64:
+ return 8;
+ case IPSEC_ESP_3DES:
+ return 24;
+ case IPSEC_ESP_CAST:
+ if (!iproto->keylen)
+ return 16;
+ return iproto->keylen / 8;
+ case IPSEC_ESP_AES:
+ case IPSEC_ESP_AES_128_CTR:
+ if (!iproto->keylen)
+ return 16;
+ /* Fallthrough */
+ default:
+ return iproto->keylen / 8;
+ }
}
/* Return the authentication keylength in octets of the ESP protocol PROTO. */
int
-ipsec_esp_authkeylength (struct proto *proto)
+ipsec_esp_authkeylength(struct proto * proto)
{
- struct ipsec_proto *iproto = proto->data;
-
- switch (iproto->auth)
- {
- case IPSEC_AUTH_HMAC_MD5:
- return 16;
- case IPSEC_AUTH_HMAC_SHA:
- case IPSEC_AUTH_HMAC_RIPEMD:
- return 20;
- case IPSEC_AUTH_HMAC_SHA2_256:
- return 32;
- case IPSEC_AUTH_HMAC_SHA2_384:
- return 48;
- case IPSEC_AUTH_HMAC_SHA2_512:
- return 64;
- default:
- return 0;
- }
+ struct ipsec_proto *iproto = proto->data;
+
+ switch (iproto->auth) {
+ case IPSEC_AUTH_HMAC_MD5:
+ return 16;
+ case IPSEC_AUTH_HMAC_SHA:
+ case IPSEC_AUTH_HMAC_RIPEMD:
+ return 20;
+ case IPSEC_AUTH_HMAC_SHA2_256:
+ return 32;
+ case IPSEC_AUTH_HMAC_SHA2_384:
+ return 48;
+ case IPSEC_AUTH_HMAC_SHA2_512:
+ return 64;
+ default:
+ return 0;
+ }
}
/* Return the authentication keylength in octets of the AH protocol PROTO. */
int
-ipsec_ah_keylength (struct proto *proto)
+ipsec_ah_keylength(struct proto * proto)
{
- switch (proto->id)
- {
- case IPSEC_AH_MD5:
- return 16;
- case IPSEC_AH_SHA:
- case IPSEC_AH_RIPEMD:
- return 20;
- case IPSEC_AH_SHA2_256:
- return 32;
- case IPSEC_AH_SHA2_384:
- return 48;
- case IPSEC_AH_SHA2_512:
- return 64;
- default:
- return -1;
- }
+ switch (proto->id) {
+ case IPSEC_AH_MD5:
+ return 16;
+ case IPSEC_AH_SHA:
+ case IPSEC_AH_RIPEMD:
+ return 20;
+ case IPSEC_AH_SHA2_256:
+ return 32;
+ case IPSEC_AH_SHA2_384:
+ return 48;
+ case IPSEC_AH_SHA2_512:
+ return 64;
+ default:
+ return -1;
+ }
}
/* Return the total keymaterial length of the protocol PROTO. */
int
-ipsec_keymat_length (struct proto *proto)
+ipsec_keymat_length(struct proto * proto)
{
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- return ipsec_esp_enckeylength (proto) + ipsec_esp_authkeylength (proto);
- case IPSEC_PROTO_IPSEC_AH:
- return ipsec_ah_keylength (proto);
- default:
- return -1;
- }
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ return ipsec_esp_enckeylength(proto) + ipsec_esp_authkeylength(proto);
+ case IPSEC_PROTO_IPSEC_AH:
+ return ipsec_ah_keylength(proto);
+ default:
+ return -1;
+ }
}
/*
@@ -1765,112 +1706,97 @@ ipsec_keymat_length (struct proto *proto)
* Return 0 on success and -1 on failure.
*/
int
-ipsec_get_id (char *section, int *id, struct sockaddr **addr,
- struct sockaddr **mask, u_int8_t *tproto, u_int16_t *port)
+ipsec_get_id(char *section, int *id, struct sockaddr ** addr,
+ struct sockaddr ** mask, u_int8_t * tproto, u_int16_t * port)
{
- char *type, *address, *netmask;
-
- type = conf_get_str (section, "ID-type");
- if (!type)
- {
- log_print ("ipsec_get_id: section %s has no \"ID-type\" tag", section);
- return -1;
- }
-
- *id = constant_value (ipsec_id_cst, type);
- switch (*id)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- address = conf_get_str (section, "Address");
- if (!address)
- {
- log_print ("ipsec_get_id: section %s has no \"Address\" tag",
- section);
- return -1;
- }
+ char *type, *address, *netmask;
- if (text2sockaddr (address, NULL, addr))
- {
- log_print ("ipsec_get_id: invalid address %s in section %s", address,
- section);
- return -1;
+ type = conf_get_str(section, "ID-type");
+ if (!type) {
+ log_print("ipsec_get_id: section %s has no \"ID-type\" tag", section);
+ return -1;
}
-
- *tproto = conf_get_num (section, "Protocol", 0);
- if (*tproto)
- *port = conf_get_num (section, "Port", 0);
- break;
+ *id = constant_value(ipsec_id_cst, type);
+ switch (*id) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ address = conf_get_str(section, "Address");
+ if (!address) {
+ log_print("ipsec_get_id: section %s has no \"Address\" tag",
+ section);
+ return -1;
+ }
+ if (text2sockaddr(address, NULL, addr)) {
+ log_print("ipsec_get_id: invalid address %s in section %s", address,
+ section);
+ return -1;
+ }
+ *tproto = conf_get_num(section, "Protocol", 0);
+ if (*tproto)
+ *port = conf_get_num(section, "Port", 0);
+ break;
#ifdef notyet
- case IPSEC_ID_FQDN:
- return -1;
+ case IPSEC_ID_FQDN:
+ return -1;
- case IPSEC_ID_USER_FQDN:
- return -1;
+ case IPSEC_ID_USER_FQDN:
+ return -1;
#endif
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- address = conf_get_str (section, "Network");
- if (!address)
- {
- log_print ("ipsec_get_id: section %s has no \"Network\" tag",
- section);
- return -1;
- }
-
- if (text2sockaddr (address, NULL, addr))
- {
- log_print ("ipsec_get_id: invalid section %s network %s", section,
- address);
- return -1;
- }
-
- netmask = conf_get_str (section, "Netmask");
- if (!netmask)
- {
- log_print ("ipsec_get_id: section %s has no \"Netmask\" tag",
- section);
- return -1;
- }
-
- if (text2sockaddr (netmask, NULL, mask))
- {
- log_print ("ipsec_id_build: invalid section %s network %s", section,
- netmask);
- return -1;
- }
-
- *tproto = conf_get_num (section, "Protocol", 0);
- if (*tproto)
- *port = conf_get_num (section, "Port", 0);
- break;
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ address = conf_get_str(section, "Network");
+ if (!address) {
+ log_print("ipsec_get_id: section %s has no \"Network\" tag",
+ section);
+ return -1;
+ }
+ if (text2sockaddr(address, NULL, addr)) {
+ log_print("ipsec_get_id: invalid section %s network %s", section,
+ address);
+ return -1;
+ }
+ netmask = conf_get_str(section, "Netmask");
+ if (!netmask) {
+ log_print("ipsec_get_id: section %s has no \"Netmask\" tag",
+ section);
+ return -1;
+ }
+ if (text2sockaddr(netmask, NULL, mask)) {
+ log_print("ipsec_id_build: invalid section %s network %s", section,
+ netmask);
+ return -1;
+ }
+ *tproto = conf_get_num(section, "Protocol", 0);
+ if (*tproto)
+ *port = conf_get_num(section, "Port", 0);
+ break;
#ifdef notyet
- case IPSEC_ID_IPV4_RANGE:
- return -1;
+ case IPSEC_ID_IPV4_RANGE:
+ return -1;
- case IPSEC_ID_IPV6_RANGE:
- return -1;
+ case IPSEC_ID_IPV6_RANGE:
+ return -1;
- case IPSEC_ID_DER_ASN1_DN:
- return -1;
+ case IPSEC_ID_DER_ASN1_DN:
+ return -1;
- case IPSEC_ID_DER_ASN1_GN:
- return -1;
+ case IPSEC_ID_DER_ASN1_GN:
+ return -1;
- case IPSEC_ID_KEY_ID:
- return -1;
+ case IPSEC_ID_KEY_ID:
+ return -1;
#endif
- default:
- log_print ("ipsec_get_id: unknown ID type \"%s\" in section %s", type,
- section);
- return -1;
- }
+ default:
+ log_print("ipsec_get_id: unknown ID type \"%s\" in section %s", type,
+ section);
+ return -1;
+ }
- return 0;
+ return 0;
}
/*
@@ -1878,102 +1804,99 @@ ipsec_get_id (char *section, int *id, struct sockaddr **addr,
* we cannot fit the information in the supplied buffer.
*/
static void
-ipsec_decode_id (char *buf, size_t size, u_int8_t *id, size_t id_len,
- int isakmpform)
+ipsec_decode_id(char *buf, size_t size, u_int8_t * id, size_t id_len,
+ int isakmpform)
{
- int id_type;
- char *addr = 0, *mask = 0;
- u_int32_t *idp;
-
- if (id)
- {
- if (!isakmpform)
- {
- /* Exchanges and SAs dont carry the IDs in ISAKMP form. */
- id -= ISAKMP_GEN_SZ;
- id_len += ISAKMP_GEN_SZ;
- }
-
- id_type = GET_ISAKMP_ID_TYPE (id);
- idp = (u_int32_t *)(id + ISAKMP_ID_DATA_OFF);
- switch (id_type)
- {
- case IPSEC_ID_IPV4_ADDR:
- util_ntoa (&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
- snprintf (buf, size, "%08x: %s",
- decode_32 (id + ISAKMP_ID_DATA_OFF), addr);
- break;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- util_ntoa (&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
- util_ntoa (&mask, AF_INET, id + ISAKMP_ID_DATA_OFF + 4);
- snprintf (buf, size, "%08x/%08x: %s/%s",
- decode_32 (id + ISAKMP_ID_DATA_OFF),
- decode_32 (id + ISAKMP_ID_DATA_OFF + 4), addr, mask);
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- util_ntoa (&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
- snprintf (buf, size, "%08x%08x%08x%08x: %s", *idp, *(idp + 1),
- *(idp + 2), *(idp + 3), addr);
- break;
-
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- util_ntoa (&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
- util_ntoa (&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF +
- sizeof (struct in6_addr));
- snprintf (buf, size, "%08x%08x%08x%08x/%08x%08x%08x%08x: %s/%s",
- *idp, *(idp + 1), *(idp + 2), *(idp + 3), *(idp + 4),
- *(idp + 5), *(idp + 6), *(idp + 7), addr, mask);
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- /* String is not NUL terminated, be careful */
- id_len -= ISAKMP_ID_DATA_OFF;
- id_len = MIN (id_len, size - 1);
- memcpy (buf, id + ISAKMP_ID_DATA_OFF, id_len);
- buf[id_len] = '\0';
- break;
+ int id_type;
+ char *addr = 0, *mask = 0;
+ u_int32_t *idp;
+
+ if (id) {
+ if (!isakmpform) {
+ /*
+ * Exchanges and SAs dont carry the IDs in ISAKMP
+ * form.
+ */
+ id -= ISAKMP_GEN_SZ;
+ id_len += ISAKMP_GEN_SZ;
+ }
+ id_type = GET_ISAKMP_ID_TYPE(id);
+ idp = (u_int32_t *) (id + ISAKMP_ID_DATA_OFF);
+ switch (id_type) {
+ case IPSEC_ID_IPV4_ADDR:
+ util_ntoa(&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
+ snprintf(buf, size, "%08x: %s",
+ decode_32(id + ISAKMP_ID_DATA_OFF), addr);
+ break;
+
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ util_ntoa(&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
+ util_ntoa(&mask, AF_INET, id + ISAKMP_ID_DATA_OFF + 4);
+ snprintf(buf, size, "%08x/%08x: %s/%s",
+ decode_32(id + ISAKMP_ID_DATA_OFF),
+ decode_32(id + ISAKMP_ID_DATA_OFF + 4), addr, mask);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa(&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
+ snprintf(buf, size, "%08x%08x%08x%08x: %s", *idp, *(idp + 1),
+ *(idp + 2), *(idp + 3), addr);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ util_ntoa(&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
+ util_ntoa(&addr, AF_INET6, id + ISAKMP_ID_DATA_OFF +
+ sizeof(struct in6_addr));
+ snprintf(buf, size, "%08x%08x%08x%08x/%08x%08x%08x%08x: %s/%s",
+ *idp, *(idp + 1), *(idp + 2), *(idp + 3), *(idp + 4),
+ *(idp + 5), *(idp + 6), *(idp + 7), addr, mask);
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ /* String is not NUL terminated, be careful */
+ id_len -= ISAKMP_ID_DATA_OFF;
+ id_len = MIN(id_len, size - 1);
+ memcpy(buf, id + ISAKMP_ID_DATA_OFF, id_len);
+ buf[id_len] = '\0';
+ break;
#ifdef USE_X509
- case IPSEC_ID_DER_ASN1_DN:
- addr = x509_DN_string (id + ISAKMP_ID_DATA_OFF,
- id_len - ISAKMP_ID_DATA_OFF);
- if (!addr)
- {
- snprintf (buf, size, "unparsable ASN1 DN ID");
- return;
- }
- strlcpy (buf, addr, size);
- break;
+ case IPSEC_ID_DER_ASN1_DN:
+ addr = x509_DN_string(id + ISAKMP_ID_DATA_OFF,
+ id_len - ISAKMP_ID_DATA_OFF);
+ if (!addr) {
+ snprintf(buf, size, "unparsable ASN1 DN ID");
+ return;
+ }
+ strlcpy(buf, addr, size);
+ break;
#endif
- default:
- snprintf (buf, size, "<id type unknown: %x>", id_type);
- break;
- }
- }
- else
- snprintf (buf, size, "<no ipsec id>");
- if (addr)
- free (addr);
- if (mask)
- free (mask);
+ default:
+ snprintf(buf, size, "<id type unknown: %x>", id_type);
+ break;
+ }
+ } else
+ snprintf(buf, size, "<no ipsec id>");
+ if (addr)
+ free(addr);
+ if (mask)
+ free(mask);
}
-char *
-ipsec_decode_ids (char *fmt, u_int8_t *id1, size_t id1_len,
- u_int8_t *id2, size_t id2_len, int isakmpform)
+char *
+ipsec_decode_ids(char *fmt, u_int8_t * id1, size_t id1_len,
+ u_int8_t * id2, size_t id2_len, int isakmpform)
{
- static char result[1024];
- char s_id1[256], s_id2[256];
+ static char result[1024];
+ char s_id1[256], s_id2[256];
- ipsec_decode_id (s_id1, sizeof s_id1, id1, id1_len, isakmpform);
- ipsec_decode_id (s_id2, sizeof s_id2, id2, id2_len, isakmpform);
+ ipsec_decode_id(s_id1, sizeof s_id1, id1, id1_len, isakmpform);
+ ipsec_decode_id(s_id2, sizeof s_id2, id2, id2_len, isakmpform);
- snprintf (result, sizeof result, fmt, s_id1, s_id2);
- return result;
+ snprintf(result, sizeof result, fmt, s_id1, s_id2);
+ return result;
}
/*
@@ -1981,75 +1904,69 @@ ipsec_decode_ids (char *fmt, u_int8_t *id1, size_t id1_len,
* ISAKMP ID payload. Ths payload size should be stashed in SZ.
* The caller is responsible for freeing the payload.
*/
-u_int8_t *
-ipsec_build_id (char *section, size_t *sz)
+u_int8_t *
+ipsec_build_id(char *section, size_t * sz)
{
- struct sockaddr *addr, *mask;
- u_int8_t *p;
- int id, subnet = 0;
- u_int8_t tproto = 0;
- u_int16_t port = 0;
-
- if (ipsec_get_id (section, &id, &addr, &mask, &tproto, &port))
- return 0;
-
- if (id == IPSEC_ID_IPV4_ADDR_SUBNET || id == IPSEC_ID_IPV6_ADDR_SUBNET)
- subnet = 1;
-
- *sz = ISAKMP_ID_SZ + sockaddr_addrlen (addr);
- if (subnet)
- *sz += sockaddr_addrlen (mask);
-
- p = malloc (*sz);
- if (!p)
- {
- log_print ("ipsec_build_id: malloc(%lu) failed", (unsigned long)*sz);
- return 0;
- }
-
- SET_ISAKMP_ID_TYPE (p, id);
- SET_ISAKMP_ID_DOI_DATA (p, (unsigned char *)"\000\000\000");
-
- memcpy (p + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (addr),
- sockaddr_addrlen (addr));
- if (subnet)
- memcpy (p + ISAKMP_ID_DATA_OFF + sockaddr_addrlen (addr),
- sockaddr_addrdata (mask), sockaddr_addrlen (mask));
-
- SET_IPSEC_ID_PROTO (p + ISAKMP_ID_DOI_DATA_OFF, tproto);
- SET_IPSEC_ID_PORT (p + ISAKMP_ID_DOI_DATA_OFF, port);
-
- return p;
+ struct sockaddr *addr, *mask;
+ u_int8_t *p;
+ int id, subnet = 0;
+ u_int8_t tproto = 0;
+ u_int16_t port = 0;
+
+ if (ipsec_get_id(section, &id, &addr, &mask, &tproto, &port))
+ return 0;
+
+ if (id == IPSEC_ID_IPV4_ADDR_SUBNET || id == IPSEC_ID_IPV6_ADDR_SUBNET)
+ subnet = 1;
+
+ *sz = ISAKMP_ID_SZ + sockaddr_addrlen(addr);
+ if (subnet)
+ *sz += sockaddr_addrlen(mask);
+
+ p = malloc(*sz);
+ if (!p) {
+ log_print("ipsec_build_id: malloc(%lu) failed", (unsigned long) *sz);
+ return 0;
+ }
+ SET_ISAKMP_ID_TYPE(p, id);
+ SET_ISAKMP_ID_DOI_DATA(p, (unsigned char *) "\000\000\000");
+
+ memcpy(p + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(addr),
+ sockaddr_addrlen(addr));
+ if (subnet)
+ memcpy(p + ISAKMP_ID_DATA_OFF + sockaddr_addrlen(addr),
+ sockaddr_addrdata(mask), sockaddr_addrlen(mask));
+
+ SET_IPSEC_ID_PROTO(p + ISAKMP_ID_DOI_DATA_OFF, tproto);
+ SET_IPSEC_ID_PORT(p + ISAKMP_ID_DOI_DATA_OFF, port);
+
+ return p;
}
/*
* copy an ISAKMPD id
*/
int
-ipsec_clone_id (u_int8_t **did, size_t *did_len, u_int8_t *id, size_t id_len)
+ipsec_clone_id(u_int8_t ** did, size_t * did_len, u_int8_t * id, size_t id_len)
{
- if (*did)
- free (*did);
-
- if (!id_len || !id)
- {
- *did = 0;
- *did_len = 0;
- return 0;
- }
-
- *did = malloc (id_len);
- if (!*did)
- {
- *did_len = 0;
- log_error ("ipsec_clone_id: malloc(%lu) failed", (unsigned long)id_len);
- return -1;
- }
-
- *did_len = id_len;
- memcpy (*did, id, id_len);
-
- return 0;
+ if (*did)
+ free(*did);
+
+ if (!id_len || !id) {
+ *did = 0;
+ *did_len = 0;
+ return 0;
+ }
+ *did = malloc(id_len);
+ if (!*did) {
+ *did_len = 0;
+ log_error("ipsec_clone_id: malloc(%lu) failed", (unsigned long) id_len);
+ return -1;
+ }
+ *did_len = id_len;
+ memcpy(*did, id, id_len);
+
+ return 0;
}
/*
@@ -2058,13 +1975,13 @@ ipsec_clone_id (u_int8_t **did, size_t *did_len, u_int8_t *id, size_t id_len)
* XXX I want to fix this later.
*/
void
-ipsec_proto_init (struct proto *proto, char *section)
+ipsec_proto_init(struct proto * proto, char *section)
{
- struct ipsec_proto *iproto = proto->data;
+ struct ipsec_proto *iproto = proto->data;
- if (proto->sa->phase == 2 && section)
- iproto->replay_window
- = conf_get_num (section, "ReplayWindow", DEFAULT_REPLAY_WINDOW);
+ if (proto->sa->phase == 2 && section)
+ iproto->replay_window
+ = conf_get_num(section, "ReplayWindow", DEFAULT_REPLAY_WINDOW);
}
/*
@@ -2072,34 +1989,31 @@ ipsec_proto_init (struct proto *proto, char *section)
* the first contact we have made to our peer.
*/
int
-ipsec_initial_contact (struct message *msg)
+ipsec_initial_contact(struct message * msg)
{
- u_int8_t *buf;
-
- if (ipsec_contacted (msg))
- return 0;
-
- buf = malloc (ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN);
- if (!buf)
- {
- log_error ("ike_phase_1_initial_contact: malloc (%d) failed",
- ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN);
- return -1;
- }
- SET_ISAKMP_NOTIFY_DOI (buf, IPSEC_DOI_IPSEC);
- SET_ISAKMP_NOTIFY_PROTO (buf, ISAKMP_PROTO_ISAKMP);
- SET_ISAKMP_NOTIFY_SPI_SZ (buf, ISAKMP_HDR_COOKIES_LEN);
- SET_ISAKMP_NOTIFY_MSG_TYPE (buf, IPSEC_NOTIFY_INITIAL_CONTACT);
- memcpy (buf + ISAKMP_NOTIFY_SPI_OFF, msg->isakmp_sa->cookies,
- ISAKMP_HDR_COOKIES_LEN);
- if (message_add_payload (msg, ISAKMP_PAYLOAD_NOTIFY, buf,
- ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN, 1))
- {
- free (buf);
- return -1;
- }
-
- return ipsec_add_contact (msg);
+ u_int8_t *buf;
+
+ if (ipsec_contacted(msg))
+ return 0;
+
+ buf = malloc(ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN);
+ if (!buf) {
+ log_error("ike_phase_1_initial_contact: malloc (%d) failed",
+ ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN);
+ return -1;
+ }
+ SET_ISAKMP_NOTIFY_DOI(buf, IPSEC_DOI_IPSEC);
+ SET_ISAKMP_NOTIFY_PROTO(buf, ISAKMP_PROTO_ISAKMP);
+ SET_ISAKMP_NOTIFY_SPI_SZ(buf, ISAKMP_HDR_COOKIES_LEN);
+ SET_ISAKMP_NOTIFY_MSG_TYPE(buf, IPSEC_NOTIFY_INITIAL_CONTACT);
+ memcpy(buf + ISAKMP_NOTIFY_SPI_OFF, msg->isakmp_sa->cookies,
+ ISAKMP_HDR_COOKIES_LEN);
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_NOTIFY, buf,
+ ISAKMP_NOTIFY_SZ + ISAKMP_HDR_COOKIES_LEN, 1)) {
+ free(buf);
+ return -1;
+ }
+ return ipsec_add_contact(msg);
}
/*
@@ -2107,13 +2021,13 @@ ipsec_initial_contact (struct message *msg)
* *A < *B, 0 if they are equal, and positive if *A is the largest of them.
*/
static int
-addr_cmp (const void *a, const void *b)
+addr_cmp(const void *a, const void *b)
{
- const struct contact *x = a, *y = b;
- int minlen = MIN (x->len, y->len);
- int rv = memcmp (x->addr, y->addr, minlen);
+ const struct contact *x = a, *y = b;
+ int minlen = MIN(x->len, y->len);
+ int rv = memcmp(x->addr, y->addr, minlen);
- return rv ? rv : (x->len - y->len);
+ return rv ? rv : (x->len - y->len);
}
/*
@@ -2123,297 +2037,283 @@ addr_cmp (const void *a, const void *b)
* is unimportant, if this is to scale.
*/
static int
-ipsec_add_contact (struct message *msg)
+ipsec_add_contact(struct message * msg)
{
- struct contact *new_contacts;
- struct sockaddr *dst, *addr;
- int cnt;
-
- if (contact_cnt == contact_limit)
- {
- cnt = contact_limit ? 2 * contact_limit : 64;
- new_contacts = realloc (contacts, cnt * sizeof contacts[0]);
- if (!new_contacts)
- {
- log_error ("ipsec_add_contact: realloc (%p, %lu) failed", contacts,
- cnt * (unsigned long)sizeof contacts[0]);
- return -1;
+ struct contact *new_contacts;
+ struct sockaddr *dst, *addr;
+ int cnt;
+
+ if (contact_cnt == contact_limit) {
+ cnt = contact_limit ? 2 * contact_limit : 64;
+ new_contacts = realloc(contacts, cnt * sizeof contacts[0]);
+ if (!new_contacts) {
+ log_error("ipsec_add_contact: realloc (%p, %lu) failed", contacts,
+ cnt * (unsigned long) sizeof contacts[0]);
+ return -1;
+ }
+ contact_limit = cnt;
+ contacts = new_contacts;
}
- contact_limit = cnt;
- contacts = new_contacts;
- }
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- addr = malloc (sysdep_sa_len (dst));
- if (!addr)
- {
- log_error ("ipsec_add_contact: malloc (%d) failed", sysdep_sa_len (dst));
- return -1;
- }
- memcpy (addr, dst, sysdep_sa_len (dst));
- contacts[contact_cnt].addr = addr;
- contacts[contact_cnt++].len = sysdep_sa_len (dst);
-
- /*
- * XXX There are better algorithms for already mostly-sorted data like
- * this, but only qsort is standard. I will someday do this inline.
- */
- qsort (contacts, contact_cnt, sizeof *contacts, addr_cmp);
- return 0;
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ addr = malloc(sysdep_sa_len(dst));
+ if (!addr) {
+ log_error("ipsec_add_contact: malloc (%d) failed", sysdep_sa_len(dst));
+ return -1;
+ }
+ memcpy(addr, dst, sysdep_sa_len(dst));
+ contacts[contact_cnt].addr = addr;
+ contacts[contact_cnt++].len = sysdep_sa_len(dst);
+
+ /*
+ * XXX There are better algorithms for already mostly-sorted data like
+ * this, but only qsort is standard. I will someday do this inline.
+ */
+ qsort(contacts, contact_cnt, sizeof *contacts, addr_cmp);
+ return 0;
}
/* Return true if the recipient of MSG has already been contacted. */
static int
-ipsec_contacted (struct message *msg)
+ipsec_contacted(struct message * msg)
{
- struct contact contact;
-
- msg->transport->vtbl->get_dst (msg->transport, &contact.addr);
- contact.len = sysdep_sa_len (contact.addr);
- return contacts
- ? (bsearch (&contact, contacts, contact_cnt, sizeof *contacts, addr_cmp)
- != 0)
- : 0;
+ struct contact contact;
+
+ msg->transport->vtbl->get_dst(msg->transport, &contact.addr);
+ contact.len = sysdep_sa_len(contact.addr);
+ return contacts
+ ? (bsearch(&contact, contacts, contact_cnt, sizeof *contacts, addr_cmp)
+ != 0)
+ : 0;
}
/* Add a HASH for to MSG. */
-u_int8_t *
-ipsec_add_hash_payload (struct message *msg, size_t hashsize)
+u_int8_t *
+ipsec_add_hash_payload(struct message * msg, size_t hashsize)
{
- u_int8_t *buf;
-
- buf = malloc (ISAKMP_HASH_SZ + hashsize);
- if (!buf)
- {
- log_error ("ipsec_add_hash_payload: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hashsize);
- return 0;
- }
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, buf,
- ISAKMP_HASH_SZ + hashsize, 1))
- {
- free (buf);
- return 0;
- }
-
- return buf;
+ u_int8_t *buf;
+
+ buf = malloc(ISAKMP_HASH_SZ + hashsize);
+ if (!buf) {
+ log_error("ipsec_add_hash_payload: malloc (%lu) failed",
+ ISAKMP_HASH_SZ + (unsigned long) hashsize);
+ return 0;
+ }
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, buf,
+ ISAKMP_HASH_SZ + hashsize, 1)) {
+ free(buf);
+ return 0;
+ }
+ return buf;
}
/* Fill in the HASH payload of MSG. */
int
-ipsec_fill_in_hash (struct message *msg)
+ipsec_fill_in_hash(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct hash *hash = hash_get (isa->hash);
- struct prf *prf;
- struct payload *payload;
- u_int8_t *buf;
- u_int32_t i;
- char header[80];
-
- /* If no SKEYID_a, we need not do anything. */
- if (!isa->skeyid_a)
- return 0;
-
- payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- if (!payload)
- {
- log_print ("ipsec_fill_in_hash: no HASH payload found");
- return -1;
- }
- buf = payload->p;
-
- /* Allocate the prf and start calculating our HASH(1). */
- LOG_DBG_BUF ((LOG_MISC, 90, "ipsec_fill_in_hash: SKEYID_a", isa->skeyid_a,
- isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- return -1;
-
- prf->Init (prf->prfctx);
- LOG_DBG_BUF ((LOG_MISC, 90, "ipsec_fill_in_hash: message_id",
- exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
-
- /* Loop over all payloads after HASH(1). */
- for (i = 2; i < msg->iovlen; i++)
- {
- /* XXX Misleading payload type printouts. */
- snprintf (header, sizeof header,
- "ipsec_fill_in_hash: payload %d after HASH(1)", i - 1);
- LOG_DBG_BUF ((LOG_MISC, 90, header, msg->iov[i].iov_base,
- msg->iov[i].iov_len));
- prf->Update (prf->prfctx, msg->iov[i].iov_base, msg->iov[i].iov_len);
- }
- prf->Final (buf + ISAKMP_HASH_DATA_OFF, prf->prfctx);
- prf_free (prf);
- LOG_DBG_BUF ((LOG_MISC, 80, "ipsec_fill_in_hash: HASH(1)",
- buf + ISAKMP_HASH_DATA_OFF, hash->hashsize));
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa = isakmp_sa->data;
+ struct hash *hash = hash_get(isa->hash);
+ struct prf *prf;
+ struct payload *payload;
+ u_int8_t *buf;
+ u_int32_t i;
+ char header[80];
+
+ /* If no SKEYID_a, we need not do anything. */
+ if (!isa->skeyid_a)
+ return 0;
+
+ payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ if (!payload) {
+ log_print("ipsec_fill_in_hash: no HASH payload found");
+ return -1;
+ }
+ buf = payload->p;
+
+ /* Allocate the prf and start calculating our HASH(1). */
+ LOG_DBG_BUF((LOG_MISC, 90, "ipsec_fill_in_hash: SKEYID_a", isa->skeyid_a,
+ isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+
+ prf->Init(prf->prfctx);
+ LOG_DBG_BUF((LOG_MISC, 90, "ipsec_fill_in_hash: message_id",
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+
+ /* Loop over all payloads after HASH(1). */
+ for (i = 2; i < msg->iovlen; i++) {
+ /* XXX Misleading payload type printouts. */
+ snprintf(header, sizeof header,
+ "ipsec_fill_in_hash: payload %d after HASH(1)", i - 1);
+ LOG_DBG_BUF((LOG_MISC, 90, header, msg->iov[i].iov_base,
+ msg->iov[i].iov_len));
+ prf->Update(prf->prfctx, msg->iov[i].iov_base, msg->iov[i].iov_len);
+ }
+ prf->Final(buf + ISAKMP_HASH_DATA_OFF, prf->prfctx);
+ prf_free(prf);
+ LOG_DBG_BUF((LOG_MISC, 80, "ipsec_fill_in_hash: HASH(1)",
+ buf + ISAKMP_HASH_DATA_OFF, hash->hashsize));
+
+ return 0;
}
/* Add a HASH payload to MSG, if we have an ISAKMP SA we're protected by. */
static int
-ipsec_informational_pre_hook (struct message *msg)
+ipsec_informational_pre_hook(struct message * msg)
{
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa;
- struct hash *hash;
-
- if (!isakmp_sa)
- return 0;
- isa = isakmp_sa->data;
- hash = hash_get (isa->hash);
- return ipsec_add_hash_payload (msg, hash->hashsize) == 0;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa;
+ struct hash *hash;
+
+ if (!isakmp_sa)
+ return 0;
+ isa = isakmp_sa->data;
+ hash = hash_get(isa->hash);
+ return ipsec_add_hash_payload(msg, hash->hashsize) == 0;
}
/*
* Fill in the HASH payload in MSG, if we have an ISAKMP SA we're protected by.
*/
static int
-ipsec_informational_post_hook (struct message *msg)
+ipsec_informational_post_hook(struct message * msg)
{
- if (!msg->isakmp_sa)
- return 0;
- return ipsec_fill_in_hash (msg);
+ if (!msg->isakmp_sa)
+ return 0;
+ return ipsec_fill_in_hash(msg);
}
ssize_t
-ipsec_id_size (char *section, u_int8_t *id)
+ipsec_id_size(char *section, u_int8_t * id)
{
- char *type, *data;
-
- type = conf_get_str (section, "ID-type");
- if (!type)
- {
- log_print ("ipsec_id_size: section %s has no \"ID-type\" tag", section);
- return -1;
- }
-
- *id = constant_value (ipsec_id_cst, type);
- switch (*id)
- {
- case IPSEC_ID_IPV4_ADDR:
- return sizeof (struct in_addr);
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- return 2 * sizeof (struct in_addr);
- case IPSEC_ID_IPV6_ADDR:
- return sizeof (struct in6_addr);
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- return 2 * sizeof (struct in6_addr);
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- case IPSEC_ID_KEY_ID:
- case IPSEC_ID_DER_ASN1_DN:
- case IPSEC_ID_DER_ASN1_GN:
- data = conf_get_str (section, "Name");
- if (!data)
- {
- log_print ("ipsec_id_size: section %s has no \"Name\" tag", section);
- return -1;
+ char *type, *data;
+
+ type = conf_get_str(section, "ID-type");
+ if (!type) {
+ log_print("ipsec_id_size: section %s has no \"ID-type\" tag", section);
+ return -1;
}
- return strlen (data);
- }
- log_print ("ipsec_id_size: unrecognized/unsupported ID-type %d (%s)",
- *id, type);
- return -1;
+ *id = constant_value(ipsec_id_cst, type);
+ switch (*id) {
+ case IPSEC_ID_IPV4_ADDR:
+ return sizeof(struct in_addr);
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ return 2 * sizeof(struct in_addr);
+ case IPSEC_ID_IPV6_ADDR:
+ return sizeof(struct in6_addr);
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ return 2 * sizeof(struct in6_addr);
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ case IPSEC_ID_KEY_ID:
+ case IPSEC_ID_DER_ASN1_DN:
+ case IPSEC_ID_DER_ASN1_GN:
+ data = conf_get_str(section, "Name");
+ if (!data) {
+ log_print("ipsec_id_size: section %s has no \"Name\" tag", section);
+ return -1;
+ }
+ return strlen(data);
+ }
+ log_print("ipsec_id_size: unrecognized/unsupported ID-type %d (%s)",
+ *id, type);
+ return -1;
}
/*
* Generate a string version of the ID.
*/
-char *
-ipsec_id_string (u_int8_t *id, size_t id_len)
+char *
+ipsec_id_string(u_int8_t * id, size_t id_len)
{
- char *buf = 0;
- char *addrstr = 0;
- size_t len, size;
-
- /*
- * XXX Real ugly way of making the offsets correct. Be aware that id now
- * will point before the actual buffer and cannot be dereferenced without
- * an offset larger than or equal to ISAKM_GEN_SZ.
- */
- id -= ISAKMP_GEN_SZ;
-
- /* This is the actual length of the ID data field. */
- id_len += ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF;
-
- /*
- * Conservative allocation.
- * XXX I think the ASN1 DN case can be thought through to give a better
- * estimate.
- */
- size = MAX (sizeof "ipv6/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
- sizeof "asn1_dn/" + id_len - ISAKMP_ID_DATA_OFF);
- buf = malloc (size);
- if (!buf)
- /* XXX Log? */
- goto fail;
-
- switch (GET_ISAKMP_ID_TYPE (id))
- {
- case IPSEC_ID_IPV4_ADDR:
- if (id_len < sizeof (struct in_addr))
- goto fail;
- util_ntoa (&addrstr, AF_INET, id + ISAKMP_ID_DATA_OFF);
- if (!addrstr)
- goto fail;
- snprintf (buf, size, "ipv4/%s", addrstr);
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- if (id_len < sizeof (struct in6_addr))
- goto fail;
- util_ntoa (&addrstr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
- if (!addrstr)
- goto fail;
- snprintf (buf, size, "ipv6/%s", addrstr);
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- strlcpy (buf,
- GET_ISAKMP_ID_TYPE (id) == IPSEC_ID_FQDN ? "fqdn/" : "ufqdn/",
- size);
- len = strlen (buf);
-
- memcpy (buf + len, id + ISAKMP_ID_DATA_OFF, id_len);
- *(buf + len + id_len) = '\0';
- break;
+ char *buf = 0;
+ char *addrstr = 0;
+ size_t len, size;
+
+ /*
+ * XXX Real ugly way of making the offsets correct. Be aware that id now
+ * will point before the actual buffer and cannot be dereferenced without
+ * an offset larger than or equal to ISAKM_GEN_SZ.
+ */
+ id -= ISAKMP_GEN_SZ;
+
+ /* This is the actual length of the ID data field. */
+ id_len += ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF;
+
+ /*
+ * Conservative allocation.
+ * XXX I think the ASN1 DN case can be thought through to give a better
+ * estimate.
+ */
+ size = MAX(sizeof "ipv6/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+ sizeof "asn1_dn/" + id_len - ISAKMP_ID_DATA_OFF);
+ buf = malloc(size);
+ if (!buf)
+ /* XXX Log? */
+ goto fail;
+
+ switch (GET_ISAKMP_ID_TYPE(id)) {
+ case IPSEC_ID_IPV4_ADDR:
+ if (id_len < sizeof(struct in_addr))
+ goto fail;
+ util_ntoa(&addrstr, AF_INET, id + ISAKMP_ID_DATA_OFF);
+ if (!addrstr)
+ goto fail;
+ snprintf(buf, size, "ipv4/%s", addrstr);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ if (id_len < sizeof(struct in6_addr))
+ goto fail;
+ util_ntoa(&addrstr, AF_INET6, id + ISAKMP_ID_DATA_OFF);
+ if (!addrstr)
+ goto fail;
+ snprintf(buf, size, "ipv6/%s", addrstr);
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ strlcpy(buf,
+ GET_ISAKMP_ID_TYPE(id) == IPSEC_ID_FQDN ? "fqdn/" : "ufqdn/",
+ size);
+ len = strlen(buf);
+
+ memcpy(buf + len, id + ISAKMP_ID_DATA_OFF, id_len);
+ *(buf + len + id_len) = '\0';
+ break;
#ifdef USE_X509
- case IPSEC_ID_DER_ASN1_DN:
- strlcpy (buf, "asn1_dn/", size);
- len = strlen (buf);
- addrstr = x509_DN_string (id + ISAKMP_ID_DATA_OFF,
- id_len - ISAKMP_ID_DATA_OFF);
- if (!addrstr)
- goto fail;
- if (size < len + strlen (addrstr) + 1)
- goto fail;
- strlcpy (buf + len, addrstr, size - len);
- break;
+ case IPSEC_ID_DER_ASN1_DN:
+ strlcpy(buf, "asn1_dn/", size);
+ len = strlen(buf);
+ addrstr = x509_DN_string(id + ISAKMP_ID_DATA_OFF,
+ id_len - ISAKMP_ID_DATA_OFF);
+ if (!addrstr)
+ goto fail;
+ if (size < len + strlen(addrstr) + 1)
+ goto fail;
+ strlcpy(buf + len, addrstr, size - len);
+ break;
#endif
- default:
- /* Unknown type. */
- LOG_DBG ((LOG_MISC, 10, "ipsec_id_string: unknown identity type %d\n",
- GET_ISAKMP_ID_TYPE (id)));
- goto fail;
- }
-
- if (addrstr)
- free (addrstr);
- return buf;
-
- fail:
- if (buf)
- free (buf);
- if (addrstr)
- free (addrstr);
- return 0;
+ default:
+ /* Unknown type. */
+ LOG_DBG((LOG_MISC, 10, "ipsec_id_string: unknown identity type %d\n",
+ GET_ISAKMP_ID_TYPE(id)));
+ goto fail;
+ }
+
+ if (addrstr)
+ free(addrstr);
+ return buf;
+
+fail:
+ if (buf)
+ free(buf);
+ if (addrstr)
+ free(addrstr);
+ return 0;
}
diff --git a/sbin/isakmpd/ipsec.h b/sbin/isakmpd/ipsec.h
index e95a2abc9bb..a39184f041a 100644
--- a/sbin/isakmpd/ipsec.h
+++ b/sbin/isakmpd/ipsec.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ipsec.h,v 1.22 2003/06/04 07:31:17 ho Exp $ */
-/* $EOM: ipsec.h,v 1.42 2000/12/03 07:58:20 angelos Exp $ */
+/* $OpenBSD: ipsec.h,v 1.23 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ipsec.h,v 1.42 2000/12/03 07:58:20 angelos Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -57,117 +57,121 @@ struct sa;
* separated.
*/
struct ipsec_exch {
- u_int flags;
- struct hash *hash;
- struct ike_auth *ike_auth;
- struct group *group;
- u_int16_t prf_type;
-
- /* 0 if no KEY_EXCH was proposed, 1 otherwise */
- u_int8_t pfs;
-
- /*
- * A copy of the initiator SA payload body for later computation of hashes.
- * Phase 1 only.
- */
- size_t sa_i_b_len;
- u_int8_t *sa_i_b;
-
- /* Diffie-Hellman values. */
- size_t g_x_len;
- u_int8_t *g_xi;
- u_int8_t *g_xr;
- u_int8_t* g_xy;
-
- /* SKEYIDs. XXX Phase 1 only? */
- size_t skeyid_len;
- u_int8_t *skeyid;
- u_int8_t *skeyid_d;
- u_int8_t *skeyid_a;
- u_int8_t *skeyid_e;
-
- /* HASH_I & HASH_R. XXX Do these need to be saved here? */
- u_int8_t *hash_i;
- u_int8_t *hash_r;
-
- /* KEYMAT */
- size_t keymat_len;
-
- /* Phase 2. */
- u_int8_t *id_ci;
- size_t id_ci_sz;
- u_int8_t *id_cr;
- size_t id_cr_sz;
+ u_int flags;
+ struct hash *hash;
+ struct ike_auth *ike_auth;
+ struct group *group;
+ u_int16_t prf_type;
+
+ /* 0 if no KEY_EXCH was proposed, 1 otherwise */
+ u_int8_t pfs;
+
+ /*
+ * A copy of the initiator SA payload body for later computation of hashes.
+ * Phase 1 only.
+ */
+ size_t sa_i_b_len;
+ u_int8_t *sa_i_b;
+
+ /* Diffie-Hellman values. */
+ size_t g_x_len;
+ u_int8_t *g_xi;
+ u_int8_t *g_xr;
+ u_int8_t *g_xy;
+
+ /* SKEYIDs. XXX Phase 1 only? */
+ size_t skeyid_len;
+ u_int8_t *skeyid;
+ u_int8_t *skeyid_d;
+ u_int8_t *skeyid_a;
+ u_int8_t *skeyid_e;
+
+ /* HASH_I & HASH_R. XXX Do these need to be saved here? */
+ u_int8_t *hash_i;
+ u_int8_t *hash_r;
+
+ /* KEYMAT */
+ size_t keymat_len;
+
+ /* Phase 2. */
+ u_int8_t *id_ci;
+ size_t id_ci_sz;
+ u_int8_t *id_cr;
+ size_t id_cr_sz;
#ifdef USE_ISAKMP_CFG
- /* ISAKMP configuration mode parameters */
- u_int16_t cfg_id;
- u_int16_t cfg_type;
- LIST_HEAD (isakmp_cfg_attr_head, isakmp_cfg_attr) attrs;
+ /* ISAKMP configuration mode parameters */
+ u_int16_t cfg_id;
+ u_int16_t cfg_type;
+ LIST_HEAD(isakmp_cfg_attr_head, isakmp_cfg_attr) attrs;
#endif
};
#define IPSEC_EXCH_FLAG_NO_ID 1
struct ipsec_sa {
- /* Phase 1. */
- u_int8_t hash;
- size_t skeyid_len;
- u_int8_t *skeyid_d;
- u_int8_t *skeyid_a;
- u_int16_t prf_type;
-
- /* Phase 2. */
- u_int16_t group_desc;
-
- /* Tunnel parameters. These are in network byte order. */
- struct sockaddr *src_net;
- struct sockaddr *src_mask;
- struct sockaddr *dst_net;
- struct sockaddr *dst_mask;
- u_int8_t tproto;
- u_int16_t sport;
- u_int16_t dport;
+ /* Phase 1. */
+ u_int8_t hash;
+ size_t skeyid_len;
+ u_int8_t *skeyid_d;
+ u_int8_t *skeyid_a;
+ u_int16_t prf_type;
+
+ /* Phase 2. */
+ u_int16_t group_desc;
+
+ /* Tunnel parameters. These are in network byte order. */
+ struct sockaddr *src_net;
+ struct sockaddr *src_mask;
+ struct sockaddr *dst_net;
+ struct sockaddr *dst_mask;
+ u_int8_t tproto;
+ u_int16_t sport;
+ u_int16_t dport;
};
struct ipsec_proto {
- /* Phase 2. */
- u_int16_t encap_mode;
- u_int16_t auth;
- u_int16_t keylen;
- u_int16_t keyrounds;
+ /* Phase 2. */
+ u_int16_t encap_mode;
+ u_int16_t auth;
+ u_int16_t keylen;
+ u_int16_t keyrounds;
- /* This is not negotiated, but rather configured. */
- int32_t replay_window;
+ /* This is not negotiated, but rather configured. */
+ int32_t replay_window;
- /* KEYMAT */
- u_int8_t *keymat[2];
+ /* KEYMAT */
+ u_int8_t *keymat[2];
};
-extern u_int8_t *ipsec_add_hash_payload (struct message *msg, size_t);
-extern int ipsec_ah_keylength (struct proto *);
-extern u_int8_t *ipsec_build_id (char *, size_t *);
-extern int ipsec_decode_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
-extern void ipsec_decode_transform (struct message *, struct sa *,
- struct proto *, u_int8_t *);
-extern int ipsec_esp_authkeylength (struct proto *);
-extern int ipsec_esp_enckeylength (struct proto *);
-extern int ipsec_fill_in_hash (struct message *msg);
-extern int ipsec_gen_g_x (struct message *);
-extern int ipsec_get_id (char *, int *, struct sockaddr **,
- struct sockaddr **, u_int8_t *, u_int16_t *);
-extern ssize_t ipsec_id_size (char *, u_int8_t *);
-extern char *ipsec_id_string (u_int8_t *, size_t);
-extern void ipsec_init (void);
-extern int ipsec_initial_contact (struct message *msg);
-extern int ipsec_is_attribute_incompatible (u_int16_t, u_int8_t *, u_int16_t,
- void *);
-extern int ipsec_keymat_length (struct proto *);
-extern int ipsec_save_g_x (struct message *);
-extern struct sa *ipsec_sa_lookup (struct sockaddr *, u_int32_t, u_int8_t);
-
-extern char *ipsec_decode_ids(char *, u_int8_t *, size_t, u_int8_t *, size_t,
- int);
-extern int ipsec_clone_id(u_int8_t **, size_t *, u_int8_t *, size_t);
-
-#endif /* _IPSEC_H_ */
+extern u_int8_t *ipsec_add_hash_payload(struct message * msg, size_t);
+extern int ipsec_ah_keylength(struct proto *);
+extern u_int8_t *ipsec_build_id(char *, size_t *);
+extern int ipsec_decode_attribute(u_int16_t, u_int8_t *, u_int16_t, void *);
+extern void
+ipsec_decode_transform(struct message *, struct sa *,
+ struct proto *, u_int8_t *);
+extern int ipsec_esp_authkeylength(struct proto *);
+extern int ipsec_esp_enckeylength(struct proto *);
+extern int ipsec_fill_in_hash(struct message * msg);
+extern int ipsec_gen_g_x(struct message *);
+extern int
+ipsec_get_id(char *, int *, struct sockaddr **,
+ struct sockaddr **, u_int8_t *, u_int16_t *);
+extern ssize_t ipsec_id_size(char *, u_int8_t *);
+extern char *ipsec_id_string(u_int8_t *, size_t);
+extern void ipsec_init(void);
+extern int ipsec_initial_contact(struct message * msg);
+extern int
+ipsec_is_attribute_incompatible(u_int16_t, u_int8_t *, u_int16_t,
+ void *);
+extern int ipsec_keymat_length(struct proto *);
+extern int ipsec_save_g_x(struct message *);
+extern struct sa *ipsec_sa_lookup(struct sockaddr *, u_int32_t, u_int8_t);
+
+extern char *
+ipsec_decode_ids(char *, u_int8_t *, size_t, u_int8_t *, size_t,
+ int);
+extern int ipsec_clone_id(u_int8_t **, size_t *, u_int8_t *, size_t);
+
+#endif /* _IPSEC_H_ */
diff --git a/sbin/isakmpd/ipsec_doi.h b/sbin/isakmpd/ipsec_doi.h
index 24ccd8cd264..c7000c76759 100644
--- a/sbin/isakmpd/ipsec_doi.h
+++ b/sbin/isakmpd/ipsec_doi.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ipsec_doi.h,v 1.7 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ipsec_doi.h,v 1.10 1999/04/02 00:57:51 niklas Exp $ */
+/* $OpenBSD: ipsec_doi.h,v 1.8 2004/04/15 18:39:25 deraadt Exp $ */
+/* $EOM: ipsec_doi.h,v 1.10 1999/04/02 00:57:51 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -41,4 +41,4 @@
/* The low limit if valid SPI values. */
#define IPSEC_SPI_LOW 0x100
-#endif /* _IPSEC_DOI_H_ */
+#endif /* _IPSEC_DOI_H_ */
diff --git a/sbin/isakmpd/isakmp.h b/sbin/isakmpd/isakmp.h
index 1ab711c14c3..11051fb7c15 100644
--- a/sbin/isakmpd/isakmp.h
+++ b/sbin/isakmpd/isakmp.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: isakmp.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: isakmp.h,v 1.11 2000/07/05 10:48:43 ho Exp $ */
+/* $OpenBSD: isakmp.h,v 1.6 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: isakmp.h,v 1.11 2000/07/05 10:48:43 ho Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -56,4 +56,4 @@
#define ISAKMP_VERSION_MINOR(x) ((x) & 0xf)
#define ISAKMP_VERSION_MAKE(maj, min) ((maj) << 4 | (min))
-#endif /* _ISAKMP_H_ */
+#endif /* _ISAKMP_H_ */
diff --git a/sbin/isakmpd/isakmp_cfg.c b/sbin/isakmpd/isakmp_cfg.c
index 8788a02e518..9a31de1583a 100644
--- a/sbin/isakmpd/isakmp_cfg.c
+++ b/sbin/isakmpd/isakmp_cfg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isakmp_cfg.c,v 1.27 2004/03/11 16:56:11 hshoexer Exp $ */
+/* $OpenBSD: isakmp_cfg.c,v 1.28 2004/04/15 18:39:26 deraadt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist. All rights reserved.
@@ -57,36 +57,38 @@
* Validation script used to test messages for correct content of
* payloads depending on the exchange type.
*/
-int16_t script_transaction[] = {
- ISAKMP_PAYLOAD_ATTRIBUTE, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_ATTRIBUTE, /* Responder -> initiator. */
- EXCHANGE_SCRIPT_END
+int16_t script_transaction[] = {
+ ISAKMP_PAYLOAD_ATTRIBUTE, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_ATTRIBUTE, /* Responder -> initiator. */
+ EXCHANGE_SCRIPT_END
};
-static int cfg_decode_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
-static int cfg_encode_attributes (struct isakmp_cfg_attr_head *, u_int32_t,
- u_int32_t, char *, u_int8_t **, u_int16_t *);
-static int cfg_initiator_send_ATTR (struct message *);
-static int cfg_initiator_recv_ATTR (struct message *);
-static int cfg_responder_recv_ATTR (struct message *);
-static int cfg_responder_send_ATTR (struct message *);
-
-u_int8_t *cfg_add_hash (struct message *);
-int cfg_finalize_hash (struct message *,u_int8_t *, u_int8_t *,
- u_int16_t);
-int cfg_verify_hash (struct message *msg);
+static int cfg_decode_attribute(u_int16_t, u_int8_t *, u_int16_t, void *);
+static int
+cfg_encode_attributes(struct isakmp_cfg_attr_head *, u_int32_t,
+ u_int32_t, char *, u_int8_t **, u_int16_t *);
+static int cfg_initiator_send_ATTR(struct message *);
+static int cfg_initiator_recv_ATTR(struct message *);
+static int cfg_responder_recv_ATTR(struct message *);
+static int cfg_responder_send_ATTR(struct message *);
+
+u_int8_t *cfg_add_hash(struct message *);
+int
+cfg_finalize_hash(struct message *, u_int8_t *, u_int8_t *,
+ u_int16_t);
+int cfg_verify_hash(struct message * msg);
/* Server: SET/ACK Client; REQ/REPLY */
-int (*isakmp_cfg_initiator[]) (struct message *) = {
- cfg_initiator_send_ATTR,
- cfg_initiator_recv_ATTR
+int (*isakmp_cfg_initiator[]) (struct message *) = {
+ cfg_initiator_send_ATTR,
+ cfg_initiator_recv_ATTR
};
/* Server: REQ/REPLY Client: SET/ACK */
-int (*isakmp_cfg_responder[]) (struct message *) = {
- cfg_responder_recv_ATTR,
- cfg_responder_send_ATTR
+int (*isakmp_cfg_responder[]) (struct message *) = {
+ cfg_responder_recv_ATTR,
+ cfg_responder_send_ATTR
};
/*
@@ -94,48 +96,43 @@ int (*isakmp_cfg_responder[]) (struct message *) = {
* When we are "the client", this starts REQ/REPLY mode
*/
static int
-cfg_initiator_send_ATTR (struct message *msg)
+cfg_initiator_send_ATTR(struct message * msg)
{
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_exch *ie = msg->exchange->data;
- u_int8_t *hashp = 0, *attrp, *attr;
- size_t attrlen, off;
- char *id_string, *cfg_mode, *field;
- struct sockaddr *sa;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_exch *ie = msg->exchange->data;
+ u_int8_t *hashp = 0, *attrp, *attr;
+ size_t attrlen, off;
+ char *id_string, *cfg_mode, *field;
+ struct sockaddr *sa;
#define CFG_ATTR_BIT_MAX ISAKMP_CFG_ATTR_FUTURE_MIN /* XXX */
- bitstr_t bit_decl (attrbits, CFG_ATTR_BIT_MAX);
- u_int16_t bit, length;
- u_int32_t life;
-
- if (msg->exchange->phase == 2)
- {
- hashp = cfg_add_hash (msg);
- if (!hashp)
- return -1;
- }
-
- /* We initiated this exchange, check isakmp_sa for other side. */
- if (isakmp_sa->initiator)
- id_string = ipsec_id_string (isakmp_sa->id_r, isakmp_sa->id_r_len);
- else
- id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
- if (!id_string)
- {
- log_print ("cfg_initiator_send_ATTR: cannot parse ID");
- goto fail;
- }
-
- /* Check for attribute list to send to the other side */
- attrlen = 0;
- bit_nclear (attrbits, 0, CFG_ATTR_BIT_MAX - 1);
-
- cfg_mode = conf_get_str (id_string, "Mode");
- if (!cfg_mode || strcmp (cfg_mode, "SET") == 0)
- {
- /* SET/ACK mode */
- ie->cfg_type = ISAKMP_CFG_SET;
-
- LOG_DBG ((LOG_NEGOTIATION, 10, "cfg_initiator_send_ATTR: SET/ACK mode"));
+ bitstr_t bit_decl(attrbits, CFG_ATTR_BIT_MAX);
+ u_int16_t bit, length;
+ u_int32_t life;
+
+ if (msg->exchange->phase == 2) {
+ hashp = cfg_add_hash(msg);
+ if (!hashp)
+ return -1;
+ }
+ /* We initiated this exchange, check isakmp_sa for other side. */
+ if (isakmp_sa->initiator)
+ id_string = ipsec_id_string(isakmp_sa->id_r, isakmp_sa->id_r_len);
+ else
+ id_string = ipsec_id_string(isakmp_sa->id_i, isakmp_sa->id_i_len);
+ if (!id_string) {
+ log_print("cfg_initiator_send_ATTR: cannot parse ID");
+ goto fail;
+ }
+ /* Check for attribute list to send to the other side */
+ attrlen = 0;
+ bit_nclear(attrbits, 0, CFG_ATTR_BIT_MAX - 1);
+
+ cfg_mode = conf_get_str(id_string, "Mode");
+ if (!cfg_mode || strcmp(cfg_mode, "SET") == 0) {
+ /* SET/ACK mode */
+ ie->cfg_type = ISAKMP_CFG_SET;
+
+ LOG_DBG((LOG_NEGOTIATION, 10, "cfg_initiator_send_ATTR: SET/ACK mode"));
#define ATTRFIND(STR,ATTR4,LEN4,ATTR6,LEN6) do \
{ \
@@ -156,221 +153,192 @@ cfg_initiator_send_ATTR (struct message *msg)
free (sa); \
} while (0)
- /* XXX We don't simultaneously support IPv4 and IPv6 addresses. */
- ATTRFIND ("Address", ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS, 4,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS, 16);
- ATTRFIND ("Netmask", ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK, 4,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK, 16);
- ATTRFIND ("Nameserver", ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS, 4,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS, 16);
- ATTRFIND ("WINS-server", ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS, 4,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS, 16);
- ATTRFIND ("DHCP-server", ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP, 4,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP, 16);
+ /*
+ * XXX We don't simultaneously support IPv4 and IPv6
+ * addresses.
+ */
+ ATTRFIND("Address", ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS, 4,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS, 16);
+ ATTRFIND("Netmask", ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK, 4,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK, 16);
+ ATTRFIND("Nameserver", ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS, 4,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS, 16);
+ ATTRFIND("WINS-server", ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS, 4,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS, 16);
+ ATTRFIND("DHCP-server", ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP, 4,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP, 16);
#ifdef notyet
- ATTRFIND ("Network", ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET, 8,
- ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET, 17);
+ ATTRFIND("Network", ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET, 8,
+ ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET, 17);
#endif
#undef ATTRFIND
- if (conf_get_str (id_string, "Lifetime"))
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY);
- attrlen += ISAKMP_ATTR_SZ + 4;
- }
- }
- else
- {
- struct conf_list *alist;
- struct conf_list_node *anode;
-
- ie->cfg_type = ISAKMP_CFG_REQUEST;
-
- LOG_DBG ((LOG_NEGOTIATION, 10,
- "cfg_initiator_send_ATTR: REQ/REPLY mode"));
-
- alist = conf_get_list (id_string, "Attributes");
- if (alist)
- {
- for (anode = TAILQ_FIRST (&alist->fields); anode;
- anode = TAILQ_NEXT (anode, link))
- {
- if (strcasecmp (anode->field, "Address") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS);
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS);
- attrlen += ISAKMP_ATTR_SZ * 2;
+ if (conf_get_str(id_string, "Lifetime")) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY);
+ attrlen += ISAKMP_ATTR_SZ + 4;
}
- else if (strcasecmp (anode->field, "Netmask") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK);
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK);
- attrlen += ISAKMP_ATTR_SZ * 2;
+ } else {
+ struct conf_list *alist;
+ struct conf_list_node *anode;
+
+ ie->cfg_type = ISAKMP_CFG_REQUEST;
+
+ LOG_DBG((LOG_NEGOTIATION, 10,
+ "cfg_initiator_send_ATTR: REQ/REPLY mode"));
+
+ alist = conf_get_list(id_string, "Attributes");
+ if (alist) {
+ for (anode = TAILQ_FIRST(&alist->fields); anode;
+ anode = TAILQ_NEXT(anode, link)) {
+ if (strcasecmp(anode->field, "Address") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS);
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS);
+ attrlen += ISAKMP_ATTR_SZ * 2;
+ } else if (strcasecmp(anode->field, "Netmask") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK);
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK);
+ attrlen += ISAKMP_ATTR_SZ * 2;
+ } else if (strcasecmp(anode->field, "Nameserver") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS);
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS);
+ attrlen += ISAKMP_ATTR_SZ * 2;
+ } else if (strcasecmp(anode->field, "WINS-server") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS);
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS);
+ attrlen += ISAKMP_ATTR_SZ * 2;
+ } else if (strcasecmp(anode->field, "DHCP-server") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP);
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP);
+ attrlen += ISAKMP_ATTR_SZ * 2;
+ } else if (strcasecmp(anode->field, "Lifetime") == 0) {
+ bit_set(attrbits, ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY);
+ attrlen += ISAKMP_ATTR_SZ;
+ } else {
+ log_print("cfg_initiator_send_ATTR: unknown attribute "
+ "%.20s in section [%s]", anode->field, id_string);
+ }
+ }
+
+ conf_free_list(alist);
}
- else if (strcasecmp (anode->field, "Nameserver") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS);
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS);
- attrlen += ISAKMP_ATTR_SZ * 2;
- }
- else if (strcasecmp (anode->field, "WINS-server") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS);
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS);
- attrlen += ISAKMP_ATTR_SZ * 2;
- }
- else if (strcasecmp (anode->field, "DHCP-server") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP);
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP);
- attrlen += ISAKMP_ATTR_SZ * 2;
- }
- else if (strcasecmp (anode->field, "Lifetime") == 0)
- {
- bit_set (attrbits, ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY);
- attrlen += ISAKMP_ATTR_SZ;
- }
- else
- {
- log_print ("cfg_initiator_send_ATTR: unknown attribute "
- "%.20s in section [%s]", anode->field, id_string);
- }
- }
+ }
- conf_free_list (alist);
+ if (attrlen == 0) {
+ /* No data found. */
+ log_print("cfg_initiator_send_ATTR: no IKECFG attributes "
+ "found for [%s]", id_string);
+
+ /*
+ * We can continue, but this indicates a configuration error that
+ * the user probably will want to correct.
+ */
+ free(id_string);
+ return 0;
+ }
+ attrlen += ISAKMP_ATTRIBUTE_SZ;
+ attrp = calloc(1, attrlen);
+ if (!attrp) {
+ log_error("cfg_initiator_send_ATTR: calloc (1, %lu) failed",
+ (unsigned long) attrlen);
+ goto fail;
}
- }
-
- if (attrlen == 0)
- {
- /* No data found. */
- log_print ("cfg_initiator_send_ATTR: no IKECFG attributes "
- "found for [%s]", id_string);
-
- /*
- * We can continue, but this indicates a configuration error that
- * the user probably will want to correct.
- */
- free (id_string);
- return 0;
- }
-
- attrlen += ISAKMP_ATTRIBUTE_SZ;
- attrp = calloc (1, attrlen);
- if (!attrp)
- {
- log_error ("cfg_initiator_send_ATTR: calloc (1, %lu) failed",
- (unsigned long)attrlen);
- goto fail;
- }
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1))
- {
- free (attrp);
- goto fail;
- }
-
- SET_ISAKMP_ATTRIBUTE_TYPE (attrp, ie->cfg_type);
- getrandom ((u_int8_t *)&ie->cfg_id, sizeof ie->cfg_id);
- SET_ISAKMP_ATTRIBUTE_ID (attrp, ie->cfg_id);
-
- off = ISAKMP_ATTRIBUTE_SZ;
-
- /*
- * Use the bitstring built previously to collect the right
- * parameters for attrp.
- */
- for (bit = 0; bit < CFG_ATTR_BIT_MAX; bit++)
- if (bit_test (attrbits, bit))
- {
- attr = attrp + off;
- SET_ISAKMP_ATTR_TYPE (attr, bit);
-
- if (ie->cfg_type == ISAKMP_CFG_REQUEST)
- {
- off += ISAKMP_ATTR_SZ;
- continue;
- }
-
- /* All the other are similar, this is the odd one. */
- if (bit == ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY)
- {
- life = conf_get_num (id_string, "Lifetime", 1200);
- SET_ISAKMP_ATTR_LENGTH_VALUE (attr, 4);
- encode_32 (attr + ISAKMP_ATTR_VALUE_OFF, life);
- off += ISAKMP_ATTR_SZ + 4;
- continue;
- }
-
- switch (bit)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- length = 4;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- length = 16;
- break;
-
- default:
- length = 0; /* Silence gcc. */
- }
-
- switch (bit)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- field = "Address";
- break;
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- field = "Netmask";
- break;
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- field = "Nameserver";
- break;
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- field = "DHCP-server";
- break;
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- field = "WINS-server";
- break;
- default:
- field = 0; /* Silence gcc. */
- }
-
- sa = conf_get_address (id_string, field);
-
- SET_ISAKMP_ATTR_LENGTH_VALUE (attr, length);
- memcpy (attr + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata (sa),
- length);
-
- free (sa);
-
- off += ISAKMP_ATTR_SZ + length;
- }
-
- if (msg->exchange->phase == 2)
- if (cfg_finalize_hash (msg, hashp, attrp, attrlen))
- goto fail;
-
- return 0;
-
- fail:
- if (id_string)
- free (id_string);
- return -1;
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1)) {
+ free(attrp);
+ goto fail;
+ }
+ SET_ISAKMP_ATTRIBUTE_TYPE(attrp, ie->cfg_type);
+ getrandom((u_int8_t *) & ie->cfg_id, sizeof ie->cfg_id);
+ SET_ISAKMP_ATTRIBUTE_ID(attrp, ie->cfg_id);
+
+ off = ISAKMP_ATTRIBUTE_SZ;
+
+ /*
+ * Use the bitstring built previously to collect the right
+ * parameters for attrp.
+ */
+ for (bit = 0; bit < CFG_ATTR_BIT_MAX; bit++)
+ if (bit_test(attrbits, bit)) {
+ attr = attrp + off;
+ SET_ISAKMP_ATTR_TYPE(attr, bit);
+
+ if (ie->cfg_type == ISAKMP_CFG_REQUEST) {
+ off += ISAKMP_ATTR_SZ;
+ continue;
+ }
+ /* All the other are similar, this is the odd one. */
+ if (bit == ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY) {
+ life = conf_get_num(id_string, "Lifetime", 1200);
+ SET_ISAKMP_ATTR_LENGTH_VALUE(attr, 4);
+ encode_32(attr + ISAKMP_ATTR_VALUE_OFF, life);
+ off += ISAKMP_ATTR_SZ + 4;
+ continue;
+ }
+ switch (bit) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ length = 4;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ length = 16;
+ break;
+
+ default:
+ length = 0; /* Silence gcc. */
+ }
+
+ switch (bit) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ field = "Address";
+ break;
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ field = "Netmask";
+ break;
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ field = "Nameserver";
+ break;
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ field = "DHCP-server";
+ break;
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ field = "WINS-server";
+ break;
+ default:
+ field = 0; /* Silence gcc. */
+ }
+
+ sa = conf_get_address(id_string, field);
+
+ SET_ISAKMP_ATTR_LENGTH_VALUE(attr, length);
+ memcpy(attr + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata(sa),
+ length);
+
+ free(sa);
+
+ off += ISAKMP_ATTR_SZ + length;
+ }
+ if (msg->exchange->phase == 2)
+ if (cfg_finalize_hash(msg, hashp, attrp, attrlen))
+ goto fail;
+
+ return 0;
+
+fail:
+ if (id_string)
+ free(id_string);
+ return -1;
}
/*
@@ -378,104 +346,101 @@ cfg_initiator_send_ATTR (struct message *msg)
* As "the client", this ends REQ/REPLY.
*/
static int
-cfg_initiator_recv_ATTR (struct message *msg)
+cfg_initiator_recv_ATTR(struct message * msg)
{
- struct payload *attrp
- = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
- struct ipsec_exch *ie = msg->exchange->data;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct isakmp_cfg_attr *attr;
- struct sockaddr *sa;
- const char *uk_addr = "<unknown>";
- char *addr;
-
- if (msg->exchange->phase == 2)
- if (cfg_verify_hash (msg))
- return -1;
-
- /* Sanity. */
- if (ie->cfg_id != GET_ISAKMP_ATTRIBUTE_ID (attrp->p))
- {
- log_print ("cfg_initiator_recv_ATTR: cfg packet ID does not match!");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF])
- {
- case ISAKMP_CFG_ACK:
- if (ie->cfg_type != ISAKMP_CFG_SET)
- {
- log_print ("cfg_initiator_recv_ATTR: bad packet type ACK");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
+ struct payload *attrp
+ = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
+ struct ipsec_exch *ie = msg->exchange->data;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct isakmp_cfg_attr *attr;
+ struct sockaddr *sa;
+ const char *uk_addr = "<unknown>";
+ char *addr;
+
+ if (msg->exchange->phase == 2)
+ if (cfg_verify_hash(msg))
+ return -1;
+
+ /* Sanity. */
+ if (ie->cfg_id != GET_ISAKMP_ATTRIBUTE_ID(attrp->p)) {
+ log_print("cfg_initiator_recv_ATTR: cfg packet ID does not match!");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
}
- break;
- case ISAKMP_CFG_REPLY:
- if (ie->cfg_type != ISAKMP_CFG_REQUEST)
- {
- log_print ("cfg_initiator_recv_ATTR: bad packet type REPLY");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
+ switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF]) {
+ case ISAKMP_CFG_ACK:
+ if (ie->cfg_type != ISAKMP_CFG_SET) {
+ log_print("cfg_initiator_recv_ATTR: bad packet type ACK");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ break;
+ case ISAKMP_CFG_REPLY:
+ if (ie->cfg_type != ISAKMP_CFG_REQUEST) {
+ log_print("cfg_initiator_recv_ATTR: bad packet type REPLY");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
+ }
+ break;
+
+ default:
+ log_print("cfg_initiator_recv_ATTR: "
+ "unexpected configuration message type %d",
+ attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF]);
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ return -1;
}
- break;
-
- default:
- log_print ("cfg_initiator_recv_ATTR: "
- "unexpected configuration message type %d",
- attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF]);
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- return -1;
- }
-
- attribute_map (attrp->p + ISAKMP_ATTRIBUTE_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (attrp->p)
+
+ attribute_map(attrp->p + ISAKMP_ATTRIBUTE_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(attrp->p)
- ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute, ie);
- switch (ie->cfg_type)
- {
- case ISAKMP_CFG_ACK:
- {
- /* SET/ACK -- Server side (ACK from client) */
- msg->transport->vtbl->get_src (isakmp_sa->transport, &sa);
- if (sockaddr2text (sa, &addr, 0) < 0)
- addr = (char *)uk_addr;
-
- for (attr = LIST_FIRST (&ie->attrs); attr;
- attr = LIST_NEXT (attr, link))
- LOG_DBG ((LOG_NEGOTIATION, 50, "cfg_initiator_recv_ATTR: "
- "client %s ACKs attribute %s", addr,
- constant_name (isakmp_cfg_attr_cst, attr->type)));
-
- if (addr != uk_addr)
- free (addr);
- }
- break;
-
- case ISAKMP_CFG_REPLY:
- {
- /* REQ/REPLY: effect attributes we've gotten responses on. */
- msg->transport->vtbl->get_src (isakmp_sa->transport, &sa);
- if (sockaddr2text (sa, &addr, 0) < 0)
- addr = (char *)uk_addr;
-
- for (attr = LIST_FIRST (&ie->attrs); attr;
- attr = LIST_NEXT (attr, link))
- LOG_DBG ((LOG_NEGOTIATION, 50, "cfg_initiator_recv_ATTR: "
- "server %s replied with attribute %s", addr,
- constant_name (isakmp_cfg_attr_cst, attr->type)));
-
- if (addr != uk_addr)
- free (addr);
- }
- break;
-
- default:
- break;
- }
-
- attrp->flags |= PL_MARK;
- return 0;
+ switch (ie->cfg_type) {
+ case ISAKMP_CFG_ACK:
+ {
+ /* SET/ACK -- Server side (ACK from client) */
+ msg->transport->vtbl->get_src(isakmp_sa->transport, &sa);
+ if (sockaddr2text(sa, &addr, 0) < 0)
+ addr = (char *) uk_addr;
+
+ for (attr = LIST_FIRST(&ie->attrs); attr;
+ attr = LIST_NEXT(attr, link))
+ LOG_DBG((LOG_NEGOTIATION, 50, "cfg_initiator_recv_ATTR: "
+ "client %s ACKs attribute %s", addr,
+ constant_name(isakmp_cfg_attr_cst, attr->type)));
+
+ if (addr != uk_addr)
+ free(addr);
+ }
+ break;
+
+ case ISAKMP_CFG_REPLY:
+ {
+ /*
+ * REQ/REPLY: effect attributes we've gotten
+ * responses on.
+ */
+ msg->transport->vtbl->get_src(isakmp_sa->transport, &sa);
+ if (sockaddr2text(sa, &addr, 0) < 0)
+ addr = (char *) uk_addr;
+
+ for (attr = LIST_FIRST(&ie->attrs); attr;
+ attr = LIST_NEXT(attr, link))
+ LOG_DBG((LOG_NEGOTIATION, 50, "cfg_initiator_recv_ATTR: "
+ "server %s replied with attribute %s", addr,
+ constant_name(isakmp_cfg_attr_cst, attr->type)));
+
+ if (addr != uk_addr)
+ free(addr);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ attrp->flags |= PL_MARK;
+ return 0;
}
/*
@@ -483,80 +448,78 @@ cfg_initiator_recv_ATTR (struct message *msg)
* As "the client", this starts SET/ACK (initiated by the server).
*/
static int
-cfg_responder_recv_ATTR (struct message *msg)
+cfg_responder_recv_ATTR(struct message * msg)
{
- struct payload *attrp
- = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
- struct ipsec_exch *ie = msg->exchange->data;
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct isakmp_cfg_attr *attr;
- struct sockaddr *sa;
- char *addr;
-
- if (msg->exchange->phase == 2)
- if (cfg_verify_hash (msg))
- return -1;
-
- ie->cfg_id = GET_ISAKMP_ATTRIBUTE_ID (attrp->p);
- ie->cfg_type = attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF];
-
- switch (ie->cfg_type)
- {
- case ISAKMP_CFG_REQUEST:
- case ISAKMP_CFG_SET:
- break;
-
- default:
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
- log_print ("cfg_responder_recv_ATTR: "
- "unexpected configuration message type %d", ie->cfg_type);
- return -1;
- }
-
- attribute_map (attrp->p + ISAKMP_ATTRIBUTE_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (attrp->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute, ie);
+ struct payload *attrp
+ = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
+ struct ipsec_exch *ie = msg->exchange->data;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct isakmp_cfg_attr *attr;
+ struct sockaddr *sa;
+ char *addr;
+
+ if (msg->exchange->phase == 2)
+ if (cfg_verify_hash(msg))
+ return -1;
+
+ ie->cfg_id = GET_ISAKMP_ATTRIBUTE_ID(attrp->p);
+ ie->cfg_type = attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF];
+
+ switch (ie->cfg_type) {
+ case ISAKMP_CFG_REQUEST:
+ case ISAKMP_CFG_SET:
+ break;
- switch (ie->cfg_type)
- {
- case ISAKMP_CFG_REQUEST:
- /* We're done. */
- break;
+ default:
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
+ log_print("cfg_responder_recv_ATTR: "
+ "unexpected configuration message type %d", ie->cfg_type);
+ return -1;
+ }
- case ISAKMP_CFG_SET:
- {
- /* SET/ACK -- Client side (SET from server) */
- const char *uk_addr = "<unknown>";
+ attribute_map(attrp->p + ISAKMP_ATTRIBUTE_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(attrp->p)
+ - ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute, ie);
- msg->transport->vtbl->get_dst (isakmp_sa->transport, &sa);
- if (sockaddr2text (sa, &addr, 0) < 0)
- addr = (char *)uk_addr;
+ switch (ie->cfg_type) {
+ case ISAKMP_CFG_REQUEST:
+ /* We're done. */
+ break;
- for (attr = LIST_FIRST (&ie->attrs); attr;
- attr = LIST_NEXT (attr, link))
- LOG_DBG ((LOG_NEGOTIATION, 50, "cfg_responder_recv_ATTR: "
- "server %s asks us to SET attribute %s", addr,
- constant_name (isakmp_cfg_attr_cst, attr->type)));
+ case ISAKMP_CFG_SET:
+ {
+ /* SET/ACK -- Client side (SET from server) */
+ const char *uk_addr = "<unknown>";
+
+ msg->transport->vtbl->get_dst(isakmp_sa->transport, &sa);
+ if (sockaddr2text(sa, &addr, 0) < 0)
+ addr = (char *) uk_addr;
+
+ for (attr = LIST_FIRST(&ie->attrs); attr;
+ attr = LIST_NEXT(attr, link))
+ LOG_DBG((LOG_NEGOTIATION, 50, "cfg_responder_recv_ATTR: "
+ "server %s asks us to SET attribute %s", addr,
+ constant_name(isakmp_cfg_attr_cst, attr->type)));
+
+ /*
+ * XXX Here's the place to add code to walk through each attribute
+ * XXX and send them along to dhclient or whatever. Each attribute
+ * XXX that we act upon (such as setting a netmask), should be
+ * XXX marked like this for us to send the proper ACK response:
+ * XXX attr->attr_used++;
+ */
+
+ if (addr != uk_addr)
+ free(addr);
+ }
+ break;
- /*
- * XXX Here's the place to add code to walk through each attribute
- * XXX and send them along to dhclient or whatever. Each attribute
- * XXX that we act upon (such as setting a netmask), should be
- * XXX marked like this for us to send the proper ACK response:
- * XXX attr->attr_used++;
- */
-
- if (addr != uk_addr)
- free (addr);
- }
- break;
-
- default:
- break;
- }
-
- attrp->flags |= PL_MARK;
- return 0;
+ default:
+ break;
+ }
+
+ attrp->flags |= PL_MARK;
+ return 0;
}
/*
@@ -564,152 +527,136 @@ cfg_responder_recv_ATTR (struct message *msg)
* As "the client", this ends SET/ACK mode.
*/
static int
-cfg_responder_send_ATTR (struct message *msg)
+cfg_responder_send_ATTR(struct message * msg)
{
- struct ipsec_exch *ie = msg->exchange->data;
- struct sa *isakmp_sa = msg->isakmp_sa;
- u_int8_t *hashp = 0, *attrp;
- u_int16_t attrlen;
- char *id_string;
-
- if (msg->exchange->phase == 2)
- {
- hashp = cfg_add_hash (msg);
- if (!hashp)
- return -1;
- }
-
- /* We are responder, check isakmp_sa for other side. */
- if (isakmp_sa->initiator ^ (ie->cfg_type == ISAKMP_CFG_REQUEST))
- id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
- else
- id_string = ipsec_id_string (isakmp_sa->id_r, isakmp_sa->id_r_len);
- if (!id_string)
- {
- log_print ("cfg_responder_send_ATTR: cannot parse client's ID");
- return -1;
- }
-
- if (cfg_encode_attributes (&ie->attrs, (ie->cfg_type == ISAKMP_CFG_SET ?
- ISAKMP_CFG_ACK : ISAKMP_CFG_REPLY),
- ie->cfg_id, id_string, &attrp, &attrlen))
- {
- free (id_string);
- return -1;
- }
- free (id_string);
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1))
- {
- free (attrp);
- return -1;
- }
-
- if (msg->exchange->phase == 2)
- if (cfg_finalize_hash (msg, hashp, attrp, attrlen))
- return -1;
-
- return 0;
+ struct ipsec_exch *ie = msg->exchange->data;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ u_int8_t *hashp = 0, *attrp;
+ u_int16_t attrlen;
+ char *id_string;
+
+ if (msg->exchange->phase == 2) {
+ hashp = cfg_add_hash(msg);
+ if (!hashp)
+ return -1;
+ }
+ /* We are responder, check isakmp_sa for other side. */
+ if (isakmp_sa->initiator ^ (ie->cfg_type == ISAKMP_CFG_REQUEST))
+ id_string = ipsec_id_string(isakmp_sa->id_i, isakmp_sa->id_i_len);
+ else
+ id_string = ipsec_id_string(isakmp_sa->id_r, isakmp_sa->id_r_len);
+ if (!id_string) {
+ log_print("cfg_responder_send_ATTR: cannot parse client's ID");
+ return -1;
+ }
+ if (cfg_encode_attributes(&ie->attrs, (ie->cfg_type == ISAKMP_CFG_SET ?
+ ISAKMP_CFG_ACK : ISAKMP_CFG_REPLY),
+ ie->cfg_id, id_string, &attrp, &attrlen)) {
+ free(id_string);
+ return -1;
+ }
+ free(id_string);
+
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1)) {
+ free(attrp);
+ return -1;
+ }
+ if (msg->exchange->phase == 2)
+ if (cfg_finalize_hash(msg, hashp, attrp, attrlen))
+ return -1;
+
+ return 0;
}
-u_int8_t *
-cfg_add_hash (struct message *msg)
+u_int8_t *
+cfg_add_hash(struct message * msg)
{
- struct ipsec_sa *isa = msg->isakmp_sa->data;
- struct hash *hash = hash_get (isa->hash);
- u_int8_t *hashp;
-
- hashp = malloc (ISAKMP_HASH_SZ + hash->hashsize);
- if (!hashp)
- {
- log_error ("cfg_add_hash: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hash->hashsize);
- return 0;
- }
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, hashp,
- ISAKMP_HASH_SZ + hash->hashsize, 1))
- {
- free (hashp);
- return 0;
- }
- return hashp;
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct hash *hash = hash_get(isa->hash);
+ u_int8_t *hashp;
+
+ hashp = malloc(ISAKMP_HASH_SZ + hash->hashsize);
+ if (!hashp) {
+ log_error("cfg_add_hash: malloc (%lu) failed",
+ ISAKMP_HASH_SZ + (unsigned long) hash->hashsize);
+ return 0;
+ }
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, hashp,
+ ISAKMP_HASH_SZ + hash->hashsize, 1)) {
+ free(hashp);
+ return 0;
+ }
+ return hashp;
}
int
-cfg_finalize_hash (struct message *msg, u_int8_t *hashp, u_int8_t *data,
- u_int16_t length)
+cfg_finalize_hash(struct message * msg, u_int8_t * hashp, u_int8_t * data,
+ u_int16_t length)
{
- struct ipsec_sa *isa = msg->isakmp_sa->data;
- struct prf *prf;
-
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- return -1;
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, msg->exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, data, length);
- prf->Final (hashp + ISAKMP_GEN_SZ, prf->prfctx);
- prf_free (prf);
- return 0;
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct prf *prf;
+
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, msg->exchange->message_id,
+ ISAKMP_HDR_MESSAGE_ID_LEN);
+ prf->Update(prf->prfctx, data, length);
+ prf->Final(hashp + ISAKMP_GEN_SZ, prf->prfctx);
+ prf_free(prf);
+ return 0;
}
int
-cfg_verify_hash (struct message *msg)
+cfg_verify_hash(struct message * msg)
{
- struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- struct ipsec_sa *isa = msg->isakmp_sa->data;
- struct prf *prf;
- u_int8_t *hash, *comp_hash;
- size_t hash_len;
-
- if (!hashp)
- {
- log_print ("cfg_verify_hash: phase 2 message missing HASH");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- return -1;
- }
-
- hash = hashp->p;
- hash_len = GET_ISAKMP_GEN_LENGTH (hash);
- comp_hash = malloc (hash_len - ISAKMP_GEN_SZ);
- if (!comp_hash)
- {
- log_error ("cfg_verify_hash: malloc (%lu) failed",
- (unsigned long)hash_len - ISAKMP_GEN_SZ);
- return -1;
- }
-
- /* Verify hash. */
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
- isa->skeyid_len);
- if (!prf)
- {
- free (comp_hash);
- return -1;
- }
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, msg->exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, hash + hash_len,
- msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
- prf->Final (comp_hash, prf->prfctx);
- prf_free (prf);
-
- if (memcmp (hash + ISAKMP_GEN_SZ, comp_hash, hash_len - ISAKMP_GEN_SZ) != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- free (comp_hash);
- return -1;
- }
- free (comp_hash);
-
- /* Mark the HASH as handled. */
- hashp->flags |= PL_MARK;
-
- return 0;
+ struct payload *hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct prf *prf;
+ u_int8_t *hash, *comp_hash;
+ size_t hash_len;
+
+ if (!hashp) {
+ log_print("cfg_verify_hash: phase 2 message missing HASH");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ return -1;
+ }
+ hash = hashp->p;
+ hash_len = GET_ISAKMP_GEN_LENGTH(hash);
+ comp_hash = malloc(hash_len - ISAKMP_GEN_SZ);
+ if (!comp_hash) {
+ log_error("cfg_verify_hash: malloc (%lu) failed",
+ (unsigned long) hash_len - ISAKMP_GEN_SZ);
+ return -1;
+ }
+ /* Verify hash. */
+ prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
+ isa->skeyid_len);
+ if (!prf) {
+ free(comp_hash);
+ return -1;
+ }
+ prf->Init(prf->prfctx);
+ prf->Update(prf->prfctx, msg->exchange->message_id,
+ ISAKMP_HDR_MESSAGE_ID_LEN);
+ prf->Update(prf->prfctx, hash + hash_len,
+ msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
+ prf->Final(comp_hash, prf->prfctx);
+ prf_free(prf);
+
+ if (memcmp(hash + ISAKMP_GEN_SZ, comp_hash, hash_len - ISAKMP_GEN_SZ) != 0) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ free(comp_hash);
+ return -1;
+ }
+ free(comp_hash);
+
+ /* Mark the HASH as handled. */
+ hashp->flags |= PL_MARK;
+
+ return 0;
}
/*
@@ -718,303 +665,277 @@ cfg_verify_hash (struct message *msg)
* attributes indexed by type for easy retrieval.
*/
static int
-cfg_decode_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vie)
+cfg_decode_attribute(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *vie)
{
- struct ipsec_exch *ie = vie;
- struct isakmp_cfg_attr *attr;
-
- if (type >= ISAKMP_CFG_ATTR_PRIVATE_MIN
- && type <= ISAKMP_CFG_ATTR_PRIVATE_MAX)
- return 0;
- if (type == 0 || type >= ISAKMP_CFG_ATTR_FUTURE_MIN)
- {
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "cfg_decode_attribute: invalid attr type %u", type));
- return -1;
- }
-
- attr = calloc (1, sizeof *attr);
- if (!attr)
- {
- log_error ("cfg_decode_attribute: calloc (1, %lu) failed",
- (unsigned long)sizeof *attr);
- return -1;
- }
- attr->type = type;
- attr->length = len;
- if (len)
- {
- attr->value = malloc (len);
- if (!attr->value)
- {
- log_error ("cfg_decode_attribute: malloc (%d) failed", len);
- free (attr);
- /* Should we also deallocate all other values? */
- return -1;
+ struct ipsec_exch *ie = vie;
+ struct isakmp_cfg_attr *attr;
+
+ if (type >= ISAKMP_CFG_ATTR_PRIVATE_MIN
+ && type <= ISAKMP_CFG_ATTR_PRIVATE_MAX)
+ return 0;
+ if (type == 0 || type >= ISAKMP_CFG_ATTR_FUTURE_MIN) {
+ LOG_DBG((LOG_NEGOTIATION, 30,
+ "cfg_decode_attribute: invalid attr type %u", type));
+ return -1;
+ }
+ attr = calloc(1, sizeof *attr);
+ if (!attr) {
+ log_error("cfg_decode_attribute: calloc (1, %lu) failed",
+ (unsigned long) sizeof *attr);
+ return -1;
+ }
+ attr->type = type;
+ attr->length = len;
+ if (len) {
+ attr->value = malloc(len);
+ if (!attr->value) {
+ log_error("cfg_decode_attribute: malloc (%d) failed", len);
+ free(attr);
+ /* Should we also deallocate all other values? */
+ return -1;
+ }
+ memcpy(attr->value, value, len);
}
- memcpy (attr->value, value, len);
- }
- LIST_INSERT_HEAD (&ie->attrs, attr, link);
- return 0;
+ LIST_INSERT_HEAD(&ie->attrs, attr, link);
+ return 0;
}
/*
* Encode list of attributes from ie->attrs into a attribute payload.
*/
static int
-cfg_encode_attributes (struct isakmp_cfg_attr_head *attrs, u_int32_t type,
- u_int32_t cfg_id, char *id_string, u_int8_t **attrp,
- u_int16_t *len)
+cfg_encode_attributes(struct isakmp_cfg_attr_head * attrs, u_int32_t type,
+ u_int32_t cfg_id, char *id_string, u_int8_t ** attrp,
+ u_int16_t * len)
{
- struct isakmp_cfg_attr *attr;
- struct sockaddr *sa;
- sa_family_t family;
- u_int32_t value;
- u_int16_t off;
- char *field;
-
- /* Compute length */
- *len = ISAKMP_ATTRIBUTE_SZ;
- for (attr = LIST_FIRST (attrs); attr; attr = LIST_NEXT (attr, link))
- {
- /* With ACK we only include the attrs we've actually used. */
- if (type == ISAKMP_CFG_ACK && attr->attr_used == 0)
- continue;
-
- switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- case ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
- attr->length = 4;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
- attr->length = 8;
- break;
-
- case ISAKMP_CFG_ATTR_APPLICATION_VERSION:
- /* XXX So far no version identifier of isakmpd here. */
- attr->length = 0;
- break;
-
- case ISAKMP_CFG_ATTR_SUPPORTED_ATTRIBUTES:
- attr->length = 2 * 15;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- attr->length = 16;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
- attr->length = 17;
- break;
+ struct isakmp_cfg_attr *attr;
+ struct sockaddr *sa;
+ sa_family_t family;
+ u_int32_t value;
+ u_int16_t off;
+ char *field;
+
+ /* Compute length */
+ *len = ISAKMP_ATTRIBUTE_SZ;
+ for (attr = LIST_FIRST(attrs); attr; attr = LIST_NEXT(attr, link)) {
+ /* With ACK we only include the attrs we've actually used. */
+ if (type == ISAKMP_CFG_ACK && attr->attr_used == 0)
+ continue;
+
+ switch (attr->type) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
+ attr->length = 4;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
+ attr->length = 8;
+ break;
+
+ case ISAKMP_CFG_ATTR_APPLICATION_VERSION:
+ /* XXX So far no version identifier of isakmpd here. */
+ attr->length = 0;
+ break;
+
+ case ISAKMP_CFG_ATTR_SUPPORTED_ATTRIBUTES:
+ attr->length = 2 * 15;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ attr->length = 16;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
+ attr->length = 17;
+ break;
+
+ default:
+ attr->ignore++;
+ /* XXX Log! */
+ }
+ *len += ISAKMP_ATTR_SZ + attr->length;
+ }
- default:
- attr->ignore++;
- /* XXX Log! */
+ /* Allocate enough space for the payload */
+ *attrp = calloc(1, *len);
+ if (!*attrp) {
+ log_error("cfg_encode_attributes: calloc (1, %lu) failed",
+ (unsigned long) *len);
+ return -1;
}
- *len += ISAKMP_ATTR_SZ + attr->length;
- }
-
- /* Allocate enough space for the payload */
- *attrp = calloc (1, *len);
- if (!*attrp)
- {
- log_error ("cfg_encode_attributes: calloc (1, %lu) failed",
- (unsigned long)*len);
- return -1;
- }
-
- SET_ISAKMP_ATTRIBUTE_TYPE (*attrp, type);
- SET_ISAKMP_ATTRIBUTE_ID (*attrp, cfg_id);
-
- off = ISAKMP_ATTRIBUTE_SZ;
- for (attr = LIST_FIRST (attrs); attr; attr = LIST_NEXT (attr, link))
- {
- /* With ACK we only include the attrs we've actually used. */
- if (type == ISAKMP_CFG_ACK && attr->attr_used == 0)
- continue;
-
- switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- family = AF_INET;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- family = AF_INET6;
- break;
-
- default:
- family = 0;
- break;
- }
-
- switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- field = "Address";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
- field = "Network"; /* XXX or just "Address" */
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- field = "Netmask";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- field = "DHCP-server";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- field = "Nameserver";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- field = "WINS-server";
- break;
-
- default:
- field = 0;
- }
-
- switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- sa = conf_get_address (id_string, field);
- if (!sa)
- {
- LOG_DBG ((LOG_NEGOTIATION, 10, "cfg_responder_send_ATTR: "
- "attribute not found: %s", field));
- attr->length = 0;
- break;
- }
-
- if (sa->sa_family != family)
- {
- log_print ("cfg_responder_send_ATTR: attribute %s - expected %s "
- "got %s data", field,
- (family == AF_INET ? "IPv4" : "IPv6"),
- (sa->sa_family == AF_INET ? "IPv4" : "IPv6"));
- free (sa);
- attr->length = 0;
- break;
- }
-
- /* Temporary limit length for the _SUBNET types. */
- if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET)
- attr->length = 4;
- else if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET)
- attr->length = 16;
-
- memcpy (*attrp + off + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata (sa),
- attr->length);
- free (sa);
-
- /* _SUBNET types need some extra work. */
- if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET)
- {
- sa = conf_get_address (id_string, "Netmask");
- if (!sa)
- {
- LOG_DBG ((LOG_NEGOTIATION, 10, "cfg_responder_send_ATTR: "
- "attribute not found: Netmask"));
- attr->length = 0;
- break;
- }
- if (sa->sa_family != AF_INET)
- {
- log_print ("cfg_responder_send_ATTR: attribute Netmask - "
- "expected IPv4 got IPv6 data");
- free (sa);
- attr->length = 0;
- break;
- }
- memcpy (*attrp + off + ISAKMP_ATTR_VALUE_OFF + attr->length,
- sockaddr_addrdata (sa), attr->length);
- attr->length = 8;
- free (sa);
- }
- else if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET)
- {
- int prefix = conf_get_num (id_string, "Prefix", -1);
-
- if (prefix == -1)
- {
- log_print ("cfg_responder_send_ATTR: "
- "attribute not found: Prefix");
- attr->length = 0;
- break;
+ SET_ISAKMP_ATTRIBUTE_TYPE(*attrp, type);
+ SET_ISAKMP_ATTRIBUTE_ID(*attrp, cfg_id);
+
+ off = ISAKMP_ATTRIBUTE_SZ;
+ for (attr = LIST_FIRST(attrs); attr; attr = LIST_NEXT(attr, link)) {
+ /* With ACK we only include the attrs we've actually used. */
+ if (type == ISAKMP_CFG_ACK && attr->attr_used == 0)
+ continue;
+
+ switch (attr->type) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ family = AF_INET;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ family = AF_INET6;
+ break;
+
+ default:
+ family = 0;
+ break;
}
- else if (prefix < -1 || prefix > 128)
- {
- log_print ("cfg_responder_send_ATTR: attribute Prefix - "
- "invalid value %d", prefix);
- attr->length = 0;
- break;
- }
-
- *(*attrp + off + ISAKMP_ATTR_VALUE_OFF + 16) = (u_int8_t)prefix;
- attr->length = 17;
- }
- break;
- case ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
- value = conf_get_num (id_string, "Lifetime", 1200);
- encode_32 (*attrp + off + ISAKMP_ATTR_VALUE_OFF, value);
- break;
-
- case ISAKMP_CFG_ATTR_APPLICATION_VERSION:
- /* XXX So far no version identifier of isakmpd here. */
- break;
+ switch (attr->type) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ field = "Address";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
+ field = "Network"; /* XXX or just "Address" */
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ field = "Netmask";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ field = "DHCP-server";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ field = "Nameserver";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ field = "WINS-server";
+ break;
+
+ default:
+ field = 0;
+ }
- case ISAKMP_CFG_ATTR_SUPPORTED_ATTRIBUTES:
- break;
+ switch (attr->type) {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ sa = conf_get_address(id_string, field);
+ if (!sa) {
+ LOG_DBG((LOG_NEGOTIATION, 10, "cfg_responder_send_ATTR: "
+ "attribute not found: %s", field));
+ attr->length = 0;
+ break;
+ }
+ if (sa->sa_family != family) {
+ log_print("cfg_responder_send_ATTR: attribute %s - expected %s "
+ "got %s data", field,
+ (family == AF_INET ? "IPv4" : "IPv6"),
+ (sa->sa_family == AF_INET ? "IPv4" : "IPv6"));
+ free(sa);
+ attr->length = 0;
+ break;
+ }
+ /* Temporary limit length for the _SUBNET types. */
+ if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET)
+ attr->length = 4;
+ else if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET)
+ attr->length = 16;
+
+ memcpy(*attrp + off + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata(sa),
+ attr->length);
+ free(sa);
+
+ /* _SUBNET types need some extra work. */
+ if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET) {
+ sa = conf_get_address(id_string, "Netmask");
+ if (!sa) {
+ LOG_DBG((LOG_NEGOTIATION, 10, "cfg_responder_send_ATTR: "
+ "attribute not found: Netmask"));
+ attr->length = 0;
+ break;
+ }
+ if (sa->sa_family != AF_INET) {
+ log_print("cfg_responder_send_ATTR: attribute Netmask - "
+ "expected IPv4 got IPv6 data");
+ free(sa);
+ attr->length = 0;
+ break;
+ }
+ memcpy(*attrp + off + ISAKMP_ATTR_VALUE_OFF + attr->length,
+ sockaddr_addrdata(sa), attr->length);
+ attr->length = 8;
+ free(sa);
+ } else if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET) {
+ int prefix = conf_get_num(id_string, "Prefix", -1);
+
+ if (prefix == -1) {
+ log_print("cfg_responder_send_ATTR: "
+ "attribute not found: Prefix");
+ attr->length = 0;
+ break;
+ } else if (prefix < -1 || prefix > 128) {
+ log_print("cfg_responder_send_ATTR: attribute Prefix - "
+ "invalid value %d", prefix);
+ attr->length = 0;
+ break;
+ }
+ *(*attrp + off + ISAKMP_ATTR_VALUE_OFF + 16) = (u_int8_t) prefix;
+ attr->length = 17;
+ }
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
+ value = conf_get_num(id_string, "Lifetime", 1200);
+ encode_32(*attrp + off + ISAKMP_ATTR_VALUE_OFF, value);
+ break;
+
+ case ISAKMP_CFG_ATTR_APPLICATION_VERSION:
+ /* XXX So far no version identifier of isakmpd here. */
+ break;
+
+ case ISAKMP_CFG_ATTR_SUPPORTED_ATTRIBUTES:
+ break;
+
+ default:
+ break;
+ }
- default:
- break;
+ SET_ISAKMP_ATTR_TYPE(*attrp + off, attr->type);
+ SET_ISAKMP_ATTR_LENGTH_VALUE(*attrp + off, attr->length);
+ off += ISAKMP_ATTR_VALUE_OFF + attr->length;
}
- SET_ISAKMP_ATTR_TYPE (*attrp + off, attr->type);
- SET_ISAKMP_ATTR_LENGTH_VALUE (*attrp + off, attr->length);
- off += ISAKMP_ATTR_VALUE_OFF + attr->length;
- }
-
- return 0;
+ return 0;
}
diff --git a/sbin/isakmpd/isakmp_cfg.h b/sbin/isakmpd/isakmp_cfg.h
index cdad6e2507f..58f9e00f235 100644
--- a/sbin/isakmpd/isakmp_cfg.h
+++ b/sbin/isakmpd/isakmp_cfg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isakmp_cfg.h,v 1.3 2003/06/03 14:28:16 ho Exp $ */
+/* $OpenBSD: isakmp_cfg.h,v 1.4 2004/04/15 18:39:26 deraadt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist. All rights reserved.
@@ -35,19 +35,19 @@
#include <sys/queue.h>
struct isakmp_cfg_attr {
- LIST_ENTRY (isakmp_cfg_attr) link;
- u_int16_t type;
- u_int8_t attr_used;
- /* 8 bits just to be well-aligned. */
- u_int8_t ignore;
- size_t length;
- void *value;
+ LIST_ENTRY(isakmp_cfg_attr) link;
+ u_int16_t type;
+ u_int8_t attr_used;
+ /* 8 bits just to be well-aligned. */
+ u_int8_t ignore;
+ size_t length;
+ void *value;
};
struct message;
-extern int (*isakmp_cfg_initiator[]) (struct message *);
-extern int (*isakmp_cfg_responder[]) (struct message *);
-extern int16_t script_transaction[];
+extern int (*isakmp_cfg_initiator[]) (struct message *);
+extern int (*isakmp_cfg_responder[]) (struct message *);
+extern int16_t script_transaction[];
-#endif /* _ISAKMP_CFG_H_ */
+#endif /* _ISAKMP_CFG_H_ */
diff --git a/sbin/isakmpd/isakmp_doi.c b/sbin/isakmpd/isakmp_doi.c
index 0aab1c83712..1ef681f0942 100644
--- a/sbin/isakmpd/isakmp_doi.c
+++ b/sbin/isakmpd/isakmp_doi.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: isakmp_doi.c,v 1.18 2004/03/10 23:08:49 hshoexer Exp $ */
-/* $EOM: isakmp_doi.c,v 1.42 2000/09/12 16:29:41 ho Exp $ */
+/* $OpenBSD: isakmp_doi.c,v 1.19 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: isakmp_doi.c,v 1.42 2000/09/12 16:29:41 ho Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -50,219 +50,215 @@
#include "util.h"
#ifdef USE_DEBUG
-static int isakmp_debug_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
+static int isakmp_debug_attribute(u_int16_t, u_int8_t *, u_int16_t, void *);
#endif
-static void isakmp_finalize_exchange (struct message *);
-static struct keystate *isakmp_get_keystate (struct message *);
-static int isakmp_initiator (struct message *);
-static int isakmp_responder (struct message *);
-static void isakmp_setup_situation (u_int8_t *);
-static size_t isakmp_situation_size (void);
-static u_int8_t isakmp_spi_size (u_int8_t);
-static int isakmp_validate_attribute (u_int16_t, u_int8_t *, u_int16_t,
- void *);
-static int isakmp_validate_exchange (u_int8_t);
-static int isakmp_validate_id_information (u_int8_t, u_int8_t *, u_int8_t *,
- size_t, struct exchange *);
-static int isakmp_validate_key_information (u_int8_t *, size_t);
-static int isakmp_validate_notification (u_int16_t);
-static int isakmp_validate_proto (u_int8_t);
-static int isakmp_validate_situation (u_int8_t *, size_t *, size_t);
-static int isakmp_validate_transform_id (u_int8_t, u_int8_t);
+static void isakmp_finalize_exchange(struct message *);
+static struct keystate *isakmp_get_keystate(struct message *);
+static int isakmp_initiator(struct message *);
+static int isakmp_responder(struct message *);
+static void isakmp_setup_situation(u_int8_t *);
+static size_t isakmp_situation_size(void);
+static u_int8_t isakmp_spi_size(u_int8_t);
+static int
+isakmp_validate_attribute(u_int16_t, u_int8_t *, u_int16_t,
+ void *);
+static int isakmp_validate_exchange(u_int8_t);
+static int
+isakmp_validate_id_information(u_int8_t, u_int8_t *, u_int8_t *,
+ size_t, struct exchange *);
+static int isakmp_validate_key_information(u_int8_t *, size_t);
+static int isakmp_validate_notification(u_int16_t);
+static int isakmp_validate_proto(u_int8_t);
+static int isakmp_validate_situation(u_int8_t *, size_t *, size_t);
+static int isakmp_validate_transform_id(u_int8_t, u_int8_t);
static struct doi isakmp_doi = {
- { 0 }, ISAKMP_DOI_ISAKMP, 0, 0, 0,
+ {0}, ISAKMP_DOI_ISAKMP, 0, 0, 0,
#ifdef USE_DEBUG
- isakmp_debug_attribute,
+ isakmp_debug_attribute,
#endif
- 0, /* delete_spi not needed. */
- 0, /* exchange_script not needed. */
- isakmp_finalize_exchange,
- 0, /* free_exchange_data not needed. */
- 0, /* free_proto_data not needed. */
- 0, /* free_sa_data not needed. */
- isakmp_get_keystate,
- 0, /* get_spi not needed. */
- 0, /* handle_leftover_payload not needed. */
- 0, /* informational_post_hook not needed. */
- 0, /* informational_pre_hook not needed. */
- 0, /* XXX need maybe be filled-in. */
- 0, /* proto_init not needed. */
- isakmp_setup_situation,
- isakmp_situation_size,
- isakmp_spi_size,
- isakmp_validate_attribute,
- isakmp_validate_exchange,
- isakmp_validate_id_information,
- isakmp_validate_key_information,
- isakmp_validate_notification,
- isakmp_validate_proto,
- isakmp_validate_situation,
- isakmp_validate_transform_id,
- isakmp_initiator,
- isakmp_responder,
+ 0, /* delete_spi not needed. */
+ 0, /* exchange_script not needed. */
+ isakmp_finalize_exchange,
+ 0, /* free_exchange_data not needed. */
+ 0, /* free_proto_data not needed. */
+ 0, /* free_sa_data not needed. */
+ isakmp_get_keystate,
+ 0, /* get_spi not needed. */
+ 0, /* handle_leftover_payload not needed. */
+ 0, /* informational_post_hook not needed. */
+ 0, /* informational_pre_hook not needed. */
+ 0, /* XXX need maybe be filled-in. */
+ 0, /* proto_init not needed. */
+ isakmp_setup_situation,
+ isakmp_situation_size,
+ isakmp_spi_size,
+ isakmp_validate_attribute,
+ isakmp_validate_exchange,
+ isakmp_validate_id_information,
+ isakmp_validate_key_information,
+ isakmp_validate_notification,
+ isakmp_validate_proto,
+ isakmp_validate_situation,
+ isakmp_validate_transform_id,
+ isakmp_initiator,
+ isakmp_responder,
#ifdef USE_DEBUG
- ipsec_decode_ids
+ ipsec_decode_ids
#endif
};
/* Requires doi_init to already have been called. */
void
-isakmp_doi_init (void)
+isakmp_doi_init(void)
{
- doi_register (&isakmp_doi);
+ doi_register(&isakmp_doi);
}
#ifdef USE_DEBUG
int
-isakmp_debug_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vmsg)
+isakmp_debug_attribute(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *vmsg)
{
- /* XXX Not implemented yet. */
- return 0;
+ /* XXX Not implemented yet. */
+ return 0;
}
-#endif /* USE_DEBUG */
+#endif /* USE_DEBUG */
static void
-isakmp_finalize_exchange (struct message *msg)
+isakmp_finalize_exchange(struct message * msg)
{
}
static struct keystate *
-isakmp_get_keystate (struct message *msg)
+isakmp_get_keystate(struct message * msg)
{
- return 0;
+ return 0;
}
static void
-isakmp_setup_situation (u_int8_t *buf)
+isakmp_setup_situation(u_int8_t * buf)
{
- /* Nothing to do. */
+ /* Nothing to do. */
}
static size_t
-isakmp_situation_size (void)
+isakmp_situation_size(void)
{
- return 0;
+ return 0;
}
static u_int8_t
-isakmp_spi_size (u_int8_t proto)
+isakmp_spi_size(u_int8_t proto)
{
- /* One way to specify ISAKMP SPIs is to say they're zero-sized. */
- return 0;
+ /* One way to specify ISAKMP SPIs is to say they're zero-sized. */
+ return 0;
}
static int
-isakmp_validate_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vmsg)
+isakmp_validate_attribute(u_int16_t type, u_int8_t *value, u_int16_t len,
+ void *vmsg)
{
- /* XXX Not implemented yet. */
- return -1;
+ /* XXX Not implemented yet. */
+ return -1;
}
static int
-isakmp_validate_exchange (u_int8_t exch)
+isakmp_validate_exchange(u_int8_t exch)
{
- /* If we get here the exchange is invalid. */
- return -1;
+ /* If we get here the exchange is invalid. */
+ return -1;
}
static int
-isakmp_validate_id_information (u_int8_t type, u_int8_t *extra, u_int8_t *buf,
- size_t sz, struct exchange *exchange)
+isakmp_validate_id_information(u_int8_t type, u_int8_t *extra, u_int8_t *buf,
+ size_t sz, struct exchange *exchange)
{
- return zero_test (extra, ISAKMP_ID_DOI_DATA_LEN);
+ return zero_test(extra, ISAKMP_ID_DOI_DATA_LEN);
}
static int
-isakmp_validate_key_information (u_int8_t *buf, size_t sz)
+isakmp_validate_key_information(u_int8_t *buf, size_t sz)
{
- /* Nothing to do. */
- return 0;
+ /* Nothing to do. */
+ return 0;
}
static int
-isakmp_validate_notification (u_int16_t type)
+isakmp_validate_notification(u_int16_t type)
{
- /* If we get here the message type is invalid. */
- return -1;
+ /* If we get here the message type is invalid. */
+ return -1;
}
static int
-isakmp_validate_proto (u_int8_t proto)
+isakmp_validate_proto(u_int8_t proto)
{
- /* If we get here the protocol is invalid. */
- return -1;
+ /* If we get here the protocol is invalid. */
+ return -1;
}
static int
-isakmp_validate_situation (u_int8_t *buf, size_t *sz, size_t len)
+isakmp_validate_situation(u_int8_t *buf, size_t *sz, size_t len)
{
- /* There are no situations in the ISAKMP DOI. */
- *sz = 0;
- return 0;
+ /* There are no situations in the ISAKMP DOI. */
+ *sz = 0;
+ return 0;
}
static int
-isakmp_validate_transform_id (u_int8_t proto, u_int8_t transform_id)
+isakmp_validate_transform_id(u_int8_t proto, u_int8_t transform_id)
{
- /* XXX Not yet implemented. */
- return -1;
+ /* XXX Not yet implemented. */
+ return -1;
}
static int
-isakmp_initiator (struct message *msg)
+isakmp_initiator(struct message *msg)
{
- if (msg->exchange->type != ISAKMP_EXCH_INFO)
- {
- log_print ("isakmp_initiator: unsupported exchange type %d in phase %d",
- msg->exchange->type, msg->exchange->phase);
- return -1;
- }
-
- return message_send_info (msg);
+ if (msg->exchange->type != ISAKMP_EXCH_INFO) {
+ log_print("isakmp_initiator: unsupported exchange type %d in phase %d",
+ msg->exchange->type, msg->exchange->phase);
+ return -1;
+ }
+ return message_send_info(msg);
}
static int
-isakmp_responder (struct message *msg)
+isakmp_responder(struct message * msg)
{
- struct payload *p;
+ struct payload *p;
- switch (msg->exchange->type)
- {
- case ISAKMP_EXCH_INFO:
- for (p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p;
- p = TAILQ_NEXT (p, link))
- {
- LOG_DBG ((LOG_EXCHANGE, 10,
- "isakmp_responder: got NOTIFY of type %s, ignoring",
- constant_name (isakmp_notify_cst,
- GET_ISAKMP_NOTIFY_MSG_TYPE (p->p))));
- p->flags |= PL_MARK;
- }
+ switch (msg->exchange->type) {
+ case ISAKMP_EXCH_INFO:
+ for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p;
+ p = TAILQ_NEXT(p, link)) {
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "isakmp_responder: got NOTIFY of type %s, ignoring",
+ constant_name(isakmp_notify_cst,
+ GET_ISAKMP_NOTIFY_MSG_TYPE(p->p))));
+ p->flags |= PL_MARK;
+ }
- for (p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_DELETE]); p;
- p = TAILQ_NEXT (p, link))
- {
- LOG_DBG ((LOG_EXCHANGE, 10,
- "isakmp_responder: got DELETE, ignoring"));
- p->flags |= PL_MARK;
- }
- return 0;
+ for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE]); p;
+ p = TAILQ_NEXT(p, link)) {
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "isakmp_responder: got DELETE, ignoring"));
+ p->flags |= PL_MARK;
+ }
+ return 0;
#ifdef USE_ISAKMP_CFG
- case ISAKMP_EXCH_TRANSACTION:
- /* return 0 isakmp_cfg_responder (msg); */
+ case ISAKMP_EXCH_TRANSACTION:
+ /* return 0 isakmp_cfg_responder (msg); */
#endif /* USE_ISAKMP_CFG */
- default:
- /* XXX So far we don't accept any proposals. */
- if (TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]))
- {
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- return -1;
+ default:
+ /* XXX So far we don't accept any proposals. */
+ if (TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])) {
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
diff --git a/sbin/isakmpd/isakmp_doi.h b/sbin/isakmpd/isakmp_doi.h
index c0bb521013b..13a485b9107 100644
--- a/sbin/isakmpd/isakmp_doi.h
+++ b/sbin/isakmpd/isakmp_doi.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: isakmp_doi.h,v 1.4 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: isakmp_doi.h,v 1.1 1998/07/07 23:20:29 niklas Exp $ */
+/* $OpenBSD: isakmp_doi.h,v 1.5 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: isakmp_doi.h,v 1.1 1998/07/07 23:20:29 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -32,6 +32,6 @@
#ifndef _ISAKMP_DOI_H_
#define _ISAKMP_DOI_H_
-extern void isakmp_doi_init (void);
+extern void isakmp_doi_init(void);
-#endif /* _ISAKMP_DOI_H_ */
+#endif /* _ISAKMP_DOI_H_ */
diff --git a/sbin/isakmpd/isakmpd.c b/sbin/isakmpd/isakmpd.c
index 3130491da1e..bdb61b733fd 100644
--- a/sbin/isakmpd/isakmpd.c
+++ b/sbin/isakmpd/isakmpd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: isakmpd.c,v 1.60 2004/04/08 10:05:54 hshoexer Exp $ */
-/* $EOM: isakmpd.c,v 1.54 2000/10/05 09:28:22 niklas Exp $ */
+/* $OpenBSD: isakmpd.c,v 1.61 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: isakmpd.c,v 1.54 2000/10/05 09:28:22 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -64,13 +64,13 @@
#include "policy.h"
#endif
-static void usage (void);
+static void usage(void);
/*
* Set if -d is given, currently just for running in the foreground and log
* to stderr instead of syslog.
*/
-int debug = 0;
+int debug = 0;
/*
* If we receive a SIGHUP signal, this flag gets set to show we need to
@@ -84,7 +84,7 @@ volatile sig_atomic_t sighupped = 0;
* via the -R parameter.
*/
volatile sig_atomic_t sigusr1ed = 0;
-static char *report_file = "/var/run/isakmpd.report";
+static char *report_file = "/var/run/isakmpd.report";
/*
* If we receive a USR2 signal, this flag gets set to show we need to
@@ -99,442 +99,419 @@ volatile sig_atomic_t sigusr2ed = 0;
* Also on recv of an INT signal (Ctrl-C out of an '-d' session, typically).
*/
volatile sig_atomic_t sigtermed = 0;
-void daemon_shutdown_now (int);
+void daemon_shutdown_now(int);
/* The default path of the PID file. */
-static char *pid_file = "/var/run/isakmpd.pid";
+static char *pid_file = "/var/run/isakmpd.pid";
#ifdef USE_DEBUG
/* The path of the IKE packet capture log file. */
-static char *pcap_file = 0;
+static char *pcap_file = 0;
#endif
static void
-usage (void)
+usage(void)
{
- fprintf (stderr,
- "usage: %s [-4] [-6] [-c config-file] [-d] [-D class=level]\n"
- " [-f fifo] [-i pid-file] [-n] [-p listen-port]\n"
- " [-P local-port] [-L] [-l packetlog-file] [-r seed]\n"
- " [-R report-file] [-v]\n",
- sysdep_progname ());
- exit (1);
+ fprintf(stderr,
+ "usage: %s [-4] [-6] [-c config-file] [-d] [-D class=level]\n"
+ " [-f fifo] [-i pid-file] [-n] [-p listen-port]\n"
+ " [-P local-port] [-L] [-l packetlog-file] [-r seed]\n"
+ " [-R report-file] [-v]\n",
+ sysdep_progname());
+ exit(1);
}
static void
-parse_args (int argc, char *argv[])
+parse_args(int argc, char *argv[])
{
- int ch;
- char *ep;
+ int ch;
+ char *ep;
#ifdef USE_DEBUG
- int cls, level;
- int do_packetlog = 0;
+ int cls, level;
+ int do_packetlog = 0;
#endif
- while ((ch = getopt (argc, argv, "46c:dD:f:i:np:P:Ll:r:R:v")) != -1) {
- switch (ch) {
- case '4':
- bind_family |= BIND_FAMILY_INET4;
- break;
+ while ((ch = getopt(argc, argv, "46c:dD:f:i:np:P:Ll:r:R:v")) != -1) {
+ switch (ch) {
+ case '4':
+ bind_family |= BIND_FAMILY_INET4;
+ break;
- case '6':
- bind_family |= BIND_FAMILY_INET6;
- break;
+ case '6':
+ bind_family |= BIND_FAMILY_INET6;
+ break;
- case 'c':
- conf_path = optarg;
- break;
+ case 'c':
+ conf_path = optarg;
+ break;
- case 'd':
- debug++;
- break;
+ case 'd':
+ debug++;
+ break;
#ifdef USE_DEBUG
- case 'D':
- if (sscanf (optarg, "%d=%d", &cls, &level) != 2)
- {
- if (sscanf (optarg, "A=%d", &level) == 1)
- {
- for (cls = 0; cls < LOG_ENDCLASS; cls++)
- log_debug_cmd (cls, level);
- }
- else
- log_print ("parse_args: -D argument unparseable: %s", optarg);
- }
- else
- log_debug_cmd (cls, level);
- break;
-#endif /* USE_DEBUG */
-
- case 'f':
- ui_fifo = optarg;
- break;
-
- case 'i':
- pid_file = optarg;
- break;
-
- case 'n':
- app_none++;
- break;
-
- case 'p':
- udp_default_port = optarg;
- break;
-
- case 'P':
- udp_bind_port = optarg;
- break;
+ case 'D':
+ if (sscanf(optarg, "%d=%d", &cls, &level) != 2) {
+ if (sscanf(optarg, "A=%d", &level) == 1) {
+ for (cls = 0; cls < LOG_ENDCLASS; cls++)
+ log_debug_cmd(cls, level);
+ } else
+ log_print("parse_args: -D argument unparseable: %s", optarg);
+ } else
+ log_debug_cmd(cls, level);
+ break;
+#endif /* USE_DEBUG */
+
+ case 'f':
+ ui_fifo = optarg;
+ break;
+
+ case 'i':
+ pid_file = optarg;
+ break;
+
+ case 'n':
+ app_none++;
+ break;
+
+ case 'p':
+ udp_default_port = optarg;
+ break;
+
+ case 'P':
+ udp_bind_port = optarg;
+ break;
#ifdef USE_DEBUG
- case 'l':
- pcap_file = optarg;
- /* Fallthrough intended. */
-
- case 'L':
- do_packetlog++;
- break;
-#endif /* USE_DEBUG */
-
- case 'r':
- seed = strtoul (optarg, &ep, 0);
- srandom (seed);
- if (*ep != '\0')
- log_fatal ("parse_args: invalid numeric arg to -r (%s)", optarg);
- regrand = 1;
- break;
-
- case 'R':
- report_file = optarg;
- break;
-
- case 'v':
- verbose_logging = 1;
- break;
-
- case '?':
- default:
- usage ();
- }
- }
- argc -= optind;
- argv += optind;
+ case 'l':
+ pcap_file = optarg;
+ /* Fallthrough intended. */
+
+ case 'L':
+ do_packetlog++;
+ break;
+#endif /* USE_DEBUG */
+
+ case 'r':
+ seed = strtoul(optarg, &ep, 0);
+ srandom(seed);
+ if (*ep != '\0')
+ log_fatal("parse_args: invalid numeric arg to -r (%s)", optarg);
+ regrand = 1;
+ break;
+
+ case 'R':
+ report_file = optarg;
+ break;
+
+ case 'v':
+ verbose_logging = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
#ifdef USE_DEBUG
- if (do_packetlog && !pcap_file)
- pcap_file = PCAP_FILE_DEFAULT;
+ if (do_packetlog && !pcap_file)
+ pcap_file = PCAP_FILE_DEFAULT;
#endif
}
static void
-sighup (int sig)
+sighup(int sig)
{
- sighupped = 1;
+ sighupped = 1;
}
/* Report internal state on SIGUSR1. */
static void
-report (void)
+report(void)
{
- FILE *rfp, *old;
- mode_t old_umask;
-
- old_umask = umask (S_IRWXG | S_IRWXO);
- rfp = monitor_fopen (report_file, "w");
- umask (old_umask);
-
- if (!rfp)
- {
- log_error ("report: fopen (\"%s\", \"w\") failed", report_file);
- return;
- }
-
- /* Divert the log channel to the report file during the report. */
- old = log_current ();
- log_to (rfp);
- ui_report ("r");
- log_to (old);
- fclose (rfp);
-
- sigusr1ed = 0;
+ FILE *rfp, *old;
+ mode_t old_umask;
+
+ old_umask = umask(S_IRWXG | S_IRWXO);
+ rfp = monitor_fopen(report_file, "w");
+ umask(old_umask);
+
+ if (!rfp) {
+ log_error("report: fopen (\"%s\", \"w\") failed", report_file);
+ return;
+ }
+ /* Divert the log channel to the report file during the report. */
+ old = log_current();
+ log_to(rfp);
+ ui_report("r");
+ log_to(old);
+ fclose(rfp);
+
+ sigusr1ed = 0;
}
static void
-sigusr1 (int sig)
+sigusr1(int sig)
{
- sigusr1ed = 1;
+ sigusr1ed = 1;
}
/* Rehash soft expiration timers on SIGUSR2. */
static void
-rehash_timers (void)
+rehash_timers(void)
{
#if 0
- /* XXX - not yet */
- log_print ("SIGUSR2 received, rehashing soft expiration timers.");
+ /* XXX - not yet */
+ log_print("SIGUSR2 received, rehashing soft expiration timers.");
- timer_rehash_timers ();
+ timer_rehash_timers();
#endif
- sigusr2ed = 0;
+ sigusr2ed = 0;
}
static void
-sigusr2 (int sig)
+sigusr2(int sig)
{
- sigusr2ed = 1;
+ sigusr2ed = 1;
}
static int
-phase2_sa_check (struct sa *sa, void *arg)
+phase2_sa_check(struct sa * sa, void *arg)
{
- return sa->phase == 2;
+ return sa->phase == 2;
}
static void
-daemon_shutdown (void)
+daemon_shutdown(void)
{
- /* Perform a (protocol-wise) clean shutdown of the daemon. */
- struct sa *sa;
-
- if (sigtermed == 1)
- {
- log_print ("isakmpd: shutting down...");
-
- /* Delete all active phase 2 SAs. */
- while ((sa = sa_find (phase2_sa_check, NULL)))
- {
- /* Each DELETE is another (outgoing) message. */
- sa_delete (sa, 1);
+ /* Perform a (protocol-wise) clean shutdown of the daemon. */
+ struct sa *sa;
+
+ if (sigtermed == 1) {
+ log_print("isakmpd: shutting down...");
+
+ /* Delete all active phase 2 SAs. */
+ while ((sa = sa_find(phase2_sa_check, NULL))) {
+ /* Each DELETE is another (outgoing) message. */
+ sa_delete(sa, 1);
+ }
+ sigtermed++;
}
- sigtermed++;
- }
-
- if (transport_prio_sendqs_empty ())
- {
- /*
- * When the prioritized transport sendq:s are empty, i.e all
- * the DELETE notifications have been sent, we can shutdown.
- */
-
+ if (transport_prio_sendqs_empty()) {
+ /*
+ * When the prioritized transport sendq:s are empty, i.e all
+ * the DELETE notifications have been sent, we can shutdown.
+ */
+
#ifdef USE_DEBUG
- log_packet_stop ();
+ log_packet_stop();
#endif
- /* Remove FIFO and pid files. */
- unlink (ui_fifo);
- unlink (pid_file);
- log_print ("isakmpd: exit");
- exit (0);
- }
+ /* Remove FIFO and pid files. */
+ unlink(ui_fifo);
+ unlink(pid_file);
+ log_print("isakmpd: exit");
+ exit(0);
+ }
}
/* Called on SIGTERM, SIGINT or by ui_shutdown_daemon(). */
void
-daemon_shutdown_now (int sig)
+daemon_shutdown_now(int sig)
{
- sigtermed = 1;
+ sigtermed = 1;
}
/* Write pid file. */
static void
-write_pid_file (void)
+write_pid_file(void)
{
- FILE *fp;
-
- /* Ignore errors. This will fail with USE_PRIVSEP. */
- unlink (pid_file);
-
- fp = monitor_fopen (pid_file, "w");
- if (fp != NULL)
- {
- if (fprintf (fp, "%ld\n", (long) getpid ()) < 0)
- log_error ("write_pid_file: failed to write PID to \"%.100s\"",
- pid_file);
- fclose (fp);
- }
- else
- log_fatal ("write_pid_file: fopen (\"%.100s\", \"w\") failed", pid_file);
+ FILE *fp;
+
+ /* Ignore errors. This will fail with USE_PRIVSEP. */
+ unlink(pid_file);
+
+ fp = monitor_fopen(pid_file, "w");
+ if (fp != NULL) {
+ if (fprintf(fp, "%ld\n", (long) getpid()) < 0)
+ log_error("write_pid_file: failed to write PID to \"%.100s\"",
+ pid_file);
+ fclose(fp);
+ } else
+ log_fatal("write_pid_file: fopen (\"%.100s\", \"w\") failed", pid_file);
}
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- fd_set *rfds, *wfds;
- int n, m;
- size_t mask_size;
- struct timeval tv, *timeout;
+ fd_set *rfds, *wfds;
+ int n, m;
+ size_t mask_size;
+ struct timeval tv, *timeout;
#if defined (HAVE_CLOSEFROM) && (!defined (OpenBSD) || (OpenBSD >= 200405))
- closefrom (STDERR_FILENO + 1);
+ closefrom(STDERR_FILENO + 1);
#else
- m = getdtablesize ();
- for (n = STDERR_FILENO + 1; n < m; n++)
- (void)close (n);
+ m = getdtablesize();
+ for (n = STDERR_FILENO + 1; n < m; n++)
+ (void) close(n);
#endif
- /* Make sure init() won't alloc fd 0, 1 or 2, as daemon() will close them. */
- for (n = 0; n <= 2; n++)
- if (fcntl (n, F_GETFL, 0) == -1 && errno == EBADF)
- (void)open ("/dev/null", n ? O_WRONLY : O_RDONLY, 0);
-
- for (n = 1; n < _NSIG; n++)
- signal (n, SIG_DFL);
-
- /* Log cmd line parsing and initialization errors to stderr. */
- log_to (stderr);
- parse_args (argc, argv);
- log_init (debug);
-
- /*
- * Do a clean daemon shutdown on TERM/INT. These signals must be
- * initialized before monitor_init(). INT is only used with '-d'.
- */
- signal (SIGTERM, daemon_shutdown_now);
- if (debug == 1) /* i.e '-dd' will skip this. */
- signal (SIGINT, daemon_shutdown_now);
-
- /* Daemonize before forking unpriv'ed child */
- if (!debug)
- if (daemon (0, 0))
- log_fatal ("main: daemon (0, 0) failed");
-
- /* Set timezone before priv'separation */
- tzset();
+ /*
+ * Make sure init() won't alloc fd 0, 1 or 2, as daemon() will close
+ * them.
+ */
+ for (n = 0; n <= 2; n++)
+ if (fcntl(n, F_GETFL, 0) == -1 && errno == EBADF)
+ (void) open("/dev/null", n ? O_WRONLY : O_RDONLY, 0);
+
+ for (n = 1; n < _NSIG; n++)
+ signal(n, SIG_DFL);
+
+ /* Log cmd line parsing and initialization errors to stderr. */
+ log_to(stderr);
+ parse_args(argc, argv);
+ log_init(debug);
+
+ /*
+ * Do a clean daemon shutdown on TERM/INT. These signals must be
+ * initialized before monitor_init(). INT is only used with '-d'.
+ */
+ signal(SIGTERM, daemon_shutdown_now);
+ if (debug == 1) /* i.e '-dd' will skip this. */
+ signal(SIGINT, daemon_shutdown_now);
+
+ /* Daemonize before forking unpriv'ed child */
+ if (!debug)
+ if (daemon(0, 0))
+ log_fatal("main: daemon (0, 0) failed");
+
+ /* Set timezone before priv'separation */
+ tzset();
#if defined (USE_PRIVSEP)
- if (monitor_init ())
- {
- /* The parent, with privileges enters infinite monitor loop. */
- monitor_loop (debug);
- exit (0); /* Never reached. */
- }
-
- /* Child process only from this point on, no privileges left. */
+ if (monitor_init()) {
+ /* The parent, with privileges enters infinite monitor loop. */
+ monitor_loop(debug);
+ exit(0); /* Never reached. */
+ }
+ /* Child process only from this point on, no privileges left. */
#endif
- init ();
+ init();
- write_pid_file ();
+ write_pid_file();
- /* Reinitialize on HUP reception. */
- signal (SIGHUP, sighup);
+ /* Reinitialize on HUP reception. */
+ signal(SIGHUP, sighup);
- /* Report state on USR1 reception. */
- signal (SIGUSR1, sigusr1);
+ /* Report state on USR1 reception. */
+ signal(SIGUSR1, sigusr1);
- /* Rehash soft expiration timers on USR2 reception. */
- signal (SIGUSR2, sigusr2);
+ /* Rehash soft expiration timers on USR2 reception. */
+ signal(SIGUSR2, sigusr2);
#if defined (USE_DEBUG)
- /* If we wanted IKE packet capture to file, initialize it now. */
- if (pcap_file != 0)
- log_packet_init (pcap_file);
+ /* If we wanted IKE packet capture to file, initialize it now. */
+ if (pcap_file != 0)
+ log_packet_init(pcap_file);
#endif
- /* Allocate the file descriptor sets just big enough. */
- n = getdtablesize ();
- mask_size = howmany (n, NFDBITS) * sizeof (fd_mask);
- rfds = (fd_set *)malloc (mask_size);
- if (!rfds)
- log_fatal ("main: malloc (%lu) failed", (unsigned long)mask_size);
- wfds = (fd_set *)malloc (mask_size);
- if (!wfds)
- log_fatal ("main: malloc (%lu) failed", (unsigned long)mask_size);
+ /* Allocate the file descriptor sets just big enough. */
+ n = getdtablesize();
+ mask_size = howmany(n, NFDBITS) * sizeof(fd_mask);
+ rfds = (fd_set *) malloc(mask_size);
+ if (!rfds)
+ log_fatal("main: malloc (%lu) failed", (unsigned long) mask_size);
+ wfds = (fd_set *) malloc(mask_size);
+ if (!wfds)
+ log_fatal("main: malloc (%lu) failed", (unsigned long) mask_size);
#if defined (USE_PRIVSEP)
- monitor_init_done();
+ monitor_init_done();
#endif
- while (1)
- {
- /* If someone has sent SIGHUP to us, reconfigure. */
- if (sighupped)
- {
- log_print ("SIGHUP received");
- reinit ();
- sighupped = 0;
- }
-
- /* and if someone sent SIGUSR1, do a state report. */
- if (sigusr1ed)
- {
- log_print ("SIGUSR1 received");
- report ();
- }
-
- /* and if someone sent SIGUSR2, do a timer rehash. */
- if (sigusr2ed)
- {
- log_print ("SIGUSR2 received");
- rehash_timers ();
- }
-
- /*
- * and if someone set 'sigtermed' (SIGTERM, SIGINT or via the UI),
- * this indicates we should start a controlled shutdown of the daemon.
- *
- * Note: Since _one_ message is sent per iteration of this enclosing
- * while-loop, and we want to send a number of DELETE notifications,
- * we must loop atleast this number of times. The daemon_shutdown()
- * function starts by queueing the DELETEs, all other calls just
- * increments the 'sigtermed' variable until it reaches a "safe"
- * value, and the daemon exits.
- */
- if (sigtermed)
- daemon_shutdown ();
-
- /* Setup the descriptors to look for incoming messages at. */
- memset (rfds, 0, mask_size);
- n = transport_fd_set (rfds);
- FD_SET (ui_socket, rfds);
- if (ui_socket + 1 > n)
- n = ui_socket + 1;
-
- /*
- * XXX Some day we might want to deal with an abstract application
- * class instead, with many instantiations possible.
- */
- if (!app_none && app_socket >= 0)
- {
- FD_SET (app_socket, rfds);
- if (app_socket + 1 > n)
- n = app_socket + 1;
- }
-
- /* Setup the descriptors that have pending messages to send. */
- memset (wfds, 0, mask_size);
- m = transport_pending_wfd_set (wfds);
- if (m > n)
- n = m;
-
- /* Find out when the next timed event is. */
- timeout = &tv;
- timer_next_event (&timeout);
-
- n = select (n, rfds, wfds, 0, timeout);
- if (n == -1)
- {
- if (errno != EINTR)
- {
- log_error ("main: select");
-
- /*
- * In order to give the unexpected error condition time to
- * resolve without letting this process eat up all available CPU
- * we sleep for a short while.
- */
- sleep (1);
- }
- }
- else if (n)
- {
- transport_handle_messages (rfds);
- transport_send_messages (wfds);
- if (FD_ISSET (ui_socket, rfds))
- ui_handler ();
- if (!app_none && app_socket >= 0 && FD_ISSET (app_socket, rfds))
- app_handler ();
+ while (1) {
+ /* If someone has sent SIGHUP to us, reconfigure. */
+ if (sighupped) {
+ log_print("SIGHUP received");
+ reinit();
+ sighupped = 0;
+ }
+ /* and if someone sent SIGUSR1, do a state report. */
+ if (sigusr1ed) {
+ log_print("SIGUSR1 received");
+ report();
+ }
+ /* and if someone sent SIGUSR2, do a timer rehash. */
+ if (sigusr2ed) {
+ log_print("SIGUSR2 received");
+ rehash_timers();
+ }
+ /*
+ * and if someone set 'sigtermed' (SIGTERM, SIGINT or via the UI),
+ * this indicates we should start a controlled shutdown of the daemon.
+ *
+ * Note: Since _one_ message is sent per iteration of this enclosing
+ * while-loop, and we want to send a number of DELETE notifications,
+ * we must loop atleast this number of times. The daemon_shutdown()
+ * function starts by queueing the DELETEs, all other calls just
+ * increments the 'sigtermed' variable until it reaches a "safe"
+ * value, and the daemon exits.
+ */
+ if (sigtermed)
+ daemon_shutdown();
+
+ /* Setup the descriptors to look for incoming messages at. */
+ memset(rfds, 0, mask_size);
+ n = transport_fd_set(rfds);
+ FD_SET(ui_socket, rfds);
+ if (ui_socket + 1 > n)
+ n = ui_socket + 1;
+
+ /*
+ * XXX Some day we might want to deal with an abstract application
+ * class instead, with many instantiations possible.
+ */
+ if (!app_none && app_socket >= 0) {
+ FD_SET(app_socket, rfds);
+ if (app_socket + 1 > n)
+ n = app_socket + 1;
+ }
+ /* Setup the descriptors that have pending messages to send. */
+ memset(wfds, 0, mask_size);
+ m = transport_pending_wfd_set(wfds);
+ if (m > n)
+ n = m;
+
+ /* Find out when the next timed event is. */
+ timeout = &tv;
+ timer_next_event(&timeout);
+
+ n = select(n, rfds, wfds, 0, timeout);
+ if (n == -1) {
+ if (errno != EINTR) {
+ log_error("main: select");
+
+ /*
+ * In order to give the unexpected error
+ * condition time to resolve without letting
+ * this process eat up all available CPU
+ * we sleep for a short while.
+ */
+ sleep(1);
+ }
+ } else if (n) {
+ transport_handle_messages(rfds);
+ transport_send_messages(wfds);
+ if (FD_ISSET(ui_socket, rfds))
+ ui_handler();
+ if (!app_none && app_socket >= 0 && FD_ISSET(app_socket, rfds))
+ app_handler();
+ }
+ timer_handle_expirations();
}
- timer_handle_expirations ();
- }
}
diff --git a/sbin/isakmpd/key.c b/sbin/isakmpd/key.c
index c1426abe628..15aac15936f 100644
--- a/sbin/isakmpd/key.c
+++ b/sbin/isakmpd/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.14 2004/04/07 22:45:04 ho Exp $ */
+/* $OpenBSD: key.c,v 1.15 2004/04/15 18:39:26 deraadt Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -31,159 +31,154 @@
#include "x509.h"
void
-key_free (int type, int private, void *key)
+key_free(int type, int private, void *key)
{
- switch (type)
- {
- case ISAKMP_KEY_PASSPHRASE:
- free (key);
- break;
- case ISAKMP_KEY_RSA:
- RSA_free (key);
- break;
- case ISAKMP_KEY_NONE:
- default:
- log_error ("key_free: unknown/unsupportedkey type %d", type);
- break;
- }
+ switch (type) {
+ case ISAKMP_KEY_PASSPHRASE:
+ free(key);
+ break;
+ case ISAKMP_KEY_RSA:
+ RSA_free(key);
+ break;
+ case ISAKMP_KEY_NONE:
+ default:
+ log_error("key_free: unknown/unsupportedkey type %d", type);
+ break;
+ }
}
/* Convert from internal form to serialized */
void
-key_serialize (int type, int private, void *key, u_int8_t **data, size_t *datalen)
+key_serialize(int type, int private, void *key, u_int8_t **data, size_t *datalen)
{
- u_int8_t *p;
-
- switch (type)
- {
- case ISAKMP_KEY_PASSPHRASE:
- *datalen = strlen ((char *)key);
- *data = (u_int8_t *)strdup ((char *)key);
- break;
- case ISAKMP_KEY_RSA:
- switch (private)
- {
- case ISAKMP_KEYTYPE_PUBLIC:
- *datalen = i2d_RSAPublicKey ((RSA *)key, NULL);
- *data = p = malloc (*datalen);
- if (!p)
- {
- log_error ("key_serialize: malloc (%lu) failed",
- (unsigned long)*datalen);
- return;
- }
- *datalen = i2d_RSAPublicKey ((RSA *)key, &p);
- break;
-
- case ISAKMP_KEYTYPE_PRIVATE:
- *datalen = i2d_RSAPrivateKey ((RSA *)key, NULL);
- *data = p = malloc (*datalen);
- if (!p)
- {
- log_error ("key_serialize: malloc (%lu) failed",
- (unsigned long)*datalen);
- return;
- }
- *datalen = i2d_RSAPrivateKey ((RSA *)key, &p);
- break;
+ u_int8_t *p;
+
+ switch (type) {
+ case ISAKMP_KEY_PASSPHRASE:
+ *datalen = strlen((char *) key);
+ *data = (u_int8_t *) strdup((char *) key);
+ break;
+ case ISAKMP_KEY_RSA:
+ switch (private) {
+ case ISAKMP_KEYTYPE_PUBLIC:
+ *datalen = i2d_RSAPublicKey((RSA *) key, NULL);
+ *data = p = malloc(*datalen);
+ if (!p) {
+ log_error("key_serialize: malloc (%lu) failed",
+ (unsigned long) *datalen);
+ return;
+ }
+ *datalen = i2d_RSAPublicKey((RSA *) key, &p);
+ break;
+
+ case ISAKMP_KEYTYPE_PRIVATE:
+ *datalen = i2d_RSAPrivateKey((RSA *) key, NULL);
+ *data = p = malloc(*datalen);
+ if (!p) {
+ log_error("key_serialize: malloc (%lu) failed",
+ (unsigned long) *datalen);
+ return;
+ }
+ *datalen = i2d_RSAPrivateKey((RSA *) key, &p);
+ break;
+ }
+ break;
+ default:
+ log_error("key_serialize: unknown/unsupported key type %d", type);
+ break;
}
- break;
- default:
- log_error ("key_serialize: unknown/unsupported key type %d", type);
- break;
- }
}
/* Convert from serialized to printable */
char *
-key_printable (int type, int private, u_int8_t *data, int datalen)
+key_printable(int type, int private, u_int8_t *data, int datalen)
{
- char *s;
- int i;
-
- switch (type)
- {
- case ISAKMP_KEY_PASSPHRASE:
- return strdup ((char *)data);
-
- case ISAKMP_KEY_RSA:
- s = malloc (datalen * 2 + 1);
- if (!s)
- {
- log_error ("key_printable: malloc (%d) failed", datalen * 2 + 1);
- return 0;
+ char *s;
+ int i;
+
+ switch (type) {
+ case ISAKMP_KEY_PASSPHRASE:
+ return strdup((char *) data);
+
+ case ISAKMP_KEY_RSA:
+ s = malloc(datalen * 2 + 1);
+ if (!s) {
+ log_error("key_printable: malloc (%d) failed",
+ datalen * 2 + 1);
+ return 0;
+ }
+ for (i = 0; i < datalen; i++)
+ snprintf(s + (2 * i), 2 * (datalen - i) + 1, "%02x",
+ data[i]);
+ return s;
+
+ default:
+ log_error("key_printable: unknown/unsupported key type %d", type);
+ return 0;
}
- for (i = 0; i < datalen; i++)
- snprintf (s + (2 * i), 2 * (datalen - i) + 1, "%02x", data[i]);
- return s;
-
- default:
- log_error ("key_printable: unknown/unsupported key type %d", type);
- return 0;
- }
}
/* Convert from serialized to internal. */
void *
-key_internalize (int type, int private, u_int8_t *data, int datalen)
+key_internalize(int type, int private, u_int8_t *data, int datalen)
{
- switch (type)
- {
- case ISAKMP_KEY_PASSPHRASE:
- return strdup ((char *)data);
- case ISAKMP_KEY_RSA:
- switch (private)
- {
+ switch (type) {
+ case ISAKMP_KEY_PASSPHRASE:
+ return strdup((char *) data);
+ case ISAKMP_KEY_RSA:
+ switch (private) {
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- case ISAKMP_KEYTYPE_PUBLIC:
- return d2i_RSAPublicKey (NULL, (const u_int8_t **)&data, datalen);
- case ISAKMP_KEYTYPE_PRIVATE:
- return d2i_RSAPrivateKey (NULL, (const u_int8_t **)&data, datalen);
+ case ISAKMP_KEYTYPE_PUBLIC:
+ return d2i_RSAPublicKey(NULL,
+ (const u_int8_t **)&data, datalen);
+ case ISAKMP_KEYTYPE_PRIVATE:
+ return d2i_RSAPrivateKey(NULL,
+ (const u_int8_t **)&data, datalen);
#else
- case ISAKMP_KEYTYPE_PUBLIC:
- return d2i_RSAPublicKey (NULL, &data, datalen);
- case ISAKMP_KEYTYPE_PRIVATE:
- return d2i_RSAPrivateKey (NULL, &data, datalen);
+ case ISAKMP_KEYTYPE_PUBLIC:
+ return d2i_RSAPublicKey(NULL, &data, datalen);
+ case ISAKMP_KEYTYPE_PRIVATE:
+ return d2i_RSAPrivateKey(NULL, &data, datalen);
#endif
+ default:
+ log_error("key_internalize: not public or private "
+ "RSA key passed");
+ return 0;
+ }
+ break;
default:
- log_error ("key_internalize: not public or private RSA key passed");
- return 0;
+ log_error("key_internalize: unknown/unsupported key type %d",
+ type);
+ break;
}
- break;
- default:
- log_error ("key_internalize: unknown/unsupported key type %d", type);
- break;
- }
- return 0;
+ return 0;
}
/* Convert from printable to serialized */
void
-key_from_printable (int type, int private, char *key, u_int8_t **data,
- u_int32_t *datalen)
+key_from_printable(int type, int private, char *key, u_int8_t **data,
+ u_int32_t *datalen)
{
- switch (type)
- {
- case ISAKMP_KEY_PASSPHRASE:
- *datalen = strlen (key);
- *data = (u_int8_t *)strdup (key);
- break;
-
- case ISAKMP_KEY_RSA:
- *datalen = (strlen (key) + 1) / 2; /* Round up, just in case */
- *data = malloc (*datalen);
- if (!*data)
- {
- log_error ("key_from_printable: malloc (%d) failed", *datalen);
- return;
+ switch (type) {
+ case ISAKMP_KEY_PASSPHRASE:
+ *datalen = strlen(key);
+ *data = (u_int8_t *) strdup(key);
+ break;
+
+ case ISAKMP_KEY_RSA:
+ *datalen = (strlen(key) + 1) / 2; /* Round up, just in case */
+ *data = malloc(*datalen);
+ if (!*data) {
+ log_error("key_from_printable: malloc (%d) failed", *datalen);
+ return;
+ }
+ *datalen = hex2raw(key, *data, *datalen);
+ break;
+
+ default:
+ log_error("key_from_printable: unknown/unsupported key type %d", type);
+ *data = 0;
+ break;
}
- *datalen = hex2raw (key, *data, *datalen);
- break;
-
- default:
- log_error ("key_from_printable: unknown/unsupported key type %d", type);
- *data = 0;
- break;
- }
}
diff --git a/sbin/isakmpd/key.h b/sbin/isakmpd/key.h
index b31c7c92397..81b13289046 100644
--- a/sbin/isakmpd/key.h
+++ b/sbin/isakmpd/key.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.h,v 1.6 2002/09/11 09:50:44 ho Exp $ */
+/* $OpenBSD: key.h,v 1.7 2004/04/15 18:39:26 deraadt Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -31,9 +31,9 @@
#define ISAKMP_KEYTYPE_PUBLIC 0
#define ISAKMP_KEYTYPE_PRIVATE 1
-void key_free (int, int, void *);
-void key_serialize (int, int, void *, u_int8_t **, size_t *);
-char *key_printable (int, int, u_int8_t *, int);
-void key_from_printable (int, int, char *, u_int8_t **, u_int32_t *);
-void *key_internalize (int, int, u_int8_t *, int);
-#endif /* _KEY_H_ */
+void key_free(int, int, void *);
+void key_serialize(int, int, void *, u_int8_t **, size_t *);
+char *key_printable(int, int, u_int8_t *, int);
+void key_from_printable(int, int, char *, u_int8_t **, u_int32_t *);
+void *key_internalize(int, int, u_int8_t *, int);
+#endif /* _KEY_H_ */
diff --git a/sbin/isakmpd/libcrypto.c b/sbin/isakmpd/libcrypto.c
index 482f61c54de..d66c58a47ca 100644
--- a/sbin/isakmpd/libcrypto.c
+++ b/sbin/isakmpd/libcrypto.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: libcrypto.c,v 1.15 2003/06/04 07:31:17 ho Exp $ */
-/* $EOM: libcrypto.c,v 1.14 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: libcrypto.c,v 1.16 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: libcrypto.c,v 1.14 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -34,17 +34,16 @@
#include "libcrypto.h"
void
-libcrypto_init (void)
+libcrypto_init(void)
{
#if defined (USE_X509) && defined (USE_LIBCRYPTO)
- /* Add all algorithms known by SSL */
+ /* Add all algorithms known by SSL */
#if OPENSSL_VERSION_NUMBER >= 0x00905100L
- OpenSSL_add_all_algorithms ();
+ OpenSSL_add_all_algorithms();
#else
- SSLeay_add_all_algorithms ();
+ SSLeay_add_all_algorithms();
#endif
#endif /* USE_X509 && USE_LIBCRYPTO */
}
-
diff --git a/sbin/isakmpd/libcrypto.h b/sbin/isakmpd/libcrypto.h
index b3892b7eedd..e9581bfc1dd 100644
--- a/sbin/isakmpd/libcrypto.h
+++ b/sbin/isakmpd/libcrypto.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: libcrypto.h,v 1.15 2003/06/04 07:31:17 ho Exp $ */
-/* $EOM: libcrypto.h,v 1.16 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: libcrypto.h,v 1.16 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: libcrypto.h,v 1.16 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -45,8 +45,8 @@
#include <openssl/x509_vfy.h>
#include <openssl/x509.h>
-#endif /* USE_X509 */
+#endif /* USE_X509 */
-extern void libcrypto_init (void);
+extern void libcrypto_init(void);
-#endif /* _LIBCRYPTO_H_ */
+#endif /* _LIBCRYPTO_H_ */
diff --git a/sbin/isakmpd/log.c b/sbin/isakmpd/log.c
index 273e1237aa7..c48b8771eaa 100644
--- a/sbin/isakmpd/log.c
+++ b/sbin/isakmpd/log.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: log.c,v 1.42 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: log.c,v 1.30 2000/09/29 08:19:23 niklas Exp $ */
+/* $OpenBSD: log.c,v 1.43 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: log.c,v 1.30 2000/09/29 08:19:23 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -50,7 +50,7 @@
#include "sysdep/common/pcap.h"
#endif
-#endif /* USE_DEBUG */
+#endif /* USE_DEBUG */
#include <errno.h>
#include <stdio.h>
@@ -66,654 +66,616 @@
#include "monitor.h"
#include "util.h"
-static void _log_print (int, int, const char *, va_list, int, int);
+static void _log_print(int, int, const char *, va_list, int, int);
-static FILE *log_output;
+static FILE *log_output;
-int verbose_logging = 0;
+int verbose_logging = 0;
#if defined (USE_DEBUG)
-static int log_level[LOG_ENDCLASS];
+static int log_level[LOG_ENDCLASS];
#define TCPDUMP_MAGIC 0xa1b2c3d4
#define SNAPLEN (64 * 1024)
struct packhdr {
- struct pcap_pkthdr pcap; /* pcap file packet header */
- u_int32_t sa_family; /* address family */
- union {
- struct ip ip4; /* IPv4 header (w/o options) */
- struct ip6_hdr ip6; /* IPv6 header */
- } ip;
+ struct pcap_pkthdr pcap;/* pcap file packet header */
+ u_int32_t sa_family; /* address family */
+ union {
+ struct ip ip4; /* IPv4 header (w/o options) */
+ struct ip6_hdr ip6; /* IPv6 header */
+ } ip;
};
struct isakmp_hdr {
- u_int8_t icookie[8], rcookie[8];
- u_int8_t next, ver, type, flags;
- u_int32_t msgid, len;
+ u_int8_t icookie[8], rcookie[8];
+ u_int8_t next, ver, type, flags;
+ u_int32_t msgid, len;
};
-static char *pcaplog_file = NULL;
-static FILE *packet_log;
+static char *pcaplog_file = NULL;
+static FILE *packet_log;
static u_int8_t *packet_buf = NULL;
-static int udp_cksum (struct packhdr *, const struct udphdr *, u_int16_t *);
-static u_int16_t in_cksum (const u_int16_t *, int);
-#endif /* USE_DEBUG */
+static int udp_cksum(struct packhdr *, const struct udphdr *, u_int16_t *);
+static u_int16_t in_cksum(const u_int16_t *, int);
+#endif /* USE_DEBUG */
void
-log_init (int debug)
+log_init(int debug)
{
- if (debug)
- log_output = stderr;
- else
- log_to (0); /* syslog */
+ if (debug)
+ log_output = stderr;
+ else
+ log_to(0); /* syslog */
}
void
-log_reinit (void)
+log_reinit(void)
{
- struct conf_list *logging;
+ struct conf_list *logging;
#ifdef USE_DEBUG
- struct conf_list_node *logclass;
- int class, level;
-#endif /* USE_DEBUG */
-
- logging = conf_get_list ("General", "Logverbose");
- if (logging)
- {
- verbose_logging = 1;
- conf_free_list (logging);
- }
-
-
+ struct conf_list_node *logclass;
+ int class, level;
+#endif /* USE_DEBUG */
+
+ logging = conf_get_list("General", "Logverbose");
+ if (logging) {
+ verbose_logging = 1;
+ conf_free_list(logging);
+ }
#ifdef USE_DEBUG
- logging = conf_get_list ("General", "Loglevel");
- if (logging)
- {
- for (logclass = TAILQ_FIRST (&logging->fields); logclass;
- logclass = TAILQ_NEXT (logclass, link))
- {
- if (sscanf (logclass->field, "%d=%d", &class, &level) != 2)
- {
- if (sscanf (logclass->field, "A=%d", &level) == 1)
- for (class = 0; class < LOG_ENDCLASS; class++)
- log_debug_cmd (class, level);
- else
- {
- log_print ("init: invalid logging class or level: %s",
- logclass->field);
- continue;
- }
- }
- else
- log_debug_cmd (class, level);
+ logging = conf_get_list("General", "Loglevel");
+ if (!logging)
+ return;
+
+ for (logclass = TAILQ_FIRST(&logging->fields); logclass;
+ logclass = TAILQ_NEXT(logclass, link)) {
+ if (sscanf(logclass->field, "%d=%d", &class, &level) != 2) {
+ if (sscanf(logclass->field, "A=%d", &level) == 1)
+ for (class = 0; class < LOG_ENDCLASS; class++)
+ log_debug_cmd(class, level);
+ else {
+ log_print("init: invalid logging class or level: %s",
+ logclass->field);
+ continue;
+ }
+ } else
+ log_debug_cmd(class, level);
}
- conf_free_list (logging);
- }
-#endif /* USE_DEBUG */
+ conf_free_list(logging);
+#endif /* USE_DEBUG */
}
void
-log_to (FILE *f)
+log_to(FILE *f)
{
- if (!log_output && f)
- closelog ();
- log_output = f;
- if (!f)
- openlog ("isakmpd", LOG_PID | LOG_CONS, LOG_DAEMON);
+ if (!log_output && f)
+ closelog();
+ log_output = f;
+ if (!f)
+ openlog("isakmpd", LOG_PID | LOG_CONS, LOG_DAEMON);
}
FILE *
-log_current (void)
+log_current(void)
{
- return log_output;
+ return log_output;
}
static char *
-_log_get_class (int error_class)
+_log_get_class(int error_class)
{
- /* XXX For test purposes. To be removed later on? */
- static char *class_text[] = LOG_CLASSES_TEXT;
-
- if (error_class < 0)
- return "Dflt";
- else if (error_class >= LOG_ENDCLASS)
- return "Unkn";
- else
- return class_text[error_class];
+ /* XXX For test purposes. To be removed later on? */
+ static char *class_text[] = LOG_CLASSES_TEXT;
+
+ if (error_class < 0)
+ return "Dflt";
+ else if (error_class >= LOG_ENDCLASS)
+ return "Unkn";
+ else
+ return class_text[error_class];
}
static void
-_log_print (int error, int syslog_level, const char *fmt, va_list ap,
- int class, int level)
+_log_print(int error, int syslog_level, const char *fmt, va_list ap,
+ int class, int level)
{
- char buffer[LOG_SIZE], nbuf[LOG_SIZE + 32];
- static const char fallback_msg[] =
- "write to log file failed (errno %d), redirecting output to syslog";
- int len;
- struct tm *tm;
- struct timeval now;
- time_t t;
-
- len = vsnprintf (buffer, sizeof buffer, fmt, ap);
- if (len > 0 && len < (int)sizeof buffer - 1 && error)
- snprintf (buffer + len, sizeof buffer - len, ": %s", strerror (errno));
- if (log_output)
- {
- gettimeofday (&now, 0);
- t = now.tv_sec;
- tm = localtime (&t);
- if (class >= 0)
- snprintf (nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s %02d ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec,
- _log_get_class (class), level);
- else /* LOG_PRINT (-1) or LOG_REPORT (-2) */
- snprintf (nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s ", tm->tm_hour,
- tm->tm_min, tm->tm_sec, now.tv_usec,
- class == LOG_PRINT ? "Default" : "Report>");
- strlcat (nbuf, buffer, sizeof nbuf);
+ char buffer[LOG_SIZE], nbuf[LOG_SIZE + 32];
+ static const char fallback_msg[] =
+ "write to log file failed (errno %d), redirecting output to syslog";
+ int len;
+ struct tm *tm;
+ struct timeval now;
+ time_t t;
+
+ len = vsnprintf(buffer, sizeof buffer, fmt, ap);
+ if (len > 0 && len < (int) sizeof buffer - 1 && error)
+ snprintf(buffer + len, sizeof buffer - len, ": %s", strerror(errno));
+ if (log_output) {
+ gettimeofday(&now, 0);
+ t = now.tv_sec;
+ tm = localtime(&t);
+ if (class >= 0)
+ snprintf(nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s %02d ",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec,
+ _log_get_class(class), level);
+ else /* LOG_PRINT (-1) or LOG_REPORT (-2) */
+ snprintf(nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s ",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec,
+ class == LOG_PRINT ? "Default" : "Report>");
+ strlcat(nbuf, buffer, sizeof nbuf);
#if defined (USE_PRIVSEP)
- strlcat (nbuf, getuid () ? "" : " [priv]", LOG_SIZE + 32);
+ strlcat(nbuf, getuid() ? "" : " [priv]", LOG_SIZE + 32);
#endif
- strlcat (nbuf, "\n", sizeof nbuf);
-
- if (fwrite (nbuf, strlen (nbuf), 1, log_output) == 0)
- {
- /* Report fallback. */
- syslog (LOG_ALERT, fallback_msg, errno);
- fprintf (log_output, fallback_msg, errno);
-
- /*
- * Close log_output to prevent isakmpd from locking the file.
- * We may need to explicitly close stdout to do this properly.
- * XXX - Figure out how to match two FILE *'s and rewrite.
- */
- if (fileno (log_output) != -1
- && fileno (stdout) == fileno (log_output))
- fclose (stdout);
- fclose (log_output);
-
- /* Fallback to syslog. */
- log_to (0);
-
- /* (Re)send current message to syslog(). */
- syslog (class == LOG_REPORT ? LOG_ALERT
- : syslog_level, "%s", buffer);
- }
- }
- else
- syslog (class == LOG_REPORT ? LOG_ALERT : syslog_level, "%s", buffer);
+ strlcat(nbuf, "\n", sizeof nbuf);
+
+ if (fwrite(nbuf, strlen(nbuf), 1, log_output) == 0) {
+ /* Report fallback. */
+ syslog(LOG_ALERT, fallback_msg, errno);
+ fprintf(log_output, fallback_msg, errno);
+
+ /*
+ * Close log_output to prevent isakmpd from locking the file.
+ * We may need to explicitly close stdout to do this properly.
+ * XXX - Figure out how to match two FILE *'s and rewrite.
+ */
+ if (fileno(log_output) != -1 &&
+ fileno(stdout) == fileno(log_output))
+ fclose(stdout);
+ fclose(log_output);
+
+ /* Fallback to syslog. */
+ log_to(0);
+
+ /* (Re)send current message to syslog(). */
+ syslog(class == LOG_REPORT ? LOG_ALERT :
+ syslog_level, "%s", buffer);
+ }
+ } else
+ syslog(class == LOG_REPORT ? LOG_ALERT : syslog_level,
+ "%s", buffer);
}
#ifdef USE_DEBUG
void
-log_debug (int cls, int level, const char *fmt, ...)
+log_debug(int cls, int level, const char *fmt, ...)
{
- va_list ap;
-
- /*
- * If we are not debugging this class, or the level is too low, just return.
- */
- if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls]))
- return;
- va_start (ap, fmt);
- _log_print (0, LOG_INFO, fmt, ap, cls, level);
- va_end (ap);
+ va_list ap;
+
+ /*
+ * If we are not debugging this class, or the level is too low, just return.
+ */
+ if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls]))
+ return;
+ va_start(ap, fmt);
+ _log_print(0, LOG_INFO, fmt, ap, cls, level);
+ va_end(ap);
}
void
-log_debug_buf (int cls, int level, const char *header, const u_int8_t *buf,
- size_t sz)
+log_debug_buf(int cls, int level, const char *header, const u_int8_t *buf,
+ size_t sz)
{
- char s[73];
- size_t i, j;
-
- /*
- * If we are not debugging this class, or the level is too low, just return.
- */
- if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls]))
- return;
-
- log_debug (cls, level, "%s:", header);
- for (i = j = 0; i < sz;)
- {
- snprintf (s + j, sizeof s - j, "%02x", buf[i++]);
- j += 2;
- if (i % 4 == 0)
- {
- if (i % 32 == 0)
- {
- s[j] = '\0';
- log_debug (cls, level, "%s", s);
- j = 0;
- }
- else
- s[j++] = ' ';
+ size_t i, j;
+ char s[73];
+
+ /*
+ * If we are not debugging this class, or the level is too low, just return.
+ */
+ if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls]))
+ return;
+
+ log_debug(cls, level, "%s:", header);
+ for (i = j = 0; i < sz;) {
+ snprintf(s + j, sizeof s - j, "%02x", buf[i++]);
+ j += 2;
+ if (i % 4 == 0) {
+ if (i % 32 == 0) {
+ s[j] = '\0';
+ log_debug(cls, level, "%s", s);
+ j = 0;
+ } else
+ s[j++] = ' ';
+ }
+ }
+ if (j) {
+ s[j] = '\0';
+ log_debug(cls, level, "%s", s);
}
- }
- if (j)
- {
- s[j] = '\0';
- log_debug (cls, level, "%s", s);
- }
}
void
-log_debug_cmd (int cls, int level)
+log_debug_cmd(int cls, int level)
{
- if (cls < 0 || cls >= LOG_ENDCLASS)
- {
- log_print ("log_debug_cmd: invalid debugging class %d", cls);
- return;
- }
-
- if (level < 0)
- {
- log_print ("log_debug_cmd: invalid debugging level %d for class %d",
- level, cls);
- return;
- }
-
- if (level == log_level[cls])
- log_print ("log_debug_cmd: log level unchanged for class %d", cls);
- else
- {
- log_print ("log_debug_cmd: log level changed from %d to %d for class %d",
- log_level[cls], level, cls);
- log_level[cls] = level;
- }
+ if (cls < 0 || cls >= LOG_ENDCLASS) {
+ log_print("log_debug_cmd: invalid debugging class %d", cls);
+ return;
+ }
+ if (level < 0) {
+ log_print("log_debug_cmd: invalid debugging level %d for class %d",
+ level, cls);
+ return;
+ }
+ if (level == log_level[cls])
+ log_print("log_debug_cmd: log level unchanged for class %d", cls);
+ else {
+ log_print("log_debug_cmd: log level changed from %d to %d for class %d",
+ log_level[cls], level, cls);
+ log_level[cls] = level;
+ }
}
void
-log_debug_toggle (void)
+log_debug_toggle(void)
{
- static int log_level_copy[LOG_ENDCLASS], toggle = 0;
-
- if (!toggle)
- {
- LOG_DBG ((LOG_MISC, 50, "log_debug_toggle: debug levels cleared"));
- memcpy (&log_level_copy, &log_level, sizeof log_level);
- memset (&log_level, 0, sizeof log_level);
- }
- else
- {
- memcpy (&log_level, &log_level_copy, sizeof log_level);
- LOG_DBG ((LOG_MISC, 50, "log_debug_toggle: debug levels restored"));
- }
- toggle = !toggle;
+ static int log_level_copy[LOG_ENDCLASS], toggle = 0;
+
+ if (!toggle) {
+ LOG_DBG((LOG_MISC, 50, "log_debug_toggle: debug levels cleared"));
+ memcpy(&log_level_copy, &log_level, sizeof log_level);
+ memset(&log_level, 0, sizeof log_level);
+ } else {
+ memcpy(&log_level, &log_level_copy, sizeof log_level);
+ LOG_DBG((LOG_MISC, 50, "log_debug_toggle: debug levels restored"));
+ }
+ toggle = !toggle;
}
-#endif /* USE_DEBUG */
+#endif /* USE_DEBUG */
void
-log_print (const char *fmt, ...)
+log_print(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- va_start (ap, fmt);
- _log_print (0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0);
- va_end (ap);
+ va_start(ap, fmt);
+ _log_print(0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0);
+ va_end(ap);
}
void
-log_verbose (const char *fmt, ...)
+log_verbose(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
#ifdef USE_DEBUG
- int i;
-#endif /* USE_DEBUG */
+ int i;
+#endif /* USE_DEBUG */
- if (verbose_logging == 0)
- return;
+ if (verbose_logging == 0)
+ return;
#ifdef USE_DEBUG
- for (i = 0; i < LOG_ENDCLASS; i++)
- if (log_level[i] > 0)
- return;
+ for (i = 0; i < LOG_ENDCLASS; i++)
+ if (log_level[i] > 0)
+ return;
#endif
- va_start (ap, fmt);
- _log_print (0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0);
- va_end (ap);
+ va_start(ap, fmt);
+ _log_print(0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0);
+ va_end(ap);
}
void
-log_error (const char *fmt, ...)
+log_error(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- va_start (ap, fmt);
- _log_print (1, LOG_ERR, fmt, ap, LOG_PRINT, 0);
- va_end (ap);
+ va_start(ap, fmt);
+ _log_print(1, LOG_ERR, fmt, ap, LOG_PRINT, 0);
+ va_end(ap);
}
void
-log_fatal (const char *fmt, ...)
+log_fatal(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- va_start (ap, fmt);
- _log_print (1, LOG_CRIT, fmt, ap, LOG_PRINT, 0);
- va_end (ap);
- exit (1);
+ va_start(ap, fmt);
+ _log_print(1, LOG_CRIT, fmt, ap, LOG_PRINT, 0);
+ va_end(ap);
+ exit(1);
}
#ifdef USE_DEBUG
void
-log_packet_init (char *newname)
+log_packet_init(char *newname)
{
- struct pcap_file_header sf_hdr;
- struct stat st;
- mode_t old_umask;
- char *mode;
-
- /* Allocate packet buffer first time through. */
- if (!packet_buf)
- packet_buf = malloc (SNAPLEN);
-
- if (!packet_buf)
- {
- log_error ("log_packet_init: malloc (%d) failed", SNAPLEN);
- return;
- }
-
- if (pcaplog_file && strcmp (pcaplog_file, PCAP_FILE_DEFAULT) != 0)
- free (pcaplog_file);
-
- pcaplog_file = strdup (newname);
- if (!pcaplog_file)
- {
- log_error ("log_packet_init: strdup (\"%s\") failed", newname);
- return;
- }
-
- /* Does the file already exist? XXX lstat() or stat()? */
+ struct pcap_file_header sf_hdr;
+ struct stat st;
+ mode_t old_umask;
+ char *mode;
+
+ /* Allocate packet buffer first time through. */
+ if (!packet_buf)
+ packet_buf = malloc(SNAPLEN);
+
+ if (!packet_buf) {
+ log_error("log_packet_init: malloc (%d) failed", SNAPLEN);
+ return;
+ }
+ if (pcaplog_file && strcmp(pcaplog_file, PCAP_FILE_DEFAULT) != 0)
+ free(pcaplog_file);
+
+ pcaplog_file = strdup(newname);
+ if (!pcaplog_file) {
+ log_error("log_packet_init: strdup (\"%s\") failed", newname);
+ return;
+ }
+ /* Does the file already exist? XXX lstat() or stat()? */
#if defined (USE_PRIVSEP)
- /* XXX This is a fstat! */
- if (monitor_stat (pcaplog_file, &st) == 0)
+ /* XXX This is a fstat! */
+ if (monitor_stat(pcaplog_file, &st) == 0) {
#else
- if (lstat (pcaplog_file, &st) == 0)
+ if (lstat(pcaplog_file, &st) == 0) {
#endif
- {
- /* Sanity checks. */
- if ((st.st_mode & S_IFMT) != S_IFREG)
- {
- log_print ("log_packet_init: existing capture file is "
- "not a regular file");
- return;
+ /* Sanity checks. */
+ if ((st.st_mode & S_IFMT) != S_IFREG) {
+ log_print("log_packet_init: existing capture file is "
+ "not a regular file");
+ return;
+ }
+ if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
+ log_print("log_packet_init: existing capture "
+ "file has bad modes");
+ return;
+ }
+ /*
+ * XXX It would be nice to check if it actually is a pcap
+ * file...
+ */
+
+ mode = "a";
+ } else
+ mode = "w";
+
+ old_umask = umask(S_IRWXG | S_IRWXO);
+ packet_log = monitor_fopen(pcaplog_file, mode);
+ umask(old_umask);
+
+ if (!packet_log) {
+ log_error("log_packet_init: fopen (\"%s\", \"%s\") failed",
+ pcaplog_file, mode);
+ return;
}
-
- if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
- {
- log_print ("log_packet_init: existing capture file has bad modes");
- return;
+ log_print("log_packet_init: starting IKE packet capture to file \"%s\"",
+ pcaplog_file);
+
+ /* If this is a new file, we need to write a PCAP header to it. */
+ if (*mode == 'w') {
+ sf_hdr.magic = TCPDUMP_MAGIC;
+ sf_hdr.version_major = PCAP_VERSION_MAJOR;
+ sf_hdr.version_minor = PCAP_VERSION_MINOR;
+ sf_hdr.thiszone = 0;
+ sf_hdr.snaplen = SNAPLEN;
+ sf_hdr.sigfigs = 0;
+ sf_hdr.linktype = DLT_LOOP;
+
+ fwrite((char *) &sf_hdr, sizeof sf_hdr, 1, packet_log);
+ fflush(packet_log);
}
-
- /* XXX It would be nice to check if it actually is a pcap file... */
-
- mode = "a";
- }
- else
- mode = "w";
-
- old_umask = umask (S_IRWXG | S_IRWXO);
- packet_log = monitor_fopen (pcaplog_file, mode);
- umask (old_umask);
-
- if (!packet_log)
- {
- log_error ("log_packet_init: fopen (\"%s\", \"%s\") failed",
- pcaplog_file, mode);
- return;
- }
-
- log_print ("log_packet_init: starting IKE packet capture to file \"%s\"",
- pcaplog_file);
-
- /* If this is a new file, we need to write a PCAP header to it. */
- if (*mode == 'w')
- {
- sf_hdr.magic = TCPDUMP_MAGIC;
- sf_hdr.version_major = PCAP_VERSION_MAJOR;
- sf_hdr.version_minor = PCAP_VERSION_MINOR;
- sf_hdr.thiszone = 0;
- sf_hdr.snaplen = SNAPLEN;
- sf_hdr.sigfigs = 0;
- sf_hdr.linktype = DLT_LOOP;
-
- fwrite ((char *)&sf_hdr, sizeof sf_hdr, 1, packet_log);
- fflush (packet_log);
- }
}
void
-log_packet_restart (char *newname)
+log_packet_restart(char *newname)
{
- if (packet_log)
- {
- log_print ("log_packet_restart: capture already active on file \"%s\"",
- pcaplog_file);
- return;
- }
-
- if (newname)
- log_packet_init (newname);
- else if (!pcaplog_file)
- log_packet_init (PCAP_FILE_DEFAULT);
- else
- log_packet_init (pcaplog_file);
+ if (packet_log) {
+ log_print("log_packet_restart: capture already active on file \"%s\"",
+ pcaplog_file);
+ return;
+ }
+ if (newname)
+ log_packet_init(newname);
+ else if (!pcaplog_file)
+ log_packet_init(PCAP_FILE_DEFAULT);
+ else
+ log_packet_init(pcaplog_file);
}
void
-log_packet_stop (void)
+log_packet_stop(void)
{
- /* Stop capture. */
- if (packet_log)
- {
- fclose (packet_log);
- log_print ("log_packet_stop: stopped capture");
- }
- packet_log = 0;
+ /* Stop capture. */
+ if (packet_log) {
+ fclose(packet_log);
+ log_print("log_packet_stop: stopped capture");
+ }
+ packet_log = 0;
}
void
-log_packet_iov (struct sockaddr *src, struct sockaddr *dst, struct iovec *iov,
- int iovcnt)
+log_packet_iov(struct sockaddr * src, struct sockaddr * dst, struct iovec * iov,
+ int iovcnt)
{
- struct isakmp_hdr *isakmphdr;
- struct packhdr hdr;
- struct udphdr udp;
- int off, datalen, hdrlen, i;
- struct timeval tv;
-
- for (i = 0, datalen = 0; i < iovcnt; i++)
- datalen += iov[i].iov_len;
-
- if (!packet_log || datalen > SNAPLEN)
- return;
-
- /* copy packet into buffer */
- for (i = 0, off = 0; i < iovcnt; i++)
- {
- memcpy (packet_buf + off, iov[i].iov_base, iov[i].iov_len);
- off += iov[i].iov_len;
- }
-
- memset (&hdr, 0, sizeof hdr);
- memset (&udp, 0, sizeof udp);
-
- /* isakmp - turn off the encryption bit in the isakmp hdr */
- isakmphdr = (struct isakmp_hdr *)packet_buf;
- isakmphdr->flags &= ~(ISAKMP_FLAGS_ENC);
-
- /* udp */
- udp.uh_sport = sockaddr_port (src);
- udp.uh_dport = sockaddr_port (dst);
- datalen += sizeof udp;
- udp.uh_ulen = htons (datalen);
-
- /* ip */
- hdr.sa_family = htonl (src->sa_family);
- switch (src->sa_family)
- {
- default:
- /* Assume IPv4. XXX Can 'default' ever happen here? */
- hdr.sa_family = htonl (AF_INET);
- hdr.ip.ip4.ip_src.s_addr = 0x02020202;
- hdr.ip.ip4.ip_dst.s_addr = 0x01010101;
- /* The rest of the setup is common to AF_INET. */
- goto setup_ip4;
-
- case AF_INET:
- hdr.ip.ip4.ip_src.s_addr = ((struct sockaddr_in *)src)->sin_addr.s_addr;
- hdr.ip.ip4.ip_dst.s_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
-
- setup_ip4:
- hdrlen = sizeof hdr.ip.ip4;
- hdr.ip.ip4.ip_v = 0x4;
- hdr.ip.ip4.ip_hl = 0x5;
- hdr.ip.ip4.ip_p = IPPROTO_UDP;
- hdr.ip.ip4.ip_len = htons (datalen + hdrlen);
- /* Let's use the IP ID as a "packet counter". */
- i = ntohs (hdr.ip.ip4.ip_id) + 1;
- hdr.ip.ip4.ip_id = htons (i);
- /* Calculate IP header checksum. */
- hdr.ip.ip4.ip_sum = in_cksum ((u_int16_t *)&hdr.ip.ip4,
- hdr.ip.ip4.ip_hl << 2);
- break;
-
- case AF_INET6:
- hdrlen = sizeof (hdr.ip.ip6);
- hdr.ip.ip6.ip6_vfc = IPV6_VERSION;
- hdr.ip.ip6.ip6_nxt = IPPROTO_UDP;
- hdr.ip.ip6.ip6_plen = udp.uh_ulen;
- memcpy (&hdr.ip.ip6.ip6_src, &((struct sockaddr_in6 *)src)->sin6_addr,
- sizeof hdr.ip.ip6.ip6_src);
- memcpy (&hdr.ip.ip6.ip6_dst, &((struct sockaddr_in6 *)dst)->sin6_addr,
- sizeof hdr.ip.ip6.ip6_dst);
- break;
- }
-
- /* Calculate UDP checksum. */
- udp.uh_sum = udp_cksum (&hdr, &udp, (u_int16_t *)packet_buf);
- hdrlen += sizeof hdr.sa_family;
-
- /* pcap file packet header */
- gettimeofday (&tv, 0);
- hdr.pcap.ts.tv_sec = tv.tv_sec;
- hdr.pcap.ts.tv_usec = tv.tv_usec;
- hdr.pcap.caplen = datalen + hdrlen;
- hdr.pcap.len = datalen + hdrlen;
-
- hdrlen += sizeof (struct pcap_pkthdr);
- datalen -= sizeof (struct udphdr);
-
- /* Write to pcap file. */
- fwrite (&hdr, hdrlen, 1, packet_log); /* pcap + IP */
- fwrite (&udp, sizeof (struct udphdr), 1, packet_log); /* UDP */
- fwrite (packet_buf, datalen, 1, packet_log); /* IKE-data */
- fflush (packet_log);
- return;
+ struct isakmp_hdr *isakmphdr;
+ struct packhdr hdr;
+ struct udphdr udp;
+ int off, datalen, hdrlen, i;
+ struct timeval tv;
+
+ for (i = 0, datalen = 0; i < iovcnt; i++)
+ datalen += iov[i].iov_len;
+
+ if (!packet_log || datalen > SNAPLEN)
+ return;
+
+ /* copy packet into buffer */
+ for (i = 0, off = 0; i < iovcnt; i++) {
+ memcpy(packet_buf + off, iov[i].iov_base, iov[i].iov_len);
+ off += iov[i].iov_len;
+ }
+
+ memset(&hdr, 0, sizeof hdr);
+ memset(&udp, 0, sizeof udp);
+
+ /* isakmp - turn off the encryption bit in the isakmp hdr */
+ isakmphdr = (struct isakmp_hdr *) packet_buf;
+ isakmphdr->flags &= ~(ISAKMP_FLAGS_ENC);
+
+ /* udp */
+ udp.uh_sport = sockaddr_port(src);
+ udp.uh_dport = sockaddr_port(dst);
+ datalen += sizeof udp;
+ udp.uh_ulen = htons(datalen);
+
+ /* ip */
+ hdr.sa_family = htonl(src->sa_family);
+ switch (src->sa_family) {
+ default:
+ /* Assume IPv4. XXX Can 'default' ever happen here? */
+ hdr.sa_family = htonl(AF_INET);
+ hdr.ip.ip4.ip_src.s_addr = 0x02020202;
+ hdr.ip.ip4.ip_dst.s_addr = 0x01010101;
+ /* The rest of the setup is common to AF_INET. */
+ goto setup_ip4;
+
+ case AF_INET:
+ hdr.ip.ip4.ip_src.s_addr = ((struct sockaddr_in *) src)->sin_addr.s_addr;
+ hdr.ip.ip4.ip_dst.s_addr = ((struct sockaddr_in *) dst)->sin_addr.s_addr;
+
+setup_ip4:
+ hdrlen = sizeof hdr.ip.ip4;
+ hdr.ip.ip4.ip_v = 0x4;
+ hdr.ip.ip4.ip_hl = 0x5;
+ hdr.ip.ip4.ip_p = IPPROTO_UDP;
+ hdr.ip.ip4.ip_len = htons(datalen + hdrlen);
+ /* Let's use the IP ID as a "packet counter". */
+ i = ntohs(hdr.ip.ip4.ip_id) + 1;
+ hdr.ip.ip4.ip_id = htons(i);
+ /* Calculate IP header checksum. */
+ hdr.ip.ip4.ip_sum = in_cksum((u_int16_t *) & hdr.ip.ip4,
+ hdr.ip.ip4.ip_hl << 2);
+ break;
+
+ case AF_INET6:
+ hdrlen = sizeof(hdr.ip.ip6);
+ hdr.ip.ip6.ip6_vfc = IPV6_VERSION;
+ hdr.ip.ip6.ip6_nxt = IPPROTO_UDP;
+ hdr.ip.ip6.ip6_plen = udp.uh_ulen;
+ memcpy(&hdr.ip.ip6.ip6_src, &((struct sockaddr_in6 *) src)->sin6_addr,
+ sizeof hdr.ip.ip6.ip6_src);
+ memcpy(&hdr.ip.ip6.ip6_dst, &((struct sockaddr_in6 *) dst)->sin6_addr,
+ sizeof hdr.ip.ip6.ip6_dst);
+ break;
+ }
+
+ /* Calculate UDP checksum. */
+ udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf);
+ hdrlen += sizeof hdr.sa_family;
+
+ /* pcap file packet header */
+ gettimeofday(&tv, 0);
+ hdr.pcap.ts.tv_sec = tv.tv_sec;
+ hdr.pcap.ts.tv_usec = tv.tv_usec;
+ hdr.pcap.caplen = datalen + hdrlen;
+ hdr.pcap.len = datalen + hdrlen;
+
+ hdrlen += sizeof(struct pcap_pkthdr);
+ datalen -= sizeof(struct udphdr);
+
+ /* Write to pcap file. */
+ fwrite(&hdr, hdrlen, 1, packet_log); /* pcap + IP */
+ fwrite(&udp, sizeof(struct udphdr), 1, packet_log); /* UDP */
+ fwrite(packet_buf, datalen, 1, packet_log); /* IKE-data */
+ fflush(packet_log);
}
/* Copied from tcpdump/print-udp.c, mostly rewritten. */
static int
-udp_cksum (struct packhdr *hdr, const struct udphdr *u, u_int16_t *d)
+udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d)
{
- int i, hdrlen, tlen = ntohs (u->uh_ulen) - sizeof (struct udphdr);
- struct ip *ip4;
- struct ip6_hdr *ip6;
-
- union phu {
- struct ip4pseudo {
- struct in_addr src;
- struct in_addr dst;
- u_int8_t z;
- u_int8_t proto;
- u_int16_t len;
- } ip4p;
- struct ip6pseudo {
- struct in6_addr src;
- struct in6_addr dst;
- u_int32_t plen;
- u_int16_t z0;
- u_int8_t z1;
- u_int8_t nxt;
- } ip6p;
- u_int16_t pa[20];
- } phu;
- const u_int16_t *sp;
- u_int32_t sum;
-
- /* Setup pseudoheader. */
- memset (phu.pa, 0, sizeof phu);
- switch (ntohl (hdr->sa_family))
- {
- case AF_INET:
- ip4 = &hdr->ip.ip4;
- memcpy (&phu.ip4p.src, &ip4->ip_src, sizeof (struct in_addr));
- memcpy (&phu.ip4p.dst, &ip4->ip_dst, sizeof (struct in_addr));
- phu.ip4p.proto = ip4->ip_p;
- phu.ip4p.len = u->uh_ulen;
- hdrlen = sizeof phu.ip4p;
- break;
-
- case AF_INET6:
- ip6 = &hdr->ip.ip6;
- memcpy (&phu.ip6p.src, &ip6->ip6_src, sizeof (phu.ip6p.src));
- memcpy (&phu.ip6p.dst, &ip6->ip6_dst, sizeof (phu.ip6p.dst));
- phu.ip6p.plen = u->uh_ulen;
- phu.ip6p.nxt = ip6->ip6_nxt;
- hdrlen = sizeof phu.ip6p;
- break;
-
- default:
- return 0;
- }
-
- /* IPv6 wants a 0xFFFF checksum "on error", not 0x0. */
- if (tlen < 0)
- return (ntohl (hdr->sa_family) == AF_INET ? 0 : 0xFFFF);
-
- sum = 0;
- for (i = 0; i < hdrlen; i += 2)
- sum += phu.pa[i/2];
-
- sp = (u_int16_t *)u;
- for (i = 0; i < (int)sizeof (struct udphdr); i += 2)
- sum += *sp++;
-
- sp = d;
- for (i = 0; i < (tlen&~1); i += 2)
- sum += *sp++;
-
- if (tlen & 1)
- sum += htons ((*(const char *)sp) << 8);
-
- while (sum > 0xffff)
- sum = (sum & 0xffff) + (sum >> 16);
- sum = ~sum & 0xffff;
-
- return sum;
+ struct ip *ip4;
+ struct ip6_hdr *ip6;
+ int i, hdrlen, tlen = ntohs(u->uh_ulen) - sizeof(struct udphdr);
+
+ union phu {
+ struct ip4pseudo {
+ struct in_addr src;
+ struct in_addr dst;
+ u_int8_t z;
+ u_int8_t proto;
+ u_int16_t len;
+ } ip4p;
+ struct ip6pseudo {
+ struct in6_addr src;
+ struct in6_addr dst;
+ u_int32_t plen;
+ u_int16_t z0;
+ u_int8_t z1;
+ u_int8_t nxt;
+ } ip6p;
+ u_int16_t pa[20];
+ } phu;
+ const u_int16_t *sp;
+ u_int32_t sum;
+
+ /* Setup pseudoheader. */
+ memset(phu.pa, 0, sizeof phu);
+ switch (ntohl(hdr->sa_family)) {
+ case AF_INET:
+ ip4 = &hdr->ip.ip4;
+ memcpy(&phu.ip4p.src, &ip4->ip_src, sizeof(struct in_addr));
+ memcpy(&phu.ip4p.dst, &ip4->ip_dst, sizeof(struct in_addr));
+ phu.ip4p.proto = ip4->ip_p;
+ phu.ip4p.len = u->uh_ulen;
+ hdrlen = sizeof phu.ip4p;
+ break;
+
+ case AF_INET6:
+ ip6 = &hdr->ip.ip6;
+ memcpy(&phu.ip6p.src, &ip6->ip6_src, sizeof(phu.ip6p.src));
+ memcpy(&phu.ip6p.dst, &ip6->ip6_dst, sizeof(phu.ip6p.dst));
+ phu.ip6p.plen = u->uh_ulen;
+ phu.ip6p.nxt = ip6->ip6_nxt;
+ hdrlen = sizeof phu.ip6p;
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* IPv6 wants a 0xFFFF checksum "on error", not 0x0. */
+ if (tlen < 0)
+ return (ntohl(hdr->sa_family) == AF_INET ? 0 : 0xFFFF);
+
+ sum = 0;
+ for (i = 0; i < hdrlen; i += 2)
+ sum += phu.pa[i / 2];
+
+ sp = (u_int16_t *) u;
+ for (i = 0; i < (int) sizeof(struct udphdr); i += 2)
+ sum += *sp++;
+
+ sp = d;
+ for (i = 0; i < (tlen & ~1); i += 2)
+ sum += *sp++;
+
+ if (tlen & 1)
+ sum += htons((*(const char *) sp) << 8);
+
+ while (sum > 0xffff)
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = ~sum & 0xffff;
+
+ return sum;
}
/* Copied from tcpdump/print-ip.c, modified. */
static u_int16_t
-in_cksum (const u_int16_t *w, int len)
+in_cksum(const u_int16_t *w, int len)
{
- int nleft = len, sum = 0;
- u_int16_t answer;
-
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
- if (nleft == 1)
- sum += htons (*(u_char *)w << 8);
-
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return answer;
+ int nleft = len, sum = 0;
+ u_int16_t answer;
+
+ while (nleft > 1) {
+ sum += *w++;
+ nleft -= 2;
+ }
+ if (nleft == 1)
+ sum += htons(*(u_char *) w << 8);
+
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return answer;
}
-#endif /* USE_DEBUG */
+#endif /* USE_DEBUG */
diff --git a/sbin/isakmpd/log.h b/sbin/isakmpd/log.h
index df96760b79f..1efa9e78d0e 100644
--- a/sbin/isakmpd/log.h
+++ b/sbin/isakmpd/log.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: log.h,v 1.19 2004/02/25 16:01:28 hshoexer Exp $ */
-/* $EOM: log.h,v 1.19 2000/03/30 14:27:23 ho Exp $ */
+/* $OpenBSD: log.h,v 1.20 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: log.h,v 1.19 2000/03/30 14:27:23 ho Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -38,7 +38,7 @@
#include <sys/uio.h>
#include <stdio.h>
-extern int verbose_logging;
+extern int verbose_logging;
/*
* We cannot do the log strings dynamically sizeable as out of memory is one
@@ -47,8 +47,8 @@ extern int verbose_logging;
#define LOG_SIZE 200
enum log_classes {
- LOG_MISC, LOG_TRANSPORT, LOG_MESSAGE, LOG_CRYPTO, LOG_TIMER, LOG_SYSDEP,
- LOG_SA, LOG_EXCHANGE, LOG_NEGOTIATION, LOG_POLICY, LOG_UI, LOG_ENDCLASS
+ LOG_MISC, LOG_TRANSPORT, LOG_MESSAGE, LOG_CRYPTO, LOG_TIMER, LOG_SYSDEP,
+ LOG_SA, LOG_EXCHANGE, LOG_NEGOTIATION, LOG_POLICY, LOG_UI, LOG_ENDCLASS
};
#define LOG_CLASSES_TEXT \
{ "Misc", "Trpt", "Mesg", "Cryp", "Timr", "Sdep", "SA ", "Exch", "Negt", \
@@ -66,37 +66,39 @@ enum log_classes {
#define LOG_DBG(x) log_debug x
#define LOG_DBG_BUF(x) log_debug_buf x
-extern void log_debug (int, int, const char *, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-extern void log_debug_buf (int, int, const char *, const u_int8_t *, size_t);
-extern void log_debug_cmd (int, int);
-extern void log_debug_toggle (void);
+extern void
+log_debug(int, int, const char *,...)
+__attribute__((__format__(__printf__, 3, 4)));
+ extern void log_debug_buf(int, int, const char *, const u_int8_t *, size_t);
+ extern void log_debug_cmd(int, int);
+ extern void log_debug_toggle(void);
#define PCAP_FILE_DEFAULT "/var/run/isakmpd.pcap"
-extern void log_packet_init (char *);
-extern void log_packet_iov (struct sockaddr *, struct sockaddr *,
- struct iovec *, int);
-extern void log_packet_restart (char *);
-extern void log_packet_stop (void);
+ extern void log_packet_init(char *);
+ extern void log_packet_iov(struct sockaddr *, struct sockaddr *,
+ struct iovec *, int);
+ extern void log_packet_restart(char *);
+ extern void log_packet_stop(void);
-#else /* !USE_DEBUG */
+#else /* !USE_DEBUG */
#define LOG_DBG(x)
#define LOG_DBG_BUF(x)
-#endif /* USE_DEBUG */
-
-extern FILE *log_current (void);
-extern void log_error (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void log_fatal (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void log_print (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void log_verbose (const char *, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void log_to (FILE *);
-extern void log_init (int);
-extern void log_reinit (void);
-
-#endif /* _LOG_H_ */
+#endif /* USE_DEBUG */
+
+extern FILE *log_current(void);
+extern void
+log_error(const char *,...)
+__attribute__((__format__(__printf__, 1, 2)));
+ extern void log_fatal(const char *,...)
+ __attribute__((__format__(__printf__, 1, 2)));
+ extern void log_print(const char *,...)
+ __attribute__((__format__(__printf__, 1, 2)));
+ extern void log_verbose(const char *,...)
+ __attribute__((__format__(__printf__, 1, 2)));
+ extern void log_to(FILE *);
+ extern void log_init(int);
+ extern void log_reinit(void);
+
+#endif /* _LOG_H_ */
diff --git a/sbin/isakmpd/math_2n.c b/sbin/isakmpd/math_2n.c
index 4b600d04b8a..c5e37b3a27e 100644
--- a/sbin/isakmpd/math_2n.c
+++ b/sbin/isakmpd/math_2n.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_2n.c,v 1.13 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: math_2n.c,v 1.15 1999/04/20 09:23:30 niklas Exp $ */
+/* $OpenBSD: math_2n.c,v 1.14 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_2n.c,v 1.15 1999/04/20 09:23:30 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -48,507 +48,486 @@
#include "math_2n.h"
#include "util.h"
-static u_int8_t hex2int (char);
+static u_int8_t hex2int(char);
-static char int2hex[] = "0123456789abcdef";
-CHUNK_TYPE b2n_mask[CHUNK_BITS] = {
- 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
+static char int2hex[] = "0123456789abcdef";
+CHUNK_TYPE b2n_mask[CHUNK_BITS] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
#if CHUNK_BITS > 8
- 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
#if CHUNK_BITS > 16
- 0x00010000,0x00020000,0x00040000,0x00080000,
- 0x00100000,0x00200000,0x00400000,0x00800000,
- 0x01000000,0x02000000,0x04000000,0x08000000,
- 0x10000000,0x20000000,0x40000000,0x80000000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
#endif
#endif
};
/* Convert a hex character to its integer value. */
-static u_int8_t
-hex2int (char c)
+static u_int8_t
+hex2int(char c)
{
- if (c <= '9')
- return c - '0';
- if (c <= 'f')
- return 10 + c - 'a';
+ if (c <= '9')
+ return c - '0';
+ if (c <= 'f')
+ return 10 + c - 'a';
- return 0;
+ return 0;
}
int
-b2n_random (b2n_ptr n, u_int32_t bits)
+b2n_random(b2n_ptr n, u_int32_t bits)
{
- if (b2n_resize (n, (CHUNK_MASK + bits) >> CHUNK_SHIFTS))
- return -1;
+ if (b2n_resize(n, (CHUNK_MASK + bits) >> CHUNK_SHIFTS))
+ return -1;
- getrandom ((u_int8_t *)n->limp, CHUNK_BYTES * n->chunks);
+ getrandom((u_int8_t *) n->limp, CHUNK_BYTES * n->chunks);
- /* Get the number of significant bits right */
- if (bits & CHUNK_MASK)
- {
- CHUNK_TYPE m = (((1 << ((bits & CHUNK_MASK)-1)) - 1) << 1) | 1;
- n->limp[n->chunks-1] &= m;
- }
-
- n->dirty = 1;
- return 0;
+ /* Get the number of significant bits right */
+ if (bits & CHUNK_MASK) {
+ CHUNK_TYPE m = (((1 << ((bits & CHUNK_MASK) - 1)) - 1) << 1) | 1;
+ n->limp[n->chunks - 1] &= m;
+ }
+ n->dirty = 1;
+ return 0;
}
/* b2n management functions */
void
-b2n_init (b2n_ptr n)
+b2n_init(b2n_ptr n)
{
- n->chunks = 0;
- n->limp = 0;
+ n->chunks = 0;
+ n->limp = 0;
}
void
-b2n_clear (b2n_ptr n)
+b2n_clear(b2n_ptr n)
{
- if (n->limp)
- free (n->limp);
+ if (n->limp)
+ free(n->limp);
}
int
-b2n_resize (b2n_ptr n, unsigned int chunks)
+b2n_resize(b2n_ptr n, unsigned int chunks)
{
- size_t old = n->chunks;
- size_t size;
- CHUNK_TYPE *new;
+ size_t old = n->chunks;
+ size_t size;
+ CHUNK_TYPE *new;
- if (chunks == 0)
- chunks = 1;
+ if (chunks == 0)
+ chunks = 1;
- if (chunks == old)
- return 0;
+ if (chunks == old)
+ return 0;
- size = CHUNK_BYTES * chunks;
+ size = CHUNK_BYTES * chunks;
- new = realloc (n->limp, size);
- if (!new)
- return -1;
+ new = realloc(n->limp, size);
+ if (!new)
+ return -1;
- n->limp = new;
- n->chunks = chunks;
- n->bits = chunks << CHUNK_SHIFTS;
- n->dirty = 1;
+ n->limp = new;
+ n->chunks = chunks;
+ n->bits = chunks << CHUNK_SHIFTS;
+ n->dirty = 1;
- if (chunks > old)
- memset (n->limp + old, 0, size - CHUNK_BYTES * old);
+ if (chunks > old)
+ memset(n->limp + old, 0, size - CHUNK_BYTES * old);
- return 0;
+ return 0;
}
/* Simple assignment functions. */
int
-b2n_set (b2n_ptr d, b2n_ptr s)
+b2n_set(b2n_ptr d, b2n_ptr s)
{
- if (d == s)
- return 0;
-
- b2n_sigbit (s);
- if (b2n_resize (d, (CHUNK_MASK + s->bits) >> CHUNK_SHIFTS))
- return -1;
- memcpy (d->limp, s->limp, CHUNK_BYTES * d->chunks);
- d->bits = s->bits;
- d->dirty = s->dirty;
- return 0;
+ if (d == s)
+ return 0;
+
+ b2n_sigbit(s);
+ if (b2n_resize(d, (CHUNK_MASK + s->bits) >> CHUNK_SHIFTS))
+ return -1;
+ memcpy(d->limp, s->limp, CHUNK_BYTES * d->chunks);
+ d->bits = s->bits;
+ d->dirty = s->dirty;
+ return 0;
}
int
-b2n_set_null (b2n_ptr n)
+b2n_set_null(b2n_ptr n)
{
- if (b2n_resize (n, 1))
- return -1;
- n->limp[0] = n->bits = n->dirty = 0;
- return 0;
+ if (b2n_resize(n, 1))
+ return -1;
+ n->limp[0] = n->bits = n->dirty = 0;
+ return 0;
}
int
-b2n_set_ui (b2n_ptr n, unsigned int val)
+b2n_set_ui(b2n_ptr n, unsigned int val)
{
#if CHUNK_BITS < 32
- int i, chunks;
+ int i, chunks;
- chunks = (CHUNK_BYTES - 1 + sizeof (val)) / CHUNK_BYTES;
+ chunks = (CHUNK_BYTES - 1 + sizeof(val)) / CHUNK_BYTES;
- if (b2n_resize (n, chunks))
- return -1;
+ if (b2n_resize(n, chunks))
+ return -1;
- for (i = 0; i < chunks; i++)
- {
- n->limp[i] = val & CHUNK_BMASK;
- val >>= CHUNK_BITS;
- }
+ for (i = 0; i < chunks; i++) {
+ n->limp[i] = val & CHUNK_BMASK;
+ val >>= CHUNK_BITS;
+ }
#else
- if (b2n_resize (n, 1))
- return -1;
- n->limp[0] = val;
+ if (b2n_resize(n, 1))
+ return -1;
+ n->limp[0] = val;
#endif
- n->dirty = 1;
- return 0;
+ n->dirty = 1;
+ return 0;
}
/* XXX This one only takes hex at the moment. */
int
-b2n_set_str (b2n_ptr n, char *str)
+b2n_set_str(b2n_ptr n, char *str)
{
- int i, j, w, len, chunks;
- CHUNK_TYPE tmp;
-
- if (strncasecmp (str, "0x", 2))
- return -1;
-
- /* Make the hex string even lengthed */
- len = strlen (str) - 2;
- if (len & 1)
- {
- len ++;
- str ++;
- }
- else
- str += 2;
-
- len /= 2;
-
- chunks = (CHUNK_BYTES - 1 + len) / CHUNK_BYTES;
- if (b2n_resize (n, chunks))
- return -1;
- memset (n->limp, 0, CHUNK_BYTES * n->chunks);
-
- for (w = 0, i = 0; i < chunks; i++)
- {
- tmp = 0;
- for (j = (i == 0 ? ((len - 1) % CHUNK_BYTES) + 1 : CHUNK_BYTES); j > 0;
- j--)
- {
- tmp <<= 8;
- tmp |= (hex2int (str[w]) << 4) | hex2int (str[w + 1]);
- w += 2;
+ int i, j, w, len, chunks;
+ CHUNK_TYPE tmp;
+
+ if (strncasecmp(str, "0x", 2))
+ return -1;
+
+ /* Make the hex string even lengthed */
+ len = strlen(str) - 2;
+ if (len & 1) {
+ len++;
+ str++;
+ } else
+ str += 2;
+
+ len /= 2;
+
+ chunks = (CHUNK_BYTES - 1 + len) / CHUNK_BYTES;
+ if (b2n_resize(n, chunks))
+ return -1;
+ memset(n->limp, 0, CHUNK_BYTES * n->chunks);
+
+ for (w = 0, i = 0; i < chunks; i++) {
+ tmp = 0;
+ for (j = (i == 0 ? ((len - 1) % CHUNK_BYTES) + 1 : CHUNK_BYTES); j > 0;
+ j--) {
+ tmp <<= 8;
+ tmp |= (hex2int(str[w]) << 4) | hex2int(str[w + 1]);
+ w += 2;
+ }
+ n->limp[chunks - 1 - i] = tmp;
}
- n->limp[chunks - 1 - i] = tmp;
- }
- n->dirty = 1;
- return 0;
+ n->dirty = 1;
+ return 0;
}
/* Output function, mainly for debugging purposes. */
void
-b2n_print (b2n_ptr n)
+b2n_print(b2n_ptr n)
{
- int i, j, w, flag = 0;
- int left;
- char buffer[2 * CHUNK_BYTES];
- CHUNK_TYPE tmp;
-
- left = ((((7 + b2n_sigbit (n)) >> 3) - 1) % CHUNK_BYTES) + 1;
- printf ("0x");
- for (i = 0; i < n->chunks; i++)
- {
- tmp = n->limp[n->chunks - 1 - i];
- memset (buffer, '0', sizeof (buffer));
- for (w = 0, j = (i == 0 ? left : CHUNK_BYTES); j > 0; j--)
- {
- buffer[w++] = int2hex[(tmp >> 4) & 0xf];
- buffer[w++] = int2hex[tmp & 0xf];
- tmp >>= 8;
+ int i, j, w, flag = 0;
+ int left;
+ char buffer[2 * CHUNK_BYTES];
+ CHUNK_TYPE tmp;
+
+ left = ((((7 + b2n_sigbit(n)) >> 3) - 1) % CHUNK_BYTES) + 1;
+ printf("0x");
+ for (i = 0; i < n->chunks; i++) {
+ tmp = n->limp[n->chunks - 1 - i];
+ memset(buffer, '0', sizeof(buffer));
+ for (w = 0, j = (i == 0 ? left : CHUNK_BYTES); j > 0; j--) {
+ buffer[w++] = int2hex[(tmp >> 4) & 0xf];
+ buffer[w++] = int2hex[tmp & 0xf];
+ tmp >>= 8;
+ }
+
+ for (j = (i == 0 ? left - 1 : CHUNK_BYTES - 1); j >= 0; j--)
+ if (flag || (i == n->chunks - 1 && j == 0) ||
+ buffer[2 * j] != '0' || buffer[2 * j + 1] != '0') {
+ putchar(buffer[2 * j]);
+ putchar(buffer[2 * j + 1]);
+ flag = 1;
+ }
}
-
- for (j = (i == 0 ? left - 1: CHUNK_BYTES - 1); j >= 0; j--)
- if (flag || (i == n->chunks - 1 && j == 0) ||
- buffer[2 * j] != '0' || buffer[2 * j + 1] != '0')
- {
- putchar (buffer[2 * j]);
- putchar (buffer[2 * j + 1]);
- flag = 1;
- }
- }
- printf ("\n");
+ printf("\n");
}
int
-b2n_snprint (char *buf, size_t sz, b2n_ptr n)
+b2n_snprint(char *buf, size_t sz, b2n_ptr n)
{
- int i, j, w, flag = 0;
- size_t k;
- int left;
- char buffer[2 * CHUNK_BYTES];
- CHUNK_TYPE tmp;
-
- left = ((((7 + b2n_sigbit (n)) >> 3) - 1) % CHUNK_BYTES) + 1;
-
- k = strlcpy (buf, "0x", sz);
- for (i = 0; i < n->chunks && k < sz - 1; i++)
- {
- tmp = n->limp[n->chunks - 1 - i];
- memset (buffer, '0', sizeof (buffer));
- for (w = 0, j = (i == 0 ? left : CHUNK_BYTES); j > 0; j--)
- {
- buffer[w++] = int2hex[(tmp >> 4) & 0xf];
- buffer[w++] = int2hex[tmp & 0xf];
- tmp >>= 8;
+ int i, j, w, flag = 0;
+ size_t k;
+ int left;
+ char buffer[2 * CHUNK_BYTES];
+ CHUNK_TYPE tmp;
+
+ left = ((((7 + b2n_sigbit(n)) >> 3) - 1) % CHUNK_BYTES) + 1;
+
+ k = strlcpy(buf, "0x", sz);
+ for (i = 0; i < n->chunks && k < sz - 1; i++) {
+ tmp = n->limp[n->chunks - 1 - i];
+ memset(buffer, '0', sizeof(buffer));
+ for (w = 0, j = (i == 0 ? left : CHUNK_BYTES); j > 0; j--) {
+ buffer[w++] = int2hex[(tmp >> 4) & 0xf];
+ buffer[w++] = int2hex[tmp & 0xf];
+ tmp >>= 8;
+ }
+
+ for (j = (i == 0 ? left - 1 : CHUNK_BYTES - 1); j >= 0 && k < sz - 3; j--)
+ if (flag || (i == n->chunks - 1 && j == 0) ||
+ buffer[2 * j] != '0' || buffer[2 * j + 1] != '0') {
+ buf[k++] = buffer[2 * j];
+ buf[k++] = buffer[2 * j + 1];
+ flag = 1;
+ }
}
- for (j = (i == 0 ? left - 1: CHUNK_BYTES - 1); j >= 0 && k < sz - 3; j--)
- if (flag || (i == n->chunks - 1 && j == 0) ||
- buffer[2 * j] != '0' || buffer[2 * j + 1] != '0')
- {
- buf[k++] = buffer[2 * j];
- buf[k++] = buffer[2 * j + 1];
- flag = 1;
- }
- }
-
- buf[k++] = 0;
- return k;
+ buf[k++] = 0;
+ return k;
}
/* Arithmetic functions. */
u_int32_t
-b2n_sigbit (b2n_ptr n)
+b2n_sigbit(b2n_ptr n)
{
- int i, j;
+ int i, j;
- if (!n->dirty)
- return n->bits;
+ if (!n->dirty)
+ return n->bits;
- for (i = n->chunks - 1; i > 0; i--)
- if (n->limp[i])
- break;
+ for (i = n->chunks - 1; i > 0; i--)
+ if (n->limp[i])
+ break;
- if (!n->limp[i])
- return 0;
+ if (!n->limp[i])
+ return 0;
- for (j = CHUNK_MASK; j > 0; j--)
- if (n->limp[i] & b2n_mask[j])
- break;
+ for (j = CHUNK_MASK; j > 0; j--)
+ if (n->limp[i] & b2n_mask[j])
+ break;
- n->bits = (i << CHUNK_SHIFTS) + j + 1;
- n->dirty = 0;
- return n->bits;
+ n->bits = (i << CHUNK_SHIFTS) + j + 1;
+ n->dirty = 0;
+ return n->bits;
}
/* Addition on GF(2)[x] is nice, its just an XOR. */
int
-b2n_add (b2n_ptr d, b2n_ptr a, b2n_ptr b)
+b2n_add(b2n_ptr d, b2n_ptr a, b2n_ptr b)
{
- int i;
- b2n_ptr bmin, bmax;
-
- if (!b2n_cmp_null (a))
- return b2n_set (d, b);
-
- if (!b2n_cmp_null (b))
- return b2n_set (d, a);
-
- bmin = B2N_MIN (a,b);
- bmax = B2N_MAX (a,b);
-
- if (b2n_resize (d, bmax->chunks))
- return -1;
-
- for (i = 0; i < bmin->chunks; i++)
- d->limp[i] = bmax->limp[i] ^ bmin->limp[i];
-
- /*
- * If d is not bmax, we have to copy the rest of the bytes, and also
- * need to adjust to number of relevant bits.
- */
- if (d != bmax)
- {
- for ( ; i < bmax->chunks; i++)
- d->limp[i] = bmax->limp[i];
-
- d->bits = bmax->bits;
- }
-
- /*
- * Help to converse memory. When the result of the addition is zero
- * truncate the used amount of memory.
- */
- if (d != bmax && !b2n_cmp_null (d))
- return b2n_set_null (d);
- else
- d->dirty = 1;
- return 0;
+ int i;
+ b2n_ptr bmin, bmax;
+
+ if (!b2n_cmp_null(a))
+ return b2n_set(d, b);
+
+ if (!b2n_cmp_null(b))
+ return b2n_set(d, a);
+
+ bmin = B2N_MIN(a, b);
+ bmax = B2N_MAX(a, b);
+
+ if (b2n_resize(d, bmax->chunks))
+ return -1;
+
+ for (i = 0; i < bmin->chunks; i++)
+ d->limp[i] = bmax->limp[i] ^ bmin->limp[i];
+
+ /*
+ * If d is not bmax, we have to copy the rest of the bytes, and also
+ * need to adjust to number of relevant bits.
+ */
+ if (d != bmax) {
+ for (; i < bmax->chunks; i++)
+ d->limp[i] = bmax->limp[i];
+
+ d->bits = bmax->bits;
+ }
+ /*
+ * Help to converse memory. When the result of the addition is zero
+ * truncate the used amount of memory.
+ */
+ if (d != bmax && !b2n_cmp_null(d))
+ return b2n_set_null(d);
+ else
+ d->dirty = 1;
+ return 0;
}
/* Compare two polynomials. */
int
-b2n_cmp (b2n_ptr n, b2n_ptr m)
+b2n_cmp(b2n_ptr n, b2n_ptr m)
{
- int sn, sm;
- int i;
+ int sn, sm;
+ int i;
- sn = b2n_sigbit (n);
- sm = b2n_sigbit (m);
+ sn = b2n_sigbit(n);
+ sm = b2n_sigbit(m);
- if (sn > sm)
- return 1;
- if (sn < sm)
- return -1;
+ if (sn > sm)
+ return 1;
+ if (sn < sm)
+ return -1;
- for (i = n->chunks-1; i >= 0; i--)
- if (n->limp[i] > m->limp[i])
- return 1;
- else if (n->limp[i] < m->limp[i])
- return -1;
+ for (i = n->chunks - 1; i >= 0; i--)
+ if (n->limp[i] > m->limp[i])
+ return 1;
+ else if (n->limp[i] < m->limp[i])
+ return -1;
- return 0;
+ return 0;
}
int
-b2n_cmp_null (b2n_ptr a)
+b2n_cmp_null(b2n_ptr a)
{
- int i = 0;
+ int i = 0;
- do
- {
- if (a->limp[i])
- return 1;
- }
- while (++i < a->chunks);
+ do {
+ if (a->limp[i])
+ return 1;
+ }
+ while (++i < a->chunks);
- return 0;
+ return 0;
}
/* Left shift, needed for polynomial multiplication. */
int
-b2n_lshift (b2n_ptr d, b2n_ptr n, unsigned int s)
+b2n_lshift(b2n_ptr d, b2n_ptr n, unsigned int s)
{
- int i, maj, min, chunks;
- u_int16_t bits = b2n_sigbit (n), add;
- CHUNK_TYPE *p, *op;
-
- if (!s)
- return b2n_set (d, n);
-
- maj = s >> CHUNK_SHIFTS;
- min = s & CHUNK_MASK;
-
- add = (!(bits & CHUNK_MASK) || ((bits & CHUNK_MASK) + min) > CHUNK_MASK)
- ? 1 : 0;
- chunks = n->chunks;
- if (b2n_resize (d, chunks + maj + add))
- return -1;
- memmove (d->limp + maj, n->limp, CHUNK_BYTES * chunks);
-
- if (maj)
- memset (d->limp, 0, CHUNK_BYTES * maj);
- if (add)
- d->limp[d->chunks - 1] = 0;
-
- /* If !min there are no bit shifts, we are done */
- if (!min)
- return 0;
-
- op = p = &d->limp[d->chunks - 1];
- for (i = d->chunks - 2; i >= maj; i--)
- {
- op--;
- *p = (*p << min) | (*op >> (CHUNK_BITS - min));
- p--;
- }
- *p <<= min;
-
- d->dirty = 0;
- d->bits = bits + (maj << CHUNK_SHIFTS) + min;
- return 0;
+ int i, maj, min, chunks;
+ u_int16_t bits = b2n_sigbit(n), add;
+ CHUNK_TYPE *p, *op;
+
+ if (!s)
+ return b2n_set(d, n);
+
+ maj = s >> CHUNK_SHIFTS;
+ min = s & CHUNK_MASK;
+
+ add = (!(bits & CHUNK_MASK) || ((bits & CHUNK_MASK) + min) > CHUNK_MASK)
+ ? 1 : 0;
+ chunks = n->chunks;
+ if (b2n_resize(d, chunks + maj + add))
+ return -1;
+ memmove(d->limp + maj, n->limp, CHUNK_BYTES * chunks);
+
+ if (maj)
+ memset(d->limp, 0, CHUNK_BYTES * maj);
+ if (add)
+ d->limp[d->chunks - 1] = 0;
+
+ /* If !min there are no bit shifts, we are done */
+ if (!min)
+ return 0;
+
+ op = p = &d->limp[d->chunks - 1];
+ for (i = d->chunks - 2; i >= maj; i--) {
+ op--;
+ *p = (*p << min) | (*op >> (CHUNK_BITS - min));
+ p--;
+ }
+ *p <<= min;
+
+ d->dirty = 0;
+ d->bits = bits + (maj << CHUNK_SHIFTS) + min;
+ return 0;
}
/* Right shift, needed for polynomial division. */
int
-b2n_rshift (b2n_ptr d, b2n_ptr n, unsigned int s)
+b2n_rshift(b2n_ptr d, b2n_ptr n, unsigned int s)
{
- int maj, min, size = n->chunks, newsize;
- b2n_ptr tmp;
+ int maj, min, size = n->chunks, newsize;
+ b2n_ptr tmp;
- if (!s)
- return b2n_set (d, n);
+ if (!s)
+ return b2n_set(d, n);
- maj = s >> CHUNK_SHIFTS;
+ maj = s >> CHUNK_SHIFTS;
- newsize = size - maj;
+ newsize = size - maj;
- if (size < maj)
- return b2n_set_null (d);
+ if (size < maj)
+ return b2n_set_null(d);
- min = (CHUNK_BITS - (s & CHUNK_MASK)) & CHUNK_MASK;
- if (min)
- {
- if ((b2n_sigbit (n) & CHUNK_MASK) > (u_int32_t)min)
- newsize++;
+ min = (CHUNK_BITS - (s & CHUNK_MASK)) & CHUNK_MASK;
+ if (min) {
+ if ((b2n_sigbit(n) & CHUNK_MASK) > (u_int32_t) min)
+ newsize++;
- if (b2n_lshift (d, n, min))
- return -1;
- tmp = d;
- }
- else
- tmp = n;
+ if (b2n_lshift(d, n, min))
+ return -1;
+ tmp = d;
+ } else
+ tmp = n;
- memmove (d->limp, tmp->limp + maj + (min ? 1 : 0), CHUNK_BYTES * newsize);
- if (b2n_resize (d, newsize))
- return -1;
+ memmove(d->limp, tmp->limp + maj + (min ? 1 : 0), CHUNK_BYTES * newsize);
+ if (b2n_resize(d, newsize))
+ return -1;
- d->bits = tmp->bits - ((maj + (min ? 1 : 0)) << CHUNK_SHIFTS);
- return 0;
+ d->bits = tmp->bits - ((maj + (min ? 1 : 0)) << CHUNK_SHIFTS);
+ return 0;
}
/* Normal polynomial multiplication. */
int
-b2n_mul (b2n_ptr d, b2n_ptr n, b2n_ptr m)
+b2n_mul(b2n_ptr d, b2n_ptr n, b2n_ptr m)
{
- int i, j;
- b2n_t tmp, tmp2;
-
- if (!b2n_cmp_null (m) || !b2n_cmp_null (n))
- return b2n_set_null (d);
-
- if (b2n_sigbit (m) == 1)
- return b2n_set (d, n);
-
- if (b2n_sigbit (n) == 1)
- return b2n_set (d, m);
-
- b2n_init (tmp);
- b2n_init (tmp2);
-
- if (b2n_set (tmp, B2N_MAX (n, m)))
- goto fail;
- if (b2n_set (tmp2, B2N_MIN (n, m)))
- goto fail;
-
- if (b2n_set_null (d))
- goto fail;
-
- for (i = 0; i < tmp2->chunks; i++)
- if (tmp2->limp[i])
- for (j = 0; j < CHUNK_BITS; j++)
- {
- if (tmp2->limp[i] & b2n_mask[j])
- if (b2n_add (d, d, tmp))
- goto fail;
-
- if (b2n_lshift (tmp, tmp, 1))
- goto fail;
- }
- else
- if (b2n_lshift (tmp, tmp, CHUNK_BITS))
- goto fail;
-
- b2n_clear (tmp);
- b2n_clear (tmp2);
- return 0;
-
- fail:
- b2n_clear (tmp);
- b2n_clear (tmp2);
- return -1;
+ int i, j;
+ b2n_t tmp, tmp2;
+
+ if (!b2n_cmp_null(m) || !b2n_cmp_null(n))
+ return b2n_set_null(d);
+
+ if (b2n_sigbit(m) == 1)
+ return b2n_set(d, n);
+
+ if (b2n_sigbit(n) == 1)
+ return b2n_set(d, m);
+
+ b2n_init(tmp);
+ b2n_init(tmp2);
+
+ if (b2n_set(tmp, B2N_MAX(n, m)))
+ goto fail;
+ if (b2n_set(tmp2, B2N_MIN(n, m)))
+ goto fail;
+
+ if (b2n_set_null(d))
+ goto fail;
+
+ for (i = 0; i < tmp2->chunks; i++)
+ if (tmp2->limp[i])
+ for (j = 0; j < CHUNK_BITS; j++) {
+ if (tmp2->limp[i] & b2n_mask[j])
+ if (b2n_add(d, d, tmp))
+ goto fail;
+
+ if (b2n_lshift(tmp, tmp, 1))
+ goto fail;
+ }
+ else if (b2n_lshift(tmp, tmp, CHUNK_BITS))
+ goto fail;
+
+ b2n_clear(tmp);
+ b2n_clear(tmp2);
+ return 0;
+
+fail:
+ b2n_clear(tmp);
+ b2n_clear(tmp2);
+ return -1;
}
/*
@@ -556,46 +535,42 @@ b2n_mul (b2n_ptr d, b2n_ptr n, b2n_ptr m)
* multiplication.
*/
int
-b2n_square (b2n_ptr d, b2n_ptr n)
+b2n_square(b2n_ptr d, b2n_ptr n)
{
- int i, j, maj, min, bits, chunk;
- b2n_t t;
-
- maj = b2n_sigbit (n);
- min = maj & CHUNK_MASK;
- maj = (maj + CHUNK_MASK) >> CHUNK_SHIFTS;
-
- b2n_init (t);
- if (b2n_resize (t, 2 * maj + ((CHUNK_MASK + 2 * min) >> CHUNK_SHIFTS)))
- {
- b2n_clear (t);
- return -1;
- }
-
- chunk = 0;
- bits = 0;
-
- for (i = 0; i < maj; i++)
- if (n->limp[i])
- for (j = 0; j < CHUNK_BITS; j++)
- {
- if (n->limp[i] & b2n_mask[j])
- t->limp[chunk] ^= b2n_mask[bits];
-
- bits += 2;
- if (bits >= CHUNK_BITS)
- {
- chunk++;
- bits &= CHUNK_MASK;
- }
- }
- else
- chunk += 2;
+ int i, j, maj, min, bits, chunk;
+ b2n_t t;
+
+ maj = b2n_sigbit(n);
+ min = maj & CHUNK_MASK;
+ maj = (maj + CHUNK_MASK) >> CHUNK_SHIFTS;
- t->dirty = 1;
- B2N_SWAP (d, t);
- b2n_clear (t);
- return 0;
+ b2n_init(t);
+ if (b2n_resize(t, 2 * maj + ((CHUNK_MASK + 2 * min) >> CHUNK_SHIFTS))) {
+ b2n_clear(t);
+ return -1;
+ }
+ chunk = 0;
+ bits = 0;
+
+ for (i = 0; i < maj; i++)
+ if (n->limp[i])
+ for (j = 0; j < CHUNK_BITS; j++) {
+ if (n->limp[i] & b2n_mask[j])
+ t->limp[chunk] ^= b2n_mask[bits];
+
+ bits += 2;
+ if (bits >= CHUNK_BITS) {
+ chunk++;
+ bits &= CHUNK_MASK;
+ }
+ }
+ else
+ chunk += 2;
+
+ t->dirty = 1;
+ B2N_SWAP(d, t);
+ b2n_clear(t);
+ return 0;
}
/*
@@ -603,248 +578,240 @@ b2n_square (b2n_ptr d, b2n_ptr n)
* These functions are far from optimal in speed.
*/
int
-b2n_div_q (b2n_ptr d, b2n_ptr n, b2n_ptr m)
+b2n_div_q(b2n_ptr d, b2n_ptr n, b2n_ptr m)
{
- b2n_t r;
- int rv;
+ b2n_t r;
+ int rv;
- b2n_init (r);
- rv = b2n_div (d, r, n, m);
- b2n_clear (r);
- return rv;
+ b2n_init(r);
+ rv = b2n_div(d, r, n, m);
+ b2n_clear(r);
+ return rv;
}
int
-b2n_div_r (b2n_ptr r, b2n_ptr n, b2n_ptr m)
+b2n_div_r(b2n_ptr r, b2n_ptr n, b2n_ptr m)
{
- b2n_t q;
- int rv;
+ b2n_t q;
+ int rv;
- b2n_init (q);
- rv = b2n_div (q, r, n, m);
- b2n_clear (q);
- return rv;
+ b2n_init(q);
+ rv = b2n_div(q, r, n, m);
+ b2n_clear(q);
+ return rv;
}
int
-b2n_div (b2n_ptr q, b2n_ptr r, b2n_ptr n, b2n_ptr m)
+b2n_div(b2n_ptr q, b2n_ptr r, b2n_ptr n, b2n_ptr m)
{
- int i, j, len, bits;
- u_int32_t sm, sn;
- b2n_t nenn, div, shift, mask;
-
- /* If Teiler > Zaehler, the result is 0 */
- if ((sm = b2n_sigbit (m)) > (sn = b2n_sigbit (n)))
- {
- if (b2n_set_null (q))
- return -1;
- return b2n_set (r, n);
- }
-
- if (sm == 0)
- /* Division by Zero */
- return -1;
- else if (sm == 1)
- {
- /* Division by the One-Element */
- if (b2n_set (q, n))
- return -1;
- return b2n_set_null (r);
- }
-
- b2n_init (nenn);
- b2n_init (div);
- b2n_init (shift);
- b2n_init (mask);
-
- if (b2n_set (nenn, n))
- goto fail;
- if (b2n_set (div, m))
- goto fail;
- if (b2n_set (shift, m))
- goto fail;
- if (b2n_set_ui (mask, 1))
- goto fail;
-
- if (b2n_resize (q, (sn - sm + CHUNK_MASK) >> CHUNK_SHIFTS))
- goto fail;
- memset (q->limp, 0, CHUNK_BYTES * q->chunks);
-
- if (b2n_lshift (shift, shift, sn - sm))
- goto fail;
- if (b2n_lshift (mask, mask, sn - sm))
- goto fail;
-
- /* Number of significant octets */
- len = (sn - 1) >> CHUNK_SHIFTS;
- /* The first iteration is done over the relevant bits */
- bits = (CHUNK_MASK + sn) & CHUNK_MASK;
- for (i = len; i >= 0 && b2n_sigbit (nenn) >= sm; i--)
- for (j = (i == len ? bits : CHUNK_MASK); j >= 0 && b2n_sigbit (nenn) >= sm;
- j--)
- {
- if (nenn->limp[i] & b2n_mask[j])
- {
- if (b2n_sub (nenn, nenn, shift))
- goto fail;
- if (b2n_add (q, q, mask))
- goto fail;
- }
- if (b2n_rshift (shift, shift, 1))
- goto fail;
- if (b2n_rshift (mask, mask, 1))
- goto fail;
- }
-
- B2N_SWAP (r, nenn);
-
- b2n_clear (nenn);
- b2n_clear (div);
- b2n_clear (shift);
- b2n_clear (mask);
- return 0;
+ int i, j, len, bits;
+ u_int32_t sm, sn;
+ b2n_t nenn, div, shift, mask;
+
+ /* If Teiler > Zaehler, the result is 0 */
+ if ((sm = b2n_sigbit(m)) > (sn = b2n_sigbit(n))) {
+ if (b2n_set_null(q))
+ return -1;
+ return b2n_set(r, n);
+ }
+ if (sm == 0)
+ /* Division by Zero */
+ return -1;
+ else if (sm == 1) {
+ /* Division by the One-Element */
+ if (b2n_set(q, n))
+ return -1;
+ return b2n_set_null(r);
+ }
+ b2n_init(nenn);
+ b2n_init(div);
+ b2n_init(shift);
+ b2n_init(mask);
+
+ if (b2n_set(nenn, n))
+ goto fail;
+ if (b2n_set(div, m))
+ goto fail;
+ if (b2n_set(shift, m))
+ goto fail;
+ if (b2n_set_ui(mask, 1))
+ goto fail;
+
+ if (b2n_resize(q, (sn - sm + CHUNK_MASK) >> CHUNK_SHIFTS))
+ goto fail;
+ memset(q->limp, 0, CHUNK_BYTES * q->chunks);
+
+ if (b2n_lshift(shift, shift, sn - sm))
+ goto fail;
+ if (b2n_lshift(mask, mask, sn - sm))
+ goto fail;
+
+ /* Number of significant octets */
+ len = (sn - 1) >> CHUNK_SHIFTS;
+ /* The first iteration is done over the relevant bits */
+ bits = (CHUNK_MASK + sn) & CHUNK_MASK;
+ for (i = len; i >= 0 && b2n_sigbit(nenn) >= sm; i--)
+ for (j = (i == len ? bits : CHUNK_MASK); j >= 0 && b2n_sigbit(nenn) >= sm;
+ j--) {
+ if (nenn->limp[i] & b2n_mask[j]) {
+ if (b2n_sub(nenn, nenn, shift))
+ goto fail;
+ if (b2n_add(q, q, mask))
+ goto fail;
+ }
+ if (b2n_rshift(shift, shift, 1))
+ goto fail;
+ if (b2n_rshift(mask, mask, 1))
+ goto fail;
+ }
+
+ B2N_SWAP(r, nenn);
+
+ b2n_clear(nenn);
+ b2n_clear(div);
+ b2n_clear(shift);
+ b2n_clear(mask);
+ return 0;
fail:
- b2n_clear (nenn);
- b2n_clear (div);
- b2n_clear (shift);
- b2n_clear (mask);
- return -1;
+ b2n_clear(nenn);
+ b2n_clear(div);
+ b2n_clear(shift);
+ b2n_clear(mask);
+ return -1;
}
/* Functions for Operation on GF(2**n) ~= GF(2)[x]/p(x). */
int
-b2n_mod (b2n_ptr m, b2n_ptr n, b2n_ptr p)
+b2n_mod(b2n_ptr m, b2n_ptr n, b2n_ptr p)
{
- int bits, size;
-
- if (b2n_div_r (m, n, p))
- return -1;
-
- bits = b2n_sigbit (m);
- size = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS);
- if (size == 0)
- size = 1;
- if (m->chunks > size)
- if (b2n_resize (m, size))
- return -1;
-
- m->bits = bits;
- m->dirty = 0;
- return 0;
+ int bits, size;
+
+ if (b2n_div_r(m, n, p))
+ return -1;
+
+ bits = b2n_sigbit(m);
+ size = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS);
+ if (size == 0)
+ size = 1;
+ if (m->chunks > size)
+ if (b2n_resize(m, size))
+ return -1;
+
+ m->bits = bits;
+ m->dirty = 0;
+ return 0;
}
int
-b2n_gcd (b2n_ptr e, b2n_ptr go, b2n_ptr ho)
+b2n_gcd(b2n_ptr e, b2n_ptr go, b2n_ptr ho)
{
- b2n_t g, h;
-
- b2n_init (g);
- b2n_init (h);
- if (b2n_set (g, go))
- goto fail;
- if (b2n_set (h, ho))
- goto fail;
-
- while (b2n_cmp_null (h))
- {
- if (b2n_mod (g, g, h))
- goto fail;
- B2N_SWAP (g, h);
- }
+ b2n_t g, h;
+
+ b2n_init(g);
+ b2n_init(h);
+ if (b2n_set(g, go))
+ goto fail;
+ if (b2n_set(h, ho))
+ goto fail;
+
+ while (b2n_cmp_null(h)) {
+ if (b2n_mod(g, g, h))
+ goto fail;
+ B2N_SWAP(g, h);
+ }
- B2N_SWAP (e, g);
+ B2N_SWAP(e, g);
- b2n_clear (g);
- b2n_clear (h);
- return 0;
+ b2n_clear(g);
+ b2n_clear(h);
+ return 0;
fail:
- b2n_clear (g);
- b2n_clear (h);
- return -1;
+ b2n_clear(g);
+ b2n_clear(h);
+ return -1;
}
int
-b2n_mul_inv (b2n_ptr ga, b2n_ptr be, b2n_ptr p)
+b2n_mul_inv(b2n_ptr ga, b2n_ptr be, b2n_ptr p)
{
- b2n_t a;
+ b2n_t a;
- b2n_init (a);
- if (b2n_set_ui (a, 1))
- goto fail;
+ b2n_init(a);
+ if (b2n_set_ui(a, 1))
+ goto fail;
- if (b2n_div_mod (ga, a, be, p))
- goto fail;
+ if (b2n_div_mod(ga, a, be, p))
+ goto fail;
- b2n_clear (a);
- return 0;
+ b2n_clear(a);
+ return 0;
- fail:
- b2n_clear (a);
- return -1;
+fail:
+ b2n_clear(a);
+ return -1;
}
int
-b2n_div_mod (b2n_ptr ga, b2n_ptr a, b2n_ptr be, b2n_ptr p)
+b2n_div_mod(b2n_ptr ga, b2n_ptr a, b2n_ptr be, b2n_ptr p)
{
- b2n_t s0, s1, s2, q, r0, r1;
-
- /* There is no multiplicative inverse to Null. */
- if (!b2n_cmp_null (be))
- return b2n_set_null (ga);
-
- b2n_init (s0);
- b2n_init (s1);
- b2n_init (s2);
- b2n_init (r0);
- b2n_init (r1);
- b2n_init (q);
-
- if (b2n_set (r0, p))
- goto fail;
- if (b2n_set (r1, be))
- goto fail;
-
- if (b2n_set_null (s0))
- goto fail;
- if (b2n_set (s1, a))
- goto fail;
-
- while (b2n_cmp_null (r1))
- {
- if (b2n_div (q, r0, r0, r1))
- goto fail;
- B2N_SWAP (r0, r1);
-
- if (b2n_mul (s2, q, s1))
- goto fail;
- if (b2n_mod (s2, s2, p))
- goto fail;
- if (b2n_sub (s2, s0, s2))
- goto fail;
-
- B2N_SWAP (s0, s1);
- B2N_SWAP (s1, s2);
- }
- B2N_SWAP (ga, s0);
-
- b2n_clear (s0);
- b2n_clear (s1);
- b2n_clear (s2);
- b2n_clear (r0);
- b2n_clear (r1);
- b2n_clear (q);
- return 0;
+ b2n_t s0, s1, s2, q, r0, r1;
+
+ /* There is no multiplicative inverse to Null. */
+ if (!b2n_cmp_null(be))
+ return b2n_set_null(ga);
+
+ b2n_init(s0);
+ b2n_init(s1);
+ b2n_init(s2);
+ b2n_init(r0);
+ b2n_init(r1);
+ b2n_init(q);
+
+ if (b2n_set(r0, p))
+ goto fail;
+ if (b2n_set(r1, be))
+ goto fail;
+
+ if (b2n_set_null(s0))
+ goto fail;
+ if (b2n_set(s1, a))
+ goto fail;
+
+ while (b2n_cmp_null(r1)) {
+ if (b2n_div(q, r0, r0, r1))
+ goto fail;
+ B2N_SWAP(r0, r1);
+
+ if (b2n_mul(s2, q, s1))
+ goto fail;
+ if (b2n_mod(s2, s2, p))
+ goto fail;
+ if (b2n_sub(s2, s0, s2))
+ goto fail;
+
+ B2N_SWAP(s0, s1);
+ B2N_SWAP(s1, s2);
+ }
+ B2N_SWAP(ga, s0);
+
+ b2n_clear(s0);
+ b2n_clear(s1);
+ b2n_clear(s2);
+ b2n_clear(r0);
+ b2n_clear(r1);
+ b2n_clear(q);
+ return 0;
fail:
- b2n_clear (s0);
- b2n_clear (s1);
- b2n_clear (s2);
- b2n_clear (r0);
- b2n_clear (r1);
- b2n_clear (q);
- return -1;
+ b2n_clear(s0);
+ b2n_clear(s1);
+ b2n_clear(s2);
+ b2n_clear(r0);
+ b2n_clear(r1);
+ b2n_clear(q);
+ return -1;
}
/*
@@ -854,33 +821,32 @@ fail:
* If z is a square root, z + 1 is the other.
*/
int
-b2n_trace (b2n_ptr ho, b2n_ptr a, b2n_ptr p)
+b2n_trace(b2n_ptr ho, b2n_ptr a, b2n_ptr p)
{
- int i, m = b2n_sigbit (p) - 1;
- b2n_t h;
-
- b2n_init (h);
- if (b2n_set (h, a))
- goto fail;
-
- for (i = 0; i < m - 1; i++)
- {
- if (b2n_square (h, h))
- goto fail;
- if (b2n_mod (h, h, p))
- goto fail;
-
- if (b2n_add (h, h, a))
- goto fail;
- }
- B2N_SWAP (ho, h);
-
- b2n_clear (h);
- return 0;
-
- fail:
- b2n_clear (h);
- return -1;
+ int i, m = b2n_sigbit(p) - 1;
+ b2n_t h;
+
+ b2n_init(h);
+ if (b2n_set(h, a))
+ goto fail;
+
+ for (i = 0; i < m - 1; i++) {
+ if (b2n_square(h, h))
+ goto fail;
+ if (b2n_mod(h, h, p))
+ goto fail;
+
+ if (b2n_add(h, h, a))
+ goto fail;
+ }
+ B2N_SWAP(ho, h);
+
+ b2n_clear(h);
+ return 0;
+
+fail:
+ b2n_clear(h);
+ return -1;
}
/*
@@ -888,38 +854,37 @@ b2n_trace (b2n_ptr ho, b2n_ptr a, b2n_ptr p)
* irreduceable polynomial is odd.
*/
int
-b2n_halftrace (b2n_ptr ho, b2n_ptr a, b2n_ptr p)
+b2n_halftrace(b2n_ptr ho, b2n_ptr a, b2n_ptr p)
{
- int i, m = b2n_sigbit (p) - 1;
- b2n_t h;
-
- b2n_init (h);
- if (b2n_set (h, a))
- goto fail;
-
- for (i = 0; i < (m - 1) / 2; i++)
- {
- if (b2n_square (h, h))
- goto fail;
- if (b2n_mod (h, h, p))
- goto fail;
- if (b2n_square (h, h))
- goto fail;
- if (b2n_mod (h, h, p))
- goto fail;
-
- if (b2n_add (h, h, a))
- goto fail;
- }
-
- B2N_SWAP (ho, h);
-
- b2n_clear (h);
- return 0;
-
- fail:
- b2n_clear (h);
- return -1;
+ int i, m = b2n_sigbit(p) - 1;
+ b2n_t h;
+
+ b2n_init(h);
+ if (b2n_set(h, a))
+ goto fail;
+
+ for (i = 0; i < (m - 1) / 2; i++) {
+ if (b2n_square(h, h))
+ goto fail;
+ if (b2n_mod(h, h, p))
+ goto fail;
+ if (b2n_square(h, h))
+ goto fail;
+ if (b2n_mod(h, h, p))
+ goto fail;
+
+ if (b2n_add(h, h, a))
+ goto fail;
+ }
+
+ B2N_SWAP(ho, h);
+
+ b2n_clear(h);
+ return 0;
+
+fail:
+ b2n_clear(h);
+ return -1;
}
/*
@@ -927,111 +892,107 @@ b2n_halftrace (b2n_ptr ho, b2n_ptr a, b2n_ptr p)
* irreduceable polynomial. If m is odd, use the half trace.
*/
int
-b2n_sqrt (b2n_ptr zo, b2n_ptr b, b2n_ptr ip)
+b2n_sqrt(b2n_ptr zo, b2n_ptr b, b2n_ptr ip)
{
- int i, m = b2n_sigbit (ip) - 1;
- b2n_t w, p, temp, z;
-
- if (!b2n_cmp_null (b))
- return b2n_set_null (z);
-
- if (m & 1)
- return b2n_halftrace (zo, b, ip);
-
- b2n_init (z);
- b2n_init (w);
- b2n_init (p);
- b2n_init (temp);
-
- do
- {
- if (b2n_random (p, m))
- goto fail;
- if (b2n_set_null (z))
- goto fail;
- if (b2n_set (w, p))
- goto fail;
-
- for (i = 1; i < m; i++)
- {
- if (b2n_square (z, z)) /* z**2 */
- goto fail;
- if (b2n_mod (z, z, ip))
- goto fail;
-
- if (b2n_square (w, w)) /* w**2 */
- goto fail;
- if (b2n_mod (w, w, ip))
- goto fail;
-
- if (b2n_mul (temp, w, b)) /* w**2 * b */
- goto fail;
- if (b2n_mod (temp, temp, ip))
- goto fail;
- if (b2n_add (z, z, temp)) /* z**2 + w**2 + b */
- goto fail;
-
- if (b2n_add (w, w, p)) /* w**2 + p */
- goto fail;
+ int i, m = b2n_sigbit(ip) - 1;
+ b2n_t w, p, temp, z;
+
+ if (!b2n_cmp_null(b))
+ return b2n_set_null(z);
+
+ if (m & 1)
+ return b2n_halftrace(zo, b, ip);
+
+ b2n_init(z);
+ b2n_init(w);
+ b2n_init(p);
+ b2n_init(temp);
+
+ do {
+ if (b2n_random(p, m))
+ goto fail;
+ if (b2n_set_null(z))
+ goto fail;
+ if (b2n_set(w, p))
+ goto fail;
+
+ for (i = 1; i < m; i++) {
+ if (b2n_square(z, z)) /* z**2 */
+ goto fail;
+ if (b2n_mod(z, z, ip))
+ goto fail;
+
+ if (b2n_square(w, w)) /* w**2 */
+ goto fail;
+ if (b2n_mod(w, w, ip))
+ goto fail;
+
+ if (b2n_mul(temp, w, b)) /* w**2 * b */
+ goto fail;
+ if (b2n_mod(temp, temp, ip))
+ goto fail;
+ if (b2n_add(z, z, temp)) /* z**2 + w**2 + b */
+ goto fail;
+
+ if (b2n_add(w, w, p)) /* w**2 + p */
+ goto fail;
+ }
}
- }
- while (!b2n_cmp_null (w));
-
- B2N_SWAP (zo, z);
-
- b2n_clear (w);
- b2n_clear (p);
- b2n_clear (temp);
- b2n_clear (z);
- return 0;
-
- fail:
- b2n_clear (w);
- b2n_clear (p);
- b2n_clear (temp);
- b2n_clear (z);
- return -1;
+ while (!b2n_cmp_null(w));
+
+ B2N_SWAP(zo, z);
+
+ b2n_clear(w);
+ b2n_clear(p);
+ b2n_clear(temp);
+ b2n_clear(z);
+ return 0;
+
+fail:
+ b2n_clear(w);
+ b2n_clear(p);
+ b2n_clear(temp);
+ b2n_clear(z);
+ return -1;
}
/* Exponentiation modulo a polynomial. */
int
-b2n_exp_mod (b2n_ptr d, b2n_ptr b0, u_int32_t e, b2n_ptr p)
+b2n_exp_mod(b2n_ptr d, b2n_ptr b0, u_int32_t e, b2n_ptr p)
{
- b2n_t u, b;
-
- b2n_init (u);
- b2n_init (b);
- if (b2n_set_ui (u, 1))
- goto fail;
- if (b2n_mod (b, b0, p))
- goto fail;
-
- while (e)
- {
- if (e & 1)
- {
- if (b2n_mul (u, u, b))
- goto fail;
- if (b2n_mod (u, u, p))
- goto fail;
+ b2n_t u, b;
+
+ b2n_init(u);
+ b2n_init(b);
+ if (b2n_set_ui(u, 1))
+ goto fail;
+ if (b2n_mod(b, b0, p))
+ goto fail;
+
+ while (e) {
+ if (e & 1) {
+ if (b2n_mul(u, u, b))
+ goto fail;
+ if (b2n_mod(u, u, p))
+ goto fail;
+ }
+ if (b2n_square(b, b))
+ goto fail;
+ if (b2n_mod(b, b, p))
+ goto fail;
+ e >>= 1;
}
- if (b2n_square (b, b))
- goto fail;
- if (b2n_mod (b, b, p))
- goto fail;
- e >>= 1;
- }
-
- B2N_SWAP (d, u);
-
- b2n_clear (u);
- b2n_clear (b);
- return 0;
-
- fail:
- b2n_clear (u);
- b2n_clear (b);
- return -1;
+
+ B2N_SWAP(d, u);
+
+ b2n_clear(u);
+ b2n_clear(b);
+ return 0;
+
+fail:
+ b2n_clear(u);
+ b2n_clear(b);
+ return -1;
}
/*
@@ -1042,106 +1003,98 @@ b2n_exp_mod (b2n_ptr d, b2n_ptr b0, u_int32_t e, b2n_ptr p)
/* Normal addition behaves as Z_{2**n} and not F_{2**n}. */
int
-b2n_nadd (b2n_ptr d0, b2n_ptr a0, b2n_ptr b0)
+b2n_nadd(b2n_ptr d0, b2n_ptr a0, b2n_ptr b0)
{
- int i, carry;
- b2n_ptr a, b;
- b2n_t d;
-
- if (!b2n_cmp_null (a0))
- return b2n_set (d0, b0);
-
- if (!b2n_cmp_null (b0))
- return b2n_set (d0, a0);
-
- b2n_init (d);
- a = B2N_MAX (a0, b0);
- b = B2N_MIN (a0, b0);
-
- if (b2n_resize (d, a->chunks + 1))
- {
- b2n_clear (d);
- return -1;
- }
-
- for (carry = i = 0; i < b->chunks; i++)
- {
- d->limp[i] = a->limp[i] + b->limp[i] + carry;
- carry = (d->limp[i] < a->limp[i] ? 1 : 0);
- }
-
- for (; i < a->chunks && carry; i++)
- {
- d->limp[i] = a->limp[i] + carry;
- carry = (d->limp[i] < a->limp[i] ? 1 : 0);
- }
-
- if (i < a->chunks)
- memcpy (d->limp + i, a->limp + i, CHUNK_BYTES * (a->chunks - i));
-
- d->dirty = 1;
- B2N_SWAP (d0, d);
-
- b2n_clear (d);
- return 0;
+ int i, carry;
+ b2n_ptr a, b;
+ b2n_t d;
+
+ if (!b2n_cmp_null(a0))
+ return b2n_set(d0, b0);
+
+ if (!b2n_cmp_null(b0))
+ return b2n_set(d0, a0);
+
+ b2n_init(d);
+ a = B2N_MAX(a0, b0);
+ b = B2N_MIN(a0, b0);
+
+ if (b2n_resize(d, a->chunks + 1)) {
+ b2n_clear(d);
+ return -1;
+ }
+ for (carry = i = 0; i < b->chunks; i++) {
+ d->limp[i] = a->limp[i] + b->limp[i] + carry;
+ carry = (d->limp[i] < a->limp[i] ? 1 : 0);
+ }
+
+ for (; i < a->chunks && carry; i++) {
+ d->limp[i] = a->limp[i] + carry;
+ carry = (d->limp[i] < a->limp[i] ? 1 : 0);
+ }
+
+ if (i < a->chunks)
+ memcpy(d->limp + i, a->limp + i, CHUNK_BYTES * (a->chunks - i));
+
+ d->dirty = 1;
+ B2N_SWAP(d0, d);
+
+ b2n_clear(d);
+ return 0;
}
/* Very special sub, a > b. */
int
-b2n_nsub (b2n_ptr d0, b2n_ptr a, b2n_ptr b)
+b2n_nsub(b2n_ptr d0, b2n_ptr a, b2n_ptr b)
{
- int i, carry;
- b2n_t d;
-
- if (b2n_cmp (a, b) <= 0)
- return b2n_set_null (d0);
+ int i, carry;
+ b2n_t d;
- b2n_init (d);
- if (b2n_resize (d, a->chunks))
- {
- b2n_clear (d);
- return -1;
- }
+ if (b2n_cmp(a, b) <= 0)
+ return b2n_set_null(d0);
- for (carry = i = 0; i < b->chunks; i++)
- {
- d->limp[i] = a->limp[i] - b->limp[i] - carry;
- carry = (d->limp[i] > a->limp[i] ? 1 : 0);
- }
+ b2n_init(d);
+ if (b2n_resize(d, a->chunks)) {
+ b2n_clear(d);
+ return -1;
+ }
+ for (carry = i = 0; i < b->chunks; i++) {
+ d->limp[i] = a->limp[i] - b->limp[i] - carry;
+ carry = (d->limp[i] > a->limp[i] ? 1 : 0);
+ }
- for (; i < a->chunks && carry; i++)
- {
- d->limp[i] = a->limp[i] - carry;
- carry = (d->limp[i] > a->limp[i] ? 1 : 0);
- }
+ for (; i < a->chunks && carry; i++) {
+ d->limp[i] = a->limp[i] - carry;
+ carry = (d->limp[i] > a->limp[i] ? 1 : 0);
+ }
- if (i < a->chunks)
- memcpy (d->limp + i, a->limp + i, CHUNK_BYTES*(a->chunks - i));
+ if (i < a->chunks)
+ memcpy(d->limp + i, a->limp + i, CHUNK_BYTES * (a->chunks - i));
- d->dirty = 1;
+ d->dirty = 1;
- B2N_SWAP (d0, d);
+ B2N_SWAP(d0, d);
- b2n_clear (d);
- return 0;
+ b2n_clear(d);
+ return 0;
}
int
-b2n_3mul (b2n_ptr d0, b2n_ptr e)
+b2n_3mul(b2n_ptr d0, b2n_ptr e)
{
- b2n_t d;
+ b2n_t d;
- b2n_init (d);
- if (b2n_lshift (d, e, 1))
- goto fail;
+ b2n_init(d);
+ if (b2n_lshift(d, e, 1))
+ goto fail;
- if (b2n_nadd (d0, d, e))
- goto fail;
+ if (b2n_nadd(d0, d, e))
+ goto fail;
- b2n_clear (d);
- return 0;
+ b2n_clear(d);
+ return 0;
- fail:
- b2n_clear (d);
- return -1;
+fail:
+ b2n_clear(d);
+ return -1;
}
diff --git a/sbin/isakmpd/math_2n.h b/sbin/isakmpd/math_2n.h
index e8d43835e10..0515199cf59 100644
--- a/sbin/isakmpd/math_2n.h
+++ b/sbin/isakmpd/math_2n.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_2n.h,v 1.6 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: math_2n.h,v 1.9 1999/04/17 23:20:32 niklas Exp $ */
+/* $OpenBSD: math_2n.h,v 1.7 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_2n.h,v 1.9 1999/04/17 23:20:32 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -39,7 +39,7 @@
* XXX - b2n_mask is only up to 32 bit at the moment.
*/
-#define USE_32BIT /* XXX - This obviously needs fixing */
+#define USE_32BIT /* XXX - This obviously needs fixing */
#ifdef USE_32BIT
#define CHUNK_TYPE u_int32_t
@@ -64,14 +64,14 @@ extern CHUNK_TYPE b2n_mask[CHUNK_BITS];
/* An element of GF(2**n), n = bits */
typedef struct {
- u_int16_t chunks;
- u_int16_t bits;
- u_int8_t dirty; /* Sig bits are dirty */
- CHUNK_TYPE *limp;
-} _b2n;
+ u_int16_t chunks;
+ u_int16_t bits;
+ u_int8_t dirty; /* Sig bits are dirty */
+ CHUNK_TYPE *limp;
+} _b2n;
-typedef _b2n *b2n_ptr;
-typedef _b2n b2n_t[1];
+typedef _b2n *b2n_ptr;
+typedef _b2n b2n_t[1];
#define B2N_SET(x,y) do \
{ \
@@ -95,38 +95,38 @@ while (0)
#define B2N_MIN(x,y) ((x)->chunks > (y)->chunks ? (y) : (x))
#define B2N_MAX(x,y) ((x)->chunks > (y)->chunks ? (x) : (y))
-int b2n_3mul (b2n_ptr, b2n_ptr);
-int b2n_add (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_cmp (b2n_ptr, b2n_ptr);
-int b2n_cmp_null (b2n_ptr);
-int b2n_div (b2n_ptr, b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_div_mod (b2n_ptr, b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_div_q (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_div_r (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_exp_mod (b2n_ptr, b2n_ptr, u_int32_t, b2n_ptr);
-void b2n_init (b2n_ptr);
-void b2n_clear (b2n_ptr);
-int b2n_gcd (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_halftrace (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_lshift (b2n_ptr, b2n_ptr, unsigned int);
-int b2n_mod (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_mul (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_mul_inv (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_nadd (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_nsub (b2n_ptr, b2n_ptr, b2n_ptr);
-void b2n_print (b2n_ptr);
-int b2n_random (b2n_ptr, u_int32_t);
-int b2n_resize (b2n_ptr, unsigned int);
-int b2n_rshift (b2n_ptr, b2n_ptr, unsigned int);
-int b2n_set (b2n_ptr, b2n_ptr);
-int b2n_set_null (b2n_ptr);
-int b2n_set_str (b2n_ptr, char *);
-int b2n_set_ui (b2n_ptr, unsigned int);
-u_int32_t b2n_sigbit (b2n_ptr);
-int b2n_snprint (char *, size_t, b2n_ptr);
-int b2n_sqrt (b2n_ptr, b2n_ptr, b2n_ptr);
-int b2n_square (b2n_ptr, b2n_ptr);
+int b2n_3mul(b2n_ptr, b2n_ptr);
+int b2n_add(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_cmp(b2n_ptr, b2n_ptr);
+int b2n_cmp_null(b2n_ptr);
+int b2n_div(b2n_ptr, b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_div_mod(b2n_ptr, b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_div_q(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_div_r(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_exp_mod(b2n_ptr, b2n_ptr, u_int32_t, b2n_ptr);
+void b2n_init(b2n_ptr);
+void b2n_clear(b2n_ptr);
+int b2n_gcd(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_halftrace(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_lshift(b2n_ptr, b2n_ptr, unsigned int);
+int b2n_mod(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_mul(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_mul_inv(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_nadd(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_nsub(b2n_ptr, b2n_ptr, b2n_ptr);
+void b2n_print(b2n_ptr);
+int b2n_random(b2n_ptr, u_int32_t);
+int b2n_resize(b2n_ptr, unsigned int);
+int b2n_rshift(b2n_ptr, b2n_ptr, unsigned int);
+int b2n_set(b2n_ptr, b2n_ptr);
+int b2n_set_null(b2n_ptr);
+int b2n_set_str(b2n_ptr, char *);
+int b2n_set_ui(b2n_ptr, unsigned int);
+u_int32_t b2n_sigbit(b2n_ptr);
+int b2n_snprint(char *, size_t, b2n_ptr);
+int b2n_sqrt(b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_square(b2n_ptr, b2n_ptr);
#define b2n_sub b2n_add
-int b2n_trace (b2n_ptr, b2n_ptr, b2n_ptr);
+int b2n_trace(b2n_ptr, b2n_ptr, b2n_ptr);
-#endif /* _MATH_2N_H_ */
+#endif /* _MATH_2N_H_ */
diff --git a/sbin/isakmpd/math_ec2n.c b/sbin/isakmpd/math_ec2n.c
index ce770cfefa7..5843ba1c8b3 100644
--- a/sbin/isakmpd/math_ec2n.c
+++ b/sbin/isakmpd/math_ec2n.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_ec2n.c,v 1.9 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: math_ec2n.c,v 1.9 1999/04/20 09:23:31 niklas Exp $ */
+/* $OpenBSD: math_ec2n.c,v 1.10 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_ec2n.c,v 1.9 1999/04/20 09:23:31 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -39,356 +39,342 @@
#include "math_ec2n.h"
void
-ec2np_init (ec2np_ptr n)
+ec2np_init(ec2np_ptr n)
{
- b2n_init (n->x);
- b2n_init (n->y);
- n->inf = 0;
+ b2n_init(n->x);
+ b2n_init(n->y);
+ n->inf = 0;
}
void
-ec2np_clear (ec2np_ptr n)
+ec2np_clear(ec2np_ptr n)
{
- b2n_clear (n->x);
- b2n_clear (n->y);
+ b2n_clear(n->x);
+ b2n_clear(n->y);
}
int
-ec2np_set (ec2np_ptr d, ec2np_ptr n)
+ec2np_set(ec2np_ptr d, ec2np_ptr n)
{
- if (d == n)
- return 0;
+ if (d == n)
+ return 0;
- d->inf = n->inf;
- if (b2n_set (d->x, n->x))
- return -1;
- return b2n_set (d->y, n->y);
+ d->inf = n->inf;
+ if (b2n_set(d->x, n->x))
+ return -1;
+ return b2n_set(d->y, n->y);
}
/* Group */
void
-ec2ng_init (ec2ng_ptr n)
+ec2ng_init(ec2ng_ptr n)
{
- b2n_init (n->a);
- b2n_init (n->b);
- b2n_init (n->p);
+ b2n_init(n->a);
+ b2n_init(n->b);
+ b2n_init(n->p);
}
void
-ec2ng_clear (ec2ng_ptr n)
+ec2ng_clear(ec2ng_ptr n)
{
- b2n_clear (n->a);
- b2n_clear (n->b);
- b2n_clear (n->p);
+ b2n_clear(n->a);
+ b2n_clear(n->b);
+ b2n_clear(n->p);
}
int
-ec2ng_set (ec2ng_ptr d, ec2ng_ptr n)
+ec2ng_set(ec2ng_ptr d, ec2ng_ptr n)
{
- if (b2n_set (d->a, n->a))
- return -1;
- if (b2n_set (d->b, n->b))
- return -1;
- return b2n_set (d->p, n->p);
+ if (b2n_set(d->a, n->a))
+ return -1;
+ if (b2n_set(d->b, n->b))
+ return -1;
+ return b2n_set(d->p, n->p);
}
/* Arithmetic functions */
int
-ec2np_right (b2n_ptr n, ec2np_ptr p, ec2ng_ptr g)
+ec2np_right(b2n_ptr n, ec2np_ptr p, ec2ng_ptr g)
{
- b2n_t temp;
+ b2n_t temp;
- b2n_init (temp);
+ b2n_init(temp);
- /* First calc x**3 + ax**2 + b */
- if (b2n_square (n, p->x))
- goto fail;
- if (b2n_mod (n, n, g->p))
- goto fail;
+ /* First calc x**3 + ax**2 + b */
+ if (b2n_square(n, p->x))
+ goto fail;
+ if (b2n_mod(n, n, g->p))
+ goto fail;
- if (b2n_mul (temp, g->a, n)) /* a*x**2 */
- goto fail;
- if (b2n_mod (temp, temp, g->p))
- goto fail;
+ if (b2n_mul(temp, g->a, n)) /* a*x**2 */
+ goto fail;
+ if (b2n_mod(temp, temp, g->p))
+ goto fail;
- if (b2n_mul (n, n, p->x)) /* x**3 */
- goto fail;
- if (b2n_mod (n, n, g->p))
- goto fail;
+ if (b2n_mul(n, n, p->x))/* x**3 */
+ goto fail;
+ if (b2n_mod(n, n, g->p))
+ goto fail;
- if (b2n_add (n, n, temp))
- goto fail;
- if (b2n_add (n, n, g->b))
- goto fail;
+ if (b2n_add(n, n, temp))
+ goto fail;
+ if (b2n_add(n, n, g->b))
+ goto fail;
- b2n_clear (temp);
- return 0;
+ b2n_clear(temp);
+ return 0;
- fail:
- b2n_clear (temp);
- return -1;
+fail:
+ b2n_clear(temp);
+ return -1;
}
int
-ec2np_ison (ec2np_ptr p, ec2ng_ptr g)
+ec2np_ison(ec2np_ptr p, ec2ng_ptr g)
{
- int res;
+ int res;
- b2n_t x, y, temp;
+ b2n_t x, y, temp;
- if (p->inf)
- return 1;
+ if (p->inf)
+ return 1;
- b2n_init (x);
- b2n_init (y);
- b2n_init (temp);
+ b2n_init(x);
+ b2n_init(y);
+ b2n_init(temp);
- /* First calc x**3 + ax**2 + b */
- if (ec2np_right (x, p, g))
- goto fail;
+ /* First calc x**3 + ax**2 + b */
+ if (ec2np_right(x, p, g))
+ goto fail;
- /* Now calc y**2 + xy */
- if (b2n_square (y, p->y))
- goto fail;
- if (b2n_mod (y, y, g->p))
- goto fail;
+ /* Now calc y**2 + xy */
+ if (b2n_square(y, p->y))
+ goto fail;
+ if (b2n_mod(y, y, g->p))
+ goto fail;
- if (b2n_mul (temp, p->y, p->x))
- goto fail;
- if (b2n_mod (temp, temp, g->p))
- goto fail;
+ if (b2n_mul(temp, p->y, p->x))
+ goto fail;
+ if (b2n_mod(temp, temp, g->p))
+ goto fail;
- if (b2n_add (y, y, temp))
- goto fail;
+ if (b2n_add(y, y, temp))
+ goto fail;
- res = !b2n_cmp (x, y);
+ res = !b2n_cmp(x, y);
- b2n_clear (x);
- b2n_clear (y);
- b2n_clear (temp);
- return res;
+ b2n_clear(x);
+ b2n_clear(y);
+ b2n_clear(temp);
+ return res;
- fail:
- b2n_clear (x);
- b2n_clear (y);
- b2n_clear (temp);
- return -1;
+fail:
+ b2n_clear(x);
+ b2n_clear(y);
+ b2n_clear(temp);
+ return -1;
}
int
-ec2np_find_y (ec2np_ptr p, ec2ng_ptr g)
+ec2np_find_y(ec2np_ptr p, ec2ng_ptr g)
{
- b2n_t right;
-
- b2n_init (right);
-
- if (ec2np_right (right, p, g)) /* Right sight of equation */
- goto fail;
- if (b2n_mul_inv (p->y, p->x, g->p))
- goto fail;
-
- if (b2n_square (p->y, p->y))
- goto fail;
- if (b2n_mod (p->y, p->y, g->p))
- goto fail;
-
- if (b2n_mul (right, right, p->y)) /* x^-2 * right */
- goto fail;
- if (b2n_mod (right, right, g->p))
- goto fail;
-
- if (b2n_sqrt (p->y, right, g->p)) /* Find root */
- goto fail;
- if (b2n_mul (p->y, p->y, p->x))
- goto fail;
- if (b2n_mod (p->y, p->y, g->p))
- goto fail;
-
- b2n_clear (right);
- return 0;
-
- fail:
- b2n_clear (right);
- return -1;
+ b2n_t right;
+
+ b2n_init(right);
+
+ if (ec2np_right(right, p, g)) /* Right sight of equation */
+ goto fail;
+ if (b2n_mul_inv(p->y, p->x, g->p))
+ goto fail;
+
+ if (b2n_square(p->y, p->y))
+ goto fail;
+ if (b2n_mod(p->y, p->y, g->p))
+ goto fail;
+
+ if (b2n_mul(right, right, p->y)) /* x^-2 * right */
+ goto fail;
+ if (b2n_mod(right, right, g->p))
+ goto fail;
+
+ if (b2n_sqrt(p->y, right, g->p)) /* Find root */
+ goto fail;
+ if (b2n_mul(p->y, p->y, p->x))
+ goto fail;
+ if (b2n_mod(p->y, p->y, g->p))
+ goto fail;
+
+ b2n_clear(right);
+ return 0;
+
+fail:
+ b2n_clear(right);
+ return -1;
}
int
-ec2np_add (ec2np_ptr d, ec2np_ptr a, ec2np_ptr b, ec2ng_ptr g)
+ec2np_add(ec2np_ptr d, ec2np_ptr a, ec2np_ptr b, ec2ng_ptr g)
{
- b2n_t lambda, temp;
- ec2np_t pn;
-
- /* Check for Neutral Element */
- if (b->inf)
- return ec2np_set (d, a);
- if (a->inf)
- return ec2np_set (d, b);
-
- if (!b2n_cmp (a->x, b->x) && (b2n_cmp (a->y, b->y) || !b2n_cmp_null (a->x)))
- {
- d->inf = 1;
- if (b2n_set_null (d->x))
+ b2n_t lambda, temp;
+ ec2np_t pn;
+
+ /* Check for Neutral Element */
+ if (b->inf)
+ return ec2np_set(d, a);
+ if (a->inf)
+ return ec2np_set(d, b);
+
+ if (!b2n_cmp(a->x, b->x) && (b2n_cmp(a->y, b->y) || !b2n_cmp_null(a->x))) {
+ d->inf = 1;
+ if (b2n_set_null(d->x))
+ return -1;
+ return b2n_set_null(d->y);
+ }
+ b2n_init(lambda);
+ b2n_init(temp);
+ ec2np_init(pn);
+
+ if (b2n_cmp(a->x, b->x)) {
+ if (b2n_add(temp, a->x, b->x))
+ goto fail;
+ if (b2n_add(lambda, a->y, b->y))
+ goto fail;
+ if (b2n_div_mod(lambda, lambda, temp, g->p))
+ goto fail;
+
+ if (b2n_square(pn->x, lambda))
+ goto fail;
+ if (b2n_mod(pn->x, pn->x, g->p))
+ goto fail;
+
+ if (b2n_add(pn->x, pn->x, lambda))
+ goto fail;
+ if (b2n_add(pn->x, pn->x, g->a))
+ goto fail;
+ if (b2n_add(pn->x, pn->x, a->x))
+ goto fail;
+ if (b2n_add(pn->x, pn->x, b->x))
+ goto fail;
+ } else {
+ if (b2n_div_mod(lambda, b->y, b->x, g->p))
+ goto fail;
+ if (b2n_add(lambda, lambda, b->x))
+ goto fail;
+
+ if (b2n_square(pn->x, lambda))
+ goto fail;
+ if (b2n_mod(pn->x, pn->x, g->p))
+ goto fail;
+ if (b2n_add(pn->x, pn->x, lambda))
+ goto fail;
+ if (b2n_add(pn->x, pn->x, g->a))
+ goto fail;
+ }
+
+ if (b2n_add(pn->y, b->x, pn->x))
+ goto fail;
+
+ if (b2n_mul(pn->y, pn->y, lambda))
+ goto fail;
+ if (b2n_mod(pn->y, pn->y, g->p))
+ goto fail;
+
+ if (b2n_add(pn->y, pn->y, pn->x))
+ goto fail;
+ if (b2n_add(pn->y, pn->y, b->y))
+ goto fail;
+
+ EC2NP_SWAP(d, pn);
+
+ ec2np_clear(pn);
+ b2n_clear(lambda);
+ b2n_clear(temp);
+ return 0;
+
+fail:
+ ec2np_clear(pn);
+ b2n_clear(lambda);
+ b2n_clear(temp);
return -1;
- return b2n_set_null (d->y);
- }
-
- b2n_init (lambda);
- b2n_init (temp);
- ec2np_init (pn);
-
- if (b2n_cmp (a->x, b->x))
- {
- if (b2n_add (temp, a->x, b->x))
- goto fail;
- if (b2n_add (lambda, a->y, b->y))
- goto fail;
- if (b2n_div_mod (lambda, lambda, temp, g->p))
- goto fail;
-
- if (b2n_square (pn->x, lambda))
- goto fail;
- if (b2n_mod (pn->x, pn->x, g->p))
- goto fail;
-
- if (b2n_add (pn->x, pn->x, lambda))
- goto fail;
- if (b2n_add (pn->x, pn->x, g->a))
- goto fail;
- if (b2n_add (pn->x, pn->x, a->x))
- goto fail;
- if (b2n_add (pn->x, pn->x, b->x))
- goto fail;
- }
- else
- {
- if (b2n_div_mod (lambda, b->y, b->x, g->p))
- goto fail;
- if (b2n_add (lambda, lambda, b->x))
- goto fail;
-
- if (b2n_square (pn->x, lambda))
- goto fail;
- if (b2n_mod (pn->x, pn->x, g->p))
- goto fail;
- if (b2n_add (pn->x, pn->x, lambda))
- goto fail;
- if (b2n_add (pn->x, pn->x, g->a))
- goto fail;
- }
-
- if (b2n_add (pn->y, b->x, pn->x))
- goto fail;
-
- if (b2n_mul (pn->y, pn->y, lambda))
- goto fail;
- if (b2n_mod (pn->y, pn->y, g->p))
- goto fail;
-
- if (b2n_add (pn->y, pn->y, pn->x))
- goto fail;
- if (b2n_add (pn->y, pn->y, b->y))
- goto fail;
-
- EC2NP_SWAP (d, pn);
-
- ec2np_clear (pn);
- b2n_clear (lambda);
- b2n_clear (temp);
- return 0;
-
- fail:
- ec2np_clear (pn);
- b2n_clear (lambda);
- b2n_clear (temp);
- return -1;
}
int
-ec2np_mul (ec2np_ptr d, ec2np_ptr a, b2n_ptr e, ec2ng_ptr g)
+ec2np_mul(ec2np_ptr d, ec2np_ptr a, b2n_ptr e, ec2ng_ptr g)
{
- int i, j, bits, start;
- b2n_t h, k;
- ec2np_t q, mina;
-
- if (!b2n_cmp_null (e))
- {
- d->inf = 1;
- if (b2n_set_null (d->x))
- return -1;
- return b2n_set_null (d->y);
- }
-
- b2n_init (h);
- b2n_init (k);
- ec2np_init (q);
- ec2np_init (mina);
-
- if (ec2np_set (q, a))
- goto fail;
-
- /* Create the point -a. */
- if (ec2np_set (mina, a))
- goto fail;
- if (b2n_add (mina->y, mina->y, mina->x))
- goto fail;
-
- if (b2n_set (k, e))
- goto fail;
- if (b2n_3mul (h, k))
- goto fail;
- if (b2n_resize (k, h->chunks))
- goto fail;
-
- /*
- * This is low level but can not be avoided, since we have to do single
- * bit checks on h and k.
- */
- bits = b2n_sigbit (h);
- if ((bits & CHUNK_MASK) == 1)
- {
- start = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS) - 2;
- bits = CHUNK_BITS;
- }
- else
- {
- start = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS) - 1;
- bits = ((bits - 1) & CHUNK_MASK);
- }
-
- /*
- * This is the addition, subtraction method which is faster because
- * we avoid one out of three additions (mean).
- */
- for (i = start; i >= 0; i--)
- for (j = (i == start ? bits : CHUNK_BITS) - 1; j >= 0; j--)
- if (i > 0 || j > 0)
- {
- if (ec2np_add (q, q, q, g))
- goto fail;
- if ((h->limp[i] & b2n_mask[j]) && !(k->limp[i] & b2n_mask[j]))
- {
- if (ec2np_add (q, q, a, g))
- goto fail;
- }
- else if (!(h->limp[i] & b2n_mask[j]) && (k->limp[i] & b2n_mask[j]))
- if (ec2np_add (q, q, mina, g))
- goto fail;
+ int i, j, bits, start;
+ b2n_t h, k;
+ ec2np_t q, mina;
+
+ if (!b2n_cmp_null(e)) {
+ d->inf = 1;
+ if (b2n_set_null(d->x))
+ return -1;
+ return b2n_set_null(d->y);
}
+ b2n_init(h);
+ b2n_init(k);
+ ec2np_init(q);
+ ec2np_init(mina);
+
+ if (ec2np_set(q, a))
+ goto fail;
+
+ /* Create the point -a. */
+ if (ec2np_set(mina, a))
+ goto fail;
+ if (b2n_add(mina->y, mina->y, mina->x))
+ goto fail;
- EC2NP_SWAP (d, q);
+ if (b2n_set(k, e))
+ goto fail;
+ if (b2n_3mul(h, k))
+ goto fail;
+ if (b2n_resize(k, h->chunks))
+ goto fail;
- b2n_clear (k);
- b2n_clear (h);
- ec2np_clear (q);
- ec2np_clear (mina);
- return 0;
+ /*
+ * This is low level but can not be avoided, since we have to do single
+ * bit checks on h and k.
+ */
+ bits = b2n_sigbit(h);
+ if ((bits & CHUNK_MASK) == 1) {
+ start = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS) - 2;
+ bits = CHUNK_BITS;
+ } else {
+ start = ((CHUNK_MASK + bits) >> CHUNK_SHIFTS) - 1;
+ bits = ((bits - 1) & CHUNK_MASK);
+ }
- fail:
- b2n_clear (k);
- b2n_clear (h);
- ec2np_clear (q);
- ec2np_clear (mina);
- return -1;
+ /*
+ * This is the addition, subtraction method which is faster because
+ * we avoid one out of three additions (mean).
+ */
+ for (i = start; i >= 0; i--)
+ for (j = (i == start ? bits : CHUNK_BITS) - 1; j >= 0; j--)
+ if (i > 0 || j > 0) {
+ if (ec2np_add(q, q, q, g))
+ goto fail;
+ if ((h->limp[i] & b2n_mask[j]) && !(k->limp[i] & b2n_mask[j])) {
+ if (ec2np_add(q, q, a, g))
+ goto fail;
+ } else if (!(h->limp[i] & b2n_mask[j]) && (k->limp[i] & b2n_mask[j]))
+ if (ec2np_add(q, q, mina, g))
+ goto fail;
+ }
+ EC2NP_SWAP(d, q);
+
+ b2n_clear(k);
+ b2n_clear(h);
+ ec2np_clear(q);
+ ec2np_clear(mina);
+ return 0;
+
+fail:
+ b2n_clear(k);
+ b2n_clear(h);
+ ec2np_clear(q);
+ ec2np_clear(mina);
+ return -1;
}
diff --git a/sbin/isakmpd/math_ec2n.h b/sbin/isakmpd/math_ec2n.h
index dbd360f7ace..078eb4b19d9 100644
--- a/sbin/isakmpd/math_ec2n.h
+++ b/sbin/isakmpd/math_ec2n.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_ec2n.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: math_ec2n.h,v 1.4 1999/04/17 23:20:37 niklas Exp $ */
+/* $OpenBSD: math_ec2n.h,v 1.6 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_ec2n.h,v 1.4 1999/04/17 23:20:37 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -35,9 +35,9 @@
/* Definitions for points on an elliptic curve */
typedef struct {
- int inf; /* Are we the point at infinity ? */
- b2n_t x, y;
-} _ec2n_point;
+ int inf; /* Are we the point at infinity ? */
+ b2n_t x, y;
+} _ec2n_point;
typedef _ec2n_point *ec2np_ptr;
typedef _ec2n_point ec2np_t[1];
@@ -54,9 +54,9 @@ typedef _ec2n_point ec2np_t[1];
} \
while (0)
-void ec2np_init (ec2np_ptr);
-void ec2np_clear (ec2np_ptr);
-int ec2np_set (ec2np_ptr, ec2np_ptr);
+void ec2np_init(ec2np_ptr);
+void ec2np_clear(ec2np_ptr);
+int ec2np_set(ec2np_ptr, ec2np_ptr);
#define ec2np_set_x_ui(n, y) b2n_set_ui ((n)->x, y)
#define ec2np_set_y_ui(n, x) b2n_set_ui ((n)->y, x)
@@ -66,15 +66,15 @@ int ec2np_set (ec2np_ptr, ec2np_ptr);
/* Definitions for the group to which the points to belong to. */
typedef struct {
- b2n_t a, b, p;
-} _ec2n_group;
+ b2n_t a, b, p;
+} _ec2n_group;
typedef _ec2n_group *ec2ng_ptr;
typedef _ec2n_group ec2ng_t[1];
-void ec2ng_init (ec2ng_ptr);
-void ec2ng_clear (ec2ng_ptr);
-int ec2ng_set (ec2ng_ptr, ec2ng_ptr);
+void ec2ng_init(ec2ng_ptr);
+void ec2ng_clear(ec2ng_ptr);
+int ec2ng_set(ec2ng_ptr, ec2ng_ptr);
#define ec2ng_set_a_ui(n, x) b2n_set_ui ((n)->a, x)
#define ec2ng_set_b_ui(n, x) b2n_set_ui ((n)->b, x)
@@ -85,10 +85,10 @@ int ec2ng_set (ec2ng_ptr, ec2ng_ptr);
/* Functions for computing on the elliptic group. */
-int ec2np_add (ec2np_ptr, ec2np_ptr, ec2np_ptr, ec2ng_ptr);
-int ec2np_find_y (ec2np_ptr, ec2ng_ptr);
-int ec2np_ison (ec2np_ptr, ec2ng_ptr);
-int ec2np_mul (ec2np_ptr, ec2np_ptr, b2n_ptr, ec2ng_ptr);
-int ec2np_right (b2n_ptr n, ec2np_ptr, ec2ng_ptr);
+int ec2np_add(ec2np_ptr, ec2np_ptr, ec2np_ptr, ec2ng_ptr);
+int ec2np_find_y(ec2np_ptr, ec2ng_ptr);
+int ec2np_ison(ec2np_ptr, ec2ng_ptr);
+int ec2np_mul(ec2np_ptr, ec2np_ptr, b2n_ptr, ec2ng_ptr);
+int ec2np_right(b2n_ptr n, ec2np_ptr, ec2ng_ptr);
-#endif /* _MATH_2N_H_ */
+#endif /* _MATH_2N_H_ */
diff --git a/sbin/isakmpd/math_group.c b/sbin/isakmpd/math_group.c
index 4339dad392e..124a58b97d1 100644
--- a/sbin/isakmpd/math_group.c
+++ b/sbin/isakmpd/math_group.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_group.c,v 1.20 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: math_group.c,v 1.25 2000/04/07 19:53:26 niklas Exp $ */
+/* $OpenBSD: math_group.c,v 1.21 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_group.c,v 1.25 2000/04/07 19:53:26 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -44,28 +44,28 @@
#include "math_mp.h"
/* We do not want to export these definitions. */
-int modp_getlen (struct group *);
-void modp_getraw (struct group *, math_mp_t, u_int8_t *);
-int modp_setraw (struct group *, math_mp_t, u_int8_t *, int);
-int modp_setrandom (struct group *, math_mp_t);
-int modp_operation (struct group *, math_mp_t, math_mp_t, math_mp_t);
-
-int ec2n_getlen (struct group *);
-void ec2n_getraw (struct group *, ec2np_ptr, u_int8_t *);
-int ec2n_setraw (struct group *, ec2np_ptr, u_int8_t *, int);
-int ec2n_setrandom (struct group *, ec2np_ptr);
-int ec2n_operation (struct group *, ec2np_ptr, ec2np_ptr, ec2np_ptr);
+int modp_getlen(struct group *);
+void modp_getraw(struct group *, math_mp_t, u_int8_t *);
+int modp_setraw(struct group *, math_mp_t, u_int8_t *, int);
+int modp_setrandom(struct group *, math_mp_t);
+int modp_operation(struct group *, math_mp_t, math_mp_t, math_mp_t);
+
+int ec2n_getlen(struct group *);
+void ec2n_getraw(struct group *, ec2np_ptr, u_int8_t *);
+int ec2n_setraw(struct group *, ec2np_ptr, u_int8_t *, int);
+int ec2n_setrandom(struct group *, ec2np_ptr);
+int ec2n_operation(struct group *, ec2np_ptr, ec2np_ptr, ec2np_ptr);
struct ec2n_group {
- ec2np_t gen; /* Generator */
- ec2ng_t grp;
- ec2np_t a, b, c, d;
+ ec2np_t gen; /* Generator */
+ ec2ng_t grp;
+ ec2np_t a, b, c, d;
};
struct modp_group {
- math_mp_t gen; /* Generator */
- math_mp_t p; /* Prime */
- math_mp_t a, b, c, d;
+ math_mp_t gen; /* Generator */
+ math_mp_t p; /* Prime */
+ math_mp_t a, b, c, d;
};
/*
@@ -102,172 +102,173 @@ struct modp_group {
struct modp_dscr oakley_modp[] =
{
- { OAKLEY_GRP_1, 72, /* This group is insecure, only sufficient for DES */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_2, 82, /* This group is a bit better */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
- "FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_5, 102,
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_14, 135, /* 2048 bit */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_15, 170, /* 3072 bit */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
- "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
- "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
- "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
- "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
- "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_16, 195, /* 4096 bit */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
- "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
- "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
- "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
- "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
- "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
- "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
- "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
- "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
- "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
- "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
- "FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_17, 220, /* 6144 bit */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
- "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
- "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
- "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
- "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
- "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
- "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
- "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
- "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
- "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
- "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
- "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
- "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
- "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
- "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
- "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
- "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
- "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
- "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
- "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
- "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
- "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
- "0x02"
- },
- { OAKLEY_GRP_18, 250, /* 8192 bit */
- "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
- "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
- "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
- "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
- "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
- "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
- "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
- "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
- "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
- "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
- "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
- "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
- "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
- "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
- "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
- "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
- "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
- "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
- "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
- "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
- "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
- "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
- "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
- "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
- "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
- "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
- "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
- "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
- "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
- "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
- "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
- "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
- "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
- "0x02"
- },
+ {OAKLEY_GRP_1, 72, /* This group is insecure, only sufficient
+ * for DES */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_2, 82, /* This group is a bit better */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
+ "FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_5, 102,
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_14, 135, /* 2048 bit */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_15, 170, /* 3072 bit */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
+ "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
+ "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
+ "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
+ "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_16, 195, /* 4096 bit */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
+ "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
+ "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
+ "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
+ "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
+ "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
+ "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+ "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
+ "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
+ "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
+ "FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_17, 220, /* 6144 bit */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
+ "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
+ "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
+ "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
+ "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
+ "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
+ "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+ "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
+ "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
+ "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
+ "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
+ "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
+ "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
+ "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
+ "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
+ "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
+ "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
+ "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
+ "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
+ "0x02"
+ },
+ {OAKLEY_GRP_18, 250, /* 8192 bit */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
+ "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
+ "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
+ "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
+ "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
+ "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
+ "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
+ "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
+ "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
+ "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
+ "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
+ "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
+ "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
+ "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
+ "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
+ "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
+ "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
+ "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
+ "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
+ "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
+ "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
+ "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
+ "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
+ "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
+ "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
+ "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
+ "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
+ "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
+ "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
+ "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
+ "0x02"
+ },
};
#ifdef USE_EC
@@ -279,139 +280,140 @@ struct modp_dscr oakley_modp[] =
*/
struct ec2n_dscr oakley_ec2n[] = {
- { OAKLEY_GRP_3, 76, /* This group is also considered insecure (P1363) */
- "0x0800000000000000000000004000000000000001",
- "0x7b",
- "0x00",
- "0x7338f" },
- { OAKLEY_GRP_4, 91,
- "0x020000000000000000000000000000200000000000000001",
- "0x18",
- "0x00",
- "0x1ee9" },
+ {OAKLEY_GRP_3, 76, /* This group is also considered insecure
+ * (P1363) */
+ "0x0800000000000000000000004000000000000001",
+ "0x7b",
+ "0x00",
+ "0x7338f"},
+ {OAKLEY_GRP_4, 91,
+ "0x020000000000000000000000000000200000000000000001",
+ "0x18",
+ "0x00",
+ "0x1ee9"},
};
-#endif /* USE_EC */
+#endif /* USE_EC */
/* XXX I want to get rid of the casting here. */
-struct group groups[] = {
- {
- MODP, OAKLEY_GRP_1, 0, &oakley_modp[0], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
- {
- MODP, OAKLEY_GRP_2, 0, &oakley_modp[1], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
+struct group groups[] = {
+ {
+ MODP, OAKLEY_GRP_1, 0, &oakley_modp[0], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
+ {
+ MODP, OAKLEY_GRP_2, 0, &oakley_modp[1], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
#ifdef USE_EC
- {
- EC2N, OAKLEY_GRP_3, 0, &oakley_ec2n[0], 0, 0, 0, 0, 0,
- (int (*) (struct group *))ec2n_getlen,
- (void (*) (struct group *, void *, u_int8_t *))ec2n_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))ec2n_setraw,
- (int (*) (struct group *, void *))ec2n_setrandom,
- (int (*) (struct group *, void *, void *, void *))ec2n_operation
- },
- {
- EC2N, OAKLEY_GRP_4, 0, &oakley_ec2n[1], 0, 0, 0, 0, 0,
- (int (*) (struct group *))ec2n_getlen,
- (void (*) (struct group *, void *, u_int8_t *))ec2n_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))ec2n_setraw,
- (int (*) (struct group *, void *))ec2n_setrandom,
- (int (*) (struct group *, void *, void *, void *))ec2n_operation
- },
-#endif /* USE_EC */
- {
- MODP, OAKLEY_GRP_5, 0, &oakley_modp[2], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
+ {
+ EC2N, OAKLEY_GRP_3, 0, &oakley_ec2n[0], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) ec2n_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) ec2n_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) ec2n_setraw,
+ (int (*) (struct group *, void *)) ec2n_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) ec2n_operation
+ },
+ {
+ EC2N, OAKLEY_GRP_4, 0, &oakley_ec2n[1], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) ec2n_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) ec2n_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) ec2n_setraw,
+ (int (*) (struct group *, void *)) ec2n_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) ec2n_operation
+ },
+#endif /* USE_EC */
+ {
+ MODP, OAKLEY_GRP_5, 0, &oakley_modp[2], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
#ifdef USE_EC
- /* XXX Higher EC2N group go here... */
-#endif /* USE_EC */
- /* XXX group 6 to 13 are not yet defined (draft-ike-ecc) */
- {
- NOTYET, OAKLEY_GRP_6, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_7, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_8, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_9, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_10, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_11, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_12, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- NOTYET, OAKLEY_GRP_13, 0, NULL, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL
- },
- {
- MODP, OAKLEY_GRP_14, 0, &oakley_modp[3], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
- {
- MODP, OAKLEY_GRP_15, 0, &oakley_modp[4], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
- {
- MODP, OAKLEY_GRP_16, 0, &oakley_modp[5], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
- {
- MODP, OAKLEY_GRP_17, 0, &oakley_modp[6], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
- {
- MODP, OAKLEY_GRP_18, 0, &oakley_modp[7], 0, 0, 0, 0, 0,
- (int (*) (struct group *))modp_getlen,
- (void (*) (struct group *, void *, u_int8_t *))modp_getraw,
- (int (*) (struct group *, void *, u_int8_t *, int))modp_setraw,
- (int (*) (struct group *, void *))modp_setrandom,
- (int (*) (struct group *, void *, void *, void *))modp_operation
- },
+ /* XXX Higher EC2N group go here... */
+#endif /* USE_EC */
+ /* XXX group 6 to 13 are not yet defined (draft-ike-ecc) */
+ {
+ NOTYET, OAKLEY_GRP_6, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_7, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_8, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_9, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_10, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_11, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_12, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ NOTYET, OAKLEY_GRP_13, 0, NULL, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL
+ },
+ {
+ MODP, OAKLEY_GRP_14, 0, &oakley_modp[3], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
+ {
+ MODP, OAKLEY_GRP_15, 0, &oakley_modp[4], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
+ {
+ MODP, OAKLEY_GRP_16, 0, &oakley_modp[5], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
+ {
+ MODP, OAKLEY_GRP_17, 0, &oakley_modp[6], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
+ {
+ MODP, OAKLEY_GRP_18, 0, &oakley_modp[7], 0, 0, 0, 0, 0,
+ (int (*) (struct group *)) modp_getlen,
+ (void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
+ (int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
+ (int (*) (struct group *, void *)) modp_setrandom,
+ (int (*) (struct group *, void *, void *, void *)) modp_operation
+ },
};
/*
@@ -420,437 +422,421 @@ struct group groups[] = {
* and converting them to their native representation.
*/
void
-group_init (void)
+group_init(void)
{
- int i;
+ int i;
- for (i = sizeof (groups) / sizeof (groups[0]) - 1; i >= 0; i--)
- switch (groups[i].type)
- {
+ for (i = sizeof(groups) / sizeof(groups[0]) - 1; i >= 0; i--)
+ switch (groups[i].type) {
#ifdef USE_EC
- case EC2N: /* Initialize an Elliptic Curve over GF(2**n) */
- ec2n_init (&groups[i]);
- break;
+ case EC2N: /* Initialize an Elliptic Curve over GF(2**n) */
+ ec2n_init(&groups[i]);
+ break;
#endif
- case MODP: /* Initialize an over GF(p) */
- modp_init (&groups[i]);
- break;
-
- case NOTYET: /* Not yet assigned, drop silently */
- break;
-
- default:
- log_print ("Unknown group type %d at index %d in group_init().",
- groups[i].type, i);
- break;
- }
-}
+ case MODP: /* Initialize an over GF(p) */
+ modp_init(&groups[i]);
+ break;
-struct group *
-group_get (u_int32_t id)
-{
- struct group *new, *clone;
+ case NOTYET: /* Not yet assigned, drop silently */
+ break;
- if (id < 1 || id > (sizeof (groups) / sizeof (groups[0])))
- {
- log_print ("group_get: group ID (%u) out of range", id);
- return 0;
- }
+ default:
+ log_print("Unknown group type %d at index %d in group_init().",
+ groups[i].type, i);
+ break;
+ }
+}
- clone = &groups[id - 1];
+struct group *
+group_get(u_int32_t id)
+{
+ struct group *new, *clone;
- new = malloc (sizeof *new);
- if (!new)
- {
- log_error ("group_get: malloc (%lu) failed", (unsigned long)sizeof *new);
- return 0;
- }
+ if (id < 1 || id > (sizeof(groups) / sizeof(groups[0]))) {
+ log_print("group_get: group ID (%u) out of range", id);
+ return 0;
+ }
+ clone = &groups[id - 1];
- switch (clone->type)
- {
+ new = malloc(sizeof *new);
+ if (!new) {
+ log_error("group_get: malloc (%lu) failed", (unsigned long) sizeof *new);
+ return 0;
+ }
+ switch (clone->type) {
#ifdef USE_EC
- case EC2N:
- new = ec2n_clone (new, clone);
- break;
+ case EC2N:
+ new = ec2n_clone(new, clone);
+ break;
#endif
- case MODP:
- new = modp_clone (new, clone);
- break;
- default:
- log_print ("group_get: unknown group type %d", clone->type);
- free (new);
- return 0;
- }
- LOG_DBG ((LOG_MISC, 70, "group_get: returning %p of group %d", new,
- new->id));
- return new;
+ case MODP:
+ new = modp_clone(new, clone);
+ break;
+ default:
+ log_print("group_get: unknown group type %d", clone->type);
+ free(new);
+ return 0;
+ }
+ LOG_DBG((LOG_MISC, 70, "group_get: returning %p of group %d", new,
+ new->id));
+ return new;
}
void
-group_free (struct group *grp)
+group_free(struct group * grp)
{
- switch (grp->type)
- {
+ switch (grp->type) {
#ifdef USE_EC
- case EC2N:
- ec2n_free (grp);
- break;
+ case EC2N:
+ ec2n_free(grp);
+ break;
#endif
- case MODP:
- modp_free (grp);
- break;
- default:
- log_print ("group_free: unknown group type %d", grp->type);
- break;
- }
- free (grp);
+ case MODP:
+ modp_free(grp);
+ break;
+ default:
+ log_print("group_free: unknown group type %d", grp->type);
+ break;
+ }
+ free(grp);
}
-struct group *
-modp_clone (struct group *new, struct group *clone)
+struct group *
+modp_clone(struct group * new, struct group * clone)
{
- struct modp_group *new_grp, *clone_grp = clone->group;
-
- new_grp = malloc (sizeof *new_grp);
- if (!new_grp)
- {
- log_print ("modp_clone: malloc (%lu) failed",
- (unsigned long)sizeof *new_grp);
- free (new);
- return 0;
- }
-
- memcpy (new, clone, sizeof (struct group));
+ struct modp_group *new_grp, *clone_grp = clone->group;
+
+ new_grp = malloc(sizeof *new_grp);
+ if (!new_grp) {
+ log_print("modp_clone: malloc (%lu) failed",
+ (unsigned long) sizeof *new_grp);
+ free(new);
+ return 0;
+ }
+ memcpy(new, clone, sizeof(struct group));
- new->group = new_grp;
+ new->group = new_grp;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_init_set (new_grp->p, clone_grp->p);
- mpz_init_set (new_grp->gen, clone_grp->gen);
+ mpz_init_set(new_grp->p, clone_grp->p);
+ mpz_init_set(new_grp->gen, clone_grp->gen);
- mpz_init (new_grp->a);
- mpz_init (new_grp->b);
- mpz_init (new_grp->c);
+ mpz_init(new_grp->a);
+ mpz_init(new_grp->b);
+ mpz_init(new_grp->c);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- new_grp->p = BN_dup (clone_grp->p);
- new_grp->gen = BN_dup (clone_grp->gen);
+ new_grp->p = BN_dup(clone_grp->p);
+ new_grp->gen = BN_dup(clone_grp->gen);
- new_grp->a = BN_new ();
- new_grp->b = BN_new ();
- new_grp->c = BN_new ();
+ new_grp->a = BN_new();
+ new_grp->b = BN_new();
+ new_grp->c = BN_new();
#endif
- new->gen = new_grp->gen;
- new->a = new_grp->a;
- new->b = new_grp->b;
- new->c = new_grp->c;
+ new->gen = new_grp->gen;
+ new->a = new_grp->a;
+ new->b = new_grp->b;
+ new->c = new_grp->c;
- return new;
+ return new;
}
void
-modp_free (struct group *old)
+modp_free(struct group * old)
{
- struct modp_group *grp = old->group;
+ struct modp_group *grp = old->group;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_clear (grp->p);
- mpz_clear (grp->gen);
- mpz_clear (grp->a);
- mpz_clear (grp->b);
- mpz_clear (grp->c);
+ mpz_clear(grp->p);
+ mpz_clear(grp->gen);
+ mpz_clear(grp->a);
+ mpz_clear(grp->b);
+ mpz_clear(grp->c);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_clear_free (grp->p);
- BN_clear_free (grp->gen);
- BN_clear_free (grp->a);
- BN_clear_free (grp->b);
- BN_clear_free (grp->c);
+ BN_clear_free(grp->p);
+ BN_clear_free(grp->gen);
+ BN_clear_free(grp->a);
+ BN_clear_free(grp->b);
+ BN_clear_free(grp->c);
#endif
- free (grp);
+ free(grp);
}
void
-modp_init (struct group *group)
+modp_init(struct group * group)
{
- struct modp_dscr *dscr = (struct modp_dscr *)group->group;
- struct modp_group *grp;
+ struct modp_dscr *dscr = (struct modp_dscr *) group->group;
+ struct modp_group *grp;
- grp = malloc (sizeof *grp);
- if (!grp)
- log_fatal ("modp_init: malloc (%lu) failed", (unsigned long)sizeof *grp);
+ grp = malloc(sizeof *grp);
+ if (!grp)
+ log_fatal("modp_init: malloc (%lu) failed", (unsigned long) sizeof *grp);
- group->bits = dscr->bits;
+ group->bits = dscr->bits;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_init_set_str (grp->p, dscr->prime, 0);
- mpz_init_set_str (grp->gen, dscr->gen, 0);
+ mpz_init_set_str(grp->p, dscr->prime, 0);
+ mpz_init_set_str(grp->gen, dscr->gen, 0);
- mpz_init (grp->a);
- mpz_init (grp->b);
- mpz_init (grp->c);
+ mpz_init(grp->a);
+ mpz_init(grp->b);
+ mpz_init(grp->c);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- grp->p = BN_new ();
- BN_hex2bn (&grp->p, dscr->prime + 2);
- grp->gen = BN_new ();
- BN_hex2bn (&grp->gen, dscr->gen + 2);
-
- grp->a = BN_new ();
- grp->b = BN_new ();
- grp->c = BN_new ();
+ grp->p = BN_new();
+ BN_hex2bn(&grp->p, dscr->prime + 2);
+ grp->gen = BN_new();
+ BN_hex2bn(&grp->gen, dscr->gen + 2);
+
+ grp->a = BN_new();
+ grp->b = BN_new();
+ grp->c = BN_new();
#endif
- group->gen = grp->gen;
- group->a = grp->a;
- group->b = grp->b;
- group->c = grp->c;
+ group->gen = grp->gen;
+ group->a = grp->a;
+ group->b = grp->b;
+ group->c = grp->c;
- group->group = grp;
+ group->group = grp;
}
#ifdef USE_EC
-struct group *
-ec2n_clone (struct group *new, struct group *clone)
+struct group *
+ec2n_clone(struct group * new, struct group * clone)
{
- struct ec2n_group *new_grp, *clone_grp = clone->group;
-
- new_grp = malloc (sizeof *new_grp);
- if (!new_grp)
- {
- log_error ("ec2n_clone: malloc (%lu) failed",
- (unsigned long)sizeof *new_grp);
- free (new);
- return 0;
- }
-
- memcpy (new, clone, sizeof (struct group));
-
- new->group = new_grp;
- ec2ng_init (new_grp->grp);
- ec2np_init (new_grp->gen);
- ec2np_init (new_grp->a);
- ec2np_init (new_grp->b);
- ec2np_init (new_grp->c);
-
- if (ec2ng_set (new_grp->grp, clone_grp->grp))
- goto fail;
- if (ec2np_set (new_grp->gen, clone_grp->gen))
- goto fail;
-
- new->gen = new_grp->gen;
- new->a = new_grp->a;
- new->b = new_grp->b;
- new->c = new_grp->c;
- new->d = ((ec2np_ptr)new->a)->x;
-
- return new;
-
- fail:
- ec2ng_clear (new_grp->grp);
- ec2np_clear (new_grp->gen);
- ec2np_clear (new_grp->a);
- ec2np_clear (new_grp->b);
- ec2np_clear (new_grp->c);
- free (new_grp);
- free (new);
- return 0;
+ struct ec2n_group *new_grp, *clone_grp = clone->group;
+
+ new_grp = malloc(sizeof *new_grp);
+ if (!new_grp) {
+ log_error("ec2n_clone: malloc (%lu) failed",
+ (unsigned long) sizeof *new_grp);
+ free(new);
+ return 0;
+ }
+ memcpy(new, clone, sizeof(struct group));
+
+ new->group = new_grp;
+ ec2ng_init(new_grp->grp);
+ ec2np_init(new_grp->gen);
+ ec2np_init(new_grp->a);
+ ec2np_init(new_grp->b);
+ ec2np_init(new_grp->c);
+
+ if (ec2ng_set(new_grp->grp, clone_grp->grp))
+ goto fail;
+ if (ec2np_set(new_grp->gen, clone_grp->gen))
+ goto fail;
+
+ new->gen = new_grp->gen;
+ new->a = new_grp->a;
+ new->b = new_grp->b;
+ new->c = new_grp->c;
+ new->d = ((ec2np_ptr) new->a)->x;
+
+ return new;
+
+fail:
+ ec2ng_clear(new_grp->grp);
+ ec2np_clear(new_grp->gen);
+ ec2np_clear(new_grp->a);
+ ec2np_clear(new_grp->b);
+ ec2np_clear(new_grp->c);
+ free(new_grp);
+ free(new);
+ return 0;
}
void
-ec2n_free (struct group *old)
+ec2n_free(struct group * old)
{
- struct ec2n_group *grp = old->group;
+ struct ec2n_group *grp = old->group;
- ec2ng_clear (grp->grp);
- ec2np_clear (grp->gen);
- ec2np_clear (grp->a);
- ec2np_clear (grp->b);
- ec2np_clear (grp->c);
+ ec2ng_clear(grp->grp);
+ ec2np_clear(grp->gen);
+ ec2np_clear(grp->a);
+ ec2np_clear(grp->b);
+ ec2np_clear(grp->c);
- free (grp);
+ free(grp);
}
void
-ec2n_init (struct group *group)
+ec2n_init(struct group * group)
{
- struct ec2n_dscr *dscr = (struct ec2n_dscr *)group->group;
- struct ec2n_group *grp;
-
- grp = malloc (sizeof *grp);
- if (!grp)
- log_fatal ("ec2n_init: malloc (%lu) failed", (unsigned long)sizeof *grp);
-
- group->bits = dscr->bits;
-
- ec2ng_init (grp->grp);
- ec2np_init (grp->gen);
- ec2np_init (grp->a);
- ec2np_init (grp->b);
- ec2np_init (grp->c);
-
- if (ec2ng_set_p_str (grp->grp, dscr->polynomial))
- goto fail;
- grp->grp->p->bits = b2n_sigbit (grp->grp->p);
- if (ec2ng_set_a_str (grp->grp, dscr->a))
- goto fail;
- if (ec2ng_set_b_str (grp->grp, dscr->b))
- goto fail;
-
- if (ec2np_set_x_str (grp->gen, dscr->gen_x))
- goto fail;
- if (ec2np_find_y (grp->gen, grp->grp))
- goto fail;
-
- /* Sanity check */
- if (!ec2np_ison (grp->gen, grp->grp))
- log_fatal ("ec2n_init: generator is not on curve");
-
- group->gen = grp->gen;
- group->a = grp->a;
- group->b = grp->b;
- group->c = grp->c;
- group->d = ((ec2np_ptr)group->a)->x;
-
- group->group = grp;
- return;
-
- fail:
- log_fatal ("ec2n_init: general failure");
+ struct ec2n_dscr *dscr = (struct ec2n_dscr *) group->group;
+ struct ec2n_group *grp;
+
+ grp = malloc(sizeof *grp);
+ if (!grp)
+ log_fatal("ec2n_init: malloc (%lu) failed", (unsigned long) sizeof *grp);
+
+ group->bits = dscr->bits;
+
+ ec2ng_init(grp->grp);
+ ec2np_init(grp->gen);
+ ec2np_init(grp->a);
+ ec2np_init(grp->b);
+ ec2np_init(grp->c);
+
+ if (ec2ng_set_p_str(grp->grp, dscr->polynomial))
+ goto fail;
+ grp->grp->p->bits = b2n_sigbit(grp->grp->p);
+ if (ec2ng_set_a_str(grp->grp, dscr->a))
+ goto fail;
+ if (ec2ng_set_b_str(grp->grp, dscr->b))
+ goto fail;
+
+ if (ec2np_set_x_str(grp->gen, dscr->gen_x))
+ goto fail;
+ if (ec2np_find_y(grp->gen, grp->grp))
+ goto fail;
+
+ /* Sanity check */
+ if (!ec2np_ison(grp->gen, grp->grp))
+ log_fatal("ec2n_init: generator is not on curve");
+
+ group->gen = grp->gen;
+ group->a = grp->a;
+ group->b = grp->b;
+ group->c = grp->c;
+ group->d = ((ec2np_ptr) group->a)->x;
+
+ group->group = grp;
+ return;
+
+fail:
+ log_fatal("ec2n_init: general failure");
}
-#endif /* USE_EC */
+#endif /* USE_EC */
int
-modp_getlen (struct group *group)
+modp_getlen(struct group * group)
{
- struct modp_group *grp = (struct modp_group *)group->group;
+ struct modp_group *grp = (struct modp_group *) group->group;
- return mpz_sizeinoctets (grp->p);
+ return mpz_sizeinoctets(grp->p);
}
void
-modp_getraw (struct group *grp, math_mp_t v, u_int8_t *d)
+modp_getraw(struct group * grp, math_mp_t v, u_int8_t * d)
{
- mpz_getraw (d, v, grp->getlen (grp));
+ mpz_getraw(d, v, grp->getlen(grp));
}
int
-modp_setraw (struct group *grp, math_mp_t d, u_int8_t *s, int l)
+modp_setraw(struct group * grp, math_mp_t d, u_int8_t * s, int l)
{
- mpz_setraw (d, s, l);
- return 0;
+ mpz_setraw(d, s, l);
+ return 0;
}
int
-modp_setrandom (struct group *grp, math_mp_t d)
+modp_setrandom(struct group * grp, math_mp_t d)
{
- int i, l = grp->getlen (grp);
- u_int32_t tmp = 0;
+ int i, l = grp->getlen(grp);
+ u_int32_t tmp = 0;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_set_ui (d, 0);
+ mpz_set_ui(d, 0);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_set_word (d, 0);
+ BN_set_word(d, 0);
#endif
- for (i = 0; i < l; i++)
- {
- if (i % 4)
- tmp = sysdep_random ();
+ for (i = 0; i < l; i++) {
+ if (i % 4)
+ tmp = sysdep_random();
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_mul_2exp (d, d, 8);
- mpz_add_ui (d, d, tmp & 0xFF);
+ mpz_mul_2exp(d, d, 8);
+ mpz_add_ui(d, d, tmp & 0xFF);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_lshift (d, d, 8);
- BN_add_word (d, tmp & 0xFF);
+ BN_lshift(d, d, 8);
+ BN_add_word(d, tmp & 0xFF);
#endif
- tmp >>= 8;
- }
- return 0;
+ tmp >>= 8;
+ }
+ return 0;
}
int
-modp_operation (struct group *group, math_mp_t d, math_mp_t a, math_mp_t e)
+modp_operation(struct group * group, math_mp_t d, math_mp_t a, math_mp_t e)
{
- struct modp_group *grp = (struct modp_group *)group->group;
+ struct modp_group *grp = (struct modp_group *) group->group;
#if MP_FLAVOUR == MP_FLAVOUR_GMP
- mpz_powm (d, a, e, grp->p);
+ mpz_powm(d, a, e, grp->p);
#elif MP_FLAVOUR == MP_FLAVOUR_OPENSSL
- BN_CTX *ctx = BN_CTX_new ();
- BN_mod_exp (d, a, e, grp->p, ctx);
- BN_CTX_free (ctx);
+ BN_CTX *ctx = BN_CTX_new();
+ BN_mod_exp(d, a, e, grp->p, ctx);
+ BN_CTX_free(ctx);
#endif
- return 0;
+ return 0;
}
#ifdef USE_EC
int
-ec2n_getlen (struct group *group)
+ec2n_getlen(struct group * group)
{
- struct ec2n_group *grp = (struct ec2n_group *)group->group;
- int bits = b2n_sigbit (grp->grp->p) - 1;
+ struct ec2n_group *grp = (struct ec2n_group *) group->group;
+ int bits = b2n_sigbit(grp->grp->p) - 1;
- return (7 + bits) >> 3;
+ return (7 + bits) >> 3;
}
void
-ec2n_getraw (struct group *group, ec2np_ptr xo, u_int8_t *e)
+ec2n_getraw(struct group * group, ec2np_ptr xo, u_int8_t * e)
{
- struct ec2n_group *grp = (struct ec2n_group *)group->group;
- int chunks, bytes, i, j;
- b2n_ptr x = xo->x;
- CHUNK_TYPE tmp;
-
- bytes = b2n_sigbit (grp->grp->p) - 1;
- chunks = (CHUNK_MASK + bytes) >> CHUNK_SHIFTS;
- bytes = ((7 + (bytes & CHUNK_MASK)) >> 3);
-
- for (i = chunks - 1; i >= 0; i--)
- {
- tmp = (i >= x->chunks ? 0 : x->limp[i]);
- for (j = (i == chunks - 1 ? bytes : CHUNK_BYTES) - 1; j >= 0; j--)
- {
- e[j] = tmp & 0xff;
- tmp >>= 8;
+ struct ec2n_group *grp = (struct ec2n_group *) group->group;
+ int chunks, bytes, i, j;
+ b2n_ptr x = xo->x;
+ CHUNK_TYPE tmp;
+
+ bytes = b2n_sigbit(grp->grp->p) - 1;
+ chunks = (CHUNK_MASK + bytes) >> CHUNK_SHIFTS;
+ bytes = ((7 + (bytes & CHUNK_MASK)) >> 3);
+
+ for (i = chunks - 1; i >= 0; i--) {
+ tmp = (i >= x->chunks ? 0 : x->limp[i]);
+ for (j = (i == chunks - 1 ? bytes : CHUNK_BYTES) - 1; j >= 0; j--) {
+ e[j] = tmp & 0xff;
+ tmp >>= 8;
+ }
+ e += (i == chunks - 1 ? bytes : CHUNK_BYTES);
}
- e += (i == chunks - 1 ? bytes : CHUNK_BYTES);
- }
}
int
-ec2n_setraw (struct group *grp, ec2np_ptr out, u_int8_t *s, int l)
+ec2n_setraw(struct group * grp, ec2np_ptr out, u_int8_t * s, int l)
{
- int len, bytes, i, j;
- b2n_ptr outx = out->x;
- CHUNK_TYPE tmp;
-
- len = (CHUNK_BYTES - 1 + l) / CHUNK_BYTES;
- if (b2n_resize (outx, len))
- return -1;
-
- bytes = ((l - 1) % CHUNK_BYTES) + 1;
-
- for (i = len - 1; i >= 0; i--)
- {
- tmp = 0;
- for (j = (i == len - 1 ? bytes : CHUNK_BYTES); j > 0; j--)
- {
- tmp <<= 8;
- tmp |= *s++;
+ int len, bytes, i, j;
+ b2n_ptr outx = out->x;
+ CHUNK_TYPE tmp;
+
+ len = (CHUNK_BYTES - 1 + l) / CHUNK_BYTES;
+ if (b2n_resize(outx, len))
+ return -1;
+
+ bytes = ((l - 1) % CHUNK_BYTES) + 1;
+
+ for (i = len - 1; i >= 0; i--) {
+ tmp = 0;
+ for (j = (i == len - 1 ? bytes : CHUNK_BYTES); j > 0; j--) {
+ tmp <<= 8;
+ tmp |= *s++;
+ }
+ outx->limp[i] = tmp;
}
- outx->limp[i] = tmp;
- }
- return 0;
+ return 0;
}
int
-ec2n_setrandom (struct group *group, ec2np_ptr x)
+ec2n_setrandom(struct group * group, ec2np_ptr x)
{
- b2n_ptr d = x->x;
- struct ec2n_group *grp = (struct ec2n_group *)group->group;
+ b2n_ptr d = x->x;
+ struct ec2n_group *grp = (struct ec2n_group *) group->group;
- return b2n_random (d, b2n_sigbit (grp->grp->p) - 1);
+ return b2n_random(d, b2n_sigbit(grp->grp->p) - 1);
}
/*
@@ -861,15 +847,15 @@ ec2n_setrandom (struct group *group, ec2np_ptr x)
* set to zero.
*/
int
-ec2n_operation (struct group *grp, ec2np_ptr d, ec2np_ptr a, ec2np_ptr e)
+ec2n_operation(struct group * grp, ec2np_ptr d, ec2np_ptr a, ec2np_ptr e)
{
- b2n_ptr ex = e->x;
- struct ec2n_group *group = (struct ec2n_group *)grp->group;
+ b2n_ptr ex = e->x;
+ struct ec2n_group *group = (struct ec2n_group *) grp->group;
- if (a->y->chunks == 0)
- if (ec2np_find_y (a, group->grp))
- return -1;
+ if (a->y->chunks == 0)
+ if (ec2np_find_y(a, group->grp))
+ return -1;
- return ec2np_mul (d, a, ex, group->grp);
+ return ec2np_mul(d, a, ex, group->grp);
}
-#endif /* USE_EC */
+#endif /* USE_EC */
diff --git a/sbin/isakmpd/math_group.h b/sbin/isakmpd/math_group.h
index 2365f00f624..d5a19bcc76d 100644
--- a/sbin/isakmpd/math_group.h
+++ b/sbin/isakmpd/math_group.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_group.h,v 1.9 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: math_group.h,v 1.7 1999/04/17 23:20:40 niklas Exp $ */
+/* $OpenBSD: math_group.h,v 1.10 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_group.h,v 1.7 1999/04/17 23:20:40 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -34,10 +34,10 @@
#define _MATH_GROUP_H_
enum groups {
- MODP, /* F_p, Z modulo a prime */
- EC2N, /* Elliptic Curve over the Field GF(2**N) */
- ECP, /* Elliptic Curve over the Field Z_p */
- NOTYET /* Not yet assigned */
+ MODP, /* F_p, Z modulo a prime */
+ EC2N, /* Elliptic Curve over the Field GF(2**N) */
+ ECP, /* Elliptic Curve over the Field Z_p */
+ NOTYET /* Not yet assigned */
};
/*
@@ -45,50 +45,50 @@ enum groups {
*/
struct group {
- enum groups type;
- int id; /* Group ID */
- int bits; /* Number of key bits provided by this group */
- void *group;
- void *a, *b, *c, *d;
- void *gen; /* Group Generator */
- int (*getlen) (struct group *);
- void (*getraw) (struct group *, void *, u_int8_t *);
- int (*setraw) (struct group *, void *, u_int8_t *, int);
- int (*setrandom) (struct group *, void *);
- int (*operation) (struct group *, void *, void *, void *);
+ enum groups type;
+ int id; /* Group ID */
+ int bits; /* Number of key bits provided by this group */
+ void *group;
+ void *a, *b, *c, *d;
+ void *gen; /* Group Generator */
+ int (*getlen) (struct group *);
+ void (*getraw) (struct group *, void *, u_int8_t *);
+ int (*setraw) (struct group *, void *, u_int8_t *, int);
+ int (*setrandom) (struct group *, void *);
+ int (*operation) (struct group *, void *, void *, void *);
};
/* Description of an Elliptic Group over GF(2**n) for Boot-Strapping */
struct ec2n_dscr {
- int id;
- int bits; /* Key Bits provided by this group */
- char *polynomial; /* Irreduceable polynomial */
- char *gen_x; /* X - Coord. of Generator */
- char *a, *b; /* Curve Parameters */
+ int id;
+ int bits; /* Key Bits provided by this group */
+ char *polynomial; /* Irreduceable polynomial */
+ char *gen_x; /* X - Coord. of Generator */
+ char *a, *b; /* Curve Parameters */
};
/* Description of F_p for Boot-Strapping */
struct modp_dscr {
- int id;
- int bits; /* Key Bits provided by this group */
- char *prime; /* Prime */
- char *gen; /* Generator */
+ int id;
+ int bits; /* Key Bits provided by this group */
+ char *prime; /* Prime */
+ char *gen; /* Generator */
};
/* Prototypes */
-void group_init (void);
-void group_free (struct group *);
-struct group *group_get (u_int32_t);
+void group_init(void);
+void group_free(struct group *);
+struct group *group_get(u_int32_t);
-void ec2n_free (struct group *);
-struct group *ec2n_clone (struct group *, struct group *);
-void ec2n_init (struct group *);
+void ec2n_free(struct group *);
+struct group *ec2n_clone(struct group *, struct group *);
+void ec2n_init(struct group *);
-void modp_free (struct group *);
-struct group *modp_clone (struct group *, struct group *);
-void modp_init (struct group *);
+void modp_free(struct group *);
+struct group *modp_clone(struct group *, struct group *);
+void modp_init(struct group *);
-#endif /* _MATH_GROUP_H_ */
+#endif /* _MATH_GROUP_H_ */
diff --git a/sbin/isakmpd/math_mp.h b/sbin/isakmpd/math_mp.h
index 6cb189ddfe9..ed554fc23a4 100644
--- a/sbin/isakmpd/math_mp.h
+++ b/sbin/isakmpd/math_mp.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: math_mp.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: math_mp.h,v 1.4 2000/09/16 09:41:43 ho Exp $ */
+/* $OpenBSD: math_mp.h,v 1.6 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: math_mp.h,v 1.4 2000/09/16 09:41:43 ho Exp $ */
/*
* Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -53,4 +53,4 @@ typedef BIGNUM *math_mp_t;
#endif
-#endif /* _MATH_MP_H_ */
+#endif /* _MATH_MP_H_ */
diff --git a/sbin/isakmpd/message.c b/sbin/isakmpd/message.c
index 9898ad69ca4..3f83c78cac0 100644
--- a/sbin/isakmpd/message.c
+++ b/sbin/isakmpd/message.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: message.c,v 1.70 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: message.c,v 1.156 2000/10/10 12:36:39 provos Exp $ */
+/* $OpenBSD: message.c,v 1.71 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: message.c,v 1.156 2000/10/10 12:36:39 provos Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -66,55 +66,57 @@
#endif
/* A local set datatype, coincidentally fd_set suits our purpose fine. */
-typedef fd_set set;
+typedef fd_set set;
#define ISSET FD_ISSET
#define SET FD_SET
#define ZERO FD_ZERO
-static int message_check_duplicate (struct message *);
-static int message_encrypt (struct message *);
-static int message_index_payload (struct message *, struct payload *, u_int8_t,
- u_int8_t *);
-static int message_parse_transform (struct message *, struct payload *,
- u_int8_t, u_int8_t *);
-static int message_validate_attribute (struct message *, struct payload *);
-static int message_validate_cert (struct message *, struct payload *);
-static int message_validate_cert_req (struct message *, struct payload *);
-static int message_validate_delete (struct message *, struct payload *);
-static int message_validate_hash (struct message *, struct payload *);
-static int message_validate_id (struct message *, struct payload *);
-static int message_validate_key_exch (struct message *, struct payload *);
-static int message_validate_nonce (struct message *, struct payload *);
-static int message_validate_notify (struct message *, struct payload *);
-static int message_validate_proposal (struct message *, struct payload *);
-static int message_validate_sa (struct message *, struct payload *);
-static int message_validate_sig (struct message *, struct payload *);
-static int message_validate_transform (struct message *, struct payload *);
-static int message_validate_vendor (struct message *, struct payload *);
-
-static void message_packet_log (struct message *);
-
-static int (*message_validate_payload[]) (struct message *, struct payload *) =
+static int message_check_duplicate(struct message *);
+static int message_encrypt(struct message *);
+static int
+message_index_payload(struct message *, struct payload *, u_int8_t,
+ u_int8_t *);
+static int
+message_parse_transform(struct message *, struct payload *,
+ u_int8_t, u_int8_t *);
+static int message_validate_attribute(struct message *, struct payload *);
+static int message_validate_cert(struct message *, struct payload *);
+static int message_validate_cert_req(struct message *, struct payload *);
+static int message_validate_delete(struct message *, struct payload *);
+static int message_validate_hash(struct message *, struct payload *);
+static int message_validate_id(struct message *, struct payload *);
+static int message_validate_key_exch(struct message *, struct payload *);
+static int message_validate_nonce(struct message *, struct payload *);
+static int message_validate_notify(struct message *, struct payload *);
+static int message_validate_proposal(struct message *, struct payload *);
+static int message_validate_sa(struct message *, struct payload *);
+static int message_validate_sig(struct message *, struct payload *);
+static int message_validate_transform(struct message *, struct payload *);
+static int message_validate_vendor(struct message *, struct payload *);
+
+static void message_packet_log(struct message *);
+
+static int (*message_validate_payload[]) (struct message *, struct payload *) =
{
- message_validate_sa, message_validate_proposal, message_validate_transform,
- message_validate_key_exch, message_validate_id, message_validate_cert,
- message_validate_cert_req, message_validate_hash, message_validate_sig,
- message_validate_nonce, message_validate_notify, message_validate_delete,
- message_validate_vendor, message_validate_attribute
+ message_validate_sa, message_validate_proposal, message_validate_transform,
+ message_validate_key_exch, message_validate_id, message_validate_cert,
+ message_validate_cert_req, message_validate_hash, message_validate_sig,
+ message_validate_nonce, message_validate_notify, message_validate_delete,
+ message_validate_vendor, message_validate_attribute
};
static struct field *fields[] = {
- isakmp_sa_fld, isakmp_prop_fld, isakmp_transform_fld, isakmp_ke_fld,
- isakmp_id_fld, isakmp_cert_fld, isakmp_certreq_fld, isakmp_hash_fld,
- isakmp_sig_fld, isakmp_nonce_fld, isakmp_notify_fld, isakmp_delete_fld,
- isakmp_vendor_fld, isakmp_attribute_fld
+ isakmp_sa_fld, isakmp_prop_fld, isakmp_transform_fld, isakmp_ke_fld,
+ isakmp_id_fld, isakmp_cert_fld, isakmp_certreq_fld, isakmp_hash_fld,
+ isakmp_sig_fld, isakmp_nonce_fld, isakmp_notify_fld, isakmp_delete_fld,
+ isakmp_vendor_fld, isakmp_attribute_fld
};
static u_int16_t min_payload_lengths[] = {
- 0, ISAKMP_SA_SZ, ISAKMP_PROP_SZ, ISAKMP_TRANSFORM_SZ, ISAKMP_KE_SZ,
- ISAKMP_ID_SZ, ISAKMP_CERT_SZ, ISAKMP_CERTREQ_SZ, ISAKMP_HASH_SZ,
- ISAKMP_SIG_SZ, ISAKMP_NONCE_SZ, ISAKMP_NOTIFY_SZ, ISAKMP_DELETE_SZ,
- ISAKMP_VENDOR_SZ, ISAKMP_ATTRIBUTE_SZ
+ 0, ISAKMP_SA_SZ, ISAKMP_PROP_SZ, ISAKMP_TRANSFORM_SZ, ISAKMP_KE_SZ,
+ ISAKMP_ID_SZ, ISAKMP_CERT_SZ, ISAKMP_CERTREQ_SZ, ISAKMP_HASH_SZ,
+ ISAKMP_SIG_SZ, ISAKMP_NONCE_SZ, ISAKMP_NOTIFY_SZ, ISAKMP_DELETE_SZ,
+ ISAKMP_VENDOR_SZ, ISAKMP_ATTRIBUTE_SZ
};
/*
@@ -131,42 +133,40 @@ static u_int32_t last_xf_no;
* segment buffer sized SZ, copied from BUF if given.
*/
struct message *
-message_alloc (struct transport *t, u_int8_t *buf, size_t sz)
+message_alloc(struct transport * t, u_int8_t * buf, size_t sz)
{
- struct message *msg;
- int i;
-
- /*
- * We use calloc(3) because it zeroes the structure which we rely on in
- * message_free when determining what sub-allocations to free.
- */
- msg = (struct message *)calloc (1, sizeof *msg);
- if (!msg)
- return 0;
- msg->iov = calloc (1, sizeof *msg->iov);
- if (!msg->iov)
- {
- message_free (msg);
- return 0;
- }
- msg->iov[0].iov_len = sz;
- msg->iov[0].iov_base = malloc (sz);
- if (!msg->iov[0].iov_base)
- {
- message_free (msg);
- return 0;
- }
- msg->iovlen = 1;
- if (buf)
- memcpy (msg->iov[0].iov_base, buf, sz);
- msg->nextp = (u_int8_t *)msg->iov[0].iov_base + ISAKMP_HDR_NEXT_PAYLOAD_OFF;
- msg->transport = t;
- transport_reference (t);
- for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
- TAILQ_INIT (&msg->payload[i]);
- TAILQ_INIT (&msg->post_send);
- LOG_DBG ((LOG_MESSAGE, 90, "message_alloc: allocated %p", msg));
- return msg;
+ struct message *msg;
+ int i;
+
+ /*
+ * We use calloc(3) because it zeroes the structure which we rely on in
+ * message_free when determining what sub-allocations to free.
+ */
+ msg = (struct message *) calloc(1, sizeof *msg);
+ if (!msg)
+ return 0;
+ msg->iov = calloc(1, sizeof *msg->iov);
+ if (!msg->iov) {
+ message_free(msg);
+ return 0;
+ }
+ msg->iov[0].iov_len = sz;
+ msg->iov[0].iov_base = malloc(sz);
+ if (!msg->iov[0].iov_base) {
+ message_free(msg);
+ return 0;
+ }
+ msg->iovlen = 1;
+ if (buf)
+ memcpy(msg->iov[0].iov_base, buf, sz);
+ msg->nextp = (u_int8_t *) msg->iov[0].iov_base + ISAKMP_HDR_NEXT_PAYLOAD_OFF;
+ msg->transport = t;
+ transport_reference(t);
+ for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
+ TAILQ_INIT(&msg->payload[i]);
+ TAILQ_INIT(&msg->post_send);
+ LOG_DBG((LOG_MESSAGE, 90, "message_alloc: allocated %p", msg));
+ return msg;
}
/*
@@ -174,62 +174,59 @@ message_alloc (struct transport *t, u_int8_t *buf, size_t sz)
* ISAKMP header as the first segment.
*/
struct message *
-message_alloc_reply (struct message *msg)
+message_alloc_reply(struct message * msg)
{
- struct message *reply;
-
- reply = message_alloc (msg->transport, 0, ISAKMP_HDR_SZ);
- reply->exchange = msg->exchange;
- reply->isakmp_sa = msg->isakmp_sa;
- if (msg->isakmp_sa)
- sa_reference (msg->isakmp_sa);
- return reply;
+ struct message *reply;
+
+ reply = message_alloc(msg->transport, 0, ISAKMP_HDR_SZ);
+ reply->exchange = msg->exchange;
+ reply->isakmp_sa = msg->isakmp_sa;
+ if (msg->isakmp_sa)
+ sa_reference(msg->isakmp_sa);
+ return reply;
}
/* Free up all resources used by the MSG message. */
void
-message_free (struct message *msg)
+message_free(struct message * msg)
{
- u_int32_t i;
- struct payload *payload, *next;
-
- LOG_DBG ((LOG_MESSAGE, 20, "message_free: freeing %p", msg));
- if (!msg)
- return;
- if (msg->orig && msg->orig != (u_int8_t *)msg->iov[0].iov_base)
- free (msg->orig);
- if (msg->iov)
- {
- for (i = 0; i < msg->iovlen; i++)
- if (msg->iov[i].iov_base)
- free (msg->iov[i].iov_base);
- free (msg->iov);
- }
- if (msg->retrans)
- timer_remove_event (msg->retrans);
- for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
- for (payload = TAILQ_FIRST (&msg->payload[i]); payload; payload = next)
- {
- next = TAILQ_NEXT (payload, link);
- free (payload);
- }
- while (TAILQ_FIRST (&msg->post_send) != 0)
- TAILQ_REMOVE (&msg->post_send, TAILQ_FIRST (&msg->post_send), link);
-
- /* If we are on the send queue, remove us from there. */
- if (msg->flags & MSG_IN_TRANSIT)
- {
- if (msg->flags & MSG_PRIORITIZED)
- TAILQ_REMOVE (&msg->transport->prio_sendq, msg, link);
- else
- TAILQ_REMOVE (&msg->transport->sendq, msg, link);
- }
- transport_release (msg->transport);
-
- if (msg->isakmp_sa)
- sa_release (msg->isakmp_sa);
-
- free (msg);
+ u_int32_t i;
+ struct payload *payload, *next;
+
+ LOG_DBG((LOG_MESSAGE, 20, "message_free: freeing %p", msg));
+ if (!msg)
+ return;
+ if (msg->orig && msg->orig != (u_int8_t *) msg->iov[0].iov_base)
+ free(msg->orig);
+ if (msg->iov) {
+ for (i = 0; i < msg->iovlen; i++)
+ if (msg->iov[i].iov_base)
+ free(msg->iov[i].iov_base);
+ free(msg->iov);
+ }
+ if (msg->retrans)
+ timer_remove_event(msg->retrans);
+ for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
+ for (payload = TAILQ_FIRST(&msg->payload[i]); payload; payload = next) {
+ next = TAILQ_NEXT(payload, link);
+ free(payload);
+ }
+ while (TAILQ_FIRST(&msg->post_send) != 0)
+ TAILQ_REMOVE(&msg->post_send, TAILQ_FIRST(&msg->post_send), link);
+
+ /* If we are on the send queue, remove us from there. */
+ if (msg->flags & MSG_IN_TRANSIT) {
+ if (msg->flags & MSG_PRIORITIZED)
+ TAILQ_REMOVE(&msg->transport->prio_sendq, msg, link);
+ else
+ TAILQ_REMOVE(&msg->transport->sendq, msg, link);
+ }
+ transport_release(msg->transport);
+
+ if (msg->isakmp_sa)
+ sa_release(msg->isakmp_sa);
+
+ free(msg);
}
/*
@@ -241,106 +238,91 @@ message_free (struct message *msg)
* parsed payloads.
*/
static int
-message_parse_payloads (struct message *msg, struct payload *p, u_int8_t next,
- u_int8_t *buf, set *accepted_payloads,
- int (*func) (struct message *, struct payload *,
- u_int8_t, u_int8_t *))
+message_parse_payloads(struct message * msg, struct payload * p, u_int8_t next,
+ u_int8_t * buf, set * accepted_payloads,
+ int (*func) (struct message *, struct payload *,
+ u_int8_t, u_int8_t *))
{
- u_int8_t payload;
- u_int16_t len;
- int sz = 0;
-
- do
- {
- LOG_DBG ((LOG_MESSAGE, 50,
- "message_parse_payloads: offset %ld payload %s",
- (long)(buf - (u_int8_t *)msg->iov[0].iov_base),
- constant_name (isakmp_payload_cst, next)));
-
- /* Does this payload's header fit? */
- if (buf + ISAKMP_GEN_SZ
- > (u_int8_t *)msg->iov[0].iov_base + msg->iov[0].iov_len)
- {
- log_print ("message_parse_payloads: short message");
- message_drop (msg, ISAKMP_NOTIFY_UNEQUAL_PAYLOAD_LENGTHS, 0, 1, 1);
- return -1;
- }
-
- /* Ponder on the payload that is at BUF... */
- payload = next;
-
- /* Look at the next payload's type. */
- next = GET_ISAKMP_GEN_NEXT_PAYLOAD (buf);
- if (next >= ISAKMP_PAYLOAD_RESERVED_MIN &&
- next <= ISAKMP_PAYLOAD_RESERVED_MAX)
- {
- log_print ("message_parse_payloads: invalid next payload type %d "
- "in payload of type %d", next, payload);
- message_drop (msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
- return -1;
- }
-
- /* Reserved fields in ISAKMP messages should be zero. */
- if (GET_ISAKMP_GEN_RESERVED (buf) != 0)
- {
- log_print ("message_parse_payloads: reserved field non-zero: %x",
- GET_ISAKMP_GEN_RESERVED (buf));
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /*
- * Decode and validate the payload length field.
- */
- len = GET_ISAKMP_GEN_LENGTH (buf);
-
- if ((payload < ISAKMP_PAYLOAD_RESERVED_MIN)
- && (len < min_payload_lengths[payload]))
- {
- log_print ("message_parse_payloads: payload too short: %u", len);
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- if (buf + len > (u_int8_t *)msg->iov[0].iov_base + msg->iov[0].iov_len)
- {
- log_print ("message_parse_payloads: payload too long: %u", len);
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /* Ignore private payloads. */
- if (next >= ISAKMP_PAYLOAD_PRIVATE_MIN)
- {
- LOG_DBG ((LOG_MESSAGE, 30,
- "message_parse_payloads: private next payload type %d "
- "in payload of type %d ignored", next, payload));
- goto next_payload;
- }
-
- /*
- * Check if the current payload is one of the accepted ones at this
- * stage.
- */
- if (!ISSET (payload, accepted_payloads))
- {
- log_print ("message_parse_payloads: payload type %d unexpected",
- payload);
- message_drop (msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
- return -1;
- }
-
- /* Call the payload handler specified by the caller. */
- if (func (msg, p, payload, buf))
- return -1;
-
- next_payload:
- /* Advance to next payload. */
- buf += len;
- sz += len;
- }
- while (next != ISAKMP_PAYLOAD_NONE);
- return sz;
+ u_int8_t payload;
+ u_int16_t len;
+ int sz = 0;
+
+ do {
+ LOG_DBG((LOG_MESSAGE, 50,
+ "message_parse_payloads: offset %ld payload %s",
+ (long) (buf - (u_int8_t *) msg->iov[0].iov_base),
+ constant_name(isakmp_payload_cst, next)));
+
+ /* Does this payload's header fit? */
+ if (buf + ISAKMP_GEN_SZ
+ > (u_int8_t *) msg->iov[0].iov_base + msg->iov[0].iov_len) {
+ log_print("message_parse_payloads: short message");
+ message_drop(msg, ISAKMP_NOTIFY_UNEQUAL_PAYLOAD_LENGTHS, 0, 1, 1);
+ return -1;
+ }
+ /* Ponder on the payload that is at BUF... */
+ payload = next;
+
+ /* Look at the next payload's type. */
+ next = GET_ISAKMP_GEN_NEXT_PAYLOAD(buf);
+ if (next >= ISAKMP_PAYLOAD_RESERVED_MIN &&
+ next <= ISAKMP_PAYLOAD_RESERVED_MAX) {
+ log_print("message_parse_payloads: invalid next payload type %d "
+ "in payload of type %d", next, payload);
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
+ return -1;
+ }
+ /* Reserved fields in ISAKMP messages should be zero. */
+ if (GET_ISAKMP_GEN_RESERVED(buf) != 0) {
+ log_print("message_parse_payloads: reserved field non-zero: %x",
+ GET_ISAKMP_GEN_RESERVED(buf));
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Decode and validate the payload length field.
+ */
+ len = GET_ISAKMP_GEN_LENGTH(buf);
+
+ if ((payload < ISAKMP_PAYLOAD_RESERVED_MIN)
+ && (len < min_payload_lengths[payload])) {
+ log_print("message_parse_payloads: payload too short: %u", len);
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ if (buf + len > (u_int8_t *) msg->iov[0].iov_base + msg->iov[0].iov_len) {
+ log_print("message_parse_payloads: payload too long: %u", len);
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /* Ignore private payloads. */
+ if (next >= ISAKMP_PAYLOAD_PRIVATE_MIN) {
+ LOG_DBG((LOG_MESSAGE, 30,
+ "message_parse_payloads: private next payload type %d "
+ "in payload of type %d ignored", next, payload));
+ goto next_payload;
+ }
+ /*
+ * Check if the current payload is one of the accepted ones at this
+ * stage.
+ */
+ if (!ISSET(payload, accepted_payloads)) {
+ log_print("message_parse_payloads: payload type %d unexpected",
+ payload);
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
+ return -1;
+ }
+ /* Call the payload handler specified by the caller. */
+ if (func(msg, p, payload, buf))
+ return -1;
+
+next_payload:
+ /* Advance to next payload. */
+ buf += len;
+ sz += len;
+ }
+ while (next != ISAKMP_PAYLOAD_NONE);
+ return sz;
}
/*
@@ -350,109 +332,103 @@ message_parse_payloads (struct message *msg, struct payload *p, u_int8_t next,
* generic payload header.
*/
static int
-message_parse_proposal (struct message *msg, struct payload *p,
- u_int8_t payload, u_int8_t *buf)
+message_parse_proposal(struct message * msg, struct payload * p,
+ u_int8_t payload, u_int8_t * buf)
{
- set payload_set;
-
- /* Put the proposal into the proposal bucket. */
- message_index_payload (msg, p, payload, buf);
-
- ZERO (&payload_set);
- SET (ISAKMP_PAYLOAD_TRANSFORM, &payload_set);
- if (message_parse_payloads (msg,
- TAILQ_LAST (&msg->payload
- [ISAKMP_PAYLOAD_PROPOSAL],
- payload_head),
- ISAKMP_PAYLOAD_TRANSFORM,
- buf + ISAKMP_PROP_SPI_OFF
- + GET_ISAKMP_PROP_SPI_SZ (buf),
- &payload_set, message_parse_transform) == -1)
- return -1;
-
- return 0;
+ set payload_set;
+
+ /* Put the proposal into the proposal bucket. */
+ message_index_payload(msg, p, payload, buf);
+
+ ZERO(&payload_set);
+ SET(ISAKMP_PAYLOAD_TRANSFORM, &payload_set);
+ if (message_parse_payloads(msg,
+ TAILQ_LAST(&msg->payload
+ [ISAKMP_PAYLOAD_PROPOSAL],
+ payload_head),
+ ISAKMP_PAYLOAD_TRANSFORM,
+ buf + ISAKMP_PROP_SPI_OFF
+ + GET_ISAKMP_PROP_SPI_SZ(buf),
+ &payload_set, message_parse_transform) == -1)
+ return -1;
+
+ return 0;
}
static int
-message_parse_transform (struct message *msg, struct payload *p,
- u_int8_t payload, u_int8_t *buf)
+message_parse_transform(struct message * msg, struct payload * p,
+ u_int8_t payload, u_int8_t * buf)
{
- /* Put the transform into the transform bucket. */
- message_index_payload (msg, p, payload, buf);
+ /* Put the transform into the transform bucket. */
+ message_index_payload(msg, p, payload, buf);
- LOG_DBG ((LOG_MESSAGE, 50, "Transform %d's attributes",
- GET_ISAKMP_TRANSFORM_NO (buf)));
+ LOG_DBG((LOG_MESSAGE, 50, "Transform %d's attributes",
+ GET_ISAKMP_TRANSFORM_NO(buf)));
#ifdef USE_DEBUG
- attribute_map (buf + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (buf) - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- msg->exchange->doi->debug_attribute, msg);
+ attribute_map(buf + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(buf) - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ msg->exchange->doi->debug_attribute, msg);
#endif
- return 0;
+ return 0;
}
/* Validate the attribute payload P in message MSG. */
static int
-message_validate_attribute (struct message *msg, struct payload *p)
+message_validate_attribute(struct message * msg, struct payload * p)
{
#ifdef USE_ISAKMP_CFG
- /* If we don't have an exchange yet, create one. */
- if (!msg->exchange)
- {
- if (zero_test ((u_int8_t *)msg->iov[0].iov_base
- + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
- msg->exchange = exchange_setup_p1 (msg, IPSEC_DOI_IPSEC);
- else
- msg->exchange = exchange_setup_p2 (msg, IPSEC_DOI_IPSEC);
- if (!msg->exchange)
- {
- log_print ("message_validate_attribute: can not create exchange");
- message_free (msg);
- return -1;
- }
- }
+ /* If we don't have an exchange yet, create one. */
+ if (!msg->exchange) {
+ if (zero_test((u_int8_t *) msg->iov[0].iov_base
+ + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
+ msg->exchange = exchange_setup_p1(msg, IPSEC_DOI_IPSEC);
+ else
+ msg->exchange = exchange_setup_p2(msg, IPSEC_DOI_IPSEC);
+ if (!msg->exchange) {
+ log_print("message_validate_attribute: can not create exchange");
+ message_free(msg);
+ return -1;
+ }
+ }
#endif
- return 0;
+ return 0;
}
/* Validate the certificate payload P in message MSG. */
static int
-message_validate_cert (struct message *msg, struct payload *p)
+message_validate_cert(struct message * msg, struct payload * p)
{
- if (GET_ISAKMP_CERT_ENCODING (p->p) >= ISAKMP_CERTENC_RESERVED_MIN)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_CERT_ENCODING, 0, 1, 1);
- return -1;
- }
- return 0;
+ if (GET_ISAKMP_CERT_ENCODING(p->p) >= ISAKMP_CERTENC_RESERVED_MIN) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_CERT_ENCODING, 0, 1, 1);
+ return -1;
+ }
+ return 0;
}
/* Validate the certificate request payload P in message MSG. */
static int
-message_validate_cert_req (struct message *msg, struct payload *p)
+message_validate_cert_req(struct message * msg, struct payload * p)
{
- struct cert_handler *cert;
- size_t len = GET_ISAKMP_GEN_LENGTH (p->p)- ISAKMP_CERTREQ_AUTHORITY_OFF;
-
- if (GET_ISAKMP_CERTREQ_TYPE (p->p) >= ISAKMP_CERTENC_RESERVED_MIN)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_CERT_ENCODING, 0, 1, 1);
- return -1;
- }
-
- /*
- * Check the certificate types we support and if an acceptable authority
- * is included in the payload check if it can be decoded
- */
- cert = cert_get (GET_ISAKMP_CERTREQ_TYPE (p->p));
- if (!cert
- || (len && !cert->certreq_validate (p->p + ISAKMP_CERTREQ_AUTHORITY_OFF,
- len)))
- {
- message_drop (msg, ISAKMP_NOTIFY_CERT_TYPE_UNSUPPORTED, 0, 1, 1);
- return -1;
- }
- return 0;
+ struct cert_handler *cert;
+ size_t len = GET_ISAKMP_GEN_LENGTH(p->p) - ISAKMP_CERTREQ_AUTHORITY_OFF;
+
+ if (GET_ISAKMP_CERTREQ_TYPE(p->p) >= ISAKMP_CERTENC_RESERVED_MIN) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_CERT_ENCODING, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Check the certificate types we support and if an acceptable authority
+ * is included in the payload check if it can be decoded
+ */
+ cert = cert_get(GET_ISAKMP_CERTREQ_TYPE(p->p));
+ if (!cert
+ || (len && !cert->certreq_validate(p->p + ISAKMP_CERTREQ_AUTHORITY_OFF,
+ len))) {
+ message_drop(msg, ISAKMP_NOTIFY_CERT_TYPE_UNSUPPORTED, 0, 1, 1);
+ return -1;
+ }
+ return 0;
}
/*
@@ -460,94 +436,83 @@ message_validate_cert_req (struct message *msg, struct payload *p)
* an exchange if we do not have one already.
*/
static int
-message_validate_delete (struct message *msg, struct payload *p)
+message_validate_delete(struct message * msg, struct payload * p)
{
- u_int8_t proto = GET_ISAKMP_DELETE_PROTO (p->p);
- struct doi *doi;
- struct sa *sa, *isakmp_sa;
- struct sockaddr *dst, *dst_isa;
- u_int32_t nspis = GET_ISAKMP_DELETE_NSPIS (p->p);
- u_int8_t *spis = (u_int8_t *)p->p + ISAKMP_DELETE_SPI_OFF;
- u_int32_t i;
- char *addr;
-
- doi = doi_lookup (GET_ISAKMP_DELETE_DOI (p->p));
- if (!doi)
- {
- log_print ("message_validate_delete: DOI not supported");
- message_free (msg);
- return -1;
- }
-
- /* If we don't have an exchange yet, create one. */
- if (!msg->exchange)
- {
- if (zero_test ((u_int8_t *)msg->iov[0].iov_base
- + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
- msg->exchange = exchange_setup_p1 (msg, doi->id);
- else
- msg->exchange = exchange_setup_p2 (msg, doi->id);
- if (!msg->exchange)
- {
- log_print ("message_validate_delete: can not create exchange");
- message_free (msg);
- return -1;
- }
- }
-
- if (proto != ISAKMP_PROTO_ISAKMP && doi->validate_proto (proto))
- {
- log_print ("message_validate_delete: protocol not supported");
- message_free (msg);
- return -1;
- }
-
- /* Validate the SPIs. */
- for (i = 0; i < nspis; i++)
- {
- /* Get ISAKMP SA protecting this message. */
- isakmp_sa = msg->isakmp_sa;
- if (!isakmp_sa)
- {
- /* XXX should not happen? */
- log_print ("message_validate_delete: invalid spi "
- "(no valid ISAKMP SA found)");
- message_free (msg);
- return -1;
- }
- isakmp_sa->transport->vtbl->get_dst (isakmp_sa->transport, &dst_isa);
-
- /* Get SA to be deleted. */
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- if (proto == ISAKMP_PROTO_ISAKMP)
- sa = sa_lookup_isakmp_sa (dst, spis + i * ISAKMP_HDR_COOKIES_LEN);
- else
- sa = ipsec_sa_lookup (dst, ((u_int32_t *)spis)[i], proto);
- if (!sa)
- {
- LOG_DBG ((LOG_MESSAGE, 50, "message_validate_delete: invalid spi "
- "(no valid SA found)"));
- message_free (msg);
- return -1;
- }
- sa->transport->vtbl->get_dst (sa->transport, &dst);
-
- /* Destination addresses must match. */
- if (dst->sa_family != dst_isa->sa_family ||
- memcmp (sockaddr_addrdata (dst_isa), sockaddr_addrdata (dst),
- sockaddr_addrlen (dst)))
- {
- sockaddr2text (dst_isa, &addr, 0);
-
- log_print ("message_validate_delete: invalid spi "
- "(illegal delete request from %s)", addr);
- free (addr);
- message_free (msg);
- return -1;
- }
- }
-
- return 0;
+ u_int8_t proto = GET_ISAKMP_DELETE_PROTO(p->p);
+ struct doi *doi;
+ struct sa *sa, *isakmp_sa;
+ struct sockaddr *dst, *dst_isa;
+ u_int32_t nspis = GET_ISAKMP_DELETE_NSPIS(p->p);
+ u_int8_t *spis = (u_int8_t *) p->p + ISAKMP_DELETE_SPI_OFF;
+ u_int32_t i;
+ char *addr;
+
+ doi = doi_lookup(GET_ISAKMP_DELETE_DOI(p->p));
+ if (!doi) {
+ log_print("message_validate_delete: DOI not supported");
+ message_free(msg);
+ return -1;
+ }
+ /* If we don't have an exchange yet, create one. */
+ if (!msg->exchange) {
+ if (zero_test((u_int8_t *) msg->iov[0].iov_base
+ + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
+ msg->exchange = exchange_setup_p1(msg, doi->id);
+ else
+ msg->exchange = exchange_setup_p2(msg, doi->id);
+ if (!msg->exchange) {
+ log_print("message_validate_delete: can not create exchange");
+ message_free(msg);
+ return -1;
+ }
+ }
+ if (proto != ISAKMP_PROTO_ISAKMP && doi->validate_proto(proto)) {
+ log_print("message_validate_delete: protocol not supported");
+ message_free(msg);
+ return -1;
+ }
+ /* Validate the SPIs. */
+ for (i = 0; i < nspis; i++) {
+ /* Get ISAKMP SA protecting this message. */
+ isakmp_sa = msg->isakmp_sa;
+ if (!isakmp_sa) {
+ /* XXX should not happen? */
+ log_print("message_validate_delete: invalid spi "
+ "(no valid ISAKMP SA found)");
+ message_free(msg);
+ return -1;
+ }
+ isakmp_sa->transport->vtbl->get_dst(isakmp_sa->transport, &dst_isa);
+
+ /* Get SA to be deleted. */
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ if (proto == ISAKMP_PROTO_ISAKMP)
+ sa = sa_lookup_isakmp_sa(dst, spis + i * ISAKMP_HDR_COOKIES_LEN);
+ else
+ sa = ipsec_sa_lookup(dst, ((u_int32_t *) spis)[i], proto);
+ if (!sa) {
+ LOG_DBG((LOG_MESSAGE, 50, "message_validate_delete: invalid spi "
+ "(no valid SA found)"));
+ message_free(msg);
+ return -1;
+ }
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+
+ /* Destination addresses must match. */
+ if (dst->sa_family != dst_isa->sa_family ||
+ memcmp(sockaddr_addrdata(dst_isa), sockaddr_addrdata(dst),
+ sockaddr_addrlen(dst))) {
+ sockaddr2text(dst_isa, &addr, 0);
+
+ log_print("message_validate_delete: invalid spi "
+ "(illegal delete request from %s)", addr);
+ free(addr);
+ message_free(msg);
+ return -1;
+ }
+ }
+
+ return 0;
}
/*
@@ -556,165 +521,146 @@ message_validate_delete (struct message *msg, struct payload *p)
* except INFORMATIONAL. This should be actually done here.
*/
static int
-message_validate_hash (struct message *msg, struct payload *p)
+message_validate_hash(struct message * msg, struct payload * p)
{
- struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa;
- struct hash *hash;
- struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
- struct prf *prf;
- u_int8_t *comp_hash, *rest;
- u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
- size_t rest_len;
-
- if (msg->exchange) /* active exchange validates hash payload. */
- return 0;
-
- if (isakmp_sa == NULL)
- {
- log_print ("message_validate_hash: invalid hash information");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
- return -1;
- }
-
- isa = isakmp_sa->data;
- hash = hash_get (isa->hash);
-
- if (hash == NULL)
- {
- log_print ("message_validate_hash: invalid hash information");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
- return -1;
- }
-
- /* If no SKEYID_a, we can not do anything (should not happen). */
- if (!isa->skeyid_a)
- {
- log_print ("message_validate_hash: invalid hash information");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
- return -1;
- }
-
- /* Allocate the prf and start calculating our HASH(1). */
- LOG_DBG_BUF ((LOG_MISC, 90, "message_validate_hash: SKEYID_a", isa->skeyid_a,
- isa->skeyid_len));
- prf = prf_alloc (isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
- if (!prf)
- {
- message_free (msg);
- return -1;
- }
-
- comp_hash = (u_int8_t *)malloc (hash->hashsize);
- if (!comp_hash)
- {
- log_error ("message_validate_hash: malloc (%lu) failed",
- (unsigned long)hash->hashsize);
- prf_free (prf);
- message_free (msg);
- return -1;
- }
-
- /* This is not an active exchange. */
- GET_ISAKMP_HDR_MESSAGE_ID (msg->iov[0].iov_base, message_id);
-
- prf->Init (prf->prfctx);
- LOG_DBG_BUF ((LOG_MISC, 90, "message_validate_hash: message_id",
- message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
- prf->Update (prf->prfctx, message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- rest = hashp->p + GET_ISAKMP_GEN_LENGTH (hashp->p);
- rest_len = (GET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base)
- - (rest - (u_int8_t*)msg->iov[0].iov_base));
- LOG_DBG_BUF ((LOG_MISC, 90, "message_validate_hash: payloads after HASH(1)",
- rest, rest_len));
- prf->Update (prf->prfctx, rest, rest_len);
- prf->Final (comp_hash, prf->prfctx);
- prf_free (prf);
-
- if (memcmp (hashp->p + ISAKMP_HASH_DATA_OFF, comp_hash, hash->hashsize))
- {
- log_print ("message_validate_hash: invalid hash value for %s payload",
- TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_DELETE])
- ? "DELETE" : "NOTIFY");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- free (comp_hash);
- return -1;
- }
- free (comp_hash);
-
- /* Mark the HASH as handled. */
- hashp->flags |= PL_MARK;
-
- return 0;
+ struct sa *isakmp_sa = msg->isakmp_sa;
+ struct ipsec_sa *isa;
+ struct hash *hash;
+ struct payload *hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ struct prf *prf;
+ u_int8_t *comp_hash, *rest;
+ u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
+ size_t rest_len;
+
+ if (msg->exchange) /* active exchange validates hash payload. */
+ return 0;
+
+ if (isakmp_sa == NULL) {
+ log_print("message_validate_hash: invalid hash information");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
+ return -1;
+ }
+ isa = isakmp_sa->data;
+ hash = hash_get(isa->hash);
+
+ if (hash == NULL) {
+ log_print("message_validate_hash: invalid hash information");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
+ return -1;
+ }
+ /* If no SKEYID_a, we can not do anything (should not happen). */
+ if (!isa->skeyid_a) {
+ log_print("message_validate_hash: invalid hash information");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1);
+ return -1;
+ }
+ /* Allocate the prf and start calculating our HASH(1). */
+ LOG_DBG_BUF((LOG_MISC, 90, "message_validate_hash: SKEYID_a", isa->skeyid_a,
+ isa->skeyid_len));
+ prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, isa->skeyid_len);
+ if (!prf) {
+ message_free(msg);
+ return -1;
+ }
+ comp_hash = (u_int8_t *) malloc(hash->hashsize);
+ if (!comp_hash) {
+ log_error("message_validate_hash: malloc (%lu) failed",
+ (unsigned long) hash->hashsize);
+ prf_free(prf);
+ message_free(msg);
+ return -1;
+ }
+ /* This is not an active exchange. */
+ GET_ISAKMP_HDR_MESSAGE_ID(msg->iov[0].iov_base, message_id);
+
+ prf->Init(prf->prfctx);
+ LOG_DBG_BUF((LOG_MISC, 90, "message_validate_hash: message_id",
+ message_id, ISAKMP_HDR_MESSAGE_ID_LEN));
+ prf->Update(prf->prfctx, message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ rest = hashp->p + GET_ISAKMP_GEN_LENGTH(hashp->p);
+ rest_len = (GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base)
+ - (rest - (u_int8_t *) msg->iov[0].iov_base));
+ LOG_DBG_BUF((LOG_MISC, 90, "message_validate_hash: payloads after HASH(1)",
+ rest, rest_len));
+ prf->Update(prf->prfctx, rest, rest_len);
+ prf->Final(comp_hash, prf->prfctx);
+ prf_free(prf);
+
+ if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF, comp_hash, hash->hashsize)) {
+ log_print("message_validate_hash: invalid hash value for %s payload",
+ TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE])
+ ? "DELETE" : "NOTIFY");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ free(comp_hash);
+ return -1;
+ }
+ free(comp_hash);
+
+ /* Mark the HASH as handled. */
+ hashp->flags |= PL_MARK;
+
+ return 0;
}
/* Validate the identification payload P in message MSG. */
static int
-message_validate_id (struct message *msg, struct payload *p)
+message_validate_id(struct message * msg, struct payload * p)
{
- struct exchange *exchange = msg->exchange;
- size_t len = GET_ISAKMP_GEN_LENGTH (p->p);
-
- if (!exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_id: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- if (exchange->doi
- && exchange->doi->validate_id_information (GET_ISAKMP_ID_TYPE (p->p),
- p->p + ISAKMP_ID_DOI_DATA_OFF,
- p->p + ISAKMP_ID_DATA_OFF,
- len - ISAKMP_ID_DATA_OFF,
- exchange))
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 1);
- return -1;
- }
- return 0;
+ struct exchange *exchange = msg->exchange;
+ size_t len = GET_ISAKMP_GEN_LENGTH(p->p);
+
+ if (!exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_id: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ if (exchange->doi
+ && exchange->doi->validate_id_information(GET_ISAKMP_ID_TYPE(p->p),
+ p->p + ISAKMP_ID_DOI_DATA_OFF,
+ p->p + ISAKMP_ID_DATA_OFF,
+ len - ISAKMP_ID_DATA_OFF,
+ exchange)) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 1);
+ return -1;
+ }
+ return 0;
}
/* Validate the key exchange payload P in message MSG. */
static int
-message_validate_key_exch (struct message *msg, struct payload *p)
+message_validate_key_exch(struct message * msg, struct payload * p)
{
- struct exchange *exchange = msg->exchange;
- size_t len = GET_ISAKMP_GEN_LENGTH (p->p);
-
- if (!exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_key_exch: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- if (exchange->doi
- && exchange->doi->validate_key_information (p->p + ISAKMP_KE_DATA_OFF,
- len - ISAKMP_KE_DATA_OFF))
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_KEY_INFORMATION, 0, 1, 1);
- return -1;
- }
- return 0;
+ struct exchange *exchange = msg->exchange;
+ size_t len = GET_ISAKMP_GEN_LENGTH(p->p);
+
+ if (!exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_key_exch: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ if (exchange->doi
+ && exchange->doi->validate_key_information(p->p + ISAKMP_KE_DATA_OFF,
+ len - ISAKMP_KE_DATA_OFF)) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_KEY_INFORMATION, 0, 1, 1);
+ return -1;
+ }
+ return 0;
}
/* Validate the nonce payload P in message MSG. */
static int
-message_validate_nonce (struct message *msg, struct payload *p)
+message_validate_nonce(struct message * msg, struct payload * p)
{
- if (!msg->exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_nonce: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /* Nonces require no specific validation. */
- return 0;
+ if (!msg->exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_nonce: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /* Nonces require no specific validation. */
+ return 0;
}
/*
@@ -722,97 +668,84 @@ message_validate_nonce (struct message *msg, struct payload *p)
* an exchange if we do not have one already.
*/
static int
-message_validate_notify (struct message *msg, struct payload *p)
+message_validate_notify(struct message * msg, struct payload * p)
{
- u_int8_t proto = GET_ISAKMP_NOTIFY_PROTO (p->p);
- u_int16_t type = GET_ISAKMP_NOTIFY_MSG_TYPE (p->p);
- struct doi *doi;
-
- doi = doi_lookup (GET_ISAKMP_NOTIFY_DOI (p->p));
- if (!doi)
- {
- log_print ("message_validate_notify: DOI not supported");
- message_free (msg);
- return -1;
- }
-
- /* If we don't have an exchange yet, create one. */
- if (!msg->exchange)
- {
- if (zero_test ((u_int8_t *)msg->iov[0].iov_base
- + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
- msg->exchange = exchange_setup_p1 (msg, doi->id);
- else
- msg->exchange = exchange_setup_p2 (msg, doi->id);
- if (!msg->exchange)
- {
- log_print ("message_validate_notify: can not create exchange");
- message_free (msg);
- return -1;
- }
- }
-
- if (proto != ISAKMP_PROTO_ISAKMP && doi->validate_proto (proto))
- {
- log_print ("message_validate_notify: protocol not supported");
- message_free (msg);
- return -1;
- }
-
- /* XXX Validate the SPI. */
-
- if (type < ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE
- || (type >= ISAKMP_NOTIFY_RESERVED_MIN
- && type < ISAKMP_NOTIFY_PRIVATE_MIN)
- || (type >= ISAKMP_NOTIFY_STATUS_RESERVED1_MIN
- && type <= ISAKMP_NOTIFY_STATUS_RESERVED1_MAX)
- || (type >= ISAKMP_NOTIFY_STATUS_DOI_MIN
- && type <= ISAKMP_NOTIFY_STATUS_DOI_MAX
- && doi->validate_notification (type))
- || type >= ISAKMP_NOTIFY_STATUS_RESERVED2_MIN)
- {
- log_print ("message_validate_notify: message type not supported");
- message_free (msg);
- return -1;
- }
- return 0;
+ u_int8_t proto = GET_ISAKMP_NOTIFY_PROTO(p->p);
+ u_int16_t type = GET_ISAKMP_NOTIFY_MSG_TYPE(p->p);
+ struct doi *doi;
+
+ doi = doi_lookup(GET_ISAKMP_NOTIFY_DOI(p->p));
+ if (!doi) {
+ log_print("message_validate_notify: DOI not supported");
+ message_free(msg);
+ return -1;
+ }
+ /* If we don't have an exchange yet, create one. */
+ if (!msg->exchange) {
+ if (zero_test((u_int8_t *) msg->iov[0].iov_base
+ + ISAKMP_HDR_MESSAGE_ID_OFF, ISAKMP_HDR_MESSAGE_ID_LEN))
+ msg->exchange = exchange_setup_p1(msg, doi->id);
+ else
+ msg->exchange = exchange_setup_p2(msg, doi->id);
+ if (!msg->exchange) {
+ log_print("message_validate_notify: can not create exchange");
+ message_free(msg);
+ return -1;
+ }
+ }
+ if (proto != ISAKMP_PROTO_ISAKMP && doi->validate_proto(proto)) {
+ log_print("message_validate_notify: protocol not supported");
+ message_free(msg);
+ return -1;
+ }
+ /* XXX Validate the SPI. */
+
+ if (type < ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE
+ || (type >= ISAKMP_NOTIFY_RESERVED_MIN
+ && type < ISAKMP_NOTIFY_PRIVATE_MIN)
+ || (type >= ISAKMP_NOTIFY_STATUS_RESERVED1_MIN
+ && type <= ISAKMP_NOTIFY_STATUS_RESERVED1_MAX)
+ || (type >= ISAKMP_NOTIFY_STATUS_DOI_MIN
+ && type <= ISAKMP_NOTIFY_STATUS_DOI_MAX
+ && doi->validate_notification(type))
+ || type >= ISAKMP_NOTIFY_STATUS_RESERVED2_MIN) {
+ log_print("message_validate_notify: message type not supported");
+ message_free(msg);
+ return -1;
+ }
+ return 0;
}
/* Validate the proposal payload P in message MSG. */
static int
-message_validate_proposal (struct message *msg, struct payload *p)
+message_validate_proposal(struct message * msg, struct payload * p)
{
- u_int8_t proto = GET_ISAKMP_PROP_PROTO (p->p);
- u_int8_t *sa = p->context->p;
-
- if (!msg->exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_proposal: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- if (proto != ISAKMP_PROTO_ISAKMP
- && msg->exchange->doi->validate_proto (proto))
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_PROTOCOL_ID, 0, 1, 1);
- return -1;
- }
-
- /* Check that we get monotonically increasing proposal IDs per SA. */
- if (sa != last_sa)
- last_sa = sa;
- else if (GET_ISAKMP_PROP_NO (p->p) < last_prop_no)
- {
- message_drop (msg, ISAKMP_NOTIFY_BAD_PROPOSAL_SYNTAX, 0, 1, 1);
- return -1;
- }
- last_prop_no = GET_ISAKMP_PROP_NO (p->p);
-
- /* XXX Validate the SPI, and other syntactic things. */
-
- return 0;
+ u_int8_t proto = GET_ISAKMP_PROP_PROTO(p->p);
+ u_int8_t *sa = p->context->p;
+
+ if (!msg->exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_proposal: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ if (proto != ISAKMP_PROTO_ISAKMP
+ && msg->exchange->doi->validate_proto(proto)) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_PROTOCOL_ID, 0, 1, 1);
+ return -1;
+ }
+ /* Check that we get monotonically increasing proposal IDs per SA. */
+ if (sa != last_sa)
+ last_sa = sa;
+ else if (GET_ISAKMP_PROP_NO(p->p) < last_prop_no) {
+ message_drop(msg, ISAKMP_NOTIFY_BAD_PROPOSAL_SYNTAX, 0, 1, 1);
+ return -1;
+ }
+ last_prop_no = GET_ISAKMP_PROP_NO(p->p);
+
+ /* XXX Validate the SPI, and other syntactic things. */
+
+ return 0;
}
/*
@@ -827,190 +760,165 @@ message_validate_proposal (struct message *msg, struct payload *p)
* first due to the IANA assigned payload number?
*/
static int
-message_validate_sa (struct message *msg, struct payload *p)
+message_validate_sa(struct message * msg, struct payload * p)
{
- set payload_set;
- size_t len;
- u_int32_t doi_id;
- struct exchange *exchange = msg->exchange;
- u_int8_t *pkt = msg->iov[0].iov_base;
-
- doi_id = GET_ISAKMP_SA_DOI (p->p);
- if (!doi_lookup (doi_id))
- {
- log_print ("message_validate_sa: DOI not supported");
- message_drop (msg, ISAKMP_NOTIFY_DOI_NOT_SUPPORTED, 0, 1, 1);
- return -1;
- }
-
- /*
- * It's time to figure out what SA this message is about. If it is
- * already set, then we are creating a new phase 1 SA. Otherwise, lookup
- * the SA using the cookies and the message ID. If we cannot find
- * it, and the phase 1 SA is ready, setup a phase 2 SA.
- */
- if (!exchange)
- {
- if (zero_test (pkt + ISAKMP_HDR_RCOOKIE_OFF, ISAKMP_HDR_RCOOKIE_LEN))
- exchange = exchange_setup_p1 (msg, doi_id);
- else if (msg->isakmp_sa->flags & SA_FLAG_READY)
- exchange = exchange_setup_p2 (msg, doi_id);
- else
- {
- /* XXX What to do here? */
- message_free (msg);
- return -1;
- }
- if (!exchange)
- {
- /* XXX Log? */
- message_free (msg);
- return -1;
- }
- }
- msg->exchange = exchange;
-
- /*
- * Create a struct sa for each SA payload handed to us unless we are the
- * initiator where we only will count them.
- */
- if (exchange->initiator)
- {
- /* XXX Count SA payloads. */
- }
- else if (sa_create (exchange, msg->transport))
- {
- /* XXX Remove exchange if we just created it? */
- message_free (msg);
- return -1;
- }
-
- if (exchange->phase == 1)
- {
- msg->isakmp_sa = TAILQ_FIRST (&exchange->sa_list);
- if (msg->isakmp_sa)
- sa_reference (msg->isakmp_sa);
- }
-
- /*
- * Let the DOI validate the situation, at the same time it tells us what
- * the length of the situation field is.
- */
- if (exchange->doi->validate_situation (p->p + ISAKMP_SA_SIT_OFF, &len,
- GET_ISAKMP_GEN_LENGTH (p->p) - ISAKMP_SA_SIT_OFF))
- {
- log_print ("message_validate_sa: situation not supported");
- message_drop (msg, ISAKMP_NOTIFY_SITUATION_NOT_SUPPORTED, 0, 1, 1);
- return -1;
- }
-
- /* Reset the fields we base our proposal & transform number checks on. */
- last_sa = last_prop = 0;
- last_prop_no = last_xf_no = 0;
-
- /* Go through the PROPOSAL payloads. */
- ZERO (&payload_set);
- SET (ISAKMP_PAYLOAD_PROPOSAL, &payload_set);
- if (message_parse_payloads (msg, p, ISAKMP_PAYLOAD_PROPOSAL,
- p->p + ISAKMP_SA_SIT_OFF + len, &payload_set,
- message_parse_proposal) == -1)
- return -1;
-
- return 0;
+ set payload_set;
+ size_t len;
+ u_int32_t doi_id;
+ struct exchange *exchange = msg->exchange;
+ u_int8_t *pkt = msg->iov[0].iov_base;
+
+ doi_id = GET_ISAKMP_SA_DOI(p->p);
+ if (!doi_lookup(doi_id)) {
+ log_print("message_validate_sa: DOI not supported");
+ message_drop(msg, ISAKMP_NOTIFY_DOI_NOT_SUPPORTED, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * It's time to figure out what SA this message is about. If it is
+ * already set, then we are creating a new phase 1 SA. Otherwise, lookup
+ * the SA using the cookies and the message ID. If we cannot find
+ * it, and the phase 1 SA is ready, setup a phase 2 SA.
+ */
+ if (!exchange) {
+ if (zero_test(pkt + ISAKMP_HDR_RCOOKIE_OFF, ISAKMP_HDR_RCOOKIE_LEN))
+ exchange = exchange_setup_p1(msg, doi_id);
+ else if (msg->isakmp_sa->flags & SA_FLAG_READY)
+ exchange = exchange_setup_p2(msg, doi_id);
+ else {
+ /* XXX What to do here? */
+ message_free(msg);
+ return -1;
+ }
+ if (!exchange) {
+ /* XXX Log? */
+ message_free(msg);
+ return -1;
+ }
+ }
+ msg->exchange = exchange;
+
+ /*
+ * Create a struct sa for each SA payload handed to us unless we are the
+ * initiator where we only will count them.
+ */
+ if (exchange->initiator) {
+ /* XXX Count SA payloads. */
+ } else if (sa_create(exchange, msg->transport)) {
+ /* XXX Remove exchange if we just created it? */
+ message_free(msg);
+ return -1;
+ }
+ if (exchange->phase == 1) {
+ msg->isakmp_sa = TAILQ_FIRST(&exchange->sa_list);
+ if (msg->isakmp_sa)
+ sa_reference(msg->isakmp_sa);
+ }
+ /*
+ * Let the DOI validate the situation, at the same time it tells us what
+ * the length of the situation field is.
+ */
+ if (exchange->doi->validate_situation(p->p + ISAKMP_SA_SIT_OFF, &len,
+ GET_ISAKMP_GEN_LENGTH(p->p) - ISAKMP_SA_SIT_OFF)) {
+ log_print("message_validate_sa: situation not supported");
+ message_drop(msg, ISAKMP_NOTIFY_SITUATION_NOT_SUPPORTED, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Reset the fields we base our proposal & transform number checks
+ * on.
+ */
+ last_sa = last_prop = 0;
+ last_prop_no = last_xf_no = 0;
+
+ /* Go through the PROPOSAL payloads. */
+ ZERO(&payload_set);
+ SET(ISAKMP_PAYLOAD_PROPOSAL, &payload_set);
+ if (message_parse_payloads(msg, p, ISAKMP_PAYLOAD_PROPOSAL,
+ p->p + ISAKMP_SA_SIT_OFF + len, &payload_set,
+ message_parse_proposal) == -1)
+ return -1;
+
+ return 0;
}
/* Validate the signature payload P in message MSG. */
static int
-message_validate_sig (struct message *msg, struct payload *p)
+message_validate_sig(struct message * msg, struct payload * p)
{
- if (!msg->exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_sig: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /* XXX Not implemented yet. */
- return 0;
+ if (!msg->exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_sig: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /* XXX Not implemented yet. */
+ return 0;
}
/* Validate the transform payload P in message MSG. */
static int
-message_validate_transform (struct message *msg, struct payload *p)
+message_validate_transform(struct message * msg, struct payload * p)
{
- u_int8_t proto = GET_ISAKMP_PROP_PROTO (p->context->p);
- u_int8_t *prop = p->context->p;
-
- if (!msg->exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_transform: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- if (msg->exchange->doi
- ->validate_transform_id (proto, GET_ISAKMP_TRANSFORM_ID (p->p)))
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_TRANSFORM_ID, 0, 1, 1);
- return -1;
- }
-
- /* Check that the reserved field is zero. */
- if (!zero_test (p->p + ISAKMP_TRANSFORM_RESERVED_OFF,
- ISAKMP_TRANSFORM_RESERVED_LEN))
- {
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /*
- * Check that we get monotonically increasing transform numbers per proposal.
- */
- if (prop != last_prop)
- last_prop = prop;
- else if (GET_ISAKMP_TRANSFORM_NO (p->p) <= last_xf_no)
- {
- message_drop (msg, ISAKMP_NOTIFY_BAD_PROPOSAL_SYNTAX, 0, 1, 1);
- return -1;
- }
- last_xf_no = GET_ISAKMP_TRANSFORM_NO (p->p);
-
- /* Validate the attributes. */
- if (attribute_map (p->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (p->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- msg->exchange->doi->validate_attribute, msg))
- {
- message_drop (msg, ISAKMP_NOTIFY_ATTRIBUTES_NOT_SUPPORTED, 0, 1, 1);
- return -1;
- }
-
- return 0;
+ u_int8_t proto = GET_ISAKMP_PROP_PROTO(p->context->p);
+ u_int8_t *prop = p->context->p;
+
+ if (!msg->exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_transform: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ if (msg->exchange->doi
+ ->validate_transform_id(proto, GET_ISAKMP_TRANSFORM_ID(p->p))) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_TRANSFORM_ID, 0, 1, 1);
+ return -1;
+ }
+ /* Check that the reserved field is zero. */
+ if (!zero_test(p->p + ISAKMP_TRANSFORM_RESERVED_OFF,
+ ISAKMP_TRANSFORM_RESERVED_LEN)) {
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Check that we get monotonically increasing transform numbers per proposal.
+ */
+ if (prop != last_prop)
+ last_prop = prop;
+ else if (GET_ISAKMP_TRANSFORM_NO(p->p) <= last_xf_no) {
+ message_drop(msg, ISAKMP_NOTIFY_BAD_PROPOSAL_SYNTAX, 0, 1, 1);
+ return -1;
+ }
+ last_xf_no = GET_ISAKMP_TRANSFORM_NO(p->p);
+
+ /* Validate the attributes. */
+ if (attribute_map(p->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(p->p)
+ - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ msg->exchange->doi->validate_attribute, msg)) {
+ message_drop(msg, ISAKMP_NOTIFY_ATTRIBUTES_NOT_SUPPORTED, 0, 1, 1);
+ return -1;
+ }
+ return 0;
}
/* Validate the vendor payload P in message MSG. */
static int
-message_validate_vendor (struct message *msg, struct payload *p)
+message_validate_vendor(struct message * msg, struct payload * p)
{
- if (!msg->exchange)
- {
- /* We should have an exchange at this point. */
- log_print ("message_validate_vendor: payload out of sequence");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return -1;
- }
-
- /* Vendor IDs are only allowed in phase 1. */
- if (msg->exchange->phase != 1)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
- return -1;
- }
-
- LOG_DBG ((LOG_MESSAGE, 40, "message_validate_vendor: vendor ID seen"));
- return 0;
+ if (!msg->exchange) {
+ /* We should have an exchange at this point. */
+ log_print("message_validate_vendor: payload out of sequence");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return -1;
+ }
+ /* Vendor IDs are only allowed in phase 1. */
+ if (msg->exchange->phase != 1) {
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
+ return -1;
+ }
+ LOG_DBG((LOG_MESSAGE, 40, "message_validate_vendor: vendor ID seen"));
+ return 0;
}
/*
@@ -1020,20 +928,20 @@ message_validate_vendor (struct message *msg, struct payload *p)
* node so we can go from transforms -> payloads -> SAs.
*/
static int
-message_index_payload (struct message *msg, struct payload *p,
- u_int8_t payload, u_int8_t *buf)
+message_index_payload(struct message * msg, struct payload * p,
+ u_int8_t payload, u_int8_t * buf)
{
- struct payload *payload_node;
-
- /* Put the payload pointer into the right bucket. */
- payload_node = malloc (sizeof *payload_node);
- if (!payload_node)
- return -1;
- payload_node->p = buf;
- payload_node->context = p;
- payload_node->flags = 0;
- TAILQ_INSERT_TAIL (&msg->payload[payload], payload_node, link);
- return 0;
+ struct payload *payload_node;
+
+ /* Put the payload pointer into the right bucket. */
+ payload_node = malloc(sizeof *payload_node);
+ if (!payload_node)
+ return -1;
+ payload_node->p = buf;
+ payload_node->context = p;
+ payload_node->flags = 0;
+ TAILQ_INSERT_TAIL(&msg->payload[payload], payload_node, link);
+ return 0;
}
/*
@@ -1043,45 +951,44 @@ message_index_payload (struct message *msg, struct payload *p,
* computed message length (i.e. without padding) in msg->iov[0].iov_len.
*/
static int
-message_sort_payloads (struct message *msg, u_int8_t next)
+message_sort_payloads(struct message * msg, u_int8_t next)
{
- set payload_set;
- int i, sz;
-
- ZERO (&payload_set);
- for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
- if (i != ISAKMP_PAYLOAD_PROPOSAL && i != ISAKMP_PAYLOAD_TRANSFORM)
- SET (i, &payload_set);
- sz =
- message_parse_payloads (msg, 0, next,
- (u_int8_t *)msg->iov[0].iov_base + ISAKMP_HDR_SZ,
- &payload_set, message_index_payload);
- if (sz == -1)
- return -1;
- msg->iov[0].iov_len = ISAKMP_HDR_SZ + sz;
- SET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base, ISAKMP_HDR_SZ + sz);
- return 0;
+ set payload_set;
+ int i, sz;
+
+ ZERO(&payload_set);
+ for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
+ if (i != ISAKMP_PAYLOAD_PROPOSAL && i != ISAKMP_PAYLOAD_TRANSFORM)
+ SET(i, &payload_set);
+ sz =
+ message_parse_payloads(msg, 0, next,
+ (u_int8_t *) msg->iov[0].iov_base + ISAKMP_HDR_SZ,
+ &payload_set, message_index_payload);
+ if (sz == -1)
+ return -1;
+ msg->iov[0].iov_len = ISAKMP_HDR_SZ + sz;
+ SET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base, ISAKMP_HDR_SZ + sz);
+ return 0;
}
/* Run all the generic payload tests that the drafts specify. */
static int
-message_validate_payloads (struct message *msg)
+message_validate_payloads(struct message * msg)
{
- int i;
- struct payload *p;
-
- for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
- for (p = TAILQ_FIRST (&msg->payload[i]); p; p = TAILQ_NEXT (p, link))
- {
- LOG_DBG ((LOG_MESSAGE, 60,
- "message_validate_payloads: "
- "payload %s at %p of message %p",
- constant_name (isakmp_payload_cst, i), p->p, msg));
- field_dump_payload (fields[i - ISAKMP_PAYLOAD_SA], p->p);
- if (message_validate_payload[i - ISAKMP_PAYLOAD_SA] (msg, p))
- return -1;
- }
- return 0;
+ int i;
+ struct payload *p;
+
+ for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
+ for (p = TAILQ_FIRST(&msg->payload[i]); p; p = TAILQ_NEXT(p, link)) {
+ LOG_DBG((LOG_MESSAGE, 60,
+ "message_validate_payloads: "
+ "payload %s at %p of message %p",
+ constant_name(isakmp_payload_cst, i), p->p, msg));
+ field_dump_payload(fields[i - ISAKMP_PAYLOAD_SA], p->p);
+ if (message_validate_payload[i - ISAKMP_PAYLOAD_SA] (msg, p))
+ return -1;
+ }
+ return 0;
}
/*
@@ -1090,390 +997,342 @@ message_validate_payloads (struct message *msg)
* the exchange this message, MSG, is part of, and feed it there.
*/
int
-message_recv (struct message *msg)
+message_recv(struct message * msg)
{
- u_int8_t *buf = msg->iov[0].iov_base;
- size_t sz = msg->iov[0].iov_len;
- u_int8_t exch_type;
- int setup_isakmp_sa, msgid_is_zero;
- u_int8_t flags;
- struct keystate *ks = 0;
- struct proto tmp_proto;
- struct sa tmp_sa;
-
- /* Messages shorter than an ISAKMP header are bad. */
- if (sz < ISAKMP_HDR_SZ || sz != GET_ISAKMP_HDR_LENGTH (buf))
- {
- log_print ("message_recv: bad message length");
- message_drop (msg, ISAKMP_NOTIFY_UNEQUAL_PAYLOAD_LENGTHS, 0, 1, 1);
- return -1;
- }
-
+ u_int8_t *buf = msg->iov[0].iov_base;
+ size_t sz = msg->iov[0].iov_len;
+ u_int8_t exch_type;
+ int setup_isakmp_sa, msgid_is_zero;
+ u_int8_t flags;
+ struct keystate *ks = 0;
+ struct proto tmp_proto;
+ struct sa tmp_sa;
+
+ /* Messages shorter than an ISAKMP header are bad. */
+ if (sz < ISAKMP_HDR_SZ || sz != GET_ISAKMP_HDR_LENGTH(buf)) {
+ log_print("message_recv: bad message length");
+ message_drop(msg, ISAKMP_NOTIFY_UNEQUAL_PAYLOAD_LENGTHS, 0, 1, 1);
+ return -1;
+ }
#ifdef USE_DEBUG
- /* Possibly dump a raw hex image of the message to the log channel. */
- message_dump_raw ("message_recv", msg, LOG_MESSAGE);
+ /* Possibly dump a raw hex image of the message to the log channel. */
+ message_dump_raw("message_recv", msg, LOG_MESSAGE);
#endif
- /*
- * If the responder cookie is zero, this is a request to setup an ISAKMP SA.
- * Otherwise the cookies should refer to an existing ISAKMP SA.
- *
- * XXX This is getting ugly, please reread later to see if it can be made
- * nicer.
- */
- setup_isakmp_sa = zero_test (buf + ISAKMP_HDR_RCOOKIE_OFF,
- ISAKMP_HDR_RCOOKIE_LEN);
- if (setup_isakmp_sa)
- {
- /*
- * This might be a retransmission of a former ISAKMP SA setup message.
- * If so, just drop it.
- * XXX Must we really look in both the SA and exchange pools?
- */
- if (exchange_lookup_from_icookie (buf + ISAKMP_HDR_ICOOKIE_OFF)
- || sa_lookup_from_icookie (buf + ISAKMP_HDR_ICOOKIE_OFF))
- {
- /*
- * XXX Later we should differentiate between retransmissions and
- * potential replay attacks.
- */
- LOG_DBG ((LOG_MESSAGE, 90,
- "message_recv: dropping setup for existing SA"));
- message_free (msg);
- return -1;
- }
- }
- else
- {
- msg->isakmp_sa = sa_lookup_by_header (buf, 0);
- if (msg->isakmp_sa)
- sa_reference (msg->isakmp_sa);
-
- /*
- * If we cannot find an ISAKMP SA out of the cookies, this is either
- * a responder's first reply, and we need to upgrade our exchange,
- * or it's just plain invalid cookies.
- */
- if (!msg->isakmp_sa)
- {
- msg->exchange
- = exchange_lookup_from_icookie (buf + ISAKMP_HDR_ICOOKIE_OFF);
- if (msg->exchange && msg->exchange->phase == 1
- && zero_test (msg->exchange->cookies + ISAKMP_HDR_RCOOKIE_OFF,
- ISAKMP_HDR_RCOOKIE_LEN))
- exchange_upgrade_p1 (msg);
- else
- {
- log_print ("message_recv: invalid cookie(s) %08x%08x %08x%08x",
- decode_32 (buf + ISAKMP_HDR_ICOOKIE_OFF),
- decode_32 (buf + ISAKMP_HDR_ICOOKIE_OFF + 4),
- decode_32 (buf + ISAKMP_HDR_RCOOKIE_OFF),
- decode_32 (buf + ISAKMP_HDR_RCOOKIE_OFF + 4));
- tmp_proto.sa = &tmp_sa;
- tmp_sa.doi = doi_lookup (ISAKMP_DOI_ISAKMP);
- tmp_proto.proto = ISAKMP_PROTO_ISAKMP;
- tmp_proto.spi_sz[1] = ISAKMP_HDR_COOKIES_LEN;
- tmp_proto.spi[1] = buf + ISAKMP_HDR_COOKIES_OFF;
- message_drop (msg, ISAKMP_NOTIFY_INVALID_COOKIE, &tmp_proto, 1,
- 1);
- return -1;
- }
+ /*
+ * If the responder cookie is zero, this is a request to setup an ISAKMP SA.
+ * Otherwise the cookies should refer to an existing ISAKMP SA.
+ *
+ * XXX This is getting ugly, please reread later to see if it can be made
+ * nicer.
+ */
+ setup_isakmp_sa = zero_test(buf + ISAKMP_HDR_RCOOKIE_OFF,
+ ISAKMP_HDR_RCOOKIE_LEN);
+ if (setup_isakmp_sa) {
+ /*
+ * This might be a retransmission of a former ISAKMP SA setup message.
+ * If so, just drop it.
+ * XXX Must we really look in both the SA and exchange pools?
+ */
+ if (exchange_lookup_from_icookie(buf + ISAKMP_HDR_ICOOKIE_OFF)
+ || sa_lookup_from_icookie(buf + ISAKMP_HDR_ICOOKIE_OFF)) {
+ /*
+ * XXX Later we should differentiate between retransmissions and
+ * potential replay attacks.
+ */
+ LOG_DBG((LOG_MESSAGE, 90,
+ "message_recv: dropping setup for existing SA"));
+ message_free(msg);
+ return -1;
+ }
+ } else {
+ msg->isakmp_sa = sa_lookup_by_header(buf, 0);
+ if (msg->isakmp_sa)
+ sa_reference(msg->isakmp_sa);
+
+ /*
+ * If we cannot find an ISAKMP SA out of the cookies, this is either
+ * a responder's first reply, and we need to upgrade our exchange,
+ * or it's just plain invalid cookies.
+ */
+ if (!msg->isakmp_sa) {
+ msg->exchange
+ = exchange_lookup_from_icookie(buf + ISAKMP_HDR_ICOOKIE_OFF);
+ if (msg->exchange && msg->exchange->phase == 1
+ && zero_test(msg->exchange->cookies + ISAKMP_HDR_RCOOKIE_OFF,
+ ISAKMP_HDR_RCOOKIE_LEN))
+ exchange_upgrade_p1(msg);
+ else {
+ log_print("message_recv: invalid cookie(s) %08x%08x %08x%08x",
+ decode_32(buf + ISAKMP_HDR_ICOOKIE_OFF),
+ decode_32(buf + ISAKMP_HDR_ICOOKIE_OFF + 4),
+ decode_32(buf + ISAKMP_HDR_RCOOKIE_OFF),
+ decode_32(buf + ISAKMP_HDR_RCOOKIE_OFF + 4));
+ tmp_proto.sa = &tmp_sa;
+ tmp_sa.doi = doi_lookup(ISAKMP_DOI_ISAKMP);
+ tmp_proto.proto = ISAKMP_PROTO_ISAKMP;
+ tmp_proto.spi_sz[1] = ISAKMP_HDR_COOKIES_LEN;
+ tmp_proto.spi[1] = buf + ISAKMP_HDR_COOKIES_OFF;
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_COOKIE, &tmp_proto, 1,
+ 1);
+ return -1;
+ }
#if 0
- msg->isakmp_sa
- = sa_lookup_from_icookie (buf + ISAKMP_HDR_ICOOKIE_OFF);
- if (msg->isakmp_sa)
- sa_isakmp_upgrade (msg);
+ msg->isakmp_sa
+ = sa_lookup_from_icookie(buf + ISAKMP_HDR_ICOOKIE_OFF);
+ if (msg->isakmp_sa)
+ sa_isakmp_upgrade(msg);
#endif
+ }
+ msg->exchange = exchange_lookup(buf, 1);
+ }
+
+ if (message_check_duplicate(msg))
+ return -1;
+
+ if (GET_ISAKMP_HDR_NEXT_PAYLOAD(buf) >= ISAKMP_PAYLOAD_RESERVED_MIN) {
+ log_print("message_recv: "
+ "invalid payload type %d in ISAKMP header "
+ "(check passphrases, if applicable and in Phase 1)",
+ GET_ISAKMP_HDR_NEXT_PAYLOAD(buf));
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
+ return -1;
+ }
+ /* Validate that the message is of version 1.0. */
+ if (ISAKMP_VERSION_MAJOR(GET_ISAKMP_HDR_VERSION(buf)) != 1) {
+ log_print("message_recv: invalid version major %d",
+ ISAKMP_VERSION_MAJOR(GET_ISAKMP_HDR_VERSION(buf)));
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_MAJOR_VERSION, 0, 1, 1);
+ return -1;
+ }
+ if (ISAKMP_VERSION_MINOR(GET_ISAKMP_HDR_VERSION(buf)) != 0) {
+ log_print("message_recv: invalid version minor %d",
+ ISAKMP_VERSION_MINOR(GET_ISAKMP_HDR_VERSION(buf)));
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_MINOR_VERSION, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Validate the exchange type. If it's a DOI-specified exchange wait until
+ * after all payloads have been seen for the validation as the SA payload
+ * might not yet have been parsed, thus the DOI might be unknown.
+ */
+ exch_type = GET_ISAKMP_HDR_EXCH_TYPE(buf);
+ if (exch_type == ISAKMP_EXCH_NONE
+ || (exch_type >= ISAKMP_EXCH_FUTURE_MIN &&
+ exch_type <= ISAKMP_EXCH_FUTURE_MAX)
+ || (setup_isakmp_sa && exch_type >= ISAKMP_EXCH_DOI_MIN)) {
+ log_print("message_recv: invalid exchange type %s",
+ constant_name(isakmp_exch_cst, exch_type));
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_EXCHANGE_TYPE, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * Check for unrecognized flags, or the encryption flag when we don't
+ * have an ISAKMP SA to decrypt with.
+ */
+ flags = GET_ISAKMP_HDR_FLAGS(buf);
+ if (flags
+ & ~(ISAKMP_FLAGS_ENC | ISAKMP_FLAGS_COMMIT | ISAKMP_FLAGS_AUTH_ONLY)) {
+ log_print("message_recv: invalid flags 0x%x",
+ GET_ISAKMP_HDR_FLAGS(buf));
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_FLAGS, 0, 1, 1);
+ return -1;
+ }
+ /*
+ * If we are about to setup an ISAKMP SA, the message ID must be
+ * zero.
+ */
+ msgid_is_zero = zero_test(buf + ISAKMP_HDR_MESSAGE_ID_OFF,
+ ISAKMP_HDR_MESSAGE_ID_LEN);
+ if (setup_isakmp_sa && !msgid_is_zero) {
+ log_print("message_recv: invalid message id");
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_MESSAGE_ID, 0, 1, 1);
+ return -1;
+ }
+ if (!setup_isakmp_sa && msgid_is_zero) {
+ /*
+ * XXX Very likely redundant, look at the else clause of the
+ * if (setup_isakmp_sa) statement above.
+ */
+ msg->exchange = exchange_lookup(buf, 0);
+ if (!msg->exchange) {
+ log_print("message_recv: phase 1 message after ISAKMP SA is ready");
+ message_free(msg);
+ return -1;
+ } else if (msg->exchange->last_sent) {
+ LOG_DBG((LOG_MESSAGE, 80,
+ "message_recv: resending last message from phase 1"));
+ message_send(msg->exchange->last_sent);
+ }
+ }
+ if (flags & ISAKMP_FLAGS_ENC) {
+ if (!msg->isakmp_sa) {
+ LOG_DBG((LOG_MISC, 10,
+ "message_recv: no isakmp_sa for encrypted message"));
+ message_free(msg);
+ return -1;
+ }
+ /* Decrypt rest of message using a DOI-specified IV. */
+ ks = msg->isakmp_sa->doi->get_keystate(msg);
+ if (!ks) {
+ message_free(msg);
+ return -1;
+ }
+ msg->orig = malloc(sz);
+ if (!msg->orig) {
+ message_free(msg);
+ free(ks);
+ return -1;
+ }
+ memcpy(msg->orig, buf, sz);
+ crypto_decrypt(ks, buf + ISAKMP_HDR_SZ, sz - ISAKMP_HDR_SZ);
+ } else
+ msg->orig = buf;
+ msg->orig_sz = sz;
+
+ /* IKE packet capture */
+ message_packet_log(msg);
+
+ /*
+ * Check the overall payload structure at the same time as indexing them by
+ * type.
+ */
+ if (GET_ISAKMP_HDR_NEXT_PAYLOAD(buf) != ISAKMP_PAYLOAD_NONE
+ && message_sort_payloads(msg, GET_ISAKMP_HDR_NEXT_PAYLOAD(buf))) {
+ if (ks)
+ free(ks);
+ return -1;
+ }
+ /*
+ * Run generic payload tests now. If anything fails these checks, the
+ * message needs either to be retained for later duplicate checks or
+ * freed entirely.
+ * XXX Should SAs and even transports be cleaned up then too?
+ */
+ if (message_validate_payloads(msg)) {
+ if (ks)
+ free(ks);
+ return -1;
+ }
+ /*
+ * If we have not found an exchange by now something is definitely
+ * wrong.
+ */
+ if (!msg->exchange) {
+ log_print("message_recv: no exchange");
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ if (ks)
+ free(ks);
+ return -1;
+ }
+ /*
+ * Now we can validate DOI-specific exchange types. If we have no SA
+ * DOI-specific exchange types are definitely wrong.
+ */
+ if (exch_type >= ISAKMP_EXCH_DOI_MIN && exch_type <= ISAKMP_EXCH_DOI_MAX
+ && msg->exchange->doi->validate_exchange(exch_type)) {
+ log_print("message_recv: invalid DOI exchange type %d", exch_type);
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_EXCHANGE_TYPE, 0, 1, 1);
+ if (ks)
+ free(ks);
+ return -1;
+ }
+ /* Make sure the IV we used gets saved in the proper SA. */
+ if (ks) {
+ if (!msg->exchange->keystate) {
+ msg->exchange->keystate = ks;
+ msg->exchange->crypto = ks->xf;
+ } else
+ free(ks);
}
- msg->exchange = exchange_lookup (buf, 1);
- }
-
- if (message_check_duplicate (msg))
- return -1;
-
- if (GET_ISAKMP_HDR_NEXT_PAYLOAD (buf) >= ISAKMP_PAYLOAD_RESERVED_MIN)
- {
- log_print ("message_recv: "
- "invalid payload type %d in ISAKMP header "
- "(check passphrases, if applicable and in Phase 1)",
- GET_ISAKMP_HDR_NEXT_PAYLOAD (buf));
- message_drop (msg, ISAKMP_NOTIFY_INVALID_PAYLOAD_TYPE, 0, 1, 1);
- return -1;
- }
-
- /* Validate that the message is of version 1.0. */
- if (ISAKMP_VERSION_MAJOR (GET_ISAKMP_HDR_VERSION (buf)) != 1)
- {
- log_print ("message_recv: invalid version major %d",
- ISAKMP_VERSION_MAJOR (GET_ISAKMP_HDR_VERSION (buf)));
- message_drop (msg, ISAKMP_NOTIFY_INVALID_MAJOR_VERSION, 0, 1, 1);
- return -1;
- }
-
- if (ISAKMP_VERSION_MINOR (GET_ISAKMP_HDR_VERSION (buf)) != 0)
- {
- log_print ("message_recv: invalid version minor %d",
- ISAKMP_VERSION_MINOR (GET_ISAKMP_HDR_VERSION (buf)));
- message_drop (msg, ISAKMP_NOTIFY_INVALID_MINOR_VERSION, 0, 1, 1);
- return -1;
- }
-
- /*
- * Validate the exchange type. If it's a DOI-specified exchange wait until
- * after all payloads have been seen for the validation as the SA payload
- * might not yet have been parsed, thus the DOI might be unknown.
- */
- exch_type = GET_ISAKMP_HDR_EXCH_TYPE (buf);
- if (exch_type == ISAKMP_EXCH_NONE
- || (exch_type >= ISAKMP_EXCH_FUTURE_MIN &&
- exch_type <= ISAKMP_EXCH_FUTURE_MAX)
- || (setup_isakmp_sa && exch_type >= ISAKMP_EXCH_DOI_MIN))
- {
- log_print ("message_recv: invalid exchange type %s",
- constant_name (isakmp_exch_cst, exch_type));
- message_drop (msg, ISAKMP_NOTIFY_INVALID_EXCHANGE_TYPE, 0, 1, 1);
- return -1;
- }
-
- /*
- * Check for unrecognized flags, or the encryption flag when we don't
- * have an ISAKMP SA to decrypt with.
- */
- flags = GET_ISAKMP_HDR_FLAGS (buf);
- if (flags
- & ~(ISAKMP_FLAGS_ENC | ISAKMP_FLAGS_COMMIT | ISAKMP_FLAGS_AUTH_ONLY))
- {
- log_print ("message_recv: invalid flags 0x%x",
- GET_ISAKMP_HDR_FLAGS (buf));
- message_drop (msg, ISAKMP_NOTIFY_INVALID_FLAGS, 0, 1, 1);
- return -1;
- }
-
- /* If we are about to setup an ISAKMP SA, the message ID must be zero. */
- msgid_is_zero = zero_test (buf + ISAKMP_HDR_MESSAGE_ID_OFF,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- if (setup_isakmp_sa && !msgid_is_zero)
- {
- log_print ("message_recv: invalid message id");
- message_drop (msg, ISAKMP_NOTIFY_INVALID_MESSAGE_ID, 0, 1, 1);
- return -1;
- }
-
- if (!setup_isakmp_sa && msgid_is_zero)
- {
- /*
- * XXX Very likely redundant, look at the else clause of the
- * if (setup_isakmp_sa) statement above.
- */
- msg->exchange = exchange_lookup (buf, 0);
- if (!msg->exchange)
- {
- log_print ("message_recv: phase 1 message after ISAKMP SA is ready");
- message_free (msg);
- return -1;
- }
- else if (msg->exchange->last_sent)
- {
- LOG_DBG ((LOG_MESSAGE, 80,
- "message_recv: resending last message from phase 1"));
- message_send (msg->exchange->last_sent);
- }
- }
-
- if (flags & ISAKMP_FLAGS_ENC)
- {
- if (!msg->isakmp_sa)
- {
- LOG_DBG ((LOG_MISC, 10,
- "message_recv: no isakmp_sa for encrypted message"));
- message_free (msg);
- return -1;
- }
-
- /* Decrypt rest of message using a DOI-specified IV. */
- ks = msg->isakmp_sa->doi->get_keystate (msg);
- if (!ks)
- {
- message_free (msg);
- return -1;
- }
- msg->orig = malloc (sz);
- if (!msg->orig)
- {
- message_free (msg);
- free (ks);
- return -1;
- }
- memcpy (msg->orig, buf, sz);
- crypto_decrypt (ks, buf + ISAKMP_HDR_SZ, sz - ISAKMP_HDR_SZ);
- }
- else
- msg->orig = buf;
- msg->orig_sz = sz;
-
- /* IKE packet capture */
- message_packet_log (msg);
-
- /*
- * Check the overall payload structure at the same time as indexing them by
- * type.
- */
- if (GET_ISAKMP_HDR_NEXT_PAYLOAD (buf) != ISAKMP_PAYLOAD_NONE
- && message_sort_payloads (msg, GET_ISAKMP_HDR_NEXT_PAYLOAD (buf)))
- {
- if (ks)
- free (ks);
- return -1;
- }
-
- /*
- * Run generic payload tests now. If anything fails these checks, the
- * message needs either to be retained for later duplicate checks or
- * freed entirely.
- * XXX Should SAs and even transports be cleaned up then too?
- */
- if (message_validate_payloads (msg))
- {
- if (ks)
- free (ks);
- return -1;
- }
-
- /* If we have not found an exchange by now something is definitely wrong. */
- if (!msg->exchange)
- {
- log_print ("message_recv: no exchange");
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- if (ks)
- free (ks);
- return -1;
- }
-
- /*
- * Now we can validate DOI-specific exchange types. If we have no SA
- * DOI-specific exchange types are definitely wrong.
- */
- if (exch_type >= ISAKMP_EXCH_DOI_MIN && exch_type <= ISAKMP_EXCH_DOI_MAX
- && msg->exchange->doi->validate_exchange (exch_type))
- {
- log_print ("message_recv: invalid DOI exchange type %d", exch_type);
- message_drop (msg, ISAKMP_NOTIFY_INVALID_EXCHANGE_TYPE, 0, 1, 1);
- if (ks)
- free (ks);
- return -1;
- }
-
- /* Make sure the IV we used gets saved in the proper SA. */
- if (ks)
- {
- if (!msg->exchange->keystate)
- {
- msg->exchange->keystate = ks;
- msg->exchange->crypto = ks->xf;
- }
- else
- free (ks);
- }
-
- /* Handle the flags. */
- if (flags & ISAKMP_FLAGS_ENC)
- msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
- if ((msg->exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0
- && (flags & ISAKMP_FLAGS_COMMIT))
- msg->exchange->flags |= EXCHANGE_FLAG_HE_COMMITTED;
-
- /* Require encryption as soon as we have the keystate for it. */
- if ((flags & ISAKMP_FLAGS_ENC) == 0 &&
- (msg->exchange->phase == 2 || msg->exchange->keystate))
- {
- log_print ("message_recv: cleartext phase %d message",
- msg->exchange->phase);
- message_drop (msg, ISAKMP_NOTIFY_INVALID_FLAGS, 0, 1, 1);
- return -1;
- }
-
- /* OK let the exchange logic do the rest. */
- exchange_run (msg);
-
- return 0;
+ /* Handle the flags. */
+ if (flags & ISAKMP_FLAGS_ENC)
+ msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+ if ((msg->exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0
+ && (flags & ISAKMP_FLAGS_COMMIT))
+ msg->exchange->flags |= EXCHANGE_FLAG_HE_COMMITTED;
+
+ /* Require encryption as soon as we have the keystate for it. */
+ if ((flags & ISAKMP_FLAGS_ENC) == 0 &&
+ (msg->exchange->phase == 2 || msg->exchange->keystate)) {
+ log_print("message_recv: cleartext phase %d message",
+ msg->exchange->phase);
+ message_drop(msg, ISAKMP_NOTIFY_INVALID_FLAGS, 0, 1, 1);
+ return -1;
+ }
+ /* OK let the exchange logic do the rest. */
+ exchange_run(msg);
+
+ return 0;
}
void
-message_send_expire (struct message *msg)
+message_send_expire(struct message * msg)
{
- msg->retrans = 0;
+ msg->retrans = 0;
- message_send (msg);
+ message_send(msg);
}
/* Queue up message MSG for transmittal. */
void
-message_send (struct message *msg)
+message_send(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct message *m;
- struct msg_head *q;
-
- /* Remove retransmissions on this message */
- if (msg->retrans)
- {
- timer_remove_event (msg->retrans);
- msg->retrans = 0;
- }
-
- /* IKE packet capture */
- message_packet_log (msg);
-
- /*
- * If the ISAKMP SA has set up encryption, encrypt the message.
- * However, in a retransmit, it is already encrypted.
- */
- if ((msg->flags & MSG_ENCRYPTED) == 0
- && exchange->flags & EXCHANGE_FLAG_ENCRYPT)
- {
- if (!exchange->keystate)
- {
- exchange->keystate = exchange->doi->get_keystate (msg);
- exchange->crypto = exchange->keystate->xf;
- exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
- }
-
- if (message_encrypt (msg))
- {
- /* XXX Log. */
- return;
- }
- }
-
- /* Keep the COMMIT bit on. */
- if (exchange->flags & EXCHANGE_FLAG_COMMITTED)
- SET_ISAKMP_HDR_FLAGS (msg->iov[0].iov_base,
- GET_ISAKMP_HDR_FLAGS (msg->iov[0].iov_base)
- | ISAKMP_FLAGS_COMMIT);
+ struct exchange *exchange = msg->exchange;
+ struct message *m;
+ struct msg_head *q;
+
+ /* Remove retransmissions on this message */
+ if (msg->retrans) {
+ timer_remove_event(msg->retrans);
+ msg->retrans = 0;
+ }
+ /* IKE packet capture */
+ message_packet_log(msg);
+
+ /*
+ * If the ISAKMP SA has set up encryption, encrypt the message.
+ * However, in a retransmit, it is already encrypted.
+ */
+ if ((msg->flags & MSG_ENCRYPTED) == 0
+ && exchange->flags & EXCHANGE_FLAG_ENCRYPT) {
+ if (!exchange->keystate) {
+ exchange->keystate = exchange->doi->get_keystate(msg);
+ exchange->crypto = exchange->keystate->xf;
+ exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+ }
+ if (message_encrypt(msg)) {
+ /* XXX Log. */
+ return;
+ }
+ }
+ /* Keep the COMMIT bit on. */
+ if (exchange->flags & EXCHANGE_FLAG_COMMITTED)
+ SET_ISAKMP_HDR_FLAGS(msg->iov[0].iov_base,
+ GET_ISAKMP_HDR_FLAGS(msg->iov[0].iov_base)
+ | ISAKMP_FLAGS_COMMIT);
#ifdef USE_DEBUG
- message_dump_raw ("message_send", msg, LOG_MESSAGE);
+ message_dump_raw("message_send", msg, LOG_MESSAGE);
#endif
- msg->flags |= MSG_IN_TRANSIT;
- exchange->in_transit = msg;
-
- /*
- * If we get a retransmission of a message before our response
- * has left the queue, don't queue it again, as it will result
- * in a circular list.
- */
- q = msg->flags & MSG_PRIORITIZED ? &msg->transport->prio_sendq :
- &msg->transport->sendq;
-
- for (m = TAILQ_FIRST (q); m; m = TAILQ_NEXT (m, link))
- if (m == msg)
- {
- LOG_DBG ((LOG_MESSAGE, 60,
- "message_send: msg %p already on sendq %p", m, q));
- return;
- }
-
- TAILQ_INSERT_TAIL (q, msg, link);
+ msg->flags |= MSG_IN_TRANSIT;
+ exchange->in_transit = msg;
+
+ /*
+ * If we get a retransmission of a message before our response
+ * has left the queue, don't queue it again, as it will result
+ * in a circular list.
+ */
+ q = msg->flags & MSG_PRIORITIZED ? &msg->transport->prio_sendq :
+ &msg->transport->sendq;
+
+ for (m = TAILQ_FIRST(q); m; m = TAILQ_NEXT(m, link))
+ if (m == msg) {
+ LOG_DBG((LOG_MESSAGE, 60,
+ "message_send: msg %p already on sendq %p", m, q));
+ return;
+ }
+ TAILQ_INSERT_TAIL(q, msg, link);
}
/*
@@ -1482,20 +1341,20 @@ message_send (struct message *msg)
* identifying the exchange.
*/
void
-message_setup_header (struct message *msg, u_int8_t exchange, u_int8_t flags,
- u_int8_t *msg_id)
+message_setup_header(struct message * msg, u_int8_t exchange, u_int8_t flags,
+ u_int8_t * msg_id)
{
- u_int8_t *buf = msg->iov[0].iov_base;
-
- SET_ISAKMP_HDR_ICOOKIE (buf, msg->exchange->cookies);
- SET_ISAKMP_HDR_RCOOKIE (buf,
- msg->exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
- SET_ISAKMP_HDR_NEXT_PAYLOAD (buf, ISAKMP_PAYLOAD_NONE);
- SET_ISAKMP_HDR_VERSION (buf, ISAKMP_VERSION_MAKE (1, 0));
- SET_ISAKMP_HDR_EXCH_TYPE (buf, exchange);
- SET_ISAKMP_HDR_FLAGS (buf, flags);
- SET_ISAKMP_HDR_MESSAGE_ID (buf, msg_id);
- SET_ISAKMP_HDR_LENGTH (buf, msg->iov[0].iov_len);
+ u_int8_t *buf = msg->iov[0].iov_base;
+
+ SET_ISAKMP_HDR_ICOOKIE(buf, msg->exchange->cookies);
+ SET_ISAKMP_HDR_RCOOKIE(buf,
+ msg->exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
+ SET_ISAKMP_HDR_NEXT_PAYLOAD(buf, ISAKMP_PAYLOAD_NONE);
+ SET_ISAKMP_HDR_VERSION(buf, ISAKMP_VERSION_MAKE(1, 0));
+ SET_ISAKMP_HDR_EXCH_TYPE(buf, exchange);
+ SET_ISAKMP_HDR_FLAGS(buf, flags);
+ SET_ISAKMP_HDR_MESSAGE_ID(buf, msg_id);
+ SET_ISAKMP_HDR_LENGTH(buf, msg->iov[0].iov_len);
}
/*
@@ -1507,66 +1366,64 @@ message_setup_header (struct message *msg, u_int8_t exchange, u_int8_t flags,
* XXX We might want to resize the iov array several slots at a time.
*/
int
-message_add_payload (struct message *msg, u_int8_t payload, u_int8_t *buf,
- size_t sz, int link)
+message_add_payload(struct message * msg, u_int8_t payload, u_int8_t * buf,
+ size_t sz, int link)
{
- struct iovec *new_iov;
- struct payload *payload_node;
-
- payload_node = calloc (1, sizeof *payload_node);
- if (!payload_node)
- {
- log_error ("message_add_payload: calloc (1, %lu) failed",
- (unsigned long)sizeof *payload_node);
- return -1;
- }
- new_iov
- = (struct iovec *)realloc (msg->iov, (msg->iovlen + 1) * sizeof *msg->iov);
- if (!new_iov)
- {
- log_error ("message_add_payload: realloc (%p, %lu) failed", msg->iov,
- (msg->iovlen + 1) * (unsigned long)sizeof *msg->iov);
- free (payload_node);
- return -1;
- }
- msg->iov = new_iov;
- new_iov[msg->iovlen].iov_base = buf;
- new_iov[msg->iovlen].iov_len = sz;
- msg->iovlen++;
- if (link)
- *msg->nextp = payload;
- msg->nextp = buf + ISAKMP_GEN_NEXT_PAYLOAD_OFF;
- *msg->nextp = ISAKMP_PAYLOAD_NONE;
- SET_ISAKMP_GEN_RESERVED (buf, 0);
- SET_ISAKMP_GEN_LENGTH (buf, sz);
- SET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base,
- GET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base) + sz);
-
- /*
- * For the sake of exchange_validate we index the payloads even in outgoing
- * messages, however context and flags are uninteresting in this situation.
- */
- payload_node->p = buf;
- TAILQ_INSERT_TAIL (&msg->payload[payload], payload_node, link);
- return 0;
+ struct iovec *new_iov;
+ struct payload *payload_node;
+
+ payload_node = calloc(1, sizeof *payload_node);
+ if (!payload_node) {
+ log_error("message_add_payload: calloc (1, %lu) failed",
+ (unsigned long) sizeof *payload_node);
+ return -1;
+ }
+ new_iov
+ = (struct iovec *) realloc(msg->iov, (msg->iovlen + 1) * sizeof *msg->iov);
+ if (!new_iov) {
+ log_error("message_add_payload: realloc (%p, %lu) failed", msg->iov,
+ (msg->iovlen + 1) * (unsigned long) sizeof *msg->iov);
+ free(payload_node);
+ return -1;
+ }
+ msg->iov = new_iov;
+ new_iov[msg->iovlen].iov_base = buf;
+ new_iov[msg->iovlen].iov_len = sz;
+ msg->iovlen++;
+ if (link)
+ *msg->nextp = payload;
+ msg->nextp = buf + ISAKMP_GEN_NEXT_PAYLOAD_OFF;
+ *msg->nextp = ISAKMP_PAYLOAD_NONE;
+ SET_ISAKMP_GEN_RESERVED(buf, 0);
+ SET_ISAKMP_GEN_LENGTH(buf, sz);
+ SET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base,
+ GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base) + sz);
+
+ /*
+ * For the sake of exchange_validate we index the payloads even in outgoing
+ * messages, however context and flags are uninteresting in this situation.
+ */
+ payload_node->p = buf;
+ TAILQ_INSERT_TAIL(&msg->payload[payload], payload_node, link);
+ return 0;
}
/* XXX Move up when ready. */
struct info_args {
- char discr;
- u_int32_t doi;
- u_int8_t proto;
- u_int16_t spi_sz;
- union {
- struct {
- u_int16_t msg_type;
- u_int8_t *spi;
- } n;
- struct {
- u_int16_t nspis;
- u_int8_t *spis;
- } d;
- } u;
+ char discr;
+ u_int32_t doi;
+ u_int8_t proto;
+ u_int16_t spi_sz;
+ union {
+ struct {
+ u_int16_t msg_type;
+ u_int8_t *spi;
+ } n;
+ struct {
+ u_int16_t nspis;
+ u_int8_t *spis;
+ } d;
+ } u;
};
/*
@@ -1581,127 +1438,117 @@ struct info_args {
* status value?
*/
void
-message_send_notification (struct message *msg, struct sa *isakmp_sa,
- u_int16_t notify, struct proto *proto,
- int incoming)
+message_send_notification(struct message * msg, struct sa * isakmp_sa,
+ u_int16_t notify, struct proto * proto,
+ int incoming)
{
- struct info_args args;
- struct sa *doi_sa = proto ? proto->sa : isakmp_sa;
-
- args.discr = 'N';
- args.doi = doi_sa ? doi_sa->doi->id : ISAKMP_DOI_ISAKMP;
- args.proto = proto ? proto->proto : ISAKMP_PROTO_ISAKMP;
- args.spi_sz = proto ? proto->spi_sz[incoming] : 0;
- args.u.n.msg_type = notify;
- args.u.n.spi = proto ? proto->spi[incoming] : 0;
- if (isakmp_sa && (isakmp_sa->flags & SA_FLAG_READY))
- exchange_establish_p2 (isakmp_sa, ISAKMP_EXCH_INFO, 0, &args, 0 ,0);
- else
- exchange_establish_p1 (msg->transport, ISAKMP_EXCH_INFO,
- msg->exchange
- ? msg->exchange->doi->id : ISAKMP_DOI_ISAKMP,
- 0, &args, 0, 0);
+ struct info_args args;
+ struct sa *doi_sa = proto ? proto->sa : isakmp_sa;
+
+ args.discr = 'N';
+ args.doi = doi_sa ? doi_sa->doi->id : ISAKMP_DOI_ISAKMP;
+ args.proto = proto ? proto->proto : ISAKMP_PROTO_ISAKMP;
+ args.spi_sz = proto ? proto->spi_sz[incoming] : 0;
+ args.u.n.msg_type = notify;
+ args.u.n.spi = proto ? proto->spi[incoming] : 0;
+ if (isakmp_sa && (isakmp_sa->flags & SA_FLAG_READY))
+ exchange_establish_p2(isakmp_sa, ISAKMP_EXCH_INFO, 0, &args, 0, 0);
+ else
+ exchange_establish_p1(msg->transport, ISAKMP_EXCH_INFO,
+ msg->exchange
+ ? msg->exchange->doi->id : ISAKMP_DOI_ISAKMP,
+ 0, &args, 0, 0);
}
/* Send a DELETE inside an informational exchange for each protocol in SA. */
void
-message_send_delete (struct sa *sa)
+message_send_delete(struct sa * sa)
{
- struct info_args args;
- struct proto *proto;
- struct sa *isakmp_sa;
- struct sockaddr *dst;
-
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- isakmp_sa = sa_isakmp_lookup_by_peer (dst, sysdep_sa_len (dst));
- if (!isakmp_sa)
- {
- /*
- * XXX We ought to setup an ISAKMP SA with our peer here and send
- * the DELETE over that one.
- */
- return;
- }
-
- args.discr = 'D';
- args.doi = sa->doi->id;
- args.u.d.nspis = 1;
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- args.proto = proto->proto;
- args.spi_sz = proto->spi_sz[1];
- args.u.d.spis = proto->spi[1];
- exchange_establish_p2 (isakmp_sa, ISAKMP_EXCH_INFO, 0, &args, 0 ,0);
- }
+ struct info_args args;
+ struct proto *proto;
+ struct sa *isakmp_sa;
+ struct sockaddr *dst;
+
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ isakmp_sa = sa_isakmp_lookup_by_peer(dst, sysdep_sa_len(dst));
+ if (!isakmp_sa) {
+ /*
+ * XXX We ought to setup an ISAKMP SA with our peer here and send
+ * the DELETE over that one.
+ */
+ return;
+ }
+ args.discr = 'D';
+ args.doi = sa->doi->id;
+ args.u.d.nspis = 1;
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ args.proto = proto->proto;
+ args.spi_sz = proto->spi_sz[1];
+ args.u.d.spis = proto->spi[1];
+ exchange_establish_p2(isakmp_sa, ISAKMP_EXCH_INFO, 0, &args, 0, 0);
+ }
}
/* Build the informational message into MSG. */
int
-message_send_info (struct message *msg)
+message_send_info(struct message * msg)
{
- u_int8_t *buf;
- size_t sz;
- struct info_args *args = msg->extra;
- u_int8_t payload;
-
- /* Let the DOI get the first hand on the message. */
- if (msg->exchange->doi->informational_pre_hook)
- if (msg->exchange->doi->informational_pre_hook (msg))
- return -1;
-
- sz = (args->discr == 'N' ? ISAKMP_NOTIFY_SPI_OFF + args->spi_sz
- : ISAKMP_DELETE_SPI_OFF + args->u.d.nspis * args->spi_sz);
- buf = calloc (1, sz);
- if (!buf)
- {
- log_error ("message_send_info: calloc (1, %lu) failed", (unsigned long)sz);
- message_free (msg);
- return -1;
- }
-
- switch (args->discr)
- {
- case 'N':
- /* Build the NOTIFY payload. */
- payload = ISAKMP_PAYLOAD_NOTIFY;
- SET_ISAKMP_NOTIFY_DOI (buf, args->doi);
- SET_ISAKMP_NOTIFY_PROTO (buf, args->proto);
- SET_ISAKMP_NOTIFY_SPI_SZ (buf, args->spi_sz);
- SET_ISAKMP_NOTIFY_MSG_TYPE (buf, args->u.n.msg_type);
- memcpy (buf + ISAKMP_NOTIFY_SPI_OFF, args->u.n.spi, args->spi_sz);
- break;
-
- case 'D':
- default: /* Silence GCC. */
- /* Build the DELETE payload. */
- payload = ISAKMP_PAYLOAD_DELETE;
- SET_ISAKMP_DELETE_DOI (buf, args->doi);
- SET_ISAKMP_DELETE_PROTO (buf, args->proto);
- SET_ISAKMP_DELETE_SPI_SZ (buf, args->spi_sz);
- SET_ISAKMP_DELETE_NSPIS (buf, args->u.d.nspis);
- memcpy (buf + ISAKMP_DELETE_SPI_OFF, args->u.d.spis,
- args->u.d.nspis * args->spi_sz);
- msg->flags |= MSG_PRIORITIZED;
- break;
- }
-
- if (message_add_payload (msg, payload, buf, sz, 1))
- {
- free (buf);
- message_free (msg);
- return -1;
- }
-
- /* Let the DOI get the last hand on the message. */
- if (msg->exchange->doi->informational_post_hook)
- if (msg->exchange->doi->informational_post_hook (msg))
- {
- message_free (msg);
- return -1;
- }
+ u_int8_t *buf;
+ size_t sz;
+ struct info_args *args = msg->extra;
+ u_int8_t payload;
+
+ /* Let the DOI get the first hand on the message. */
+ if (msg->exchange->doi->informational_pre_hook)
+ if (msg->exchange->doi->informational_pre_hook(msg))
+ return -1;
+
+ sz = (args->discr == 'N' ? ISAKMP_NOTIFY_SPI_OFF + args->spi_sz
+ : ISAKMP_DELETE_SPI_OFF + args->u.d.nspis * args->spi_sz);
+ buf = calloc(1, sz);
+ if (!buf) {
+ log_error("message_send_info: calloc (1, %lu) failed", (unsigned long) sz);
+ message_free(msg);
+ return -1;
+ }
+ switch (args->discr) {
+ case 'N':
+ /* Build the NOTIFY payload. */
+ payload = ISAKMP_PAYLOAD_NOTIFY;
+ SET_ISAKMP_NOTIFY_DOI(buf, args->doi);
+ SET_ISAKMP_NOTIFY_PROTO(buf, args->proto);
+ SET_ISAKMP_NOTIFY_SPI_SZ(buf, args->spi_sz);
+ SET_ISAKMP_NOTIFY_MSG_TYPE(buf, args->u.n.msg_type);
+ memcpy(buf + ISAKMP_NOTIFY_SPI_OFF, args->u.n.spi, args->spi_sz);
+ break;
+
+ case 'D':
+ default: /* Silence GCC. */
+ /* Build the DELETE payload. */
+ payload = ISAKMP_PAYLOAD_DELETE;
+ SET_ISAKMP_DELETE_DOI(buf, args->doi);
+ SET_ISAKMP_DELETE_PROTO(buf, args->proto);
+ SET_ISAKMP_DELETE_SPI_SZ(buf, args->spi_sz);
+ SET_ISAKMP_DELETE_NSPIS(buf, args->u.d.nspis);
+ memcpy(buf + ISAKMP_DELETE_SPI_OFF, args->u.d.spis,
+ args->u.d.nspis * args->spi_sz);
+ msg->flags |= MSG_PRIORITIZED;
+ break;
+ }
- return 0;
+ if (message_add_payload(msg, payload, buf, sz, 1)) {
+ free(buf);
+ message_free(msg);
+ return -1;
+ }
+ /* Let the DOI get the last hand on the message. */
+ if (msg->exchange->doi->informational_post_hook)
+ if (msg->exchange->doi->informational_post_hook(msg)) {
+ message_free(msg);
+ return -1;
+ }
+ return 0;
}
/*
@@ -1711,45 +1558,42 @@ message_send_info (struct message *msg)
* set, free the message when ready with it.
*/
void
-message_drop (struct message *msg, int notify, struct proto *proto,
- int incoming, int clean)
+message_drop(struct message * msg, int notify, struct proto * proto,
+ int incoming, int clean)
{
- struct transport *t = msg->transport;
- struct sockaddr *dst;
- char *address;
- short port = 0;
-
- t->vtbl->get_dst (t, &dst);
- if (sockaddr2text (dst, &address, 0))
- {
- log_error ("message_drop: sockaddr2text () failed");
- address = 0;
- }
-
- switch (dst->sa_family)
- {
- case AF_INET:
- port = ((struct sockaddr_in *)dst)->sin_port;
- break;
- case AF_INET6:
- port = ((struct sockaddr_in6 *)dst)->sin6_port;
- break;
- default:
- log_print ("message_drop: unknown protocol family %d", dst->sa_family);
- }
-
- log_print ("dropped message from %s port %d due to notification type %s",
- address ? address : "<unknown>", htons (port),
- constant_name (isakmp_notify_cst, notify));
-
- if (address)
- free (address);
-
- /* If specified, return a notification. */
- if (notify)
- message_send_notification (msg, msg->isakmp_sa, notify, proto, incoming);
- if (clean)
- message_free (msg);
+ struct transport *t = msg->transport;
+ struct sockaddr *dst;
+ char *address;
+ short port = 0;
+
+ t->vtbl->get_dst(t, &dst);
+ if (sockaddr2text(dst, &address, 0)) {
+ log_error("message_drop: sockaddr2text () failed");
+ address = 0;
+ }
+ switch (dst->sa_family) {
+ case AF_INET:
+ port = ((struct sockaddr_in *) dst)->sin_port;
+ break;
+ case AF_INET6:
+ port = ((struct sockaddr_in6 *) dst)->sin6_port;
+ break;
+ default:
+ log_print("message_drop: unknown protocol family %d", dst->sa_family);
+ }
+
+ log_print("dropped message from %s port %d due to notification type %s",
+ address ? address : "<unknown>", htons(port),
+ constant_name(isakmp_notify_cst, notify));
+
+ if (address)
+ free(address);
+
+ /* If specified, return a notification. */
+ if (notify)
+ message_send_notification(msg, msg->isakmp_sa, notify, proto, incoming);
+ if (clean)
+ message_free(msg);
}
/*
@@ -1757,57 +1601,51 @@ message_drop (struct message *msg, int notify, struct proto *proto,
* as we can without resorting to per-payload handling.
*/
void
-message_dump_raw (char *header, struct message *msg, int class)
+message_dump_raw(char *header, struct message * msg, int class)
{
- u_int32_t i, j, k = 0;
- char buf[80], *p = buf;
-
- LOG_DBG ((class, 70, "%s: message %p", header, msg));
- field_dump_payload (isakmp_hdr_fld, msg->iov[0].iov_base);
- for (i = 0; i < msg->iovlen; i++)
- for (j = 0; j < msg->iov[i].iov_len; j++)
- {
- snprintf (p, sizeof buf - (int)(p - buf), "%02x",
- ((u_int8_t *)msg->iov[i].iov_base)[j]);
- p += 2;
- if (++k % 32 == 0)
- {
- *p = '\0';
- LOG_DBG ((class, 70, "%s: %s", header, buf));
- p = buf;
- }
- else if (k % 4 == 0)
- *p++ = ' ';
- }
- *p = '\0';
- if (p != buf)
- LOG_DBG ((class, 70, "%s: %s", header, buf));
+ u_int32_t i, j, k = 0;
+ char buf[80], *p = buf;
+
+ LOG_DBG((class, 70, "%s: message %p", header, msg));
+ field_dump_payload(isakmp_hdr_fld, msg->iov[0].iov_base);
+ for (i = 0; i < msg->iovlen; i++)
+ for (j = 0; j < msg->iov[i].iov_len; j++) {
+ snprintf(p, sizeof buf - (int) (p - buf), "%02x",
+ ((u_int8_t *) msg->iov[i].iov_base)[j]);
+ p += 2;
+ if (++k % 32 == 0) {
+ *p = '\0';
+ LOG_DBG((class, 70, "%s: %s", header, buf));
+ p = buf;
+ } else if (k % 4 == 0)
+ *p++ = ' ';
+ }
+ *p = '\0';
+ if (p != buf)
+ LOG_DBG((class, 70, "%s: %s", header, buf));
}
static void
-message_packet_log (struct message *msg)
+message_packet_log(struct message * msg)
{
#ifdef USE_DEBUG
- struct sockaddr *src, *dst;
-
- /* Don't log retransmissions. Redundant for incoming packets... */
- if (msg->xmits > 0)
- return;
-
- /* Figure out direction. */
- if (msg->exchange && msg->exchange->initiator ^ (msg->exchange->step % 2))
- {
- msg->transport->vtbl->get_src (msg->transport, &src);
- msg->transport->vtbl->get_dst (msg->transport, &dst);
- }
- else
- {
- msg->transport->vtbl->get_src (msg->transport, &dst);
- msg->transport->vtbl->get_dst (msg->transport, &src);
- }
-
- log_packet_iov (src, dst, msg->iov, msg->iovlen);
-#endif /* USE_DEBUG */
+ struct sockaddr *src, *dst;
+
+ /* Don't log retransmissions. Redundant for incoming packets... */
+ if (msg->xmits > 0)
+ return;
+
+ /* Figure out direction. */
+ if (msg->exchange && msg->exchange->initiator ^ (msg->exchange->step % 2)) {
+ msg->transport->vtbl->get_src(msg->transport, &src);
+ msg->transport->vtbl->get_dst(msg->transport, &dst);
+ } else {
+ msg->transport->vtbl->get_src(msg->transport, &dst);
+ msg->transport->vtbl->get_dst(msg->transport, &src);
+ }
+
+ log_packet_iov(src, dst, msg->iov, msg->iovlen);
+#endif /* USE_DEBUG */
}
/*
@@ -1817,56 +1655,54 @@ message_packet_log (struct message *msg)
* we encrypt.
*/
static int
-message_encrypt (struct message *msg)
+message_encrypt(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- size_t i, sz = 0;
- u_int8_t *buf;
-
- /* If no payloads, nothing to do. */
- if (msg->iovlen == 1)
- return 0;
-
- /*
- * For encryption we need to put all payloads together in a single buffer.
- * This buffer should be padded to the current crypto transform's blocksize.
- */
- for (i = 1; i < msg->iovlen; i++)
- sz += msg->iov[i].iov_len;
- sz = ((sz + exchange->crypto->blocksize - 1) / exchange->crypto->blocksize)
- * exchange->crypto->blocksize;
- buf = realloc (msg->iov[1].iov_base, sz);
- if (!buf)
- {
- log_error ("message_encrypt: realloc (%p, %lu) failed",
- msg->iov[1].iov_base, (unsigned long)sz);
- return -1;
- }
- msg->iov[1].iov_base = buf;
- for (i = 2; i < msg->iovlen; i++)
- {
- memcpy (buf + msg->iov[1].iov_len, msg->iov[i].iov_base,
- msg->iov[i].iov_len);
- msg->iov[1].iov_len += msg->iov[i].iov_len;
- free (msg->iov[i].iov_base);
- }
-
- /* Pad with zeroes. */
- memset (buf + msg->iov[1].iov_len, '\0', sz - msg->iov[1].iov_len);
- msg->iov[1].iov_len = sz;
- msg->iovlen = 2;
-
- SET_ISAKMP_HDR_FLAGS (msg->iov[0].iov_base,
- GET_ISAKMP_HDR_FLAGS (msg->iov[0].iov_base)
- | ISAKMP_FLAGS_ENC);
- SET_ISAKMP_HDR_LENGTH (msg->iov[0].iov_base, ISAKMP_HDR_SZ + sz);
- crypto_encrypt (exchange->keystate, buf, msg->iov[1].iov_len);
- msg->flags |= MSG_ENCRYPTED;
-
- /* Update the IV so we can decrypt the next incoming message. */
- crypto_update_iv (exchange->keystate);
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ size_t i, sz = 0;
+ u_int8_t *buf;
+
+ /* If no payloads, nothing to do. */
+ if (msg->iovlen == 1)
+ return 0;
+
+ /*
+ * For encryption we need to put all payloads together in a single buffer.
+ * This buffer should be padded to the current crypto transform's blocksize.
+ */
+ for (i = 1; i < msg->iovlen; i++)
+ sz += msg->iov[i].iov_len;
+ sz = ((sz + exchange->crypto->blocksize - 1) / exchange->crypto->blocksize)
+ * exchange->crypto->blocksize;
+ buf = realloc(msg->iov[1].iov_base, sz);
+ if (!buf) {
+ log_error("message_encrypt: realloc (%p, %lu) failed",
+ msg->iov[1].iov_base, (unsigned long) sz);
+ return -1;
+ }
+ msg->iov[1].iov_base = buf;
+ for (i = 2; i < msg->iovlen; i++) {
+ memcpy(buf + msg->iov[1].iov_len, msg->iov[i].iov_base,
+ msg->iov[i].iov_len);
+ msg->iov[1].iov_len += msg->iov[i].iov_len;
+ free(msg->iov[i].iov_base);
+ }
+
+ /* Pad with zeroes. */
+ memset(buf + msg->iov[1].iov_len, '\0', sz - msg->iov[1].iov_len);
+ msg->iov[1].iov_len = sz;
+ msg->iovlen = 2;
+
+ SET_ISAKMP_HDR_FLAGS(msg->iov[0].iov_base,
+ GET_ISAKMP_HDR_FLAGS(msg->iov[0].iov_base)
+ | ISAKMP_FLAGS_ENC);
+ SET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base, ISAKMP_HDR_SZ + sz);
+ crypto_encrypt(exchange->keystate, buf, msg->iov[1].iov_len);
+ msg->flags |= MSG_ENCRYPTED;
+
+ /* Update the IV so we can decrypt the next incoming message. */
+ crypto_update_iv(exchange->keystate);
+
+ return 0;
}
/*
@@ -1874,77 +1710,70 @@ message_encrypt (struct message *msg)
* this specific SA.
*/
static int
-message_check_duplicate (struct message *msg)
+message_check_duplicate(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- size_t sz = msg->iov[0].iov_len;
- u_int8_t *pkt = msg->iov[0].iov_base;
-
- /* If no SA has been found, we cannot test, thus it's good. */
- if (!exchange)
- return 0;
-
- LOG_DBG ((LOG_MESSAGE, 90, "message_check_duplicate: last_received %p",
- exchange->last_received));
- if (exchange->last_received)
- {
- LOG_DBG_BUF ((LOG_MESSAGE, 95,
- "message_check_duplicate: last_received",
- exchange->last_received->orig,
- exchange->last_received->orig_sz));
- /* Is it a duplicate, lose the new one. */
- if (sz == exchange->last_received->orig_sz
- && memcmp (pkt, exchange->last_received->orig, sz) == 0)
- {
- LOG_DBG ((LOG_MESSAGE, 80,
- "message_check_duplicate: dropping dup"));
-
- /*
- * Retransmit if the previos sent message was the last of an
- * exchange, otherwise just wait for the ordinary retransmission.
- */
- if (exchange->last_sent && (exchange->last_sent->flags & MSG_LAST))
- message_send (exchange->last_sent);
- message_free (msg);
- return -1;
- }
- }
-
- /*
- * As this new message is an indication that state is moving forward
- * at the peer, remove the retransmit timer on our last message.
- */
- if (exchange->last_sent)
- {
- if (exchange->last_sent == exchange->in_transit)
- {
- if (exchange->in_transit->flags & MSG_PRIORITIZED)
- TAILQ_REMOVE (&exchange->in_transit->transport->prio_sendq,
- exchange->in_transit, link);
- else
- TAILQ_REMOVE (&exchange->in_transit->transport->sendq,
- exchange->in_transit, link);
- exchange->in_transit = 0;
- }
- message_free (exchange->last_sent);
- exchange->last_sent = 0;
- }
-
- return 0;
+ struct exchange *exchange = msg->exchange;
+ size_t sz = msg->iov[0].iov_len;
+ u_int8_t *pkt = msg->iov[0].iov_base;
+
+ /* If no SA has been found, we cannot test, thus it's good. */
+ if (!exchange)
+ return 0;
+
+ LOG_DBG((LOG_MESSAGE, 90, "message_check_duplicate: last_received %p",
+ exchange->last_received));
+ if (exchange->last_received) {
+ LOG_DBG_BUF((LOG_MESSAGE, 95,
+ "message_check_duplicate: last_received",
+ exchange->last_received->orig,
+ exchange->last_received->orig_sz));
+ /* Is it a duplicate, lose the new one. */
+ if (sz == exchange->last_received->orig_sz
+ && memcmp(pkt, exchange->last_received->orig, sz) == 0) {
+ LOG_DBG((LOG_MESSAGE, 80,
+ "message_check_duplicate: dropping dup"));
+
+ /*
+ * Retransmit if the previos sent message was the last of an
+ * exchange, otherwise just wait for the ordinary retransmission.
+ */
+ if (exchange->last_sent && (exchange->last_sent->flags & MSG_LAST))
+ message_send(exchange->last_sent);
+ message_free(msg);
+ return -1;
+ }
+ }
+ /*
+ * As this new message is an indication that state is moving forward
+ * at the peer, remove the retransmit timer on our last message.
+ */
+ if (exchange->last_sent) {
+ if (exchange->last_sent == exchange->in_transit) {
+ if (exchange->in_transit->flags & MSG_PRIORITIZED)
+ TAILQ_REMOVE(&exchange->in_transit->transport->prio_sendq,
+ exchange->in_transit, link);
+ else
+ TAILQ_REMOVE(&exchange->in_transit->transport->sendq,
+ exchange->in_transit, link);
+ exchange->in_transit = 0;
+ }
+ message_free(exchange->last_sent);
+ exchange->last_sent = 0;
+ }
+ return 0;
}
/* Helper to message_negotiate_sa. */
static INLINE struct payload *
-step_transform (struct payload *tp, struct payload **propp,
- struct payload **sap)
+step_transform(struct payload * tp, struct payload ** propp,
+ struct payload ** sap)
{
- tp = TAILQ_NEXT (tp, link);
- if (tp)
- {
- *propp = tp->context;
- *sap = (*propp)->context;
- }
- return tp;
+ tp = TAILQ_NEXT(tp, link);
+ if (tp) {
+ *propp = tp->context;
+ *sap = (*propp)->context;
+ }
+ return tp;
}
/*
@@ -1952,172 +1781,173 @@ step_transform (struct payload *tp, struct payload **propp,
* SA payload) we accept as a full protection suite.
*/
int
-message_negotiate_sa (struct message *msg,
- int (*validate) (struct exchange *, struct sa *,
- struct sa *))
+message_negotiate_sa(struct message * msg,
+ int (*validate) (struct exchange *, struct sa *,
+ struct sa *))
{
- struct payload *tp, *propp, *sap, *next_tp = 0, *next_propp, *next_sap;
- struct payload *saved_tp = 0, *saved_propp = 0, *saved_sap = 0;
- struct sa *sa;
- struct proto *proto;
- int suite_ok_so_far = 0;
- struct exchange *exchange = msg->exchange;
-
- /*
- * This algorithm is a weird bottom-up thing... mostly due to the
- * payload links pointing upwards.
- *
- * The algorithm goes something like this:
- * Foreach transform
- * If transform is compatible
- * Remember that this protocol can work
- * Skip to last transform of this protocol
- * If next transform belongs to a new protocol inside the same suite
- * If no transform was found for the current protocol
- * Forget all earlier transforms for protocols in this suite
- * Skip to last transform of this suite
- * If next transform belongs to a new suite
- * If the current protocol had an OK transform
- * Skip to the last transform of this SA
- * If the next transform belongs to a new SA
- * If no transforms have been chosen
- * Issue a NO_PROPOSAL_CHOSEN notification
- */
-
- sa = TAILQ_FIRST (&exchange->sa_list);
- for (tp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); tp;
- tp = next_tp)
- {
- propp = tp->context;
- sap = propp->context;
- sap->flags |= PL_MARK;
- next_tp = step_transform (tp, &next_propp, &next_sap);
-
- /* For each transform, see if it is compatible. */
- if (!attribute_map (tp->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (tp->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- exchange->doi->is_attribute_incompatible, msg))
- {
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "message_negotiate_sa: "
- "transform %d proto %d proposal %d ok",
- GET_ISAKMP_TRANSFORM_NO (tp->p),
- GET_ISAKMP_PROP_PROTO (propp->p),
- GET_ISAKMP_PROP_NO (propp->p)));
- if (sa_add_transform (sa, tp, exchange->initiator, &proto))
- goto cleanup;
- suite_ok_so_far = 1;
-
- saved_tp = next_tp;
- saved_propp = next_propp;
- saved_sap = next_sap;
- /* Skip to last transform of this protocol proposal. */
- while ((next_tp = step_transform (tp, &next_propp, &next_sap))
- && next_propp == propp)
- tp = next_tp;
- }
-
- retry_transform:
- /*
- * Figure out if we will be looking at a new protocol proposal
- * inside the current protection suite.
- */
- if (next_tp && propp != next_propp && sap == next_sap
- && (GET_ISAKMP_PROP_NO (propp->p)
- == GET_ISAKMP_PROP_NO (next_propp->p)))
- {
- if (!suite_ok_so_far)
- {
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "message_negotiate_sa: proto %d proposal %d failed",
- GET_ISAKMP_PROP_PROTO (propp->p),
- GET_ISAKMP_PROP_NO (propp->p)));
- /* Remove potentially succeeded choices from the SA. */
- while (TAILQ_FIRST (&sa->protos))
- TAILQ_REMOVE (&sa->protos, TAILQ_FIRST (&sa->protos), link);
-
- /* Skip to the last transform of this protection suite. */
- while ((next_tp = step_transform (tp, &next_propp, &next_sap))
- && (GET_ISAKMP_PROP_NO (next_propp->p)
- == GET_ISAKMP_PROP_NO (propp->p))
- && next_sap == sap)
- tp = next_tp;
- }
- suite_ok_so_far = 0;
- }
-
- /* Figure out if we will be looking at a new protection suite. */
- if (!next_tp
- || (propp != next_propp
- && (GET_ISAKMP_PROP_NO (propp->p)
- != GET_ISAKMP_PROP_NO (next_propp->p)))
- || sap != next_sap)
- {
- /*
- * Check if the suite we just considered was OK, if so we check
- * it against the accepted ones.
- */
- if (suite_ok_so_far)
- {
- if (!validate || validate (exchange, sa, msg->isakmp_sa))
- {
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "message_negotiate_sa: proposal %d succeeded",
- GET_ISAKMP_PROP_NO (propp->p)));
-
- /* Skip to the last transform of this SA. */
- while ((next_tp
- = step_transform (tp, &next_propp, &next_sap))
- && next_sap == sap)
- tp = next_tp;
+ struct payload *tp, *propp, *sap, *next_tp = 0, *next_propp, *next_sap;
+ struct payload *saved_tp = 0, *saved_propp = 0, *saved_sap = 0;
+ struct sa *sa;
+ struct proto *proto;
+ int suite_ok_so_far = 0;
+ struct exchange *exchange = msg->exchange;
+
+ /*
+ * This algorithm is a weird bottom-up thing... mostly due to the
+ * payload links pointing upwards.
+ *
+ * The algorithm goes something like this:
+ * Foreach transform
+ * If transform is compatible
+ * Remember that this protocol can work
+ * Skip to last transform of this protocol
+ * If next transform belongs to a new protocol inside the same suite
+ * If no transform was found for the current protocol
+ * Forget all earlier transforms for protocols in this suite
+ * Skip to last transform of this suite
+ * If next transform belongs to a new suite
+ * If the current protocol had an OK transform
+ * Skip to the last transform of this SA
+ * If the next transform belongs to a new SA
+ * If no transforms have been chosen
+ * Issue a NO_PROPOSAL_CHOSEN notification
+ */
+
+ sa = TAILQ_FIRST(&exchange->sa_list);
+ for (tp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); tp;
+ tp = next_tp) {
+ propp = tp->context;
+ sap = propp->context;
+ sap->flags |= PL_MARK;
+ next_tp = step_transform(tp, &next_propp, &next_sap);
+
+ /* For each transform, see if it is compatible. */
+ if (!attribute_map(tp->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(tp->p)
+ - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ exchange->doi->is_attribute_incompatible, msg)) {
+ LOG_DBG((LOG_NEGOTIATION, 30,
+ "message_negotiate_sa: "
+ "transform %d proto %d proposal %d ok",
+ GET_ISAKMP_TRANSFORM_NO(tp->p),
+ GET_ISAKMP_PROP_PROTO(propp->p),
+ GET_ISAKMP_PROP_NO(propp->p)));
+ if (sa_add_transform(sa, tp, exchange->initiator, &proto))
+ goto cleanup;
+ suite_ok_so_far = 1;
+
+ saved_tp = next_tp;
+ saved_propp = next_propp;
+ saved_sap = next_sap;
+ /* Skip to last transform of this protocol proposal. */
+ while ((next_tp = step_transform(tp, &next_propp, &next_sap))
+ && next_propp == propp)
+ tp = next_tp;
+ }
+retry_transform:
+ /*
+ * Figure out if we will be looking at a new protocol proposal
+ * inside the current protection suite.
+ */
+ if (next_tp && propp != next_propp && sap == next_sap
+ && (GET_ISAKMP_PROP_NO(propp->p)
+ == GET_ISAKMP_PROP_NO(next_propp->p))) {
+ if (!suite_ok_so_far) {
+ LOG_DBG((LOG_NEGOTIATION, 30,
+ "message_negotiate_sa: proto %d proposal %d failed",
+ GET_ISAKMP_PROP_PROTO(propp->p),
+ GET_ISAKMP_PROP_NO(propp->p)));
+ /*
+ * Remove potentially succeeded choices from
+ * the SA.
+ */
+ while (TAILQ_FIRST(&sa->protos))
+ TAILQ_REMOVE(&sa->protos, TAILQ_FIRST(&sa->protos), link);
+
+ /*
+ * Skip to the last transform of this
+ * protection suite.
+ */
+ while ((next_tp = step_transform(tp, &next_propp, &next_sap))
+ && (GET_ISAKMP_PROP_NO(next_propp->p)
+ == GET_ISAKMP_PROP_NO(propp->p))
+ && next_sap == sap)
+ tp = next_tp;
+ }
+ suite_ok_so_far = 0;
+ }
+ /*
+ * Figure out if we will be looking at a new protection
+ * suite.
+ */
+ if (!next_tp
+ || (propp != next_propp
+ && (GET_ISAKMP_PROP_NO(propp->p)
+ != GET_ISAKMP_PROP_NO(next_propp->p)))
+ || sap != next_sap) {
+ /*
+ * Check if the suite we just considered was OK, if so we check
+ * it against the accepted ones.
+ */
+ if (suite_ok_so_far) {
+ if (!validate || validate(exchange, sa, msg->isakmp_sa)) {
+ LOG_DBG((LOG_NEGOTIATION, 30,
+ "message_negotiate_sa: proposal %d succeeded",
+ GET_ISAKMP_PROP_NO(propp->p)));
+
+ /*
+ * Skip to the last transform of this
+ * SA.
+ */
+ while ((next_tp
+ = step_transform(tp, &next_propp, &next_sap))
+ && next_sap == sap)
+ tp = next_tp;
+ } else {
+ /* Backtrack. */
+ LOG_DBG((LOG_NEGOTIATION, 30,
+ "message_negotiate_sa: proposal %d failed",
+ GET_ISAKMP_PROP_NO(propp->p)));
+ next_tp = saved_tp;
+ next_propp = saved_propp;
+ next_sap = saved_sap;
+ suite_ok_so_far = 0;
+
+ /*
+ * Remove potentially succeeded
+ * choices from the SA.
+ */
+ while (TAILQ_FIRST(&sa->protos))
+ TAILQ_REMOVE(&sa->protos, TAILQ_FIRST(&sa->protos),
+ link);
+ goto retry_transform;
+ }
+ }
}
- else
- {
- /* Backtrack. */
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "message_negotiate_sa: proposal %d failed",
- GET_ISAKMP_PROP_NO (propp->p)));
- next_tp = saved_tp;
- next_propp = saved_propp;
- next_sap = saved_sap;
- suite_ok_so_far = 0;
-
- /* Remove potentially succeeded choices from the SA. */
- while (TAILQ_FIRST (&sa->protos))
- TAILQ_REMOVE (&sa->protos, TAILQ_FIRST (&sa->protos),
- link);
- goto retry_transform;
+ /* Have we walked all the proposals of an SA? */
+ if (!next_tp || sap != next_sap) {
+ if (!suite_ok_so_far) {
+ /*
+ * XXX We cannot possibly call this a drop... seeing we just turn
+ * down one of the offers, can we? I suggest renaming
+ * message_drop to something else.
+ */
+ log_print("message_negotiate_sa: no compatible proposal found");
+ message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
+ }
+ sa = TAILQ_NEXT(sa, next);
}
- }
- }
-
- /* Have we walked all the proposals of an SA? */
- if (!next_tp || sap != next_sap)
- {
- if (!suite_ok_so_far)
- {
- /*
- * XXX We cannot possibly call this a drop... seeing we just turn
- * down one of the offers, can we? I suggest renaming
- * message_drop to something else.
- */
- log_print ("message_negotiate_sa: no compatible proposal found");
- message_drop (msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0);
- }
- sa = TAILQ_NEXT (sa, next);
- }
- }
- return 0;
-
- cleanup:
- /*
- * Remove potentially succeeded choices from the SA.
- * XXX Do we leak struct protos and related data here?
- */
- while (TAILQ_FIRST (&sa->protos))
- TAILQ_REMOVE (&sa->protos, TAILQ_FIRST (&sa->protos), link);
- return -1;
+ }
+ return 0;
+
+cleanup:
+ /*
+ * Remove potentially succeeded choices from the SA.
+ * XXX Do we leak struct protos and related data here?
+ */
+ while (TAILQ_FIRST(&sa->protos))
+ TAILQ_REMOVE(&sa->protos, TAILQ_FIRST(&sa->protos), link);
+ return -1;
}
/*
@@ -2125,248 +1955,228 @@ message_negotiate_sa (struct message *msg,
* found in the exchange MSG is part of..
*/
int
-message_add_sa_payload (struct message *msg)
+message_add_sa_payload(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- u_int8_t *sa_buf, *saved_nextp_sa, *saved_nextp_prop;
- size_t sa_len, extra_sa_len;
- int i, nprotos = 0;
- struct proto *proto;
- u_int8_t **transforms = 0, **proposals = 0;
- size_t *transform_lens = 0, *proposal_lens = 0;
- struct sa *sa;
- struct doi *doi = exchange->doi;
- u_int8_t *spi = 0;
- size_t spi_sz;
-
- /*
- * Generate SA payloads.
- */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa;
- sa = TAILQ_NEXT (sa, next))
- {
- /* Setup a SA payload. */
- sa_len = ISAKMP_SA_SIT_OFF + doi->situation_size ();
- extra_sa_len = 0;
- sa_buf = malloc (sa_len);
- if (!sa_buf)
- {
- log_error ("message_add_sa_payload: malloc (%lu) failed",
- (unsigned long)sa_len);
- goto cleanup;
- }
-
- SET_ISAKMP_SA_DOI (sa_buf, doi->id);
- doi->setup_situation (sa_buf);
-
- /* Count transforms. */
- nprotos = 0;
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- nprotos++;
-
- /* Allocate transient transform and proposal payload/size vectors. */
- transforms = calloc (nprotos, sizeof *transforms);
- if (!transforms)
- {
- log_error ("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
- (unsigned long)sizeof *transforms);
- goto cleanup;
- }
-
- transform_lens = calloc (nprotos, sizeof *transform_lens);
- if (!transform_lens)
- {
- log_error ("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
- (unsigned long)sizeof *transform_lens);
- goto cleanup;
- }
-
- proposals = calloc (nprotos, sizeof *proposals);
- if (!proposals)
- {
- log_error ("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
- (unsigned long)sizeof *proposals);
- goto cleanup;
- }
-
- proposal_lens = calloc (nprotos, sizeof *proposal_lens);
- if (!proposal_lens)
- {
- log_error ("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
- (unsigned long)sizeof *proposal_lens);
- goto cleanup;
- }
-
- /* Pick out the chosen transforms. */
- for (proto = TAILQ_FIRST (&sa->protos), i = 0; proto;
- proto = TAILQ_NEXT (proto, link), i++)
- {
- transform_lens[i] = GET_ISAKMP_GEN_LENGTH (proto->chosen->p);
- transforms[i] = malloc (transform_lens[i]);
- if (!transforms[i])
- {
- log_error ("message_add_sa_payload: malloc (%lu) failed",
- (unsigned long)transform_lens[i]);
- goto cleanup;
- }
-
- /* Get incoming SPI from application. */
- if (doi->get_spi)
- {
- spi = doi->get_spi (&spi_sz,
- GET_ISAKMP_PROP_PROTO (proto->chosen
- ->context->p),
- msg);
- if (spi_sz && !spi)
- goto cleanup;
- proto->spi[1] = spi;
- proto->spi_sz[1] = spi_sz;
- }
- else
- spi_sz = 0;
-
- proposal_lens[i] = ISAKMP_PROP_SPI_OFF + spi_sz;
- proposals[i] = malloc (proposal_lens[i]);
- if (!proposals[i])
- {
- log_error ("message_add_sa_payload: malloc (%lu) failed",
- (unsigned long)proposal_lens[i]);
- goto cleanup;
- }
-
- memcpy (transforms[i], proto->chosen->p, transform_lens[i]);
- memcpy (proposals[i], proto->chosen->context->p,
- ISAKMP_PROP_SPI_OFF);
- SET_ISAKMP_PROP_NTRANSFORMS (proposals[i], 1);
- SET_ISAKMP_PROP_SPI_SZ (proposals[i], spi_sz);
- if (spi_sz)
- memcpy (proposals[i] + ISAKMP_PROP_SPI_OFF, spi, spi_sz);
- extra_sa_len += proposal_lens[i] + transform_lens[i];
- }
-
- /*
- * Add the payloads. As this is a SA, we need to recompute the
- * lengths of the payloads containing others. We also need to
- * reset these payload's "next payload type" field.
- */
- if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
- goto cleanup;
- SET_ISAKMP_GEN_LENGTH (sa_buf, sa_len + extra_sa_len);
- sa_buf = 0;
-
- saved_nextp_sa = msg->nextp;
- for (proto = TAILQ_FIRST (&sa->protos), i = 0; proto;
- proto = TAILQ_NEXT (proto, link), i++)
- {
- if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposals[i],
- proposal_lens[i], i > 1))
- goto cleanup;
- SET_ISAKMP_GEN_LENGTH (proposals[i],
- proposal_lens[i] + transform_lens[i]);
- proposals[i] = 0;
-
- saved_nextp_prop = msg->nextp;
- if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM,
- transforms[i], transform_lens[i], 0))
- goto cleanup;
- msg->nextp = saved_nextp_prop;
- transforms[i] = 0;
- }
- msg->nextp = saved_nextp_sa;
-
- /* Free the temporary allocations made above. */
- free (transforms);
- free (transform_lens);
- free (proposals);
- free (proposal_lens);
- }
- return 0;
-
- cleanup:
- if (sa_buf)
- free (sa_buf);
- for (i = 0; i < nprotos; i++)
- {
- if (transforms[i])
- free (transforms[i]);
- if (proposals[i])
- free (proposals[i]);
- }
- if (transforms)
- free (transforms);
- if (transform_lens)
- free (transform_lens);
- if (proposals)
- free (proposals);
- if (proposal_lens)
- free (proposal_lens);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ u_int8_t *sa_buf, *saved_nextp_sa, *saved_nextp_prop;
+ size_t sa_len, extra_sa_len;
+ int i, nprotos = 0;
+ struct proto *proto;
+ u_int8_t **transforms = 0, **proposals = 0;
+ size_t *transform_lens = 0, *proposal_lens = 0;
+ struct sa *sa;
+ struct doi *doi = exchange->doi;
+ u_int8_t *spi = 0;
+ size_t spi_sz;
+
+ /*
+ * Generate SA payloads.
+ */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa;
+ sa = TAILQ_NEXT(sa, next)) {
+ /* Setup a SA payload. */
+ sa_len = ISAKMP_SA_SIT_OFF + doi->situation_size();
+ extra_sa_len = 0;
+ sa_buf = malloc(sa_len);
+ if (!sa_buf) {
+ log_error("message_add_sa_payload: malloc (%lu) failed",
+ (unsigned long) sa_len);
+ goto cleanup;
+ }
+ SET_ISAKMP_SA_DOI(sa_buf, doi->id);
+ doi->setup_situation(sa_buf);
+
+ /* Count transforms. */
+ nprotos = 0;
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link))
+ nprotos++;
+
+ /*
+ * Allocate transient transform and proposal payload/size
+ * vectors.
+ */
+ transforms = calloc(nprotos, sizeof *transforms);
+ if (!transforms) {
+ log_error("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
+ (unsigned long) sizeof *transforms);
+ goto cleanup;
+ }
+ transform_lens = calloc(nprotos, sizeof *transform_lens);
+ if (!transform_lens) {
+ log_error("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
+ (unsigned long) sizeof *transform_lens);
+ goto cleanup;
+ }
+ proposals = calloc(nprotos, sizeof *proposals);
+ if (!proposals) {
+ log_error("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
+ (unsigned long) sizeof *proposals);
+ goto cleanup;
+ }
+ proposal_lens = calloc(nprotos, sizeof *proposal_lens);
+ if (!proposal_lens) {
+ log_error("message_add_sa_payload: calloc (%d, %lu) failed", nprotos,
+ (unsigned long) sizeof *proposal_lens);
+ goto cleanup;
+ }
+ /* Pick out the chosen transforms. */
+ for (proto = TAILQ_FIRST(&sa->protos), i = 0; proto;
+ proto = TAILQ_NEXT(proto, link), i++) {
+ transform_lens[i] = GET_ISAKMP_GEN_LENGTH(proto->chosen->p);
+ transforms[i] = malloc(transform_lens[i]);
+ if (!transforms[i]) {
+ log_error("message_add_sa_payload: malloc (%lu) failed",
+ (unsigned long) transform_lens[i]);
+ goto cleanup;
+ }
+ /* Get incoming SPI from application. */
+ if (doi->get_spi) {
+ spi = doi->get_spi(&spi_sz,
+ GET_ISAKMP_PROP_PROTO(proto->chosen
+ ->context->p),
+ msg);
+ if (spi_sz && !spi)
+ goto cleanup;
+ proto->spi[1] = spi;
+ proto->spi_sz[1] = spi_sz;
+ } else
+ spi_sz = 0;
+
+ proposal_lens[i] = ISAKMP_PROP_SPI_OFF + spi_sz;
+ proposals[i] = malloc(proposal_lens[i]);
+ if (!proposals[i]) {
+ log_error("message_add_sa_payload: malloc (%lu) failed",
+ (unsigned long) proposal_lens[i]);
+ goto cleanup;
+ }
+ memcpy(transforms[i], proto->chosen->p, transform_lens[i]);
+ memcpy(proposals[i], proto->chosen->context->p,
+ ISAKMP_PROP_SPI_OFF);
+ SET_ISAKMP_PROP_NTRANSFORMS(proposals[i], 1);
+ SET_ISAKMP_PROP_SPI_SZ(proposals[i], spi_sz);
+ if (spi_sz)
+ memcpy(proposals[i] + ISAKMP_PROP_SPI_OFF, spi, spi_sz);
+ extra_sa_len += proposal_lens[i] + transform_lens[i];
+ }
+
+ /*
+ * Add the payloads. As this is a SA, we need to recompute the
+ * lengths of the payloads containing others. We also need to
+ * reset these payload's "next payload type" field.
+ */
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
+ goto cleanup;
+ SET_ISAKMP_GEN_LENGTH(sa_buf, sa_len + extra_sa_len);
+ sa_buf = 0;
+
+ saved_nextp_sa = msg->nextp;
+ for (proto = TAILQ_FIRST(&sa->protos), i = 0; proto;
+ proto = TAILQ_NEXT(proto, link), i++) {
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL, proposals[i],
+ proposal_lens[i], i > 1))
+ goto cleanup;
+ SET_ISAKMP_GEN_LENGTH(proposals[i],
+ proposal_lens[i] + transform_lens[i]);
+ proposals[i] = 0;
+
+ saved_nextp_prop = msg->nextp;
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM,
+ transforms[i], transform_lens[i], 0))
+ goto cleanup;
+ msg->nextp = saved_nextp_prop;
+ transforms[i] = 0;
+ }
+ msg->nextp = saved_nextp_sa;
+
+ /* Free the temporary allocations made above. */
+ free(transforms);
+ free(transform_lens);
+ free(proposals);
+ free(proposal_lens);
+ }
+ return 0;
+
+cleanup:
+ if (sa_buf)
+ free(sa_buf);
+ for (i = 0; i < nprotos; i++) {
+ if (transforms[i])
+ free(transforms[i]);
+ if (proposals[i])
+ free(proposals[i]);
+ }
+ if (transforms)
+ free(transforms);
+ if (transform_lens)
+ free(transform_lens);
+ if (proposals)
+ free(proposals);
+ if (proposal_lens)
+ free(proposal_lens);
+ return -1;
}
/*
* Return a copy of MSG's constants starting from OFFSET and stash the size
* in SZP. It is the callers responsibility to free this up.
*/
-u_int8_t *
-message_copy (struct message *msg, size_t offset, size_t *szp)
+u_int8_t *
+message_copy(struct message * msg, size_t offset, size_t * szp)
{
- int skip = 0;
- size_t i, sz = 0;
- ssize_t start = -1;
- u_int8_t *buf, *p;
-
- /* Calculate size of message and where we want to start to copy. */
- for (i = 1; i < msg->iovlen; i++)
- {
- sz += msg->iov[i].iov_len;
- if (sz <= offset)
- skip = i;
- else if (start < 0)
- start = offset - (sz - msg->iov[i].iov_len);
- }
-
- /* Allocate and copy. */
- *szp = sz - offset;
- buf = malloc (*szp);
- if (!buf)
- return 0;
- p = buf;
- for (i = skip + 1; i < msg->iovlen; i++)
- {
- memcpy (p, (u_int8_t *)msg->iov[i].iov_base + start,
- msg->iov[i].iov_len - start);
- p += msg->iov[i].iov_len - start;
- start = 0;
- }
- return buf;
+ int skip = 0;
+ size_t i, sz = 0;
+ ssize_t start = -1;
+ u_int8_t *buf, *p;
+
+ /* Calculate size of message and where we want to start to copy. */
+ for (i = 1; i < msg->iovlen; i++) {
+ sz += msg->iov[i].iov_len;
+ if (sz <= offset)
+ skip = i;
+ else if (start < 0)
+ start = offset - (sz - msg->iov[i].iov_len);
+ }
+
+ /* Allocate and copy. */
+ *szp = sz - offset;
+ buf = malloc(*szp);
+ if (!buf)
+ return 0;
+ p = buf;
+ for (i = skip + 1; i < msg->iovlen; i++) {
+ memcpy(p, (u_int8_t *) msg->iov[i].iov_base + start,
+ msg->iov[i].iov_len - start);
+ p += msg->iov[i].iov_len - start;
+ start = 0;
+ }
+ return buf;
}
/* Register a post-send function POST_SEND with message MSG. */
int
-message_register_post_send (struct message *msg,
- void (*post_send) (struct message *))
+message_register_post_send(struct message * msg,
+ void (*post_send) (struct message *))
{
- struct post_send *node;
-
- node = malloc (sizeof *node);
- if (!node)
- return -1;
- node->func = post_send;
- TAILQ_INSERT_TAIL (&msg->post_send, node, link);
- return 0;
+ struct post_send *node;
+
+ node = malloc(sizeof *node);
+ if (!node)
+ return -1;
+ node->func = post_send;
+ TAILQ_INSERT_TAIL(&msg->post_send, node, link);
+ return 0;
}
/* Run the post-send functions of message MSG. */
void
-message_post_send (struct message *msg)
+message_post_send(struct message * msg)
{
- struct post_send *node;
-
- while ((node = TAILQ_FIRST (&msg->post_send)) != 0)
- {
- TAILQ_REMOVE (&msg->post_send, node, link);
- node->func (msg);
- free (node);
- }
+ struct post_send *node;
+
+ while ((node = TAILQ_FIRST(&msg->post_send)) != 0) {
+ TAILQ_REMOVE(&msg->post_send, node, link);
+ node->func(msg);
+ free(node);
+ }
}
diff --git a/sbin/isakmpd/message.h b/sbin/isakmpd/message.h
index 3cb2153336a..45fdfb30835 100644
--- a/sbin/isakmpd/message.h
+++ b/sbin/isakmpd/message.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: message.h,v 1.17 2003/11/06 16:12:07 ho Exp $ */
-/* $EOM: message.h,v 1.51 2000/10/10 12:36:39 provos Exp $ */
+/* $OpenBSD: message.h,v 1.18 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: message.h,v 1.51 2000/10/10 12:36:39 provos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -48,19 +48,19 @@ struct sa;
struct transport;
struct payload {
- /* Link all payloads of the same type through here. */
- TAILQ_ENTRY (payload) link;
+ /* Link all payloads of the same type through here. */
+ TAILQ_ENTRY(payload) link;
- /* The pointer to the actual payload data. */
- u_int8_t *p;
+ /* The pointer to the actual payload data. */
+ u_int8_t *p;
- /*
- * A pointer to the parent payload, used for proposal and transform payloads.
- */
- struct payload *context;
+ /*
+ * A pointer to the parent payload, used for proposal and transform payloads.
+ */
+ struct payload *context;
- /* Payload flags described below. */
- int flags;
+ /* Payload flags described below. */
+ int flags;
};
/* Payload flags. */
@@ -73,73 +73,73 @@ struct payload {
/* A post-send chain of functions to be called. */
struct post_send {
- /* Link to the next function in the chain. */
- TAILQ_ENTRY (post_send) link;
+ /* Link to the next function in the chain. */
+ TAILQ_ENTRY(post_send) link;
- /* The actual function. */
- void (*func) (struct message *);
+ /* The actual function. */
+ void (*func) (struct message *);
};
struct message {
- /* Link message in send queues via this link. */
- TAILQ_ENTRY (message) link;
-
- /* Message flags described below. */
- u_int flags;
-
- /*
- * This is the transport the message either arrived on or will be sent to.
- */
- struct transport *transport;
-
- /*
- * This is the ISAKMP SA protecting this message.
- * XXX Needs to be redone to some keystate pointer or something.
- */
- struct sa *isakmp_sa;
-
- /* This is the exchange where this message appears. */
- struct exchange *exchange;
-
- /*
- * A segmented buffer structure holding the messages raw contents. On input
- * only segment 0 will be filled, holding all of the message. On output, as
- * long as the message body is unencrypted each segment will be one payload,
- * after encryption segment 0 will be the unencrypted header, and segment 1
- * will be the encrypted payloads, all of them.
- */
- struct iovec *iov;
-
- /* The segment count. */
- u_int iovlen;
-
- /* Pointer to the last "next payload" field. */
- u_int8_t *nextp;
-
- /* "Smart" pointers to each payload, sorted by type. */
- TAILQ_HEAD (payload_head, payload) payload[ISAKMP_PAYLOAD_RESERVED_MIN];
-
- /* Number of times this message has been sent. */
- int xmits;
-
- /* The timeout event causing retransmission of this message. */
- struct event *retrans;
-
- /* The (possibly encrypted) message text, used for duplicate testing. */
- u_int8_t *orig;
- size_t orig_sz;
-
- /*
- * Extra baggage needed to travel with the message. Used transiently
- * in context sensitive ways.
- */
- void *extra;
-
- /*
- * Hooks for stuff needed to be done after the message has gone out to
- * the wire.
- */
- TAILQ_HEAD (post_send_head, post_send) post_send;
+ /* Link message in send queues via this link. */
+ TAILQ_ENTRY(message) link;
+
+ /* Message flags described below. */
+ u_int flags;
+
+ /*
+ * This is the transport the message either arrived on or will be sent to.
+ */
+ struct transport *transport;
+
+ /*
+ * This is the ISAKMP SA protecting this message.
+ * XXX Needs to be redone to some keystate pointer or something.
+ */
+ struct sa *isakmp_sa;
+
+ /* This is the exchange where this message appears. */
+ struct exchange *exchange;
+
+ /*
+ * A segmented buffer structure holding the messages raw contents. On input
+ * only segment 0 will be filled, holding all of the message. On output, as
+ * long as the message body is unencrypted each segment will be one payload,
+ * after encryption segment 0 will be the unencrypted header, and segment 1
+ * will be the encrypted payloads, all of them.
+ */
+ struct iovec *iov;
+
+ /* The segment count. */
+ u_int iovlen;
+
+ /* Pointer to the last "next payload" field. */
+ u_int8_t *nextp;
+
+ /* "Smart" pointers to each payload, sorted by type. */
+ TAILQ_HEAD(payload_head, payload) payload[ISAKMP_PAYLOAD_RESERVED_MIN];
+
+ /* Number of times this message has been sent. */
+ int xmits;
+
+ /* The timeout event causing retransmission of this message. */
+ struct event *retrans;
+
+ /* The (possibly encrypted) message text, used for duplicate testing. */
+ u_int8_t *orig;
+ size_t orig_sz;
+
+ /*
+ * Extra baggage needed to travel with the message. Used transiently
+ * in context sensitive ways.
+ */
+ void *extra;
+
+ /*
+ * Hooks for stuff needed to be done after the message has gone out to
+ * the wire.
+ */
+ TAILQ_HEAD(post_send_head, post_send) post_send;
};
/* Message flags. */
@@ -160,31 +160,33 @@ struct message {
/* This message should be kept on the prioritized sendq. */
#define MSG_PRIORITIZED 8
-TAILQ_HEAD (msg_head, message);
-
-extern int message_add_payload (struct message *, u_int8_t, u_int8_t *,
- size_t, int);
-extern int message_add_sa_payload (struct message *);
-extern struct message *message_alloc (struct transport *, u_int8_t *, size_t);
-extern struct message *message_alloc_reply (struct message *);
-extern u_int8_t *message_copy (struct message *, size_t, size_t *);
-extern void message_drop (struct message *, int, struct proto *, int, int);
-extern void message_dump_raw (char *, struct message *, int);
-extern void message_free (struct message *);
-extern int message_negotiate_sa (struct message *,
- int (*) (struct exchange *, struct sa *,
- struct sa *));
-extern int message_recv (struct message *);
-extern int message_register_post_send (struct message *,
- void (*) (struct message *));
-extern void message_post_send (struct message *);
-extern void message_send (struct message *);
-extern void message_send_expire (struct message *);
-extern void message_send_delete (struct sa *);
-extern int message_send_info (struct message *);
-extern void message_send_notification (struct message *, struct sa *,
- u_int16_t, struct proto *, int);
-extern void message_setup_header (struct message *, u_int8_t, u_int8_t,
- u_int8_t *);
-
-#endif /* _MESSAGE_H_ */
+TAILQ_HEAD(msg_head, message);
+
+extern int
+message_add_payload(struct message *, u_int8_t, u_int8_t *,
+ size_t, int);
+extern int message_add_sa_payload(struct message *);
+extern struct message *message_alloc(struct transport *, u_int8_t *, size_t);
+extern struct message *message_alloc_reply(struct message *);
+extern u_int8_t *message_copy(struct message *, size_t, size_t *);
+extern void message_drop(struct message *, int, struct proto *, int, int);
+extern void message_dump_raw(char *, struct message *, int);
+extern void message_free(struct message *);
+extern int
+message_negotiate_sa(struct message *,
+ int (*) (struct exchange *, struct sa *,
+ struct sa *));
+ extern int message_recv(struct message *);
+ extern int message_register_post_send(struct message *,
+ void (*) (struct message *));
+ extern void message_post_send(struct message *);
+ extern void message_send(struct message *);
+ extern void message_send_expire(struct message *);
+ extern void message_send_delete(struct sa *);
+ extern int message_send_info(struct message *);
+ extern void message_send_notification(struct message *, struct sa *,
+ u_int16_t, struct proto *, int);
+ extern void message_setup_header(struct message *, u_int8_t, u_int8_t,
+ u_int8_t *);
+
+#endif /* _MESSAGE_H_ */
diff --git a/sbin/isakmpd/monitor.c b/sbin/isakmpd/monitor.c
index a4517e1d9fb..7afaa27c2df 100644
--- a/sbin/isakmpd/monitor.c
+++ b/sbin/isakmpd/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.18 2004/04/07 22:45:49 ho Exp $ */
+/* $OpenBSD: monitor.c,v 1.19 2004/04/15 18:39:26 deraadt Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -52,37 +52,36 @@
#include "policy.h"
#include "util.h"
-struct monitor_state
-{
- pid_t pid;
- int s;
- char root[MAXPATHLEN];
-} m_state;
+struct monitor_state {
+ pid_t pid;
+ int s;
+ char root[MAXPATHLEN];
+} m_state;
volatile sig_atomic_t sigchlded = 0;
volatile sig_atomic_t monitor_sighupped = 0;
extern volatile sig_atomic_t sigtermed;
static volatile sig_atomic_t cur_state = STATE_INIT;
-extern char *ui_fifo;
+extern char *ui_fifo;
/* Private functions. */
-int m_write_int32 (int, int32_t);
-int m_write_raw (int, char *, size_t);
-int m_read_int32 (int, int32_t *);
-int m_read_raw (int, char *, size_t);
-void m_flush (int);
-
-static void m_priv_getfd (int);
-static void m_priv_getsocket (int);
-static void m_priv_setsockopt (int);
-static void m_priv_bind (int);
-static void m_priv_mkfifo (int);
-static int m_priv_local_sanitize_path (char *, size_t, int);
-static int m_priv_check_sockopt (int, int);
-static int m_priv_check_bind (const struct sockaddr *, socklen_t);
-static void m_priv_increase_state (int);
-static void m_priv_test_state (int);
+int m_write_int32(int, int32_t);
+int m_write_raw(int, char *, size_t);
+int m_read_int32(int, int32_t *);
+int m_read_raw(int, char *, size_t);
+void m_flush(int);
+
+static void m_priv_getfd(int);
+static void m_priv_getsocket(int);
+static void m_priv_setsockopt(int);
+static void m_priv_bind(int);
+static void m_priv_mkfifo(int);
+static int m_priv_local_sanitize_path(char *, size_t, int);
+static int m_priv_check_sockopt(int, int);
+static int m_priv_check_bind(const struct sockaddr *, socklen_t);
+static void m_priv_increase_state(int);
+static void m_priv_test_state(int);
/*
* Public functions, unprivileged.
@@ -90,428 +89,401 @@ static void m_priv_test_state (int);
/* Setup monitor context, fork, drop child privs. */
pid_t
-monitor_init (void)
+monitor_init(void)
{
- struct passwd *pw;
- int p[2];
- memset (&m_state, 0, sizeof m_state);
+ struct passwd *pw;
+ int p[2];
+
+ memset(&m_state, 0, sizeof m_state);
- if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0)
- log_fatal ("monitor_init: socketpair() failed");
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0)
+ log_fatal("monitor_init: socketpair() failed");
- pw = getpwnam (ISAKMPD_PRIVSEP_USER);
- if (pw == NULL)
- log_fatal ("monitor_init: getpwnam(\"%s\") failed",
- ISAKMPD_PRIVSEP_USER);
+ pw = getpwnam(ISAKMPD_PRIVSEP_USER);
+ if (pw == NULL)
+ log_fatal("monitor_init: getpwnam(\"%s\") failed",
+ ISAKMPD_PRIVSEP_USER);
- m_state.pid = fork ();
- m_state.s = p[m_state.pid ? 1 : 0];
- strlcpy (m_state.root, pw->pw_dir, sizeof m_state.root);
+ m_state.pid = fork();
+ m_state.s = p[m_state.pid ? 1 : 0];
+ strlcpy(m_state.root, pw->pw_dir, sizeof m_state.root);
- LOG_DBG ((LOG_SYSDEP, 30, "monitor_init: pid %d my fd %d", m_state.pid,
+ LOG_DBG((LOG_SYSDEP, 30, "monitor_init: pid %d my fd %d", m_state.pid,
m_state.s));
- /* The child process should drop privileges now. */
- if (!m_state.pid)
- {
- if (chroot (pw->pw_dir) != 0 || chdir("/") != 0)
- log_fatal ("monitor_init: chroot failed");
+ /* The child process should drop privileges now. */
+ if (!m_state.pid) {
+ if (chroot(pw->pw_dir) != 0 || chdir("/") != 0)
+ log_fatal("monitor_init: chroot failed");
- if (setgid (pw->pw_gid) != 0)
- log_fatal ("monitor_init: setgid(%d) failed", pw->pw_gid);
+ if (setgid(pw->pw_gid) != 0)
+ log_fatal("monitor_init: setgid(%d) failed", pw->pw_gid);
- if (setuid (pw->pw_uid) != 0)
- log_fatal ("monitor_init: setuid(%d) failed", pw->pw_uid);
+ if (setuid(pw->pw_uid) != 0)
+ log_fatal("monitor_init: setuid(%d) failed", pw->pw_uid);
- LOG_DBG ((LOG_MISC, 10,
- "monitor_init: privileges dropped for child process"));
- }
- else
- {
- setproctitle ("monitor [priv]");
- }
+ LOG_DBG((LOG_MISC, 10,
+ "monitor_init: privileges dropped for child process"));
+ } else {
+ setproctitle("monitor [priv]");
+ }
- return m_state.pid;
+ return m_state.pid;
}
int
-monitor_open (const char *path, int flags, mode_t mode)
+monitor_open(const char *path, int flags, mode_t mode)
{
- int fd, mode32 = (int32_t) mode;
- int32_t err;
- char realpath[MAXPATHLEN];
-
- if (path[0] == '/')
- strlcpy (realpath, path, sizeof realpath);
- else
- snprintf (realpath, sizeof realpath, "%s/%s", m_state.root, path);
-
- /* Write data to priv process. */
- if (m_write_int32 (m_state.s, MONITOR_GET_FD))
- goto errout;
-
- if (m_write_raw (m_state.s, realpath, strlen (realpath) + 1))
- goto errout;
-
- if (m_write_int32 (m_state.s, flags))
- goto errout;
-
- if (m_write_int32 (m_state.s, mode32))
- goto errout;
-
- if (m_read_int32 (m_state.s, &err))
- goto errout;
-
- if (err != 0)
- {
- errno = (int)err;
- return -1;
- }
-
- /* Wait for response. */
- fd = mm_receive_fd (m_state.s);
- if (fd < 0)
- {
- log_error ("monitor_open: mm_receive_fd () failed: %s",
- strerror (errno));
- return -1;
- }
-
- return fd;
-
- errout:
- log_error ("monitor_open: problem talking to privileged process");
- return -1;
+ int fd, mode32 = (int32_t) mode;
+ int32_t err;
+ char realpath[MAXPATHLEN];
+
+ if (path[0] == '/')
+ strlcpy(realpath, path, sizeof realpath);
+ else
+ snprintf(realpath, sizeof realpath, "%s/%s", m_state.root, path);
+
+ /* Write data to priv process. */
+ if (m_write_int32(m_state.s, MONITOR_GET_FD))
+ goto errout;
+
+ if (m_write_raw(m_state.s, realpath, strlen(realpath) + 1))
+ goto errout;
+
+ if (m_write_int32(m_state.s, flags))
+ goto errout;
+
+ if (m_write_int32(m_state.s, mode32))
+ goto errout;
+
+ if (m_read_int32(m_state.s, &err))
+ goto errout;
+
+ if (err != 0) {
+ errno = (int) err;
+ return -1;
+ }
+ /* Wait for response. */
+ fd = mm_receive_fd(m_state.s);
+ if (fd < 0) {
+ log_error("monitor_open: mm_receive_fd () failed: %s",
+ strerror(errno));
+ return -1;
+ }
+ return fd;
+
+errout:
+ log_error("monitor_open: problem talking to privileged process");
+ return -1;
}
FILE *
-monitor_fopen (const char *path, const char *mode)
+monitor_fopen(const char *path, const char *mode)
{
- FILE *fp;
- int fd, flags = 0, mask, saved_errno;
-
- /* Only the child process is supposed to run this. */
- if (m_state.pid)
- log_fatal ("[priv] bad call to monitor_fopen");
-
- switch (mode[0])
- {
- case 'r':
- flags = (mode[1] == '+' ? O_RDWR : O_RDONLY);
- break;
- case 'w':
- flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | O_TRUNC;
- break;
- case 'a':
- flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | O_APPEND;
- break;
- default:
- log_fatal ("monitor_fopen: bad call");
- }
-
- mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-
- fd = monitor_open (path, flags, mask);
- if (fd < 0)
- return NULL;
-
- /* Got the fd, attach a FILE * to it. */
- fp = fdopen (fd, mode);
- if (!fp)
- {
- log_error ("monitor_fopen: fdopen() failed");
- saved_errno = errno;
- close (fd);
- errno = saved_errno;
- return NULL;
- }
-
- return fp;
+ FILE *fp;
+ int fd, flags = 0, mask, saved_errno;
+
+ /* Only the child process is supposed to run this. */
+ if (m_state.pid)
+ log_fatal("[priv] bad call to monitor_fopen");
+
+ switch (mode[0]) {
+ case 'r':
+ flags = (mode[1] == '+' ? O_RDWR : O_RDONLY);
+ break;
+ case 'w':
+ flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | O_TRUNC;
+ break;
+ case 'a':
+ flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | O_APPEND;
+ break;
+ default:
+ log_fatal("monitor_fopen: bad call");
+ }
+
+ mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+
+ fd = monitor_open(path, flags, mask);
+ if (fd < 0)
+ return NULL;
+
+ /* Got the fd, attach a FILE * to it. */
+ fp = fdopen(fd, mode);
+ if (!fp) {
+ log_error("monitor_fopen: fdopen() failed");
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return NULL;
+ }
+ return fp;
}
int
-monitor_stat (const char *path, struct stat *sb)
+monitor_stat(const char *path, struct stat *sb)
{
- int fd, r, saved_errno;
-
- /* O_NONBLOCK is needed for stat'ing fifos. */
- fd = monitor_open (path, O_RDONLY | O_NONBLOCK, 0);
- if (fd < 0)
- return -1;
-
- r = fstat (fd, sb);
- saved_errno = errno;
- close (fd);
- errno = saved_errno;
- return r;
+ int fd, r, saved_errno;
+
+ /* O_NONBLOCK is needed for stat'ing fifos. */
+ fd = monitor_open(path, O_RDONLY | O_NONBLOCK, 0);
+ if (fd < 0)
+ return -1;
+
+ r = fstat(fd, sb);
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return r;
}
int
-monitor_socket (int domain, int type, int protocol)
+monitor_socket(int domain, int type, int protocol)
{
- int s;
- int32_t err;
+ int s;
+ int32_t err;
- if (m_write_int32 (m_state.s, MONITOR_GET_SOCKET))
- goto errout;
+ if (m_write_int32(m_state.s, MONITOR_GET_SOCKET))
+ goto errout;
- if (m_write_int32 (m_state.s, (int32_t)domain))
- goto errout;
+ if (m_write_int32(m_state.s, (int32_t) domain))
+ goto errout;
- if (m_write_int32 (m_state.s, (int32_t)type))
- goto errout;
+ if (m_write_int32(m_state.s, (int32_t) type))
+ goto errout;
- if (m_write_int32 (m_state.s, (int32_t)protocol))
- goto errout;
+ if (m_write_int32(m_state.s, (int32_t) protocol))
+ goto errout;
- if (m_read_int32 (m_state.s, &err))
- goto errout;
+ if (m_read_int32(m_state.s, &err))
+ goto errout;
- if (err != 0)
- {
- errno = (int)err;
- return -1;
- }
-
- /* Read result. */
- s = mm_receive_fd (m_state.s);
- if (s < 0)
- {
- log_error ("monitor_socket: mm_receive_fd () failed: %s",
- strerror (errno));
- return -1;
- }
-
- return s;
+ if (err != 0) {
+ errno = (int) err;
+ return -1;
+ }
+ /* Read result. */
+ s = mm_receive_fd(m_state.s);
+ if (s < 0) {
+ log_error("monitor_socket: mm_receive_fd () failed: %s",
+ strerror(errno));
+ return -1;
+ }
+ return s;
- errout:
- log_error ("monitor_socket: problem talking to privileged process");
- return -1;
+errout:
+ log_error("monitor_socket: problem talking to privileged process");
+ return -1;
}
int
-monitor_setsockopt (int s, int level, int optname, const void *optval,
- socklen_t optlen)
+monitor_setsockopt(int s, int level, int optname, const void *optval,
+ socklen_t optlen)
{
- int32_t ret, err;
+ int32_t ret, err;
- if (m_write_int32 (m_state.s, MONITOR_SETSOCKOPT))
- goto errout;
- if (mm_send_fd (m_state.s, s))
- goto errout;
+ if (m_write_int32(m_state.s, MONITOR_SETSOCKOPT))
+ goto errout;
+ if (mm_send_fd(m_state.s, s))
+ goto errout;
- if (m_write_int32 (m_state.s, (int32_t)level))
- goto errout;
- if (m_write_int32 (m_state.s, (int32_t)optname))
- goto errout;
- if (m_write_int32 (m_state.s, (int32_t)optlen))
- goto errout;
- if (m_write_raw (m_state.s, (char *)optval, (size_t)optlen))
- goto errout;
+ if (m_write_int32(m_state.s, (int32_t) level))
+ goto errout;
+ if (m_write_int32(m_state.s, (int32_t) optname))
+ goto errout;
+ if (m_write_int32(m_state.s, (int32_t) optlen))
+ goto errout;
+ if (m_write_raw(m_state.s, (char *) optval, (size_t) optlen))
+ goto errout;
- if (m_read_int32 (m_state.s, &err))
- goto errout;
+ if (m_read_int32(m_state.s, &err))
+ goto errout;
- if (err != 0)
- errno = (int)err;
+ if (err != 0)
+ errno = (int) err;
- if (m_read_int32 (m_state.s, &ret))
- goto errout;
+ if (m_read_int32(m_state.s, &ret))
+ goto errout;
- return (int)ret;
+ return (int) ret;
- errout:
- log_print ("monitor_setsockopt: read/write error");
- return -1;
+errout:
+ log_print("monitor_setsockopt: read/write error");
+ return -1;
}
int
-monitor_bind (int s, const struct sockaddr *name, socklen_t namelen)
+monitor_bind(int s, const struct sockaddr *name, socklen_t namelen)
{
- int32_t ret, err;
+ int32_t ret, err;
- if (m_write_int32 (m_state.s, MONITOR_BIND))
- goto errout;
- if (mm_send_fd (m_state.s, s))
- goto errout;
+ if (m_write_int32(m_state.s, MONITOR_BIND))
+ goto errout;
+ if (mm_send_fd(m_state.s, s))
+ goto errout;
- if (m_write_int32 (m_state.s, (int32_t)namelen))
- goto errout;
- if (m_write_raw (m_state.s, (char *)name, (size_t)namelen))
- goto errout;
+ if (m_write_int32(m_state.s, (int32_t) namelen))
+ goto errout;
+ if (m_write_raw(m_state.s, (char *) name, (size_t) namelen))
+ goto errout;
- if (m_read_int32 (m_state.s, &err))
- goto errout;
+ if (m_read_int32(m_state.s, &err))
+ goto errout;
- if (err != 0)
- errno = (int)err;
+ if (err != 0)
+ errno = (int) err;
- if (m_read_int32 (m_state.s, &ret))
- goto errout;
+ if (m_read_int32(m_state.s, &ret))
+ goto errout;
- return (int)ret;
+ return (int) ret;
- errout:
- log_print ("monitor_bind: read/write error");
- return -1;
+errout:
+ log_print("monitor_bind: read/write error");
+ return -1;
}
int
-monitor_mkfifo (const char *path, mode_t mode)
+monitor_mkfifo(const char *path, mode_t mode)
{
- int32_t ret, err;
- char realpath[MAXPATHLEN];
+ int32_t ret, err;
+ char realpath[MAXPATHLEN];
- /* Only the child process is supposed to run this. */
- if (m_state.pid)
- log_fatal ("[priv] bad call to monitor_mkfifo");
+ /* Only the child process is supposed to run this. */
+ if (m_state.pid)
+ log_fatal("[priv] bad call to monitor_mkfifo");
- if (path[0] == '/')
- strlcpy (realpath, path, sizeof realpath);
- else
- snprintf (realpath, sizeof realpath, "%s/%s", m_state.root, path);
+ if (path[0] == '/')
+ strlcpy(realpath, path, sizeof realpath);
+ else
+ snprintf(realpath, sizeof realpath, "%s/%s", m_state.root, path);
- if (m_write_int32 (m_state.s, MONITOR_MKFIFO))
- goto errout;
+ if (m_write_int32(m_state.s, MONITOR_MKFIFO))
+ goto errout;
- if (m_write_raw (m_state.s, realpath, strlen (realpath) + 1))
- goto errout;
+ if (m_write_raw(m_state.s, realpath, strlen(realpath) + 1))
+ goto errout;
- ret = (int32_t)mode;
- if (m_write_int32 (m_state.s, ret))
- goto errout;
+ ret = (int32_t) mode;
+ if (m_write_int32(m_state.s, ret))
+ goto errout;
- if (m_read_int32 (m_state.s, &err))
- goto errout;
+ if (m_read_int32(m_state.s, &err))
+ goto errout;
- if (err != 0)
- errno = (int)err;
+ if (err != 0)
+ errno = (int) err;
- if (m_read_int32 (m_state.s, &ret))
- goto errout;
+ if (m_read_int32(m_state.s, &ret))
+ goto errout;
- return (int)ret;
+ return (int) ret;
- errout:
- log_print ("monitor_mkfifo: read/write error");
- return -1;
+errout:
+ log_print("monitor_mkfifo: read/write error");
+ return -1;
}
struct monitor_dirents *
-monitor_opendir (const char *path)
+monitor_opendir(const char *path)
{
- char *buf, *cp;
- size_t bufsize;
- int fd, nbytes, entries;
- long base;
- struct stat sb;
- struct dirent *dp;
- struct monitor_dirents *direntries;
-
- fd = monitor_open (path, 0, O_RDONLY);
- if (fd < 0)
- {
- log_error ("monitor_opendir: opendir(\"%s\") failed", path);
- return NULL;
- }
-
- /* Now build a list with all dirents from fd. */
- if (fstat (fd, &sb) < 0)
- {
- (void)close (fd);
- return NULL;
- }
-
- if (!S_ISDIR (sb.st_mode))
- {
- (void)close (fd);
- errno = EACCES;
- return NULL;
- }
-
- bufsize = sb.st_size;
- if (bufsize < sb.st_blksize)
- bufsize = sb.st_blksize;
-
- buf = calloc (bufsize, sizeof (char));
- if (buf == NULL)
- {
- (void)close (fd);
- errno = EACCES;
- return NULL;
- }
-
- nbytes = getdirentries (fd, buf, bufsize, &base);
- if (nbytes <= 0)
- {
- (void)close (fd);
- free (buf);
- errno = EACCES;
- return NULL;
- }
- (void)close (fd);
-
- for (entries = 0, cp = buf; cp < buf + nbytes; )
- {
- dp = (struct dirent *)cp;
- cp += dp->d_reclen;
- entries++;
- }
-
- direntries = calloc (1, sizeof (struct monitor_dirents));
- if (direntries == NULL)
- {
- free (buf);
- errno = EACCES;
- return NULL;
- }
-
- direntries->dirents = calloc (entries + 1, sizeof (struct dirent *));
- if (direntries->dirents == NULL)
- {
- free (buf);
- free (direntries);
- errno = EACCES;
- return NULL;
- }
- direntries->current = 0;
-
- for (entries = 0, cp = buf; cp < buf + nbytes; )
- {
- dp = (struct dirent *)cp;
- direntries->dirents[entries++] = dp;
- cp += dp->d_reclen;
- }
- direntries->dirents[entries] = NULL;
-
- return direntries;
+ char *buf, *cp;
+ size_t bufsize;
+ int fd, nbytes, entries;
+ long base;
+ struct stat sb;
+ struct dirent *dp;
+ struct monitor_dirents *direntries;
+
+ fd = monitor_open(path, 0, O_RDONLY);
+ if (fd < 0) {
+ log_error("monitor_opendir: opendir(\"%s\") failed", path);
+ return NULL;
+ }
+ /* Now build a list with all dirents from fd. */
+ if (fstat(fd, &sb) < 0) {
+ (void) close(fd);
+ return NULL;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ (void) close(fd);
+ errno = EACCES;
+ return NULL;
+ }
+ bufsize = sb.st_size;
+ if (bufsize < sb.st_blksize)
+ bufsize = sb.st_blksize;
+
+ buf = calloc(bufsize, sizeof(char));
+ if (buf == NULL) {
+ (void) close(fd);
+ errno = EACCES;
+ return NULL;
+ }
+ nbytes = getdirentries(fd, buf, bufsize, &base);
+ if (nbytes <= 0) {
+ (void) close(fd);
+ free(buf);
+ errno = EACCES;
+ return NULL;
+ }
+ (void) close(fd);
+
+ for (entries = 0, cp = buf; cp < buf + nbytes;) {
+ dp = (struct dirent *) cp;
+ cp += dp->d_reclen;
+ entries++;
+ }
+
+ direntries = calloc(1, sizeof(struct monitor_dirents));
+ if (direntries == NULL) {
+ free(buf);
+ errno = EACCES;
+ return NULL;
+ }
+ direntries->dirents = calloc(entries + 1, sizeof(struct dirent *));
+ if (direntries->dirents == NULL) {
+ free(buf);
+ free(direntries);
+ errno = EACCES;
+ return NULL;
+ }
+ direntries->current = 0;
+
+ for (entries = 0, cp = buf; cp < buf + nbytes;) {
+ dp = (struct dirent *) cp;
+ direntries->dirents[entries++] = dp;
+ cp += dp->d_reclen;
+ }
+ direntries->dirents[entries] = NULL;
+
+ return direntries;
}
struct dirent *
-monitor_readdir (struct monitor_dirents *direntries)
+monitor_readdir(struct monitor_dirents *direntries)
{
- if (direntries->dirents[direntries->current] != NULL)
- return direntries->dirents[direntries->current++];
+ if (direntries->dirents[direntries->current] != NULL)
+ return direntries->dirents[direntries->current++];
- return NULL;
+ return NULL;
}
int
-monitor_closedir (struct monitor_dirents *direntries)
+monitor_closedir(struct monitor_dirents *direntries)
{
- free (direntries->dirents);
- free (direntries);
+ free(direntries->dirents);
+ free(direntries);
- return 0;
+ return 0;
}
void
-monitor_init_done (void)
+monitor_init_done(void)
{
- if (m_write_int32 (m_state.s, MONITOR_INIT_DONE))
- log_print ("monitor_init_done: read/write error");
+ if (m_write_int32(m_state.s, MONITOR_INIT_DONE))
+ log_print("monitor_init_done: read/write error");
- return;
+ return;
}
/*
@@ -520,425 +492,395 @@ monitor_init_done (void)
/* Help functions for monitor_loop(). */
static void
-monitor_got_sigchld (int sig)
+monitor_got_sigchld(int sig)
{
- sigchlded = 1;
+ sigchlded = 1;
}
static void
sig_pass_to_chld(int sig)
{
- int oerrno = errno;
+ int oerrno = errno;
- if (m_state.pid != -1)
- kill(m_state.pid, sig);
- errno = oerrno;
+ if (m_state.pid != -1)
+ kill(m_state.pid, sig);
+ errno = oerrno;
}
/* This function is where the privileged process waits(loops) indefinitely. */
void
-monitor_loop (int debugging)
+monitor_loop(int debugging)
{
- pid_t pid;
- fd_set *fds;
- size_t fdsn;
- int n, maxfd;
-
- if (!debugging)
- log_to (0);
-
- maxfd = m_state.s + 1;
-
- fdsn = howmany (maxfd, NFDBITS) * sizeof (fd_mask);
- fds = (fd_set *)malloc (fdsn);
- if (!fds)
- {
- kill (m_state.pid, SIGTERM);
- log_fatal ("monitor_loop: malloc (%u) failed", fdsn);
- return;
- }
-
- /* If the child dies, we should shutdown also. */
- signal (SIGCHLD, monitor_got_sigchld);
-
- /* SIGHUP, SIGUSR1 and SIGUSR2 will be forwarded to child. */
- signal (SIGHUP, sig_pass_to_chld);
- signal (SIGUSR1, sig_pass_to_chld);
- signal (SIGUSR2, sig_pass_to_chld);
-
- while (cur_state < STATE_QUIT)
- {
- /*
- * Currently, there is no need for us to hang around if the child
- * is in the process of shutting down.
- */
- if (sigtermed || sigchlded)
- {
- if (sigtermed)
- kill (m_state.pid, SIGTERM);
-
- if (sigchlded)
- {
- do
- {
- pid = waitpid (m_state.pid, &n, WNOHANG);
+ pid_t pid;
+ fd_set *fds;
+ size_t fdsn;
+ int n, maxfd;
+
+ if (!debugging)
+ log_to(0);
+
+ maxfd = m_state.s + 1;
+
+ fdsn = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *) malloc(fdsn);
+ if (!fds) {
+ kill(m_state.pid, SIGTERM);
+ log_fatal("monitor_loop: malloc (%u) failed", fdsn);
+ return;
+ }
+ /* If the child dies, we should shutdown also. */
+ signal(SIGCHLD, monitor_got_sigchld);
+
+ /* SIGHUP, SIGUSR1 and SIGUSR2 will be forwarded to child. */
+ signal(SIGHUP, sig_pass_to_chld);
+ signal(SIGUSR1, sig_pass_to_chld);
+ signal(SIGUSR2, sig_pass_to_chld);
+
+ while (cur_state < STATE_QUIT) {
+ /*
+ * Currently, there is no need for us to hang around if the child
+ * is in the process of shutting down.
+ */
+ if (sigtermed || sigchlded) {
+ if (sigtermed)
+ kill(m_state.pid, SIGTERM);
+
+ if (sigchlded) {
+ do {
+ pid = waitpid(m_state.pid, &n, WNOHANG);
+ }
+ while (pid == -1 && errno == EINTR);
+
+ if (pid == m_state.pid && (WIFEXITED(n) ||
+ WIFSIGNALED(n)))
+ m_priv_increase_state(STATE_QUIT);
+ }
+ break;
}
- while (pid == -1 && errno == EINTR);
+ if (monitor_sighupped) {
+ kill(m_state.pid, SIGHUP);
+ monitor_sighupped = 0;
+ }
+ memset(fds, 0, fdsn);
+ FD_SET(m_state.s, fds);
+
+ n = select(maxfd, fds, NULL, NULL, NULL);
+ if (n == -1) {
+ if (errno != EINTR) {
+ log_error("select");
+ sleep(1);
+ }
+ } else if (n)
+ if (FD_ISSET(m_state.s, fds)) {
+ int32_t msgcode;
+ if (m_read_int32(m_state.s, &msgcode))
+ m_flush(m_state.s);
+ else
+ switch (msgcode) {
+ case MONITOR_GET_FD:
+ m_priv_getfd(m_state.s);
+ break;
+
+ case MONITOR_GET_SOCKET:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_GET_SOCKET", __func__));
+ m_priv_test_state(STATE_INIT);
+ m_priv_getsocket(m_state.s);
+ break;
+
+ case MONITOR_SETSOCKOPT:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_SETSOCKOPT", __func__));
+ m_priv_test_state(STATE_INIT);
+ m_priv_setsockopt(m_state.s);
+ break;
+
+ case MONITOR_BIND:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_BIND", __func__));
+ m_priv_test_state(STATE_INIT);
+ m_priv_bind(m_state.s);
+ break;
+
+ case MONITOR_MKFIFO:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_MKFIFO", __func__));
+ m_priv_test_state(STATE_INIT);
+ m_priv_mkfifo(m_state.s);
+ break;
+
+ case MONITOR_INIT_DONE:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_INIT_DONE", __func__));
+ m_priv_test_state(STATE_INIT);
+ m_priv_increase_state(STATE_RUNNING);
+ break;
+
+ case MONITOR_SHUTDOWN:
+ LOG_DBG((LOG_MISC, 80, "%s: MONITOR_SHUTDOWN", __func__));
+ m_priv_increase_state(STATE_QUIT);
+ break;
+
+ default:
+ log_print("monitor_loop: got unknown code %d", msgcode);
+ }
+ }
+ }
- if (pid == m_state.pid && (WIFEXITED (n) || WIFSIGNALED (n)))
- m_priv_increase_state (STATE_QUIT);
- }
+ free(fds);
+ exit(0);
+}
- break;
+/* Privileged: called by monitor_loop. */
+static void
+m_priv_getfd(int s)
+{
+ char path[MAXPATHLEN];
+ int32_t v, err;
+ int flags;
+ mode_t mode;
+
+ /*
+ * We expect the following data on the socket:
+ * u_int32_t pathlen
+ * <variable> path
+ * u_int32_t flags
+ * u_int32_t mode
+ */
+
+ if (m_read_raw(s, path, MAXPATHLEN))
+ goto errout;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ flags = (int) v;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ mode = (mode_t) v;
+
+ if (m_priv_local_sanitize_path(path, sizeof path, flags) != 0) {
+ err = EACCES;
+ v = -1;
+ } else {
+ err = 0;
+ v = (int32_t) open(path, flags, mode);
+ if (v < 0)
+ err = (int32_t) errno;
}
- if (monitor_sighupped)
- {
- kill (m_state.pid, SIGHUP);
- monitor_sighupped = 0;
- }
+ if (m_write_int32(s, err))
+ goto errout;
- memset (fds, 0, fdsn);
- FD_SET (m_state.s, fds);
-
- n = select (maxfd, fds, NULL, NULL, NULL);
- if (n == -1)
- {
- if (errno != EINTR)
- {
- log_error ("select");
- sleep (1);
- }
+ if (v > 0 && mm_send_fd(s, v)) {
+ close(v);
+ goto errout;
}
- else if (n)
- if (FD_ISSET (m_state.s, fds))
- {
- int32_t msgcode;
- if (m_read_int32 (m_state.s, &msgcode))
- m_flush (m_state.s);
- else
- switch (msgcode)
- {
- case MONITOR_GET_FD:
- m_priv_getfd (m_state.s);
- break;
-
- case MONITOR_GET_SOCKET:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_GET_SOCKET", __func__));
- m_priv_test_state (STATE_INIT);
- m_priv_getsocket (m_state.s);
- break;
-
- case MONITOR_SETSOCKOPT:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_SETSOCKOPT", __func__));
- m_priv_test_state (STATE_INIT);
- m_priv_setsockopt (m_state.s);
- break;
-
- case MONITOR_BIND:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_BIND", __func__));
- m_priv_test_state (STATE_INIT);
- m_priv_bind (m_state.s);
- break;
-
- case MONITOR_MKFIFO:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_MKFIFO", __func__));
- m_priv_test_state (STATE_INIT);
- m_priv_mkfifo (m_state.s);
- break;
-
- case MONITOR_INIT_DONE:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_INIT_DONE", __func__));
- m_priv_test_state (STATE_INIT);
- m_priv_increase_state (STATE_RUNNING);
- break;
-
- case MONITOR_SHUTDOWN:
- LOG_DBG ((LOG_MISC, 80, "%s: MONITOR_SHUTDOWN", __func__));
- m_priv_increase_state (STATE_QUIT);
- break;
-
- default:
- log_print ("monitor_loop: got unknown code %d", msgcode);
- }
- }
- }
+ close(v);
+ return;
- free (fds);
- exit (0);
+errout:
+ log_error("m_priv_getfd: read/write operation failed");
+ return;
}
/* Privileged: called by monitor_loop. */
static void
-m_priv_getfd (int s)
+m_priv_getsocket(int s)
{
- char path[MAXPATHLEN];
- int32_t v, err;
- int flags;
- mode_t mode;
-
- /*
- * We expect the following data on the socket:
- * u_int32_t pathlen
- * <variable> path
- * u_int32_t flags
- * u_int32_t mode
- */
-
- if (m_read_raw (s, path, MAXPATHLEN))
- goto errout;
-
- if (m_read_int32 (s, &v))
- goto errout;
- flags = (int)v;
-
- if (m_read_int32 (s, &v))
- goto errout;
- mode = (mode_t)v;
-
- if (m_priv_local_sanitize_path (path, sizeof path, flags) != 0)
- {
- err = EACCES;
- v = -1;
- }
- else
- {
- err = 0;
- v = (int32_t)open (path, flags, mode);
- if (v < 0)
- err = (int32_t)errno;
- }
-
- if (m_write_int32 (s, err))
- goto errout;
-
- if (v > 0 && mm_send_fd (s, v))
- {
- close (v);
- goto errout;
- }
- close (v);
- return;
-
- errout:
- log_error ("m_priv_getfd: read/write operation failed");
- return;
-}
+ int domain, type, protocol;
+ int32_t v, err;
-/* Privileged: called by monitor_loop. */
-static void
-m_priv_getsocket (int s)
-{
- int domain, type, protocol;
- int32_t v, err;
-
- if (m_read_int32 (s, &v))
- goto errout;
- domain = (int)v;
-
- if (m_read_int32 (s, &v))
- goto errout;
- type = (int)v;
-
- if (m_read_int32 (s, &v))
- goto errout;
- protocol = (int)v;
-
- err = 0;
- v = (int32_t)socket (domain, type, protocol);
- if (v < 0)
- err = (int32_t)errno;
-
- if (m_write_int32 (s, err))
- goto errout;
-
- if (v > 0 && mm_send_fd (s, v))
- {
- close (v);
- goto errout;
- }
- close (v);
- return;
-
- errout:
- log_error ("m_priv_getsocket: read/write operation failed");
- return;
+ if (m_read_int32(s, &v))
+ goto errout;
+ domain = (int) v;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ type = (int) v;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ protocol = (int) v;
+
+ err = 0;
+ v = (int32_t) socket(domain, type, protocol);
+ if (v < 0)
+ err = (int32_t) errno;
+
+ if (m_write_int32(s, err))
+ goto errout;
+
+ if (v > 0 && mm_send_fd(s, v)) {
+ close(v);
+ goto errout;
+ }
+ close(v);
+ return;
+
+errout:
+ log_error("m_priv_getsocket: read/write operation failed");
+ return;
}
/* Privileged: called by monitor_loop. */
static void
-m_priv_setsockopt (int s)
+m_priv_setsockopt(int s)
{
- int sock, level, optname;
- char *optval = 0;
- socklen_t optlen;
- int32_t v, err;
-
- sock = mm_receive_fd (s);
- if (sock < 0)
- goto errout;
-
- if (m_read_int32 (s, &level))
- goto errout;
-
- if (m_read_int32 (s, &optname))
- goto errout;
-
- if (m_read_int32 (s, &optlen))
- goto errout;
-
- optval = (char *)malloc (optlen);
- if (!optval)
- goto errout;
-
- if (m_read_raw (s, optval, optlen))
- goto errout;
-
- if (m_priv_check_sockopt (level, optname) != 0)
- {
- err = EACCES;
- v = -1;
- }
- else
- {
- err = 0;
- v = (int32_t) setsockopt (sock, level, optname, optval, optlen);
- if (v < 0)
- err = (int32_t)errno;
- }
-
- close (sock);
- sock = -1;
-
- if (m_write_int32 (s, err))
- goto errout;
-
- if (m_write_int32 (s, v))
- goto errout;
-
- free (optval);
- return;
-
- errout:
- log_print ("m_priv_setsockopt: read/write error");
- if (optval)
- free (optval);
- if (sock >= 0)
- close (sock);
- return;
+ int sock, level, optname;
+ char *optval = 0;
+ socklen_t optlen;
+ int32_t v, err;
+
+ sock = mm_receive_fd(s);
+ if (sock < 0)
+ goto errout;
+
+ if (m_read_int32(s, &level))
+ goto errout;
+
+ if (m_read_int32(s, &optname))
+ goto errout;
+
+ if (m_read_int32(s, &optlen))
+ goto errout;
+
+ optval = (char *) malloc(optlen);
+ if (!optval)
+ goto errout;
+
+ if (m_read_raw(s, optval, optlen))
+ goto errout;
+
+ if (m_priv_check_sockopt(level, optname) != 0) {
+ err = EACCES;
+ v = -1;
+ } else {
+ err = 0;
+ v = (int32_t) setsockopt(sock, level, optname, optval, optlen);
+ if (v < 0)
+ err = (int32_t) errno;
+ }
+
+ close(sock);
+ sock = -1;
+
+ if (m_write_int32(s, err))
+ goto errout;
+
+ if (m_write_int32(s, v))
+ goto errout;
+
+ free(optval);
+ return;
+
+errout:
+ log_print("m_priv_setsockopt: read/write error");
+ if (optval)
+ free(optval);
+ if (sock >= 0)
+ close(sock);
+ return;
}
/* Privileged: called by monitor_loop. */
static void
-m_priv_bind (int s)
+m_priv_bind(int s)
{
- int sock;
- struct sockaddr *name = 0;
- socklen_t namelen;
- int32_t v, err;
-
- sock = mm_receive_fd (s);
- if (sock < 0)
- goto errout;
-
- if (m_read_int32 (s, &v))
- goto errout;
- namelen = (socklen_t)v;
-
- name = (struct sockaddr *)malloc (namelen);
- if (!name)
- goto errout;
-
- if (m_read_raw (s, (char *)name, (size_t)namelen))
- goto errout;
-
- if (m_priv_check_bind (name, namelen) != 0)
- {
- err = EACCES;
- v = -1;
- }
- else
- {
- err = 0;
- v = (int32_t)bind (sock, name, namelen);
- if (v < 0)
- {
- log_error ("m_priv_bind: bind(%d,%p,%d) returned %d",
- sock, name, namelen, v);
- err = (int32_t)errno;
- }
- }
-
- close (sock);
- sock = -1;
-
- if (m_write_int32 (s, err))
- goto errout;
-
- if (m_write_int32 (s, v))
- goto errout;
-
- free (name);
- return;
-
- errout:
- log_print ("m_priv_bind: read/write error");
- if (name)
- free (name);
- if (sock >= 0)
- close (sock);
- return;
+ int sock;
+ struct sockaddr *name = 0;
+ socklen_t namelen;
+ int32_t v, err;
+
+ sock = mm_receive_fd(s);
+ if (sock < 0)
+ goto errout;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ namelen = (socklen_t) v;
+
+ name = (struct sockaddr *) malloc(namelen);
+ if (!name)
+ goto errout;
+
+ if (m_read_raw(s, (char *) name, (size_t) namelen))
+ goto errout;
+
+ if (m_priv_check_bind(name, namelen) != 0) {
+ err = EACCES;
+ v = -1;
+ } else {
+ err = 0;
+ v = (int32_t) bind(sock, name, namelen);
+ if (v < 0) {
+ log_error("m_priv_bind: bind(%d,%p,%d) returned %d",
+ sock, name, namelen, v);
+ err = (int32_t) errno;
+ }
+ }
+
+ close(sock);
+ sock = -1;
+
+ if (m_write_int32(s, err))
+ goto errout;
+
+ if (m_write_int32(s, v))
+ goto errout;
+
+ free(name);
+ return;
+
+errout:
+ log_print("m_priv_bind: read/write error");
+ if (name)
+ free(name);
+ if (sock >= 0)
+ close(sock);
+ return;
}
/* Privileged: called by monitor_loop. */
static void
-m_priv_mkfifo (int s)
+m_priv_mkfifo(int s)
{
- char path[MAXPATHLEN];
- mode_t mode;
- int32_t v, err;
-
- if (m_read_raw (s, path, MAXPATHLEN))
- goto errout;
-
- if (m_read_int32 (s, &v))
- goto errout;
- mode = (mode_t)v;
-
- /*
- * ui_fifo is set before creation of the unpriv'ed child. So path should
- * exactly match ui_fifo. It's also restricted to /var/run.
- */
- if (m_priv_local_sanitize_path (path, sizeof path, O_RDWR) != 0 ||
- strncmp (ui_fifo, path, strlen (ui_fifo)))
- {
- err = EACCES;
- v = -1;
- }
- else
- {
- unlink (path); /* XXX See ui.c:ui_init() */
-
- err = 0;
- v = (int32_t)mkfifo (path, mode);
- if (v)
- {
- log_error ("m_priv_mkfifo: mkfifo(\"%s\", %o) failed", path, mode);
- err = (int32_t)errno;
+ char path[MAXPATHLEN];
+ mode_t mode;
+ int32_t v, err;
+
+ if (m_read_raw(s, path, MAXPATHLEN))
+ goto errout;
+
+ if (m_read_int32(s, &v))
+ goto errout;
+ mode = (mode_t) v;
+
+ /*
+ * ui_fifo is set before creation of the unpriv'ed child. So path
+ * should exactly match ui_fifo. It's also restricted to /var/run.
+ */
+ if (m_priv_local_sanitize_path(path, sizeof path, O_RDWR) != 0 ||
+ strncmp(ui_fifo, path, strlen(ui_fifo))) {
+ err = EACCES;
+ v = -1;
+ } else {
+ unlink(path); /* XXX See ui.c:ui_init() */
+
+ err = 0;
+ v = (int32_t) mkfifo(path, mode);
+ if (v) {
+ log_error("m_priv_mkfifo: mkfifo(\"%s\", %o) failed", path, mode);
+ err = (int32_t) errno;
+ }
}
- }
- if (m_write_int32 (s, err))
- goto errout;
+ if (m_write_int32(s, err))
+ goto errout;
- if (m_write_int32 (s, v))
- goto errout;
+ if (m_write_int32(s, v))
+ goto errout;
- return;
+ return;
- errout:
- log_print ("m_priv_mkfifo: read/write error");
- return;
+errout:
+ log_print("m_priv_mkfifo: read/write error");
+ return;
}
/*
@@ -947,206 +889,193 @@ m_priv_mkfifo (int s)
/* Write a 32-bit value to a socket. */
int
-m_write_int32 (int s, int32_t value)
+m_write_int32(int s, int32_t value)
{
- u_int32_t v;
- memcpy (&v, &value, sizeof v);
- return (write (s, &v, sizeof v) == -1);
+ u_int32_t v;
+ memcpy(&v, &value, sizeof v);
+ return (write(s, &v, sizeof v) == -1);
}
/* Write a number of bytes of data to a socket. */
int
-m_write_raw (int s, char *data, size_t dlen)
+m_write_raw(int s, char *data, size_t dlen)
{
- if (m_write_int32 (s, (int32_t)dlen))
- return 1;
- return (write (s, data, dlen) == -1);
+ if (m_write_int32(s, (int32_t) dlen))
+ return 1;
+ return (write(s, data, dlen) == -1);
}
int
-m_read_int32 (int s, int32_t *value)
+m_read_int32(int s, int32_t *value)
{
- u_int32_t v;
- if (read (s, &v, sizeof v) != sizeof v)
- return 1;
- memcpy (value, &v, sizeof v);
- return 0;
+ u_int32_t v;
+ if (read(s, &v, sizeof v) != sizeof v)
+ return 1;
+ memcpy(value, &v, sizeof v);
+ return 0;
}
int
-m_read_raw (int s, char *data, size_t maxlen)
+m_read_raw(int s, char *data, size_t maxlen)
{
- u_int32_t v;
- int r;
- if (m_read_int32 (s, &v))
- return 1;
- if (v > maxlen)
- return 1;
- r = read (s, data, v);
- return (r == -1);
+ u_int32_t v;
+ int r;
+ if (m_read_int32(s, &v))
+ return 1;
+ if (v > maxlen)
+ return 1;
+ r = read(s, data, v);
+ return (r == -1);
}
/* Drain all available input on a socket. */
void
-m_flush (int s)
+m_flush(int s)
{
- u_int8_t tmp;
- int one = 1;
+ u_int8_t tmp;
+ int one = 1;
- ioctl (s, FIONBIO, &one); /* Non-blocking */
- while (read (s, &tmp, 1) > 0) ;
- ioctl (s, FIONBIO, 0); /* Blocking */
+ ioctl(s, FIONBIO, &one);/* Non-blocking */
+ while (read(s, &tmp, 1) > 0);
+ ioctl(s, FIONBIO, 0); /* Blocking */
}
/* Check that path/mode is permitted. */
static int
-m_priv_local_sanitize_path (char *path, size_t pmax, int flags)
+m_priv_local_sanitize_path(char *path, size_t pmax, int flags)
{
- char *p;
-
- /*
- * We only permit paths starting with
- * /etc/isakmpd/ (read only)
- * /var/run/ (rw)
- */
-
- if (strlen (path) < strlen ("/var/run/"))
- goto bad_path;
-
- /* Any path containing '..' is invalid. */
- for (p = path; *p && (p - path) < (int)pmax; p++)
- if (*p == '.' && *(p + 1) == '.')
- goto bad_path;
-
- /* For any write-mode, only a few paths are permitted. */
- if ((flags & O_ACCMODE) != O_RDONLY)
- {
- if (strncmp ("/var/run/", path, strlen ("/var/run/")) == 0)
- return 0;
- goto bad_path;
- }
-
- /* Any other path is read-only. */
- if (strncmp (ISAKMPD_ROOT, path, strlen (ISAKMPD_ROOT)) == 0 ||
- strncmp ("/var/run/", path, strlen ("/var/run/")) == 0)
- return 0;
-
- bad_path:
- log_print ("m_priv_local_sanitize_path: illegal path \"%.1023s\", "
- "replaced with \"/dev/null\"", path);
- strlcpy (path, "/dev/null", pmax);
- return 1;
+ char *p;
+
+ /*
+ * We only permit paths starting with
+ * /etc/isakmpd/ (read only)
+ * /var/run/ (rw)
+ */
+
+ if (strlen(path) < strlen("/var/run/"))
+ goto bad_path;
+
+ /* Any path containing '..' is invalid. */
+ for (p = path; *p && (p - path) < (int) pmax; p++)
+ if (*p == '.' && *(p + 1) == '.')
+ goto bad_path;
+
+ /* For any write-mode, only a few paths are permitted. */
+ if ((flags & O_ACCMODE) != O_RDONLY) {
+ if (strncmp("/var/run/", path, strlen("/var/run/")) == 0)
+ return 0;
+ goto bad_path;
+ }
+ /* Any other path is read-only. */
+ if (strncmp(ISAKMPD_ROOT, path, strlen(ISAKMPD_ROOT)) == 0 ||
+ strncmp("/var/run/", path, strlen("/var/run/")) == 0)
+ return 0;
+
+bad_path:
+ log_print("m_priv_local_sanitize_path: illegal path \"%.1023s\", "
+ "replaced with \"/dev/null\"", path);
+ strlcpy(path, "/dev/null", pmax);
+ return 1;
}
/* Check setsockopt */
static int
-m_priv_check_sockopt (int level, int name)
+m_priv_check_sockopt(int level, int name)
{
- switch (level)
- {
- /* These are allowed */
- case SOL_SOCKET:
- case IPPROTO_IP:
- case IPPROTO_IPV6:
- break;
-
- default:
- log_print ("m_priv_check_sockopt: Illegal level %d", level);
- return 1;
- }
-
- switch (name)
- {
- /* These are allowed */
- case SO_REUSEPORT:
- case SO_REUSEADDR:
- case IP_AUTH_LEVEL:
- case IP_ESP_TRANS_LEVEL:
- case IP_ESP_NETWORK_LEVEL:
- case IP_IPCOMP_LEVEL:
- case IPV6_AUTH_LEVEL:
- case IPV6_ESP_TRANS_LEVEL:
- case IPV6_ESP_NETWORK_LEVEL:
- case IPV6_IPCOMP_LEVEL:
- break;
-
- default:
- log_print ("m_priv_check_sockopt: Illegal option name %d", name);
- return 1;
- }
-
- return 0;
+ switch (level) {
+ /* These are allowed */
+ case SOL_SOCKET:
+ case IPPROTO_IP:
+ case IPPROTO_IPV6:
+ break;
+
+ default:
+ log_print("m_priv_check_sockopt: Illegal level %d", level);
+ return 1;
+ }
+
+ switch (name) {
+ /* These are allowed */
+ case SO_REUSEPORT:
+ case SO_REUSEADDR:
+ case IP_AUTH_LEVEL:
+ case IP_ESP_TRANS_LEVEL:
+ case IP_ESP_NETWORK_LEVEL:
+ case IP_IPCOMP_LEVEL:
+ case IPV6_AUTH_LEVEL:
+ case IPV6_ESP_TRANS_LEVEL:
+ case IPV6_ESP_NETWORK_LEVEL:
+ case IPV6_IPCOMP_LEVEL:
+ break;
+
+ default:
+ log_print("m_priv_check_sockopt: Illegal option name %d", name);
+ return 1;
+ }
+
+ return 0;
}
/* Check bind */
static int
-m_priv_check_bind (const struct sockaddr *sa, socklen_t salen)
+m_priv_check_bind(const struct sockaddr *sa, socklen_t salen)
{
- in_port_t port;
-
- if (sa == NULL)
- {
- log_print ("NULL address");
- return 1;
- }
-
- if (sysdep_sa_len ((struct sockaddr *)sa) != salen)
- {
- log_print ("Length mismatch: %d %d",
- (int) sysdep_sa_len ((struct sockaddr *)sa), (int) salen);
- return 1;
- }
-
- switch (sa->sa_family)
- {
- case AF_INET:
- if (salen != sizeof (struct sockaddr_in))
- {
- log_print ("Invalid inet address length");
- return 1;
- }
- port = ((const struct sockaddr_in *)sa)->sin_port;
- break;
- case AF_INET6:
- if (salen != sizeof (struct sockaddr_in6))
- {
- log_print ("Invalid inet6 address length");
- return 1;
- }
- port = ((const struct sockaddr_in6 *)sa)->sin6_port;
- break;
- default:
- log_print ("Unknown address family");
- return 1;
- }
+ in_port_t port;
- port = ntohs(port);
+ if (sa == NULL) {
+ log_print("NULL address");
+ return 1;
+ }
+ if (sysdep_sa_len((struct sockaddr *) sa) != salen) {
+ log_print("Length mismatch: %d %d",
+ (int) sysdep_sa_len((struct sockaddr *) sa), (int) salen);
+ return 1;
+ }
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (salen != sizeof(struct sockaddr_in)) {
+ log_print("Invalid inet address length");
+ return 1;
+ }
+ port = ((const struct sockaddr_in *) sa)->sin_port;
+ break;
+ case AF_INET6:
+ if (salen != sizeof(struct sockaddr_in6)) {
+ log_print("Invalid inet6 address length");
+ return 1;
+ }
+ port = ((const struct sockaddr_in6 *) sa)->sin6_port;
+ break;
+ default:
+ log_print("Unknown address family");
+ return 1;
+ }
- if (port != ISAKMP_PORT_DEFAULT && port < 1024)
- {
- log_print ("Disallowed port %u", port);
- return 1;
- }
+ port = ntohs(port);
- return 0;
+ if (port != ISAKMP_PORT_DEFAULT && port < 1024) {
+ log_print("Disallowed port %u", port);
+ return 1;
+ }
+ return 0;
}
-
+
/* Increase state into less permissive mode */
static void
-m_priv_increase_state (int state)
+m_priv_increase_state(int state)
{
- if (state <= cur_state)
- log_print ("m_priv_increase_state: attempt to decrase state or match "
- "current state");
- if (state < STATE_INIT || state > STATE_QUIT)
- log_print ("m_priv_increase_state: attempt to switch to invalid state");
- cur_state = state;
+ if (state <= cur_state)
+ log_print("m_priv_increase_state: attempt to decrase state or match "
+ "current state");
+ if (state < STATE_INIT || state > STATE_QUIT)
+ log_print("m_priv_increase_state: attempt to switch to invalid state");
+ cur_state = state;
}
static void
-m_priv_test_state (int state)
+m_priv_test_state(int state)
{
- if (cur_state != state)
- log_print ("m_priv_test_state: Illegal state: %d != %d", cur_state, state);
- return;
+ if (cur_state != state)
+ log_print("m_priv_test_state: Illegal state: %d != %d", cur_state, state);
+ return;
}
diff --git a/sbin/isakmpd/monitor.h b/sbin/isakmpd/monitor.h
index b76af5318ed..2d20f5eb0f0 100644
--- a/sbin/isakmpd/monitor.h
+++ b/sbin/isakmpd/monitor.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.h,v 1.7 2004/03/19 14:04:43 hshoexer Exp $ */
+/* $OpenBSD: monitor.h,v 1.8 2004/04/15 18:39:26 deraadt Exp $ */
/*
* Copyright (c) 2003 Håkan Olsson. All rights reserved.
@@ -38,15 +38,14 @@
#define ISAKMP_PORT_DEFAULT 500
-enum monitor_reqtypes
-{
- MONITOR_GET_FD,
- MONITOR_GET_SOCKET,
- MONITOR_SETSOCKOPT,
- MONITOR_BIND,
- MONITOR_MKFIFO,
- MONITOR_INIT_DONE,
- MONITOR_SHUTDOWN
+enum monitor_reqtypes {
+ MONITOR_GET_FD,
+ MONITOR_GET_SOCKET,
+ MONITOR_SETSOCKOPT,
+ MONITOR_BIND,
+ MONITOR_MKFIFO,
+ MONITOR_INIT_DONE,
+ MONITOR_SHUTDOWN
};
enum priv_state {
@@ -55,31 +54,30 @@ enum priv_state {
STATE_QUIT /* shutting down */
};
-struct monitor_dirents
-{
- int current;
- struct dirent **dirents;
+struct monitor_dirents {
+ int current;
+ struct dirent **dirents;
};
-pid_t monitor_init (void);
-void monitor_loop (int);
+pid_t monitor_init(void);
+void monitor_loop(int);
-int mm_send_fd (int, int);
-int mm_receive_fd (int);
+int mm_send_fd(int, int);
+int mm_receive_fd(int);
-FILE *monitor_fopen (const char *, const char *);
-int monitor_open (const char *, int, mode_t);
-int monitor_stat (const char *, struct stat *);
-int monitor_socket (int, int, int);
-int monitor_setsockopt (int, int, int, const void *, socklen_t);
-int monitor_bind (int, const struct sockaddr *, socklen_t);
-int monitor_mkfifo (const char *, mode_t);
-struct monitor_dirents *monitor_opendir (const char *);
-struct dirent *monitor_readdir (struct monitor_dirents *);
-int monitor_closedir (struct monitor_dirents *);
-void monitor_init_done (void);
+FILE *monitor_fopen(const char *, const char *);
+int monitor_open(const char *, int, mode_t);
+int monitor_stat(const char *, struct stat *);
+int monitor_socket(int, int, int);
+int monitor_setsockopt(int, int, int, const void *, socklen_t);
+int monitor_bind(int, const struct sockaddr *, socklen_t);
+int monitor_mkfifo(const char *, mode_t);
+struct monitor_dirents *monitor_opendir(const char *);
+struct dirent *monitor_readdir(struct monitor_dirents *);
+int monitor_closedir(struct monitor_dirents *);
+void monitor_init_done(void);
-#else /* !USE_PRIVSEP */
+#else /* !USE_PRIVSEP */
#define monitor_fopen fopen
#define monitor_open open
@@ -92,5 +90,5 @@ void monitor_init_done (void);
#define monitor_readdir readdir
#define monitor_closedir closedir
-#endif /* USE_PRIVSEP */
-#endif /* _MONITOR_H_ */
+#endif /* USE_PRIVSEP */
+#endif /* _MONITOR_H_ */
diff --git a/sbin/isakmpd/monitor_fdpass.c b/sbin/isakmpd/monitor_fdpass.c
index 14370205349..0a1e3065c4d 100644
--- a/sbin/isakmpd/monitor_fdpass.c
+++ b/sbin/isakmpd/monitor_fdpass.c
@@ -32,81 +32,73 @@
#include "monitor.h"
int
-mm_send_fd (int socket, int fd)
+mm_send_fd(int socket, int fd)
{
- struct msghdr msg;
- char tmp[CMSG_SPACE (sizeof (int))];
- struct cmsghdr *cmsg;
- struct iovec vec;
- char ch = '\0';
- ssize_t n;
+ struct msghdr msg;
+ char tmp[CMSG_SPACE(sizeof(int))], ch = '\0';
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ ssize_t n;
- memset (&msg, 0, sizeof msg);
- msg.msg_control = (caddr_t)tmp;
- msg.msg_controllen = CMSG_LEN (sizeof (int));
- cmsg = CMSG_FIRSTHDR (&msg);
- cmsg->cmsg_len = CMSG_LEN (sizeof (int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA (cmsg) = fd;
+ memset(&msg, 0, sizeof msg);
+ msg.msg_control = (caddr_t) tmp;
+ msg.msg_controllen = CMSG_LEN(sizeof(int));
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *) CMSG_DATA(cmsg) = fd;
- vec.iov_base = &ch;
- vec.iov_len = 1;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
- if ((n = sendmsg (socket, &msg, 0)) == -1)
- {
- log_error ("%s: sendmsg(%d)", __func__, fd);
- return -1;
- }
- if (n != 1)
- {
- log_error ("%s: sendmsg: expected sent 1 got %ld", __func__, (long)n);
- return -1;
- }
- return 0;
+ if ((n = sendmsg(socket, &msg, 0)) == -1) {
+ log_error("%s: sendmsg(%d)", __func__, fd);
+ return -1;
+ }
+ if (n != 1) {
+ log_error("%s: sendmsg: expected sent 1 got %ld",
+ __func__, (long) n);
+ return -1;
+ }
+ return 0;
}
int
-mm_receive_fd (int socket)
+mm_receive_fd(int socket)
{
- struct msghdr msg;
- char tmp[CMSG_SPACE (sizeof (int))];
- struct cmsghdr *cmsg;
- struct iovec vec;
- ssize_t n;
- char ch;
- int fd;
+ struct msghdr msg;
+ char tmp[CMSG_SPACE(sizeof(int))], ch;
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ ssize_t n;
+ int fd;
- memset (&msg, 0, sizeof msg);
- vec.iov_base = &ch;
- vec.iov_len = 1;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_control = tmp;
- msg.msg_controllen = sizeof tmp;
+ memset(&msg, 0, sizeof msg);
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_control = tmp;
+ msg.msg_controllen = sizeof tmp;
- if ((n = recvmsg (socket, &msg, 0)) == -1)
- {
- log_error ("%s: recvmsg", __func__);
- return -1;
- }
- if (n != 1)
- {
- log_error ("%s: recvmsg: expected received 1 got %ld", __func__,
- (long)n);
- return -1;
- }
-
- cmsg = CMSG_FIRSTHDR (&msg);
- if (cmsg->cmsg_type != SCM_RIGHTS)
- {
- log_error ("%s: expected type %d got %d", __func__, SCM_RIGHTS,
- cmsg->cmsg_type);
- return -1;
- }
- fd = (*(int *)CMSG_DATA (cmsg));
-
- return fd;
+ if ((n = recvmsg(socket, &msg, 0)) == -1) {
+ log_error("%s: recvmsg", __func__);
+ return -1;
+ }
+ if (n != 1) {
+ log_error("%s: recvmsg: expected received 1 got %ld", __func__,
+ (long) n);
+ return -1;
+ }
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg->cmsg_type != SCM_RIGHTS) {
+ log_error("%s: expected type %d got %d", __func__, SCM_RIGHTS,
+ cmsg->cmsg_type);
+ return -1;
+ }
+ fd = (*(int *) CMSG_DATA(cmsg));
+ return fd;
}
diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c
index debe23d2f66..cc243b8d05a 100644
--- a/sbin/isakmpd/pf_key_v2.c
+++ b/sbin/isakmpd/pf_key_v2.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pf_key_v2.c,v 1.139 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */
+/* $OpenBSD: pf_key_v2.c,v 1.140 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -75,10 +75,10 @@
#endif
#define IN6_IS_ADDR_FULL(a) \
- ((*(u_int32_t *)(void *)(&(a)->s6_addr[0]) == 0xffff) \
- && (*(u_int32_t *)(void *)(&(a)->s6_addr[4]) == 0xffff) \
- && (*(u_int32_t *)(void *)(&(a)->s6_addr[8]) == 0xffff) \
- && (*(u_int32_t *)(void *)(&(a)->s6_addr[12]) == 0xffff))
+ ((*(u_int32_t *)(void *)(&(a)->s6_addr[0]) == 0xffff) && \
+ (*(u_int32_t *)(void *)(&(a)->s6_addr[4]) == 0xffff) && \
+ (*(u_int32_t *)(void *)(&(a)->s6_addr[8]) == 0xffff) && \
+ (*(u_int32_t *)(void *)(&(a)->s6_addr[12]) == 0xffff))
#define ADDRESS_MAX sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"
@@ -87,27 +87,27 @@
*/
#define PF_KEY_V2_CHUNK 8
#define PF_KEY_V2_ROUND(x) \
- (((x) + PF_KEY_V2_CHUNK - 1) & ~(PF_KEY_V2_CHUNK - 1))
+ (((x) + PF_KEY_V2_CHUNK - 1) & ~(PF_KEY_V2_CHUNK - 1))
/* How many microseconds we will wait for a reply from the PF_KEY socket. */
#define PF_KEY_REPLY_TIMEOUT 1000
struct pf_key_v2_node {
- TAILQ_ENTRY (pf_key_v2_node) link;
- void *seg;
- size_t sz;
- int cnt;
- u_int16_t type;
- u_int8_t flags;
+ TAILQ_ENTRY(pf_key_v2_node) link;
+ void *seg;
+ size_t sz;
+ int cnt;
+ u_int16_t type;
+ u_int8_t flags;
};
-TAILQ_HEAD (pf_key_v2_msg, pf_key_v2_node);
+TAILQ_HEAD(pf_key_v2_msg, pf_key_v2_node);
#define PF_KEY_V2_NODE_MALLOCED 1
#define PF_KEY_V2_NODE_MARK 2
/* Used to derive "unique" connection identifiers. */
-int connection_seq = 0;
+int connection_seq = 0;
#ifdef KAME
/*
@@ -115,159 +115,158 @@ int connection_seq = 0;
* GETSPI creating the larval SA.
*/
struct pf_key_v2_sa_seq {
- TAILQ_ENTRY (pf_key_v2_sa_seq) link;
- u_int8_t *spi;
- size_t sz;
- u_int8_t proto;
- struct sockaddr *dst;
- int dstlen;
- u_int32_t seq;
+ TAILQ_ENTRY(pf_key_v2_sa_seq) link;
+ u_int8_t *spi;
+ size_t sz;
+ u_int8_t proto;
+ struct sockaddr *dst;
+ int dstlen;
+ u_int32_t seq;
};
-TAILQ_HEAD (, pf_key_v2_sa_seq) pf_key_v2_sa_seq_map;
+TAILQ_HEAD(, pf_key_v2_sa_seq) pf_key_v2_sa_seq_map;
#endif
#ifndef KAME
-static u_int8_t *pf_key_v2_convert_id (u_int8_t *, int, size_t *, int *);
-#endif
-static struct pf_key_v2_msg *pf_key_v2_call (struct pf_key_v2_msg *);
-static struct pf_key_v2_node *pf_key_v2_find_ext (struct pf_key_v2_msg *,
- u_int16_t);
-static void pf_key_v2_notify (struct pf_key_v2_msg *);
-static struct pf_key_v2_msg *pf_key_v2_read (u_int32_t);
-static u_int32_t pf_key_v2_seq (void);
-static u_int32_t pf_key_v2_write (struct pf_key_v2_msg *);
-static int pf_key_v2_remove_conf (char *);
-static int pf_key_v2_conf_refhandle (int, char *);
+static u_int8_t *pf_key_v2_convert_id(u_int8_t *, int, size_t *, int *);
+#endif
+static struct pf_key_v2_msg *pf_key_v2_call(struct pf_key_v2_msg *);
+static struct pf_key_v2_node *pf_key_v2_find_ext(struct pf_key_v2_msg *,
+ u_int16_t);
+static void pf_key_v2_notify(struct pf_key_v2_msg *);
+static struct pf_key_v2_msg *pf_key_v2_read(u_int32_t);
+static u_int32_t pf_key_v2_seq(void);
+static u_int32_t pf_key_v2_write(struct pf_key_v2_msg *);
+static int pf_key_v2_remove_conf(char *);
+static int pf_key_v2_conf_refhandle(int, char *);
#ifdef SADB_X_ASKPOLICY
-static int pf_key_v2_conf_refinc (int, char *);
+static int pf_key_v2_conf_refinc(int, char *);
#endif
/* The socket to use for PF_KEY interactions. */
-static int pf_key_v2_socket;
+static int pf_key_v2_socket;
#ifdef KAME
static int
-pf_key_v2_register_sa_seq (u_int8_t *spi, size_t sz, u_int8_t proto,
- struct sockaddr *dst, int dstlen, u_int32_t seq)
+pf_key_v2_register_sa_seq(u_int8_t *spi, size_t sz, u_int8_t proto,
+ struct sockaddr *dst, int dstlen, u_int32_t seq)
{
- struct pf_key_v2_sa_seq *node = 0;
-
- node = malloc (sizeof *node);
- if (!node)
- goto cleanup;
- memset (node, '0', sizeof *node);
- node->spi = malloc (sz);
- if (!node->spi)
- goto cleanup;
- node->dst = malloc (sysdep_sa_len (dst));
- if (!node->dst)
- goto cleanup;
- memcpy (node->dst, dst, sysdep_sa_len (dst));
- node->dstlen = sysdep_sa_len (dst);
- memcpy (node->spi, spi, sz);
- node->sz = sz;
- node->proto = proto;
- node->seq = seq;
- TAILQ_INSERT_TAIL (&pf_key_v2_sa_seq_map, node, link);
- return 1;
-
- cleanup:
- if (node->dst)
- free (node->dst);
- if (node)
- free (node);
- return 0;
+ struct pf_key_v2_sa_seq *node = 0;
+
+ node = malloc(sizeof *node);
+ if (!node)
+ goto cleanup;
+ memset(node, '0', sizeof *node);
+ node->spi = malloc(sz);
+ if (!node->spi)
+ goto cleanup;
+ node->dst = malloc(sysdep_sa_len(dst));
+ if (!node->dst)
+ goto cleanup;
+ memcpy(node->dst, dst, sysdep_sa_len(dst));
+ node->dstlen = sysdep_sa_len(dst);
+ memcpy(node->spi, spi, sz);
+ node->sz = sz;
+ node->proto = proto;
+ node->seq = seq;
+ TAILQ_INSERT_TAIL(&pf_key_v2_sa_seq_map, node, link);
+ return 1;
+
+cleanup:
+ if (node->dst)
+ free(node->dst);
+ if (node)
+ free(node);
+ return 0;
}
static u_int32_t
-pf_key_v2_seq_by_sa (u_int8_t *spi, size_t sz, u_int8_t proto,
- struct sockaddr *dst, int dstlen)
+pf_key_v2_seq_by_sa(u_int8_t *spi, size_t sz, u_int8_t proto,
+ struct sockaddr *dst, int dstlen)
{
- struct pf_key_v2_sa_seq *node;
-
- for (node = TAILQ_FIRST (&pf_key_v2_sa_seq_map); node;
- node = TAILQ_NEXT (node, link))
- if (node->proto == proto
- && node->sz == sz && memcmp (node->spi, spi, sz) == 0
- && node->dstlen == sysdep_sa_len (dst)
- && memcmp (node->dst, dst, sysdep_sa_len (dst)) == 0)
- return node->seq;
- return 0;
+ struct pf_key_v2_sa_seq *node;
+
+ for (node = TAILQ_FIRST(&pf_key_v2_sa_seq_map); node;
+ node = TAILQ_NEXT(node, link))
+ if (node->proto == proto &&
+ node->sz == sz && memcmp(node->spi, spi, sz) == 0 &&
+ node->dstlen == sysdep_sa_len(dst) &&
+ memcmp(node->dst, dst, sysdep_sa_len(dst)) == 0)
+ return node->seq;
+ return 0;
}
#endif
static struct pf_key_v2_msg *
-pf_key_v2_msg_new (struct sadb_msg *msg, int flags)
+pf_key_v2_msg_new(struct sadb_msg *msg, int flags)
{
- struct pf_key_v2_node *node = 0;
- struct pf_key_v2_msg *ret;
-
- node = malloc (sizeof *node);
- if (!node)
- goto cleanup;
- ret = malloc (sizeof *ret);
- if (!ret)
- goto cleanup;
- TAILQ_INIT (ret);
- node->seg = msg;
- node->sz = sizeof *msg;
- node->type = 0;
- node->cnt = 1;
- node->flags = flags;
- TAILQ_INSERT_HEAD (ret, node, link);
- return ret;
-
- cleanup:
- if (node)
- free (node);
- return 0;
+ struct pf_key_v2_node *node = 0;
+ struct pf_key_v2_msg *ret;
+
+ node = malloc(sizeof *node);
+ if (!node)
+ goto cleanup;
+ ret = malloc(sizeof *ret);
+ if (!ret)
+ goto cleanup;
+ TAILQ_INIT(ret);
+ node->seg = msg;
+ node->sz = sizeof *msg;
+ node->type = 0;
+ node->cnt = 1;
+ node->flags = flags;
+ TAILQ_INSERT_HEAD(ret, node, link);
+ return ret;
+
+cleanup:
+ if (node)
+ free(node);
+ return 0;
}
/* Add a SZ sized segment SEG to the PF_KEY message MSG. */
static int
-pf_key_v2_msg_add (struct pf_key_v2_msg *msg, struct sadb_ext *ext, int flags)
+pf_key_v2_msg_add(struct pf_key_v2_msg *msg, struct sadb_ext *ext, int flags)
{
- struct pf_key_v2_node *node;
-
- node = malloc (sizeof *node);
- if (!node)
- return -1;
- node->seg = ext;
- node->sz = ext->sadb_ext_len * PF_KEY_V2_CHUNK;
- node->type = ext->sadb_ext_type;
- node->flags = flags;
- TAILQ_FIRST (msg)->cnt++;
- TAILQ_INSERT_TAIL (msg, node, link);
- return 0;
+ struct pf_key_v2_node *node;
+
+ node = malloc(sizeof *node);
+ if (!node)
+ return -1;
+ node->seg = ext;
+ node->sz = ext->sadb_ext_len * PF_KEY_V2_CHUNK;
+ node->type = ext->sadb_ext_type;
+ node->flags = flags;
+ TAILQ_FIRST(msg)->cnt++;
+ TAILQ_INSERT_TAIL(msg, node, link);
+ return 0;
}
/* Deallocate the PF_KEY message MSG. */
static void
-pf_key_v2_msg_free (struct pf_key_v2_msg *msg)
+pf_key_v2_msg_free(struct pf_key_v2_msg *msg)
{
- struct pf_key_v2_node *np;
-
- np = TAILQ_FIRST (msg);
- while (np)
- {
- TAILQ_REMOVE (msg, np, link);
- if (np->flags & PF_KEY_V2_NODE_MALLOCED)
- free (np->seg);
- free (np);
- np = TAILQ_FIRST (msg);
- }
- free (msg);
+ struct pf_key_v2_node *np;
+
+ np = TAILQ_FIRST(msg);
+ while (np) {
+ TAILQ_REMOVE(msg, np, link);
+ if (np->flags & PF_KEY_V2_NODE_MALLOCED)
+ free(np->seg);
+ free(np);
+ np = TAILQ_FIRST(msg);
+ }
+ free(msg);
}
/* Just return a new sequence number. */
static u_int32_t
-pf_key_v2_seq (void)
+pf_key_v2_seq(void)
{
- static u_int32_t seq = 0;
+ static u_int32_t seq = 0;
- return ++seq;
+ return ++seq;
}
/*
@@ -276,221 +275,201 @@ pf_key_v2_seq (void)
* messages up until both the PID and the sequence number match.
*/
static struct pf_key_v2_msg *
-pf_key_v2_read (u_int32_t seq)
+pf_key_v2_read(u_int32_t seq)
{
- ssize_t n;
- u_int8_t *buf = 0;
- struct pf_key_v2_msg *ret = 0;
- struct sadb_msg *msg;
- struct sadb_msg hdr;
- struct sadb_ext *ext;
- struct timeval tv;
- fd_set *fds;
-
- while (1)
- {
- /*
- * If this is a read of a reply we should actually expect the reply to
- * get lost as PF_KEY is an unreliable service per the specs.
- * Currently we do this by setting a short timeout, and if it is not
- * readable in that time, we fail the read.
- */
- if (seq)
- {
- fds = calloc (howmany (pf_key_v2_socket + 1, NFDBITS),
- sizeof (fd_mask));
- if (!fds)
- {
- log_error ("pf_key_v2_read: calloc (%lu, %lu) failed",
- (unsigned long)howmany (pf_key_v2_socket + 1,
- NFDBITS),
- (unsigned long)sizeof (fd_mask));
- goto cleanup;
- }
- FD_SET (pf_key_v2_socket, fds);
- tv.tv_sec = 0;
- tv.tv_usec = PF_KEY_REPLY_TIMEOUT;
- n = select (pf_key_v2_socket + 1, fds, 0, 0, &tv);
- free (fds);
- if (n == -1)
- {
- log_error ("pf_key_v2_read: select (%d, fds, 0, 0, &tv) failed",
- pf_key_v2_socket + 1);
- goto cleanup;
- }
- if (!n)
- {
- log_print ("pf_key_v2_read: no reply from PF_KEY");
- goto cleanup;
- }
- }
- n = recv (pf_key_v2_socket, &hdr, sizeof hdr, MSG_PEEK);
- if (n == -1)
- {
- log_error ("pf_key_v2_read: recv (%d, ...) failed",
- pf_key_v2_socket);
- goto cleanup;
- }
- if (n != sizeof hdr)
- {
- log_error ("pf_key_v2_read: recv (%d, ...) returned short packet "
- "(%lu bytes)", pf_key_v2_socket, (unsigned long)n);
- goto cleanup;
+ ssize_t n;
+ u_int8_t *buf = 0;
+ struct pf_key_v2_msg *ret = 0;
+ struct sadb_msg *msg;
+ struct sadb_msg hdr;
+ struct sadb_ext *ext;
+ struct timeval tv;
+ fd_set *fds;
+
+ while (1) {
+ /*
+ * If this is a read of a reply we should actually expect the reply to
+ * get lost as PF_KEY is an unreliable service per the specs.
+ * Currently we do this by setting a short timeout, and if it is not
+ * readable in that time, we fail the read.
+ */
+ if (seq) {
+ fds = calloc(howmany(pf_key_v2_socket + 1, NFDBITS),
+ sizeof(fd_mask));
+ if (!fds) {
+ log_error("pf_key_v2_read: calloc (%lu, %lu) failed",
+ (unsigned long) howmany(pf_key_v2_socket + 1,
+ NFDBITS),
+ (unsigned long) sizeof(fd_mask));
+ goto cleanup;
+ }
+ FD_SET(pf_key_v2_socket, fds);
+ tv.tv_sec = 0;
+ tv.tv_usec = PF_KEY_REPLY_TIMEOUT;
+ n = select(pf_key_v2_socket + 1, fds, 0, 0, &tv);
+ free(fds);
+ if (n == -1) {
+ log_error("pf_key_v2_read: select (%d, fds, 0, "
+ "0, &tv) failed",
+ pf_key_v2_socket + 1);
+ goto cleanup;
+ }
+ if (!n) {
+ log_print("pf_key_v2_read: no reply from PF_KEY");
+ goto cleanup;
+ }
+ }
+ n = recv(pf_key_v2_socket, &hdr, sizeof hdr, MSG_PEEK);
+ if (n == -1) {
+ log_error("pf_key_v2_read: recv (%d, ...) failed",
+ pf_key_v2_socket);
+ goto cleanup;
+ }
+ if (n != sizeof hdr) {
+ log_error("pf_key_v2_read: recv (%d, ...) "
+ "returned short packet (%lu bytes)",
+ pf_key_v2_socket, (unsigned long) n);
+ goto cleanup;
+ }
+ n = hdr.sadb_msg_len * PF_KEY_V2_CHUNK;
+ buf = malloc(n);
+ if (!buf) {
+ log_error("pf_key_v2_read: malloc (%lu) failed",
+ (unsigned long) n);
+ goto cleanup;
+ }
+ n = read(pf_key_v2_socket, buf, n);
+ if (n == -1) {
+ log_error("pf_key_v2_read: read (%d, ...) failed",
+ pf_key_v2_socket);
+ goto cleanup;
+ }
+ if (n != hdr.sadb_msg_len * PF_KEY_V2_CHUNK) {
+ log_print("pf_key_v2_read: read (%d, ...) "
+ "returned short packet (%lu bytes)",
+ pf_key_v2_socket, (unsigned long) n);
+ goto cleanup;
+ }
+ LOG_DBG_BUF((LOG_SYSDEP, 80, "pf_key_v2_read: msg", buf, n));
+
+ /* We drop all messages that is not what we expect. */
+ msg = (struct sadb_msg *) buf;
+ if (msg->sadb_msg_version != PF_KEY_V2 ||
+ (msg->sadb_msg_pid != 0 &&
+ msg->sadb_msg_pid != (u_int32_t) getpid())) {
+ if (seq) {
+ free(buf);
+ buf = 0;
+ continue;
+ } else {
+ LOG_DBG((LOG_SYSDEP, 90,
+ "pf_key_v2_read:"
+ "bad version (%d) or PID (%d, mine is %ld), ignored",
+ msg->sadb_msg_version, msg->sadb_msg_pid,
+ (long) getpid()));
+ goto cleanup;
+ }
+ }
+ /* Parse the message. */
+ ret = pf_key_v2_msg_new(msg, PF_KEY_V2_NODE_MALLOCED);
+ if (!ret)
+ goto cleanup;
+ buf = 0;
+ for (ext = (struct sadb_ext *) (msg + 1);
+ (u_int8_t *) ext - (u_int8_t *) msg <
+ msg->sadb_msg_len * PF_KEY_V2_CHUNK;
+ ext = (struct sadb_ext *) ((u_int8_t *) ext +
+ ext->sadb_ext_len * PF_KEY_V2_CHUNK))
+ pf_key_v2_msg_add(ret, ext, 0);
+
+ /*
+ * If the message is not the one we are waiting for, queue it
+ * up.
+ */
+ if (seq && (msg->sadb_msg_pid != (u_int32_t) getpid() ||
+ msg->sadb_msg_seq != seq)) {
+ gettimeofday(&tv, 0);
+ timer_add_event("pf_key_v2_notify",
+ (void (*) (void *)) pf_key_v2_notify, ret, &tv);
+ ret = 0;
+ continue;
+ }
+ return ret;
}
- n = hdr.sadb_msg_len * PF_KEY_V2_CHUNK;
- buf = malloc (n);
- if (!buf)
- {
- log_error ("pf_key_v2_read: malloc (%lu) failed", (unsigned long)n);
- goto cleanup;
- }
+cleanup:
+ if (buf)
+ free(buf);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return 0;
+}
- n = read (pf_key_v2_socket, buf, n);
- if (n == -1)
- {
- log_error ("pf_key_v2_read: read (%d, ...) failed",
- pf_key_v2_socket);
- goto cleanup;
+/* Write the message in PMSG to the PF_KEY socket. */
+u_int32_t
+pf_key_v2_write(struct pf_key_v2_msg *pmsg)
+{
+ struct iovec *iov = 0;
+ ssize_t n;
+ size_t len;
+ int i, cnt = TAILQ_FIRST(pmsg)->cnt;
+ char header[80];
+ struct sadb_msg *msg = TAILQ_FIRST(pmsg)->seg;
+ struct pf_key_v2_node *np = TAILQ_FIRST(pmsg);
+
+ iov = (struct iovec *) malloc(cnt * sizeof *iov);
+ if (!iov) {
+ log_error("pf_key_v2_write: malloc (%lu) failed",
+ cnt * (unsigned long) sizeof *iov);
+ return 0;
}
-
- if (n != hdr.sadb_msg_len * PF_KEY_V2_CHUNK)
- {
- log_print ("pf_key_v2_read: read (%d, ...) returned short packet "
- "(%lu bytes)", pf_key_v2_socket, (unsigned long)n);
- goto cleanup;
+ msg->sadb_msg_version = PF_KEY_V2;
+ msg->sadb_msg_errno = 0;
+ msg->sadb_msg_reserved = 0;
+ msg->sadb_msg_pid = getpid();
+ if (!msg->sadb_msg_seq)
+ msg->sadb_msg_seq = pf_key_v2_seq();
+
+ /* Compute the iovec segments as well as the message length. */
+ len = 0;
+ for (i = 0; i < cnt; i++) {
+ iov[i].iov_base = np->seg;
+ len += iov[i].iov_len = np->sz;
+
+ /*
+ * XXX One can envision setting specific extension fields, like
+ * *_reserved ones here. For now we require them to be set by the
+ * caller.
+ */
+
+ np = TAILQ_NEXT(np, link);
}
+ msg->sadb_msg_len = len / PF_KEY_V2_CHUNK;
- LOG_DBG_BUF ((LOG_SYSDEP, 80, "pf_key_v2_read: msg", buf, n));
-
- /* We drop all messages that is not what we expect. */
- msg = (struct sadb_msg *)buf;
- if (msg->sadb_msg_version != PF_KEY_V2
- || (msg->sadb_msg_pid != 0
- && msg->sadb_msg_pid != (u_int32_t)getpid ()))
- {
- if (seq)
- {
- free (buf);
- buf = 0;
- continue;
- }
- else
- {
- LOG_DBG ((LOG_SYSDEP, 90,
- "pf_key_v2_read:"
- "bad version (%d) or PID (%d, mine is %ld), ignored",
- msg->sadb_msg_version, msg->sadb_msg_pid,
- (long)getpid ()));
- goto cleanup;
- }
+ for (i = 0; i < cnt; i++) {
+ snprintf(header, sizeof header, "pf_key_v2_write: iov[%d]", i);
+ LOG_DBG_BUF((LOG_SYSDEP, 80, header, (u_int8_t *) iov[i].iov_base,
+ iov[i].iov_len));
}
- /* Parse the message. */
- ret = pf_key_v2_msg_new (msg, PF_KEY_V2_NODE_MALLOCED);
- if (!ret)
- goto cleanup;
- buf = 0;
- for (ext = (struct sadb_ext *)(msg + 1);
- (u_int8_t *)ext - (u_int8_t *)msg
- < msg->sadb_msg_len * PF_KEY_V2_CHUNK;
- ext = (struct sadb_ext *)((u_int8_t *)ext
- + ext->sadb_ext_len * PF_KEY_V2_CHUNK))
- pf_key_v2_msg_add (ret, ext, 0);
-
- /* If the message is not the one we are waiting for, queue it up. */
- if (seq && (msg->sadb_msg_pid != (u_int32_t)getpid ()
- || msg->sadb_msg_seq != seq))
- {
- gettimeofday (&tv, 0);
- timer_add_event ("pf_key_v2_notify",
- (void (*) (void *))pf_key_v2_notify, ret, &tv);
- ret = 0;
- continue;
+ n = writev(pf_key_v2_socket, iov, cnt);
+ if (n == -1) {
+ log_error("pf_key_v2_write: writev (%d, %p, %d) failed",
+ pf_key_v2_socket, iov, cnt);
+ goto cleanup;
}
+ if ((size_t) n != len) {
+ log_error("pf_key_v2_write: writev (%d, ...) returned prematurely "
+ "(%lu)", pf_key_v2_socket, (unsigned long) n);
+ goto cleanup;
+ }
+ free(iov);
+ return msg->sadb_msg_seq;
- return ret;
- }
-
- cleanup:
- if (buf)
- free (buf);
- if (ret)
- pf_key_v2_msg_free (ret);
- return 0;
-}
-
-/* Write the message in PMSG to the PF_KEY socket. */
-u_int32_t
-pf_key_v2_write (struct pf_key_v2_msg *pmsg)
-{
- struct iovec *iov = 0;
- ssize_t n;
- size_t len;
- int i, cnt = TAILQ_FIRST (pmsg)->cnt;
- char header[80];
- struct sadb_msg *msg = TAILQ_FIRST (pmsg)->seg;
- struct pf_key_v2_node *np = TAILQ_FIRST (pmsg);
-
- iov = (struct iovec *)malloc (cnt * sizeof *iov);
- if (!iov)
- {
- log_error ("pf_key_v2_write: malloc (%lu) failed",
- cnt * (unsigned long)sizeof *iov);
- return 0;
- }
-
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_errno = 0;
- msg->sadb_msg_reserved = 0;
- msg->sadb_msg_pid = getpid ();
- if (!msg->sadb_msg_seq)
- msg->sadb_msg_seq = pf_key_v2_seq ();
-
- /* Compute the iovec segments as well as the message length. */
- len = 0;
- for (i = 0; i < cnt; i++)
- {
- iov[i].iov_base = np->seg;
- len += iov[i].iov_len = np->sz;
-
- /*
- * XXX One can envision setting specific extension fields, like
- * *_reserved ones here. For now we require them to be set by the
- * caller.
- */
-
- np = TAILQ_NEXT (np, link);
- }
- msg->sadb_msg_len = len / PF_KEY_V2_CHUNK;
-
- for (i = 0; i < cnt; i++)
- {
- snprintf (header, sizeof header, "pf_key_v2_write: iov[%d]", i);
- LOG_DBG_BUF ((LOG_SYSDEP, 80, header, (u_int8_t *)iov[i].iov_base,
- iov[i].iov_len));
- }
-
- n = writev (pf_key_v2_socket, iov, cnt);
- if (n == -1)
- {
- log_error ("pf_key_v2_write: writev (%d, %p, %d) failed",
- pf_key_v2_socket, iov, cnt);
- goto cleanup;
- }
- if ((size_t)n != len)
- {
- log_error ("pf_key_v2_write: writev (%d, ...) returned prematurely "
- "(%lu)", pf_key_v2_socket, (unsigned long)n);
- goto cleanup;
- }
- free (iov);
- return msg->sadb_msg_seq;
-
- cleanup:
- if (iov)
- free (iov);
- return 0;
+cleanup:
+ if (iov)
+ free(iov);
+ return 0;
}
/*
@@ -498,27 +477,27 @@ pf_key_v2_write (struct pf_key_v2_msg *pmsg)
* it to the caller.
*/
static struct pf_key_v2_msg *
-pf_key_v2_call (struct pf_key_v2_msg *msg)
+pf_key_v2_call(struct pf_key_v2_msg *msg)
{
- u_int32_t seq;
+ u_int32_t seq;
- seq = pf_key_v2_write (msg);
- if (!seq)
- return 0;
- return pf_key_v2_read (seq);
+ seq = pf_key_v2_write(msg);
+ if (!seq)
+ return 0;
+ return pf_key_v2_read(seq);
}
/* Find the TYPE extension in MSG. Return zero if none found. */
static struct pf_key_v2_node *
-pf_key_v2_find_ext (struct pf_key_v2_msg *msg, u_int16_t type)
+pf_key_v2_find_ext(struct pf_key_v2_msg *msg, u_int16_t type)
{
- struct pf_key_v2_node *ext;
+ struct pf_key_v2_node *ext;
- for (ext = TAILQ_NEXT (TAILQ_FIRST (msg), link); ext;
- ext = TAILQ_NEXT (ext, link))
- if (ext->type == type)
- return ext;
- return 0;
+ for (ext = TAILQ_NEXT(TAILQ_FIRST(msg), link); ext;
+ ext = TAILQ_NEXT(ext, link))
+ if (ext->type == type)
+ return ext;
+ return 0;
}
/*
@@ -526,106 +505,98 @@ pf_key_v2_find_ext (struct pf_key_v2_msg *msg, u_int16_t type)
* Return -1 for failure and -2 if no notifies will show up.
*/
int
-pf_key_v2_open (void)
+pf_key_v2_open(void)
{
- int fd = -1, err;
- struct sadb_msg msg;
- struct pf_key_v2_msg *regmsg = 0, *ret = 0;
-
- /* Open the socket we use to speak to IPsec. */
- pf_key_v2_socket = -1;
- fd = monitor_socket (PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (fd == -1)
- {
- log_error ("pf_key_v2_open: "
- "socket (PF_KEY, SOCK_RAW, PF_KEY_V2) failed");
- goto cleanup;
- }
- pf_key_v2_socket = fd;
-
- /* Register it to get ESP and AH acquires from the kernel. */
- msg.sadb_msg_seq = 0;
- msg.sadb_msg_type = SADB_REGISTER;
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- regmsg = pf_key_v2_msg_new (&msg, 0);
- if (!regmsg)
- goto cleanup;
- ret = pf_key_v2_call (regmsg);
- pf_key_v2_msg_free (regmsg);
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- log_print ("pf_key_v2_open: REGISTER: %s", strerror (err));
- goto cleanup;
- }
-
- /* XXX Register the accepted transforms. */
-
- pf_key_v2_msg_free (ret);
- ret = 0;
-
- msg.sadb_msg_seq = 0;
- msg.sadb_msg_type = SADB_REGISTER;
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- regmsg = pf_key_v2_msg_new (&msg, 0);
- if (!regmsg)
- goto cleanup;
- ret = pf_key_v2_call (regmsg);
- pf_key_v2_msg_free (regmsg);
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- log_print ("pf_key_v2_open: REGISTER: %s", strerror (err));
- goto cleanup;
- }
-
- /* XXX Register the accepted transforms. */
-
- pf_key_v2_msg_free (ret);
- ret = 0;
+ int fd = -1, err;
+ struct sadb_msg msg;
+ struct pf_key_v2_msg *regmsg = 0, *ret = 0;
+
+ /* Open the socket we use to speak to IPsec. */
+ pf_key_v2_socket = -1;
+ fd = monitor_socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+ if (fd == -1) {
+ log_error("pf_key_v2_open: "
+ "socket (PF_KEY, SOCK_RAW, PF_KEY_V2) failed");
+ goto cleanup;
+ }
+ pf_key_v2_socket = fd;
+
+ /* Register it to get ESP and AH acquires from the kernel. */
+ msg.sadb_msg_seq = 0;
+ msg.sadb_msg_type = SADB_REGISTER;
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ regmsg = pf_key_v2_msg_new(&msg, 0);
+ if (!regmsg)
+ goto cleanup;
+ ret = pf_key_v2_call(regmsg);
+ pf_key_v2_msg_free(regmsg);
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ log_print("pf_key_v2_open: REGISTER: %s", strerror(err));
+ goto cleanup;
+ }
+ /* XXX Register the accepted transforms. */
+
+ pf_key_v2_msg_free(ret);
+ ret = 0;
+
+ msg.sadb_msg_seq = 0;
+ msg.sadb_msg_type = SADB_REGISTER;
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ regmsg = pf_key_v2_msg_new(&msg, 0);
+ if (!regmsg)
+ goto cleanup;
+ ret = pf_key_v2_call(regmsg);
+ pf_key_v2_msg_free(regmsg);
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ log_print("pf_key_v2_open: REGISTER: %s", strerror(err));
+ goto cleanup;
+ }
+ /* XXX Register the accepted transforms. */
+
+ pf_key_v2_msg_free(ret);
+ ret = 0;
#ifdef SADB_X_SATYPE_IPCOMP
- msg.sadb_msg_seq = 0;
- msg.sadb_msg_type = SADB_REGISTER;
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- regmsg = pf_key_v2_msg_new (&msg, 0);
- if (!regmsg)
- goto cleanup;
- ret = pf_key_v2_call (regmsg);
- pf_key_v2_msg_free (regmsg);
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- log_print ("pf_key_v2_open: REGISTER: %s", strerror (err));
- goto cleanup;
- }
-
- /* XXX Register the accepted transforms. */
-
- pf_key_v2_msg_free (ret);
+ msg.sadb_msg_seq = 0;
+ msg.sadb_msg_type = SADB_REGISTER;
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ regmsg = pf_key_v2_msg_new(&msg, 0);
+ if (!regmsg)
+ goto cleanup;
+ ret = pf_key_v2_call(regmsg);
+ pf_key_v2_msg_free(regmsg);
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ log_print("pf_key_v2_open: REGISTER: %s", strerror(err));
+ goto cleanup;
+ }
+ /* XXX Register the accepted transforms. */
+
+ pf_key_v2_msg_free(ret);
#endif /* SADB_X_SATYPE_IPCOMP */
#ifdef KAME
- TAILQ_INIT (&pf_key_v2_sa_seq_map);
+ TAILQ_INIT(&pf_key_v2_sa_seq_map);
#endif
- return fd;
-
- cleanup:
- if (pf_key_v2_socket != -1)
- {
- close (pf_key_v2_socket);
- pf_key_v2_socket = -1;
- }
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
+ return fd;
+
+cleanup:
+ if (pf_key_v2_socket != -1) {
+ close(pf_key_v2_socket);
+ pf_key_v2_socket = -1;
+ }
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
}
/*
@@ -633,231 +604,217 @@ pf_key_v2_open (void)
* SRC, SRCLEN, DST & DSTLEN. Stash the SPI size in SZ.
*/
u_int8_t *
-pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
- struct sockaddr *dst, u_int32_t seq)
+pf_key_v2_get_spi(size_t *sz, u_int8_t proto, struct sockaddr *src,
+ struct sockaddr *dst, u_int32_t seq)
{
- struct sadb_msg msg;
- struct sadb_sa *sa;
- struct sadb_address *addr = 0;
- struct sadb_spirange spirange;
- struct pf_key_v2_msg *getspi = 0, *ret = 0;
- struct pf_key_v2_node *ext;
- u_int8_t *spi = 0;
- int len, err;
+ struct sadb_msg msg;
+ struct sadb_sa *sa;
+ struct sadb_address *addr = 0;
+ struct sadb_spirange spirange;
+ struct pf_key_v2_msg *getspi = 0, *ret = 0;
+ struct pf_key_v2_node *ext;
+ u_int8_t *spi = 0;
+ int len, err;
#ifdef KAME
- struct sadb_x_sa2 ssa2;
+ struct sadb_x_sa2 ssa2;
#endif
- msg.sadb_msg_type = SADB_GETSPI;
- switch (proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- break;
+ msg.sadb_msg_type = SADB_GETSPI;
+ switch (proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ break;
#ifdef SADB_X_SATYPE_IPCOMP
- case IPSEC_PROTO_IPCOMP:
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- break;
+ case IPSEC_PROTO_IPCOMP:
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ break;
#endif
- default:
- log_print ("pf_key_v2_get_spi: invalid proto %d", proto);
- goto cleanup;
- }
+ default:
+ log_print("pf_key_v2_get_spi: invalid proto %d", proto);
+ goto cleanup;
+ }
- /* Set the sequence number from the ACQUIRE message. */
- msg.sadb_msg_seq = seq;
- getspi = pf_key_v2_msg_new (&msg, 0);
- if (!getspi)
- goto cleanup;
+ /* Set the sequence number from the ACQUIRE message. */
+ msg.sadb_msg_seq = seq;
+ getspi = pf_key_v2_msg_new(&msg, 0);
+ if (!getspi)
+ goto cleanup;
#ifdef KAME
- memset (&ssa2, 0, sizeof ssa2);
- ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
- ssa2.sadb_x_sa2_mode = 0;
- if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)&ssa2, 0) == -1)
- goto cleanup;
+ memset(&ssa2, 0, sizeof ssa2);
+ ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_mode = 0;
+ if (pf_key_v2_msg_add(getspi, (struct sadb_ext *) & ssa2, 0) == -1)
+ goto cleanup;
#endif
- /* Setup the ADDRESS extensions. */
- len = sizeof (struct sadb_address) + PF_KEY_V2_ROUND (sysdep_sa_len (src));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ /* Setup the ADDRESS extensions. */
+ len = sizeof(struct sadb_address) + PF_KEY_V2_ROUND(sysdep_sa_len(src));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, src, sysdep_sa_len (src));
- switch (((struct sockaddr *)(addr + 1))->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- len = sizeof (struct sadb_address) + PF_KEY_V2_ROUND (sysdep_sa_len (dst));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, src, sysdep_sa_len(src));
+ switch (((struct sockaddr *) (addr + 1))->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(getspi, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ len = sizeof(struct sadb_address) + PF_KEY_V2_ROUND(sysdep_sa_len(dst));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, dst, sysdep_sa_len (dst));
- switch (((struct sockaddr *)(addr + 1))->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- /* Setup the SPIRANGE extension. */
- spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
- spirange.sadb_spirange_len = sizeof spirange / PF_KEY_V2_CHUNK;
- if (proto == IPSEC_PROTO_IPCOMP)
- {
- spirange.sadb_spirange_min = CPI_RESERVED_MAX + 1;
- spirange.sadb_spirange_max = CPI_PRIVATE_MIN - 1;
- }
- else
- {
- spirange.sadb_spirange_min = IPSEC_SPI_LOW;
- spirange.sadb_spirange_max = 0xffffffff;
- }
- spirange.sadb_spirange_reserved = 0;
- if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)&spirange, 0) == -1)
- goto cleanup;
-
- ret = pf_key_v2_call (getspi);
- pf_key_v2_msg_free (getspi);
- getspi = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- log_print ("pf_key_v2_get_spi: GETSPI: %s", strerror (err));
- goto cleanup;
- }
-
- ext = pf_key_v2_find_ext (ret, SADB_EXT_SA);
- if (!ext)
- {
- log_print ("pf_key_v2_get_spi: no SA extension found");
- goto cleanup;
- }
- sa = ext->seg;
-
- /* IPCOMP CPIs are only 16 bits long. */
- *sz = (proto == IPSEC_PROTO_IPCOMP) ? sizeof (u_int16_t)
- : sizeof sa->sadb_sa_spi;
- spi = malloc (*sz);
- if (!spi)
- goto cleanup;
- /* XXX This is ugly. */
- if (proto == IPSEC_PROTO_IPCOMP)
- {
- u_int32_t tspi = ntohl (sa->sadb_sa_spi);
- *(u_int16_t *)spi = htons ((u_int16_t)tspi);
- }
- else
- memcpy (spi, &sa->sadb_sa_spi, *sz);
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, dst, sysdep_sa_len(dst));
+ switch (((struct sockaddr *) (addr + 1))->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(getspi, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ /* Setup the SPIRANGE extension. */
+ spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
+ spirange.sadb_spirange_len = sizeof spirange / PF_KEY_V2_CHUNK;
+ if (proto == IPSEC_PROTO_IPCOMP) {
+ spirange.sadb_spirange_min = CPI_RESERVED_MAX + 1;
+ spirange.sadb_spirange_max = CPI_PRIVATE_MIN - 1;
+ } else {
+ spirange.sadb_spirange_min = IPSEC_SPI_LOW;
+ spirange.sadb_spirange_max = 0xffffffff;
+ }
+ spirange.sadb_spirange_reserved = 0;
+ if (pf_key_v2_msg_add(getspi, (struct sadb_ext *) & spirange, 0) == -1)
+ goto cleanup;
+
+ ret = pf_key_v2_call(getspi);
+ pf_key_v2_msg_free(getspi);
+ getspi = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ log_print("pf_key_v2_get_spi: GETSPI: %s", strerror(err));
+ goto cleanup;
+ }
+ ext = pf_key_v2_find_ext(ret, SADB_EXT_SA);
+ if (!ext) {
+ log_print("pf_key_v2_get_spi: no SA extension found");
+ goto cleanup;
+ }
+ sa = ext->seg;
+
+ /* IPCOMP CPIs are only 16 bits long. */
+ *sz = (proto == IPSEC_PROTO_IPCOMP) ? sizeof(u_int16_t)
+ : sizeof sa->sadb_sa_spi;
+ spi = malloc(*sz);
+ if (!spi)
+ goto cleanup;
+ /* XXX This is ugly. */
+ if (proto == IPSEC_PROTO_IPCOMP) {
+ u_int32_t tspi = ntohl(sa->sadb_sa_spi);
+ *(u_int16_t *) spi = htons((u_int16_t) tspi);
+ } else
+ memcpy(spi, &sa->sadb_sa_spi, *sz);
#ifdef KAME
- if (!pf_key_v2_register_sa_seq (spi, *sz, proto, dst, sysdep_sa_len (dst),
- ((struct sadb_msg *)(TAILQ_FIRST (ret)->seg))
- ->sadb_msg_seq))
- goto cleanup;
+ if (!pf_key_v2_register_sa_seq(spi, *sz, proto, dst, sysdep_sa_len(dst),
+ ((struct sadb_msg *) (TAILQ_FIRST(ret)->seg))->sadb_msg_seq))
+ goto cleanup;
#endif
- pf_key_v2_msg_free (ret);
-
- LOG_DBG_BUF ((LOG_SYSDEP, 50, "pf_key_v2_get_spi: spi", spi, *sz));
-
- return spi;
-
- cleanup:
- if (spi)
- free (spi);
- if (addr)
- free (addr);
- if (getspi)
- pf_key_v2_msg_free (getspi);
- if (ret)
- pf_key_v2_msg_free (ret);
- return 0;
+ pf_key_v2_msg_free(ret);
+
+ LOG_DBG_BUF((LOG_SYSDEP, 50, "pf_key_v2_get_spi: spi", spi, *sz));
+ return spi;
+
+cleanup:
+ if (spi)
+ free(spi);
+ if (addr)
+ free(addr);
+ if (getspi)
+ pf_key_v2_msg_free(getspi);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return 0;
}
static void
-pf_key_v2_setup_sockaddr (void *res, struct sockaddr *src,
- struct sockaddr *dst, in_port_t port, int ingress)
+pf_key_v2_setup_sockaddr(void *res, struct sockaddr *src,
+ struct sockaddr *dst, in_port_t port, int ingress)
{
- struct sockaddr_in *ip4_sa;
- struct sockaddr_in6 *ip6_sa;
- u_int8_t *p;
-
- switch (src->sa_family)
- {
- case AF_INET:
- ip4_sa = (struct sockaddr_in *)res;
- ip4_sa->sin_family = AF_INET;
+ struct sockaddr_in *ip4_sa;
+ struct sockaddr_in6 *ip6_sa;
+ u_int8_t *p;
+
+ switch (src->sa_family) {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *) res;
+ ip4_sa->sin_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- ip4_sa->sin_len = sizeof *ip4_sa;
-#endif
- ip4_sa->sin_port = port;
- if (dst)
- p = (u_int8_t *)(ingress
- ? &((struct sockaddr_in *)src)->sin_addr.s_addr
- : &((struct sockaddr_in *)dst)->sin_addr.s_addr);
- else
- p = (u_int8_t *)&((struct sockaddr_in *)src)->sin_addr.s_addr;
- ip4_sa->sin_addr.s_addr = *((in_addr_t *)p);
- break;
-
- case AF_INET6:
- ip6_sa = (struct sockaddr_in6 *)res;
- ip6_sa->sin6_family = AF_INET6;
+ ip4_sa->sin_len = sizeof *ip4_sa;
+#endif
+ ip4_sa->sin_port = port;
+ if (dst)
+ p = (u_int8_t *) (ingress ?
+ &((struct sockaddr_in *)src)->sin_addr.s_addr :
+ &((struct sockaddr_in *)dst)->sin_addr.s_addr);
+ else
+ p = (u_int8_t *)&((struct sockaddr_in *)src)->sin_addr.s_addr;
+ ip4_sa->sin_addr.s_addr = *((in_addr_t *) p);
+ break;
+
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *) res;
+ ip6_sa->sin6_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- ip6_sa->sin6_len = sizeof *ip6_sa;
-#endif
- ip6_sa->sin6_port = port;
- if (dst)
- p = (u_int8_t *)(ingress
- ? &((struct sockaddr_in6 *)src)->sin6_addr.s6_addr
- : &((struct sockaddr_in6 *)dst)->sin6_addr.s6_addr);
- else
- p = (u_int8_t *)&((struct sockaddr_in6 *)src)->sin6_addr.s6_addr;
- memcpy (ip6_sa->sin6_addr.s6_addr, p, sizeof (struct in6_addr));
- break;
-
- default:
- log_print ("pf_key_v2_setup_sockaddr: unknown family %d\n",
- src->sa_family);
- break;
- }
+ ip6_sa->sin6_len = sizeof *ip6_sa;
+#endif
+ ip6_sa->sin6_port = port;
+ if (dst)
+ p = (u_int8_t *) (ingress ?
+ &((struct sockaddr_in6 *)src)->sin6_addr.s6_addr :
+ &((struct sockaddr_in6 *)dst)->sin6_addr.s6_addr);
+ else
+ p = (u_int8_t *)&((struct sockaddr_in6 *)src)->sin6_addr.s6_addr;
+ memcpy(ip6_sa->sin6_addr.s6_addr, p, sizeof(struct in6_addr));
+ break;
+
+ default:
+ log_print("pf_key_v2_setup_sockaddr: unknown family %d\n",
+ src->sa_family);
+ break;
+ }
}
/*
@@ -866,860 +823,834 @@ pf_key_v2_setup_sockaddr (void *res, struct sockaddr *src,
* parameters for the incoming SA, and cleared otherwise.
*/
int
-pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
- struct sa *isakmp_sa)
+pf_key_v2_set_spi(struct sa *sa, struct proto *proto, int incoming,
+ struct sa *isakmp_sa)
{
- struct sadb_msg msg;
- struct sadb_sa ssa;
- struct sadb_lifetime *life = 0;
- struct sadb_address *addr = 0;
- struct sadb_key *key = 0;
- struct sadb_ident *sid = 0;
- struct sockaddr *src, *dst;
- struct pf_key_v2_msg *update = 0, *ret = 0;
- struct ipsec_proto *iproto = proto->data;
- size_t len;
- int keylen, hashlen, err;
+ struct sadb_msg msg;
+ struct sadb_sa ssa;
+ struct sadb_lifetime *life = 0;
+ struct sadb_address *addr = 0;
+ struct sadb_key *key = 0;
+ struct sadb_ident *sid = 0;
+ struct sockaddr *src, *dst;
+ struct pf_key_v2_msg *update = 0, *ret = 0;
+ struct ipsec_proto *iproto = proto->data;
+ size_t len;
+ int keylen, hashlen, err;
#ifndef KAME
- u_int8_t *pp;
- int idtype;
-#else /* KAME */
- struct sadb_x_sa2 ssa2;
+ u_int8_t *pp;
+ int idtype;
+#else /* KAME */
+ struct sadb_x_sa2 ssa2;
#endif
#if defined (SADB_X_CREDTYPE_NONE) || defined (SADB_X_AUTHTYPE_NONE)
- struct ipsec_sa *isa = sa->data;
- struct sadb_x_cred *cred;
- struct sadb_protocol flowtype, tprotocol;
+ struct ipsec_sa *isa = sa->data;
+ struct sadb_x_cred *cred;
+ struct sadb_protocol flowtype, tprotocol;
#endif
#ifdef USE_DEBUG
- char *addr_str;
+ char *addr_str;
#endif
- msg.sadb_msg_type = incoming ? SADB_UPDATE : SADB_ADD;
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- keylen = ipsec_esp_enckeylength (proto);
- hashlen = ipsec_esp_authkeylength (proto);
+ msg.sadb_msg_type = incoming ? SADB_UPDATE : SADB_ADD;
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ keylen = ipsec_esp_enckeylength(proto);
+ hashlen = ipsec_esp_authkeylength(proto);
- switch (proto->id)
- {
- case IPSEC_ESP_DES:
- case IPSEC_ESP_DES_IV32:
- case IPSEC_ESP_DES_IV64:
- ssa.sadb_sa_encrypt = SADB_EALG_DESCBC;
- break;
+ switch (proto->id) {
+ case IPSEC_ESP_DES:
+ case IPSEC_ESP_DES_IV32:
+ case IPSEC_ESP_DES_IV64:
+ ssa.sadb_sa_encrypt = SADB_EALG_DESCBC;
+ break;
- case IPSEC_ESP_3DES:
- ssa.sadb_sa_encrypt = SADB_EALG_3DESCBC;
- break;
+ case IPSEC_ESP_3DES:
+ ssa.sadb_sa_encrypt = SADB_EALG_3DESCBC;
+ break;
#ifdef SADB_X_EALG_AES
- case IPSEC_ESP_AES:
- /* case IPSEC_ESP_AES_128_CTR: */
- ssa.sadb_sa_encrypt = SADB_X_EALG_AES;
- break;
+ case IPSEC_ESP_AES:
+ /* case IPSEC_ESP_AES_128_CTR: */
+ ssa.sadb_sa_encrypt = SADB_X_EALG_AES;
+ break;
#endif
#ifdef SADB_X_EALG_CAST
- case IPSEC_ESP_CAST:
- ssa.sadb_sa_encrypt = SADB_X_EALG_CAST;
- break;
+ case IPSEC_ESP_CAST:
+ ssa.sadb_sa_encrypt = SADB_X_EALG_CAST;
+ break;
#endif
#ifdef SADB_X_EALG_BLF
- case IPSEC_ESP_BLOWFISH:
- ssa.sadb_sa_encrypt = SADB_X_EALG_BLF;
- break;
+ case IPSEC_ESP_BLOWFISH:
+ ssa.sadb_sa_encrypt = SADB_X_EALG_BLF;
+ break;
#endif
- default:
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_set_spi: unknown encryption algorithm %d",
- proto->id));
- return -1;
- }
+ default:
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_set_spi: unknown encryption algorithm %d",
+ proto->id));
+ return -1;
+ }
- switch (iproto->auth)
- {
- case IPSEC_AUTH_HMAC_MD5:
+ switch (iproto->auth) {
+ case IPSEC_AUTH_HMAC_MD5:
#ifdef SADB_AALG_MD5HMAC96
- ssa.sadb_sa_auth = SADB_AALG_MD5HMAC96;
+ ssa.sadb_sa_auth = SADB_AALG_MD5HMAC96;
#else
- ssa.sadb_sa_auth = SADB_AALG_MD5HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_MD5HMAC;
#endif
- break;
+ break;
- case IPSEC_AUTH_HMAC_SHA:
+ case IPSEC_AUTH_HMAC_SHA:
#ifdef SADB_AALG_SHA1HMAC96
- ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC96;
+ ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC96;
#else
- ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
#endif
- break;
+ break;
#ifndef KAME
- case IPSEC_AUTH_HMAC_RIPEMD:
+ case IPSEC_AUTH_HMAC_RIPEMD:
#ifdef SADB_X_AALG_RIPEMD160HMAC96
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
#elif defined (SADB_X_AALG_RIPEMD160HMAC)
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
#elif defined (SADB_X_AALG_RIPEMD160)
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160;
#else
- ssa.sadb_sa_auth = SADB_AALG_RIPEMD160HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_RIPEMD160HMAC;
#endif
- break;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_256
- case IPSEC_AUTH_HMAC_SHA2_256:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
- break;
+ case IPSEC_AUTH_HMAC_SHA2_256:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_384
- case IPSEC_AUTH_HMAC_SHA2_384:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
- break;
+ case IPSEC_AUTH_HMAC_SHA2_384:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_512
- case IPSEC_AUTH_HMAC_SHA2_512:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
- break;
+ case IPSEC_AUTH_HMAC_SHA2_512:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
+ break;
#endif
- case IPSEC_AUTH_DES_MAC:
- case IPSEC_AUTH_KPDK:
- /* XXX We should be supporting KPDK */
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_set_spi: unknown authentication algorithm %d",
- iproto->auth));
- return -1;
+ case IPSEC_AUTH_DES_MAC:
+ case IPSEC_AUTH_KPDK:
+ /* XXX We should be supporting KPDK */
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_set_spi: unknown authentication algorithm %d",
+ iproto->auth));
+ return -1;
- default:
- ssa.sadb_sa_auth = SADB_AALG_NONE;
- }
- break;
+ default:
+ ssa.sadb_sa_auth = SADB_AALG_NONE;
+ }
+ break;
- case IPSEC_PROTO_IPSEC_AH:
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- hashlen = ipsec_ah_keylength (proto);
- keylen = 0;
+ case IPSEC_PROTO_IPSEC_AH:
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ hashlen = ipsec_ah_keylength(proto);
+ keylen = 0;
- ssa.sadb_sa_encrypt = SADB_EALG_NONE;
- switch (proto->id)
- {
- case IPSEC_AH_MD5:
+ ssa.sadb_sa_encrypt = SADB_EALG_NONE;
+ switch (proto->id) {
+ case IPSEC_AH_MD5:
#ifdef SADB_AALG_MD5HMAC96
- ssa.sadb_sa_auth = SADB_AALG_MD5HMAC96;
+ ssa.sadb_sa_auth = SADB_AALG_MD5HMAC96;
#else
- ssa.sadb_sa_auth = SADB_AALG_MD5HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_MD5HMAC;
#endif
- break;
+ break;
- case IPSEC_AH_SHA:
+ case IPSEC_AH_SHA:
#ifdef SADB_AALG_SHA1HMAC96
- ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC96;
+ ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC96;
#else
- ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
#endif
- break;
+ break;
#ifndef KAME
- case IPSEC_AH_RIPEMD:
+ case IPSEC_AH_RIPEMD:
#ifdef SADB_X_AALG_RIPEMD160HMAC96
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC96;
#elif defined (SADB_X_AALG_RIPEMD160HMAC)
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
#elif defined (SADB_X_AALG_RIPEMD160)
- ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160;
+ ssa.sadb_sa_auth = SADB_X_AALG_RIPEMD160;
#else
- ssa.sadb_sa_auth = SADB_AALG_RIPEMD160HMAC;
+ ssa.sadb_sa_auth = SADB_AALG_RIPEMD160HMAC;
#endif
- break;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_256
- case IPSEC_AH_SHA2_256:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
- break;
+ case IPSEC_AH_SHA2_256:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_384
- case IPSEC_AH_SHA2_384:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
- break;
+ case IPSEC_AH_SHA2_384:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
+ break;
#endif
#ifdef SADB_X_AALG_SHA2_512
- case IPSEC_AH_SHA2_512:
- ssa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
- break;
+ case IPSEC_AH_SHA2_512:
+ ssa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
+ break;
#endif
- default:
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_set_spi: unknown authentication algorithm %d",
- proto->id));
- goto cleanup;
- }
- break;
+ default:
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_set_spi: unknown authentication algorithm %d",
+ proto->id));
+ goto cleanup;
+ }
+ break;
#ifdef SADB_X_SATYPE_IPCOMP
- case IPSEC_PROTO_IPCOMP:
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- ssa.sadb_sa_auth = SADB_AALG_NONE;
- keylen = 0;
- hashlen = 0;
-
- /* Put compression algorithm type in the sadb_sa_encrypt field. */
- switch (proto->id)
- {
+ case IPSEC_PROTO_IPCOMP:
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ ssa.sadb_sa_auth = SADB_AALG_NONE;
+ keylen = 0;
+ hashlen = 0;
+
+ /*
+ * Put compression algorithm type in the sadb_sa_encrypt
+ * field.
+ */
+ switch (proto->id) {
#ifdef SADB_X_CALG_OUI
- case IPSEC_IPCOMP_OUI:
- ssa.sadb_sa_encrypt = SADB_X_CALG_OUI;
- break;
+ case IPSEC_IPCOMP_OUI:
+ ssa.sadb_sa_encrypt = SADB_X_CALG_OUI;
+ break;
#endif
#ifdef SADB_X_CALG_DEFLATE
- case IPSEC_IPCOMP_DEFLATE:
- ssa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
- break;
+ case IPSEC_IPCOMP_DEFLATE:
+ ssa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
+ break;
#endif
#ifdef SADB_X_CALG_LZS
- case IPSEC_IPCOMP_LZS:
- ssa.sadb_sa_encrypt = SADB_X_CALG_LZS;
- break;
+ case IPSEC_IPCOMP_LZS:
+ ssa.sadb_sa_encrypt = SADB_X_CALG_LZS;
+ break;
#endif
#ifdef SADB_X_CALG_V42BIS
- case IPSEC_IPCOMP_V42BIS:
- ssa.sadb_sa_encrypt = SADB_X_CALG_V42BIS;
- break;
+ case IPSEC_IPCOMP_V42BIS:
+ ssa.sadb_sa_encrypt = SADB_X_CALG_V42BIS;
+ break;
#endif
- default:
- break;
- }
- break;
+ default:
+ break;
+ }
+ break;
#endif /* SADB_X_SATYPE_IPCOMP */
- default:
- log_print ("pf_key_v2_set_spi: invalid proto %d", proto->proto);
- goto cleanup;
- }
- if (incoming)
- sa->transport->vtbl->get_src (sa->transport, &dst);
- else
- sa->transport->vtbl->get_dst (sa->transport, &dst);
+ default:
+ log_print("pf_key_v2_set_spi: invalid proto %d", proto->proto);
+ goto cleanup;
+ }
+ if (incoming)
+ sa->transport->vtbl->get_src(sa->transport, &dst);
+ else
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
#ifdef KAME
- msg.sadb_msg_seq
- = (incoming ? pf_key_v2_seq_by_sa (proto->spi[incoming],
- sizeof ssa.sadb_sa_spi, proto->proto,
- dst, sysdep_sa_len (dst))
- : 0);
+ msg.sadb_msg_seq = (incoming ?
+ pf_key_v2_seq_by_sa(proto->spi[incoming], sizeof ssa.sadb_sa_spi,
+ proto->proto, dst, sysdep_sa_len(dst)) : 0);
#else
- msg.sadb_msg_seq = sa->seq;
+ msg.sadb_msg_seq = sa->seq;
#endif
- update = pf_key_v2_msg_new (&msg, 0);
- if (!update)
- goto cleanup;
+ update = pf_key_v2_msg_new(&msg, 0);
+ if (!update)
+ goto cleanup;
#ifdef KAME
- memset (&ssa2, 0, sizeof ssa2);
- ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
+ memset(&ssa2, 0, sizeof ssa2);
+ ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
#if defined (LINUX_IPSEC)
- if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
- ssa2.sadb_x_sa2_mode = IPSEC_MODE_TUNNEL;
- else
- ssa2.sadb_x_sa2_mode = IPSEC_MODE_TRANSPORT;
+ if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
+ ssa2.sadb_x_sa2_mode = IPSEC_MODE_TUNNEL;
+ else
+ ssa2.sadb_x_sa2_mode = IPSEC_MODE_TRANSPORT;
#else
- ssa2.sadb_x_sa2_mode = 0;
+ ssa2.sadb_x_sa2_mode = 0;
#endif
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)&ssa2, 0) == -1)
- goto cleanup;
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) & ssa2, 0) == -1)
+ goto cleanup;
#endif
- /* Setup the rest of the SA extension. */
- ssa.sadb_sa_exttype = SADB_EXT_SA;
- ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
- if (proto->spi_sz[incoming] == 2) /* IPCOMP uses 16bit CPIs. */
- ssa.sadb_sa_spi = htonl (proto->spi[incoming][0] << 8
- | proto->spi[incoming][1]);
- else
- memcpy (&ssa.sadb_sa_spi, proto->spi[incoming], sizeof ssa.sadb_sa_spi);
- ssa.sadb_sa_replay
- = conf_get_str ("General", "Shared-SADB") ? 0 : iproto->replay_window;
- ssa.sadb_sa_state = SADB_SASTATE_MATURE;
+ /* Setup the rest of the SA extension. */
+ ssa.sadb_sa_exttype = SADB_EXT_SA;
+ ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
+ if (proto->spi_sz[incoming] == 2) /* IPCOMP uses 16bit CPIs. */
+ ssa.sadb_sa_spi = htonl(proto->spi[incoming][0] << 8 |
+ proto->spi[incoming][1]);
+ else
+ memcpy(&ssa.sadb_sa_spi, proto->spi[incoming],
+ sizeof ssa.sadb_sa_spi);
+ ssa.sadb_sa_replay = conf_get_str("General", "Shared-SADB") ? 0 :
+ iproto->replay_window;
+ ssa.sadb_sa_state = SADB_SASTATE_MATURE;
#ifdef SADB_X_SAFLAGS_TUNNEL
- ssa.sadb_sa_flags
- = iproto->encap_mode == IPSEC_ENCAP_TUNNEL ? SADB_X_SAFLAGS_TUNNEL : 0;
+ ssa.sadb_sa_flags = iproto->encap_mode == IPSEC_ENCAP_TUNNEL ?
+ SADB_X_SAFLAGS_TUNNEL : 0;
#else
- ssa.sadb_sa_flags = 0;
+ ssa.sadb_sa_flags = 0;
#endif
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)&ssa, 0) == -1)
- goto cleanup;
-
- if (sa->seconds || sa->kilobytes)
- {
- /* Setup the hard limits. */
- life = malloc (sizeof *life);
- if (!life)
- goto cleanup;
- life->sadb_lifetime_len = sizeof *life / PF_KEY_V2_CHUNK;
- life->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
- life->sadb_lifetime_allocations = 0;
- life->sadb_lifetime_bytes = sa->kilobytes * 1024;
- /*
- * XXX I am not sure which one is best in security respect. Maybe the
- * RFCs actually mandate what a lifetime really is.
- */
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) & ssa, 0) == -1)
+ goto cleanup;
+
+ if (sa->seconds || sa->kilobytes) {
+ /* Setup the hard limits. */
+ life = malloc(sizeof *life);
+ if (!life)
+ goto cleanup;
+ life->sadb_lifetime_len = sizeof *life / PF_KEY_V2_CHUNK;
+ life->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
+ life->sadb_lifetime_allocations = 0;
+ life->sadb_lifetime_bytes = sa->kilobytes * 1024;
+ /*
+ * XXX I am not sure which one is best in security respect. Maybe the
+ * RFCs actually mandate what a lifetime really is.
+ */
#if 0
- life->sadb_lifetime_addtime = 0;
- life->sadb_lifetime_usetime = sa->seconds;
+ life->sadb_lifetime_addtime = 0;
+ life->sadb_lifetime_usetime = sa->seconds;
#else
- life->sadb_lifetime_addtime = sa->seconds;
- life->sadb_lifetime_usetime = 0;
-#endif
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)life,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- life = 0;
-
- /*
- * Setup the soft limits, we use 90 % of the hard ones.
- * XXX A configurable ratio would be better.
- */
- life = malloc (sizeof *life);
- if (!life)
- goto cleanup;
- life->sadb_lifetime_len = sizeof *life / PF_KEY_V2_CHUNK;
- life->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
- life->sadb_lifetime_allocations = 0;
- life->sadb_lifetime_bytes = sa->kilobytes * 1024 * 9 / 10;
- /*
- * XXX I am not sure which one is best in security respect. Maybe the
- * RFCs actually mandate what a lifetime really is.
- */
+ life->sadb_lifetime_addtime = sa->seconds;
+ life->sadb_lifetime_usetime = 0;
+#endif
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) life,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ life = 0;
+
+ /*
+ * Setup the soft limits, we use 90 % of the hard ones.
+ * XXX A configurable ratio would be better.
+ */
+ life = malloc(sizeof *life);
+ if (!life)
+ goto cleanup;
+ life->sadb_lifetime_len = sizeof *life / PF_KEY_V2_CHUNK;
+ life->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
+ life->sadb_lifetime_allocations = 0;
+ life->sadb_lifetime_bytes = sa->kilobytes * 1024 * 9 / 10;
+ /*
+ * XXX I am not sure which one is best in security respect. Maybe the
+ * RFCs actually mandate what a lifetime really is.
+ */
#if 0
- life->sadb_lifetime_addtime = 0;
- life->sadb_lifetime_usetime = sa->seconds * 9 / 10;
+ life->sadb_lifetime_addtime = 0;
+ life->sadb_lifetime_usetime = sa->seconds * 9 / 10;
#else
- life->sadb_lifetime_addtime = sa->seconds * 9 / 10;
- life->sadb_lifetime_usetime = 0;
+ life->sadb_lifetime_addtime = sa->seconds * 9 / 10;
+ life->sadb_lifetime_usetime = 0;
#endif
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)life,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- life = 0;
- }
-
- /*
- * Setup the ADDRESS extensions.
- */
- if (incoming)
- sa->transport->vtbl->get_dst (sa->transport, &src);
- else
- sa->transport->vtbl->get_src (sa->transport, &src);
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (src));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
-#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
-#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, src, sysdep_sa_len (src));
- switch (((struct sockaddr *)(addr + 1))->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (dst));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) life,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ life = 0;
+ }
+ /*
+ * Setup the ADDRESS extensions.
+ */
+ if (incoming)
+ sa->transport->vtbl->get_dst(sa->transport, &src);
+ else
+ sa->transport->vtbl->get_src(sa->transport, &src);
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(src));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, dst, sysdep_sa_len (dst));
- switch (((struct sockaddr *)(addr + 1))->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, src, sysdep_sa_len(src));
+ switch (((struct sockaddr *) (addr + 1))->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
-#if 0
- /* XXX I am not sure about what to do here just yet. */
- if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
- {
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (dst));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(dst));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, dst, sysdep_sa_len (dst));
- switch (((struct sockaddr *)(addr + 1))->sa_family)
- {
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, dst, sysdep_sa_len(dst));
+ switch (((struct sockaddr *) (addr + 1))->sa_family) {
case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
}
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
#if 0
- msg->em_odst = msg->em_dst;
- msg->em_osrc = msg->em_src;
-#endif
- }
+ /* XXX I am not sure about what to do here just yet. */
+ if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL) {
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(dst));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+#ifndef __OpenBSD__
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
+#endif
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, dst, sysdep_sa_len(dst));
+ switch (((struct sockaddr *) (addr + 1))->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+#if 0
+ msg->em_odst = msg->em_dst;
+ msg->em_osrc = msg->em_src;
#endif
-
- if (proto->proto != IPSEC_PROTO_IPCOMP)
- {
- /* Setup the KEY extensions. */
- if (hashlen)
- {
- len = sizeof *key + PF_KEY_V2_ROUND (hashlen);
- key = malloc (len);
- if (!key)
- goto cleanup;
- key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
- key->sadb_key_len = len / PF_KEY_V2_CHUNK;
- key->sadb_key_bits = hashlen * 8;
- key->sadb_key_reserved = 0;
- memcpy (key + 1,
- iproto->keymat[incoming]
- + (proto->proto == IPSEC_PROTO_IPSEC_ESP ? keylen : 0),
- hashlen);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)key,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- key = 0;
}
+#endif
- if (keylen)
- {
- len = sizeof *key + PF_KEY_V2_ROUND (keylen);
- key = malloc (len);
- if (!key)
- goto cleanup;
- key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
- key->sadb_key_len = len / PF_KEY_V2_CHUNK;
- key->sadb_key_bits = keylen * 8;
- key->sadb_key_reserved = 0;
- memcpy (key + 1, iproto->keymat[incoming], keylen);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)key,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- key = 0;
+ if (proto->proto != IPSEC_PROTO_IPCOMP) {
+ /* Setup the KEY extensions. */
+ if (hashlen) {
+ len = sizeof *key + PF_KEY_V2_ROUND(hashlen);
+ key = malloc(len);
+ if (!key)
+ goto cleanup;
+ key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
+ key->sadb_key_len = len / PF_KEY_V2_CHUNK;
+ key->sadb_key_bits = hashlen * 8;
+ key->sadb_key_reserved = 0;
+ memcpy(key + 1,
+ iproto->keymat[incoming] +
+ (proto->proto == IPSEC_PROTO_IPSEC_ESP ? keylen : 0),
+ hashlen);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) key,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ key = 0;
+ }
+ if (keylen) {
+ len = sizeof *key + PF_KEY_V2_ROUND(keylen);
+ key = malloc(len);
+ if (!key)
+ goto cleanup;
+ key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
+ key->sadb_key_len = len / PF_KEY_V2_CHUNK;
+ key->sadb_key_bits = keylen * 8;
+ key->sadb_key_reserved = 0;
+ memcpy(key + 1, iproto->keymat[incoming], keylen);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) key,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ key = 0;
+ }
}
- }
-
#ifndef KAME
- /* Setup identity extensions. */
- if (isakmp_sa->id_i)
- {
- pp = pf_key_v2_convert_id (isakmp_sa->id_i, isakmp_sa->id_i_len,
- &len, &idtype);
- if (!pp)
- goto nosid;
-
- sid = calloc (PF_KEY_V2_ROUND (len + 1) + sizeof *sid, sizeof (u_int8_t));
- if (!sid)
- {
- free (pp);
- goto cleanup;
+ /* Setup identity extensions. */
+ if (isakmp_sa->id_i) {
+ pp = pf_key_v2_convert_id(isakmp_sa->id_i, isakmp_sa->id_i_len,
+ &len, &idtype);
+ if (!pp)
+ goto nosid;
+
+ sid = calloc(PF_KEY_V2_ROUND(len + 1) + sizeof *sid, sizeof(u_int8_t));
+ if (!sid) {
+ free(pp);
+ goto cleanup;
+ }
+ sid->sadb_ident_type = idtype;
+ sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK) +
+ PF_KEY_V2_ROUND(len + 1) / PF_KEY_V2_CHUNK;
+ if ((isakmp_sa->initiator && !incoming) ||
+ (!isakmp_sa->initiator && incoming))
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
+ else
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
+
+ memcpy(sid + 1, pp, len);
+ free(pp);
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) sid,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ sid = 0;
+
+nosid:
+ if (sid)
+ free(sid);
+ sid = 0;
}
-
- sid->sadb_ident_type = idtype;
- sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
- + PF_KEY_V2_ROUND (len + 1) / PF_KEY_V2_CHUNK;
- if ((isakmp_sa->initiator && !incoming)
- || (!isakmp_sa->initiator && incoming))
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
- else
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
-
- memcpy (sid + 1, pp, len);
- free (pp);
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)sid,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- sid = 0;
-
- nosid:
- if (sid)
- free (sid);
- sid = 0;
- }
-
- if (isakmp_sa->id_r)
- {
- pp = pf_key_v2_convert_id (isakmp_sa->id_r, isakmp_sa->id_r_len,
- &len, &idtype);
- if (!pp)
- goto nodid;
-
- sid = calloc (PF_KEY_V2_ROUND (len + 1) + sizeof *sid, sizeof (u_int8_t));
- if (!sid)
- {
- free (pp);
- goto cleanup;
+ if (isakmp_sa->id_r) {
+ pp = pf_key_v2_convert_id(isakmp_sa->id_r, isakmp_sa->id_r_len,
+ &len, &idtype);
+ if (!pp)
+ goto nodid;
+
+ sid = calloc(PF_KEY_V2_ROUND(len + 1) + sizeof *sid, sizeof(u_int8_t));
+ if (!sid) {
+ free(pp);
+ goto cleanup;
+ }
+ sid->sadb_ident_type = idtype;
+ sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK) +
+ PF_KEY_V2_ROUND(len + 1) / PF_KEY_V2_CHUNK;
+ if ((isakmp_sa->initiator && !incoming) ||
+ (!isakmp_sa->initiator && incoming))
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
+ else
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
+
+ memcpy(sid + 1, pp, len);
+ free(pp);
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) sid,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ sid = 0;
+
+nodid:
+ if (sid)
+ free(sid);
+ sid = 0;
}
-
- sid->sadb_ident_type = idtype;
- sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
- + PF_KEY_V2_ROUND (len + 1) / PF_KEY_V2_CHUNK;
- if ((isakmp_sa->initiator && !incoming)
- || (!isakmp_sa->initiator && incoming))
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
- else
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
-
- memcpy (sid + 1, pp, len);
- free (pp);
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)sid,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- sid = 0;
-
- nodid:
- if (sid)
- free (sid);
- sid = 0;
- }
#endif /* KAME */
#ifdef SADB_X_CREDTYPE_NONE
- /*
- * Send received credentials to the kernel. We don't bother with
- * our credentials, since the process either knows them (if it specified
- * them with setsockopt()), or has no business looking at them (e.g.,
- * system wide certs).
- */
- if (isakmp_sa->recv_cert)
- {
- switch (isakmp_sa->recv_certtype)
- {
- case ISAKMP_CERTENC_NONE:
- /* Nothing to be done here. */
- break;
+ /*
+ * Send received credentials to the kernel. We don't bother with
+ * our credentials, since the process either knows them (if it specified
+ * them with setsockopt()), or has no business looking at them (e.g.,
+ * system wide certs).
+ */
+ if (isakmp_sa->recv_cert) {
+ switch (isakmp_sa->recv_certtype) {
+ case ISAKMP_CERTENC_NONE:
+ /* Nothing to be done here. */
+ break;
#if defined (USE_KEYNOTE) && defined (SADB_X_EXT_REMOTE_CREDENTIALS)
- case ISAKMP_CERTENC_KEYNOTE:
- len = strlen (isakmp_sa->recv_cert);
- cred = calloc (PF_KEY_V2_ROUND (len) + sizeof *cred,
- sizeof (u_int8_t));
- if (!cred)
- goto cleanup;
-
- cred->sadb_x_cred_len = ((sizeof *cred) / PF_KEY_V2_CHUNK) +
- PF_KEY_V2_ROUND (len) / PF_KEY_V2_CHUNK;
- cred->sadb_x_cred_exttype = SADB_X_EXT_REMOTE_CREDENTIALS;
- cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
- memcpy (cred + 1, isakmp_sa->recv_cert, len);
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)cred,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- break;
-#endif /* USE_KEYNOTE */
+ case ISAKMP_CERTENC_KEYNOTE:
+ len = strlen(isakmp_sa->recv_cert);
+ cred = calloc(PF_KEY_V2_ROUND(len) + sizeof *cred,
+ sizeof(u_int8_t));
+ if (!cred)
+ goto cleanup;
+
+ cred->sadb_x_cred_len = ((sizeof *cred) / PF_KEY_V2_CHUNK) +
+ PF_KEY_V2_ROUND(len) / PF_KEY_V2_CHUNK;
+ cred->sadb_x_cred_exttype = SADB_X_EXT_REMOTE_CREDENTIALS;
+ cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
+ memcpy(cred + 1, isakmp_sa->recv_cert, len);
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) cred,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ break;
+#endif /* USE_KEYNOTE */
#if defined (USE_X509) && defined (SADB_X_EXT_REMOTE_CREDENTIALS)
- case ISAKMP_CERTENC_X509_SIG:
- {
- u_int8_t *data;
- u_int32_t datalen;
- struct cert_handler *handler;
-
- /* We do it this way to avoid weird includes. */
- handler = cert_get (ISAKMP_CERTENC_X509_SIG);
- if (!handler)
- break;
- handler->cert_serialize (isakmp_sa->recv_cert, &data, &datalen);
- if (!data)
- break;
-
- len = datalen;
- cred = calloc (PF_KEY_V2_ROUND (len) + sizeof *cred,
- sizeof (u_int8_t));
- if (!cred)
- {
- free (data);
- goto cleanup;
- }
-
- cred->sadb_x_cred_len = ((sizeof *cred) / PF_KEY_V2_CHUNK) +
- PF_KEY_V2_ROUND (len) / PF_KEY_V2_CHUNK;
- cred->sadb_x_cred_exttype = SADB_X_EXT_REMOTE_CREDENTIALS;
- cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
- memcpy (cred + 1, data, len);
- free (data);
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)cred,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- }
- break;
+ case ISAKMP_CERTENC_X509_SIG:
+ {
+ u_int8_t *data;
+ u_int32_t datalen;
+ struct cert_handler *handler;
+
+ /* We do it this way to avoid weird includes. */
+ handler = cert_get(ISAKMP_CERTENC_X509_SIG);
+ if (!handler)
+ break;
+ handler->cert_serialize(isakmp_sa->recv_cert,
+ &data, &datalen);
+ if (!data)
+ break;
+
+ len = datalen;
+ cred = calloc(PF_KEY_V2_ROUND(len) + sizeof *cred,
+ sizeof(u_int8_t));
+ if (!cred) {
+ free(data);
+ goto cleanup;
+ }
+ cred->sadb_x_cred_len =
+ ((sizeof *cred) / PF_KEY_V2_CHUNK) +
+ PF_KEY_V2_ROUND(len) / PF_KEY_V2_CHUNK;
+ cred->sadb_x_cred_exttype =
+ SADB_X_EXT_REMOTE_CREDENTIALS;
+ cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
+ memcpy(cred + 1, data, len);
+ free(data);
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) cred,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ }
+ break;
#endif /* USE_X509 */
+ }
}
- }
#endif /* SADB_X_CREDTYPE_NONE */
#ifdef SADB_X_AUTHTYPE_NONE
- /*
- * Tell the kernel what the peer used to authenticate, unless it was a
- * passphrase.
- */
- if (isakmp_sa->recv_key)
- {
- u_int8_t *data;
-
- /*
- * If it's a private key, we shouldn't pass it to the kernel for
- * processes to see; successful authentication of Phase 1 implies
- * that the process already knew the passphrase. On the other hand,
- * we don't want to reveal to processes any system-wide passphrases
- * used for authentication with remote systems. Same reason we don't
- * send up the key (private or passphrase) we used to authenticate
- * with the peer.
- */
- if (isakmp_sa->recv_keytype == ISAKMP_KEY_PASSPHRASE)
- goto doneauth;
-
- key_serialize (isakmp_sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
- isakmp_sa->recv_key, &data, &len);
- if (!data)
- goto cleanup;
-
- cred = calloc (PF_KEY_V2_ROUND (len) + sizeof *cred, sizeof (u_int8_t));
- if (!cred)
- {
- free (data);
- goto cleanup;
- }
+ /*
+ * Tell the kernel what the peer used to authenticate, unless it was a
+ * passphrase.
+ */
+ if (isakmp_sa->recv_key) {
+ u_int8_t *data;
+
+ /*
+ * If it's a private key, we shouldn't pass it to the kernel for
+ * processes to see; successful authentication of Phase 1 implies
+ * that the process already knew the passphrase. On the other hand,
+ * we don't want to reveal to processes any system-wide passphrases
+ * used for authentication with remote systems. Same reason we don't
+ * send up the key (private or passphrase) we used to authenticate
+ * with the peer.
+ */
+ if (isakmp_sa->recv_keytype == ISAKMP_KEY_PASSPHRASE)
+ goto doneauth;
+
+ key_serialize(isakmp_sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
+ isakmp_sa->recv_key, &data, &len);
+ if (!data)
+ goto cleanup;
+
+ cred = calloc(PF_KEY_V2_ROUND(len) + sizeof *cred, sizeof(u_int8_t));
+ if (!cred) {
+ free(data);
+ goto cleanup;
+ }
+ cred->sadb_x_cred_len = ((sizeof *cred) / PF_KEY_V2_CHUNK) +
+ PF_KEY_V2_ROUND(len) / PF_KEY_V2_CHUNK;
+ cred->sadb_x_cred_exttype = SADB_X_EXT_REMOTE_AUTH;
+ memcpy(cred + 1, data, len);
+ free(data);
- cred->sadb_x_cred_len = ((sizeof *cred) / PF_KEY_V2_CHUNK) +
- PF_KEY_V2_ROUND (len) / PF_KEY_V2_CHUNK;
- cred->sadb_x_cred_exttype = SADB_X_EXT_REMOTE_AUTH;
- memcpy (cred + 1, data, len);
- free (data);
+ switch (isakmp_sa->recv_keytype) {
+ case ISAKMP_KEY_RSA:
+ cred->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
+ break;
- switch (isakmp_sa->recv_keytype)
- {
- case ISAKMP_KEY_RSA:
- cred->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
- break;
+ default:
+ log_print("pf_key_v2_set_spi: unknown received key type %d",
+ isakmp_sa->recv_keytype);
+ free(cred);
+ goto cleanup;
+ }
- default:
- log_print ("pf_key_v2_set_spi: unknown received key type %d",
- isakmp_sa->recv_keytype);
- free (cred);
- goto cleanup;
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) cred,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
}
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)cred,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- }
- doneauth:
-#endif /* SADB_X_AUTHTYPE_NONE */
+doneauth:
+#endif /* SADB_X_AUTHTYPE_NONE */
#ifdef SADB_X_EXT_FLOW_TYPE
- /* Setup the flow type extension. */
- bzero (&flowtype, sizeof flowtype);
- flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
- flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
- flowtype.sadb_protocol_direction
- = incoming ? IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)&flowtype, 0) == -1)
- goto cleanup;
-
- bzero (&tprotocol, sizeof tprotocol);
- tprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- tprotocol.sadb_protocol_len = sizeof tprotocol / PF_KEY_V2_CHUNK;
- tprotocol.sadb_protocol_proto = isa->tproto;
-
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)&tprotocol, 0) == -1)
- goto cleanup;
-
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (isa->src_net));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype =
- incoming ? SADB_X_EXT_DST_FLOW : SADB_X_EXT_SRC_FLOW;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, isa->src_net, 0, isa->sport, 0);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype =
- incoming ? SADB_X_EXT_DST_MASK : SADB_X_EXT_SRC_MASK;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, isa->src_mask, 0,
- isa->sport ? 0xffff : 0, 0);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype =
- incoming ? SADB_X_EXT_SRC_FLOW : SADB_X_EXT_DST_FLOW;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, isa->dst_net, 0, isa->dport, 0);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype =
- incoming ? SADB_X_EXT_SRC_MASK : SADB_X_EXT_DST_MASK;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, isa->dst_mask, 0,
- isa->dport ? 0xffff : 0, 0);
- if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
+ /* Setup the flow type extension. */
+ bzero(&flowtype, sizeof flowtype);
+ flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
+ flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
+ flowtype.sadb_protocol_direction = incoming ?
+ IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) & flowtype, 0) == -1)
+ goto cleanup;
+
+ bzero(&tprotocol, sizeof tprotocol);
+ tprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+ tprotocol.sadb_protocol_len = sizeof tprotocol / PF_KEY_V2_CHUNK;
+ tprotocol.sadb_protocol_proto = isa->tproto;
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) & tprotocol, 0) == -1)
+ goto cleanup;
+
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(isa->src_net));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = incoming ?
+ SADB_X_EXT_DST_FLOW : SADB_X_EXT_SRC_FLOW;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, isa->src_net, 0, isa->sport, 0);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype =
+ incoming ? SADB_X_EXT_DST_MASK : SADB_X_EXT_SRC_MASK;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, isa->src_mask, 0,
+ isa->sport ? 0xffff : 0, 0);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = incoming ?
+ SADB_X_EXT_SRC_FLOW : SADB_X_EXT_DST_FLOW;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, isa->dst_net, 0, isa->dport, 0);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype =
+ incoming ? SADB_X_EXT_SRC_MASK : SADB_X_EXT_DST_MASK;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, isa->dst_mask, 0,
+ isa->dport ? 0xffff : 0, 0);
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
#endif /* SADB_X_EXT_FLOW_TYPE */
- /* XXX Here can sensitivity extensions be setup. */
+ /* XXX Here can sensitivity extensions be setup. */
#ifdef USE_DEBUG
- if (sockaddr2text (dst, &addr_str, 0))
- addr_str = 0;
+ if (sockaddr2text(dst, &addr_str, 0))
+ addr_str = 0;
- LOG_DBG ((LOG_SYSDEP, 10, "pf_key_v2_set_spi: satype %d dst %s SPI 0x%x",
+ LOG_DBG((LOG_SYSDEP, 10, "pf_key_v2_set_spi: satype %d dst %s SPI 0x%x",
msg.sadb_msg_satype, addr_str ? addr_str : "unknown",
- ntohl (ssa.sadb_sa_spi)));
-
- if (addr_str)
- free (addr_str);
-#endif /* USE_DEBUG */
-
- /*
- * Although PF_KEY knows about expirations, it is unreliable per the specs
- * thus we need to do them inside isakmpd as well.
- */
- if (sa->seconds)
- if (sa_setup_expirations (sa))
- goto cleanup;
-
- ret = pf_key_v2_call (update);
- pf_key_v2_msg_free (update);
- update = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- pf_key_v2_msg_free (ret);
- ret = 0;
-
- /*
- * If we are doing an addition into an SADB shared with our peer, errors
- * here are to be expected as the peer will already have created the SA,
- * and can thus be ignored.
- */
- if (err && !(msg.sadb_msg_type == SADB_ADD
- && conf_get_str ("General", "Shared-SADB")))
- {
- log_print ("pf_key_v2_set_spi: %s: %s",
- msg.sadb_msg_type == SADB_ADD ? "ADD" : "UPDATE",
- strerror (err));
- goto cleanup;
- }
-
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_set_spi: done"));
-
- return 0;
-
- cleanup:
- if (sid)
- free (sid);
- if (addr)
- free (addr);
- if (life)
- free (life);
- if (key)
- free (key);
- if (update)
- pf_key_v2_msg_free (update);
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
+ ntohl(ssa.sadb_sa_spi)));
+
+ if (addr_str)
+ free(addr_str);
+#endif /* USE_DEBUG */
+
+ /*
+ * Although PF_KEY knows about expirations, it is unreliable per the specs
+ * thus we need to do them inside isakmpd as well.
+ */
+ if (sa->seconds)
+ if (sa_setup_expirations(sa))
+ goto cleanup;
+
+ ret = pf_key_v2_call(update);
+ pf_key_v2_msg_free(update);
+ update = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ pf_key_v2_msg_free(ret);
+ ret = 0;
+
+ /*
+ * If we are doing an addition into an SADB shared with our peer, errors
+ * here are to be expected as the peer will already have created the SA,
+ * and can thus be ignored.
+ */
+ if (err && !(msg.sadb_msg_type == SADB_ADD &&
+ conf_get_str("General", "Shared-SADB"))) {
+ log_print("pf_key_v2_set_spi: %s: %s",
+ msg.sadb_msg_type == SADB_ADD ? "ADD" : "UPDATE",
+ strerror(err));
+ goto cleanup;
+ }
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_set_spi: done"));
+
+ return 0;
+
+cleanup:
+ if (sid)
+ free(sid);
+ if (addr)
+ free(addr);
+ if (life)
+ free(life);
+ if (key)
+ free(key);
+ if (update)
+ pf_key_v2_msg_free(update);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
}
static __inline__ int
-pf_key_v2_mask_to_bits (u_int32_t mask)
+pf_key_v2_mask_to_bits(u_int32_t mask)
{
- u_int32_t hmask = ntohl (mask);
- return (33 - ffs (~hmask + 1)) % 33;
+ u_int32_t hmask = ntohl(mask);
+
+ return (33 - ffs(~hmask + 1)) % 33;
}
static int
-pf_key_v2_mask6_to_bits (u_int8_t *mask)
+pf_key_v2_mask6_to_bits(u_int8_t * mask)
{
- int n;
- bit_ffc (mask, 128, &n);
- return n == -1 ? 128 : n;
+ int n;
+
+ bit_ffc(mask, 128, &n);
+ return n == -1 ? 128 : n;
}
/*
@@ -1728,740 +1659,718 @@ pf_key_v2_mask6_to_bits (u_int8_t *mask)
* Should probably be moved to sysdep.c
*/
static int
-pf_key_v2_flow (struct sockaddr *laddr, struct sockaddr *lmask,
- struct sockaddr *raddr, struct sockaddr *rmask,
- u_int8_t tproto, u_int16_t sport, u_int16_t dport,
- u_int8_t *spi, u_int8_t proto, struct sockaddr *dst,
- struct sockaddr *src, int delete, int ingress,
- u_int8_t srcid_type, u_int8_t *srcid, int srcid_len,
- u_int8_t dstid_type, u_int8_t *dstid, int dstid_len,
- struct ipsec_proto *iproto)
+pf_key_v2_flow(struct sockaddr *laddr, struct sockaddr *lmask,
+ struct sockaddr *raddr, struct sockaddr *rmask,
+ u_int8_t tproto, u_int16_t sport, u_int16_t dport,
+ u_int8_t *spi, u_int8_t proto, struct sockaddr *dst,
+ struct sockaddr *src, int delete, int ingress,
+ u_int8_t srcid_type, u_int8_t *srcid, int srcid_len,
+ u_int8_t dstid_type, u_int8_t *dstid, int dstid_len,
+ struct ipsec_proto *iproto)
{
#ifdef USE_DEBUG
- char *laddr_str, *lmask_str, *raddr_str, *rmask_str;
+ char *laddr_str, *lmask_str, *raddr_str, *rmask_str;
#endif
#if defined (SADB_X_ADDFLOW) && defined (SADB_X_DELFLOW)
- struct sadb_msg msg;
+ struct sadb_msg msg;
#if defined (SADB_X_EXT_FLOW_TYPE)
- struct sadb_protocol flowtype;
- struct sadb_ident *sid = 0;
+ struct sadb_protocol flowtype;
+ struct sadb_ident *sid = 0;
#else
- struct sadb_sa ssa;
+ struct sadb_sa ssa;
#endif
- struct sadb_address *addr = 0;
- struct sadb_protocol tprotocol;
- struct pf_key_v2_msg *flow = 0, *ret = 0;
- size_t len;
- int err;
+ struct sadb_address *addr = 0;
+ struct sadb_protocol tprotocol;
+ struct pf_key_v2_msg *flow = 0, *ret = 0;
+ size_t len;
+ int err;
#if !defined (SADB_X_SAFLAGS_INGRESS_FLOW) && !defined (SADB_X_EXT_FLOW_TYPE)
- if (ingress)
- return 0;
-#endif
-
- msg.sadb_msg_type = delete ? SADB_X_DELFLOW : SADB_X_ADDFLOW;
- switch (proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- break;
- case IPSEC_PROTO_IPCOMP:
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- break;
- default:
- log_print ("pf_key_v2_flow: invalid proto %d", proto);
- goto cleanup;
- }
- msg.sadb_msg_seq = 0;
- flow = pf_key_v2_msg_new (&msg, 0);
- if (!flow)
- goto cleanup;
-
-#if defined (SADB_X_EXT_FLOW_TYPE)
- if (!delete)
- {
- /* Setup the source ID, if provided. */
- if (srcid)
- {
- sid = calloc (PF_KEY_V2_ROUND (srcid_len + 1) + sizeof *sid,
- sizeof (u_int8_t));
- if (!sid)
- goto cleanup;
-
- sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
- + PF_KEY_V2_ROUND (srcid_len + 1) / PF_KEY_V2_CHUNK;
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
- sid->sadb_ident_type = srcid_type;
-
- memcpy (sid + 1, srcid, srcid_len);
-
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)sid,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
-
- sid = 0;
+ if (ingress)
+ return 0;
+#endif
+
+ msg.sadb_msg_type = delete ? SADB_X_DELFLOW : SADB_X_ADDFLOW;
+ switch (proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ break;
+ case IPSEC_PROTO_IPCOMP:
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ break;
+ default:
+ log_print("pf_key_v2_flow: invalid proto %d", proto);
+ goto cleanup;
}
+ msg.sadb_msg_seq = 0;
+ flow = pf_key_v2_msg_new(&msg, 0);
+ if (!flow)
+ goto cleanup;
- /* Setup the destination ID, if provided. */
- if (dstid)
- {
- sid = calloc (PF_KEY_V2_ROUND (dstid_len + 1) + sizeof *sid,
- sizeof (u_int8_t));
- if (!sid)
- goto cleanup;
+#if defined (SADB_X_EXT_FLOW_TYPE)
+ if (!delete) {
+ /* Setup the source ID, if provided. */
+ if (srcid) {
+ sid = calloc(PF_KEY_V2_ROUND(srcid_len + 1) + sizeof *sid,
+ sizeof(u_int8_t));
+ if (!sid)
+ goto cleanup;
+
+ sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
+ + PF_KEY_V2_ROUND(srcid_len + 1) / PF_KEY_V2_CHUNK;
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
+ sid->sadb_ident_type = srcid_type;
+
+ memcpy(sid + 1, srcid, srcid_len);
+
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) sid,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+
+ sid = 0;
+ }
+ /* Setup the destination ID, if provided. */
+ if (dstid) {
+ sid = calloc(PF_KEY_V2_ROUND(dstid_len + 1) + sizeof *sid,
+ sizeof(u_int8_t));
+ if (!sid)
+ goto cleanup;
- sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
- + PF_KEY_V2_ROUND (dstid_len + 1) / PF_KEY_V2_CHUNK;
- sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
- sid->sadb_ident_type = dstid_type;
+ sid->sadb_ident_len = ((sizeof *sid) / PF_KEY_V2_CHUNK)
+ + PF_KEY_V2_ROUND(dstid_len + 1) / PF_KEY_V2_CHUNK;
+ sid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
+ sid->sadb_ident_type = dstid_type;
- memcpy (sid + 1, dstid, dstid_len);
+ memcpy(sid + 1, dstid, dstid_len);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)sid,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) sid,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
- sid = 0;
+ sid = 0;
+ }
}
- }
-
- /* Setup the flow type extension. */
- bzero (&flowtype, sizeof flowtype);
- flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
- flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
- flowtype.sadb_protocol_direction
- = ingress ? IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
- flowtype.sadb_protocol_proto
- = ingress ? SADB_X_FLOW_TYPE_USE : SADB_X_FLOW_TYPE_REQUIRE;
-
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&flowtype, 0) == -1)
- goto cleanup;
-#else /* SADB_X_EXT_FLOW_TYPE */
- /* Setup the SA extension. */
- ssa.sadb_sa_exttype = SADB_EXT_SA;
- ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
- memcpy (&ssa.sadb_sa_spi, spi, sizeof ssa.sadb_sa_spi);
- ssa.sadb_sa_replay = 0;
- ssa.sadb_sa_state = 0;
- ssa.sadb_sa_auth = 0;
- ssa.sadb_sa_encrypt = 0;
- ssa.sadb_sa_flags = 0;
+ /* Setup the flow type extension. */
+ bzero(&flowtype, sizeof flowtype);
+ flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
+ flowtype.sadb_protocol_len = sizeof flowtype / PF_KEY_V2_CHUNK;
+ flowtype.sadb_protocol_direction
+ = ingress ? IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
+ flowtype.sadb_protocol_proto
+ = ingress ? SADB_X_FLOW_TYPE_USE : SADB_X_FLOW_TYPE_REQUIRE;
+
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) & flowtype, 0) == -1)
+ goto cleanup;
+#else /* SADB_X_EXT_FLOW_TYPE */
+ /* Setup the SA extension. */
+ ssa.sadb_sa_exttype = SADB_EXT_SA;
+ ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
+ memcpy(&ssa.sadb_sa_spi, spi, sizeof ssa.sadb_sa_spi);
+ ssa.sadb_sa_replay = 0;
+ ssa.sadb_sa_state = 0;
+ ssa.sadb_sa_auth = 0;
+ ssa.sadb_sa_encrypt = 0;
+ ssa.sadb_sa_flags = 0;
#if defined (SADB_X_SAFLAGS_INGRESS_FLOW)
- if (ingress)
- ssa.sadb_sa_flags |= SADB_X_SAFLAGS_INGRESS_FLOW;
+ if (ingress)
+ ssa.sadb_sa_flags |= SADB_X_SAFLAGS_INGRESS_FLOW;
#endif
#if defined (SADB_X_SAFLAGS_REPLACEFLOW)
- if (!delete && !ingress)
- ssa.sadb_sa_flags |= SADB_X_SAFLAGS_REPLACEFLOW;
+ if (!delete && !ingress)
+ ssa.sadb_sa_flags |= SADB_X_SAFLAGS_REPLACEFLOW;
#endif
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&ssa, 0) == -1)
- goto cleanup;
-#endif /* SADB_X_EXT_FLOW_TYPE */
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) & ssa, 0) == -1)
+ goto cleanup;
+#endif /* SADB_X_EXT_FLOW_TYPE */
- /*
- * Setup the ADDRESS extensions.
- */
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (src));
+ /*
+ * Setup the ADDRESS extensions.
+ */
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(src));
#if !defined (SADB_X_EXT_FLOW_TYPE)
- if (!delete || ingress)
+ if (!delete || ingress)
#else
- if (!delete)
-#endif /* SADB_X_EXT_FLOW_TYPE */
- {
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
+ if (!delete)
+#endif /* SADB_X_EXT_FLOW_TYPE */
+ {
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
#if defined (SADB_X_EXT_FLOW_TYPE)
- pf_key_v2_setup_sockaddr (addr + 1, src, dst, 0, ingress);
+ pf_key_v2_setup_sockaddr(addr + 1, src, dst, 0, ingress);
#else
- pf_key_v2_setup_sockaddr (addr + 1, dst, 0, 0, 0);
+ pf_key_v2_setup_sockaddr(addr + 1, dst, 0, 0, 0);
#endif
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
- }
-
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (laddr));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, laddr, 0, sport, 0);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_X_EXT_SRC_MASK;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, lmask, 0, sport ? 0xffff : 0, 0);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_X_EXT_DST_FLOW;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, raddr, 0, dport, 0);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_X_EXT_DST_MASK;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
- addr->sadb_address_reserved = 0;
- pf_key_v2_setup_sockaddr (addr + 1, rmask, 0, dport ? 0xffff : 0, 0);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- /* Setup the protocol extension. */
- bzero (&tprotocol, sizeof tprotocol);
- tprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- tprotocol.sadb_protocol_len = sizeof tprotocol / PF_KEY_V2_CHUNK;
- tprotocol.sadb_protocol_proto = tproto;
-
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&tprotocol, 0) == -1)
- goto cleanup;
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+ }
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(laddr));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, laddr, 0, sport, 0);
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_X_EXT_SRC_MASK;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, lmask, 0, sport ? 0xffff : 0, 0);
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_X_EXT_DST_FLOW;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, raddr, 0, dport, 0);
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_X_EXT_DST_MASK;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ pf_key_v2_setup_sockaddr(addr + 1, rmask, 0, dport ? 0xffff : 0, 0);
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ /* Setup the protocol extension. */
+ bzero(&tprotocol, sizeof tprotocol);
+ tprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+ tprotocol.sadb_protocol_len = sizeof tprotocol / PF_KEY_V2_CHUNK;
+ tprotocol.sadb_protocol_proto = tproto;
+
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) & tprotocol, 0) == -1)
+ goto cleanup;
#ifdef USE_DEBUG
- if (sockaddr2text (laddr, &laddr_str, 0))
- laddr_str = 0;
- if (sockaddr2text (lmask, &lmask_str, 0))
- lmask_str = 0;
- if (sockaddr2text (raddr, &raddr_str, 0))
- raddr_str = 0;
- if (sockaddr2text (rmask, &rmask_str, 0))
- rmask_str = 0;
-
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_flow: src %s %s dst %s %s proto %u sport %u dport %u",
- laddr_str ? laddr_str : "<??\?>", lmask_str ? lmask_str : "<??\?>",
- raddr_str ? raddr_str : "<??\?>", rmask_str ? rmask_str : "<??\?>",
- tproto, ntohs (sport), ntohs (dport)));
-
- if (laddr_str)
- free (laddr_str);
- if (lmask_str)
- free (lmask_str);
- if (raddr_str)
- free (raddr_str);
- if (rmask_str)
- free (rmask_str);
-#endif /* USE_DEBUG */
-
- ret = pf_key_v2_call (flow);
- pf_key_v2_msg_free (flow);
- flow = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- if (err == ESRCH) /* These are common and usually harmless. */
- LOG_DBG ((LOG_SYSDEP, 10, "pf_key_v2_flow: %sFLOW: %s",
- delete ? "DEL" : "ADD", strerror (err)));
- else
- log_print ("pf_key_v2_flow: %sFLOW: %s", delete ? "DEL" : "ADD",
- strerror (err));
- goto cleanup;
- }
- pf_key_v2_msg_free (ret);
-
- LOG_DBG ((LOG_MISC, 50, "pf_key_v2_flow: %sFLOW: done",
- delete ? "DEL" : "ADD"));
-
- return 0;
-
- cleanup:
+ if (sockaddr2text(laddr, &laddr_str, 0))
+ laddr_str = 0;
+ if (sockaddr2text(lmask, &lmask_str, 0))
+ lmask_str = 0;
+ if (sockaddr2text(raddr, &raddr_str, 0))
+ raddr_str = 0;
+ if (sockaddr2text(rmask, &rmask_str, 0))
+ rmask_str = 0;
+
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_flow: src %s %s dst %s %s proto %u sport %u dport %u",
+ laddr_str ? laddr_str : "<??\?>", lmask_str ? lmask_str : "<??\?>",
+ raddr_str ? raddr_str : "<??\?>", rmask_str ? rmask_str : "<??\?>",
+ tproto, ntohs(sport), ntohs(dport)));
+
+ if (laddr_str)
+ free(laddr_str);
+ if (lmask_str)
+ free(lmask_str);
+ if (raddr_str)
+ free(raddr_str);
+ if (rmask_str)
+ free(rmask_str);
+#endif /* USE_DEBUG */
+
+ ret = pf_key_v2_call(flow);
+ pf_key_v2_msg_free(flow);
+ flow = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ if (err == ESRCH) /* These are common and usually
+ * harmless. */
+ LOG_DBG((LOG_SYSDEP, 10, "pf_key_v2_flow: %sFLOW: %s",
+ delete ? "DEL" : "ADD", strerror(err)));
+ else
+ log_print("pf_key_v2_flow: %sFLOW: %s", delete ? "DEL" : "ADD",
+ strerror(err));
+ goto cleanup;
+ }
+ pf_key_v2_msg_free(ret);
+
+ LOG_DBG((LOG_MISC, 50, "pf_key_v2_flow: %sFLOW: done",
+ delete ? "DEL" : "ADD"));
+
+ return 0;
+
+cleanup:
#if defined (SADB_X_EXT_FLOW_TYPE)
- if (sid)
- free (sid);
-#endif /* SADB_X_EXT_FLOW_TYPE */
- if (addr)
- free (addr);
- if (flow)
- pf_key_v2_msg_free (flow);
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
+ if (sid)
+ free(sid);
+#endif /* SADB_X_EXT_FLOW_TYPE */
+ if (addr)
+ free(addr);
+ if (flow)
+ pf_key_v2_msg_free(flow);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
#elif defined (SADB_X_SPDADD) && defined (SADB_X_SPDDELETE)
- struct sadb_msg msg;
- struct sadb_x_policy *policy = 0;
- struct sadb_x_ipsecrequest *ipsecrequest;
- struct sadb_x_sa2 ssa2;
- struct sadb_address *addr = 0;
- struct sockaddr *saddr;
- struct pf_key_v2_msg *flow = 0, *ret = 0;
- u_int8_t *policy_buf;
- size_t len;
- int err;
- struct sockaddr_in *ip4_sa;
- struct sockaddr_in6 *ip6_sa;
-
- msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDADD;
- msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
- msg.sadb_msg_seq = 0;
- flow = pf_key_v2_msg_new (&msg, 0);
- if (!flow)
- goto cleanup;
-
- memset (&ssa2, 0, sizeof ssa2);
- ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
- ssa2.sadb_x_sa2_mode = 0;
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&ssa2, 0) == -1)
- goto cleanup;
-
- /*
- * Setup the ADDRESS extensions.
- */
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (src));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ struct sadb_msg msg;
+ struct sadb_x_policy *policy = 0;
+ struct sadb_x_ipsecrequest *ipsecrequest;
+ struct sadb_x_sa2 ssa2;
+ struct sadb_address *addr = 0;
+ struct sockaddr *saddr;
+ struct pf_key_v2_msg *flow = 0, *ret = 0;
+ u_int8_t *policy_buf;
+ size_t len;
+ int err;
+ struct sockaddr_in *ip4_sa;
+ struct sockaddr_in6 *ip6_sa;
+
+ msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDADD;
+ msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
+ msg.sadb_msg_seq = 0;
+ flow = pf_key_v2_msg_new(&msg, 0);
+ if (!flow)
+ goto cleanup;
+
+ memset(&ssa2, 0, sizeof ssa2);
+ ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_mode = 0;
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) & ssa2, 0) == -1)
+ goto cleanup;
+
+ /*
+ * Setup the ADDRESS extensions.
+ */
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(src));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifdef LINUX_IPSEC
- addr->sadb_address_proto = tproto;
+ addr->sadb_address_proto = tproto;
#else
- addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
+ addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
#endif
- addr->sadb_address_reserved = 0;
+ addr->sadb_address_reserved = 0;
#ifdef LINUX_IPSEC
- pf_key_v2_setup_sockaddr (addr + 1, laddr, 0, sport, 0);
+ pf_key_v2_setup_sockaddr(addr + 1, laddr, 0, sport, 0);
#else
- pf_key_v2_setup_sockaddr (addr + 1, laddr, 0, IPSEC_PORT_ANY, 0);
+ pf_key_v2_setup_sockaddr(addr + 1, laddr, 0, IPSEC_PORT_ANY, 0);
#endif
- switch (laddr->sa_family)
- {
- case AF_INET:
- ip4_sa = (struct sockaddr_in *)lmask;
- addr->sadb_address_prefixlen
- = pf_key_v2_mask_to_bits (ip4_sa->sin_addr.s_addr);
- break;
- case AF_INET6:
- ip6_sa = (struct sockaddr_in6 *)lmask;
- addr->sadb_address_prefixlen
- = pf_key_v2_mask6_to_bits (&ip6_sa->sin6_addr.s6_addr[0]);
- break;
- }
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (raddr));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ switch (laddr->sa_family) {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *) lmask;
+ addr->sadb_address_prefixlen
+ = pf_key_v2_mask_to_bits(ip4_sa->sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *) lmask;
+ addr->sadb_address_prefixlen
+ = pf_key_v2_mask6_to_bits(&ip6_sa->sin6_addr.s6_addr[0]);
+ break;
+ }
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(raddr));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifdef LINUX_IPSEC
- addr->sadb_address_proto = tproto;
+ addr->sadb_address_proto = tproto;
#else
- addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
+ addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
#endif
- addr->sadb_address_reserved = 0;
+ addr->sadb_address_reserved = 0;
#ifdef LINUX_IPSEC
- pf_key_v2_setup_sockaddr (addr + 1, raddr, 0, dport, 0);
+ pf_key_v2_setup_sockaddr(addr + 1, raddr, 0, dport, 0);
#else
- pf_key_v2_setup_sockaddr (addr + 1, raddr, 0, IPSEC_PORT_ANY, 0);
+ pf_key_v2_setup_sockaddr(addr + 1, raddr, 0, IPSEC_PORT_ANY, 0);
#endif
- switch (raddr->sa_family)
- {
- case AF_INET:
- ip4_sa = (struct sockaddr_in *)rmask;
- addr->sadb_address_prefixlen
- = pf_key_v2_mask_to_bits (ip4_sa->sin_addr.s_addr);
- break;
- case AF_INET6:
- ip6_sa = (struct sockaddr_in6 *)rmask;
- addr->sadb_address_prefixlen
- = pf_key_v2_mask6_to_bits (&ip6_sa->sin6_addr.s6_addr[0]);
- break;
- }
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- /* Setup the POLICY extension. */
- len = sizeof *policy + sizeof *ipsecrequest +
- 2 * PF_KEY_V2_ROUND (sysdep_sa_len (src));
- policy_buf = (u_int8_t *)calloc (1, len);
- if (!policy_buf)
- {
- log_error ("pf_key_v2_flow: calloc %lu failed", (unsigned long)len);
- goto cleanup;
- }
-
- policy = (struct sadb_x_policy *)policy_buf;
- policy->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy->sadb_x_policy_len = len / PF_KEY_V2_CHUNK;
- policy->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
- if (ingress)
- policy->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- else
- policy->sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
- policy->sadb_x_policy_reserved = 0;
-
- /* Setup the IPSECREQUEST extension part. */
- ipsecrequest = (struct sadb_x_ipsecrequest *)(policy + 1);
- ipsecrequest->sadb_x_ipsecrequest_len = len - sizeof *policy;
- switch (proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- ipsecrequest->sadb_x_ipsecrequest_proto = IPPROTO_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- ipsecrequest->sadb_x_ipsecrequest_proto = IPPROTO_AH;
- break;
- default:
- log_print ("pf_key_v2_flow: invalid proto %d", proto);
- goto cleanup;
- }
+ switch (raddr->sa_family) {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *) rmask;
+ addr->sadb_address_prefixlen
+ = pf_key_v2_mask_to_bits(ip4_sa->sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *) rmask;
+ addr->sadb_address_prefixlen
+ = pf_key_v2_mask6_to_bits(&ip6_sa->sin6_addr.s6_addr[0]);
+ break;
+ }
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ /* Setup the POLICY extension. */
+ len = sizeof *policy + sizeof *ipsecrequest +
+ 2 * PF_KEY_V2_ROUND(sysdep_sa_len(src));
+ policy_buf = (u_int8_t *) calloc(1, len);
+ if (!policy_buf) {
+ log_error("pf_key_v2_flow: calloc %lu failed", (unsigned long) len);
+ goto cleanup;
+ }
+ policy = (struct sadb_x_policy *) policy_buf;
+ policy->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy->sadb_x_policy_len = len / PF_KEY_V2_CHUNK;
+ policy->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
+ if (ingress)
+ policy->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+ else
+ policy->sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+ policy->sadb_x_policy_reserved = 0;
+
+ /* Setup the IPSECREQUEST extension part. */
+ ipsecrequest = (struct sadb_x_ipsecrequest *) (policy + 1);
+ ipsecrequest->sadb_x_ipsecrequest_len = len - sizeof *policy;
+ switch (proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ ipsecrequest->sadb_x_ipsecrequest_proto = IPPROTO_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ ipsecrequest->sadb_x_ipsecrequest_proto = IPPROTO_AH;
+ break;
+ default:
+ log_print("pf_key_v2_flow: invalid proto %d", proto);
+ goto cleanup;
+ }
#if defined (LINUX_IPSEC)
- if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
- ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
- else
- ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
+ if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
+ ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
+ else
+ ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
#else
- ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL; /* XXX */
+ ipsecrequest->sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL; /* XXX */
#endif
- ipsecrequest->sadb_x_ipsecrequest_level
- = ingress ? IPSEC_LEVEL_USE : IPSEC_LEVEL_REQUIRE;
- ipsecrequest->sadb_x_ipsecrequest_reqid = 0; /* XXX */
-
- /* Add source and destination addresses. */
- saddr = (struct sockaddr *)(ipsecrequest + 1);
- pf_key_v2_setup_sockaddr (saddr, src, 0, 0, 0);
- switch (src->sa_family)
- {
- case AF_INET:
- saddr = (struct sockaddr *)((struct sockaddr_in *)saddr + 1);
- break;
- case AF_INET6:
- saddr = (struct sockaddr *)((struct sockaddr_in6 *)saddr + 1);
- break;
- }
- pf_key_v2_setup_sockaddr (saddr, dst, 0, 0, 0);
- if (pf_key_v2_msg_add (flow, (struct sadb_ext *)policy, 0) == -1)
- goto cleanup;
+ ipsecrequest->sadb_x_ipsecrequest_level
+ = ingress ? IPSEC_LEVEL_USE : IPSEC_LEVEL_REQUIRE;
+ ipsecrequest->sadb_x_ipsecrequest_reqid = 0; /* XXX */
+
+ /* Add source and destination addresses. */
+ saddr = (struct sockaddr *) (ipsecrequest + 1);
+ pf_key_v2_setup_sockaddr(saddr, src, 0, 0, 0);
+ switch (src->sa_family) {
+ case AF_INET:
+ saddr = (struct sockaddr *) ((struct sockaddr_in *) saddr + 1);
+ break;
+ case AF_INET6:
+ saddr = (struct sockaddr *) ((struct sockaddr_in6 *) saddr + 1);
+ break;
+ }
+ pf_key_v2_setup_sockaddr(saddr, dst, 0, 0, 0);
+ if (pf_key_v2_msg_add(flow, (struct sadb_ext *) policy, 0) == -1)
+ goto cleanup;
#ifdef USE_DEBUG
- if (sockaddr2text (laddr, &laddr_str, 0))
- laddr_str = 0;
- if (sockaddr2text (lmask, &lmask_str, 0))
- lmask_str = 0;
- if (sockaddr2text (raddr, &raddr_str, 0))
- raddr_str = 0;
- if (sockaddr2text (rmask, &rmask_str, 0))
- rmask_str = 0;
-
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_flow: src %s %s dst %s %s",
- laddr_str ? laddr_str : "<??\?>", lmask_str ? lmask_str : "<??\?>",
- raddr_str ? raddr_str : "<??\?>",
- rmask_str ? rmask_str : "<??\?>"));
-
- if (laddr_str)
- free (laddr_str);
- if (lmask_str)
- free (lmask_str);
- if (raddr_str)
- free (raddr_str);
- if (rmask_str)
- free (rmask_str);
-#endif
+ if (sockaddr2text(laddr, &laddr_str, 0))
+ laddr_str = 0;
+ if (sockaddr2text(lmask, &lmask_str, 0))
+ lmask_str = 0;
+ if (sockaddr2text(raddr, &raddr_str, 0))
+ raddr_str = 0;
+ if (sockaddr2text(rmask, &rmask_str, 0))
+ rmask_str = 0;
+
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_flow: src %s %s dst %s %s",
+ laddr_str ? laddr_str : "<??\?>", lmask_str ? lmask_str : "<??\?>",
+ raddr_str ? raddr_str : "<??\?>",
+ rmask_str ? rmask_str : "<??\?>"));
+
+ if (laddr_str)
+ free(laddr_str);
+ if (lmask_str)
+ free(lmask_str);
+ if (raddr_str)
+ free(raddr_str);
+ if (rmask_str)
+ free(rmask_str);
+#endif
+
+ ret = pf_key_v2_call(flow);
+ pf_key_v2_msg_free(flow);
+ flow = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (!delete && err == EEXIST) {
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_flow: SPDADD returns EEXIST"));
+ } else if (err) {
+ log_print("pf_key_v2_flow: SPD%s: %s", delete ? "DELETE" : "ADD",
+ strerror(err));
+ goto cleanup;
+ }
+ pf_key_v2_msg_free(ret);
+
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_flow: SPD%s: done",
+ delete ? "DELETE" : "ADD"));
- ret = pf_key_v2_call (flow);
- pf_key_v2_msg_free (flow);
- flow = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (!delete && err == EEXIST)
- {
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_flow: SPDADD returns EEXIST"));
- }
- else if (err)
- {
- log_print ("pf_key_v2_flow: SPD%s: %s", delete ? "DELETE" : "ADD",
- strerror (err));
- goto cleanup;
- }
- pf_key_v2_msg_free (ret);
-
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_flow: SPD%s: done",
- delete ? "DELETE" : "ADD"));
-
- return 0;
-
- cleanup:
- if (addr)
- free (addr);
- if (policy)
- free (policy);
- if (flow)
- pf_key_v2_msg_free (flow);
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
+ return 0;
+
+cleanup:
+ if (addr)
+ free(addr);
+ if (policy)
+ free(policy);
+ if (flow)
+ pf_key_v2_msg_free(flow);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
#else
- log_print ("pf_key_v2_flow: not supported in pure PF_KEYv2");
- return -1;
+ log_print("pf_key_v2_flow: not supported in pure PF_KEYv2");
+ return -1;
#endif
}
#ifndef KAME
static u_int8_t *
-pf_key_v2_convert_id (u_int8_t *id, int idlen, size_t *reslen, int *idtype)
+pf_key_v2_convert_id(u_int8_t * id, int idlen, size_t * reslen, int *idtype)
{
- u_int8_t *addr, *res = 0;
- char addrbuf[ADDRESS_MAX + 5];
-
- switch (id[0])
- {
- case IPSEC_ID_FQDN:
- res = calloc (idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ,
- sizeof (u_int8_t));
- if (!res)
- return 0;
-
- *reslen = idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
- memcpy (res, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, *reslen);
- *idtype = SADB_IDENTTYPE_FQDN;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: FQDN %.*s",
- (int)*reslen, res));
- return res;
-
- case IPSEC_ID_USER_FQDN:
- res = calloc (idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ,
- sizeof (u_int8_t));
- if (!res)
- return 0;
-
- *reslen = idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
- memcpy (res, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, *reslen);
- *idtype = SADB_IDENTTYPE_USERFQDN;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: UFQDN %.*s",
- (int)*reslen, res));
- return res;
-
- case IPSEC_ID_IPV4_ADDR: /* XXX CONNECTION ? */
- if (inet_ntop (AF_INET, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- addrbuf, ADDRESS_MAX) == NULL)
- return 0;
- *reslen = strlen (addrbuf) + 3;
- strlcat (addrbuf, "/32", ADDRESS_MAX + 5);
- res = (u_int8_t *)strdup (addrbuf);
- if (!res)
- return 0;
- *idtype = SADB_IDENTTYPE_PREFIX;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv4 address %s", res));
- return res;
-
- case IPSEC_ID_IPV6_ADDR: /* XXX CONNECTION ? */
- if (inet_ntop (AF_INET6, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- addrbuf, ADDRESS_MAX) == NULL)
- return 0;
- *reslen = strlen (addrbuf) + 4;
- strlcat (addrbuf, "/128", ADDRESS_MAX + 5);
- res = (u_int8_t *)strdup (addrbuf);
- if (!res)
- return 0;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv6 address %s", res));
- *idtype = SADB_IDENTTYPE_PREFIX;
- return res;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET: /* XXX PREFIX */
- addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
- if (inet_ntop (AF_INET, addr, addrbuf, ADDRESS_MAX) == NULL)
- return 0;
- snprintf (addrbuf + strlen (addrbuf), ADDRESS_MAX - strlen (addrbuf),
- "/%d", pf_key_v2_mask_to_bits ((u_int32_t)
- *(addr +
- sizeof (struct in_addr))));
- *reslen = strlen (addrbuf);
- res = (u_int8_t *)strdup (addrbuf);
- if (!res)
- return 0;
- *idtype = SADB_IDENTTYPE_PREFIX;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv4 subnet %s", res));
- return res;
+ u_int8_t *addr, *res = 0;
+ char addrbuf[ADDRESS_MAX + 5];
+
+ switch (id[0]) {
+ case IPSEC_ID_FQDN:
+ res = calloc(idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ,
+ sizeof(u_int8_t));
+ if (!res)
+ return 0;
+
+ *reslen = idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
+ memcpy(res, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, *reslen);
+ *idtype = SADB_IDENTTYPE_FQDN;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: FQDN %.*s",
+ (int) *reslen, res));
+ return res;
+
+ case IPSEC_ID_USER_FQDN:
+ res = calloc(idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ,
+ sizeof(u_int8_t));
+ if (!res)
+ return 0;
+
+ *reslen = idlen - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
+ memcpy(res, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, *reslen);
+ *idtype = SADB_IDENTTYPE_USERFQDN;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: UFQDN %.*s",
+ (int) *reslen, res));
+ return res;
+
+ case IPSEC_ID_IPV4_ADDR: /* XXX CONNECTION ? */
+ if (inet_ntop(AF_INET, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ addrbuf, ADDRESS_MAX) == NULL)
+ return 0;
+ *reslen = strlen(addrbuf) + 3;
+ strlcat(addrbuf, "/32", ADDRESS_MAX + 5);
+ res = (u_int8_t *) strdup(addrbuf);
+ if (!res)
+ return 0;
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv4 address %s", res));
+ return res;
+
+ case IPSEC_ID_IPV6_ADDR: /* XXX CONNECTION ? */
+ if (inet_ntop(AF_INET6, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ addrbuf, ADDRESS_MAX) == NULL)
+ return 0;
+ *reslen = strlen(addrbuf) + 4;
+ strlcat(addrbuf, "/128", ADDRESS_MAX + 5);
+ res = (u_int8_t *) strdup(addrbuf);
+ if (!res)
+ return 0;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv6 address %s", res));
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ return res;
+
+ case IPSEC_ID_IPV4_ADDR_SUBNET: /* XXX PREFIX */
+ addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ if (inet_ntop(AF_INET, addr, addrbuf, ADDRESS_MAX) == NULL)
+ return 0;
+ snprintf(addrbuf + strlen(addrbuf), ADDRESS_MAX - strlen(addrbuf),
+ "/%d", pf_key_v2_mask_to_bits((u_int32_t)
+ * (addr +
+ sizeof(struct in_addr))));
+ *reslen = strlen(addrbuf);
+ res = (u_int8_t *) strdup(addrbuf);
+ if (!res)
+ return 0;
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv4 subnet %s", res));
+ return res;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX PREFIX */
+ addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ if (inet_ntop(AF_INET6, addr, addrbuf, ADDRESS_MAX) == NULL)
+ return 0;
+ snprintf(addrbuf + strlen(addrbuf), ADDRESS_MAX - strlen(addrbuf),
+ "/%d", pf_key_v2_mask6_to_bits(addr +
+ sizeof(struct in6_addr)));
+ *reslen = strlen(addrbuf);
+ res = (u_int8_t *) strdup(addrbuf);
+ if (!res)
+ return 0;
+ LOG_DBG((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv6 subnet %s", res));
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ return res;
+
+ case IPSEC_ID_IPV4_RANGE:
+ case IPSEC_ID_IPV6_RANGE:
+ case IPSEC_ID_DER_ASN1_DN:
+ case IPSEC_ID_DER_ASN1_GN:
+ case IPSEC_ID_KEY_ID:
+ /* XXX Not implemented yet. */
+ return 0;
+ }
- case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX PREFIX */
- addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
- if (inet_ntop (AF_INET6, addr, addrbuf, ADDRESS_MAX) == NULL)
- return 0;
- snprintf (addrbuf + strlen (addrbuf), ADDRESS_MAX - strlen (addrbuf),
- "/%d", pf_key_v2_mask6_to_bits (addr +
- sizeof (struct in6_addr)));
- *reslen = strlen (addrbuf);
- res = (u_int8_t *)strdup (addrbuf);
- if (!res)
return 0;
- LOG_DBG ((LOG_SYSDEP, 40, "pf_key_v2_convert_id: IPv6 subnet %s", res));
- *idtype = SADB_IDENTTYPE_PREFIX;
- return res;
-
- case IPSEC_ID_IPV4_RANGE:
- case IPSEC_ID_IPV6_RANGE:
- case IPSEC_ID_DER_ASN1_DN:
- case IPSEC_ID_DER_ASN1_GN:
- case IPSEC_ID_KEY_ID:
- /* XXX Not implemented yet. */
- return 0;
- }
-
- return 0;
}
#endif
/* Enable a flow given an SA. */
int
-pf_key_v2_enable_sa (struct sa *sa, struct sa *isakmp_sa)
+pf_key_v2_enable_sa(struct sa * sa, struct sa * isakmp_sa)
{
- struct ipsec_sa *isa = sa->data;
- struct sockaddr *dst, *src;
- int error;
- struct proto *proto = TAILQ_FIRST (&sa->protos);
- int sidtype = 0, didtype = 0;
- size_t sidlen = 0, didlen = 0;
- u_int8_t *sid = 0, *did = 0;
+ struct ipsec_sa *isa = sa->data;
+ struct sockaddr *dst, *src;
+ int error;
+ struct proto *proto = TAILQ_FIRST(&sa->protos);
+ int sidtype = 0, didtype = 0;
+ size_t sidlen = 0, didlen = 0;
+ u_int8_t *sid = 0, *did = 0;
#if !defined (SADB_X_EXT_FLOW_TYPE)
- struct sockaddr_storage hostmask_storage;
- struct sockaddr *hostmask = (struct sockaddr *)&hostmask_storage;
-#endif /* SADB_X_EXT_FLOW_TYPE */
+ struct sockaddr_storage hostmask_storage;
+ struct sockaddr *hostmask = (struct sockaddr *) & hostmask_storage;
+#endif /* SADB_X_EXT_FLOW_TYPE */
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- sa->transport->vtbl->get_src (sa->transport, &src);
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ sa->transport->vtbl->get_src(sa->transport, &src);
#if defined (SADB_X_EXT_FLOW_TYPE)
- if (isakmp_sa->id_i)
- {
- if (isakmp_sa->initiator)
- sid = pf_key_v2_convert_id (isakmp_sa->id_i, isakmp_sa->id_i_len,
- &sidlen, &sidtype);
- else
- did = pf_key_v2_convert_id (isakmp_sa->id_i, isakmp_sa->id_i_len,
- &didlen, &didtype);
- }
-
- if (isakmp_sa->id_r)
- {
- if (isakmp_sa->initiator)
- did = pf_key_v2_convert_id (isakmp_sa->id_r, isakmp_sa->id_r_len,
- &didlen, &didtype);
- else
- sid = pf_key_v2_convert_id (isakmp_sa->id_r, isakmp_sa->id_r_len,
- &sidlen, &sidtype);
- }
-#endif /* SADB_X_EXT_FLOW_TYPE */
-
- error = pf_key_v2_flow (isa->src_net, isa->src_mask, isa->dst_net,
- isa->dst_mask, isa->tproto, isa->sport, isa->dport,
- proto->spi[0], proto->proto, dst, src, 0, 0,
- sidtype, sid, sidlen, didtype, did, didlen,
- proto->data);
- if (error)
- goto cleanup;
+ if (isakmp_sa->id_i) {
+ if (isakmp_sa->initiator)
+ sid = pf_key_v2_convert_id(isakmp_sa->id_i, isakmp_sa->id_i_len,
+ &sidlen, &sidtype);
+ else
+ did = pf_key_v2_convert_id(isakmp_sa->id_i, isakmp_sa->id_i_len,
+ &didlen, &didtype);
+ }
+ if (isakmp_sa->id_r) {
+ if (isakmp_sa->initiator)
+ did = pf_key_v2_convert_id(isakmp_sa->id_r, isakmp_sa->id_r_len,
+ &didlen, &didtype);
+ else
+ sid = pf_key_v2_convert_id(isakmp_sa->id_r, isakmp_sa->id_r_len,
+ &sidlen, &sidtype);
+ }
+#endif /* SADB_X_EXT_FLOW_TYPE */
+
+ error = pf_key_v2_flow(isa->src_net, isa->src_mask, isa->dst_net,
+ isa->dst_mask, isa->tproto, isa->sport, isa->dport,
+ proto->spi[0], proto->proto, dst, src, 0, 0,
+ sidtype, sid, sidlen, didtype, did, didlen,
+ proto->data);
+ if (error)
+ goto cleanup;
#if !defined (SADB_X_EXT_FLOW_TYPE)
- /* Set hostmask to '-1'. */
- switch (dst->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)hostmask)->sin_family = AF_INET;
+ /* Set hostmask to '-1'. */
+ switch (dst->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) hostmask)->sin_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- ((struct sockaddr_in *)hostmask)->sin_len = sizeof (struct in_addr);
+ ((struct sockaddr_in *) hostmask)->sin_len = sizeof(struct in_addr);
#endif
- memset (&((struct sockaddr_in *)hostmask)->sin_addr.s_addr, 0xff,
- sizeof (struct in_addr));
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)hostmask)->sin6_family = AF_INET6;
+ memset(&((struct sockaddr_in *) hostmask)->sin_addr.s_addr, 0xff,
+ sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) hostmask)->sin6_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- ((struct sockaddr_in6 *)hostmask)->sin6_len = sizeof (struct in6_addr);
+ ((struct sockaddr_in6 *) hostmask)->sin6_len = sizeof(struct in6_addr);
#endif
- memset (&((struct sockaddr_in6 *)hostmask)->sin6_addr.s6_addr, 0xff,
- sizeof (struct in6_addr));
- break;
- }
-
- /* Ingress flows, handling SA bundles. */
- while (TAILQ_NEXT (proto, link))
- {
- error = pf_key_v2_flow (dst, hostmask, src, hostmask, 0, 0, 0,
- proto->spi[1], proto->proto, src, dst,
- 0, 1, 0, 0, 0, 0, 0, 0, proto->data);
- if (error)
- goto cleanup;
- proto = TAILQ_NEXT (proto, link);
- }
-#endif /* SADB_X_EXT_FLOW_TYPE */
+ memset(&((struct sockaddr_in6 *) hostmask)->sin6_addr.s6_addr, 0xff,
+ sizeof(struct in6_addr));
+ break;
+ }
+
+ /* Ingress flows, handling SA bundles. */
+ while (TAILQ_NEXT(proto, link)) {
+ error = pf_key_v2_flow(dst, hostmask, src, hostmask, 0, 0, 0,
+ proto->spi[1], proto->proto, src, dst,
+ 0, 1, 0, 0, 0, 0, 0, 0, proto->data);
+ if (error)
+ goto cleanup;
+ proto = TAILQ_NEXT(proto, link);
+ }
+#endif /* SADB_X_EXT_FLOW_TYPE */
- error = pf_key_v2_flow (isa->dst_net, isa->dst_mask, isa->src_net,
- isa->src_mask, isa->tproto, isa->dport, isa->sport,
- proto->spi[1], proto->proto, src, dst, 0, 1,
- sidtype, sid, sidlen, didtype, did, didlen,
- proto->data);
+ error = pf_key_v2_flow(isa->dst_net, isa->dst_mask, isa->src_net,
+ isa->src_mask, isa->tproto, isa->dport, isa->sport,
+ proto->spi[1], proto->proto, src, dst, 0, 1,
+ sidtype, sid, sidlen, didtype, did, didlen,
+ proto->data);
- cleanup:
+cleanup:
#if defined (SADB_X_EXT_FLOW_TYPE)
- if (sid)
- free (sid);
- if (did)
- free (did);
-#endif /* SADB_X_EXT_FLOW_TYPE */
+ if (sid)
+ free(sid);
+ if (did)
+ free(did);
+#endif /* SADB_X_EXT_FLOW_TYPE */
- return error;
+ return error;
}
#if defined (SADB_X_ASKPOLICY)
/* Increase reference count of refcounted sections. */
static int
-pf_key_v2_conf_refinc (int af, char *section)
+pf_key_v2_conf_refinc(int af, char *section)
{
- char conn[22];
- int num;
+ char conn[22];
+ int num;
- if (!section)
- return 0;
+ if (!section)
+ return 0;
- num = conf_get_num (section, "Refcount", 0);
- if (num == 0)
- return 0;
+ num = conf_get_num(section, "Refcount", 0);
+ if (num == 0)
+ return 0;
- snprintf (conn, sizeof conn, "%d", num + 1);
- conf_set (af, section, "Refcount", conn, 1, 0);
- return 0;
+ snprintf(conn, sizeof conn, "%d", num + 1);
+ conf_set(af, section, "Refcount", conn, 1, 0);
+ return 0;
}
#endif
@@ -2470,159 +2379,147 @@ pf_key_v2_conf_refinc (int af, char *section)
* Don't touch non-refcounted (statically defined) sections.
*/
static int
-pf_key_v2_conf_refhandle (int af, char *section)
+pf_key_v2_conf_refhandle(int af, char *section)
{
- char conn[22];
- int num;
-
- if (!section)
- return 0;
-
- num = conf_get_num (section, "Refcount", 0);
- if (num == 1)
- {
- conf_remove_section (af, section);
- num--;
- }
- else
- if (num != 0)
- {
- snprintf (conn, sizeof conn, "%d", num - 1);
- conf_set (af, section, "Refcount", conn, 1, 0);
- }
-
- return num;
+ char conn[22];
+ int num;
+
+ if (!section)
+ return 0;
+
+ num = conf_get_num(section, "Refcount", 0);
+ if (num == 1) {
+ conf_remove_section(af, section);
+ num--;
+ } else if (num != 0) {
+ snprintf(conn, sizeof conn, "%d", num - 1);
+ conf_set(af, section, "Refcount", conn, 1, 0);
+ }
+ return num;
}
/* Remove all dynamically-established configuration entries. */
static int
-pf_key_v2_remove_conf (char *section)
+pf_key_v2_remove_conf(char *section)
{
- char *ikepeer, *localid, *remoteid, *configname;
- struct conf_list_node *attr;
- struct conf_list *attrs;
- int af;
-
- if (!section)
- return 0;
-
- if (!conf_get_str (section, "Phase"))
- return 0;
-
- /* Only remove dynamically-established entries. */
- attrs = conf_get_list (section, "Flags");
- if (attrs)
- {
- for (attr = TAILQ_FIRST (&attrs->fields); attr;
- attr = TAILQ_NEXT (attr, link))
- if (!strcasecmp (attr->field, "__ondemand"))
- goto passed;
-
- conf_free_list (attrs);
- }
-
- return 0;
-
- passed:
- conf_free_list (attrs);
+ char *ikepeer, *localid, *remoteid, *configname;
+ struct conf_list_node *attr;
+ struct conf_list *attrs;
+ int af;
+
+ if (!section)
+ return 0;
+
+ if (!conf_get_str(section, "Phase"))
+ return 0;
+
+ /* Only remove dynamically-established entries. */
+ attrs = conf_get_list(section, "Flags");
+ if (attrs) {
+ for (attr = TAILQ_FIRST(&attrs->fields); attr;
+ attr = TAILQ_NEXT(attr, link))
+ if (!strcasecmp(attr->field, "__ondemand"))
+ goto passed;
+
+ conf_free_list(attrs);
+ }
+ return 0;
- af = conf_begin ();
+passed:
+ conf_free_list(attrs);
- configname = conf_get_str (section, "Configuration");
- conf_remove_section (af, configname);
+ af = conf_begin();
- /* These are the Phase 2 Local/Remote IDs. */
- localid = conf_get_str (section, "Local-ID");
- pf_key_v2_conf_refhandle (af, localid);
+ configname = conf_get_str(section, "Configuration");
+ conf_remove_section(af, configname);
- remoteid = conf_get_str (section, "Remote-ID");
- pf_key_v2_conf_refhandle (af, remoteid);
+ /* These are the Phase 2 Local/Remote IDs. */
+ localid = conf_get_str(section, "Local-ID");
+ pf_key_v2_conf_refhandle(af, localid);
- ikepeer = conf_get_str (section, "ISAKMP-peer");
+ remoteid = conf_get_str(section, "Remote-ID");
+ pf_key_v2_conf_refhandle(af, remoteid);
- pf_key_v2_conf_refhandle (af, section);
+ ikepeer = conf_get_str(section, "ISAKMP-peer");
- if (ikepeer)
- {
- remoteid = conf_get_str (ikepeer, "Remote-ID");
- localid = conf_get_str (ikepeer, "ID");
- configname = conf_get_str (ikepeer, "Configuration");
+ pf_key_v2_conf_refhandle(af, section);
- pf_key_v2_conf_refhandle (af, ikepeer);
- pf_key_v2_conf_refhandle (af, configname);
+ if (ikepeer) {
+ remoteid = conf_get_str(ikepeer, "Remote-ID");
+ localid = conf_get_str(ikepeer, "ID");
+ configname = conf_get_str(ikepeer, "Configuration");
- /* Phase 1 IDs */
- pf_key_v2_conf_refhandle (af, localid);
- pf_key_v2_conf_refhandle (af, remoteid);
- }
+ pf_key_v2_conf_refhandle(af, ikepeer);
+ pf_key_v2_conf_refhandle(af, configname);
- conf_end (af, 1);
- return 0;
+ /* Phase 1 IDs */
+ pf_key_v2_conf_refhandle(af, localid);
+ pf_key_v2_conf_refhandle(af, remoteid);
+ }
+ conf_end(af, 1);
+ return 0;
}
/* Disable a flow given a SA. */
static int
-pf_key_v2_disable_sa (struct sa *sa, int incoming)
+pf_key_v2_disable_sa(struct sa * sa, int incoming)
{
- struct ipsec_sa *isa = sa->data;
- struct sockaddr *dst, *src;
- struct proto *proto = TAILQ_FIRST (&sa->protos);
+ struct ipsec_sa *isa = sa->data;
+ struct sockaddr *dst, *src;
+ struct proto *proto = TAILQ_FIRST(&sa->protos);
#if !defined (SADB_X_EXT_FLOW_TYPE)
- struct sockaddr_storage hostmask_storage;
- struct sockaddr *hostmask = (struct sockaddr *)&hostmask_storage;
- int error;
-#endif /* SADB_X_EXT_FLOW_TYPE */
-
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- sa->transport->vtbl->get_src (sa->transport, &src);
-
- if (!incoming)
- return pf_key_v2_flow (isa->src_net, isa->src_mask, isa->dst_net,
- isa->dst_mask, isa->tproto, isa->sport, isa->dport,
- proto->spi[0], proto->proto, src, dst, 1, 0,
- 0, 0, 0, 0, 0, 0, proto->data);
- else
- {
+ struct sockaddr_storage hostmask_storage;
+ struct sockaddr *hostmask = (struct sockaddr *) & hostmask_storage;
+ int error;
+#endif /* SADB_X_EXT_FLOW_TYPE */
+
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ sa->transport->vtbl->get_src(sa->transport, &src);
+
+ if (!incoming)
+ return pf_key_v2_flow(isa->src_net, isa->src_mask, isa->dst_net,
+ isa->dst_mask, isa->tproto, isa->sport, isa->dport,
+ proto->spi[0], proto->proto, src, dst, 1, 0,
+ 0, 0, 0, 0, 0, 0, proto->data);
+ else {
#if !defined (SADB_X_EXT_FLOW_TYPE)
- /* Set hostmask to '-1'. */
- switch (dst->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)hostmask)->sin_family = AF_INET;
+ /* Set hostmask to '-1'. */
+ switch (dst->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) hostmask)->sin_family = AF_INET;
#ifndef USE_OLD_SOCKADDR
- ((struct sockaddr_in *)hostmask)->sin_len = sizeof (struct in_addr);
+ ((struct sockaddr_in *) hostmask)->sin_len = sizeof(struct in_addr);
#endif
- memset (&((struct sockaddr_in *)hostmask)->sin_addr.s_addr, 0xff,
- sizeof (struct in_addr));
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)hostmask)->sin6_family = AF_INET6;
+ memset(&((struct sockaddr_in *) hostmask)->sin_addr.s_addr, 0xff,
+ sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) hostmask)->sin6_family = AF_INET6;
#ifndef USE_OLD_SOCKADDR
- ((struct sockaddr_in6 *)hostmask)->sin6_len =
- sizeof (struct in6_addr);
+ ((struct sockaddr_in6 *) hostmask)->sin6_len =
+ sizeof(struct in6_addr);
#endif
- memset (&((struct sockaddr_in6 *)hostmask)->sin6_addr.s6_addr, 0xff,
- sizeof (struct in6_addr));
- break;
- }
+ memset(&((struct sockaddr_in6 *) hostmask)->sin6_addr.s6_addr, 0xff,
+ sizeof(struct in6_addr));
+ break;
+ }
- /* Ingress flow --- SA bundles */
- while (TAILQ_NEXT (proto, link))
- {
- error = pf_key_v2_flow (dst, hostmask, src, hostmask, 0, 0, 0,
- proto->spi[1], proto->proto, src, dst,
- 1, 1, 0, 0, 0, 0, 0, 0, proto->data);
- if (error)
- return error;
- proto = TAILQ_NEXT (proto, link);
- }
-#endif /* SADB_X_EXT_FLOW_TYPE */
+ /* Ingress flow --- SA bundles */
+ while (TAILQ_NEXT(proto, link)) {
+ error = pf_key_v2_flow(dst, hostmask, src, hostmask, 0, 0, 0,
+ proto->spi[1], proto->proto, src, dst,
+ 1, 1, 0, 0, 0, 0, 0, 0, proto->data);
+ if (error)
+ return error;
+ proto = TAILQ_NEXT(proto, link);
+ }
+#endif /* SADB_X_EXT_FLOW_TYPE */
- return pf_key_v2_flow (isa->dst_net, isa->dst_mask, isa->src_net,
- isa->src_mask, isa->tproto, isa->dport,
- isa->sport, proto->spi[1], proto->proto,
+ return pf_key_v2_flow(isa->dst_net, isa->dst_mask, isa->src_net,
+ isa->src_mask, isa->tproto, isa->dport,
+ isa->sport, proto->spi[1], proto->proto,
src, dst, 1, 1, 0, 0, 0, 0, 0, 0, proto->data);
- }
+ }
}
/*
@@ -2630,1518 +2527,1351 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
* of the IKE security association SA. Also delete potential flows tied to it.
*/
int
-pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
+pf_key_v2_delete_spi(struct sa * sa, struct proto * proto, int incoming)
{
- struct sadb_msg msg;
- struct sadb_sa ssa;
- struct sadb_address *addr = 0;
- struct sockaddr *saddr;
- int len, err;
- struct pf_key_v2_msg *delete = 0, *ret = 0;
+ struct sadb_msg msg;
+ struct sadb_sa ssa;
+ struct sadb_address *addr = 0;
+ struct sockaddr *saddr;
+ int len, err;
+ struct pf_key_v2_msg *delete = 0, *ret = 0;
#ifdef KAME
- struct sadb_x_sa2 ssa2;
-#endif
-
- /* If it's not an established SA, don't proceed. */
- if (!(sa->flags & SA_FLAG_READY))
- return 0;
-
- /*
- * If the SA was not replaced and was not one acquired through the
- * kernel (ACQUIRE message), remove the flow associated with it.
- * We ignore any errors from the disabling of the flow.
- */
- if (!(sa->flags & SA_FLAG_REPLACED)
- && !(sa->flags & SA_FLAG_ONDEMAND))
- pf_key_v2_disable_sa (sa, incoming);
-
- if (sa->name && !(sa->flags & SA_FLAG_REPLACED))
- {
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_delete_spi: removing configuration %s",
- sa->name));
- pf_key_v2_remove_conf (sa->name);
- }
-
- msg.sadb_msg_type = SADB_DELETE;
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- break;
+ struct sadb_x_sa2 ssa2;
+#endif
+
+ /* If it's not an established SA, don't proceed. */
+ if (!(sa->flags & SA_FLAG_READY))
+ return 0;
+
+ /*
+ * If the SA was not replaced and was not one acquired through the
+ * kernel (ACQUIRE message), remove the flow associated with it.
+ * We ignore any errors from the disabling of the flow.
+ */
+ if (!(sa->flags & SA_FLAG_REPLACED)
+ && !(sa->flags & SA_FLAG_ONDEMAND))
+ pf_key_v2_disable_sa(sa, incoming);
+
+ if (sa->name && !(sa->flags & SA_FLAG_REPLACED)) {
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_delete_spi: removing configuration %s",
+ sa->name));
+ pf_key_v2_remove_conf(sa->name);
+ }
+ msg.sadb_msg_type = SADB_DELETE;
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ break;
#if defined (SADB_X_SATYPE_IPCOMP)
- case IPSEC_PROTO_IPCOMP:
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- break;
+ case IPSEC_PROTO_IPCOMP:
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ break;
#endif
- default:
- log_print ("pf_key_v2_delete_spi: invalid proto %d", proto->proto);
- goto cleanup;
- }
- msg.sadb_msg_seq = 0;
- delete = pf_key_v2_msg_new (&msg, 0);
- if (!delete)
- goto cleanup;
-
- /* Setup the SA extension. */
- ssa.sadb_sa_exttype = SADB_EXT_SA;
- ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
- memcpy (&ssa.sadb_sa_spi, proto->spi[incoming], sizeof ssa.sadb_sa_spi);
- ssa.sadb_sa_replay = 0;
- ssa.sadb_sa_state = 0;
- ssa.sadb_sa_auth = 0;
- ssa.sadb_sa_encrypt = 0;
- ssa.sadb_sa_flags = 0;
- if (pf_key_v2_msg_add (delete, (struct sadb_ext *)&ssa, 0) == -1)
- goto cleanup;
+ default:
+ log_print("pf_key_v2_delete_spi: invalid proto %d", proto->proto);
+ goto cleanup;
+ }
+ msg.sadb_msg_seq = 0;
+ delete = pf_key_v2_msg_new(&msg, 0);
+ if (!delete)
+ goto cleanup;
+
+ /* Setup the SA extension. */
+ ssa.sadb_sa_exttype = SADB_EXT_SA;
+ ssa.sadb_sa_len = sizeof ssa / PF_KEY_V2_CHUNK;
+ memcpy(&ssa.sadb_sa_spi, proto->spi[incoming], sizeof ssa.sadb_sa_spi);
+ ssa.sadb_sa_replay = 0;
+ ssa.sadb_sa_state = 0;
+ ssa.sadb_sa_auth = 0;
+ ssa.sadb_sa_encrypt = 0;
+ ssa.sadb_sa_flags = 0;
+ if (pf_key_v2_msg_add(delete, (struct sadb_ext *) & ssa, 0) == -1)
+ goto cleanup;
#ifdef KAME
- memset (&ssa2, 0, sizeof ssa2);
- ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
- ssa2.sadb_x_sa2_mode = 0;
- if (pf_key_v2_msg_add (delete, (struct sadb_ext *)&ssa2, 0) == -1)
- goto cleanup;
+ memset(&ssa2, 0, sizeof ssa2);
+ ssa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ ssa2.sadb_x_sa2_len = sizeof ssa2 / PF_KEY_V2_CHUNK;
+ ssa2.sadb_x_sa2_mode = 0;
+ if (pf_key_v2_msg_add(delete, (struct sadb_ext *) & ssa2, 0) == -1)
+ goto cleanup;
#endif
- /*
- * Setup the ADDRESS extensions.
- */
- if (incoming)
- sa->transport->vtbl->get_dst (sa->transport, &saddr);
- else
- sa->transport->vtbl->get_src (sa->transport, &saddr);
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (saddr));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ /*
+ * Setup the ADDRESS extensions.
+ */
+ if (incoming)
+ sa->transport->vtbl->get_dst(sa->transport, &saddr);
+ else
+ sa->transport->vtbl->get_src(sa->transport, &saddr);
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(saddr));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, saddr, sysdep_sa_len (saddr));
- switch (saddr->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (delete, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- if (incoming)
- sa->transport->vtbl->get_src (sa->transport, &saddr);
- else
- sa->transport->vtbl->get_dst (sa->transport, &saddr);
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (saddr));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, saddr, sysdep_sa_len(saddr));
+ switch (saddr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(delete, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ if (incoming)
+ sa->transport->vtbl->get_src(sa->transport, &saddr);
+ else
+ sa->transport->vtbl->get_dst(sa->transport, &saddr);
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(saddr));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, saddr, sysdep_sa_len (saddr));
- switch (saddr->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
- break;
- }
- if (pf_key_v2_msg_add (delete, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- ret = pf_key_v2_call (delete);
- pf_key_v2_msg_free (delete);
- delete = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- LOG_DBG ((LOG_SYSDEP, 10, "pf_key_v2_delete_spi: DELETE: %s",
- strerror (err)));
- goto cleanup;
- }
- pf_key_v2_msg_free (ret);
-
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_delete_spi: done"));
-
- return 0;
-
- cleanup:
- if (addr)
- free (addr);
- if (delete)
- pf_key_v2_msg_free (delete);
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, saddr, sysdep_sa_len(saddr));
+ switch (saddr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) (addr + 1))->sin6_port = 0;
+ break;
+ }
+ if (pf_key_v2_msg_add(delete, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ ret = pf_key_v2_call(delete);
+ pf_key_v2_msg_free(delete);
+ delete = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ LOG_DBG((LOG_SYSDEP, 10, "pf_key_v2_delete_spi: DELETE: %s",
+ strerror(err)));
+ goto cleanup;
+ }
+ pf_key_v2_msg_free(ret);
+
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_delete_spi: done"));
+
+ return 0;
+
+cleanup:
+ if (addr)
+ free(addr);
+ if (delete)
+ pf_key_v2_msg_free(delete);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
}
static void
-pf_key_v2_stayalive (struct exchange *exchange, void *vconn, int fail)
+pf_key_v2_stayalive(struct exchange * exchange, void *vconn, int fail)
{
- char *conn = vconn;
- struct sa *sa;
-
- /* XXX What if it is phase 1 ? */
- sa = sa_lookup_by_name (conn, 2);
- if (sa)
- sa->flags |= SA_FLAG_STAYALIVE;
-
- /*
- * Remove failed configuration entry -- call twice because it is
- * created with a Refcount of 2.
- */
- if (fail && (!exchange || exchange->name))
- {
- pf_key_v2_remove_conf (conn);
- pf_key_v2_remove_conf (conn);
- }
+ char *conn = vconn;
+ struct sa *sa;
+
+ /* XXX What if it is phase 1 ? */
+ sa = sa_lookup_by_name(conn, 2);
+ if (sa)
+ sa->flags |= SA_FLAG_STAYALIVE;
+
+ /*
+ * Remove failed configuration entry -- call twice because it is
+ * created with a Refcount of 2.
+ */
+ if (fail && (!exchange || exchange->name)) {
+ pf_key_v2_remove_conf(conn);
+ pf_key_v2_remove_conf(conn);
+ }
}
/* Check if a connection CONN exists, otherwise establish it. */
void
-pf_key_v2_connection_check (char *conn)
+pf_key_v2_connection_check(char *conn)
{
- if (!sa_lookup_by_name (conn, 2))
- {
- LOG_DBG ((LOG_SYSDEP, 70,
- "pf_key_v2_connection_check: SA for %s missing", conn));
- exchange_establish (conn, pf_key_v2_stayalive, conn);
- }
- else
- LOG_DBG ((LOG_SYSDEP, 70, "pf_key_v2_connection_check: SA for %s exists",
- conn));
+ if (!sa_lookup_by_name(conn, 2)) {
+ LOG_DBG((LOG_SYSDEP, 70,
+ "pf_key_v2_connection_check: SA for %s missing", conn));
+ exchange_establish(conn, pf_key_v2_stayalive, conn);
+ } else
+ LOG_DBG((LOG_SYSDEP, 70, "pf_key_v2_connection_check: SA for %s exists",
+ conn));
}
/* Handle a PF_KEY lifetime expiration message PMSG. */
static void
-pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
+pf_key_v2_expire(struct pf_key_v2_msg * pmsg)
{
- struct sadb_msg *msg;
- struct sadb_sa *ssa;
- struct sadb_address *dst;
- struct sockaddr *dstaddr;
- struct sadb_lifetime *life, *lifecurrent;
- struct sa *sa;
- struct pf_key_v2_node *lifenode, *ext;
- char *dst_str;
-
- msg = (struct sadb_msg *)TAILQ_FIRST (pmsg)->seg;
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_SA);
- if (!ext)
- {
- log_print ("pf_key_v2_expire: no SA extension found");
- return;
- }
- ssa = ext->seg;
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST);
- if (!ext)
- {
- log_print ("pf_key_v2_expire: no destination address extension found");
- return;
- }
- dst = ext->seg;
- dstaddr = (struct sockaddr *)(dst + 1);
- lifenode = pf_key_v2_find_ext (pmsg, SADB_EXT_LIFETIME_HARD);
- if (!lifenode)
- lifenode = pf_key_v2_find_ext (pmsg, SADB_EXT_LIFETIME_SOFT);
- if (!lifenode)
- {
- log_print ("pf_key_v2_expire: no lifetime extension found");
- return;
- }
- life = lifenode->seg;
-
- lifenode = pf_key_v2_find_ext (pmsg, SADB_EXT_LIFETIME_CURRENT);
- if (!lifenode)
- {
- log_print ("pf_key_v2_expire: no current lifetime extension found");
- return;
- }
- lifecurrent = lifenode->seg;
+ struct sadb_msg *msg;
+ struct sadb_sa *ssa;
+ struct sadb_address *dst;
+ struct sockaddr *dstaddr;
+ struct sadb_lifetime *life, *lifecurrent;
+ struct sa *sa;
+ struct pf_key_v2_node *lifenode, *ext;
+ char *dst_str;
+
+ msg = (struct sadb_msg *) TAILQ_FIRST(pmsg)->seg;
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_SA);
+ if (!ext) {
+ log_print("pf_key_v2_expire: no SA extension found");
+ return;
+ }
+ ssa = ext->seg;
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_ADDRESS_DST);
+ if (!ext) {
+ log_print("pf_key_v2_expire: no destination address extension found");
+ return;
+ }
+ dst = ext->seg;
+ dstaddr = (struct sockaddr *) (dst + 1);
+ lifenode = pf_key_v2_find_ext(pmsg, SADB_EXT_LIFETIME_HARD);
+ if (!lifenode)
+ lifenode = pf_key_v2_find_ext(pmsg, SADB_EXT_LIFETIME_SOFT);
+ if (!lifenode) {
+ log_print("pf_key_v2_expire: no lifetime extension found");
+ return;
+ }
+ life = lifenode->seg;
+
+ lifenode = pf_key_v2_find_ext(pmsg, SADB_EXT_LIFETIME_CURRENT);
+ if (!lifenode) {
+ log_print("pf_key_v2_expire: no current lifetime extension found");
+ return;
+ }
+ lifecurrent = lifenode->seg;
#ifdef USE_DEBUG
- if (sockaddr2text (dstaddr, &dst_str, 0))
- dst_str = 0;
-
- LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_expire: %s dst %s SPI %x sproto %d",
- life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_SOFT ? "SOFT"
- : "HARD", dst_str ? dst_str : "<unknown>",
- ntohl (ssa->sadb_sa_spi), msg->sadb_msg_satype));
-
- if (dst_str)
- free (dst_str);
-
-#endif /* USE_DEBUG */
-
- /*
- * Find the IPsec SA. The IPsec stack has two SAs for every IKE SA,
- * one outgoing and one incoming, we regard expirations for any of
- * them as an expiration of the full IKE SA. Likewise, in
- * protection suites consisting of more than one protocol, any
- * expired individual IPsec stack SA will be seen as an expiration
- * of the full suite.
- */
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_ESP:
- sa = ipsec_sa_lookup (dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPSEC_ESP);
- break;
-
- case SADB_SATYPE_AH:
- sa = ipsec_sa_lookup (dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPSEC_AH);
- break;
+ if (sockaddr2text(dstaddr, &dst_str, 0))
+ dst_str = 0;
+
+ LOG_DBG((LOG_SYSDEP, 20, "pf_key_v2_expire: %s dst %s SPI %x sproto %d",
+ life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_SOFT ? "SOFT"
+ : "HARD", dst_str ? dst_str : "<unknown>",
+ ntohl(ssa->sadb_sa_spi), msg->sadb_msg_satype));
+
+ if (dst_str)
+ free(dst_str);
+
+#endif /* USE_DEBUG */
+
+ /*
+ * Find the IPsec SA. The IPsec stack has two SAs for every IKE SA,
+ * one outgoing and one incoming, we regard expirations for any of
+ * them as an expiration of the full IKE SA. Likewise, in
+ * protection suites consisting of more than one protocol, any
+ * expired individual IPsec stack SA will be seen as an expiration
+ * of the full suite.
+ */
+ switch (msg->sadb_msg_satype) {
+ case SADB_SATYPE_ESP:
+ sa = ipsec_sa_lookup(dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPSEC_ESP);
+ break;
+
+ case SADB_SATYPE_AH:
+ sa = ipsec_sa_lookup(dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPSEC_AH);
+ break;
#ifdef SADB_X_SATYPE_IPCOMP
- case SADB_X_SATYPE_IPCOMP:
- sa = ipsec_sa_lookup (dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPCOMP);
- break;
+ case SADB_X_SATYPE_IPCOMP:
+ sa = ipsec_sa_lookup(dstaddr, ssa->sadb_sa_spi, IPSEC_PROTO_IPCOMP);
+ break;
#endif
- default:
- /* XXX Log? */
- sa = 0;
- break;
- }
-
- /* If the SA is already gone, don't do anything. */
- if (!sa)
- return;
-
- /*
- * If we got a notification, try to renegotiate the SA -- unless of
- * course it has already been replaced by another.
- * Also, ignore SAs that were not dynamically established, or that
- * did not see any use.
- */
- if (!(sa->flags & SA_FLAG_REPLACED) && (sa->flags & SA_FLAG_ONDEMAND) &&
- lifecurrent->sadb_lifetime_bytes)
- exchange_establish (sa->name, 0, 0);
-
- if (life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_HARD)
- {
- /* Remove the old SA, it isn't useful anymore. */
- sa_free (sa);
- }
+ default:
+ /* XXX Log? */
+ sa = 0;
+ break;
+ }
+
+ /* If the SA is already gone, don't do anything. */
+ if (!sa)
+ return;
+
+ /*
+ * If we got a notification, try to renegotiate the SA -- unless of
+ * course it has already been replaced by another.
+ * Also, ignore SAs that were not dynamically established, or that
+ * did not see any use.
+ */
+ if (!(sa->flags & SA_FLAG_REPLACED) && (sa->flags & SA_FLAG_ONDEMAND) &&
+ lifecurrent->sadb_lifetime_bytes)
+ exchange_establish(sa->name, 0, 0);
+
+ if (life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_HARD) {
+ /* Remove the old SA, it isn't useful anymore. */
+ sa_free(sa);
+ }
}
/* Handle a PF_KEY SA ACQUIRE message PMSG. */
static void
-pf_key_v2_acquire (struct pf_key_v2_msg *pmsg)
+pf_key_v2_acquire(struct pf_key_v2_msg * pmsg)
{
#if defined (SADB_X_ASKPOLICY)
- struct sadb_msg *msg, askpolicy_msg;
- struct pf_key_v2_msg *askpolicy = 0, *ret = 0;
- struct sadb_x_policy policy;
- struct sadb_address *dst = 0, *src = 0;
- struct sockaddr *dstaddr, *srcaddr = 0;
- struct sadb_comb *scmb = 0;
- struct sadb_prop *sprp = 0;
- struct sadb_ident *srcident = 0, *dstident = 0;
- char dstbuf[ADDRESS_MAX], srcbuf[ADDRESS_MAX], *peer = 0, *conn = 0;
- char confname[120];
- char *srcid = 0, *dstid = 0, *prefstring = 0;
- int slen, af, afamily, masklen, buflen;
- struct sockaddr *smask, *sflow, *dmask, *dflow;
- struct sadb_protocol *sproto;
- char ssflow[ADDRESS_MAX], sdflow[ADDRESS_MAX];
- char sdmask[ADDRESS_MAX], ssmask[ADDRESS_MAX];
- char *sidtype = 0, *didtype = 0;
- char lname[100], dname[100], configname[30];
- int shostflag = 0, dhostflag = 0;
- struct pf_key_v2_node *ext;
- struct passwd *pwd = 0;
- u_int16_t sport = 0, dport = 0;
- u_int8_t tproto = 0;
- char tmbuf[sizeof sport * 3 + 1], *xform;
- int connlen;
+ struct sadb_msg *msg, askpolicy_msg;
+ struct pf_key_v2_msg *askpolicy = 0, *ret = 0;
+ struct sadb_x_policy policy;
+ struct sadb_address *dst = 0, *src = 0;
+ struct sockaddr *dstaddr, *srcaddr = 0;
+ struct sadb_comb *scmb = 0;
+ struct sadb_prop *sprp = 0;
+ struct sadb_ident *srcident = 0, *dstident = 0;
+ char dstbuf[ADDRESS_MAX], srcbuf[ADDRESS_MAX], *peer = 0,
+ *conn = 0;
+ char confname[120];
+ char *srcid = 0, *dstid = 0, *prefstring = 0;
+ int slen, af, afamily, masklen, buflen;
+ struct sockaddr *smask, *sflow, *dmask, *dflow;
+ struct sadb_protocol *sproto;
+ char ssflow[ADDRESS_MAX], sdflow[ADDRESS_MAX];
+ char sdmask[ADDRESS_MAX], ssmask[ADDRESS_MAX];
+ char *sidtype = 0, *didtype = 0;
+ char lname[100], dname[100], configname[30];
+ int shostflag = 0, dhostflag = 0;
+ struct pf_key_v2_node *ext;
+ struct passwd *pwd = 0;
+ u_int16_t sport = 0, dport = 0;
+ u_int8_t tproto = 0;
+ char tmbuf[sizeof sport * 3 + 1], *xform;
+ int connlen;
#if defined (SADB_X_CREDTYPE_NONE)
- struct sadb_x_cred *cred = 0, *sauth = 0;
+ struct sadb_x_cred *cred = 0, *sauth = 0;
#endif
- /* This needs to be dynamically allocated. */
- connlen = 22;
- conn = malloc (connlen);
- if (!conn)
- {
- log_error ("pf_key_v2_acquire: malloc (%d) failed", connlen);
- return;
- }
-
- msg = (struct sadb_msg *)TAILQ_FIRST (pmsg)->seg;
-
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_DST);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no destination address specified");
- return;
- }
- dst = ext->seg;
-
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_ADDRESS_SRC);
- if (ext)
- src = ext->seg;
-
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_PROPOSAL);
- if (ext)
- {
- sprp = ext->seg;
- scmb = (struct sadb_comb *)(sprp + 1);
- }
-
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_IDENTITY_SRC);
- if (ext)
- srcident = ext->seg;
-
- ext = pf_key_v2_find_ext (pmsg, SADB_EXT_IDENTITY_DST);
- if (ext)
- dstident = ext->seg;
-
- /* Ask the kernel for the matching policy. */
- bzero (&askpolicy_msg, sizeof askpolicy_msg);
- askpolicy_msg.sadb_msg_type = SADB_X_ASKPOLICY;
- askpolicy = pf_key_v2_msg_new (&askpolicy_msg, 0);
- if (!askpolicy)
- goto fail;
-
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_len = sizeof policy / PF_KEY_V2_CHUNK;
- policy.sadb_x_policy_seq = msg->sadb_msg_seq;
- if (pf_key_v2_msg_add (askpolicy, (struct sadb_ext *)&policy, 0) == -1)
- goto fail;
-
- ret = pf_key_v2_call (askpolicy);
- if (!ret)
- goto fail;
-
- /* Now we have all the information needed. */
-
- ext = pf_key_v2_find_ext (ret, SADB_X_EXT_SRC_FLOW);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no source flow extension found");
- goto fail;
- }
- sflow = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
-
- ext = pf_key_v2_find_ext (ret, SADB_X_EXT_DST_FLOW);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no destination flow extension found");
- goto fail;
- }
- dflow = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
- ext = pf_key_v2_find_ext (ret, SADB_X_EXT_SRC_MASK);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no source mask extension found");
- goto fail;
- }
- smask = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
-
- ext = pf_key_v2_find_ext (ret, SADB_X_EXT_DST_MASK);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no destination mask extension found");
- goto fail;
- }
- dmask = (struct sockaddr *)(((struct sadb_address *)ext->seg) + 1);
-
- ext = pf_key_v2_find_ext (ret, SADB_X_EXT_FLOW_TYPE);
- if (!ext)
- {
- log_print ("pf_key_v2_acquire: no flow type extension found");
- goto fail;
- }
- sproto = ext->seg;
- tproto = sproto->sadb_protocol_proto;
+ /* This needs to be dynamically allocated. */
+ connlen = 22;
+ conn = malloc(connlen);
+ if (!conn) {
+ log_error("pf_key_v2_acquire: malloc (%d) failed", connlen);
+ return;
+ }
+ msg = (struct sadb_msg *) TAILQ_FIRST(pmsg)->seg;
-#if defined (SADB_X_EXT_LOCAL_CREDENTIALS)
- ext = pf_key_v2_find_ext (pmsg, SADB_X_EXT_LOCAL_CREDENTIALS);
- if (ext)
- cred = (struct sadb_x_cred *) ext->seg;
- else
- cred = 0;
-#endif
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_ADDRESS_DST);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no destination address specified");
+ return;
+ }
+ dst = ext->seg;
-#if defined (SADB_X_EXT_LOCAL_AUTH)
- ext = pf_key_v2_find_ext (pmsg, SADB_X_EXT_LOCAL_AUTH);
- if (ext)
- sauth = (struct sadb_x_cred *) ext->seg;
- else
- sauth = 0;
-#endif
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_ADDRESS_SRC);
+ if (ext)
+ src = ext->seg;
- bzero (ssflow, sizeof ssflow);
- bzero (sdflow, sizeof sdflow);
- bzero (ssmask, sizeof ssmask);
- bzero (sdmask, sizeof sdmask);
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_PROPOSAL);
+ if (ext) {
+ sprp = ext->seg;
+ scmb = (struct sadb_comb *) (sprp + 1);
+ }
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_IDENTITY_SRC);
+ if (ext)
+ srcident = ext->seg;
+
+ ext = pf_key_v2_find_ext(pmsg, SADB_EXT_IDENTITY_DST);
+ if (ext)
+ dstident = ext->seg;
+
+ /* Ask the kernel for the matching policy. */
+ bzero(&askpolicy_msg, sizeof askpolicy_msg);
+ askpolicy_msg.sadb_msg_type = SADB_X_ASKPOLICY;
+ askpolicy = pf_key_v2_msg_new(&askpolicy_msg, 0);
+ if (!askpolicy)
+ goto fail;
- sidtype = didtype = "IPV4_ADDR_SUBNET"; /* default */
+ policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_x_policy_len = sizeof policy / PF_KEY_V2_CHUNK;
+ policy.sadb_x_policy_seq = msg->sadb_msg_seq;
+ if (pf_key_v2_msg_add(askpolicy, (struct sadb_ext *) & policy, 0) == -1)
+ goto fail;
- switch (sflow->sa_family)
- {
- case AF_INET:
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)sflow)->sin_addr, ssflow,
- ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- sport = ((struct sockaddr_in *)sflow)->sin_port;
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)dflow)->sin_addr, sdflow,
- ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- dport = ((struct sockaddr_in *)dflow)->sin_port;
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)smask)->sin_addr, ssmask,
- ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)dmask)->sin_addr, sdmask,
- ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- if (((struct sockaddr_in *)smask)->sin_addr.s_addr == INADDR_BROADCAST)
- {
- shostflag = 1;
- sidtype = "IPV4_ADDR";
- }
- if (((struct sockaddr_in *)dmask)->sin_addr.s_addr == INADDR_BROADCAST)
- {
- dhostflag = 1;
- didtype = "IPV4_ADDR";
- }
- break;
+ ret = pf_key_v2_call(askpolicy);
+ if (!ret)
+ goto fail;
- case AF_INET6:
- if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)sflow)->sin6_addr,
- ssflow, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- sport = ((struct sockaddr_in6 *)sflow)->sin6_port;
- if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dflow)->sin6_addr,
- sdflow, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- dport = ((struct sockaddr_in6 *)dflow)->sin6_port;
- if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)smask)->sin6_addr,
- ssmask, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dmask)->sin6_addr,
- sdmask, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
+ /* Now we have all the information needed. */
+
+ ext = pf_key_v2_find_ext(ret, SADB_X_EXT_SRC_FLOW);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no source flow extension found");
+ goto fail;
}
- sidtype = didtype = "IPV6_ADDR_SUBNET";
- if (IN6_IS_ADDR_FULL (&((struct sockaddr_in6 *)smask)->sin6_addr))
- {
- shostflag = 1;
- sidtype = "IPV6_ADDR";
+ sflow = (struct sockaddr *) (((struct sadb_address *) ext->seg) + 1);
+
+ ext = pf_key_v2_find_ext(ret, SADB_X_EXT_DST_FLOW);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no destination flow extension found");
+ goto fail;
}
- if (IN6_IS_ADDR_FULL (&((struct sockaddr_in6 *)dmask)->sin6_addr))
- {
- dhostflag = 1;
- didtype = "IPV6_ADDR";
+ dflow = (struct sockaddr *) (((struct sadb_address *) ext->seg) + 1);
+ ext = pf_key_v2_find_ext(ret, SADB_X_EXT_SRC_MASK);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no source mask extension found");
+ goto fail;
}
- break;
- }
+ smask = (struct sockaddr *) (((struct sadb_address *) ext->seg) + 1);
- dstaddr = (struct sockaddr *)(dst + 1);
- bzero (dstbuf, sizeof dstbuf);
- bzero (srcbuf, sizeof srcbuf);
-
- if (dstaddr->sa_family == 0)
- {
- /* Destination was not specified in the flow -- can we derive it? */
- if (dhostflag == 0)
- {
- log_print("pf_key_v2_acquire: Cannot determine precise destination");
- goto fail;
- }
- dstaddr = dflow;
- }
- switch (dstaddr->sa_family)
- {
- case AF_INET:
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)dstaddr)->sin_addr,
- dstbuf, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
+ ext = pf_key_v2_find_ext(ret, SADB_X_EXT_DST_MASK);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no destination mask extension found");
+ goto fail;
}
- LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
- msg->sadb_msg_satype));
- break;
+ dmask = (struct sockaddr *) (((struct sadb_address *) ext->seg) + 1);
- case AF_INET6:
- if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)dstaddr)->sin6_addr,
- dstbuf, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
+ ext = pf_key_v2_find_ext(ret, SADB_X_EXT_FLOW_TYPE);
+ if (!ext) {
+ log_print("pf_key_v2_acquire: no flow type extension found");
+ goto fail;
}
- LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
- msg->sadb_msg_satype));
- break;
- }
+ sproto = ext->seg;
+ tproto = sproto->sadb_protocol_proto;
- if (src)
- {
- srcaddr = (struct sockaddr *)(src + 1);
+#if defined (SADB_X_EXT_LOCAL_CREDENTIALS)
+ ext = pf_key_v2_find_ext(pmsg, SADB_X_EXT_LOCAL_CREDENTIALS);
+ if (ext)
+ cred = (struct sadb_x_cred *) ext->seg;
+ else
+ cred = 0;
+#endif
- switch (srcaddr->sa_family)
- {
- case AF_INET:
- if (inet_ntop (AF_INET, &((struct sockaddr_in *)srcaddr)->sin_addr,
- srcbuf, ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- break;
+#if defined (SADB_X_EXT_LOCAL_AUTH)
+ ext = pf_key_v2_find_ext(pmsg, SADB_X_EXT_LOCAL_AUTH);
+ if (ext)
+ sauth = (struct sadb_x_cred *) ext->seg;
+ else
+ sauth = 0;
+#endif
- case AF_INET6:
- if (inet_ntop (AF_INET6,
- &((struct sockaddr_in6 *)srcaddr)->sin6_addr, srcbuf,
- ADDRESS_MAX) == NULL)
- {
- log_print ("pf_key_v2_acquire: inet_ntop failed");
- goto fail;
- }
- break;
+ bzero(ssflow, sizeof ssflow);
+ bzero(sdflow, sizeof sdflow);
+ bzero(ssmask, sizeof ssmask);
+ bzero(sdmask, sizeof sdmask);
- default:
- /*
- * The kernel will pass an all '0' EXT_ADDRESS_SRC if it wasn't
- * specified for the flow. In that case, do NOT specify the srcaddr
- * in the Peer- name below
- */
- srcbuf[0] = 0;
- srcaddr = NULL;
- break;
- }
- }
-
- /* Insert source ID. */
- if (srcident)
- {
- slen = (srcident->sadb_ident_len * sizeof (u_int64_t))
- - sizeof (struct sadb_ident);
- if (((unsigned char *)(srcident + 1))[slen - 1] != '\0')
- {
- log_print ("pf_key_v2_acquire: source identity not NUL-terminated");
- goto fail;
- }
-
- /* Check for valid type. */
- switch (srcident->sadb_ident_type)
- {
-#if defined (SADB_X_IDENTTYPE_CONNECTION)
- case SADB_X_IDENTTYPE_CONNECTION:
- /* XXX */
- break;
-#endif
+ sidtype = didtype = "IPV4_ADDR_SUBNET"; /* default */
- case SADB_IDENTTYPE_PREFIX:
- /* Determine what the address family is. */
- srcid = memchr (srcident + 1, ':', slen);
- if (srcid)
- afamily = AF_INET6;
- else
- afamily = AF_INET;
-
- srcid = memchr (srcident + 1, '/', slen);
- if (!srcid)
- {
- log_print ("pf_key_v2_acquire: badly formatted PREFIX identity");
- goto fail;
- }
-
- masklen = atoi (srcid + 1);
-
- /* XXX We only support host addresses. */
- if ((afamily == AF_INET6 && masklen != 128)
- || (afamily == AF_INET && masklen != 32))
- {
- log_print ("pf_key_v2_acquire: non-host address specified in "
- "source identity (mask length %d), ignoring request",
- masklen);
- goto fail;
- }
-
- /* NUL-terminate the PREFIX string at the separator, then dup. */
- *srcid = '\0';
- slen = strlen ((char *)(srcident + 1)) + sizeof "ID:Address/";
- srcid = malloc (slen);
- if (!srcid)
- {
- log_error ("pf_key_v2_acquire: malloc (%d) failed", slen);
- goto fail;
- }
-
- snprintf (srcid, slen, "ID:Address/%s", (char *)(srcident + 1));
-
- /* Set the section if it doesn't already exist. */
- af = conf_begin ();
- if (!conf_get_str (srcid, "ID-type"))
- {
- if (conf_set (af, srcid, "ID-type",
- afamily == AF_INET ? "IPV4_ADDR" : "IPV6_ADDR",
- 1, 0)
- || conf_set (af, srcid, "Refcount", "1", 1, 0)
- || conf_set (af, srcid, "Address", (char *)(srcident + 1),
- 1, 0))
- {
- conf_end (af, 0);
- goto fail;
+ switch (sflow->sa_family) {
+ case AF_INET:
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) sflow)->sin_addr, ssflow,
+ ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
}
- }
- else
- pf_key_v2_conf_refinc (af, srcid);
- conf_end (af, 1);
- break;
-
- case SADB_IDENTTYPE_FQDN:
- prefstring = "FQDN";
- /* Fall through */
- case SADB_IDENTTYPE_USERFQDN:
- if (!prefstring)
- {
- prefstring = "USER_FQDN";
-
- /*
- * Check whether there is a string following the header;
- * if no, that there is a user ID (and acquire the login
- * name). If there is both a string and a user ID, check
- * that they match.
- */
- if ((slen == 0) && (srcident->sadb_ident_id == 0))
- {
- log_print ("pf_key_v2_acquire: no user FQDN or ID provided");
- goto fail;
+ sport = ((struct sockaddr_in *) sflow)->sin_port;
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) dflow)->sin_addr, sdflow,
+ ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
}
-
- if (srcident->sadb_ident_id)
- {
- pwd = getpwuid (srcident->sadb_ident_id);
- if (!pwd)
- {
- log_error ("pf_key_v2_acquire: could not acquire "
- "username from provided ID %llu",
- srcident->sadb_ident_id);
- goto fail;
- }
-
- if (slen != 0)
- if (strcmp (pwd->pw_name, (char *)(srcident + 1)) != 0)
- {
- log_print ("pf_key_v2_acquire: provided user name and "
- "ID do not match (%s != %s)",
- (char *)(srcident + 1), pwd->pw_name);
- /* String has precedence, per RFC 2367. */
- }
+ dport = ((struct sockaddr_in *) dflow)->sin_port;
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) smask)->sin_addr, ssmask,
+ ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
}
- }
-
- buflen = (slen ? slen : strlen (pwd->pw_name)) + strlen (prefstring)
- + sizeof "ID:/";
- srcid = malloc (buflen);
- if (!srcid)
- {
- log_error ("pf_key_v2_acquire: malloc (%d) failed", buflen);
- goto fail;
- }
-
- snprintf (srcid, buflen, "ID:%s/", prefstring);
- if (slen != 0)
- strlcat (srcid, (char *)(srcident + 1), buflen);
- else
- strlcat (srcid, pwd->pw_name, buflen);
- pwd = 0;
-
- /* Set the section if it doesn't already exist. */
- af = conf_begin ();
- if (!conf_get_str (srcid, "ID-type"))
- {
- if (conf_set (af, srcid, "ID-type", prefstring, 1, 0)
- || conf_set (af, srcid, "Refcount", "1", 1, 0)
- || conf_set (af, srcid, "Name",
- srcid + sizeof "ID:/" - 1 + strlen (prefstring),
- 1, 0))
- {
- conf_end (af, 0);
- goto fail;
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) dmask)->sin_addr, sdmask,
+ ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
}
- }
- else
- pf_key_v2_conf_refinc (af, srcid);
- conf_end (af, 1);
- break;
+ if (((struct sockaddr_in *) smask)->sin_addr.s_addr == INADDR_BROADCAST) {
+ shostflag = 1;
+ sidtype = "IPV4_ADDR";
+ }
+ if (((struct sockaddr_in *) dmask)->sin_addr.s_addr == INADDR_BROADCAST) {
+ dhostflag = 1;
+ didtype = "IPV4_ADDR";
+ }
+ break;
- default:
- LOG_DBG ((LOG_SYSDEP, 20,
- "pf_key_v2_acquire: invalid source ID type %d",
- srcident->sadb_ident_type));
- goto fail;
+ case AF_INET6:
+ if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *) sflow)->sin6_addr,
+ ssflow, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ sport = ((struct sockaddr_in6 *) sflow)->sin6_port;
+ if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *) dflow)->sin6_addr,
+ sdflow, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ dport = ((struct sockaddr_in6 *) dflow)->sin6_port;
+ if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *) smask)->sin6_addr,
+ ssmask, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *) dmask)->sin6_addr,
+ sdmask, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ sidtype = didtype = "IPV6_ADDR_SUBNET";
+ if (IN6_IS_ADDR_FULL(&((struct sockaddr_in6 *) smask)->sin6_addr)) {
+ shostflag = 1;
+ sidtype = "IPV6_ADDR";
+ }
+ if (IN6_IS_ADDR_FULL(&((struct sockaddr_in6 *) dmask)->sin6_addr)) {
+ dhostflag = 1;
+ didtype = "IPV6_ADDR";
+ }
+ break;
}
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_acquire: constructed source ID \"%s\"", srcid));
- prefstring = 0;
- }
+ dstaddr = (struct sockaddr *) (dst + 1);
+ bzero(dstbuf, sizeof dstbuf);
+ bzero(srcbuf, sizeof srcbuf);
+
+ if (dstaddr->sa_family == 0) {
+ /*
+ * Destination was not specified in the flow -- can we derive
+ * it?
+ */
+ if (dhostflag == 0) {
+ log_print("pf_key_v2_acquire: Cannot determine precise destination");
+ goto fail;
+ }
+ dstaddr = dflow;
+ }
+ switch (dstaddr->sa_family) {
+ case AF_INET:
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) dstaddr)->sin_addr,
+ dstbuf, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ LOG_DBG((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
+ msg->sadb_msg_satype));
+ break;
- /* Insert destination ID. */
- if (dstident)
- {
- slen = (dstident->sadb_ident_len * sizeof (u_int64_t))
- - sizeof (struct sadb_ident);
+ case AF_INET6:
+ if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *) dstaddr)->sin6_addr,
+ dstbuf, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ LOG_DBG((LOG_SYSDEP, 20, "pf_key_v2_acquire: dst=%s sproto %d", dstbuf,
+ msg->sadb_msg_satype));
+ break;
+ }
- /* Check for valid type. */
- switch (dstident->sadb_ident_type)
- {
-#if defined (SADB_X_IDENTTYPE_CONNECTION)
- case SADB_X_IDENTTYPE_CONNECTION:
- /* XXX */
- break;
-#endif
+ if (src) {
+ srcaddr = (struct sockaddr *) (src + 1);
+
+ switch (srcaddr->sa_family) {
+ case AF_INET:
+ if (inet_ntop(AF_INET, &((struct sockaddr_in *) srcaddr)->sin_addr,
+ srcbuf, ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ break;
+
+ case AF_INET6:
+ if (inet_ntop(AF_INET6,
+ &((struct sockaddr_in6 *) srcaddr)->sin6_addr, srcbuf,
+ ADDRESS_MAX) == NULL) {
+ log_print("pf_key_v2_acquire: inet_ntop failed");
+ goto fail;
+ }
+ break;
- case SADB_IDENTTYPE_PREFIX:
- /* Determine what the address family is. */
- dstid = memchr (dstident + 1, ':', slen);
- if (dstid)
- afamily = AF_INET6;
- else
- afamily = AF_INET;
-
- dstid = memchr (dstident + 1, '/', slen);
- if (!dstid)
- {
- log_print ("pf_key_v2_acquire: badly formatted PREFIX identity");
- goto fail;
- }
-
- masklen = atoi (dstid + 1);
-
- /* XXX We only support host addresses. */
- if ((afamily == AF_INET6 && masklen != 128)
- || (afamily == AF_INET && masklen != 32))
- {
- log_print ("pf_key_v2_acquire: non-host address specified in "
- "destination identity (mask length %d), ignoring "
- "request",
- masklen);
- goto fail;
- }
-
- /* NUL-terminate the PREFIX string at the separator, then dup. */
- *dstid = '\0';
- slen = strlen ((char *)(dstident + 1)) + sizeof "ID:Address/";
- dstid = malloc (slen);
- if (!dstid)
- {
- log_error ("pf_key_v2_acquire: malloc (%d) failed", slen);
- goto fail;
- }
-
- snprintf (dstid, slen, "ID:Address/%s", (char *)(dstident + 1));
-
- /* Set the section if it doesn't already exist. */
- af = conf_begin ();
- if (!conf_get_str (dstid, "ID-type"))
- {
- if (conf_set (af, dstid, "ID-type",
- afamily == AF_INET ? "IPV4_ADDR" : "IPV6_ADDR",
- 1, 0)
- || conf_set (af, dstid, "Refcount", "1", 1, 0)
- || conf_set (af, dstid, "Address", (char *)(dstident + 1),
- 1, 0))
- {
- conf_end (af, 0);
- goto fail;
+ default:
+ /*
+ * The kernel will pass an all '0' EXT_ADDRESS_SRC if it wasn't
+ * specified for the flow. In that case, do NOT specify the srcaddr
+ * in the Peer- name below
+ */
+ srcbuf[0] = 0;
+ srcaddr = NULL;
+ break;
}
- }
- else
- pf_key_v2_conf_refinc (af, dstid);
- conf_end (af, 1);
- break;
-
- case SADB_IDENTTYPE_FQDN:
- prefstring = "FQDN";
- /* Fall through */
-
- case SADB_IDENTTYPE_USERFQDN:
- if (!prefstring)
- {
- prefstring = "USER_FQDN";
-
- /*
- * Check whether there is a string following the header;
- * if no, that there is a user ID (and acquire the login
- * name). If there is both a string and a user ID, check
- * that they match.
- */
- if (slen == 0 && dstident->sadb_ident_id == 0)
- {
- log_print ("pf_key_v2_acquire: no user FQDN or ID provided");
- goto fail;
+ }
+ /* Insert source ID. */
+ if (srcident) {
+ slen = (srcident->sadb_ident_len * sizeof(u_int64_t))
+ - sizeof(struct sadb_ident);
+ if (((unsigned char *) (srcident + 1))[slen - 1] != '\0') {
+ log_print("pf_key_v2_acquire: source identity not NUL-terminated");
+ goto fail;
}
+ /* Check for valid type. */
+ switch (srcident->sadb_ident_type) {
+#if defined (SADB_X_IDENTTYPE_CONNECTION)
+ case SADB_X_IDENTTYPE_CONNECTION:
+ /* XXX */
+ break;
+#endif
+
+ case SADB_IDENTTYPE_PREFIX:
+ /* Determine what the address family is. */
+ srcid = memchr(srcident + 1, ':', slen);
+ if (srcid)
+ afamily = AF_INET6;
+ else
+ afamily = AF_INET;
+
+ srcid = memchr(srcident + 1, '/', slen);
+ if (!srcid) {
+ log_print("pf_key_v2_acquire: badly formatted PREFIX identity");
+ goto fail;
+ }
+ masklen = atoi(srcid + 1);
+
+ /* XXX We only support host addresses. */
+ if ((afamily == AF_INET6 && masklen != 128)
+ || (afamily == AF_INET && masklen != 32)) {
+ log_print("pf_key_v2_acquire: non-host address specified in "
+ "source identity (mask length %d), ignoring request",
+ masklen);
+ goto fail;
+ }
+ /*
+ * NUL-terminate the PREFIX string at the separator,
+ * then dup.
+ */
+ *srcid = '\0';
+ slen = strlen((char *) (srcident + 1)) + sizeof "ID:Address/";
+ srcid = malloc(slen);
+ if (!srcid) {
+ log_error("pf_key_v2_acquire: malloc (%d) failed", slen);
+ goto fail;
+ }
+ snprintf(srcid, slen, "ID:Address/%s", (char *) (srcident + 1));
+
+ /* Set the section if it doesn't already exist. */
+ af = conf_begin();
+ if (!conf_get_str(srcid, "ID-type")) {
+ if (conf_set(af, srcid, "ID-type",
+ afamily == AF_INET ? "IPV4_ADDR" : "IPV6_ADDR",
+ 1, 0)
+ || conf_set(af, srcid, "Refcount", "1", 1, 0)
+ || conf_set(af, srcid, "Address", (char *) (srcident + 1),
+ 1, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, srcid);
+ conf_end(af, 1);
+ break;
+
+ case SADB_IDENTTYPE_FQDN:
+ prefstring = "FQDN";
+ /* Fall through */
+ case SADB_IDENTTYPE_USERFQDN:
+ if (!prefstring) {
+ prefstring = "USER_FQDN";
+
+ /*
+ * Check whether there is a string following the header;
+ * if no, that there is a user ID (and acquire the login
+ * name). If there is both a string and a user ID, check
+ * that they match.
+ */
+ if ((slen == 0) && (srcident->sadb_ident_id == 0)) {
+ log_print("pf_key_v2_acquire: no user FQDN or ID provided");
+ goto fail;
+ }
+ if (srcident->sadb_ident_id) {
+ pwd = getpwuid(srcident->sadb_ident_id);
+ if (!pwd) {
+ log_error("pf_key_v2_acquire: could not acquire "
+ "username from provided ID %llu",
+ srcident->sadb_ident_id);
+ goto fail;
+ }
+ if (slen != 0)
+ if (strcmp(pwd->pw_name, (char *) (srcident + 1)) != 0) {
+ log_print("pf_key_v2_acquire: provided user name and "
+ "ID do not match (%s != %s)",
+ (char *) (srcident + 1), pwd->pw_name);
+ /*
+ * String has
+ * precedence, per
+ * RFC 2367.
+ */
+ }
+ }
+ }
+ buflen = (slen ? slen : strlen(pwd->pw_name)) + strlen(prefstring)
+ + sizeof "ID:/";
+ srcid = malloc(buflen);
+ if (!srcid) {
+ log_error("pf_key_v2_acquire: malloc (%d) failed", buflen);
+ goto fail;
+ }
+ snprintf(srcid, buflen, "ID:%s/", prefstring);
+ if (slen != 0)
+ strlcat(srcid, (char *) (srcident + 1), buflen);
+ else
+ strlcat(srcid, pwd->pw_name, buflen);
+ pwd = 0;
+
+ /* Set the section if it doesn't already exist. */
+ af = conf_begin();
+ if (!conf_get_str(srcid, "ID-type")) {
+ if (conf_set(af, srcid, "ID-type", prefstring, 1, 0)
+ || conf_set(af, srcid, "Refcount", "1", 1, 0)
+ || conf_set(af, srcid, "Name",
+ srcid + sizeof "ID:/" - 1 + strlen(prefstring),
+ 1, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, srcid);
+ conf_end(af, 1);
+ break;
- if (dstident->sadb_ident_id)
- {
- pwd = getpwuid (dstident->sadb_ident_id);
- if (!pwd)
- {
- log_error ("pf_key_v2_acquire: could not acquire "
- "username from provided ID %llu",
- dstident->sadb_ident_id);
- goto fail;
- }
-
- if (slen != 0)
- if (strcmp (pwd->pw_name, (char *)(dstident + 1)) != 0)
- {
- log_print ("pf_key_v2_acquire: provided user name and "
- "ID do not match (%s != %s)",
- (char *)(dstident + 1), pwd->pw_name);
- /* String has precedence, per RF 2367. */
- }
- }
- }
-
- buflen = (slen ? slen : strlen (pwd->pw_name)) + strlen (prefstring)
- + sizeof "ID:/";
- dstid = malloc (buflen);
- if (!dstid)
- {
- log_error ("pf_key_v2_acquire: malloc (%d) failed", buflen);
- goto fail;
- }
-
- snprintf (dstid, buflen, "ID:%s/", prefstring);
- if (slen != 0)
- strlcat (dstid, (char *)(dstident + 1), buflen);
- else
- strlcat (dstid, pwd->pw_name, buflen);
- pwd = 0;
-
- /* Set the section if it doesn't already exist. */
- af = conf_begin ();
- if (!conf_get_str (dstid, "ID-type"))
- {
- if (conf_set (af, dstid, "ID-type", prefstring, 1, 0)
- || conf_set (af, dstid, "Refcount", "1", 1, 0)
- || conf_set (af, dstid, "Name",
- dstid + sizeof "ID:/" - 1 + strlen (prefstring),
- 1, 0))
- {
- conf_end (af, 0);
- goto fail;
+ default:
+ LOG_DBG((LOG_SYSDEP, 20,
+ "pf_key_v2_acquire: invalid source ID type %d",
+ srcident->sadb_ident_type));
+ goto fail;
}
- }
- else
- pf_key_v2_conf_refinc (af, dstid);
- conf_end (af, 1);
- break;
- default:
- LOG_DBG ((LOG_SYSDEP, 20,
- "pf_key_v2_acquire: invalid destination ID type %d",
- dstident->sadb_ident_type));
- goto fail;
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_acquire: constructed source ID \"%s\"", srcid));
+ prefstring = 0;
}
+ /* Insert destination ID. */
+ if (dstident) {
+ slen = (dstident->sadb_ident_len * sizeof(u_int64_t))
+ - sizeof(struct sadb_ident);
- LOG_DBG ((LOG_SYSDEP, 50,
- "pf_key_v2_acquire: constructed destination ID \"%s\"",
- dstid));
- }
-
- /* Now we've placed the necessary IDs in the configuration space. */
-
- /* Get a new connection sequence number. */
- for (;; connection_seq++)
- {
- snprintf (conn, connlen, "Connection-%u", connection_seq);
- snprintf (configname, sizeof configname, "Config-Phase2-%u",
- connection_seq);
-
- /* Does it exist ? */
- if (!conf_get_str (conn, "Phase")
- && !conf_get_str (configname, "Suites"))
- break;
- }
-
- /*
- * Set the IPsec connection entry. In particular, the following fields:
- * - Phase
- * - ISAKMP-peer
- * - Local-ID/Remote-ID (if provided)
- * - Acquire-ID (sequence number of kernel message, e.g., PF_KEYv2)
- * - Configuration
- *
- * Also set the following section:
- * [Peer-dstaddr(/srcaddr)(-srcid)(/dstid)]
- * with these fields:
- * - Phase
- * - ID (if provided)
- * - Remote-ID (if provided)
- * - Local-address (if provided)
- * - Address
- * - Configuration (if an entry "ISAKMP-configuration-dstaddr(/srcaddr)"
- * exists -- otherwise use the defaults)
- */
-
- slen = strlen (dstbuf) + strlen (srcbuf) + (srcid ? strlen (srcid) : 0)
- + (dstid ? strlen (dstid) : 0) + sizeof "Peer-/-/";
- peer = malloc (slen);
- if (!peer)
- goto fail;
-
- /*
- * The various cases:
- * - Peer-dstaddr
- * - Peer-dstaddr/srcaddr
- * - Peer-dstaddr/srcaddr-srcid
- * - Peer-dstaddr/srcaddr-srcid/dstid
- * - Peer-dstaddr/srcaddr-/dstid
- * - Peer-dstaddr-srcid/dstid
- * - Peer-dstaddr-/dstid
- * - Peer-dstaddr-srcid
- */
- snprintf (peer, slen, "Peer-%s%s%s%s%s%s%s", dstbuf, srcaddr ? "/" : "",
- srcaddr ? srcbuf : "", srcid ? "-" : "", srcid ? srcid : "",
- dstid ? (srcid ? "/" : "-/") : "", dstid ? dstid : "");
-
- /*
- * Set the IPsec connection section. Refcount is set to 2, because
- * it will be linked both to the incoming and the outgoing SA.
- */
- af = conf_begin ();
- if (conf_set (af, conn, "Phase", "2", 0, 0)
- || conf_set (af, conn, "Flags", "__ondemand", 0 , 0)
- || conf_set (af, conn, "Refcount", "2", 0 , 0)
- || conf_set (af, conn, "ISAKMP-peer", peer, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- /* Set the sequence number. */
- snprintf (lname, sizeof lname, "%u", msg->sadb_msg_seq);
- if (conf_set (af, conn, "Acquire-ID", lname, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- /* Set Phase 2 IDs -- this is the Local-ID section. */
- snprintf (lname, sizeof lname, "Phase2-ID:%s/%s/%u/%u", ssflow, ssmask,
- tproto, sport);
- if (conf_set (af, conn, "Local-ID", lname, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (!conf_get_str (lname, "ID-type"))
- {
- if (conf_set (af, lname, "Refcount", "1", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
+ /* Check for valid type. */
+ switch (dstident->sadb_ident_type) {
+#if defined (SADB_X_IDENTTYPE_CONNECTION)
+ case SADB_X_IDENTTYPE_CONNECTION:
+ /* XXX */
+ break;
+#endif
+
+ case SADB_IDENTTYPE_PREFIX:
+ /* Determine what the address family is. */
+ dstid = memchr(dstident + 1, ':', slen);
+ if (dstid)
+ afamily = AF_INET6;
+ else
+ afamily = AF_INET;
+
+ dstid = memchr(dstident + 1, '/', slen);
+ if (!dstid) {
+ log_print("pf_key_v2_acquire: badly formatted PREFIX identity");
+ goto fail;
+ }
+ masklen = atoi(dstid + 1);
+
+ /* XXX We only support host addresses. */
+ if ((afamily == AF_INET6 && masklen != 128)
+ || (afamily == AF_INET && masklen != 32)) {
+ log_print("pf_key_v2_acquire: non-host address specified in "
+ "destination identity (mask length %d), ignoring "
+ "request",
+ masklen);
+ goto fail;
+ }
+ /*
+ * NUL-terminate the PREFIX string at the separator,
+ * then dup.
+ */
+ *dstid = '\0';
+ slen = strlen((char *) (dstident + 1)) + sizeof "ID:Address/";
+ dstid = malloc(slen);
+ if (!dstid) {
+ log_error("pf_key_v2_acquire: malloc (%d) failed", slen);
+ goto fail;
+ }
+ snprintf(dstid, slen, "ID:Address/%s", (char *) (dstident + 1));
+
+ /* Set the section if it doesn't already exist. */
+ af = conf_begin();
+ if (!conf_get_str(dstid, "ID-type")) {
+ if (conf_set(af, dstid, "ID-type",
+ afamily == AF_INET ? "IPV4_ADDR" : "IPV6_ADDR",
+ 1, 0)
+ || conf_set(af, dstid, "Refcount", "1", 1, 0)
+ || conf_set(af, dstid, "Address", (char *) (dstident + 1),
+ 1, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, dstid);
+ conf_end(af, 1);
+ break;
+
+ case SADB_IDENTTYPE_FQDN:
+ prefstring = "FQDN";
+ /* Fall through */
+
+ case SADB_IDENTTYPE_USERFQDN:
+ if (!prefstring) {
+ prefstring = "USER_FQDN";
+
+ /*
+ * Check whether there is a string following the header;
+ * if no, that there is a user ID (and acquire the login
+ * name). If there is both a string and a user ID, check
+ * that they match.
+ */
+ if (slen == 0 && dstident->sadb_ident_id == 0) {
+ log_print("pf_key_v2_acquire: no user FQDN or ID provided");
+ goto fail;
+ }
+ if (dstident->sadb_ident_id) {
+ pwd = getpwuid(dstident->sadb_ident_id);
+ if (!pwd) {
+ log_error("pf_key_v2_acquire: could not acquire "
+ "username from provided ID %llu",
+ dstident->sadb_ident_id);
+ goto fail;
+ }
+ if (slen != 0)
+ if (strcmp(pwd->pw_name, (char *) (dstident + 1)) != 0) {
+ log_print("pf_key_v2_acquire: provided user name and "
+ "ID do not match (%s != %s)",
+ (char *) (dstident + 1), pwd->pw_name);
+ /*
+ * String has
+ * precedence, per RF
+ * 2367.
+ */
+ }
+ }
+ }
+ buflen = (slen ? slen : strlen(pwd->pw_name)) + strlen(prefstring)
+ + sizeof "ID:/";
+ dstid = malloc(buflen);
+ if (!dstid) {
+ log_error("pf_key_v2_acquire: malloc (%d) failed", buflen);
+ goto fail;
+ }
+ snprintf(dstid, buflen, "ID:%s/", prefstring);
+ if (slen != 0)
+ strlcat(dstid, (char *) (dstident + 1), buflen);
+ else
+ strlcat(dstid, pwd->pw_name, buflen);
+ pwd = 0;
+
+ /* Set the section if it doesn't already exist. */
+ af = conf_begin();
+ if (!conf_get_str(dstid, "ID-type")) {
+ if (conf_set(af, dstid, "ID-type", prefstring, 1, 0)
+ || conf_set(af, dstid, "Refcount", "1", 1, 0)
+ || conf_set(af, dstid, "Name",
+ dstid + sizeof "ID:/" - 1 + strlen(prefstring),
+ 1, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, dstid);
+ conf_end(af, 1);
+ break;
- if (shostflag)
- {
- if (conf_set (af, lname, "ID-type", sidtype, 0, 0)
- || conf_set (af, lname, "Address", ssflow, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
- else
- {
- if (conf_set (af, lname, "ID-type", sidtype, 0, 0)
- || conf_set (af, lname, "Network", ssflow, 0, 0)
- || conf_set (af, lname, "Netmask", ssmask, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
- if (tproto)
- {
- snprintf (tmbuf, sizeof sport * 3 + 1, "%u", tproto);
- if (conf_set (af, lname, "Protocol", tmbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (sport)
- {
- snprintf (tmbuf, sizeof sport * 3 + 1, "%u", ntohs (sport));
- if (conf_set (af, lname, "Port", tmbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
+ default:
+ LOG_DBG((LOG_SYSDEP, 20,
+ "pf_key_v2_acquire: invalid destination ID type %d",
+ dstident->sadb_ident_type));
+ goto fail;
}
- }
- }
- }
- else
- pf_key_v2_conf_refinc (af, lname);
-
- /* Set Remote-ID section. */
- snprintf (dname, sizeof dname, "Phase2-ID:%s/%s/%u/%u", sdflow, sdmask,
- tproto, dport);
- if (conf_set (af, conn, "Remote-ID", dname, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (!conf_get_str (dname, "ID-type"))
- {
- if (conf_set (af, dname, "Refcount", "1", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- if (dhostflag)
- {
- if (conf_set (af, dname, "ID-type", didtype, 0, 0)
- || conf_set (af, dname, "Address", sdflow, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
+ LOG_DBG((LOG_SYSDEP, 50,
+ "pf_key_v2_acquire: constructed destination ID \"%s\"",
+ dstid));
}
- else
- {
- if (conf_set (af, dname, "ID-type", didtype, 0, 0)
- || conf_set (af, dname, "Network", sdflow, 0, 0)
- || conf_set (af, dname, "Netmask", sdmask, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
+ /* Now we've placed the necessary IDs in the configuration space. */
+
+ /* Get a new connection sequence number. */
+ for (;; connection_seq++) {
+ snprintf(conn, connlen, "Connection-%u", connection_seq);
+ snprintf(configname, sizeof configname, "Config-Phase2-%u",
+ connection_seq);
+
+ /* Does it exist ? */
+ if (!conf_get_str(conn, "Phase")
+ && !conf_get_str(configname, "Suites"))
+ break;
}
- if (tproto)
- {
- snprintf (tmbuf, sizeof dport * 3 + 1, "%u", tproto);
- if (conf_set (af, dname, "Protocol", tmbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (dport)
- {
- snprintf (tmbuf, sizeof dport * 3 + 1, "%u", ntohs (dport));
- if (conf_set (af, dname, "Port", tmbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
+ /*
+ * Set the IPsec connection entry. In particular, the following fields:
+ * - Phase
+ * - ISAKMP-peer
+ * - Local-ID/Remote-ID (if provided)
+ * - Acquire-ID (sequence number of kernel message, e.g., PF_KEYv2)
+ * - Configuration
+ *
+ * Also set the following section:
+ * [Peer-dstaddr(/srcaddr)(-srcid)(/dstid)]
+ * with these fields:
+ * - Phase
+ * - ID (if provided)
+ * - Remote-ID (if provided)
+ * - Local-address (if provided)
+ * - Address
+ * - Configuration (if an entry "ISAKMP-configuration-dstaddr(/srcaddr)"
+ * exists -- otherwise use the defaults)
+ */
+
+ slen = strlen(dstbuf) + strlen(srcbuf) + (srcid ? strlen(srcid) : 0)
+ + (dstid ? strlen(dstid) : 0) + sizeof "Peer-/-/";
+ peer = malloc(slen);
+ if (!peer)
+ goto fail;
+
+ /*
+ * The various cases:
+ * - Peer-dstaddr
+ * - Peer-dstaddr/srcaddr
+ * - Peer-dstaddr/srcaddr-srcid
+ * - Peer-dstaddr/srcaddr-srcid/dstid
+ * - Peer-dstaddr/srcaddr-/dstid
+ * - Peer-dstaddr-srcid/dstid
+ * - Peer-dstaddr-/dstid
+ * - Peer-dstaddr-srcid
+ */
+ snprintf(peer, slen, "Peer-%s%s%s%s%s%s%s", dstbuf, srcaddr ? "/" : "",
+ srcaddr ? srcbuf : "", srcid ? "-" : "", srcid ? srcid : "",
+ dstid ? (srcid ? "/" : "-/") : "", dstid ? dstid : "");
+
+ /*
+ * Set the IPsec connection section. Refcount is set to 2, because
+ * it will be linked both to the incoming and the outgoing SA.
+ */
+ af = conf_begin();
+ if (conf_set(af, conn, "Phase", "2", 0, 0)
+ || conf_set(af, conn, "Flags", "__ondemand", 0, 0)
+ || conf_set(af, conn, "Refcount", "2", 0, 0)
+ || conf_set(af, conn, "ISAKMP-peer", peer, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
}
- }
- else
- pf_key_v2_conf_refinc (af, dname);
-
- /*
- * XXX
- * We should be using information from the proposal to set this up.
- * At least, we should make this selectable.
- */
-
- /* Phase 2 configuration. */
- if (conf_set (af, conn, "Configuration", configname, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (conf_set (af, configname, "Exchange_type", "Quick_mode", 0, 0)
- || conf_set (af, configname, "DOI", "IPSEC", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (conf_get_str ("General", "Default-phase-2-suites"))
- {
- if (conf_set (af, configname, "Suites",
- conf_get_str ("General", "Default-phase-2-suites"), 0, 0))
- {
- conf_end (af, 0);
- goto fail;
+ /* Set the sequence number. */
+ snprintf(lname, sizeof lname, "%u", msg->sadb_msg_seq);
+ if (conf_set(af, conn, "Acquire-ID", lname, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
}
- }
- else
- {
- if (conf_set (af, configname, "Suites",
- "QM-ESP-3DES-SHA-PFS-SUITE", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
+ /* Set Phase 2 IDs -- this is the Local-ID section. */
+ snprintf(lname, sizeof lname, "Phase2-ID:%s/%s/%u/%u", ssflow, ssmask,
+ tproto, sport);
+ if (conf_set(af, conn, "Local-ID", lname, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
}
- }
-
- /* Set the ISAKMP-peer section. */
- if (!conf_get_str (peer, "Phase"))
- {
- if (conf_set (af, peer, "Phase", "1", 0, 0)
- || conf_set (af, peer, "Refcount", "1", 0, 0)
- || conf_set (af, peer, "Address", dstbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (srcaddr && conf_set (af, peer, "Local-address", srcbuf, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
+ if (!conf_get_str(lname, "ID-type")) {
+ if (conf_set(af, lname, "Refcount", "1", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (shostflag) {
+ if (conf_set(af, lname, "ID-type", sidtype, 0, 0)
+ || conf_set(af, lname, "Address", ssflow, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else {
+ if (conf_set(af, lname, "ID-type", sidtype, 0, 0)
+ || conf_set(af, lname, "Network", ssflow, 0, 0)
+ || conf_set(af, lname, "Netmask", ssmask, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ }
+ if (tproto) {
+ snprintf(tmbuf, sizeof sport * 3 + 1, "%u", tproto);
+ if (conf_set(af, lname, "Protocol", tmbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (sport) {
+ snprintf(tmbuf, sizeof sport * 3 + 1, "%u", ntohs(sport));
+ if (conf_set(af, lname, "Port", tmbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ }
+ }
+ } else
+ pf_key_v2_conf_refinc(af, lname);
+
+ /* Set Remote-ID section. */
+ snprintf(dname, sizeof dname, "Phase2-ID:%s/%s/%u/%u", sdflow, sdmask,
+ tproto, dport);
+ if (conf_set(af, conn, "Remote-ID", dname, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
}
+ if (!conf_get_str(dname, "ID-type")) {
+ if (conf_set(af, dname, "Refcount", "1", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (dhostflag) {
+ if (conf_set(af, dname, "ID-type", didtype, 0, 0)
+ || conf_set(af, dname, "Address", sdflow, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else {
+ if (conf_set(af, dname, "ID-type", didtype, 0, 0)
+ || conf_set(af, dname, "Network", sdflow, 0, 0)
+ || conf_set(af, dname, "Netmask", sdmask, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ }
- snprintf (confname, sizeof confname, "ISAKMP-Configuration-%s", peer);
- if (conf_set (af, peer, "Configuration", confname, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
+ if (tproto) {
+ snprintf(tmbuf, sizeof dport * 3 + 1, "%u", tproto);
+ if (conf_set(af, dname, "Protocol", tmbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (dport) {
+ snprintf(tmbuf, sizeof dport * 3 + 1, "%u", ntohs(dport));
+ if (conf_set(af, dname, "Port", tmbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ }
+ }
+ } else
+ pf_key_v2_conf_refinc(af, dname);
+
+ /*
+ * XXX
+ * We should be using information from the proposal to set this up.
+ * At least, we should make this selectable.
+ */
+
+ /* Phase 2 configuration. */
+ if (conf_set(af, conn, "Configuration", configname, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (conf_set(af, configname, "Exchange_type", "Quick_mode", 0, 0)
+ || conf_set(af, configname, "DOI", "IPSEC", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (conf_get_str("General", "Default-phase-2-suites")) {
+ if (conf_set(af, configname, "Suites",
+ conf_get_str("General", "Default-phase-2-suites"), 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else {
+ if (conf_set(af, configname, "Suites",
+ "QM-ESP-3DES-SHA-PFS-SUITE", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
}
+ /* Set the ISAKMP-peer section. */
+ if (!conf_get_str(peer, "Phase")) {
+ if (conf_set(af, peer, "Phase", "1", 0, 0)
+ || conf_set(af, peer, "Refcount", "1", 0, 0)
+ || conf_set(af, peer, "Address", dstbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (srcaddr && conf_set(af, peer, "Local-address", srcbuf, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ snprintf(confname, sizeof confname, "ISAKMP-Configuration-%s", peer);
+ if (conf_set(af, peer, "Configuration", confname, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
#if defined (SADB_X_CREDTYPE_NONE)
- /* Store any credentials passed to us. */
- if (cred)
- {
- struct cert_handler *handler = 0;
- void *cert;
- char num[12], *certprint;
-
- /* Convert to bytes in-place. */
- cred->sadb_x_cred_len *= PF_KEY_V2_CHUNK;
-
- if (cred->sadb_x_cred_len <= sizeof *cred)
- {
- log_print ("pf_key_v2_acquire: zero-length credentials, "
- "aborting SA acquisition");
- conf_end (af, 0);
- goto fail;
- }
-
- switch (cred->sadb_x_cred_type)
- {
- case SADB_X_CREDTYPE_X509:
- snprintf (num, sizeof num, "%d", ISAKMP_CERTENC_X509_SIG);
- handler = cert_get (ISAKMP_CERTENC_X509_SIG);
- break;
- case SADB_X_CREDTYPE_KEYNOTE:
- snprintf (num, sizeof num, "%d", ISAKMP_CERTENC_KEYNOTE);
- handler = cert_get (ISAKMP_CERTENC_KEYNOTE);
- break;
- default:
- log_print ("pf_key_v2_acquire: unknown credential type %d",
- cred->sadb_x_cred_type);
- conf_end (af, 0);
- goto fail;
- }
-
- if (!handler)
- {
- log_print ("pf_key_v2_acquire: cert_get (%s) failed", num);
- conf_end (af, 0);
- goto fail;
- }
-
- /* Set the credential type as a number. */
- if (conf_set (af, peer, "Credential_type", num, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- /* Get the certificate. */
- cert = handler->cert_get ((u_int8_t *)(cred + 1),
- cred->sadb_x_cred_len - sizeof *cred);
-
- /* Now convert to printable format. */
- certprint = handler->cert_printable (cert);
- handler->cert_free (cert);
- if (!certprint
- || conf_set (af, peer, "Credentials", certprint, 0, 0))
- {
- if (certprint)
- free (certprint);
- conf_end (af, 0);
- goto fail;
- }
- free (certprint);
- }
-#endif /* SADB_X_CREDTYPE_NONE */
+ /* Store any credentials passed to us. */
+ if (cred) {
+ struct cert_handler *handler = 0;
+ void *cert;
+ char num[12], *certprint;
+
+ /* Convert to bytes in-place. */
+ cred->sadb_x_cred_len *= PF_KEY_V2_CHUNK;
+
+ if (cred->sadb_x_cred_len <= sizeof *cred) {
+ log_print("pf_key_v2_acquire: zero-length credentials, "
+ "aborting SA acquisition");
+ conf_end(af, 0);
+ goto fail;
+ }
+ switch (cred->sadb_x_cred_type) {
+ case SADB_X_CREDTYPE_X509:
+ snprintf(num, sizeof num, "%d", ISAKMP_CERTENC_X509_SIG);
+ handler = cert_get(ISAKMP_CERTENC_X509_SIG);
+ break;
+ case SADB_X_CREDTYPE_KEYNOTE:
+ snprintf(num, sizeof num, "%d", ISAKMP_CERTENC_KEYNOTE);
+ handler = cert_get(ISAKMP_CERTENC_KEYNOTE);
+ break;
+ default:
+ log_print("pf_key_v2_acquire: unknown credential type %d",
+ cred->sadb_x_cred_type);
+ conf_end(af, 0);
+ goto fail;
+ }
+
+ if (!handler) {
+ log_print("pf_key_v2_acquire: cert_get (%s) failed", num);
+ conf_end(af, 0);
+ goto fail;
+ }
+ /* Set the credential type as a number. */
+ if (conf_set(af, peer, "Credential_type", num, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ /* Get the certificate. */
+ cert = handler->cert_get((u_int8_t *) (cred + 1),
+ cred->sadb_x_cred_len - sizeof *cred);
+
+ /* Now convert to printable format. */
+ certprint = handler->cert_printable(cert);
+ handler->cert_free(cert);
+ if (!certprint
+ || conf_set(af, peer, "Credentials", certprint, 0, 0)) {
+ if (certprint)
+ free(certprint);
+ conf_end(af, 0);
+ goto fail;
+ }
+ free(certprint);
+ }
+#endif /* SADB_X_CREDTYPE_NONE */
- /* Phase 1 configuration. */
- if (!conf_get_str (confname, "exchange_type"))
- {
+ /* Phase 1 configuration. */
+ if (!conf_get_str(confname, "exchange_type")) {
#if defined (SADB_X_EXT_LOCAL_AUTH)
- /* We may have been provided with authentication material. */
- if (sauth)
- {
- char *authm;
-
- /* Convert to bytes in-place. */
- sauth->sadb_x_cred_len *= PF_KEY_V2_CHUNK;
-
- switch (sauth->sadb_x_cred_type)
- {
- case SADB_X_AUTHTYPE_PASSPHRASE:
- if (conf_set (af, confname, "Transforms", "3DES-SHA", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (sauth->sadb_x_cred_len <= sizeof *sauth)
- {
- log_print ("pf_key_v2_acquire: zero-length passphrase, "
- "aborting SA acquisition");
- conf_end (af, 0);
- goto fail;
- }
-
- authm = malloc (sauth->sadb_x_cred_len - sizeof *sauth + 1);
- if (!authm)
- {
- log_error ("pf_key_v2_acquire: malloc (%lu) failed",
- sauth->sadb_x_cred_len -
- (unsigned long)sizeof *sauth + 1);
- conf_end (af, 0);
- goto fail;
- }
- memcpy (authm, sauth + 1,
- sauth->sadb_x_cred_len - sizeof *sauth + 1);
-
- /* Set the passphrase in the peer. */
- if (conf_set (af, peer, "Authentication", authm, 0, 0))
- {
- free (authm);
- conf_end (af, 0);
- goto fail;
- }
- free (authm);
- break;
-
- case SADB_X_AUTHTYPE_RSA:
- if (conf_set (af, confname, "Transforms", "3DES-SHA-RSA_SIG",
- 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- if (sauth->sadb_x_cred_len <= sizeof *sauth)
- {
- log_print ("pf_key_v2_acquire: zero-length RSA key, "
- "aborting SA acquisition");
- conf_end (af, 0);
- goto fail;
- }
-
- authm = key_printable (ISAKMP_KEY_RSA,
- ISAKMP_KEYTYPE_PRIVATE,
- (u_int8_t *) sauth + 1,
- sauth->sadb_x_cred_len
- - sizeof *sauth);
- if (!authm)
- {
- log_print ("pf_key_v2_acquire: failed to convert "
- "private key to printable format (size %lu)",
- sauth->sadb_x_cred_len -
- (unsigned long)sizeof *sauth);
- conf_end (af, 0);
- goto fail;
- }
-
- /*
- * Set the key in the peer. We don't use "Authentication"
- * to avoid potential conflicts with file-based
- * configurations that use public key authentication
- * but still specify an "Authentication" tag (typically
- * as a remnant of passphrase-based testing).
- */
- if (conf_set (af, peer, "PKAuthentication", authm, 0, 0))
- {
- free (authm);
- conf_end (af, 0);
- goto fail;
- }
- free (authm);
- break;
-
- default:
- log_print ("pf_key_v2_acquire: unknown authentication "
- "material type %d received from kernel",
- sauth->sadb_x_cred_type);
- conf_end (af, 0);
- goto fail;
+ /*
+ * We may have been provided with authentication
+ * material.
+ */
+ if (sauth) {
+ char *authm;
+
+ /* Convert to bytes in-place. */
+ sauth->sadb_x_cred_len *= PF_KEY_V2_CHUNK;
+
+ switch (sauth->sadb_x_cred_type) {
+ case SADB_X_AUTHTYPE_PASSPHRASE:
+ if (conf_set(af, confname, "Transforms", "3DES-SHA", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (sauth->sadb_x_cred_len <= sizeof *sauth) {
+ log_print("pf_key_v2_acquire: zero-length passphrase, "
+ "aborting SA acquisition");
+ conf_end(af, 0);
+ goto fail;
+ }
+ authm = malloc(sauth->sadb_x_cred_len - sizeof *sauth + 1);
+ if (!authm) {
+ log_error("pf_key_v2_acquire: malloc (%lu) failed",
+ sauth->sadb_x_cred_len -
+ (unsigned long) sizeof *sauth + 1);
+ conf_end(af, 0);
+ goto fail;
+ }
+ memcpy(authm, sauth + 1,
+ sauth->sadb_x_cred_len - sizeof *sauth + 1);
+
+ /* Set the passphrase in the peer. */
+ if (conf_set(af, peer, "Authentication", authm, 0, 0)) {
+ free(authm);
+ conf_end(af, 0);
+ goto fail;
+ }
+ free(authm);
+ break;
+
+ case SADB_X_AUTHTYPE_RSA:
+ if (conf_set(af, confname, "Transforms", "3DES-SHA-RSA_SIG",
+ 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ if (sauth->sadb_x_cred_len <= sizeof *sauth) {
+ log_print("pf_key_v2_acquire: zero-length RSA key, "
+ "aborting SA acquisition");
+ conf_end(af, 0);
+ goto fail;
+ }
+ authm = key_printable(ISAKMP_KEY_RSA,
+ ISAKMP_KEYTYPE_PRIVATE,
+ (u_int8_t *) sauth + 1,
+ sauth->sadb_x_cred_len
+ - sizeof *sauth);
+ if (!authm) {
+ log_print("pf_key_v2_acquire: failed to convert "
+ "private key to printable format (size %lu)",
+ sauth->sadb_x_cred_len -
+ (unsigned long) sizeof *sauth);
+ conf_end(af, 0);
+ goto fail;
+ }
+ /*
+ * Set the key in the peer. We don't use "Authentication"
+ * to avoid potential conflicts with file-based
+ * configurations that use public key authentication
+ * but still specify an "Authentication" tag (typically
+ * as a remnant of passphrase-based testing).
+ */
+ if (conf_set(af, peer, "PKAuthentication", authm, 0, 0)) {
+ free(authm);
+ conf_end(af, 0);
+ goto fail;
+ }
+ free(authm);
+ break;
+
+ default:
+ log_print("pf_key_v2_acquire: unknown authentication "
+ "material type %d received from kernel",
+ sauth->sadb_x_cred_type);
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else /* Fall through */
+#endif /* SADB_X_EXT_LOCAL_AUTH */
+ {
+ xform = conf_get_str("Default-phase-1-configuration",
+ "Transforms");
+ if (conf_set(af, confname, "Transforms",
+ xform ? xform : "3DES-SHA-RSA_SIG", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ }
+
+ if (conf_set(af, confname, "Exchange_Type", "ID_PROT", 0, 0)
+ || conf_set(af, confname, "DOI", "IPSEC", 0, 0)
+ || conf_set(af, confname, "Refcount", "1", 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, confname);
+
+ /* The ID we should use in Phase 1. */
+ if (srcid && conf_set(af, peer, "ID", srcid, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
}
- }
- else /* Fall through */
-#endif /* SADB_X_EXT_LOCAL_AUTH */
- {
- xform = conf_get_str ("Default-phase-1-configuration",
- "Transforms");
- if (conf_set (af, confname, "Transforms",
- xform ? xform : "3DES-SHA-RSA_SIG", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
-
- if (conf_set (af, confname, "Exchange_Type", "ID_PROT", 0, 0)
- || conf_set (af, confname, "DOI", "IPSEC", 0, 0)
- || conf_set (af, confname, "Refcount", "1", 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
- else
- pf_key_v2_conf_refinc (af, confname);
-
- /* The ID we should use in Phase 1. */
- if (srcid && conf_set (af, peer, "ID", srcid, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
-
- /* The ID the other side should use in Phase 1. */
- if (dstid && conf_set (af, peer, "Remote-ID", dstid, 0, 0))
- {
- conf_end (af, 0);
- goto fail;
- }
- }
- else
- pf_key_v2_conf_refinc (af, peer);
-
- /* All done. */
- conf_end (af, 1);
-
- /* Let's rock 'n roll. */
- pf_key_v2_connection_check (conn);
- conn = 0;
-
- /* Fall-through to cleanup. */
- fail:
- if (ret)
- pf_key_v2_msg_free (ret);
- if (askpolicy)
- pf_key_v2_msg_free (askpolicy);
- if (srcid)
- free (srcid);
- if (dstid)
- free (dstid);
- if (peer)
- free (peer);
- if (conn)
- free (conn);
- return;
+ /* The ID the other side should use in Phase 1. */
+ if (dstid && conf_set(af, peer, "Remote-ID", dstid, 0, 0)) {
+ conf_end(af, 0);
+ goto fail;
+ }
+ } else
+ pf_key_v2_conf_refinc(af, peer);
+
+ /* All done. */
+ conf_end(af, 1);
+
+ /* Let's rock 'n roll. */
+ pf_key_v2_connection_check(conn);
+ conn = 0;
+
+ /* Fall-through to cleanup. */
+fail:
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ if (askpolicy)
+ pf_key_v2_msg_free(askpolicy);
+ if (srcid)
+ free(srcid);
+ if (dstid)
+ free(dstid);
+ if (peer)
+ free(peer);
+ if (conn)
+ free(conn);
+ return;
#else
- /* acquire not supported */
- return;
-#endif /* SADB_X_ASKPOLICY */
+ /* acquire not supported */
+ return;
+#endif /* SADB_X_ASKPOLICY */
}
static void
-pf_key_v2_notify (struct pf_key_v2_msg *msg)
+pf_key_v2_notify(struct pf_key_v2_msg * msg)
{
- switch (((struct sadb_msg *)TAILQ_FIRST (msg)->seg)->sadb_msg_type)
- {
- case SADB_EXPIRE:
- pf_key_v2_expire (msg);
- break;
-
- case SADB_ACQUIRE:
- pf_key_v2_acquire (msg);
- break;
-
- default:
- log_print ("pf_key_v2_notify: unexpected message type (%d)",
- ((struct sadb_msg *)TAILQ_FIRST (msg)->seg)->sadb_msg_type);
- }
- pf_key_v2_msg_free (msg);
+ switch (((struct sadb_msg *) TAILQ_FIRST(msg)->seg)->sadb_msg_type) {
+ case SADB_EXPIRE:
+ pf_key_v2_expire(msg);
+ break;
+
+ case SADB_ACQUIRE:
+ pf_key_v2_acquire(msg);
+ break;
+
+ default:
+ log_print("pf_key_v2_notify: unexpected message type (%d)",
+ ((struct sadb_msg *) TAILQ_FIRST(msg)->seg)->sadb_msg_type);
+ }
+ pf_key_v2_msg_free(msg);
}
void
-pf_key_v2_handler (int fd)
+pf_key_v2_handler(int fd)
{
- struct pf_key_v2_msg *msg;
+ struct pf_key_v2_msg *msg;
#if !defined (LINUX_IPSEC)
- int n;
-
- /*
- * As synchronous read/writes to the socket can have taken place between
- * the select(2) call of the main loop and this handler, we need to recheck
- * the readability.
- */
- if (ioctl (pf_key_v2_socket, FIONREAD, &n) == -1)
- {
- log_error ("pf_key_v2_handler: ioctl (%d, FIONREAD, &n) failed",
- pf_key_v2_socket);
- return;
- }
- if (!n)
- return;
-#endif /* LINUX_IPSEC */
-
- msg = pf_key_v2_read (0);
- if (msg)
- pf_key_v2_notify (msg);
+ int n;
+
+ /*
+ * As synchronous read/writes to the socket can have taken place between
+ * the select(2) call of the main loop and this handler, we need to recheck
+ * the readability.
+ */
+ if (ioctl(pf_key_v2_socket, FIONREAD, &n) == -1) {
+ log_error("pf_key_v2_handler: ioctl (%d, FIONREAD, &n) failed",
+ pf_key_v2_socket);
+ return;
+ }
+ if (!n)
+ return;
+#endif /* LINUX_IPSEC */
+
+ msg = pf_key_v2_read(0);
+ if (msg)
+ pf_key_v2_notify(msg);
}
/*
@@ -4150,171 +3880,168 @@ pf_key_v2_handler (int fd)
* XXX Assumes OpenBSD GRPSPIS extension. Should probably be moved to sysdep.c
*/
int
-pf_key_v2_group_spis (struct sa *sa, struct proto *proto1,
- struct proto *proto2, int incoming)
+pf_key_v2_group_spis(struct sa * sa, struct proto * proto1,
+ struct proto * proto2, int incoming)
{
#if defined (SADB_X_GRPSPIS)
- struct sadb_msg msg;
- struct sadb_sa sa1, sa2;
- struct sadb_address *addr = 0;
- struct sadb_protocol protocol;
- struct pf_key_v2_msg *grpspis = 0, *ret = 0;
- struct sockaddr *saddr;
- int err;
- size_t len;
+ struct sadb_msg msg;
+ struct sadb_sa sa1, sa2;
+ struct sadb_address *addr = 0;
+ struct sadb_protocol protocol;
+ struct pf_key_v2_msg *grpspis = 0, *ret = 0;
+ struct sockaddr *saddr;
+ int err;
+ size_t len;
#ifdef KAME
- struct sadb_x_sa2 kamesa2;
+ struct sadb_x_sa2 kamesa2;
#endif
- msg.sadb_msg_type = SADB_X_GRPSPIS;
- switch (proto1->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- msg.sadb_msg_satype = SADB_SATYPE_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- msg.sadb_msg_satype = SADB_SATYPE_AH;
- break;
+ msg.sadb_msg_type = SADB_X_GRPSPIS;
+ switch (proto1->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ msg.sadb_msg_satype = SADB_SATYPE_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ msg.sadb_msg_satype = SADB_SATYPE_AH;
+ break;
#if defined (SADB_X_SATYPE_IPCOMP)
- case IPSEC_PROTO_IPCOMP:
- msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- break;
+ case IPSEC_PROTO_IPCOMP:
+ msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
+ break;
#endif
- default:
- log_print ("pf_key_v2_group_spis: invalid proto %d", proto1->proto);
- goto cleanup;
- }
- msg.sadb_msg_seq = 0;
- grpspis = pf_key_v2_msg_new (&msg, 0);
- if (!grpspis)
- goto cleanup;
-
- /* Setup the SA extensions. */
- sa1.sadb_sa_exttype = SADB_EXT_SA;
- sa1.sadb_sa_len = sizeof sa1 / PF_KEY_V2_CHUNK;
- memcpy (&sa1.sadb_sa_spi, proto1->spi[incoming], sizeof sa1.sadb_sa_spi);
- sa1.sadb_sa_replay = 0;
- sa1.sadb_sa_state = 0;
- sa1.sadb_sa_auth = 0;
- sa1.sadb_sa_encrypt = 0;
- sa1.sadb_sa_flags = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&sa1, 0) == -1)
- goto cleanup;
+ default:
+ log_print("pf_key_v2_group_spis: invalid proto %d", proto1->proto);
+ goto cleanup;
+ }
+ msg.sadb_msg_seq = 0;
+ grpspis = pf_key_v2_msg_new(&msg, 0);
+ if (!grpspis)
+ goto cleanup;
+
+ /* Setup the SA extensions. */
+ sa1.sadb_sa_exttype = SADB_EXT_SA;
+ sa1.sadb_sa_len = sizeof sa1 / PF_KEY_V2_CHUNK;
+ memcpy(&sa1.sadb_sa_spi, proto1->spi[incoming], sizeof sa1.sadb_sa_spi);
+ sa1.sadb_sa_replay = 0;
+ sa1.sadb_sa_state = 0;
+ sa1.sadb_sa_auth = 0;
+ sa1.sadb_sa_encrypt = 0;
+ sa1.sadb_sa_flags = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) & sa1, 0) == -1)
+ goto cleanup;
#ifndef KAME
- sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
- sa2.sadb_sa_len = sizeof sa2 / PF_KEY_V2_CHUNK;
- memcpy (&sa2.sadb_sa_spi, proto2->spi[incoming], sizeof sa2.sadb_sa_spi);
- sa2.sadb_sa_replay = 0;
- sa2.sadb_sa_state = 0;
- sa2.sadb_sa_auth = 0;
- sa2.sadb_sa_encrypt = 0;
- sa2.sadb_sa_flags = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&sa2, 0) == -1)
- goto cleanup;
+ sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
+ sa2.sadb_sa_len = sizeof sa2 / PF_KEY_V2_CHUNK;
+ memcpy(&sa2.sadb_sa_spi, proto2->spi[incoming], sizeof sa2.sadb_sa_spi);
+ sa2.sadb_sa_replay = 0;
+ sa2.sadb_sa_state = 0;
+ sa2.sadb_sa_auth = 0;
+ sa2.sadb_sa_encrypt = 0;
+ sa2.sadb_sa_flags = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) & sa2, 0) == -1)
+ goto cleanup;
#else
- memset (&kamesa2, 0, sizeof kamesa2);
- kamesa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- kamesa2.sadb_x_sa2_len = sizeof kamesa2 / PF_KEY_V2_CHUNK;
- kamesa2.sadb_x_sa2_mode = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&kamesa2, 0) == -1)
- goto cleanup;
+ memset(&kamesa2, 0, sizeof kamesa2);
+ kamesa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+ kamesa2.sadb_x_sa2_len = sizeof kamesa2 / PF_KEY_V2_CHUNK;
+ kamesa2.sadb_x_sa2_mode = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) & kamesa2, 0) == -1)
+ goto cleanup;
#endif
- /*
- * Setup the ADDRESS extensions.
- */
- if (incoming)
- sa->transport->vtbl->get_src (sa->transport, &saddr);
- else
- sa->transport->vtbl->get_dst (sa->transport, &saddr);
- len = sizeof *addr + PF_KEY_V2_ROUND (sysdep_sa_len (saddr));
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ /*
+ * Setup the ADDRESS extensions.
+ */
+ if (incoming)
+ sa->transport->vtbl->get_src(sa->transport, &saddr);
+ else
+ sa->transport->vtbl->get_dst(sa->transport, &saddr);
+ len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(saddr));
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, saddr, sysdep_sa_len (saddr));
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- addr = calloc (1, len);
- if (!addr)
- goto cleanup;
- addr->sadb_address_exttype = SADB_X_EXT_DST2;
- addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, saddr, sysdep_sa_len(saddr));
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ addr = calloc(1, len);
+ if (!addr)
+ goto cleanup;
+ addr->sadb_address_exttype = SADB_X_EXT_DST2;
+ addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
- addr->sadb_address_proto = 0;
- addr->sadb_address_prefixlen = 0;
+ addr->sadb_address_proto = 0;
+ addr->sadb_address_prefixlen = 0;
#endif
- addr->sadb_address_reserved = 0;
- memcpy (addr + 1, saddr, sysdep_sa_len (saddr));
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)addr,
- PF_KEY_V2_NODE_MALLOCED) == -1)
- goto cleanup;
- addr = 0;
-
- /* Setup the PROTOCOL extension. */
- protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- protocol.sadb_protocol_len = sizeof protocol / PF_KEY_V2_CHUNK;
- switch (proto2->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- protocol.sadb_protocol_proto = SADB_SATYPE_ESP;
- break;
- case IPSEC_PROTO_IPSEC_AH:
- protocol.sadb_protocol_proto = SADB_SATYPE_AH;
- break;
+ addr->sadb_address_reserved = 0;
+ memcpy(addr + 1, saddr, sysdep_sa_len(saddr));
+ ((struct sockaddr_in *) (addr + 1))->sin_port = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) addr,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+ addr = 0;
+
+ /* Setup the PROTOCOL extension. */
+ protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+ protocol.sadb_protocol_len = sizeof protocol / PF_KEY_V2_CHUNK;
+ switch (proto2->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ protocol.sadb_protocol_proto = SADB_SATYPE_ESP;
+ break;
+ case IPSEC_PROTO_IPSEC_AH:
+ protocol.sadb_protocol_proto = SADB_SATYPE_AH;
+ break;
#if defined (SADB_X_SATYPE_IPCOMP)
- case IPSEC_PROTO_IPCOMP:
- protocol.sadb_protocol_proto = SADB_X_SATYPE_IPCOMP;
- break;
+ case IPSEC_PROTO_IPCOMP:
+ protocol.sadb_protocol_proto = SADB_X_SATYPE_IPCOMP;
+ break;
#endif
- default:
- log_print ("pf_key_v2_group_spis: invalid proto %d", proto2->proto);
- goto cleanup;
- }
- protocol.sadb_protocol_reserved2 = 0;
- if (pf_key_v2_msg_add (grpspis, (struct sadb_ext *)&protocol, 0) == -1)
- goto cleanup;
-
- ret = pf_key_v2_call (grpspis);
- pf_key_v2_msg_free (grpspis);
- grpspis = 0;
- if (!ret)
- goto cleanup;
- err = ((struct sadb_msg *)TAILQ_FIRST (ret)->seg)->sadb_msg_errno;
- if (err)
- {
- log_print ("pf_key_v2_group_spis: GRPSPIS: %s", strerror (err));
- goto cleanup;
- }
- pf_key_v2_msg_free (ret);
-
- LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_group_spis: done"));
-
- return 0;
-
- cleanup:
- if (addr)
- free (addr);
- if (grpspis)
- pf_key_v2_msg_free (grpspis);
- if (ret)
- pf_key_v2_msg_free (ret);
- return -1;
-
-#else /* SADB_X_GRPSPIS */
- log_print ("pf_key_v2_group_spis: not supported in pure PF_KEYv2");
- return -1;
+ default:
+ log_print("pf_key_v2_group_spis: invalid proto %d", proto2->proto);
+ goto cleanup;
+ }
+ protocol.sadb_protocol_reserved2 = 0;
+ if (pf_key_v2_msg_add(grpspis, (struct sadb_ext *) & protocol, 0) == -1)
+ goto cleanup;
+
+ ret = pf_key_v2_call(grpspis);
+ pf_key_v2_msg_free(grpspis);
+ grpspis = 0;
+ if (!ret)
+ goto cleanup;
+ err = ((struct sadb_msg *) TAILQ_FIRST(ret)->seg)->sadb_msg_errno;
+ if (err) {
+ log_print("pf_key_v2_group_spis: GRPSPIS: %s", strerror(err));
+ goto cleanup;
+ }
+ pf_key_v2_msg_free(ret);
+
+ LOG_DBG((LOG_SYSDEP, 50, "pf_key_v2_group_spis: done"));
+
+ return 0;
+
+cleanup:
+ if (addr)
+ free(addr);
+ if (grpspis)
+ pf_key_v2_msg_free(grpspis);
+ if (ret)
+ pf_key_v2_msg_free(ret);
+ return -1;
+
+#else /* SADB_X_GRPSPIS */
+ log_print("pf_key_v2_group_spis: not supported in pure PF_KEYv2");
+ return -1;
#endif
}
diff --git a/sbin/isakmpd/pf_key_v2.h b/sbin/isakmpd/pf_key_v2.h
index 4236420159f..f3abff45963 100644
--- a/sbin/isakmpd/pf_key_v2.h
+++ b/sbin/isakmpd/pf_key_v2.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pf_key_v2.h,v 1.8 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: pf_key_v2.h,v 1.4 2000/12/04 04:46:35 angelos Exp $ */
+/* $OpenBSD: pf_key_v2.h,v 1.9 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: pf_key_v2.h,v 1.4 2000/12/04 04:46:35 angelos Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -39,17 +39,20 @@ struct proto;
struct sa;
struct sockaddr;
-extern void pf_key_v2_connection_check (char *);
-extern int pf_key_v2_delete_spi (struct sa *, struct proto *, int);
-extern int pf_key_v2_enable_sa (struct sa *, struct sa *);
-extern int pf_key_v2_enable_spi (in_addr_t, in_addr_t, in_addr_t, in_addr_t,
- u_int8_t *, u_int8_t, in_addr_t);
-extern u_int8_t *pf_key_v2_get_spi (size_t *, u_int8_t, struct sockaddr *,
- struct sockaddr *, u_int32_t);
-extern int pf_key_v2_group_spis (struct sa *, struct proto *, struct proto *,
- int);
-extern void pf_key_v2_handler (int);
-extern int pf_key_v2_open (void);
-extern int pf_key_v2_set_spi (struct sa *, struct proto *, int, struct sa *);
+extern void pf_key_v2_connection_check(char *);
+extern int pf_key_v2_delete_spi(struct sa *, struct proto *, int);
+extern int pf_key_v2_enable_sa(struct sa *, struct sa *);
+extern int
+pf_key_v2_enable_spi(in_addr_t, in_addr_t, in_addr_t, in_addr_t,
+ u_int8_t *, u_int8_t, in_addr_t);
+extern u_int8_t *
+pf_key_v2_get_spi(size_t *, u_int8_t, struct sockaddr *,
+ struct sockaddr *, u_int32_t);
+extern int
+pf_key_v2_group_spis(struct sa *, struct proto *, struct proto *,
+ int);
+extern void pf_key_v2_handler(int);
+extern int pf_key_v2_open(void);
+extern int pf_key_v2_set_spi(struct sa *, struct proto *, int, struct sa *);
-#endif /* _PF_KEY_V2_H_ */
+#endif /* _PF_KEY_V2_H_ */
diff --git a/sbin/isakmpd/policy.c b/sbin/isakmpd/policy.c
index 2b7ab8e7042..d6ea76eefff 100644
--- a/sbin/isakmpd/policy.c
+++ b/sbin/isakmpd/policy.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: policy.c,v 1.69 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
+/* $OpenBSD: policy.c,v 1.70 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved.
@@ -66,1861 +66,1773 @@
#include "policy.h"
#include "x509.h"
-char **keynote_policy_asserts = NULL;
-int keynote_policy_asserts_num = 0;
+char **keynote_policy_asserts = NULL;
+int keynote_policy_asserts_num = 0;
struct exchange *policy_exchange = 0;
-struct sa *policy_sa = 0;
-struct sa *policy_isakmp_sa = 0;
+struct sa *policy_sa = 0;
+struct sa *policy_isakmp_sa = 0;
static const char hextab[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
/*
* Adaptation of Vixie's inet_ntop4 ()
*/
static const char *
-my_inet_ntop4 (const in_addr_t *src, char *dst, size_t size, int normalize)
+my_inet_ntop4(const in_addr_t * src, char *dst, size_t size, int normalize)
{
- static const char fmt[] = "%03u.%03u.%03u.%03u";
- char tmp[sizeof "255.255.255.255"];
- in_addr_t src2;
-
- if (normalize)
- src2 = ntohl (*src);
- else
- src2 = *src;
-
- if (snprintf (tmp, sizeof tmp, fmt, ((u_int8_t *) &src2)[0],
- ((u_int8_t *) &src2)[1], ((u_int8_t *) &src2)[2],
- ((u_int8_t *) &src2)[3]) > (int)size)
- {
- errno = ENOSPC;
- return 0;
- }
- strlcpy (dst, tmp, size);
- return dst;
+ static const char fmt[] = "%03u.%03u.%03u.%03u";
+ char tmp[sizeof "255.255.255.255"];
+ in_addr_t src2;
+
+ if (normalize)
+ src2 = ntohl(*src);
+ else
+ src2 = *src;
+
+ if (snprintf(tmp, sizeof tmp, fmt, ((u_int8_t *) & src2)[0],
+ ((u_int8_t *) & src2)[1], ((u_int8_t *) & src2)[2],
+ ((u_int8_t *) & src2)[3]) > (int) size) {
+ errno = ENOSPC;
+ return 0;
+ }
+ strlcpy(dst, tmp, size);
+ return dst;
}
static const char *
-my_inet_ntop6 (const unsigned char *src, char *dst, size_t size)
+my_inet_ntop6(const unsigned char *src, char *dst, size_t size)
{
- static const char fmt[] = "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x";
- char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
-
- if (snprintf (tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3], src[4],
- src[5], src[6], src[7], src[8], src[9], src[10], src[11],
- src[12], src[13], src[14], src[15]) > (int)size)
- {
- errno = ENOSPC;
- return 0;
- }
- strlcpy (dst, tmp, size);
- return dst;
+ static const char fmt[] =
+ "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x";
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ if (snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3], src[4],
+ src[5], src[6], src[7], src[8], src[9], src[10], src[11],
+ src[12], src[13], src[14], src[15]) > (int) size) {
+ errno = ENOSPC;
+ return 0;
+ }
+ strlcpy(dst, tmp, size);
+ return dst;
}
char *
-policy_callback (char *name)
+policy_callback(char *name)
{
- struct proto *proto;
-
- u_int8_t *attr, *value, *id, *idlocal, *idremote;
- size_t id_sz, idlocalsz, idremotesz;
- struct sockaddr *sin;
- struct ipsec_exch *ie;
- struct ipsec_sa *is;
- size_t i;
- int fmt, lifetype = 0;
- in_addr_t net, subnet;
- u_int16_t len, type;
- time_t tt;
- char *addr;
- static char mytimeofday[15];
-
- /* We use all these as a cache. */
+ struct proto *proto;
+
+ u_int8_t *attr, *value, *id, *idlocal, *idremote;
+ size_t id_sz, idlocalsz, idremotesz;
+ struct sockaddr *sin;
+ struct ipsec_exch *ie;
+ struct ipsec_sa *is;
+ size_t i;
+ int fmt, lifetype = 0;
+ in_addr_t net, subnet;
+ u_int16_t len, type;
+ time_t tt;
+ char *addr;
+ static char mytimeofday[15];
+
+ /* We use all these as a cache. */
#define PMAX 32
- static char *esp_present, *ah_present, *comp_present;
- static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
- static char *comp_alg, ah_life_kbytes[PMAX], ah_life_seconds[PMAX];
- static char esp_life_kbytes[PMAX], esp_life_seconds[PMAX];
- static char comp_life_kbytes[PMAX];
- static char *ah_ecn, *esp_ecn, *comp_ecn;
- static char comp_life_seconds[PMAX], *ah_encapsulation, *esp_encapsulation;
- static char *comp_encapsulation, ah_key_length[PMAX], esp_key_length[PMAX];
- static char ah_key_rounds[PMAX], esp_key_rounds[PMAX], comp_dict_size[PMAX];
- static char comp_private_alg[PMAX], *remote_filter_type, *local_filter_type;
- static char remote_filter_addr_upper[NI_MAXHOST];
- static char remote_filter_addr_lower[NI_MAXHOST];
- static char local_filter_addr_upper[NI_MAXHOST];
- static char local_filter_addr_lower[NI_MAXHOST];
- static char ah_group_desc[PMAX], esp_group_desc[PMAX], comp_group_desc[PMAX];
- static char remote_ike_address[NI_MAXHOST];
- static char local_ike_address[NI_MAXHOST];
- static char *remote_id_type, remote_id_addr_upper[NI_MAXHOST], *phase_1;
- static char remote_id_addr_lower[NI_MAXHOST];
- static char *remote_id_proto, remote_id_port[PMAX];
- static char remote_filter_port[PMAX], local_filter_port[PMAX];
- static char *remote_filter_proto, *local_filter_proto, *pfs, *initiator;
- static char remote_filter_proto_num[3], local_filter_proto_num[3];
- static char remote_id_proto_num[3];
- static char phase1_group[PMAX];
-
- /* Allocated. */
- static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
-
- static int dirty = 1;
-
- /* We only need to set dirty at initialization time really. */
- if (strcmp (name, KEYNOTE_CALLBACK_CLEANUP) == 0
- || strcmp (name, KEYNOTE_CALLBACK_INITIALIZE) == 0)
- {
- esp_present = ah_present = comp_present = pfs = "no";
- ah_hash_alg = ah_auth_alg = phase_1 = "";
- esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
- ah_ecn = esp_ecn = comp_ecn = "no";
- esp_encapsulation = comp_encapsulation = remote_filter_type = "";
- local_filter_type = remote_id_type = initiator = "";
- remote_filter_proto = local_filter_proto = remote_id_proto = "";
-
- if (remote_filter != 0)
- {
- free (remote_filter);
- remote_filter = 0;
- }
-
- if (local_filter != 0)
- {
- free (local_filter);
- local_filter = 0;
- }
-
- if (remote_id != 0)
- {
- free (remote_id);
- remote_id = 0;
+ static char *esp_present, *ah_present, *comp_present;
+ static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
+ static char *comp_alg, ah_life_kbytes[PMAX], ah_life_seconds[PMAX];
+ static char esp_life_kbytes[PMAX], esp_life_seconds[PMAX];
+ static char comp_life_kbytes[PMAX];
+ static char *ah_ecn, *esp_ecn, *comp_ecn;
+ static char comp_life_seconds[PMAX], *ah_encapsulation, *esp_encapsulation;
+ static char *comp_encapsulation, ah_key_length[PMAX], esp_key_length[PMAX];
+ static char ah_key_rounds[PMAX], esp_key_rounds[PMAX], comp_dict_size[PMAX];
+ static char comp_private_alg[PMAX], *remote_filter_type, *local_filter_type;
+ static char remote_filter_addr_upper[NI_MAXHOST];
+ static char remote_filter_addr_lower[NI_MAXHOST];
+ static char local_filter_addr_upper[NI_MAXHOST];
+ static char local_filter_addr_lower[NI_MAXHOST];
+ static char ah_group_desc[PMAX], esp_group_desc[PMAX], comp_group_desc[PMAX];
+ static char remote_ike_address[NI_MAXHOST];
+ static char local_ike_address[NI_MAXHOST];
+ static char *remote_id_type, remote_id_addr_upper[NI_MAXHOST],
+ *phase_1;
+ static char remote_id_addr_lower[NI_MAXHOST];
+ static char *remote_id_proto, remote_id_port[PMAX];
+ static char remote_filter_port[PMAX], local_filter_port[PMAX];
+ static char *remote_filter_proto, *local_filter_proto, *pfs,
+ *initiator;
+ static char remote_filter_proto_num[3], local_filter_proto_num[3];
+ static char remote_id_proto_num[3];
+ static char phase1_group[PMAX];
+
+ /* Allocated. */
+ static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
+
+ static int dirty = 1;
+
+ /* We only need to set dirty at initialization time really. */
+ if (strcmp(name, KEYNOTE_CALLBACK_CLEANUP) == 0
+ || strcmp(name, KEYNOTE_CALLBACK_INITIALIZE) == 0) {
+ esp_present = ah_present = comp_present = pfs = "no";
+ ah_hash_alg = ah_auth_alg = phase_1 = "";
+ esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
+ ah_ecn = esp_ecn = comp_ecn = "no";
+ esp_encapsulation = comp_encapsulation = remote_filter_type = "";
+ local_filter_type = remote_id_type = initiator = "";
+ remote_filter_proto = local_filter_proto = remote_id_proto = "";
+
+ if (remote_filter != 0) {
+ free(remote_filter);
+ remote_filter = 0;
+ }
+ if (local_filter != 0) {
+ free(local_filter);
+ local_filter = 0;
+ }
+ if (remote_id != 0) {
+ free(remote_id);
+ remote_id = 0;
+ }
+ memset(remote_ike_address, 0, sizeof remote_ike_address);
+ memset(local_ike_address, 0, sizeof local_ike_address);
+ memset(ah_life_kbytes, 0, sizeof ah_life_kbytes);
+ memset(ah_life_seconds, 0, sizeof ah_life_seconds);
+ memset(esp_life_kbytes, 0, sizeof esp_life_kbytes);
+ memset(esp_life_seconds, 0, sizeof esp_life_seconds);
+ memset(comp_life_kbytes, 0, sizeof comp_life_kbytes);
+ memset(comp_life_seconds, 0, sizeof comp_life_seconds);
+ memset(ah_key_length, 0, sizeof ah_key_length);
+ memset(ah_key_rounds, 0, sizeof ah_key_rounds);
+ memset(esp_key_length, 0, sizeof esp_key_length);
+ memset(esp_key_rounds, 0, sizeof esp_key_rounds);
+ memset(comp_dict_size, 0, sizeof comp_dict_size);
+ memset(comp_private_alg, 0, sizeof comp_private_alg);
+ memset(remote_filter_addr_upper, 0, sizeof remote_filter_addr_upper);
+ memset(remote_filter_addr_lower, 0, sizeof remote_filter_addr_lower);
+ memset(local_filter_addr_upper, 0, sizeof local_filter_addr_upper);
+ memset(local_filter_addr_lower, 0, sizeof local_filter_addr_lower);
+ memset(remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
+ memset(remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
+ memset(ah_group_desc, 0, sizeof ah_group_desc);
+ memset(esp_group_desc, 0, sizeof esp_group_desc);
+ memset(remote_id_port, 0, sizeof remote_id_port);
+ memset(remote_filter_port, 0, sizeof remote_filter_port);
+ memset(local_filter_port, 0, sizeof local_filter_port);
+ memset(phase1_group, 0, sizeof phase1_group);
+
+ dirty = 1;
+ return "";
}
+ /*
+ * If dirty is set, this is the first request for an attribute, so
+ * populate our value cache.
+ */
+ if (dirty) {
+ ie = policy_exchange->data;
+
+ if (ie->pfs)
+ pfs = "yes";
+
+ is = policy_isakmp_sa->data;
+ snprintf(phase1_group, sizeof phase1_group, "%u", is->group_desc);
+
+ for (proto = TAILQ_FIRST(&policy_sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ ah_present = "yes";
+ switch (proto->id) {
+ case IPSEC_AH_MD5:
+ ah_hash_alg = "md5";
+ break;
+
+ case IPSEC_AH_SHA:
+ ah_hash_alg = "sha";
+ break;
+
+ case IPSEC_AH_RIPEMD:
+ ah_hash_alg = "ripemd";
+ break;
+
+ case IPSEC_AH_SHA2_256:
+ ah_auth_alg = "sha2-256";
+ break;
+
+ case IPSEC_AH_SHA2_384:
+ ah_auth_alg = "sha2-384";
+ break;
+
+ case IPSEC_AH_SHA2_512:
+ ah_auth_alg = "sha2-512";
+ break;
+
+ case IPSEC_AH_DES:
+ ah_hash_alg = "des";
+ break;
+ }
+
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ esp_present = "yes";
+ switch (proto->id) {
+ case IPSEC_ESP_DES_IV64:
+ esp_enc_alg = "des-iv64";
+ break;
+
+ case IPSEC_ESP_DES:
+ esp_enc_alg = "des";
+ break;
+
+ case IPSEC_ESP_3DES:
+ esp_enc_alg = "3des";
+ break;
+
+ case IPSEC_ESP_AES:
+ case IPSEC_ESP_AES_128_CTR:
+ esp_enc_alg = "aes";
+ break;
+
+ case IPSEC_ESP_RC5:
+ esp_enc_alg = "rc5";
+ break;
+
+ case IPSEC_ESP_IDEA:
+ esp_enc_alg = "idea";
+ break;
+
+ case IPSEC_ESP_CAST:
+ esp_enc_alg = "cast";
+ break;
+
+ case IPSEC_ESP_BLOWFISH:
+ esp_enc_alg = "blowfish";
+ break;
+
+ case IPSEC_ESP_3IDEA:
+ esp_enc_alg = "3idea";
+ break;
+
+ case IPSEC_ESP_DES_IV32:
+ esp_enc_alg = "des-iv32";
+ break;
+
+ case IPSEC_ESP_RC4:
+ esp_enc_alg = "rc4";
+ break;
+
+ case IPSEC_ESP_NULL:
+ esp_enc_alg = "null";
+ break;
+ }
+
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ comp_present = "yes";
+ switch (proto->id) {
+ case IPSEC_IPCOMP_OUI:
+ comp_alg = "oui";
+ break;
+
+ case IPSEC_IPCOMP_DEFLATE:
+ comp_alg = "deflate";
+ break;
+
+ case IPSEC_IPCOMP_LZS:
+ comp_alg = "lzs";
+ break;
+
+ case IPSEC_IPCOMP_V42BIS:
+ comp_alg = "v42bis";
+ break;
+ }
+
+ break;
+ }
- memset (remote_ike_address, 0, sizeof remote_ike_address);
- memset (local_ike_address, 0, sizeof local_ike_address);
- memset (ah_life_kbytes, 0, sizeof ah_life_kbytes);
- memset (ah_life_seconds, 0, sizeof ah_life_seconds);
- memset (esp_life_kbytes, 0, sizeof esp_life_kbytes);
- memset (esp_life_seconds, 0, sizeof esp_life_seconds);
- memset (comp_life_kbytes, 0, sizeof comp_life_kbytes);
- memset (comp_life_seconds, 0, sizeof comp_life_seconds);
- memset (ah_key_length, 0, sizeof ah_key_length);
- memset (ah_key_rounds, 0, sizeof ah_key_rounds);
- memset (esp_key_length, 0, sizeof esp_key_length);
- memset (esp_key_rounds, 0, sizeof esp_key_rounds);
- memset (comp_dict_size, 0, sizeof comp_dict_size);
- memset (comp_private_alg, 0, sizeof comp_private_alg);
- memset (remote_filter_addr_upper, 0, sizeof remote_filter_addr_upper);
- memset (remote_filter_addr_lower, 0, sizeof remote_filter_addr_lower);
- memset (local_filter_addr_upper, 0, sizeof local_filter_addr_upper);
- memset (local_filter_addr_lower, 0, sizeof local_filter_addr_lower);
- memset (remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
- memset (remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
- memset (ah_group_desc, 0, sizeof ah_group_desc);
- memset (esp_group_desc, 0, sizeof esp_group_desc);
- memset (remote_id_port, 0, sizeof remote_id_port);
- memset (remote_filter_port, 0, sizeof remote_filter_port);
- memset (local_filter_port, 0, sizeof local_filter_port);
- memset (phase1_group, 0, sizeof phase1_group);
-
- dirty = 1;
- return "";
- }
-
- /*
- * If dirty is set, this is the first request for an attribute, so
- * populate our value cache.
- */
- if (dirty)
- {
- ie = policy_exchange->data;
-
- if (ie->pfs)
- pfs = "yes";
-
- is = policy_isakmp_sa->data;
- snprintf (phase1_group, sizeof phase1_group, "%u", is->group_desc);
-
- for (proto = TAILQ_FIRST (&policy_sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- ah_present = "yes";
- switch (proto->id)
- {
- case IPSEC_AH_MD5:
- ah_hash_alg = "md5";
- break;
-
- case IPSEC_AH_SHA:
- ah_hash_alg = "sha";
- break;
-
- case IPSEC_AH_RIPEMD:
- ah_hash_alg = "ripemd";
- break;
-
- case IPSEC_AH_SHA2_256:
- ah_auth_alg = "sha2-256";
- break;
-
- case IPSEC_AH_SHA2_384:
- ah_auth_alg = "sha2-384";
- break;
+ for (attr = proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
+ attr < proto->chosen->p +
+ GET_ISAKMP_GEN_LENGTH(proto->chosen->p);
+ attr = value + len) {
+ if (attr + ISAKMP_ATTR_VALUE_OFF >
+ (proto->chosen->p +
+ GET_ISAKMP_GEN_LENGTH(proto->chosen->p)))
+ return "";
+
+ type = GET_ISAKMP_ATTR_TYPE(attr);
+ fmt = ISAKMP_ATTR_FORMAT(type);
+ type = ISAKMP_ATTR_TYPE(type);
+ value = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF :
+ ISAKMP_ATTR_VALUE_OFF);
+ len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
+ GET_ISAKMP_ATTR_LENGTH_VALUE(attr));
+
+ if (value + len > proto->chosen->p +
+ GET_ISAKMP_GEN_LENGTH(proto->chosen->p))
+ return "";
+
+ switch (type) {
+ case IPSEC_ATTR_SA_LIFE_TYPE:
+ lifetype = decode_16(value);
+ break;
+
+ case IPSEC_ATTR_SA_LIFE_DURATION:
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ if (lifetype == IPSEC_DURATION_SECONDS) {
+ if (len == 2)
+ snprintf(ah_life_seconds, sizeof ah_life_seconds,
+ "%u", decode_16(value));
+ else
+ snprintf(ah_life_seconds, sizeof ah_life_seconds,
+ "%u", decode_32(value));
+ } else {
+ if (len == 2)
+ snprintf(ah_life_kbytes, sizeof ah_life_kbytes,
+ "%u", decode_16(value));
+ else
+ snprintf(ah_life_kbytes, sizeof ah_life_kbytes,
+ "%u", decode_32(value));
+ }
+
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ if (lifetype == IPSEC_DURATION_SECONDS) {
+ if (len == 2)
+ snprintf(esp_life_seconds,
+ sizeof esp_life_seconds, "%u",
+ decode_16(value));
+ else
+ snprintf(esp_life_seconds,
+ sizeof esp_life_seconds, "%u",
+ decode_32(value));
+ } else {
+ if (len == 2)
+ snprintf(esp_life_kbytes,
+ sizeof esp_life_kbytes, "%u",
+ decode_16(value));
+ else
+ snprintf(esp_life_kbytes,
+ sizeof esp_life_kbytes, "%u",
+ decode_32(value));
+ }
+
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ if (lifetype == IPSEC_DURATION_SECONDS) {
+ if (len == 2)
+ snprintf(comp_life_seconds,
+ sizeof comp_life_seconds, "%u",
+ decode_16(value));
+ else
+ snprintf(comp_life_seconds,
+ sizeof comp_life_seconds, "%u",
+ decode_32(value));
+ } else {
+ if (len == 2)
+ snprintf(comp_life_kbytes,
+ sizeof comp_life_kbytes, "%u",
+ decode_16(value));
+ else
+ snprintf(comp_life_kbytes,
+ sizeof comp_life_kbytes, "%u",
+ decode_32(value));
+ }
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_GROUP_DESCRIPTION:
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ snprintf(ah_group_desc,
+ sizeof ah_group_desc, "%u",
+ decode_16(value));
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ snprintf(esp_group_desc,
+ sizeof esp_group_desc, "%u",
+ decode_16(value));
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ snprintf(comp_group_desc,
+ sizeof comp_group_desc, "%u",
+ decode_16(value));
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_ECN_TUNNEL:
+ if (decode_16(value))
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ ah_ecn = "yes";
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ esp_ecn = "yes";
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ comp_ecn = "yes";
+ break;
+ }
+
+ case IPSEC_ATTR_ENCAPSULATION_MODE:
+ if (decode_16(value) == IPSEC_ENCAP_TUNNEL)
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ ah_encapsulation = "tunnel";
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ esp_encapsulation = "tunnel";
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ comp_encapsulation = "tunnel";
+ break;
+ }
+ else
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ ah_encapsulation = "transport";
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ esp_encapsulation = "transport";
+ break;
+
+ case IPSEC_PROTO_IPCOMP:
+ comp_encapsulation = "transport";
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ switch (decode_16(value)) {
+ case IPSEC_AUTH_HMAC_MD5:
+ ah_auth_alg = "hmac-md5";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA:
+ ah_auth_alg = "hmac-sha";
+ break;
+
+ case IPSEC_AUTH_HMAC_RIPEMD:
+ ah_auth_alg = "hmac-ripemd";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_256:
+ ah_auth_alg = "hmac-sha2-256";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_384:
+ ah_auth_alg = "hmac-sha2-384";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_512:
+ ah_auth_alg = "hmac-sha2-512";
+ break;
+
+ case IPSEC_AUTH_DES_MAC:
+ ah_auth_alg = "des-mac";
+ break;
+
+ case IPSEC_AUTH_KPDK:
+ ah_auth_alg = "kpdk";
+ break;
+ }
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ switch (decode_16(value)) {
+ case IPSEC_AUTH_HMAC_MD5:
+ esp_auth_alg = "hmac-md5";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA:
+ esp_auth_alg = "hmac-sha";
+ break;
+
+ case IPSEC_AUTH_HMAC_RIPEMD:
+ esp_auth_alg = "hmac-ripemd";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_256:
+ esp_auth_alg = "hmac-sha2-256";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_384:
+ esp_auth_alg = "hmac-sha2-384";
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_512:
+ esp_auth_alg = "hmac-sha2-512";
+ break;
+
+ case IPSEC_AUTH_DES_MAC:
+ esp_auth_alg = "des-mac";
+ break;
+
+ case IPSEC_AUTH_KPDK:
+ esp_auth_alg = "kpdk";
+ break;
+ }
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_KEY_LENGTH:
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ snprintf(ah_key_length,
+ sizeof ah_key_length, "%u",
+ decode_16(value));
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ snprintf(esp_key_length,
+ sizeof esp_key_length, "%u",
+ decode_16(value));
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_KEY_ROUNDS:
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_AH:
+ snprintf(ah_key_rounds,
+ sizeof ah_key_rounds, "%u",
+ decode_16(value));
+ break;
+
+ case IPSEC_PROTO_IPSEC_ESP:
+ snprintf(esp_key_rounds,
+ sizeof esp_key_rounds, "%u",
+ decode_16(value));
+ break;
+ }
+ break;
+
+ case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
+ snprintf(comp_dict_size,
+ sizeof comp_dict_size, "%u",
+ decode_16(value));
+ break;
+
+ case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
+ snprintf(comp_private_alg,
+ sizeof comp_private_alg, "%u",
+ decode_16(value));
+ break;
+ }
+ }
+ }
- case IPSEC_AH_SHA2_512:
- ah_auth_alg = "sha2-512";
- break;
+ policy_sa->transport->vtbl->get_src(policy_sa->transport, &sin);
+ if (sockaddr2text(sin, &addr, 1)) {
+ log_error("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ strlcpy(local_ike_address, addr, sizeof local_ike_address);
+ free(addr);
- case IPSEC_AH_DES:
- ah_hash_alg = "des";
- break;
+ policy_sa->transport->vtbl->get_dst(policy_sa->transport, &sin);
+ if (sockaddr2text(sin, &addr, 1)) {
+ log_error("policy_callback: sockaddr2text failed");
+ goto bad;
}
+ strlcpy(remote_ike_address, addr, sizeof remote_ike_address);
+ free(addr);
- break;
+ switch (policy_isakmp_sa->exch_type) {
+ case ISAKMP_EXCH_AGGRESSIVE:
+ phase_1 = "aggressive";
+ break;
- case IPSEC_PROTO_IPSEC_ESP:
- esp_present = "yes";
- switch (proto->id)
- {
- case IPSEC_ESP_DES_IV64:
- esp_enc_alg = "des-iv64";
- break;
-
- case IPSEC_ESP_DES:
- esp_enc_alg = "des";
- break;
-
- case IPSEC_ESP_3DES:
- esp_enc_alg = "3des";
- break;
-
- case IPSEC_ESP_AES:
- case IPSEC_ESP_AES_128_CTR:
- esp_enc_alg = "aes";
- break;
-
- case IPSEC_ESP_RC5:
- esp_enc_alg = "rc5";
- break;
-
- case IPSEC_ESP_IDEA:
- esp_enc_alg = "idea";
- break;
-
- case IPSEC_ESP_CAST:
- esp_enc_alg = "cast";
- break;
-
- case IPSEC_ESP_BLOWFISH:
- esp_enc_alg = "blowfish";
- break;
-
- case IPSEC_ESP_3IDEA:
- esp_enc_alg = "3idea";
- break;
-
- case IPSEC_ESP_DES_IV32:
- esp_enc_alg = "des-iv32";
- break;
-
- case IPSEC_ESP_RC4:
- esp_enc_alg = "rc4";
- break;
-
- case IPSEC_ESP_NULL:
- esp_enc_alg = "null";
- break;
+ case ISAKMP_EXCH_ID_PROT:
+ phase_1 = "main";
+ break;
}
- break;
+ if (policy_isakmp_sa->initiator) {
+ id = policy_isakmp_sa->id_r;
+ id_sz = policy_isakmp_sa->id_r_len;
+ } else {
+ id = policy_isakmp_sa->id_i;
+ id_sz = policy_isakmp_sa->id_i_len;
+ }
- case IPSEC_PROTO_IPCOMP:
- comp_present = "yes";
- switch (proto->id)
- {
- case IPSEC_IPCOMP_OUI:
- comp_alg = "oui";
- break;
+ switch (id[0]) {
+ case IPSEC_ID_IPV4_ADDR:
+ remote_id_type = "IPv4 address";
+
+ net = decode_32(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ my_inet_ntop4(&net, remote_id_addr_upper,
+ sizeof remote_id_addr_upper - 1, 1);
+ my_inet_ntop4(&net, remote_id_addr_lower,
+ sizeof remote_id_addr_lower - 1, 1);
+ remote_id = strdup(remote_id_addr_upper);
+ if (!remote_id) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ remote_id_addr_upper);
+ goto bad;
+ }
+ break;
- case IPSEC_IPCOMP_DEFLATE:
- comp_alg = "deflate";
- break;
+ case IPSEC_ID_IPV4_RANGE:
+ remote_id_type = "IPv4 range";
+
+ net = decode_32(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ my_inet_ntop4(&net, remote_id_addr_lower,
+ sizeof remote_id_addr_lower - 1, 1);
+ net = decode_32(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
+ my_inet_ntop4(&net, remote_id_addr_upper,
+ sizeof remote_id_addr_upper - 1, 1);
+ len = strlen(remote_id_addr_upper) +
+ strlen(remote_id_addr_lower) + 2;
+ remote_id = calloc(len, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%d, %lu) failed",
+ len, (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_id, remote_id_addr_lower, len);
+ strlcat(remote_id, "-", len);
+ strlcat(remote_id, remote_id_addr_upper, len);
+ break;
- case IPSEC_IPCOMP_LZS:
- comp_alg = "lzs";
- break;
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ remote_id_type = "IPv4 subnet";
+
+ net = decode_32(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ subnet = decode_32(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
+ net &= subnet;
+ my_inet_ntop4(&net, remote_id_addr_lower,
+ sizeof remote_id_addr_lower - 1, 1);
+ net |= ~subnet;
+ my_inet_ntop4(&net, remote_id_addr_upper,
+ sizeof remote_id_addr_upper - 1, 1);
+ len = strlen(remote_id_addr_upper) +
+ strlen(remote_id_addr_lower) + 2;
+ remote_id = calloc(len, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%d, %lu) failed",
+ len, (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_id, remote_id_addr_lower, len);
+ strlcat(remote_id, "-", len);
+ strlcat(remote_id, remote_id_addr_upper, len);
+ break;
- case IPSEC_IPCOMP_V42BIS:
- comp_alg = "v42bis";
- break;
- }
+ case IPSEC_ID_IPV6_ADDR:
+ remote_id_type = "IPv6 address";
+ my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ remote_id_addr_upper, sizeof remote_id_addr_upper);
+ strlcpy(remote_id_addr_lower, remote_id_addr_upper,
+ sizeof remote_id_addr_lower);
+ remote_id = strdup(remote_id_addr_upper);
+ if (!remote_id) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ remote_id_addr_upper);
+ goto bad;
+ }
+ break;
- break;
- }
-
- for (attr = proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
- attr
- < proto->chosen->p + GET_ISAKMP_GEN_LENGTH (proto->chosen->p);
- attr = value + len)
- {
- if (attr + ISAKMP_ATTR_VALUE_OFF
- > (proto->chosen->p
- + GET_ISAKMP_GEN_LENGTH (proto->chosen->p)))
- return "";
+ case IPSEC_ID_IPV6_RANGE:
+ remote_id_type = "IPv6 range";
- type = GET_ISAKMP_ATTR_TYPE (attr);
- fmt = ISAKMP_ATTR_FORMAT (type);
- type = ISAKMP_ATTR_TYPE (type);
- value = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF :
- ISAKMP_ATTR_VALUE_OFF);
- len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
- GET_ISAKMP_ATTR_LENGTH_VALUE (attr));
+ my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ remote_id_addr_lower,
+ sizeof remote_id_addr_lower - 1);
- if (value + len > proto->chosen->p +
- GET_ISAKMP_GEN_LENGTH (proto->chosen->p))
- return "";
+ my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16,
+ remote_id_addr_upper,
+ sizeof remote_id_addr_upper - 1);
- switch (type)
- {
- case IPSEC_ATTR_SA_LIFE_TYPE:
- lifetype = decode_16 (value);
- break;
+ len = strlen(remote_id_addr_upper) +
+ strlen(remote_id_addr_lower) + 2;
+ remote_id = calloc(len, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%d, %lu) failed",
+ len, (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_id, remote_id_addr_lower, len);
+ strlcat(remote_id, "-", len);
+ strlcat(remote_id, remote_id_addr_upper, len);
+ break;
- case IPSEC_ATTR_SA_LIFE_DURATION:
- switch (proto->proto)
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
{
- case IPSEC_PROTO_IPSEC_AH:
- if (lifetype == IPSEC_DURATION_SECONDS)
- {
- if (len == 2)
- snprintf (ah_life_seconds, sizeof ah_life_seconds,
- "%u", decode_16 (value));
- else
- snprintf (ah_life_seconds, sizeof ah_life_seconds,
- "%u", decode_32 (value));
- }
- else
- {
- if (len == 2)
- snprintf (ah_life_kbytes, sizeof ah_life_kbytes,
- "%u", decode_16 (value));
- else
- snprintf (ah_life_kbytes, sizeof ah_life_kbytes,
- "%u", decode_32 (value));
- }
+ struct in6_addr net, mask;
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- if (lifetype == IPSEC_DURATION_SECONDS)
- {
- if (len == 2)
- snprintf (esp_life_seconds,
- sizeof esp_life_seconds, "%u",
- decode_16 (value));
- else
- snprintf (esp_life_seconds,
- sizeof esp_life_seconds, "%u",
- decode_32 (value));
- }
- else
- {
- if (len == 2)
- snprintf (esp_life_kbytes,
- sizeof esp_life_kbytes, "%u",
- decode_16 (value));
- else
- snprintf (esp_life_kbytes,
- sizeof esp_life_kbytes, "%u",
- decode_32 (value));
- }
+ remote_id_type = "IPv6 subnet";
- break;
-
- case IPSEC_PROTO_IPCOMP:
- if (lifetype == IPSEC_DURATION_SECONDS)
- {
- if (len == 2)
- snprintf (comp_life_seconds,
- sizeof comp_life_seconds, "%u",
- decode_16 (value));
- else
- snprintf (comp_life_seconds,
- sizeof comp_life_seconds, "%u",
- decode_32 (value));
- }
- else
- {
- if (len == 2)
- snprintf (comp_life_kbytes,
- sizeof comp_life_kbytes, "%u",
- decode_16 (value));
- else
- snprintf (comp_life_kbytes,
- sizeof comp_life_kbytes, "%u",
- decode_32 (value));
- }
+ bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, &net,
+ sizeof(net));
+ bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16, &mask,
+ sizeof(mask));
- break;
- }
- break;
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] &= mask.s6_addr[i];
- case IPSEC_ATTR_GROUP_DESCRIPTION:
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- snprintf (ah_group_desc, sizeof ah_group_desc, "%u",
- decode_16 (value));
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- snprintf (esp_group_desc, sizeof esp_group_desc, "%u",
- decode_16 (value));
- break;
-
- case IPSEC_PROTO_IPCOMP:
- snprintf (comp_group_desc, sizeof comp_group_desc, "%u",
- decode_16 (value));
- break;
- }
- break;
-
- case IPSEC_ATTR_ECN_TUNNEL:
- if (decode_16 (value))
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- ah_ecn = "yes";
- break;
+ my_inet_ntop6((unsigned char *) &net, remote_id_addr_lower,
+ sizeof remote_id_addr_lower - 1);
- case IPSEC_PROTO_IPSEC_ESP:
- esp_ecn = "yes";
- break;
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] |= ~mask.s6_addr[i];
- case IPSEC_PROTO_IPCOMP:
- comp_ecn = "yes";
- break;
- }
-
- case IPSEC_ATTR_ENCAPSULATION_MODE:
- if (decode_16 (value) == IPSEC_ENCAP_TUNNEL)
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- ah_encapsulation = "tunnel";
- break;
+ my_inet_ntop6((unsigned char *) &net, remote_id_addr_upper,
+ sizeof remote_id_addr_upper - 1);
- case IPSEC_PROTO_IPSEC_ESP:
- esp_encapsulation = "tunnel";
+ len = strlen(remote_id_addr_upper) +
+ strlen(remote_id_addr_lower) + 2;
+ remote_id = calloc(len, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%d, %lu) failed",
+ len, (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_id, remote_id_addr_lower, len);
+ strlcat(remote_id, "-", len);
+ strlcat(remote_id, remote_id_addr_upper, len);
break;
+ }
- case IPSEC_PROTO_IPCOMP:
- comp_encapsulation = "tunnel";
+ case IPSEC_ID_FQDN:
+ remote_id_type = "FQDN";
+ remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%lu, %lu) failed",
+ (unsigned long) id_sz - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ memcpy(remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
break;
- }
- else
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- ah_encapsulation = "transport";
+
+ case IPSEC_ID_USER_FQDN:
+ remote_id_type = "User FQDN";
+ remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%lu, %lu) failed",
+ (unsigned long) id_sz - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ + 1,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ memcpy(remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
+ id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
break;
- case IPSEC_PROTO_IPSEC_ESP:
- esp_encapsulation = "transport";
+ case IPSEC_ID_DER_ASN1_DN:
+ remote_id_type = "ASN1 DN";
+
+ remote_id = x509_DN_string(id + ISAKMP_ID_DATA_OFF -
+ ISAKMP_GEN_SZ,
+ id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
+ if (!remote_id) {
+ LOG_DBG((LOG_POLICY, 50,
+ "policy_callback: failed to decode name"));
+ goto bad;
+ }
break;
- case IPSEC_PROTO_IPCOMP:
- comp_encapsulation = "transport";
+ case IPSEC_ID_DER_ASN1_GN: /* XXX */
+ remote_id_type = "ASN1 GN";
break;
- }
- break;
- case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- switch (decode_16 (value))
- {
- case IPSEC_AUTH_HMAC_MD5:
- ah_auth_alg = "hmac-md5";
- break;
-
- case IPSEC_AUTH_HMAC_SHA:
- ah_auth_alg = "hmac-sha";
- break;
-
- case IPSEC_AUTH_HMAC_RIPEMD:
- ah_auth_alg = "hmac-ripemd";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_256:
- ah_auth_alg = "hmac-sha2-256";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_384:
- ah_auth_alg = "hmac-sha2-384";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_512:
- ah_auth_alg = "hmac-sha2-512";
- break;
-
- case IPSEC_AUTH_DES_MAC:
- ah_auth_alg = "des-mac";
- break;
-
- case IPSEC_AUTH_KPDK:
- ah_auth_alg = "kpdk";
- break;
+ case IPSEC_ID_KEY_ID:
+ remote_id_type = "Key ID";
+ remote_id = calloc(2 * (id_sz - ISAKMP_ID_DATA_OFF +
+ ISAKMP_GEN_SZ) + 1, sizeof(char));
+ if (!remote_id) {
+ log_error("policy_callback: calloc (%lu, %lu) failed",
+ 2 * ((unsigned long) id_sz -
+ ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
+ (unsigned long) sizeof(char));
+ goto bad;
}
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- switch (decode_16 (value))
- {
- case IPSEC_AUTH_HMAC_MD5:
- esp_auth_alg = "hmac-md5";
- break;
-
- case IPSEC_AUTH_HMAC_SHA:
- esp_auth_alg = "hmac-sha";
- break;
-
- case IPSEC_AUTH_HMAC_RIPEMD:
- esp_auth_alg = "hmac-ripemd";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_256:
- esp_auth_alg = "hmac-sha2-256";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_384:
- esp_auth_alg = "hmac-sha2-384";
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_512:
- esp_auth_alg = "hmac-sha2-512";
- break;
-
- case IPSEC_AUTH_DES_MAC:
- esp_auth_alg = "des-mac";
- break;
-
- case IPSEC_AUTH_KPDK:
- esp_auth_alg = "kpdk";
- break;
+ /* Does it contain any non-printable characters ? */
+ for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
+ if (!isprint(*(id + ISAKMP_ID_DATA_OFF -
+ ISAKMP_GEN_SZ + i)))
+ break;
+ if (i >= id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) {
+ memcpy(remote_id, id + ISAKMP_ID_DATA_OFF -
+ ISAKMP_GEN_SZ,
+ id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
+ break;
}
- break;
- }
- break;
-
- case IPSEC_ATTR_KEY_LENGTH:
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- snprintf (ah_key_length, sizeof ah_key_length, "%u",
- decode_16 (value));
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- snprintf (esp_key_length, sizeof esp_key_length, "%u",
- decode_16 (value));
- break;
- }
- break;
-
- case IPSEC_ATTR_KEY_ROUNDS:
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_AH:
- snprintf (ah_key_rounds, sizeof ah_key_rounds, "%u",
- decode_16 (value));
- break;
-
- case IPSEC_PROTO_IPSEC_ESP:
- snprintf (esp_key_rounds, sizeof esp_key_rounds, "%u",
- decode_16 (value));
- break;
- }
- break;
-
- case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
- snprintf (comp_dict_size, sizeof comp_dict_size, "%u",
- decode_16 (value));
- break;
+ /* Non-printable characters, convert to hex */
+ for (i = 0;
+ i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++) {
+ remote_id[2 * i] = hextab[*(id +
+ ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4];
+ remote_id[2 * i + 1] = hextab[*(id +
+ ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF];
+ }
+ break;
- case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
- snprintf (comp_private_alg, sizeof comp_private_alg, "%u",
- decode_16 (value));
- break;
+ default:
+ log_print("policy_callback: unknown remote ID type %u", id[0]);
+ goto bad;
}
- }
- }
-
- policy_sa->transport->vtbl->get_src (policy_sa->transport, &sin);
- if (sockaddr2text (sin, &addr, 1))
- {
- log_error ("policy_callback: sockaddr2text failed");
- goto bad;
- }
- strlcpy (local_ike_address, addr, sizeof local_ike_address);
- free (addr);
-
- policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
- if (sockaddr2text (sin, &addr, 1))
- {
- log_error ("policy_callback: sockaddr2text failed");
- goto bad;
- }
- strlcpy (remote_ike_address, addr, sizeof remote_ike_address);
- free (addr);
-
- switch (policy_isakmp_sa->exch_type)
- {
- case ISAKMP_EXCH_AGGRESSIVE:
- phase_1 = "aggressive";
- break;
-
- case ISAKMP_EXCH_ID_PROT:
- phase_1 = "main";
- break;
- }
-
- if (policy_isakmp_sa->initiator)
- {
- id = policy_isakmp_sa->id_r;
- id_sz = policy_isakmp_sa->id_r_len;
- }
- else
- {
- id = policy_isakmp_sa->id_i;
- id_sz = policy_isakmp_sa->id_i_len;
- }
-
- switch (id[0])
- {
- case IPSEC_ID_IPV4_ADDR:
- remote_id_type = "IPv4 address";
-
- net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- my_inet_ntop4 (&net, remote_id_addr_upper,
- sizeof remote_id_addr_upper - 1, 1);
- my_inet_ntop4 (&net, remote_id_addr_lower,
- sizeof remote_id_addr_lower - 1, 1);
- remote_id = strdup (remote_id_addr_upper);
- if (!remote_id)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- remote_id_addr_upper);
- goto bad;
- }
- break;
-
- case IPSEC_ID_IPV4_RANGE:
- remote_id_type = "IPv4 range";
-
- net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- my_inet_ntop4 (&net, remote_id_addr_lower,
- sizeof remote_id_addr_lower - 1, 1);
- net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
- my_inet_ntop4 (&net, remote_id_addr_upper,
- sizeof remote_id_addr_upper - 1, 1);
- len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
- + 2;
- remote_id = calloc (len, sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
-
- strlcpy (remote_id, remote_id_addr_lower, len);
- strlcat (remote_id, "-", len);
- strlcat (remote_id, remote_id_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- remote_id_type = "IPv4 subnet";
-
- net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
- subnet = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
- net &= subnet;
- my_inet_ntop4 (&net, remote_id_addr_lower,
- sizeof remote_id_addr_lower - 1, 1);
- net |= ~subnet;
- my_inet_ntop4 (&net, remote_id_addr_upper,
- sizeof remote_id_addr_upper - 1, 1);
- len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
- + 2;
- remote_id = calloc (len, sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
-
- strlcpy (remote_id, remote_id_addr_lower, len);
- strlcat (remote_id, "-", len);
- strlcat (remote_id, remote_id_addr_upper, len);
- break;
- case IPSEC_ID_IPV6_ADDR:
- remote_id_type = "IPv6 address";
- my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- remote_id_addr_upper, sizeof remote_id_addr_upper);
- strlcpy (remote_id_addr_lower, remote_id_addr_upper,
- sizeof remote_id_addr_lower);
- remote_id = strdup (remote_id_addr_upper);
- if (!remote_id)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- remote_id_addr_upper);
- goto bad;
- }
- break;
-
- case IPSEC_ID_IPV6_RANGE:
- remote_id_type = "IPv6 range";
-
- my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- remote_id_addr_lower,
- sizeof remote_id_addr_lower - 1);
-
- my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16,
- remote_id_addr_upper,
- sizeof remote_id_addr_upper - 1);
-
- len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
- + 2;
- remote_id = calloc (len, sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
-
- strlcpy (remote_id, remote_id_addr_lower, len);
- strlcat (remote_id, "-", len);
- strlcat (remote_id, remote_id_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- {
- struct in6_addr net, mask;
-
- remote_id_type = "IPv6 subnet";
-
- bcopy (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, &net, sizeof (net));
- bcopy (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16, &mask,
- sizeof (mask));
-
- for (i = 0; i < 16; i++)
- net.s6_addr[i] &= mask.s6_addr[i];
-
- my_inet_ntop6 ((unsigned char *) &net, remote_id_addr_lower,
- sizeof remote_id_addr_lower - 1);
-
- for (i = 0; i < 16; i++)
- net.s6_addr[i] |= ~mask.s6_addr[i];
-
- my_inet_ntop6 ((unsigned char *) &net, remote_id_addr_upper,
- sizeof remote_id_addr_upper - 1);
-
- len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
- + 2;
- remote_id = calloc (len, sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
-
- strlcpy (remote_id, remote_id_addr_lower, len);
- strlcat (remote_id, "-", len);
- strlcat (remote_id, remote_id_addr_upper, len);
- break;
- }
-
- case IPSEC_ID_FQDN:
- remote_id_type = "FQDN";
- remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%lu, %lu) failed",
- (unsigned long)id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- (unsigned long)sizeof (char));
- goto bad;
- }
- memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
-
- case IPSEC_ID_USER_FQDN:
- remote_id_type = "User FQDN";
- remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%lu, %lu) failed",
- (unsigned long)id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
- (unsigned long)sizeof (char));
- goto bad;
- }
- memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
-
- case IPSEC_ID_DER_ASN1_DN:
- remote_id_type = "ASN1 DN";
-
- remote_id = x509_DN_string (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_sz - ISAKMP_ID_DATA_OFF
- + ISAKMP_GEN_SZ);
- if (!remote_id)
- {
- LOG_DBG ((LOG_POLICY, 50,
- "policy_callback: failed to decode name"));
- goto bad;
- }
- break;
-
- case IPSEC_ID_DER_ASN1_GN: /* XXX */
- remote_id_type = "ASN1 GN";
- break;
-
- case IPSEC_ID_KEY_ID:
- remote_id_type = "Key ID";
- remote_id
- = calloc (2 * (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
- sizeof (char));
- if (!remote_id)
- {
- log_error ("policy_callback: calloc (%lu, %lu) failed",
- 2 * ((unsigned long)id_sz - ISAKMP_ID_DATA_OFF
- + ISAKMP_GEN_SZ) + 1,
- (unsigned long)sizeof (char));
- goto bad;
- }
- /* Does it contain any non-printable characters ? */
- for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
- if (!isprint (*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + i)))
- break;
- if (i >= id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ)
- {
- memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
- id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
- break;
- }
- /* Non-printable characters, convert to hex */
- for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
- {
- remote_id[2 * i]
- = hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4];
- remote_id[2 * i + 1]
- = hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF];
- }
- break;
-
- default:
- log_print ("policy_callback: unknown remote ID type %u", id[0]);
- goto bad;
- }
-
- switch (id[1])
- {
- case IPPROTO_TCP:
- remote_id_proto = "tcp";
- break;
+ switch (id[1]) {
+ case IPPROTO_TCP:
+ remote_id_proto = "tcp";
+ break;
- case IPPROTO_UDP:
- remote_id_proto = "udp";
- break;
+ case IPPROTO_UDP:
+ remote_id_proto = "udp";
+ break;
#ifdef IPPROTO_ETHERIP
- case IPPROTO_ETHERIP:
- remote_id_proto = "etherip";
- break;
+ case IPPROTO_ETHERIP:
+ remote_id_proto = "etherip";
+ break;
#endif
- default:
- snprintf (remote_id_proto_num, sizeof remote_id_proto_num, "%d",
- id[1]);
- remote_id_proto = remote_id_proto_num;
- break;
- }
-
- snprintf (remote_id_port, sizeof remote_id_port, "%u",
- decode_16 (id + 2));
-
- if (policy_exchange->initiator)
- {
- initiator = "yes";
- idlocal = ie->id_ci;
- idremote = ie->id_cr;
- idlocalsz = ie->id_ci_sz;
- idremotesz = ie->id_cr_sz;
- }
- else
- {
- initiator = "no";
- idlocal = ie->id_cr;
- idremote = ie->id_ci;
- idlocalsz = ie->id_cr_sz;
- idremotesz = ie->id_ci_sz;
- }
-
- /* Initialize the ID variables. */
- if (idremote)
- {
- switch (GET_ISAKMP_ID_TYPE (idremote))
- {
- case IPSEC_ID_IPV4_ADDR:
- remote_filter_type = "IPv4 address";
-
- net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
- my_inet_ntop4 (&net, remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1, 1);
- my_inet_ntop4 (&net, remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1, 1);
- remote_filter = strdup (remote_filter_addr_upper);
- if (!remote_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- remote_filter_addr_upper);
- goto bad;
- }
- break;
-
- case IPSEC_ID_IPV4_RANGE:
- remote_filter_type = "IPv4 range";
-
- net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
- my_inet_ntop4 (&net, remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1, 1);
- net = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
- my_inet_ntop4 (&net, remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1, 1);
- len = strlen (remote_filter_addr_upper)
- + strlen (remote_filter_addr_lower) + 2;
- remote_filter = calloc (len, sizeof (char));
- if (!remote_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
+ default:
+ snprintf(remote_id_proto_num, sizeof remote_id_proto_num, "%d",
+ id[1]);
+ remote_id_proto = remote_id_proto_num;
+ break;
}
- strlcpy (remote_filter, remote_filter_addr_lower, len);
- strlcat (remote_filter, "-", len);
- strlcat (remote_filter, remote_filter_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- remote_filter_type = "IPv4 subnet";
-
- net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
- subnet = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
- net &= subnet;
- my_inet_ntop4 (&net, remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1, 1);
- net |= ~subnet;
- my_inet_ntop4 (&net, remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1, 1);
- len = strlen (remote_filter_addr_upper)
- + strlen (remote_filter_addr_lower) + 2;
- remote_filter = calloc (len, sizeof (char));
- if (!remote_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
- strlcpy (remote_filter, remote_filter_addr_lower, len);
- strlcat (remote_filter, "-", len);
- strlcat (remote_filter, remote_filter_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- remote_filter_type = "IPv6 address";
- my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF,
- remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1);
- strlcpy (remote_filter_addr_lower, remote_filter_addr_upper,
- sizeof remote_filter_addr_lower);
- remote_filter = strdup (remote_filter_addr_upper);
- if (!remote_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- remote_filter_addr_upper);
- goto bad;
+ snprintf(remote_id_port, sizeof remote_id_port, "%u",
+ decode_16(id + 2));
+
+ if (policy_exchange->initiator) {
+ initiator = "yes";
+ idlocal = ie->id_ci;
+ idremote = ie->id_cr;
+ idlocalsz = ie->id_ci_sz;
+ idremotesz = ie->id_cr_sz;
+ } else {
+ initiator = "no";
+ idlocal = ie->id_cr;
+ idremote = ie->id_ci;
+ idlocalsz = ie->id_cr_sz;
+ idremotesz = ie->id_ci_sz;
}
- break;
-
- case IPSEC_ID_IPV6_RANGE:
- remote_filter_type = "IPv6 range";
- my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF,
- remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1);
+ /* Initialize the ID variables. */
+ if (idremote) {
+ switch (GET_ISAKMP_ID_TYPE(idremote)) {
+ case IPSEC_ID_IPV4_ADDR:
+ remote_filter_type = "IPv4 address";
+
+ net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
+ my_inet_ntop4(&net, remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1, 1);
+ my_inet_ntop4(&net, remote_filter_addr_lower,
+ sizeof remote_filter_addr_lower - 1, 1);
+ remote_filter = strdup(remote_filter_addr_upper);
+ if (!remote_filter) {
+ log_error("policy_callback: strdup "
+ "(\"%s\") failed",
+ remote_filter_addr_upper);
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_IPV4_RANGE:
+ remote_filter_type = "IPv4 range";
+
+ net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
+ my_inet_ntop4(&net, remote_filter_addr_lower,
+ sizeof remote_filter_addr_lower - 1, 1);
+ net = decode_32(idremote + ISAKMP_ID_DATA_OFF + 4);
+ my_inet_ntop4(&net, remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1, 1);
+ len = strlen(remote_filter_addr_upper) +
+ strlen(remote_filter_addr_lower) + 2;
+ remote_filter = calloc(len, sizeof(char));
+ if (!remote_filter) {
+ log_error("policy_callback: calloc "
+ "(%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_filter, remote_filter_addr_lower, len);
+ strlcat(remote_filter, "-", len);
+ strlcat(remote_filter, remote_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ remote_filter_type = "IPv4 subnet";
+
+ net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
+ subnet = decode_32(idremote + ISAKMP_ID_DATA_OFF + 4);
+ net &= subnet;
+ my_inet_ntop4(&net, remote_filter_addr_lower,
+ sizeof remote_filter_addr_lower - 1, 1);
+ net |= ~subnet;
+ my_inet_ntop4(&net, remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1, 1);
+ len = strlen(remote_filter_addr_upper) +
+ strlen(remote_filter_addr_lower) + 2;
+ remote_filter = calloc(len, sizeof(char));
+ if (!remote_filter) {
+ log_error("policy_callback: calloc "
+ "(%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_filter, remote_filter_addr_lower, len);
+ strlcat(remote_filter, "-", len);
+ strlcat(remote_filter, remote_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ remote_filter_type = "IPv6 address";
+ my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF,
+ remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1);
+ strlcpy(remote_filter_addr_lower,
+ remote_filter_addr_upper,
+ sizeof remote_filter_addr_lower);
+ remote_filter = strdup(remote_filter_addr_upper);
+ if (!remote_filter) {
+ log_error("policy_callback: strdup "
+ "(\"%s\") failed",
+ remote_filter_addr_upper);
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_IPV6_RANGE:
+ remote_filter_type = "IPv6 range";
+
+ my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF,
+ remote_filter_addr_lower,
+ sizeof remote_filter_addr_lower - 1);
+
+ my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF + 16,
+ remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1);
+
+ len = strlen(remote_filter_addr_upper) +
+ strlen(remote_filter_addr_lower) + 2;
+ remote_filter = calloc(len, sizeof(char));
+ if (!remote_filter) {
+ log_error("policy_callback: calloc "
+ "(%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_filter, remote_filter_addr_lower, len);
+ strlcat(remote_filter, "-", len);
+ strlcat(remote_filter, remote_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ {
+ struct in6_addr net, mask;
+
+ remote_filter_type = "IPv6 subnet";
+
+ bcopy(idremote + ISAKMP_ID_DATA_OFF, &net, sizeof(net));
+ bcopy(idremote + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof(mask));
+
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] &= mask.s6_addr[i];
+
+ my_inet_ntop6((unsigned char *) &net, remote_filter_addr_lower,
+ sizeof remote_filter_addr_lower - 1);
+
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] |= ~mask.s6_addr[i];
+
+ my_inet_ntop6((unsigned char *) &net, remote_filter_addr_upper,
+ sizeof remote_filter_addr_upper - 1);
+
+ len = strlen(remote_filter_addr_upper)
+ + strlen(remote_filter_addr_lower) + 2;
+ remote_filter = calloc(len, sizeof(char));
+ if (!remote_filter) {
+ log_error("policy_callback: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(remote_filter, remote_filter_addr_lower, len);
+ strlcat(remote_filter, "-", len);
+ strlcat(remote_filter, remote_filter_addr_upper, len);
+ break;
+ }
+
+ case IPSEC_ID_FQDN:
+ remote_filter_type = "FQDN";
+ remote_filter = malloc(idremotesz - ISAKMP_ID_DATA_OFF + 1);
+ if (!remote_filter) {
+ log_error("policy_callback: malloc (%lu) failed",
+ (unsigned long) idremotesz - ISAKMP_ID_DATA_OFF + 1);
+ goto bad;
+ }
+ memcpy(remote_filter, idremote + ISAKMP_ID_DATA_OFF,
+ idremotesz - ISAKMP_ID_DATA_OFF);
+ remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
+ break;
+
+ case IPSEC_ID_USER_FQDN:
+ remote_filter_type = "User FQDN";
+ remote_filter = malloc(idremotesz - ISAKMP_ID_DATA_OFF + 1);
+ if (!remote_filter) {
+ log_error("policy_callback: malloc (%lu) failed",
+ (unsigned long) idremotesz - ISAKMP_ID_DATA_OFF + 1);
+ goto bad;
+ }
+ memcpy(remote_filter, idremote + ISAKMP_ID_DATA_OFF,
+ idremotesz - ISAKMP_ID_DATA_OFF);
+ remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
+ break;
+
+ case IPSEC_ID_DER_ASN1_DN:
+ remote_filter_type = "ASN1 DN";
+
+ remote_filter = x509_DN_string(idremote + ISAKMP_ID_DATA_OFF,
+ idremotesz - ISAKMP_ID_DATA_OFF);
+ if (!remote_filter) {
+ LOG_DBG((LOG_POLICY, 50,
+ "policy_callback: failed to decode name"));
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure
+ * what's in this. */
+ remote_filter_type = "ASN1 GN";
+ break;
+
+ case IPSEC_ID_KEY_ID:
+ remote_filter_type = "Key ID";
+ remote_filter
+ = calloc(2 * (idremotesz - ISAKMP_ID_DATA_OFF) + 1,
+ sizeof(char));
+ if (!remote_filter) {
+ log_error("policy_callback: calloc (%lu, %lu) failed",
+ 2 * ((unsigned long) idremotesz - ISAKMP_ID_DATA_OFF) + 1,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ /*
+ * Does it contain any non-printable
+ * characters ?
+ */
+ for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
+ if (!isprint(*(idremote + ISAKMP_ID_DATA_OFF + i)))
+ break;
+ if (i >= idremotesz - ISAKMP_ID_DATA_OFF) {
+ memcpy(remote_filter, idremote + ISAKMP_ID_DATA_OFF,
+ idremotesz - ISAKMP_ID_DATA_OFF);
+ break;
+ }
+ /* Non-printable characters, convert to hex */
+ for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++) {
+ remote_filter[2 * i]
+ = hextab[*(idremote + ISAKMP_ID_DATA_OFF) >> 4];
+ remote_filter[2 * i + 1]
+ = hextab[*(idremote + ISAKMP_ID_DATA_OFF) & 0xF];
+ }
+ break;
+
+ default:
+ log_print("policy_callback: unknown Remote ID type %u",
+ GET_ISAKMP_ID_TYPE(idremote));
+ goto bad;
+ }
- my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF + 16,
- remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1);
+ switch (idremote[ISAKMP_GEN_SZ + 1]) {
+ case IPPROTO_TCP:
+ remote_filter_proto = "tcp";
+ break;
- len = strlen (remote_filter_addr_upper)
- + strlen (remote_filter_addr_lower) + 2;
- remote_filter = calloc (len, sizeof (char));
- if (!remote_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
+ case IPPROTO_UDP:
+ remote_filter_proto = "udp";
+ break;
- strlcpy (remote_filter, remote_filter_addr_lower, len);
- strlcat (remote_filter, "-", len);
- strlcat (remote_filter, remote_filter_addr_upper, len);
- break;
+#ifdef IPPROTO_ETHERIP
+ case IPPROTO_ETHERIP:
+ remote_filter_proto = "etherip";
+ break;
+#endif
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- {
- struct in6_addr net, mask;
+ default:
+ snprintf(remote_filter_proto_num,
+ sizeof remote_filter_proto_num, "%d",
+ idremote[ISAKMP_GEN_SZ + 1]);
+ remote_filter_proto = remote_filter_proto_num;
+ break;
+ }
- remote_filter_type = "IPv6 subnet";
+ snprintf(remote_filter_port, sizeof remote_filter_port, "%u",
+ decode_16(idremote + ISAKMP_GEN_SZ + 2));
+ } else {
+ policy_sa->transport->vtbl->get_dst(policy_sa->transport, &sin);
+ switch (sin->sa_family) {
+ case AF_INET:
+ remote_filter_type = "IPv4 address";
+ break;
+ case AF_INET6:
+ remote_filter_type = "IPv6 address";
+ break;
+ default:
+ log_print("policy_callback: unsupported protocol family %d",
+ sin->sa_family);
+ goto bad;
+ }
+ if (sockaddr2text(sin, &addr, 1)) {
+ log_error("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy(remote_filter_addr_upper, addr,
+ sizeof remote_filter_addr_upper);
+ memcpy(remote_filter_addr_lower, addr,
+ sizeof remote_filter_addr_lower);
+ free(addr);
+ remote_filter = strdup(remote_filter_addr_upper);
+ if (!remote_filter) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ remote_filter_addr_upper);
+ goto bad;
+ }
+ }
- bcopy (idremote + ISAKMP_ID_DATA_OFF, &net, sizeof (net));
- bcopy (idremote + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof (mask));
+ if (idlocal) {
+ switch (GET_ISAKMP_ID_TYPE(idlocal)) {
+ case IPSEC_ID_IPV4_ADDR:
+ local_filter_type = "IPv4 address";
+
+ net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
+ my_inet_ntop4(&net, local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1, 1);
+ my_inet_ntop4(&net, local_filter_addr_lower,
+ sizeof local_filter_addr_upper - 1, 1);
+ local_filter = strdup(local_filter_addr_upper);
+ if (!local_filter) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ local_filter_addr_upper);
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_IPV4_RANGE:
+ local_filter_type = "IPv4 range";
+
+ net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
+ my_inet_ntop4(&net, local_filter_addr_lower,
+ sizeof local_filter_addr_lower - 1, 1);
+ net = decode_32(idlocal + ISAKMP_ID_DATA_OFF + 4);
+ my_inet_ntop4(&net, local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1, 1);
+ len = strlen(local_filter_addr_upper)
+ + strlen(local_filter_addr_lower) + 2;
+ local_filter = calloc(len, sizeof(char));
+ if (!local_filter) {
+ log_error("policy_callback: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(local_filter, local_filter_addr_lower, len);
+ strlcat(local_filter, "-", len);
+ strlcat(local_filter, local_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ local_filter_type = "IPv4 subnet";
+
+ net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
+ subnet = decode_32(idlocal + ISAKMP_ID_DATA_OFF + 4);
+ net &= subnet;
+ my_inet_ntop4(&net, local_filter_addr_lower,
+ sizeof local_filter_addr_lower - 1, 1);
+ net |= ~subnet;
+ my_inet_ntop4(&net, local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1, 1);
+ len = strlen(local_filter_addr_upper)
+ + strlen(local_filter_addr_lower) + 2;
+ local_filter = calloc(len, sizeof(char));
+ if (!local_filter) {
+ log_error("policy_callback: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(local_filter, local_filter_addr_lower, len);
+ strlcat(local_filter, "-", len);
+ strlcat(local_filter, local_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ local_filter_type = "IPv6 address";
+ my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF,
+ local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1);
+ strlcpy(local_filter_addr_lower, local_filter_addr_upper,
+ sizeof local_filter_addr_lower);
+ local_filter = strdup(local_filter_addr_upper);
+ if (!local_filter) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ local_filter_addr_upper);
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_IPV6_RANGE:
+ local_filter_type = "IPv6 range";
+
+ my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF,
+ local_filter_addr_lower,
+ sizeof local_filter_addr_lower - 1);
+
+ my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF + 16,
+ local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1);
+
+ len = strlen(local_filter_addr_upper)
+ + strlen(local_filter_addr_lower) + 2;
+ local_filter = calloc(len, sizeof(char));
+ if (!local_filter) {
+ log_error("policy_callback: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(local_filter, local_filter_addr_lower, len);
+ strlcat(local_filter, "-", len);
+ strlcat(local_filter, local_filter_addr_upper, len);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ {
+ struct in6_addr net, mask;
+
+ local_filter_type = "IPv6 subnet";
+
+ bcopy(idlocal + ISAKMP_ID_DATA_OFF, &net, sizeof(net));
+ bcopy(idlocal + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof(mask));
+
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] &= mask.s6_addr[i];
+
+ my_inet_ntop6((unsigned char *) &net, local_filter_addr_lower,
+ sizeof local_filter_addr_lower - 1);
+
+ for (i = 0; i < 16; i++)
+ net.s6_addr[i] |= ~mask.s6_addr[i];
+
+ my_inet_ntop6((unsigned char *) &net, local_filter_addr_upper,
+ sizeof local_filter_addr_upper - 1);
+
+ len = strlen(local_filter_addr_upper)
+ + strlen(local_filter_addr_lower) + 2;
+ local_filter = calloc(len, sizeof(char));
+ if (!local_filter) {
+ log_error("policy_callback: calloc (%d, %lu) failed", len,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ strlcpy(local_filter, local_filter_addr_lower, len);
+ strlcat(local_filter, "-", len);
+ strlcat(local_filter, local_filter_addr_upper, len);
+ break;
+ }
+
+ case IPSEC_ID_FQDN:
+ local_filter_type = "FQDN";
+ local_filter = malloc(idlocalsz - ISAKMP_ID_DATA_OFF + 1);
+ if (!local_filter) {
+ log_error("policy_callback: malloc (%lu) failed",
+ (unsigned long) idlocalsz - ISAKMP_ID_DATA_OFF + 1);
+ goto bad;
+ }
+ memcpy(local_filter, idlocal + ISAKMP_ID_DATA_OFF,
+ idlocalsz - ISAKMP_ID_DATA_OFF);
+ local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
+ break;
+
+ case IPSEC_ID_USER_FQDN:
+ local_filter_type = "User FQDN";
+ local_filter = malloc(idlocalsz - ISAKMP_ID_DATA_OFF + 1);
+ if (!local_filter) {
+ log_error("policy_callback: malloc (%lu) failed",
+ (unsigned long) idlocalsz - ISAKMP_ID_DATA_OFF + 1);
+ goto bad;
+ }
+ memcpy(local_filter, idlocal + ISAKMP_ID_DATA_OFF,
+ idlocalsz - ISAKMP_ID_DATA_OFF);
+ local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
+ break;
+
+ case IPSEC_ID_DER_ASN1_DN:
+ local_filter_type = "ASN1 DN";
+
+ local_filter = x509_DN_string(idlocal + ISAKMP_ID_DATA_OFF,
+ idlocalsz - ISAKMP_ID_DATA_OFF);
+ if (!local_filter) {
+ LOG_DBG((LOG_POLICY, 50,
+ "policy_callback: failed to decode name"));
+ goto bad;
+ }
+ break;
+
+ case IPSEC_ID_DER_ASN1_GN:
+ /* XXX -- not sure what's in this. */
+ local_filter_type = "ASN1 GN";
+ break;
+
+ case IPSEC_ID_KEY_ID:
+ local_filter_type = "Key ID";
+ local_filter = calloc(2 * (idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
+ sizeof(char));
+ if (!local_filter) {
+ log_error("policy_callback: calloc (%lu, %lu) failed",
+ 2 * ((unsigned long) idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
+ (unsigned long) sizeof(char));
+ goto bad;
+ }
+ /*
+ * Does it contain any non-printable
+ * characters ?
+ */
+ for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
+ if (!isprint(*(idlocal + ISAKMP_ID_DATA_OFF + i)))
+ break;
+ if (i >= idlocalsz - ISAKMP_ID_DATA_OFF) {
+ memcpy(local_filter, idlocal + ISAKMP_ID_DATA_OFF,
+ idlocalsz - ISAKMP_ID_DATA_OFF);
+ break;
+ }
+ /* Non-printable characters, convert to hex */
+ for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++) {
+ local_filter[2 * i]
+ = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) >> 4];
+ local_filter[2 * i + 1]
+ = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) & 0xF];
+ }
+ break;
+
+ default:
+ log_print("policy_callback: unknown Local ID type %u",
+ GET_ISAKMP_ID_TYPE(idlocal));
+ goto bad;
+ }
- for (i = 0; i < 16; i++)
- net.s6_addr[i] &= mask.s6_addr[i];
+ switch (idlocal[ISAKMP_GEN_SZ + 1]) {
+ case IPPROTO_TCP:
+ local_filter_proto = "tcp";
+ break;
- my_inet_ntop6 ((unsigned char *) &net, remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1);
+ case IPPROTO_UDP:
+ local_filter_proto = "udp";
+ break;
- for (i = 0; i < 16; i++)
- net.s6_addr[i] |= ~mask.s6_addr[i];
+#ifdef IPPROTO_ETHERIP
+ case IPPROTO_ETHERIP:
+ local_filter_proto = "etherip";
+ break;
+#endif
- my_inet_ntop6 ((unsigned char *) &net, remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1);
+ default:
+ snprintf(local_filter_proto_num, sizeof local_filter_proto_num,
+ "%d", idlocal[ISAKMP_GEN_SZ + 1]);
+ local_filter_proto = local_filter_proto_num;
+ break;
+ }
- len = strlen (remote_filter_addr_upper)
- + strlen (remote_filter_addr_lower) + 2;
- remote_filter = calloc (len, sizeof (char));
- if (!remote_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
+ snprintf(local_filter_port, sizeof local_filter_port, "%u",
+ decode_16(idlocal + ISAKMP_GEN_SZ + 2));
+ } else {
+ policy_sa->transport->vtbl->get_src(policy_sa->transport,
+ (struct sockaddr **) & sin);
+ switch (sin->sa_family) {
+ case AF_INET:
+ local_filter_type = "IPv4 address";
+ break;
+ case AF_INET6:
+ local_filter_type = "IPv6 address";
+ break;
+ default:
+ log_print("policy_callback: unsupported protocol family %d",
+ sin->sa_family);
+ goto bad;
+ }
- strlcpy (remote_filter, remote_filter_addr_lower, len);
- strlcat (remote_filter, "-", len);
- strlcat (remote_filter, remote_filter_addr_upper, len);
- break;
- }
-
- case IPSEC_ID_FQDN:
- remote_filter_type = "FQDN";
- remote_filter = malloc (idremotesz - ISAKMP_ID_DATA_OFF + 1);
- if (!remote_filter)
- {
- log_error ("policy_callback: malloc (%lu) failed",
- (unsigned long)idremotesz - ISAKMP_ID_DATA_OFF + 1);
- goto bad;
- }
- memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
- idremotesz - ISAKMP_ID_DATA_OFF);
- remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
- break;
-
- case IPSEC_ID_USER_FQDN:
- remote_filter_type = "User FQDN";
- remote_filter = malloc (idremotesz - ISAKMP_ID_DATA_OFF + 1);
- if (!remote_filter)
- {
- log_error ("policy_callback: malloc (%lu) failed",
- (unsigned long)idremotesz - ISAKMP_ID_DATA_OFF + 1);
- goto bad;
- }
- memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
- idremotesz - ISAKMP_ID_DATA_OFF);
- remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
- break;
-
- case IPSEC_ID_DER_ASN1_DN:
- remote_filter_type = "ASN1 DN";
-
- remote_filter = x509_DN_string (idremote + ISAKMP_ID_DATA_OFF,
- idremotesz - ISAKMP_ID_DATA_OFF);
- if (!remote_filter)
- {
- LOG_DBG ((LOG_POLICY, 50,
- "policy_callback: failed to decode name"));
- goto bad;
- }
- break;
-
- case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this. */
- remote_filter_type = "ASN1 GN";
- break;
-
- case IPSEC_ID_KEY_ID:
- remote_filter_type = "Key ID";
- remote_filter
- = calloc (2 * (idremotesz - ISAKMP_ID_DATA_OFF) + 1,
- sizeof (char));
- if (!remote_filter)
- {
- log_error ("policy_callback: calloc (%lu, %lu) failed",
- 2 * ((unsigned long)idremotesz - ISAKMP_ID_DATA_OFF) + 1,
- (unsigned long)sizeof (char));
- goto bad;
- }
- /* Does it contain any non-printable characters ? */
- for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
- if (!isprint (*(idremote + ISAKMP_ID_DATA_OFF + i)))
- break;
- if (i >= idremotesz - ISAKMP_ID_DATA_OFF)
- {
- memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
- idremotesz - ISAKMP_ID_DATA_OFF);
- break;
+ if (sockaddr2text(sin, &addr, 1)) {
+ log_error("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy(local_filter_addr_upper, addr,
+ sizeof local_filter_addr_upper);
+ memcpy(local_filter_addr_lower, addr,
+ sizeof local_filter_addr_lower);
+ free(addr);
+ local_filter = strdup(local_filter_addr_upper);
+ if (!local_filter) {
+ log_error("policy_callback: strdup (\"%s\") failed",
+ local_filter_addr_upper);
+ goto bad;
+ }
}
- /* Non-printable characters, convert to hex */
- for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
- {
- remote_filter[2 * i]
- = hextab[*(idremote + ISAKMP_ID_DATA_OFF) >> 4];
- remote_filter[2 * i + 1]
- = hextab[*(idremote + ISAKMP_ID_DATA_OFF) & 0xF];
- }
- break;
-
- default:
- log_print ("policy_callback: unknown Remote ID type %u",
- GET_ISAKMP_ID_TYPE (idremote));
- goto bad;
- }
-
- switch (idremote[ISAKMP_GEN_SZ + 1])
- {
- case IPPROTO_TCP:
- remote_filter_proto = "tcp";
- break;
-
- case IPPROTO_UDP:
- remote_filter_proto = "udp";
- break;
-
-#ifdef IPPROTO_ETHERIP
- case IPPROTO_ETHERIP:
- remote_filter_proto = "etherip";
- break;
-#endif
- default:
- snprintf (remote_filter_proto_num,
- sizeof remote_filter_proto_num, "%d",
- idremote[ISAKMP_GEN_SZ + 1]);
- remote_filter_proto = remote_filter_proto_num;
- break;
- }
+ LOG_DBG((LOG_POLICY, 80, "Policy context (action attributes):"));
+ LOG_DBG((LOG_POLICY, 80, "esp_present == %s", esp_present));
+ LOG_DBG((LOG_POLICY, 80, "ah_present == %s", ah_present));
+ LOG_DBG((LOG_POLICY, 80, "comp_present == %s", comp_present));
+ LOG_DBG((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg));
+ LOG_DBG((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg));
+ LOG_DBG((LOG_POLICY, 80, "comp_alg == %s", comp_alg));
+ LOG_DBG((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg));
+ LOG_DBG((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg));
+ LOG_DBG((LOG_POLICY, 80, "ah_life_seconds == %s", ah_life_seconds));
+ LOG_DBG((LOG_POLICY, 80, "ah_life_kbytes == %s", ah_life_kbytes));
+ LOG_DBG((LOG_POLICY, 80, "esp_life_seconds == %s", esp_life_seconds));
+ LOG_DBG((LOG_POLICY, 80, "esp_life_kbytes == %s", esp_life_kbytes));
+ LOG_DBG((LOG_POLICY, 80, "comp_life_seconds == %s", comp_life_seconds));
+ LOG_DBG((LOG_POLICY, 80, "comp_life_kbytes == %s", comp_life_kbytes));
+ LOG_DBG((LOG_POLICY, 80, "ah_encapsulation == %s", ah_encapsulation));
+ LOG_DBG((LOG_POLICY, 80, "esp_encapsulation == %s", esp_encapsulation));
+ LOG_DBG((LOG_POLICY, 80, "comp_encapsulation == %s",
+ comp_encapsulation));
+ LOG_DBG((LOG_POLICY, 80, "comp_dict_size == %s", comp_dict_size));
+ LOG_DBG((LOG_POLICY, 80, "comp_private_alg == %s", comp_private_alg));
+ LOG_DBG((LOG_POLICY, 80, "ah_key_length == %s", ah_key_length));
+ LOG_DBG((LOG_POLICY, 80, "ah_key_rounds == %s", ah_key_rounds));
+ LOG_DBG((LOG_POLICY, 80, "esp_key_length == %s", esp_key_length));
+ LOG_DBG((LOG_POLICY, 80, "esp_key_rounds == %s", esp_key_rounds));
+ LOG_DBG((LOG_POLICY, 80, "ah_group_desc == %s", ah_group_desc));
+ LOG_DBG((LOG_POLICY, 80, "esp_group_desc == %s", esp_group_desc));
+ LOG_DBG((LOG_POLICY, 80, "comp_group_desc == %s", comp_group_desc));
+ LOG_DBG((LOG_POLICY, 80, "ah_ecn == %s", ah_ecn));
+ LOG_DBG((LOG_POLICY, 80, "esp_ecn == %s", esp_ecn));
+ LOG_DBG((LOG_POLICY, 80, "comp_ecn == %s", comp_ecn));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter_type == %s",
+ remote_filter_type));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_upper == %s",
+ remote_filter_addr_upper));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_lower == %s",
+ remote_filter_addr_lower));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter == %s",
+ (remote_filter ? remote_filter : "")));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter_port == %s",
+ remote_filter_port));
+ LOG_DBG((LOG_POLICY, 80, "remote_filter_proto == %s",
+ remote_filter_proto));
+ LOG_DBG((LOG_POLICY, 80, "local_filter_type == %s", local_filter_type));
+ LOG_DBG((LOG_POLICY, 80, "local_filter_addr_upper == %s",
+ local_filter_addr_upper));
+ LOG_DBG((LOG_POLICY, 80, "local_filter_addr_lower == %s",
+ local_filter_addr_lower));
+ LOG_DBG((LOG_POLICY, 80, "local_filter == %s",
+ (local_filter ? local_filter : "")));
+ LOG_DBG((LOG_POLICY, 80, "local_filter_port == %s", local_filter_port));
+ LOG_DBG((LOG_POLICY, 80, "local_filter_proto == %s",
+ local_filter_proto));
+ LOG_DBG((LOG_POLICY, 80, "remote_id_type == %s", remote_id_type));
+ LOG_DBG((LOG_POLICY, 80, "remote_id_addr_upper == %s",
+ remote_id_addr_upper));
+ LOG_DBG((LOG_POLICY, 80, "remote_id_addr_lower == %s",
+ remote_id_addr_lower));
+ LOG_DBG((LOG_POLICY, 80, "remote_id == %s",
+ (remote_id ? remote_id : "")));
+ LOG_DBG((LOG_POLICY, 80, "remote_id_port == %s", remote_id_port));
+ LOG_DBG((LOG_POLICY, 80, "remote_id_proto == %s", remote_id_proto));
+ LOG_DBG((LOG_POLICY, 80, "remote_negotiation_address == %s",
+ remote_ike_address));
+ LOG_DBG((LOG_POLICY, 80, "local_negotiation_address == %s",
+ local_ike_address));
+ LOG_DBG((LOG_POLICY, 80, "pfs == %s", pfs));
+ LOG_DBG((LOG_POLICY, 80, "initiator == %s", initiator));
+ LOG_DBG((LOG_POLICY, 80, "phase1_group_desc == %s", phase1_group));
+
+ /* Unset dirty now. */
+ dirty = 0;
+ }
+ if (strcmp(name, "phase_1") == 0)
+ return phase_1;
- snprintf (remote_filter_port, sizeof remote_filter_port, "%u",
- decode_16 (idremote + ISAKMP_GEN_SZ + 2));
+ if (strcmp(name, "GMTTimeOfDay") == 0) {
+ tt = time((time_t) NULL);
+ strftime(mytimeofday, 14, "%Y%m%d%H%M%S", gmtime(&tt));
+ return mytimeofday;
}
- else
- {
- policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
- switch (sin->sa_family)
- {
- case AF_INET:
- remote_filter_type = "IPv4 address";
- break;
- case AF_INET6:
- remote_filter_type = "IPv6 address";
- break;
- default:
- log_print ("policy_callback: unsupported protocol family %d",
- sin->sa_family);
- goto bad;
- }
- if (sockaddr2text (sin, &addr, 1))
- {
- log_error ("policy_callback: sockaddr2text failed");
- goto bad;
- }
- memcpy (remote_filter_addr_upper, addr,
- sizeof remote_filter_addr_upper);
- memcpy (remote_filter_addr_lower, addr,
- sizeof remote_filter_addr_lower);
- free (addr);
- remote_filter = strdup (remote_filter_addr_upper);
- if (!remote_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- remote_filter_addr_upper);
- goto bad;
- }
+ if (strcmp(name, "LocalTimeOfDay") == 0) {
+ tt = time((time_t) NULL);
+ strftime(mytimeofday, 14, "%Y%m%d%H%M%S", localtime(&tt));
+ return mytimeofday;
}
+ if (strcmp(name, "initiator") == 0)
+ return initiator;
- if (idlocal)
- {
- switch (GET_ISAKMP_ID_TYPE (idlocal))
- {
- case IPSEC_ID_IPV4_ADDR:
- local_filter_type = "IPv4 address";
-
- net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
- my_inet_ntop4 (&net, local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1, 1);
- my_inet_ntop4 (&net, local_filter_addr_lower,
- sizeof local_filter_addr_upper - 1, 1);
- local_filter = strdup (local_filter_addr_upper);
- if (!local_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- local_filter_addr_upper);
- goto bad;
- }
- break;
-
- case IPSEC_ID_IPV4_RANGE:
- local_filter_type = "IPv4 range";
-
- net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
- my_inet_ntop4 (&net, local_filter_addr_lower,
- sizeof local_filter_addr_lower - 1, 1);
- net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
- my_inet_ntop4 (&net, local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1, 1);
- len = strlen (local_filter_addr_upper)
- + strlen (local_filter_addr_lower) + 2;
- local_filter = calloc (len, sizeof (char));
- if (!local_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
- strlcpy (local_filter, local_filter_addr_lower, len);
- strlcat (local_filter, "-", len);
- strlcat (local_filter, local_filter_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- local_filter_type = "IPv4 subnet";
-
- net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
- subnet = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
- net &= subnet;
- my_inet_ntop4 (&net, local_filter_addr_lower,
- sizeof local_filter_addr_lower - 1, 1);
- net |= ~subnet;
- my_inet_ntop4 (&net, local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1, 1);
- len = strlen (local_filter_addr_upper)
- + strlen (local_filter_addr_lower) + 2;
- local_filter = calloc (len, sizeof (char));
- if (!local_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
- strlcpy (local_filter, local_filter_addr_lower, len);
- strlcat (local_filter, "-", len);
- strlcat (local_filter, local_filter_addr_upper, len);
- break;
-
- case IPSEC_ID_IPV6_ADDR:
- local_filter_type = "IPv6 address";
- my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF,
- local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1);
- strlcpy (local_filter_addr_lower, local_filter_addr_upper,
- sizeof local_filter_addr_lower);
- local_filter = strdup (local_filter_addr_upper);
- if (!local_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- local_filter_addr_upper);
- goto bad;
- }
- break;
+ if (strcmp(name, "pfs") == 0)
+ return pfs;
- case IPSEC_ID_IPV6_RANGE:
- local_filter_type = "IPv6 range";
+ if (strcmp(name, "app_domain") == 0)
+ return "IPsec policy";
- my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF,
- local_filter_addr_lower,
- sizeof local_filter_addr_lower - 1);
+ if (strcmp(name, "doi") == 0)
+ return "ipsec";
- my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF + 16,
- local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1);
+ if (strcmp(name, "esp_present") == 0)
+ return esp_present;
- len = strlen (local_filter_addr_upper)
- + strlen (local_filter_addr_lower) + 2;
- local_filter = calloc (len, sizeof (char));
- if (!local_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
+ if (strcmp(name, "ah_present") == 0)
+ return ah_present;
- strlcpy (local_filter, local_filter_addr_lower, len);
- strlcat (local_filter, "-", len);
- strlcat (local_filter, local_filter_addr_upper, len);
- break;
+ if (strcmp(name, "comp_present") == 0)
+ return comp_present;
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- {
- struct in6_addr net, mask;
+ if (strcmp(name, "ah_hash_alg") == 0)
+ return ah_hash_alg;
- local_filter_type = "IPv6 subnet";
+ if (strcmp(name, "ah_auth_alg") == 0)
+ return ah_auth_alg;
- bcopy (idlocal + ISAKMP_ID_DATA_OFF, &net, sizeof (net));
- bcopy (idlocal + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof (mask));
+ if (strcmp(name, "esp_auth_alg") == 0)
+ return esp_auth_alg;
- for (i = 0; i < 16; i++)
- net.s6_addr[i] &= mask.s6_addr[i];
+ if (strcmp(name, "esp_enc_alg") == 0)
+ return esp_enc_alg;
- my_inet_ntop6 ((unsigned char *) &net, local_filter_addr_lower,
- sizeof local_filter_addr_lower - 1);
+ if (strcmp(name, "comp_alg") == 0)
+ return comp_alg;
- for (i = 0; i < 16; i++)
- net.s6_addr[i] |= ~mask.s6_addr[i];
+ if (strcmp(name, "ah_life_kbytes") == 0)
+ return ah_life_kbytes;
- my_inet_ntop6 ((unsigned char *) &net, local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1);
+ if (strcmp(name, "ah_life_seconds") == 0)
+ return ah_life_seconds;
- len = strlen (local_filter_addr_upper)
- + strlen (local_filter_addr_lower) + 2;
- local_filter = calloc (len, sizeof (char));
- if (!local_filter)
- {
- log_error ("policy_callback: calloc (%d, %lu) failed", len,
- (unsigned long)sizeof (char));
- goto bad;
- }
+ if (strcmp(name, "esp_life_kbytes") == 0)
+ return esp_life_kbytes;
- strlcpy (local_filter, local_filter_addr_lower, len);
- strlcat (local_filter, "-", len);
- strlcat (local_filter, local_filter_addr_upper, len);
- break;
- }
-
- case IPSEC_ID_FQDN:
- local_filter_type = "FQDN";
- local_filter = malloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1);
- if (!local_filter)
- {
- log_error ("policy_callback: malloc (%lu) failed",
- (unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF + 1);
- goto bad;
- }
- memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
- idlocalsz - ISAKMP_ID_DATA_OFF);
- local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
- break;
-
- case IPSEC_ID_USER_FQDN:
- local_filter_type = "User FQDN";
- local_filter = malloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1);
- if (!local_filter)
- {
- log_error ("policy_callback: malloc (%lu) failed",
- (unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF + 1);
- goto bad;
- }
- memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
- idlocalsz - ISAKMP_ID_DATA_OFF);
- local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
- break;
-
- case IPSEC_ID_DER_ASN1_DN:
- local_filter_type = "ASN1 DN";
-
- local_filter = x509_DN_string (idlocal + ISAKMP_ID_DATA_OFF,
- idlocalsz - ISAKMP_ID_DATA_OFF);
- if (!local_filter)
- {
- LOG_DBG ((LOG_POLICY, 50,
- "policy_callback: failed to decode name"));
- goto bad;
- }
- break;
-
- case IPSEC_ID_DER_ASN1_GN:
- /* XXX -- not sure what's in this. */
- local_filter_type = "ASN1 GN";
- break;
-
- case IPSEC_ID_KEY_ID:
- local_filter_type = "Key ID";
- local_filter = calloc (2 * (idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
- sizeof (char));
- if (!local_filter)
- {
- log_error ("policy_callback: calloc (%lu, %lu) failed",
- 2 * ((unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
- (unsigned long)sizeof (char));
- goto bad;
- }
- /* Does it contain any non-printable characters ? */
- for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
- if (!isprint (*(idlocal + ISAKMP_ID_DATA_OFF + i)))
- break;
- if (i >= idlocalsz - ISAKMP_ID_DATA_OFF)
- {
- memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
- idlocalsz - ISAKMP_ID_DATA_OFF);
- break;
- }
- /* Non-printable characters, convert to hex */
- for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
- {
- local_filter[2 * i]
- = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) >> 4];
- local_filter[2 * i + 1]
- = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) & 0xF];
- }
- break;
-
- default:
- log_print ("policy_callback: unknown Local ID type %u",
- GET_ISAKMP_ID_TYPE (idlocal));
- goto bad;
- }
-
- switch (idlocal[ISAKMP_GEN_SZ + 1])
- {
- case IPPROTO_TCP:
- local_filter_proto = "tcp";
- break;
-
- case IPPROTO_UDP:
- local_filter_proto = "udp";
- break;
-
-#ifdef IPPROTO_ETHERIP
- case IPPROTO_ETHERIP:
- local_filter_proto = "etherip";
- break;
-#endif
+ if (strcmp(name, "esp_life_seconds") == 0)
+ return esp_life_seconds;
- default:
- snprintf (local_filter_proto_num, sizeof local_filter_proto_num,
- "%d", idlocal[ISAKMP_GEN_SZ + 1]);
- local_filter_proto = local_filter_proto_num;
- break;
- }
+ if (strcmp(name, "comp_life_kbytes") == 0)
+ return comp_life_kbytes;
- snprintf (local_filter_port, sizeof local_filter_port, "%u",
- decode_16 (idlocal + ISAKMP_GEN_SZ + 2));
- }
- else
- {
- policy_sa->transport->vtbl->get_src (policy_sa->transport,
- (struct sockaddr **)&sin);
- switch (sin->sa_family)
- {
- case AF_INET:
- local_filter_type = "IPv4 address";
- break;
- case AF_INET6:
- local_filter_type = "IPv6 address";
- break;
- default:
- log_print ("policy_callback: unsupported protocol family %d",
- sin->sa_family);
- goto bad;
- }
-
- if (sockaddr2text (sin, &addr, 1))
- {
- log_error ("policy_callback: sockaddr2text failed");
- goto bad;
- }
- memcpy (local_filter_addr_upper, addr,
- sizeof local_filter_addr_upper);
- memcpy (local_filter_addr_lower, addr,
- sizeof local_filter_addr_lower);
- free (addr);
- local_filter = strdup (local_filter_addr_upper);
- if (!local_filter)
- {
- log_error ("policy_callback: strdup (\"%s\") failed",
- local_filter_addr_upper);
- goto bad;
- }
- }
-
- LOG_DBG ((LOG_POLICY, 80, "Policy context (action attributes):"));
- LOG_DBG ((LOG_POLICY, 80, "esp_present == %s", esp_present));
- LOG_DBG ((LOG_POLICY, 80, "ah_present == %s", ah_present));
- LOG_DBG ((LOG_POLICY, 80, "comp_present == %s", comp_present));
- LOG_DBG ((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg));
- LOG_DBG ((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg));
- LOG_DBG ((LOG_POLICY, 80, "comp_alg == %s", comp_alg));
- LOG_DBG ((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg));
- LOG_DBG ((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg));
- LOG_DBG ((LOG_POLICY, 80, "ah_life_seconds == %s", ah_life_seconds));
- LOG_DBG ((LOG_POLICY, 80, "ah_life_kbytes == %s", ah_life_kbytes));
- LOG_DBG ((LOG_POLICY, 80, "esp_life_seconds == %s", esp_life_seconds));
- LOG_DBG ((LOG_POLICY, 80, "esp_life_kbytes == %s", esp_life_kbytes));
- LOG_DBG ((LOG_POLICY, 80, "comp_life_seconds == %s", comp_life_seconds));
- LOG_DBG ((LOG_POLICY, 80, "comp_life_kbytes == %s", comp_life_kbytes));
- LOG_DBG ((LOG_POLICY, 80, "ah_encapsulation == %s", ah_encapsulation));
- LOG_DBG ((LOG_POLICY, 80, "esp_encapsulation == %s", esp_encapsulation));
- LOG_DBG ((LOG_POLICY, 80, "comp_encapsulation == %s",
- comp_encapsulation));
- LOG_DBG ((LOG_POLICY, 80, "comp_dict_size == %s", comp_dict_size));
- LOG_DBG ((LOG_POLICY, 80, "comp_private_alg == %s", comp_private_alg));
- LOG_DBG ((LOG_POLICY, 80, "ah_key_length == %s", ah_key_length));
- LOG_DBG ((LOG_POLICY, 80, "ah_key_rounds == %s", ah_key_rounds));
- LOG_DBG ((LOG_POLICY, 80, "esp_key_length == %s", esp_key_length));
- LOG_DBG ((LOG_POLICY, 80, "esp_key_rounds == %s", esp_key_rounds));
- LOG_DBG ((LOG_POLICY, 80, "ah_group_desc == %s", ah_group_desc));
- LOG_DBG ((LOG_POLICY, 80, "esp_group_desc == %s", esp_group_desc));
- LOG_DBG ((LOG_POLICY, 80, "comp_group_desc == %s", comp_group_desc));
- LOG_DBG ((LOG_POLICY, 80, "ah_ecn == %s", ah_ecn));
- LOG_DBG ((LOG_POLICY, 80, "esp_ecn == %s", esp_ecn));
- LOG_DBG ((LOG_POLICY, 80, "comp_ecn == %s", comp_ecn));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter_type == %s",
- remote_filter_type));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_upper == %s",
- remote_filter_addr_upper));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_lower == %s",
- remote_filter_addr_lower));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter == %s",
- (remote_filter ? remote_filter : "")));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter_port == %s",
- remote_filter_port));
- LOG_DBG ((LOG_POLICY, 80, "remote_filter_proto == %s",
- remote_filter_proto));
- LOG_DBG ((LOG_POLICY, 80, "local_filter_type == %s", local_filter_type));
- LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_upper == %s",
- local_filter_addr_upper));
- LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_lower == %s",
- local_filter_addr_lower));
- LOG_DBG ((LOG_POLICY, 80, "local_filter == %s",
- (local_filter ? local_filter : "")));
- LOG_DBG ((LOG_POLICY, 80, "local_filter_port == %s", local_filter_port));
- LOG_DBG ((LOG_POLICY, 80, "local_filter_proto == %s",
- local_filter_proto));
- LOG_DBG ((LOG_POLICY, 80, "remote_id_type == %s", remote_id_type));
- LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_upper == %s",
- remote_id_addr_upper));
- LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_lower == %s",
- remote_id_addr_lower));
- LOG_DBG ((LOG_POLICY, 80, "remote_id == %s",
- (remote_id ? remote_id : "")));
- LOG_DBG ((LOG_POLICY, 80, "remote_id_port == %s", remote_id_port));
- LOG_DBG ((LOG_POLICY, 80, "remote_id_proto == %s", remote_id_proto));
- LOG_DBG ((LOG_POLICY, 80, "remote_negotiation_address == %s",
- remote_ike_address));
- LOG_DBG ((LOG_POLICY, 80, "local_negotiation_address == %s",
- local_ike_address));
- LOG_DBG ((LOG_POLICY, 80, "pfs == %s", pfs));
- LOG_DBG ((LOG_POLICY, 80, "initiator == %s", initiator));
- LOG_DBG ((LOG_POLICY, 80, "phase1_group_desc == %s", phase1_group));
-
- /* Unset dirty now. */
- dirty = 0;
- }
-
- if (strcmp (name, "phase_1") == 0)
- return phase_1;
-
- if (strcmp (name, "GMTTimeOfDay") == 0)
- {
- tt = time ((time_t) NULL);
- strftime (mytimeofday, 14, "%Y%m%d%H%M%S", gmtime (&tt));
- return mytimeofday;
- }
-
- if (strcmp (name, "LocalTimeOfDay") == 0)
- {
- tt = time ((time_t) NULL);
- strftime (mytimeofday, 14, "%Y%m%d%H%M%S", localtime (&tt));
- return mytimeofday;
- }
-
- if (strcmp (name, "initiator") == 0)
- return initiator;
-
- if (strcmp (name, "pfs") == 0)
- return pfs;
-
- if (strcmp (name, "app_domain") == 0)
- return "IPsec policy";
-
- if (strcmp (name, "doi") == 0)
- return "ipsec";
-
- if (strcmp (name, "esp_present") == 0)
- return esp_present;
-
- if (strcmp (name, "ah_present") == 0)
- return ah_present;
-
- if (strcmp (name, "comp_present") == 0)
- return comp_present;
-
- if (strcmp (name, "ah_hash_alg") == 0)
- return ah_hash_alg;
-
- if (strcmp (name, "ah_auth_alg") == 0)
- return ah_auth_alg;
-
- if (strcmp (name, "esp_auth_alg") == 0)
- return esp_auth_alg;
-
- if (strcmp (name, "esp_enc_alg") == 0)
- return esp_enc_alg;
-
- if (strcmp (name, "comp_alg") == 0)
- return comp_alg;
+ if (strcmp(name, "comp_life_seconds") == 0)
+ return comp_life_seconds;
- if (strcmp (name, "ah_life_kbytes") == 0)
- return ah_life_kbytes;
+ if (strcmp(name, "ah_encapsulation") == 0)
+ return ah_encapsulation;
- if (strcmp (name, "ah_life_seconds") == 0)
- return ah_life_seconds;
+ if (strcmp(name, "esp_encapsulation") == 0)
+ return esp_encapsulation;
- if (strcmp (name, "esp_life_kbytes") == 0)
- return esp_life_kbytes;
+ if (strcmp(name, "comp_encapsulation") == 0)
+ return comp_encapsulation;
- if (strcmp (name, "esp_life_seconds") == 0)
- return esp_life_seconds;
+ if (strcmp(name, "ah_key_length") == 0)
+ return ah_key_length;
- if (strcmp (name, "comp_life_kbytes") == 0)
- return comp_life_kbytes;
+ if (strcmp(name, "ah_key_rounds") == 0)
+ return ah_key_rounds;
- if (strcmp (name, "comp_life_seconds") == 0)
- return comp_life_seconds;
+ if (strcmp(name, "esp_key_length") == 0)
+ return esp_key_length;
- if (strcmp (name, "ah_encapsulation") == 0)
- return ah_encapsulation;
+ if (strcmp(name, "esp_key_rounds") == 0)
+ return esp_key_rounds;
- if (strcmp (name, "esp_encapsulation") == 0)
- return esp_encapsulation;
+ if (strcmp(name, "comp_dict_size") == 0)
+ return comp_dict_size;
- if (strcmp (name, "comp_encapsulation") == 0)
- return comp_encapsulation;
+ if (strcmp(name, "comp_private_alg") == 0)
+ return comp_private_alg;
- if (strcmp (name, "ah_key_length") == 0)
- return ah_key_length;
+ if (strcmp(name, "remote_filter_type") == 0)
+ return remote_filter_type;
- if (strcmp (name, "ah_key_rounds") == 0)
- return ah_key_rounds;
+ if (strcmp(name, "remote_filter") == 0)
+ return (remote_filter ? remote_filter : "");
- if (strcmp (name, "esp_key_length") == 0)
- return esp_key_length;
+ if (strcmp(name, "remote_filter_addr_upper") == 0)
+ return remote_filter_addr_upper;
- if (strcmp (name, "esp_key_rounds") == 0)
- return esp_key_rounds;
+ if (strcmp(name, "remote_filter_addr_lower") == 0)
+ return remote_filter_addr_lower;
- if (strcmp (name, "comp_dict_size") == 0)
- return comp_dict_size;
+ if (strcmp(name, "remote_filter_port") == 0)
+ return remote_filter_port;
- if (strcmp (name, "comp_private_alg") == 0)
- return comp_private_alg;
+ if (strcmp(name, "remote_filter_proto") == 0)
+ return remote_filter_proto;
- if (strcmp (name, "remote_filter_type") == 0)
- return remote_filter_type;
+ if (strcmp(name, "local_filter_type") == 0)
+ return local_filter_type;
- if (strcmp (name, "remote_filter") == 0)
- return (remote_filter ? remote_filter : "");
+ if (strcmp(name, "local_filter") == 0)
+ return (local_filter ? local_filter : "");
- if (strcmp (name, "remote_filter_addr_upper") == 0)
- return remote_filter_addr_upper;
+ if (strcmp(name, "local_filter_addr_upper") == 0)
+ return local_filter_addr_upper;
- if (strcmp (name, "remote_filter_addr_lower") == 0)
- return remote_filter_addr_lower;
+ if (strcmp(name, "local_filter_addr_lower") == 0)
+ return local_filter_addr_lower;
- if (strcmp (name, "remote_filter_port") == 0)
- return remote_filter_port;
+ if (strcmp(name, "local_filter_port") == 0)
+ return local_filter_port;
- if (strcmp (name, "remote_filter_proto") == 0)
- return remote_filter_proto;
+ if (strcmp(name, "local_filter_proto") == 0)
+ return local_filter_proto;
- if (strcmp (name, "local_filter_type") == 0)
- return local_filter_type;
+ if (strcmp(name, "remote_ike_address") == 0)
+ return remote_ike_address;
- if (strcmp (name, "local_filter") == 0)
- return (local_filter ? local_filter : "");
+ if (strcmp(name, "remote_negotiation_address") == 0)
+ return remote_ike_address;
- if (strcmp (name, "local_filter_addr_upper") == 0)
- return local_filter_addr_upper;
+ if (strcmp(name, "local_ike_address") == 0)
+ return local_ike_address;
- if (strcmp (name, "local_filter_addr_lower") == 0)
- return local_filter_addr_lower;
+ if (strcmp(name, "local_negotiation_address") == 0)
+ return local_ike_address;
- if (strcmp (name, "local_filter_port") == 0)
- return local_filter_port;
+ if (strcmp(name, "remote_id_type") == 0)
+ return remote_id_type;
- if (strcmp (name, "local_filter_proto") == 0)
- return local_filter_proto;
+ if (strcmp(name, "remote_id") == 0)
+ return (remote_id ? remote_id : "");
- if (strcmp (name, "remote_ike_address") == 0)
- return remote_ike_address;
+ if (strcmp(name, "remote_id_addr_upper") == 0)
+ return remote_id_addr_upper;
- if (strcmp (name, "remote_negotiation_address") == 0)
- return remote_ike_address;
+ if (strcmp(name, "remote_id_addr_lower") == 0)
+ return remote_id_addr_lower;
- if (strcmp (name, "local_ike_address") == 0)
- return local_ike_address;
+ if (strcmp(name, "remote_id_port") == 0)
+ return remote_id_port;
- if (strcmp (name, "local_negotiation_address") == 0)
- return local_ike_address;
+ if (strcmp(name, "remote_id_proto") == 0)
+ return remote_id_proto;
- if (strcmp (name, "remote_id_type") == 0)
- return remote_id_type;
+ if (strcmp(name, "phase1_group_desc") == 0)
+ return phase1_group;
- if (strcmp (name, "remote_id") == 0)
- return (remote_id ? remote_id : "");
+ if (strcmp(name, "esp_group_desc") == 0)
+ return esp_group_desc;
- if (strcmp (name, "remote_id_addr_upper") == 0)
- return remote_id_addr_upper;
+ if (strcmp(name, "ah_group_desc") == 0)
+ return ah_group_desc;
- if (strcmp (name, "remote_id_addr_lower") == 0)
- return remote_id_addr_lower;
+ if (strcmp(name, "comp_group_desc") == 0)
+ return comp_group_desc;
- if (strcmp (name, "remote_id_port") == 0)
- return remote_id_port;
+ if (strcmp(name, "comp_ecn") == 0)
+ return comp_ecn;
- if (strcmp (name, "remote_id_proto") == 0)
- return remote_id_proto;
+ if (strcmp(name, "ah_ecn") == 0)
+ return ah_ecn;
- if (strcmp (name, "phase1_group_desc") == 0)
- return phase1_group;
+ if (strcmp(name, "esp_ecn") == 0)
+ return esp_ecn;
- if (strcmp (name, "esp_group_desc") == 0)
- return esp_group_desc;
+ return "";
- if (strcmp (name, "ah_group_desc") == 0)
- return ah_group_desc;
+bad:
+ policy_callback(KEYNOTE_CALLBACK_INITIALIZE);
+ return "";
+}
- if (strcmp (name, "comp_group_desc") == 0)
- return comp_group_desc;
+void
+policy_init(void)
+{
+ char *ptr, *policy_file;
+ char **asserts;
+ size_t sz, len;
+ int fd, i;
+
+ LOG_DBG((LOG_POLICY, 30, "policy_init: initializing"));
+
+ /* Get policy file from configuration. */
+ policy_file = conf_get_str("General", "Policy-file");
+ if (!policy_file)
+ policy_file = CONF_DFLT_POLICY_FILE;
+
+ /* Check file modes and collect file size */
+ if (check_file_secrecy(policy_file, &sz))
+ log_fatal("policy_init: cannot read %s", policy_file);
+
+ /* Open policy file. */
+ fd = monitor_open(policy_file, O_RDONLY, 0);
+ if (fd == -1)
+ log_fatal("policy_init: open (\"%s\", O_RDONLY) failed", policy_file);
+
+ /* Allocate memory to keep policies. */
+ ptr = calloc(sz + 1, sizeof(char));
+ if (!ptr)
+ log_fatal("policy_init: calloc (%lu, %lu) failed", (unsigned long) sz + 1,
+ (unsigned long) sizeof(char));
+
+ /* Just in case there are short reads... */
+ for (len = 0; len < sz; len += i) {
+ i = read(fd, ptr + len, sz - len);
+ if (i == -1)
+ log_fatal("policy_init: read (%d, %p, %lu) failed", fd, ptr + len,
+ (unsigned long) (sz - len));
+ }
- if (strcmp (name, "comp_ecn") == 0)
- return comp_ecn;
+ /* We're done with this. */
+ close(fd);
- if (strcmp (name, "ah_ecn") == 0)
- return ah_ecn;
+ /* Parse buffer, break up into individual policies. */
+ asserts = kn_read_asserts(ptr, sz, &i);
- if (strcmp (name, "esp_ecn") == 0)
- return esp_ecn;
+ /* Begone! */
+ free(ptr);
- return "";
+ if (asserts == (char **) NULL)
+ log_print("policy_init: all policies flushed");
- bad:
- policy_callback (KEYNOTE_CALLBACK_INITIALIZE);
- return "";
-}
+ /* Cleanup */
+ if (keynote_policy_asserts) {
+ for (fd = 0; fd < keynote_policy_asserts_num; fd++)
+ if (keynote_policy_asserts && keynote_policy_asserts[fd])
+ free(keynote_policy_asserts[fd]);
-void
-policy_init (void)
-{
- char *ptr, *policy_file;
- char **asserts;
- size_t sz, len;
- int fd, i;
-
- LOG_DBG ((LOG_POLICY, 30, "policy_init: initializing"));
-
- /* Get policy file from configuration. */
- policy_file = conf_get_str ("General", "Policy-file");
- if (!policy_file)
- policy_file = CONF_DFLT_POLICY_FILE;
-
- /* Check file modes and collect file size */
- if (check_file_secrecy (policy_file, &sz))
- log_fatal ("policy_init: cannot read %s", policy_file);
-
- /* Open policy file. */
- fd = monitor_open (policy_file, O_RDONLY, 0);
- if (fd == -1)
- log_fatal ("policy_init: open (\"%s\", O_RDONLY) failed", policy_file);
-
- /* Allocate memory to keep policies. */
- ptr = calloc (sz + 1, sizeof (char));
- if (!ptr)
- log_fatal ("policy_init: calloc (%lu, %lu) failed", (unsigned long)sz + 1,
- (unsigned long)sizeof (char));
-
- /* Just in case there are short reads... */
- for (len = 0; len < sz; len += i)
- {
- i = read (fd, ptr + len, sz - len);
- if (i == -1)
- log_fatal ("policy_init: read (%d, %p, %lu) failed", fd, ptr + len,
- (unsigned long)(sz - len));
- }
-
- /* We're done with this. */
- close (fd);
-
- /* Parse buffer, break up into individual policies. */
- asserts = kn_read_asserts (ptr, sz, &i);
-
- /* Begone! */
- free (ptr);
-
- if (asserts == (char **) NULL)
- log_print ("policy_init: all policies flushed");
-
- /* Cleanup */
- if (keynote_policy_asserts)
- {
- for (fd = 0; fd < keynote_policy_asserts_num; fd++)
- if (keynote_policy_asserts && keynote_policy_asserts[fd])
- free (keynote_policy_asserts[fd]);
-
- free (keynote_policy_asserts);
- }
-
- keynote_policy_asserts = asserts;
- keynote_policy_asserts_num = i;
+ free(keynote_policy_asserts);
+ }
+ keynote_policy_asserts = asserts;
+ keynote_policy_asserts_num = i;
}
/* Nothing needed for initialization */
int
-keynote_cert_init (void)
+keynote_cert_init(void)
{
- return 1;
+ return 1;
}
/* Just copy and return. */
-void *
-keynote_cert_get (u_int8_t *data, u_int32_t len)
+void *
+keynote_cert_get(u_int8_t * data, u_int32_t len)
{
- char *foo = malloc (len + 1);
+ char *foo = malloc(len + 1);
- if (foo == NULL)
- return NULL;
+ if (foo == NULL)
+ return NULL;
- memcpy (foo, data, len);
- foo[len] = '\0';
- return foo;
+ memcpy(foo, data, len);
+ foo[len] = '\0';
+ return foo;
}
/*
@@ -1928,312 +1840,283 @@ keynote_cert_get (u_int8_t *data, u_int32_t len)
* On signature failure, just drop the whole payload.
*/
int
-keynote_cert_validate (void *scert)
+keynote_cert_validate(void *scert)
{
- char **foo;
- int num, i;
-
- if (scert == NULL)
- return 0;
-
- foo = kn_read_asserts ((char *) scert, strlen ((char *) scert), &num);
- if (foo == NULL)
- return 0;
-
- for (i = 0; i < num; i++)
- {
- if (kn_verify_assertion (scert, strlen ((char *) scert))
- != SIGRESULT_TRUE)
- {
- for (; i < num; i++)
- free (foo[i]);
- free (foo);
- return 0;
+ char **foo;
+ int num, i;
+
+ if (scert == NULL)
+ return 0;
+
+ foo = kn_read_asserts((char *) scert, strlen((char *) scert), &num);
+ if (foo == NULL)
+ return 0;
+
+ for (i = 0; i < num; i++) {
+ if (kn_verify_assertion(scert, strlen((char *) scert))
+ != SIGRESULT_TRUE) {
+ for (; i < num; i++)
+ free(foo[i]);
+ free(foo);
+ return 0;
+ }
+ free(foo[i]);
}
- free (foo[i]);
- }
-
- free (foo);
- return 1;
+ free(foo);
+ return 1;
}
/* Add received credentials. */
int
-keynote_cert_insert (int sid, void *scert)
+keynote_cert_insert(int sid, void *scert)
{
- char **foo;
- int num;
+ char **foo;
+ int num;
- if (scert == NULL)
- return 0;
+ if (scert == NULL)
+ return 0;
- foo = kn_read_asserts ((char *) scert, strlen ((char *) scert), &num);
- if (foo == NULL)
- return 0;
+ foo = kn_read_asserts((char *) scert, strlen((char *) scert), &num);
+ if (foo == NULL)
+ return 0;
- while (num--)
- kn_add_assertion (sid, foo[num], strlen (foo[num]), 0);
+ while (num--)
+ kn_add_assertion(sid, foo[num], strlen(foo[num]), 0);
- return 1;
+ return 1;
}
/* Just regular memory free. */
void
-keynote_cert_free (void *cert)
+keynote_cert_free(void *cert)
{
- free (cert);
+ free(cert);
}
/* Verify that the key given to us is valid. */
int
-keynote_certreq_validate (u_int8_t *data, u_int32_t len)
+keynote_certreq_validate(u_int8_t * data, u_int32_t len)
{
- struct keynote_deckey dc;
- int err = 1;
- char *dat;
-
- dat = calloc (len + 1, sizeof (char));
- if (!dat)
- {
- log_error ("keynote_certreq_validate: calloc (%d, %lu) failed", len + 1,
- (unsigned long)sizeof (char));
- return 0;
- }
-
- memcpy (dat, data, len);
+ struct keynote_deckey dc;
+ int err = 1;
+ char *dat;
+
+ dat = calloc(len + 1, sizeof(char));
+ if (!dat) {
+ log_error("keynote_certreq_validate: calloc (%d, %lu) failed", len + 1,
+ (unsigned long) sizeof(char));
+ return 0;
+ }
+ memcpy(dat, data, len);
- if (kn_decode_key (&dc, dat, KEYNOTE_PUBLIC_KEY) != 0)
- err = 0;
- else
- kn_free_key (&dc);
+ if (kn_decode_key(&dc, dat, KEYNOTE_PUBLIC_KEY) != 0)
+ err = 0;
+ else
+ kn_free_key(&dc);
- free (dat);
+ free(dat);
- return err;
+ return err;
}
/* Beats me what we should be doing with this. */
-void *
-keynote_certreq_decode (u_int8_t *data, u_int32_t len)
+void *
+keynote_certreq_decode(u_int8_t * data, u_int32_t len)
{
- /* XXX */
- return NULL;
+ /* XXX */
+ return NULL;
}
void
-keynote_free_aca (void *blob)
+keynote_free_aca(void *blob)
{
- /* XXX */
+ /* XXX */
}
int
-keynote_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
- u_int32_t *certlen)
+keynote_cert_obtain(u_int8_t * id, size_t id_len, void *data, u_int8_t ** cert,
+ u_int32_t * certlen)
{
- char *dirname, *file, *addr_str;
- struct stat sb;
- size_t size;
- int idtype, fd, len;
-
- if (!id)
- {
- log_print ("keynote_cert_obtain: ID is missing");
- return 0;
- }
-
- /* Get type of ID. */
- idtype = id[0];
- id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
- id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
-
- dirname = conf_get_str ("KeyNote", "Credential-directory");
- if (!dirname)
- {
- LOG_DBG ((LOG_POLICY, 30,
- "keynote_cert_obtain: no Credential-directory"));
- return 0;
- }
-
- len = strlen (dirname) + strlen (CREDENTIAL_FILE) + 3;
-
- switch (idtype)
- {
- case IPSEC_ID_IPV4_ADDR:
- case IPSEC_ID_IPV6_ADDR:
- util_ntoa (&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
- id);
- if (addr_str == 0)
- return 0;
+ char *dirname, *file, *addr_str;
+ struct stat sb;
+ size_t size;
+ int idtype, fd, len;
+
+ if (!id) {
+ log_print("keynote_cert_obtain: ID is missing");
+ return 0;
+ }
+ /* Get type of ID. */
+ idtype = id[0];
+ id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+
+ dirname = conf_get_str("KeyNote", "Credential-directory");
+ if (!dirname) {
+ LOG_DBG((LOG_POLICY, 30,
+ "keynote_cert_obtain: no Credential-directory"));
+ return 0;
+ }
+ len = strlen(dirname) + strlen(CREDENTIAL_FILE) + 3;
- file = calloc (len + strlen (addr_str), sizeof (char));
- if (file == NULL)
- {
- log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
- (unsigned long)len + strlen (addr_str));
- free (addr_str);
- return 0;
+ switch (idtype) {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa(&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
+ id);
+ if (addr_str == 0)
+ return 0;
+
+ file = calloc(len + strlen(addr_str), sizeof(char));
+ if (file == NULL) {
+ log_error("keynote_cert_obtain: failed to allocate %lu bytes",
+ (unsigned long) len + strlen(addr_str));
+ free(addr_str);
+ return 0;
+ }
+ snprintf(file, len + strlen(addr_str), "%s/%s/%s", dirname, addr_str,
+ CREDENTIAL_FILE);
+ free(addr_str);
+ break;
+
+ case IPSEC_ID_FQDN:
+ case IPSEC_ID_USER_FQDN:
+ {
+ file = calloc(len + id_len, sizeof(char));
+ if (file == NULL) {
+ log_error("keynote_cert_obtain: failed to allocate %lu bytes",
+ (unsigned long) len + id_len);
+ return 0;
+ }
+ snprintf(file, len + id_len, "%s/", dirname);
+ memcpy(file + strlen(dirname) + 1, id, id_len);
+ snprintf(file + strlen(dirname) + 1 + id_len,
+ len - strlen(dirname) - 1, "/%s", CREDENTIAL_FILE);
+ break;
+ }
+
+ default:
+ return 0;
}
- snprintf (file, len + strlen (addr_str), "%s/%s/%s", dirname, addr_str,
- CREDENTIAL_FILE);
- free (addr_str);
- break;
-
- case IPSEC_ID_FQDN:
- case IPSEC_ID_USER_FQDN:
- {
- file = calloc (len + id_len, sizeof (char));
- if (file == NULL)
- {
- log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
- (unsigned long)len + id_len);
- return 0;
- }
-
- snprintf (file, len + id_len, "%s/", dirname);
- memcpy (file + strlen (dirname) + 1, id, id_len);
- snprintf (file + strlen (dirname) + 1 + id_len,
- len - strlen (dirname) - 1, "/%s", CREDENTIAL_FILE);
- break;
- }
-
- default:
- return 0;
- }
-
- if (monitor_stat (file, &sb) < 0)
- {
- LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to stat \"%s\"",
- file));
- free (file);
- return 0;
- }
- size = (size_t)sb.st_size;
-
- *cert = calloc (size + 1, sizeof (char));
- if (*cert == NULL)
- {
- log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
- (unsigned long)size);
- free (file);
- return 0;
- }
-
- fd = monitor_open (file, O_RDONLY, 0);
- if (fd < 0)
- {
- LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to open \"%s\"",
- file));
- free (file);
- return 0;
- }
-
- if (read (fd, *cert, size) != (int)size)
- {
- LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to read %lu "
- "bytes from \"%s\"", (unsigned long)size, file));
- free (file);
- close (fd);
- return 0;
- }
-
- close (fd);
- free (file);
- *certlen = size;
- return 1;
+ if (monitor_stat(file, &sb) < 0) {
+ LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: failed to stat \"%s\"",
+ file));
+ free(file);
+ return 0;
+ }
+ size = (size_t) sb.st_size;
+
+ *cert = calloc(size + 1, sizeof(char));
+ if (*cert == NULL) {
+ log_error("keynote_cert_obtain: failed to allocate %lu bytes",
+ (unsigned long) size);
+ free(file);
+ return 0;
+ }
+ fd = monitor_open(file, O_RDONLY, 0);
+ if (fd < 0) {
+ LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: failed to open \"%s\"",
+ file));
+ free(file);
+ return 0;
+ }
+ if (read(fd, *cert, size) != (int) size) {
+ LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: failed to read %lu "
+ "bytes from \"%s\"", (unsigned long) size, file));
+ free(file);
+ close(fd);
+ return 0;
+ }
+ close(fd);
+ free(file);
+ *certlen = size;
+ return 1;
}
/* This should never be called. */
int
-keynote_cert_get_subjects (void *scert, int *n, u_int8_t ***id,
- u_int32_t **id_len)
+keynote_cert_get_subjects(void *scert, int *n, u_int8_t ***id,
+ u_int32_t **id_len)
{
- return 0;
+ return 0;
}
/* Get the authorizer key. */
int
-keynote_cert_get_key (void *scert, void *keyp)
+keynote_cert_get_key(void *scert, void *keyp)
{
- struct keynote_keylist *kl;
- int sid, kid, num;
- char **foo;
-
- foo = kn_read_asserts ((char *)scert, strlen ((char *)scert), &num);
- if (foo == NULL || num == 0)
- {
- log_print ("keynote_cert_get_key: failed to decompose credentials");
- return 0;
- }
-
- kid = kn_init ();
- if (kid == -1)
- {
- log_print ("keynote_cert_get_key: failed to initialize new policy "
- "session");
- while (num--)
- free (foo[num]);
- free (foo);
- return 0;
- }
-
- sid = kn_add_assertion (kid, foo[num - 1], strlen (foo[num - 1]), 0);
- while (num--)
- free (foo[num]);
- free (foo);
-
- if (sid == -1)
- {
- log_print ("keynote_cert_get_key: failed to add assertion");
- kn_close (kid);
- return 0;
- }
-
- *(RSA **)keyp = NULL;
-
- kl = kn_get_licensees (kid, sid);
- while (kl)
- {
- if (kl->key_alg == KEYNOTE_ALGORITHM_RSA)
- {
- *(RSA **)keyp = RSAPublicKey_dup (kl->key_key);
- break;
+ struct keynote_keylist *kl;
+ int sid, kid, num;
+ char **foo;
+
+ foo = kn_read_asserts((char *) scert, strlen((char *) scert), &num);
+ if (foo == NULL || num == 0) {
+ log_print("keynote_cert_get_key: failed to decompose credentials");
+ return 0;
}
+ kid = kn_init();
+ if (kid == -1) {
+ log_print("keynote_cert_get_key: failed to initialize new policy "
+ "session");
+ while (num--)
+ free(foo[num]);
+ free(foo);
+ return 0;
+ }
+ sid = kn_add_assertion(kid, foo[num - 1], strlen(foo[num - 1]), 0);
+ while (num--)
+ free(foo[num]);
+ free(foo);
+
+ if (sid == -1) {
+ log_print("keynote_cert_get_key: failed to add assertion");
+ kn_close(kid);
+ return 0;
+ }
+ *(RSA **) keyp = NULL;
- kl = kl->key_next;
- }
+ kl = kn_get_licensees(kid, sid);
+ while (kl) {
+ if (kl->key_alg == KEYNOTE_ALGORITHM_RSA) {
+ *(RSA **) keyp = RSAPublicKey_dup(kl->key_key);
+ break;
+ }
+ kl = kl->key_next;
+ }
- kn_remove_assertion (kid, sid);
- kn_close (kid);
- return *(RSA **)keyp == NULL ? 0 : 1;
+ kn_remove_assertion(kid, sid);
+ kn_close(kid);
+ return *(RSA **) keyp == NULL ? 0 : 1;
}
void *
-keynote_cert_dup (void *cert)
+keynote_cert_dup(void *cert)
{
- return strdup ((char *)cert);
+ return strdup((char *) cert);
}
void
-keynote_serialize (void *cert, u_int8_t **data, u_int32_t *datalen)
+keynote_serialize(void *cert, u_int8_t **data, u_int32_t *datalen)
{
- *datalen = strlen ((char *)cert) + 1;
- *data = (u_int8_t *)strdup (cert); /* i.e an extra character at the end... */
- if (*data == NULL)
- log_error ("keynote_serialize: malloc (%d) failed", *datalen);
+ *datalen = strlen((char *) cert) + 1;
+ *data = (u_int8_t *) strdup(cert); /* i.e an extra character at
+ * the end... */
+ if (*data == NULL)
+ log_error("keynote_serialize: malloc (%d) failed", *datalen);
}
/* From cert to printable */
char *
-keynote_printable (void *cert)
+keynote_printable(void *cert)
{
- return strdup ((char *)cert);
+ return strdup((char *) cert);
}
/* From printable to cert */
void *
-keynote_from_printable (char *cert)
+keynote_from_printable(char *cert)
{
- return strdup (cert);
+ return strdup(cert);
}
diff --git a/sbin/isakmpd/policy.h b/sbin/isakmpd/policy.h
index 8d9abbe3c46..4434f53c5bc 100644
--- a/sbin/isakmpd/policy.h
+++ b/sbin/isakmpd/policy.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: policy.h,v 1.12 2003/06/04 07:31:17 ho Exp $ */
-/* $EOM: policy.h,v 1.12 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: policy.h,v 1.13 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: policy.h,v 1.12 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1999, 2000 Angelos D. Keromytis. All rights reserved.
@@ -38,33 +38,35 @@
#define PRIVATE_KEY_FILE "private_key"
#endif
-extern int keynote_sessid;
-extern int keynote_policy_asserts_num;
-extern int x509_policy_asserts_num;
-extern int x509_policy_asserts_num_alloc;
-extern char **keynote_policy_asserts;
-extern char **x509_policy_asserts;
+extern int keynote_sessid;
+extern int keynote_policy_asserts_num;
+extern int x509_policy_asserts_num;
+extern int x509_policy_asserts_num_alloc;
+extern char **keynote_policy_asserts;
+extern char **x509_policy_asserts;
extern struct exchange *policy_exchange;
extern struct sa *policy_sa;
extern struct sa *policy_isakmp_sa;
-extern void policy_init (void);
-extern char *policy_callback (char *);
-extern int keynote_cert_init (void);
-extern void *keynote_cert_get (u_int8_t *, u_int32_t);
-extern int keynote_cert_validate (void *);
-extern int keynote_cert_insert (int, void *);
-extern void keynote_cert_free (void *);
-extern int keynote_certreq_validate (u_int8_t *, u_int32_t);
-extern void *keynote_certreq_decode (u_int8_t *, u_int32_t);
-extern void keynote_free_aca (void *);
-extern int keynote_cert_obtain (u_int8_t *, size_t, void *,
- u_int8_t **, u_int32_t *);
-extern int keynote_cert_get_subjects (void *, int *, u_int8_t ***,
- u_int32_t **);
-extern int keynote_cert_get_key (void *, void *);
-extern void *keynote_cert_dup (void *);
-extern void keynote_serialize (void *, u_int8_t **, u_int32_t *);
-extern char *keynote_printable (void *);
-extern void *keynote_from_printable (char *);
-#endif /* _POLICY_H_ */
+extern void policy_init(void);
+extern char *policy_callback(char *);
+extern int keynote_cert_init(void);
+extern void *keynote_cert_get(u_int8_t *, u_int32_t);
+extern int keynote_cert_validate(void *);
+extern int keynote_cert_insert(int, void *);
+extern void keynote_cert_free(void *);
+extern int keynote_certreq_validate(u_int8_t *, u_int32_t);
+extern void *keynote_certreq_decode(u_int8_t *, u_int32_t);
+extern void keynote_free_aca(void *);
+extern int
+keynote_cert_obtain(u_int8_t *, size_t, void *,
+ u_int8_t **, u_int32_t *);
+extern int
+keynote_cert_get_subjects(void *, int *, u_int8_t ***,
+ u_int32_t **);
+extern int keynote_cert_get_key(void *, void *);
+extern void *keynote_cert_dup(void *);
+extern void keynote_serialize(void *, u_int8_t **, u_int32_t *);
+extern char *keynote_printable(void *);
+extern void *keynote_from_printable(char *);
+#endif /* _POLICY_H_ */
diff --git a/sbin/isakmpd/prf.c b/sbin/isakmpd/prf.c
index 0c4a4c90781..c5d538a11b5 100644
--- a/sbin/isakmpd/prf.c
+++ b/sbin/isakmpd/prf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: prf.c,v 1.12 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: prf.c,v 1.7 1999/05/02 12:50:29 niklas Exp $ */
+/* $OpenBSD: prf.c,v 1.13 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: prf.c,v 1.7 1999/05/02 12:50:29 niklas Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -40,30 +40,30 @@
#include "log.h"
#include "prf.h"
-void prf_hash_init (struct prf_hash_ctx *);
-void prf_hash_update (struct prf_hash_ctx *, unsigned char *, unsigned int);
-void prf_hash_final (unsigned char *, struct prf_hash_ctx *);
+void prf_hash_init(struct prf_hash_ctx *);
+void prf_hash_update(struct prf_hash_ctx *, unsigned char *, unsigned int);
+void prf_hash_final(unsigned char *, struct prf_hash_ctx *);
/* PRF behaves likes a hash */
void
-prf_hash_init (struct prf_hash_ctx *ctx)
+prf_hash_init(struct prf_hash_ctx *ctx)
{
- memcpy (ctx->hash->ctx, ctx->ctx, ctx->hash->ctxsize);
- memcpy (ctx->hash->ctx2, ctx->ctx2, ctx->hash->ctxsize);
+ memcpy(ctx->hash->ctx, ctx->ctx, ctx->hash->ctxsize);
+ memcpy(ctx->hash->ctx2, ctx->ctx2, ctx->hash->ctxsize);
}
void
-prf_hash_update (struct prf_hash_ctx *ctx, unsigned char *data,
- unsigned int len)
+prf_hash_update(struct prf_hash_ctx *ctx, unsigned char *data,
+ unsigned int len)
{
- ctx->hash->Update (ctx->hash->ctx, data, len);
+ ctx->hash->Update(ctx->hash->ctx, data, len);
}
void
-prf_hash_final (unsigned char *digest, struct prf_hash_ctx *ctx)
+prf_hash_final(unsigned char *digest, struct prf_hash_ctx *ctx)
{
- ctx->hash->HMACFinal (digest, ctx->hash);
+ ctx->hash->HMACFinal(digest, ctx->hash);
}
/*
@@ -71,99 +71,89 @@ prf_hash_final (unsigned char *digest, struct prf_hash_ctx *ctx)
* the HMAC version of a hash. See RFC-2104 for reference.
*/
struct prf *
-prf_alloc (enum prfs type, int subtype, unsigned char *shared,
- unsigned int sharedsize)
+prf_alloc(enum prfs type, int subtype, unsigned char *shared,
+ unsigned int sharedsize)
{
- struct hash *hash;
- struct prf *prf;
- struct prf_hash_ctx *prfctx;
-
- switch (type)
- {
- case PRF_HMAC:
- hash = hash_get (subtype);
- if (!hash)
- {
- log_print ("prf_alloc: unknown hash type %d", subtype);
- return 0;
+ struct hash *hash;
+ struct prf *prf;
+ struct prf_hash_ctx *prfctx;
+
+ switch (type) {
+ case PRF_HMAC:
+ hash = hash_get(subtype);
+ if (!hash) {
+ log_print("prf_alloc: unknown hash type %d", subtype);
+ return 0;
+ }
+ break;
+ default:
+ log_print("prf_alloc: unknown PRF type %d", type);
+ return 0;
}
- break;
- default:
- log_print ("prf_alloc: unknown PRF type %d", type);
- return 0;
- }
-
- prf = malloc (sizeof *prf);
- if (!prf)
- {
- log_error ("prf_alloc: malloc (%lu) failed", (unsigned long)sizeof *prf);
- return 0;
- }
-
- if (type == PRF_HMAC)
- {
- /* Obtain needed memory. */
- prfctx = malloc (sizeof *prfctx);
- if (!prfctx)
- {
- log_error ("prf_alloc: malloc (%lu) failed",
- (unsigned long)sizeof *prfctx);
- goto cleanprf;
- }
- prf->prfctx = prfctx;
- prfctx->ctx = malloc (hash->ctxsize);
- if (!prfctx->ctx)
- {
- log_error ("prf_alloc: malloc (%d) failed", hash->ctxsize);
- goto cleanprfctx;
+ prf = malloc(sizeof *prf);
+ if (!prf) {
+ log_error("prf_alloc: malloc (%lu) failed",
+ (unsigned long) sizeof *prf);
+ return 0;
}
-
- prfctx->ctx2 = malloc (hash->ctxsize);
- if (!prfctx->ctx2)
- {
- log_error ("prf_alloc: malloc (%d) failed", hash->ctxsize);
- free (prfctx->ctx);
- goto cleanprfctx;
+ if (type == PRF_HMAC) {
+ /* Obtain needed memory. */
+ prfctx = malloc(sizeof *prfctx);
+ if (!prfctx) {
+ log_error("prf_alloc: malloc (%lu) failed",
+ (unsigned long) sizeof *prfctx);
+ goto cleanprf;
+ }
+ prf->prfctx = prfctx;
+
+ prfctx->ctx = malloc(hash->ctxsize);
+ if (!prfctx->ctx) {
+ log_error("prf_alloc: malloc (%d) failed", hash->ctxsize);
+ goto cleanprfctx;
+ }
+ prfctx->ctx2 = malloc(hash->ctxsize);
+ if (!prfctx->ctx2) {
+ log_error("prf_alloc: malloc (%d) failed", hash->ctxsize);
+ free(prfctx->ctx);
+ goto cleanprfctx;
+ }
+ prf->type = PRF_HMAC;
+ prf->blocksize = hash->hashsize;
+ prfctx->hash = hash;
+
+ /* Use the correct function pointers. */
+ prf->Init = (void (*) (void *)) prf_hash_init;
+ prf->Update = (void (*) (void *, unsigned char *,
+ unsigned int)) prf_hash_update;
+ prf->Final = (void (*) (unsigned char *, void *)) prf_hash_final;
+
+ /* Init HMAC contexts. */
+ hash->HMACInit(hash, shared, sharedsize);
+
+ /* Save contexts. */
+ memcpy(prfctx->ctx, hash->ctx, hash->ctxsize);
+ memcpy(prfctx->ctx2, hash->ctx2, hash->ctxsize);
}
- prf->type = PRF_HMAC;
- prf->blocksize = hash->hashsize;
- prfctx->hash = hash;
-
- /* Use the correct function pointers. */
- prf->Init = (void (*) (void *))prf_hash_init;
- prf->Update
- = (void (*) (void *, unsigned char *, unsigned int))prf_hash_update;
- prf->Final = (void (*) (unsigned char *, void *))prf_hash_final;
-
- /* Init HMAC contexts. */
- hash->HMACInit (hash, shared, sharedsize);
-
- /* Save contexts. */
- memcpy (prfctx->ctx, hash->ctx, hash->ctxsize);
- memcpy (prfctx->ctx2, hash->ctx2, hash->ctxsize);
- }
-
- return prf;
-
- cleanprfctx:
- free (prf->prfctx);
- cleanprf:
- free (prf);
- return 0;
+ return prf;
+
+cleanprfctx:
+ free(prf->prfctx);
+cleanprf:
+ free(prf);
+ return 0;
}
/* Deallocate the PRF pointed to by PRF. */
void
-prf_free (struct prf *prf)
+prf_free(struct prf *prf)
{
- struct prf_hash_ctx *prfctx = prf->prfctx;
-
- if (prf->type == PRF_HMAC)
- {
- free (prfctx->ctx2);
- free (prfctx->ctx);
- }
- free (prf->prfctx);
- free (prf);
+ struct prf_hash_ctx *prfctx = prf->prfctx;
+
+ if (prf->type == PRF_HMAC) {
+ free(prfctx->ctx2);
+ free(prfctx->ctx);
+ }
+ free(prf->prfctx);
+ free(prf);
}
diff --git a/sbin/isakmpd/prf.h b/sbin/isakmpd/prf.h
index e2838f866f4..08a6fb3589c 100644
--- a/sbin/isakmpd/prf.h
+++ b/sbin/isakmpd/prf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: prf.h,v 1.9 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: prf.h,v 1.1 1998/07/11 20:06:22 provos Exp $ */
+/* $OpenBSD: prf.h,v 1.10 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: prf.h,v 1.1 1998/07/11 20:06:22 provos Exp $ */
/*
* Copyright (c) 1998 Niels Provos. All rights reserved.
@@ -35,24 +35,24 @@
/* Enumeration of possible PRF - Pseudo-Random Functions. */
enum prfs {
- PRF_HMAC = 0 /* No PRFs in drafts, this is the default */
+ PRF_HMAC = 0 /* No PRFs in drafts, this is the default */
};
struct prf {
- enum prfs type; /* Type of PRF */
- void *prfctx; /* Context for PRF */
- u_int8_t blocksize; /* The blocksize of PRF */
- void (*Init) (void *);
- void (*Update) (void *, unsigned char *, unsigned int);
- void (*Final) (unsigned char *, void *);
+ enum prfs type; /* Type of PRF */
+ void *prfctx; /* Context for PRF */
+ u_int8_t blocksize; /* The blocksize of PRF */
+ void (*Init) (void *);
+ void (*Update) (void *, unsigned char *, unsigned int);
+ void (*Final) (unsigned char *, void *);
};
struct prf_hash_ctx {
- struct hash *hash; /* Hash type to use */
- void *ctx, *ctx2; /* Contexts we need for later */
+ struct hash *hash; /* Hash type to use */
+ void *ctx, *ctx2; /* Contexts we need for later */
};
-struct prf *prf_alloc (enum prfs, int, unsigned char *, unsigned int);
-void prf_free (struct prf *);
+struct prf *prf_alloc(enum prfs, int, unsigned char *, unsigned int);
+void prf_free(struct prf *);
-#endif /* _PRF_H_ */
+#endif /* _PRF_H_ */
diff --git a/sbin/isakmpd/sa.c b/sbin/isakmpd/sa.c
index 35a11c6cbd7..fa00096d5ed 100644
--- a/sbin/isakmpd/sa.c
+++ b/sbin/isakmpd/sa.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: sa.c,v 1.79 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */
+/* $OpenBSD: sa.c,v 1.80 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -38,7 +38,7 @@
#if defined (USE_KEYNOTE) || defined (USE_POLICY)
#include <regex.h>
#include <keynote.h>
-#endif /* USE_KEYNOTE || USE_POLICY */
+#endif /* USE_KEYNOTE || USE_POLICY */
#include "sysdep.h"
@@ -73,121 +73,116 @@
#define MAX_BUCKET_BITS 16
#if 0
-static void sa_resize (void);
+static void sa_resize(void);
#endif
-static void sa_soft_expire (void *);
-static void sa_hard_expire (void *);
+static void sa_soft_expire(void *);
+static void sa_hard_expire(void *);
-static LIST_HEAD (sa_list, sa) *sa_tab;
+static LIST_HEAD(sa_list, sa) *sa_tab;
/* Works both as a maximum index and a mask. */
-static int bucket_mask;
+static int bucket_mask;
void
-sa_init (void)
+sa_init(void)
{
- int i;
-
- bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
- sa_tab = malloc ((bucket_mask + 1) * sizeof (struct sa_list));
- if (!sa_tab)
- log_fatal ("sa_init: malloc (%lu) failed",
- (bucket_mask + 1) * (unsigned long)sizeof (struct sa_list));
- for (i = 0; i <= bucket_mask; i++)
- {
- LIST_INIT (&sa_tab[i]);
- }
+ int i;
+
+ bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
+ sa_tab = malloc((bucket_mask + 1) * sizeof(struct sa_list));
+ if (!sa_tab)
+ log_fatal("sa_init: malloc (%lu) failed",
+ (bucket_mask + 1) * (unsigned long) sizeof(struct sa_list));
+ for (i = 0; i <= bucket_mask; i++) {
+ LIST_INIT(&sa_tab[i]);
+ }
}
#if 0
/* XXX We don't yet resize. */
static void
-sa_resize (void)
+sa_resize(void)
{
- int new_mask = (bucket_mask + 1) * 2 - 1;
- int i;
- struct sa_list *new_tab;
-
- new_tab = realloc (sa_tab, (new_mask + 1) * sizeof (struct sa_list));
- if (!new_tab)
- return;
- sa_tab = new_tab;
- for (i = bucket_mask + 1; i <= new_mask; i++)
- {
- LIST_INIT (&sa_tab[i]);
- }
- bucket_mask = new_mask;
-
- /* XXX Rehash existing entries. */
+ int new_mask = (bucket_mask + 1) * 2 - 1;
+ int i;
+ struct sa_list *new_tab;
+
+ new_tab = realloc(sa_tab, (new_mask + 1) * sizeof(struct sa_list));
+ if (!new_tab)
+ return;
+ sa_tab = new_tab;
+ for (i = bucket_mask + 1; i <= new_mask; i++) {
+ LIST_INIT(&sa_tab[i]);
+ }
+ bucket_mask = new_mask;
+
+ /* XXX Rehash existing entries. */
}
#endif
/* Lookup an SA with the help from a user-supplied checking function. */
struct sa *
-sa_find (int (*check) (struct sa *, void *), void *arg)
+sa_find(int (*check) (struct sa*, void *), void *arg)
{
- int i;
- struct sa *sa;
-
- for (i = 0; i <= bucket_mask; i++)
- for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link))
- if (check (sa, arg))
- {
- LOG_DBG ((LOG_SA, 90, "sa_find: return SA %p", sa));
- return sa;
- }
- LOG_DBG ((LOG_SA, 90, "sa_find: no SA matched query"));
- return 0;
+ int i;
+ struct sa *sa;
+
+ for (i = 0; i <= bucket_mask; i++)
+ for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
+ if (check(sa, arg)) {
+ LOG_DBG((LOG_SA, 90, "sa_find: return SA %p", sa));
+ return sa;
+ }
+ LOG_DBG((LOG_SA, 90, "sa_find: no SA matched query"));
+ return 0;
}
/* Check if SA is an ISAKMP SA with an initiator cookie equal to ICOOKIE. */
static int
-sa_check_icookie (struct sa *sa, void *icookie)
+sa_check_icookie(struct sa *sa, void *icookie)
{
- return sa->phase == 1
- && memcmp (sa->cookies, icookie, ISAKMP_HDR_ICOOKIE_LEN) == 0;
+ return sa->phase == 1
+ && memcmp(sa->cookies, icookie, ISAKMP_HDR_ICOOKIE_LEN) == 0;
}
/* Lookup an ISAKMP SA out of just the initiator cookie. */
-struct sa *
-sa_lookup_from_icookie (u_int8_t *cookie)
+struct sa *
+sa_lookup_from_icookie(u_int8_t *cookie)
{
- return sa_find (sa_check_icookie, cookie);
+ return sa_find(sa_check_icookie, cookie);
}
struct name_phase_arg {
- char *name;
- u_int8_t phase;
+ char *name;
+ u_int8_t phase;
};
/* Check if SA has the name and phase given by V_ARG. */
static int
-sa_check_name_phase (struct sa *sa, void *v_arg)
+sa_check_name_phase(struct sa *sa, void *v_arg)
{
- struct name_phase_arg *arg = v_arg;
+ struct name_phase_arg *arg = v_arg;
- return sa->name && strcasecmp (sa->name, arg->name) == 0 &&
- sa->phase == arg->phase && !(sa->flags & SA_FLAG_REPLACED);
+ return sa->name && strcasecmp(sa->name, arg->name) == 0 &&
+ sa->phase == arg->phase && !(sa->flags & SA_FLAG_REPLACED);
}
/* Lookup an SA by name, case-independent, and phase. */
struct sa *
-sa_lookup_by_name (char *name, int phase)
+sa_lookup_by_name(char *name, int phase)
{
- struct name_phase_arg arg;
+ struct name_phase_arg arg;
- arg.name = name;
- arg.phase = phase;
-
- return sa_find (sa_check_name_phase, &arg);
+ arg.name = name;
+ arg.phase = phase;
+ return sa_find(sa_check_name_phase, &arg);
}
-struct addr_arg
-{
- struct sockaddr *addr;
- socklen_t len;
- int phase;
- int flags;
+struct addr_arg {
+ struct sockaddr *addr;
+ socklen_t len;
+ int phase;
+ int flags;
};
/*
@@ -196,23 +191,23 @@ struct addr_arg
* that too.
*/
static int
-sa_check_peer (struct sa *sa, void *v_addr)
+sa_check_peer(struct sa *sa, void *v_addr)
{
- struct addr_arg *addr = v_addr;
- struct sockaddr *dst;
+ struct addr_arg *addr = v_addr;
+ struct sockaddr *dst;
- if (!sa->transport || (sa->flags & SA_FLAG_READY) == 0
- || (addr->phase && addr->phase != sa->phase))
- return 0;
+ if (!sa->transport || (sa->flags & SA_FLAG_READY) == 0 ||
+ (addr->phase && addr->phase != sa->phase))
+ return 0;
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- return sysdep_sa_len (dst) == addr->len
- && memcmp (dst, addr->addr, sysdep_sa_len (dst)) == 0;
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ return sysdep_sa_len(dst) == addr->len &&
+ memcmp(dst, addr->addr, sysdep_sa_len(dst)) == 0;
}
struct dst_isakmpspi_arg {
- struct sockaddr *dst;
- u_int8_t *spi; /* must be ISAKMP_SPI_SIZE octets */
+ struct sockaddr *dst;
+ u_int8_t *spi; /* must be ISAKMP_SPI_SIZE octets */
};
/*
@@ -220,105 +215,103 @@ struct dst_isakmpspi_arg {
* be a finished phaes 1 (ISAKMP) SA.
*/
static int
-isakmp_sa_check (struct sa *sa, void *v_arg)
+isakmp_sa_check(struct sa * sa, void *v_arg)
{
- struct dst_isakmpspi_arg *arg = v_arg;
- struct sockaddr *dst, *src;
+ struct dst_isakmpspi_arg *arg = v_arg;
+ struct sockaddr *dst, *src;
- if (sa->phase != 1 || !(sa->flags & SA_FLAG_READY))
- return 0;
+ if (sa->phase != 1 || !(sa->flags & SA_FLAG_READY))
+ return 0;
- /* verify address is either src or dst for this sa */
- sa->transport->vtbl->get_dst (sa->transport, &dst);
- sa->transport->vtbl->get_src (sa->transport, &src);
- if (memcmp (src, arg->dst, sysdep_sa_len (src)) &&
- memcmp (dst, arg->dst, sysdep_sa_len (dst)))
- return 0;
+ /* verify address is either src or dst for this sa */
+ sa->transport->vtbl->get_dst(sa->transport, &dst);
+ sa->transport->vtbl->get_src(sa->transport, &src);
+ if (memcmp(src, arg->dst, sysdep_sa_len(src)) &&
+ memcmp(dst, arg->dst, sysdep_sa_len(dst)))
+ return 0;
- /* match icookie+rcookie against spi */
- if (memcmp (sa->cookies, arg->spi, ISAKMP_HDR_COOKIES_LEN) == 0)
- return 1;
+ /* match icookie+rcookie against spi */
+ if (memcmp(sa->cookies, arg->spi, ISAKMP_HDR_COOKIES_LEN) == 0)
+ return 1;
- return 0;
+ return 0;
}
/*
* Find an ISAKMP SA with a "name" of DST & SPI.
*/
struct sa *
-sa_lookup_isakmp_sa (struct sockaddr *dst, u_int8_t *spi)
+sa_lookup_isakmp_sa(struct sockaddr * dst, u_int8_t * spi)
{
- struct dst_isakmpspi_arg arg;
+ struct dst_isakmpspi_arg arg;
- arg.dst = dst;
- arg.spi = spi;
+ arg.dst = dst;
+ arg.spi = spi;
- return sa_find (isakmp_sa_check, &arg);
+ return sa_find(isakmp_sa_check, &arg);
}
/* Lookup a ready SA by the peer's address. */
struct sa *
-sa_lookup_by_peer (struct sockaddr *dst, socklen_t dstlen)
+sa_lookup_by_peer(struct sockaddr * dst, socklen_t dstlen)
{
- struct addr_arg arg;
+ struct addr_arg arg;
- arg.addr = dst;
- arg.len = dstlen;
- arg.phase = 0;
+ arg.addr = dst;
+ arg.len = dstlen;
+ arg.phase = 0;
- return sa_find (sa_check_peer, &arg);
+ return sa_find(sa_check_peer, &arg);
}
/* Lookup a ready ISAKMP SA given its peer address. */
struct sa *
-sa_isakmp_lookup_by_peer (struct sockaddr *dst, socklen_t dstlen)
+sa_isakmp_lookup_by_peer(struct sockaddr * dst, socklen_t dstlen)
{
- struct addr_arg arg;
+ struct addr_arg arg;
- arg.addr = dst;
- arg.len = dstlen;
- arg.phase = 1;
+ arg.addr = dst;
+ arg.len = dstlen;
+ arg.phase = 1;
- return sa_find (sa_check_peer, &arg);
+ return sa_find(sa_check_peer, &arg);
}
int
-sa_enter (struct sa *sa)
+sa_enter(struct sa *sa)
{
- u_int16_t bucket = 0;
- int i;
- u_int8_t *cp;
-
- /* XXX We might resize if we are crossing a certain threshold */
-
- for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2)
- {
- cp = sa->cookies + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2)
- {
- cp = sa->message_id + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- bucket &= bucket_mask;
- LIST_INSERT_HEAD (&sa_tab[bucket], sa, link);
- sa_reference (sa);
- LOG_DBG ((LOG_SA, 70, "sa_enter: SA %p added to SA list", sa));
- return 1;
+ u_int16_t bucket = 0;
+ int i;
+ u_int8_t *cp;
+
+ /* XXX We might resize if we are crossing a certain threshold */
+
+ for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
+ cp = sa->cookies + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
+ cp = sa->message_id + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ bucket &= bucket_mask;
+ LIST_INSERT_HEAD(&sa_tab[bucket], sa, link);
+ sa_reference(sa);
+ LOG_DBG((LOG_SA, 70, "sa_enter: SA %p added to SA list", sa));
+ return 1;
}
/*
* Lookup the SA given by the header fields MSG. PHASE2 is false when
* looking for phase 1 SAa and true otherwise.
*/
-struct sa *
-sa_lookup_by_header (u_int8_t *msg, int phase2)
+struct sa *
+sa_lookup_by_header(u_int8_t * msg, int phase2)
{
- return sa_lookup (msg + ISAKMP_HDR_COOKIES_OFF,
- phase2 ? msg + ISAKMP_HDR_MESSAGE_ID_OFF : 0);
+ return sa_lookup(msg + ISAKMP_HDR_COOKIES_OFF,
+ phase2 ? msg + ISAKMP_HDR_MESSAGE_ID_OFF : 0);
}
/*
@@ -326,97 +319,92 @@ sa_lookup_by_header (u_int8_t *msg, int phase2)
* a null pointer, meaning we are looking for phase 1 SAs.
*/
struct sa *
-sa_lookup (u_int8_t *cookies, u_int8_t *message_id)
+sa_lookup(u_int8_t *cookies, u_int8_t *message_id)
{
- u_int16_t bucket = 0;
- int i;
- struct sa *sa;
- u_int8_t *cp;
-
- /*
- * We use the cookies to get bits to use as an index into sa_tab, as at
- * least one (our cookie) is a good hash, xoring all the bits, 16 at a
- * time, and then masking, should do. Doing it this way means we can
- * validate cookies very fast thus delimiting the effects of "Denial of
- * service"-attacks using packet flooding.
- */
- for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2)
- {
- cp = cookies + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- if (message_id)
- for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2)
- {
- cp = message_id + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- bucket &= bucket_mask;
- for (sa = LIST_FIRST (&sa_tab[bucket]);
- sa && (memcmp (cookies, sa->cookies, ISAKMP_HDR_COOKIES_LEN) != 0
- || (message_id && memcmp (message_id, sa->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN)
- != 0)
- || (!message_id && !zero_test (sa->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN)));
- sa = LIST_NEXT (sa, link))
- ;
-
- return sa;
+ u_int16_t bucket = 0;
+ int i;
+ struct sa *sa;
+ u_int8_t *cp;
+
+ /*
+ * We use the cookies to get bits to use as an index into sa_tab, as at
+ * least one (our cookie) is a good hash, xoring all the bits, 16 at a
+ * time, and then masking, should do. Doing it this way means we can
+ * validate cookies very fast thus delimiting the effects of "Denial of
+ * service"-attacks using packet flooding.
+ */
+ for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
+ cp = cookies + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ if (message_id)
+ for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
+ cp = message_id + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ bucket &= bucket_mask;
+ for (sa = LIST_FIRST(&sa_tab[bucket]);
+ sa && (memcmp(cookies, sa->cookies, ISAKMP_HDR_COOKIES_LEN) != 0 ||
+ (message_id && memcmp(message_id, sa->message_id,
+ ISAKMP_HDR_MESSAGE_ID_LEN) != 0) ||
+ (!message_id && !zero_test(sa->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)));
+ sa = LIST_NEXT(sa, link))
+ ;
+
+ return sa;
}
/* Create an SA. */
int
-sa_create (struct exchange *exchange, struct transport *t)
+sa_create(struct exchange * exchange, struct transport * t)
{
- struct sa *sa;
-
- /*
- * We want the SA zeroed for sa_free to be able to find out what fields
- * have been filled-in.
- */
- sa = calloc (1, sizeof *sa);
- if (!sa)
- {
- log_error ("sa_create: calloc (1, %lu) failed",
- (unsigned long)sizeof *sa);
- return -1;
- }
- sa->transport = t;
- if (t)
- transport_reference (t);
- sa->phase = exchange->phase;
- memcpy (sa->cookies, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
- memcpy (sa->message_id, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- sa->doi = exchange->doi;
- sa->policy_id = -1;
-
- if (sa->doi->sa_size)
- {
- /* Allocate the DOI-specific structure and initialize it to zeroes. */
- sa->data = calloc (1, sa->doi->sa_size);
- if (!sa->data)
- {
- log_error ("sa_create: calloc (1, %lu) failed",
- (unsigned long)sa->doi->sa_size);
- free (sa);
- return -1;
+ struct sa *sa;
+
+ /*
+ * We want the SA zeroed for sa_free to be able to find out what fields
+ * have been filled-in.
+ */
+ sa = calloc(1, sizeof *sa);
+ if (!sa) {
+ log_error("sa_create: calloc (1, %lu) failed",
+ (unsigned long) sizeof *sa);
+ return -1;
}
- }
-
- TAILQ_INIT (&sa->protos);
+ sa->transport = t;
+ if (t)
+ transport_reference(t);
+ sa->phase = exchange->phase;
+ memcpy(sa->cookies, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
+ memcpy(sa->message_id, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ sa->doi = exchange->doi;
+ sa->policy_id = -1;
+
+ if (sa->doi->sa_size) {
+ /*
+ * Allocate the DOI-specific structure and initialize it to
+ * zeroes.
+ */
+ sa->data = calloc(1, sa->doi->sa_size);
+ if (!sa->data) {
+ log_error("sa_create: calloc (1, %lu) failed",
+ (unsigned long) sa->doi->sa_size);
+ free(sa);
+ return -1;
+ }
+ }
+ TAILQ_INIT(&sa->protos);
- sa_enter (sa);
- TAILQ_INSERT_TAIL (&exchange->sa_list, sa, next);
- sa_reference (sa);
+ sa_enter(sa);
+ TAILQ_INSERT_TAIL(&exchange->sa_list, sa, next);
+ sa_reference(sa);
- LOG_DBG ((LOG_SA, 60,
+ LOG_DBG((LOG_SA, 60,
"sa_create: sa %p phase %d added to exchange %p (%s)", sa,
sa->phase, exchange,
exchange->name ? exchange->name : "<unnamed>"));
- return 0;
+ return 0;
}
/*
@@ -424,80 +412,74 @@ sa_create (struct exchange *exchange, struct transport *t)
* prepended to each line.
*/
void
-sa_dump (int cls, int level, char *header, struct sa *sa)
+sa_dump(int cls, int level, char *header, struct sa * sa)
{
- struct proto *proto;
- char spi_header[80];
- int i;
+ struct proto *proto;
+ char spi_header[80];
+ int i;
- LOG_DBG ((cls, level, "%s: %p %s phase %d doi %d flags 0x%x", header, sa,
+ LOG_DBG((cls, level, "%s: %p %s phase %d doi %d flags 0x%x", header, sa,
sa->name ? sa->name : "<unnamed>", sa->phase, sa->doi->id,
sa->flags));
- LOG_DBG ((cls, level, "%s: icookie %08x%08x rcookie %08x%08x", header,
- decode_32 (sa->cookies), decode_32 (sa->cookies + 4),
- decode_32 (sa->cookies + 8), decode_32 (sa->cookies + 12)));
- LOG_DBG ((cls, level, "%s: msgid %08x refcnt %d", header,
- decode_32 (sa->message_id), sa->refcnt));
- LOG_DBG ((cls, level, "%s: life secs %llu kb %llu", header, sa->seconds,
+ LOG_DBG((cls, level, "%s: icookie %08x%08x rcookie %08x%08x", header,
+ decode_32(sa->cookies), decode_32(sa->cookies + 4),
+ decode_32(sa->cookies + 8), decode_32(sa->cookies + 12)));
+ LOG_DBG((cls, level, "%s: msgid %08x refcnt %d", header,
+ decode_32(sa->message_id), sa->refcnt));
+ LOG_DBG((cls, level, "%s: life secs %llu kb %llu", header, sa->seconds,
sa->kilobytes));
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- LOG_DBG ((cls, level, "%s: suite %d proto %d", header, proto->no,
- proto->proto));
- LOG_DBG ((cls, level,
- "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p", header,
- proto->spi_sz[0], proto->spi[0], proto->spi_sz[1],
- proto->spi[1]));
- LOG_DBG ((cls, level, "%s: %s, %s", header,
- !sa->doi ? "<nodoi>"
- : sa->doi->decode_ids ("initiator id: %s, responder id: %s",
- sa->id_i, sa->id_i_len,
- sa->id_r, sa->id_r_len, 0),
- !sa->transport ? "<no transport>" :
- sa->transport->vtbl->decode_ids (sa->transport)));
- for (i = 0; i < 2; i++)
- if (proto->spi[i])
- {
- snprintf (spi_header, sizeof spi_header, "%s: spi[%d]", header, i);
- LOG_DBG_BUF ((cls, level, spi_header, proto->spi[i],
- proto->spi_sz[i]));
- }
- }
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ LOG_DBG((cls, level, "%s: suite %d proto %d", header, proto->no,
+ proto->proto));
+ LOG_DBG((cls, level,
+ "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p", header,
+ proto->spi_sz[0], proto->spi[0], proto->spi_sz[1],
+ proto->spi[1]));
+ LOG_DBG((cls, level, "%s: %s, %s", header,
+ !sa->doi ? "<nodoi>" :
+ sa->doi->decode_ids("initiator id: %s, responder id: %s",
+ sa->id_i, sa->id_i_len,
+ sa->id_r, sa->id_r_len, 0),
+ !sa->transport ? "<no transport>" :
+ sa->transport->vtbl->decode_ids(sa->transport)));
+ for (i = 0; i < 2; i++)
+ if (proto->spi[i]) {
+ snprintf(spi_header, sizeof spi_header,
+ "%s: spi[%d]", header, i);
+ LOG_DBG_BUF((cls, level, spi_header, proto->spi[i],
+ proto->spi_sz[i]));
+ }
+ }
}
/*
* Display the SA's two SPI values.
*/
static void
-report_spi (FILE *fd, const u_int8_t *buf, size_t sz, int spi)
+report_spi(FILE *fd, const u_int8_t *buf, size_t sz, int spi)
{
#define SBUFSZ (2 * 32 + 9)
- char s[SBUFSZ];
- size_t i, j;
-
- for (i = j = 0; i < sz;)
- {
- snprintf (s + j, sizeof s - j, "%02x", buf[i++]);
- j += 2;
- if (i % 4 == 0)
- {
- if (i % 32 == 0)
- {
- s[j] = '\0';
- fprintf (fd, "%s", s);
- j = 0;
- }
- else
- s[j++] = ' ';
+ char s[SBUFSZ];
+ size_t i, j;
+
+ for (i = j = 0; i < sz;) {
+ snprintf(s + j, sizeof s - j, "%02x", buf[i++]);
+ j += 2;
+ if (i % 4 == 0) {
+ if (i % 32 == 0) {
+ s[j] = '\0';
+ fprintf(fd, "%s", s);
+ j = 0;
+ } else
+ s[j++] = ' ';
+ }
}
- }
- if (j)
- {
- s[j] = '\0';
- fprintf (fd, "SPI %d: %s\n", spi, s);
- }
+ if (j) {
+ s[j] = '\0';
+ fprintf(fd, "SPI %d: %s\n", spi, s);
+ }
}
@@ -507,144 +489,140 @@ report_spi (FILE *fd, const u_int8_t *buf, size_t sz, int spi)
* Transform names are taken from /usr/src/sys/crypto/xform.c.
*/
static void
-report_proto (FILE *fd, struct proto *proto)
+report_proto(FILE * fd, struct proto * proto)
{
- int keylen, hashlen;
- struct ipsec_proto *iproto = proto->data;
-
- switch (proto->proto)
- {
- case IPSEC_PROTO_IPSEC_ESP:
- keylen = ipsec_esp_enckeylength (proto);
- hashlen = ipsec_esp_authkeylength (proto);
- fprintf (fd, "Transform: IPsec ESP\n");
- fprintf (fd, "Encryption key length: %d\n", keylen);
- fprintf (fd, "Authentication key length: %d\n", hashlen);
-
- fprintf (fd, "Encryption algorithm: ");
- switch (proto->id)
- {
- case IPSEC_ESP_DES:
- case IPSEC_ESP_DES_IV32:
- case IPSEC_ESP_DES_IV64:
- fprintf (fd, "DES\n");
- break;
-
- case IPSEC_ESP_3DES:
- fprintf (fd, "3DES\n");
- break;
-
- case IPSEC_ESP_AES:
- fprintf (fd, "AES-128 (CBC)\n");
- break;
-
- case IPSEC_ESP_AES_128_CTR:
- fprintf (fd, "AES-128 (CTR)\n");
- break;
-
- case IPSEC_ESP_CAST:
- fprintf (fd, "Cast-128\n");
- break;
-
- case IPSEC_ESP_BLOWFISH:
- fprintf (fd, "Blowfish\n");
- break;
-
- default:
- fprintf (fd, "unknown (%d)\n", proto->id);
- }
-
- fprintf (fd, "Authentication algorithm: ");
- switch (iproto->auth)
- {
- case IPSEC_AUTH_HMAC_MD5:
- fprintf (fd, "HMAC-MD5\n");
- break;
-
- case IPSEC_AUTH_HMAC_SHA:
- fprintf (fd, "HMAC-SHA1\n");
- break;
-
- case IPSEC_AUTH_HMAC_RIPEMD:
- fprintf (fd, "HMAC-RIPEMD-160\n");
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_256:
- fprintf (fd, "HMAC-SHA2-256\n");
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_384:
- fprintf (fd, "HMAC-SHA2-384\n");
- break;
-
- case IPSEC_AUTH_HMAC_SHA2_512:
- fprintf (fd, "HMAC-SHA2-512\n");
- break;
-
- case IPSEC_AUTH_DES_MAC:
- case IPSEC_AUTH_KPDK:
- /* XXX We should be supporting KPDK */
- fprintf (fd, "unknown (%d)", iproto->auth);
- break;
+ int keylen, hashlen;
+ struct ipsec_proto *iproto = proto->data;
+
+ switch (proto->proto) {
+ case IPSEC_PROTO_IPSEC_ESP:
+ keylen = ipsec_esp_enckeylength(proto);
+ hashlen = ipsec_esp_authkeylength(proto);
+ fprintf(fd, "Transform: IPsec ESP\n");
+ fprintf(fd, "Encryption key length: %d\n", keylen);
+ fprintf(fd, "Authentication key length: %d\n", hashlen);
+
+ fprintf(fd, "Encryption algorithm: ");
+ switch (proto->id) {
+ case IPSEC_ESP_DES:
+ case IPSEC_ESP_DES_IV32:
+ case IPSEC_ESP_DES_IV64:
+ fprintf(fd, "DES\n");
+ break;
+
+ case IPSEC_ESP_3DES:
+ fprintf(fd, "3DES\n");
+ break;
+
+ case IPSEC_ESP_AES:
+ fprintf(fd, "AES-128 (CBC)\n");
+ break;
+
+ case IPSEC_ESP_AES_128_CTR:
+ fprintf(fd, "AES-128 (CTR)\n");
+ break;
+
+ case IPSEC_ESP_CAST:
+ fprintf(fd, "Cast-128\n");
+ break;
+
+ case IPSEC_ESP_BLOWFISH:
+ fprintf(fd, "Blowfish\n");
+ break;
+
+ default:
+ fprintf(fd, "unknown (%d)\n", proto->id);
+ }
+
+ fprintf(fd, "Authentication algorithm: ");
+ switch (iproto->auth) {
+ case IPSEC_AUTH_HMAC_MD5:
+ fprintf(fd, "HMAC-MD5\n");
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA:
+ fprintf(fd, "HMAC-SHA1\n");
+ break;
+
+ case IPSEC_AUTH_HMAC_RIPEMD:
+ fprintf(fd, "HMAC-RIPEMD-160\n");
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_256:
+ fprintf(fd, "HMAC-SHA2-256\n");
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_384:
+ fprintf(fd, "HMAC-SHA2-384\n");
+ break;
+
+ case IPSEC_AUTH_HMAC_SHA2_512:
+ fprintf(fd, "HMAC-SHA2-512\n");
+ break;
+
+ case IPSEC_AUTH_DES_MAC:
+ case IPSEC_AUTH_KPDK:
+ /* XXX We should be supporting KPDK */
+ fprintf(fd, "unknown (%d)", iproto->auth);
+ break;
+
+ default:
+ fprintf(fd, "none\n");
+ }
+ break;
+
+ case IPSEC_PROTO_IPSEC_AH:
+ hashlen = ipsec_ah_keylength(proto);
+ fprintf(fd, "Transform: IPsec AH\n");
+ fprintf(fd, "Encryption not used.\n");
+ fprintf(fd, "Authentication key length: %d\n", hashlen);
+
+ fprintf(fd, "Authentication algorithm: ");
+ switch (proto->id) {
+ case IPSEC_AH_MD5:
+ fprintf(fd, "HMAC-MD5\n");
+ break;
+
+ case IPSEC_AH_SHA:
+ fprintf(fd, "HMAC-SHA1\n");
+ break;
+
+ case IPSEC_AH_RIPEMD:
+ fprintf(fd, "HMAC-RIPEMD-160\n");
+ break;
+
+ case IPSEC_AH_SHA2_256:
+ fprintf(fd, "HMAC-SHA2-256\n");
+ break;
+
+ case IPSEC_AH_SHA2_384:
+ fprintf(fd, "HMAC-SHA2-384\n");
+ break;
+
+ case IPSEC_AH_SHA2_512:
+ fprintf(fd, "HMAC-SHA2-512\n");
+ break;
+
+ default:
+ fprintf(fd, "unknown (%d)", proto->id);
+ }
+ break;
default:
- fprintf (fd, "none\n");
+ fprintf(fd, "report_proto: invalid proto %d\n", proto->proto);
}
- break;
-
- case IPSEC_PROTO_IPSEC_AH:
- hashlen = ipsec_ah_keylength (proto);
- fprintf (fd, "Transform: IPsec AH\n");
- fprintf (fd, "Encryption not used.\n");
- fprintf (fd, "Authentication key length: %d\n", hashlen);
-
- fprintf (fd, "Authentication algorithm: ");
- switch (proto->id)
- {
- case IPSEC_AH_MD5:
- fprintf (fd, "HMAC-MD5\n");
- break;
-
- case IPSEC_AH_SHA:
- fprintf (fd, "HMAC-SHA1\n");
- break;
-
- case IPSEC_AH_RIPEMD:
- fprintf (fd, "HMAC-RIPEMD-160\n");
- break;
-
- case IPSEC_AH_SHA2_256:
- fprintf (fd, "HMAC-SHA2-256\n");
- break;
-
- case IPSEC_AH_SHA2_384:
- fprintf (fd, "HMAC-SHA2-384\n");
- break;
-
- case IPSEC_AH_SHA2_512:
- fprintf (fd, "HMAC-SHA2-512\n");
- break;
-
- default:
- fprintf (fd, "unknown (%d)", proto->id);
- }
- break;
-
- default:
- fprintf (fd, "report_proto: invalid proto %d\n", proto->proto);
- }
}
/* Report all the SAs to the report channel. */
void
-sa_report (void)
+sa_report(void)
{
- int i;
- struct sa *sa;
+ int i;
+ struct sa *sa;
- for (i = 0; i <= bucket_mask; i++)
- for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link))
- sa_dump (LOG_REPORT, 0, "sa_report", sa);
+ for (i = 0; i <= bucket_mask; i++)
+ for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
+ sa_dump(LOG_REPORT, 0, "sa_report", sa);
}
@@ -652,188 +630,179 @@ sa_report (void)
* Print an SA's connection details to file SA_FILE.
*/
static void
-sa_dump_all (FILE *fd, struct sa *sa)
+sa_dump_all(FILE * fd, struct sa * sa)
{
- struct proto *proto;
- int i;
-
- /* SA name and phase. */
- fprintf (fd, "SA name: %s", sa->name ? sa->name : "<unnamed>");
- fprintf (fd, " (Phase %d)\n", sa->phase);
-
- /* Source and destination IPs. */
- fprintf (fd, sa->transport == NULL ? "<no transport>" :
- sa->transport->vtbl->decode_ids (sa->transport));
- fprintf (fd, "\n");
-
- /* Transform information. */
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- {
- /* SPI values. */
- for (i = 0; i < 2; i++)
- if (proto->spi[i])
- report_spi (fd, proto->spi[i], proto->spi_sz[i], i);
- else
- fprintf (fd, "SPI %d not defined.", i);
-
- /* Proto values. */
- report_proto (fd, proto);
-
- /* SA separator. */
- fprintf (fd, "\n");
- }
+ struct proto *proto;
+ int i;
+
+ /* SA name and phase. */
+ fprintf(fd, "SA name: %s", sa->name ? sa->name : "<unnamed>");
+ fprintf(fd, " (Phase %d)\n", sa->phase);
+
+ /* Source and destination IPs. */
+ fprintf(fd, sa->transport == NULL ? "<no transport>" :
+ sa->transport->vtbl->decode_ids(sa->transport));
+ fprintf(fd, "\n");
+
+ /* Transform information. */
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link)) {
+ /* SPI values. */
+ for (i = 0; i < 2; i++)
+ if (proto->spi[i])
+ report_spi(fd, proto->spi[i], proto->spi_sz[i], i);
+ else
+ fprintf(fd, "SPI %d not defined.", i);
+
+ /* Proto values. */
+ report_proto(fd, proto);
+
+ /* SA separator. */
+ fprintf(fd, "\n");
+ }
}
/* Report info of all SAs to file SA_FILE. */
void
-sa_report_all (void)
+sa_report_all(void)
{
- int i;
- FILE *fd;
- struct sa *sa;
-
- /* Open SA_FILE. */
- fd = monitor_fopen (SA_FILE, "w");
-
- /* Start sa_config_report. */
- for (i = 0; i <= bucket_mask; i++)
- for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link))
- if (sa->phase == 1)
- fprintf (fd, "SA name: none (phase 1)\n\n");
- else
- sa_dump_all (fd, sa);
-
- /* End sa_config_report. */
- fclose (fd);
+ int i;
+ FILE *fd;
+ struct sa *sa;
+
+ /* Open SA_FILE. */
+ fd = monitor_fopen(SA_FILE, "w");
+
+ /* Start sa_config_report. */
+ for (i = 0; i <= bucket_mask; i++)
+ for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
+ if (sa->phase == 1)
+ fprintf(fd, "SA name: none (phase 1)\n\n");
+ else
+ sa_dump_all(fd, sa);
+
+ /* End sa_config_report. */
+ fclose(fd);
}
/* Free the protocol structure pointed to by PROTO. */
void
-proto_free (struct proto *proto)
+proto_free(struct proto * proto)
{
- int i;
- struct sa *sa = proto->sa;
- struct proto_attr *pa;
-
- for (i = 0; i < 2; i++)
- if (proto->spi[i])
- {
- if (sa->doi->delete_spi)
- sa->doi->delete_spi (sa, proto, i);
- free (proto->spi[i]);
- }
- TAILQ_REMOVE (&sa->protos, proto, link);
- if (proto->data)
- {
- if (sa->doi && sa->doi->free_proto_data)
- sa->doi->free_proto_data (proto->data);
- free (proto->data);
- }
- if (proto->xf_cnt)
- while ((pa = TAILQ_FIRST (&proto->xfs)) != NULL)
- {
- if (pa->attrs)
- free (pa->attrs);
- TAILQ_REMOVE (&proto->xfs, pa, next);
- free (pa);
- }
-
- LOG_DBG ((LOG_SA, 90, "proto_free: freeing %p", proto));
- free (proto);
+ int i;
+ struct sa *sa = proto->sa;
+ struct proto_attr *pa;
+
+ for (i = 0; i < 2; i++)
+ if (proto->spi[i]) {
+ if (sa->doi->delete_spi)
+ sa->doi->delete_spi(sa, proto, i);
+ free(proto->spi[i]);
+ }
+ TAILQ_REMOVE(&sa->protos, proto, link);
+ if (proto->data) {
+ if (sa->doi && sa->doi->free_proto_data)
+ sa->doi->free_proto_data(proto->data);
+ free(proto->data);
+ }
+ if (proto->xf_cnt)
+ while ((pa = TAILQ_FIRST(&proto->xfs)) != NULL) {
+ if (pa->attrs)
+ free(pa->attrs);
+ TAILQ_REMOVE(&proto->xfs, pa, next);
+ free(pa);
+ }
+
+ LOG_DBG((LOG_SA, 90, "proto_free: freeing %p", proto));
+ free(proto);
}
/* Release all resources this SA is using. */
void
-sa_free (struct sa *sa)
+sa_free(struct sa *sa)
{
- if (sa->death)
- {
- timer_remove_event (sa->death);
- sa->death = 0;
- sa->refcnt--;
- }
- if (sa->soft_death)
- {
- timer_remove_event (sa->soft_death);
- sa->soft_death = 0;
- sa->refcnt--;
- }
- sa_remove (sa);
+ if (sa->death) {
+ timer_remove_event(sa->death);
+ sa->death = 0;
+ sa->refcnt--;
+ }
+ if (sa->soft_death) {
+ timer_remove_event(sa->soft_death);
+ sa->soft_death = 0;
+ sa->refcnt--;
+ }
+ sa_remove(sa);
}
/* Remove the SA from the hash table of live SAs. */
void
-sa_remove (struct sa *sa)
+sa_remove(struct sa *sa)
{
- LIST_REMOVE (sa, link);
- LOG_DBG ((LOG_SA, 70, "sa_remove: SA %p removed from SA list", sa));
- sa_release (sa);
+ LIST_REMOVE(sa, link);
+ LOG_DBG((LOG_SA, 70, "sa_remove: SA %p removed from SA list", sa));
+ sa_release(sa);
}
/* Raise the reference count of SA. */
void
-sa_reference (struct sa *sa)
+sa_reference(struct sa * sa)
{
- sa->refcnt++;
- LOG_DBG ((LOG_SA, 80, "sa_reference: SA %p now has %d references",
+ sa->refcnt++;
+ LOG_DBG((LOG_SA, 80, "sa_reference: SA %p now has %d references",
sa, sa->refcnt));
}
/* Release a reference to SA. */
void
-sa_release (struct sa *sa)
+sa_release(struct sa * sa)
{
- struct proto *proto;
- struct cert_handler *handler;
+ struct proto *proto;
+ struct cert_handler *handler;
- LOG_DBG ((LOG_SA, 80, "sa_release: SA %p had %d references",
+ LOG_DBG((LOG_SA, 80, "sa_release: SA %p had %d references",
sa, sa->refcnt));
- if (--sa->refcnt)
- return;
-
- LOG_DBG ((LOG_SA, 60, "sa_release: freeing SA %p", sa));
-
- while ((proto = TAILQ_FIRST (&sa->protos)) != 0)
- proto_free (proto);
- if (sa->data)
- {
- if (sa->doi && sa->doi->free_sa_data)
- sa->doi->free_sa_data (sa->data);
- free (sa->data);
- }
- if (sa->id_i)
- free (sa->id_i);
- if (sa->id_r)
- free (sa->id_r);
- if (sa->recv_cert)
- {
- handler = cert_get (sa->recv_certtype);
- if (handler)
- handler->cert_free (sa->recv_cert);
- }
- if (sa->sent_cert)
- {
- handler = cert_get (sa->sent_certtype);
- if (handler)
- handler->cert_free (sa->sent_cert);
- }
- if (sa->recv_key)
- key_free (sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC, sa->recv_key);
- if (sa->keynote_key)
- free (sa->keynote_key); /* This is just a string */
+ if (--sa->refcnt)
+ return;
+
+ LOG_DBG((LOG_SA, 60, "sa_release: freeing SA %p", sa));
+
+ while ((proto = TAILQ_FIRST(&sa->protos)) != 0)
+ proto_free(proto);
+ if (sa->data) {
+ if (sa->doi && sa->doi->free_sa_data)
+ sa->doi->free_sa_data(sa->data);
+ free(sa->data);
+ }
+ if (sa->id_i)
+ free(sa->id_i);
+ if (sa->id_r)
+ free(sa->id_r);
+ if (sa->recv_cert) {
+ handler = cert_get(sa->recv_certtype);
+ if (handler)
+ handler->cert_free(sa->recv_cert);
+ }
+ if (sa->sent_cert) {
+ handler = cert_get(sa->sent_certtype);
+ if (handler)
+ handler->cert_free(sa->sent_cert);
+ }
+ if (sa->recv_key)
+ key_free(sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC, sa->recv_key);
+ if (sa->keynote_key)
+ free(sa->keynote_key); /* This is just a string */
#if defined (USE_POLICY) || defined (USE_KEYNOTE)
- if (sa->policy_id != -1)
- kn_close (sa->policy_id);
+ if (sa->policy_id != -1)
+ kn_close(sa->policy_id);
#endif
- if (sa->name)
- free (sa->name);
- if (sa->keystate)
- free (sa->keystate);
- if (sa->transport)
- transport_release (sa->transport);
- free (sa);
+ if (sa->name)
+ free(sa->name);
+ if (sa->keystate)
+ free(sa->keystate);
+ if (sa->transport)
+ transport_release(sa->transport);
+ free(sa);
}
/*
@@ -841,143 +810,134 @@ sa_release (struct sa *sa)
* filled in.
*/
void
-sa_isakmp_upgrade (struct message *msg)
+sa_isakmp_upgrade(struct message * msg)
{
- struct sa *sa = TAILQ_FIRST (&msg->exchange->sa_list);
-
- sa_remove (sa);
- GET_ISAKMP_HDR_RCOOKIE (msg->iov[0].iov_base,
- sa->cookies + ISAKMP_HDR_ICOOKIE_LEN);
-
- /*
- * We don't install a transport in the initiator case as we don't know
- * what local address will be chosen. Do it now instead.
- */
- sa->transport = msg->transport;
- transport_reference (sa->transport);
- sa_enter (sa);
+ struct sa *sa = TAILQ_FIRST(&msg->exchange->sa_list);
+
+ sa_remove(sa);
+ GET_ISAKMP_HDR_RCOOKIE(msg->iov[0].iov_base,
+ sa->cookies + ISAKMP_HDR_ICOOKIE_LEN);
+
+ /*
+ * We don't install a transport in the initiator case as we don't know
+ * what local address will be chosen. Do it now instead.
+ */
+ sa->transport = msg->transport;
+ transport_reference(sa->transport);
+ sa_enter(sa);
}
-#define ATTRS_SIZE (IKE_ATTR_BLOCK_SIZE + 1) /* XXX Should be dynamic. */
+#define ATTRS_SIZE (IKE_ATTR_BLOCK_SIZE + 1) /* XXX Should be dynamic. */
struct attr_validation_state {
- u_int8_t *attrp[ATTRS_SIZE];
- u_int8_t checked[ATTRS_SIZE];
- int phase; /* IKE (1) or IPSEC (2) attrs? */
- int mode; /* 0 = 'load', 1 = check */
+ u_int8_t *attrp[ATTRS_SIZE];
+ u_int8_t checked[ATTRS_SIZE];
+ int phase; /* IKE (1) or IPSEC (2) attrs? */
+ int mode; /* 0 = 'load', 1 = check */
};
/* Validate an attribute. Return 0 on match. */
static int
-sa_validate_xf_attrs (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *arg)
+sa_validate_xf_attrs(u_int16_t type, u_int8_t * value, u_int16_t len,
+ void *arg)
{
- struct attr_validation_state *avs = (struct attr_validation_state *)arg;
+ struct attr_validation_state *avs = (struct attr_validation_state *) arg;
- LOG_DBG ((LOG_SA, 95, "sa_validate_xf_attrs: phase %d mode %d type %d "
+ LOG_DBG((LOG_SA, 95, "sa_validate_xf_attrs: phase %d mode %d type %d "
"len %d", avs->phase, avs->mode, type, len));
- /* Make sure the phase and type are valid. */
- if (avs->phase == 1)
- {
- if (type < IKE_ATTR_ENCRYPTION_ALGORITHM || type > IKE_ATTR_BLOCK_SIZE)
- return 1;
- }
- else if (avs->phase == 2)
- {
- if (type < IPSEC_ATTR_SA_LIFE_TYPE || type > IPSEC_ATTR_ECN_TUNNEL)
- return 1;
- }
- else
- return 1;
-
- if (avs->mode == 0) /* Load attrs. */
- {
- avs->attrp[type] = value;
- return 0;
- }
-
- /* Checking for a missing attribute is an immediate failure. */
- if (!avs->attrp[type])
- return 1;
-
- /* Match the loaded attribute against this one, mark it as checked. */
- avs->checked[type]++;
- return memcmp (avs->attrp[type], value, len);
+ /* Make sure the phase and type are valid. */
+ if (avs->phase == 1) {
+ if (type < IKE_ATTR_ENCRYPTION_ALGORITHM || type > IKE_ATTR_BLOCK_SIZE)
+ return 1;
+ } else if (avs->phase == 2) {
+ if (type < IPSEC_ATTR_SA_LIFE_TYPE || type > IPSEC_ATTR_ECN_TUNNEL)
+ return 1;
+ } else
+ return 1;
+
+ if (avs->mode == 0) { /* Load attrs. */
+ avs->attrp[type] = value;
+ return 0;
+ }
+ /* Checking for a missing attribute is an immediate failure. */
+ if (!avs->attrp[type])
+ return 1;
+
+ /* Match the loaded attribute against this one, mark it as checked. */
+ avs->checked[type]++;
+ return memcmp(avs->attrp[type], value, len);
}
/*
* This function is used to validate the returned proposal (protection suite)
* we get from the responder against a proposal we sent. Only run as initiator.
- * We return 0 if a match is found (in any transform of this proposal), 1
+ * We return 0 if a match is found (in any transform of this proposal), 1
* otherwise. Also see note in sa_add_transform() below.
*/
static int
-sa_validate_proto_xf (struct proto *match, struct payload *xf, int phase)
+sa_validate_proto_xf(struct proto * match, struct payload * xf, int phase)
{
- struct proto_attr *pa;
- struct attr_validation_state *avs;
- int found = 0;
- size_t i;
- u_int8_t xf_id;
-
- if (!match->xf_cnt)
- return 0;
-
- if (match->proto != GET_ISAKMP_PROP_PROTO (xf->context->p))
- {
- LOG_DBG ((LOG_SA, 70, "sa_validate_proto_xf: proto %p (#%d) "
- "protocol mismatch", match, match->no));
- return 1;
- }
-
- avs = (struct attr_validation_state *)calloc (1, sizeof *avs);
- if (!avs)
- {
- log_error ("sa_validate_proto_xf: calloc (1, %lu)",
- (unsigned long)sizeof *avs);
- return 1;
- }
- avs->phase = phase;
-
- /* Load the "proposal candidate" attribute set. */
- (void)attribute_map (xf->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- GET_ISAKMP_GEN_LENGTH (xf->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- sa_validate_xf_attrs, avs);
- xf_id = GET_ISAKMP_TRANSFORM_ID (xf->p);
-
- /* Check against the transforms we suggested. */
- avs->mode++;
- for (pa = TAILQ_FIRST (&match->xfs); pa && !found;
- pa = TAILQ_NEXT (pa, next))
- {
- if (xf_id != GET_ISAKMP_TRANSFORM_ID (pa->attrs))
- continue;
-
- memset (avs->checked, 0, sizeof avs->checked);
- if (attribute_map (pa->attrs + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- pa->len - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
- sa_validate_xf_attrs, avs) == 0)
- found++;
-
- LOG_DBG ((LOG_SA, 80, "sa_validate_proto_xf: attr_map "
- "xf %p proto %p pa %p found %d", xf, match, pa, found));
-
- if (!found)
- continue;
-
- /* Require all attributes present and checked. XXX perhaps not? */
- for (i = 0; i < sizeof avs->checked; i++)
- if (avs->attrp[i] && !avs->checked[i])
- found = 0;
-
- LOG_DBG ((LOG_SA, 80, "sa_validate_proto_xf: req_attr "
- "xf %p proto %p pa %p found %d", xf, match, pa, found));
- }
- free (avs);
-
- return found ? 0 : 1;
+ struct proto_attr *pa;
+ struct attr_validation_state *avs;
+ int found = 0;
+ size_t i;
+ u_int8_t xf_id;
+
+ if (!match->xf_cnt)
+ return 0;
+
+ if (match->proto != GET_ISAKMP_PROP_PROTO(xf->context->p)) {
+ LOG_DBG((LOG_SA, 70, "sa_validate_proto_xf: proto %p (#%d) "
+ "protocol mismatch", match, match->no));
+ return 1;
+ }
+ avs = (struct attr_validation_state *) calloc(1, sizeof *avs);
+ if (!avs) {
+ log_error("sa_validate_proto_xf: calloc (1, %lu)",
+ (unsigned long) sizeof *avs);
+ return 1;
+ }
+ avs->phase = phase;
+
+ /* Load the "proposal candidate" attribute set. */
+ (void) attribute_map(xf->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ GET_ISAKMP_GEN_LENGTH(xf->p) - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ sa_validate_xf_attrs, avs);
+ xf_id = GET_ISAKMP_TRANSFORM_ID(xf->p);
+
+ /* Check against the transforms we suggested. */
+ avs->mode++;
+ for (pa = TAILQ_FIRST(&match->xfs); pa && !found;
+ pa = TAILQ_NEXT(pa, next)) {
+ if (xf_id != GET_ISAKMP_TRANSFORM_ID(pa->attrs))
+ continue;
+
+ memset(avs->checked, 0, sizeof avs->checked);
+ if (attribute_map(pa->attrs + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ pa->len - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
+ sa_validate_xf_attrs, avs) == 0)
+ found++;
+
+ LOG_DBG((LOG_SA, 80, "sa_validate_proto_xf: attr_map "
+ "xf %p proto %p pa %p found %d", xf, match, pa, found));
+
+ if (!found)
+ continue;
+
+ /*
+ * Require all attributes present and checked. XXX perhaps
+ * not?
+ */
+ for (i = 0; i < sizeof avs->checked; i++)
+ if (avs->attrp[i] && !avs->checked[i])
+ found = 0;
+
+ LOG_DBG((LOG_SA, 80, "sa_validate_proto_xf: req_attr "
+ "xf %p proto %p pa %p found %d", xf, match, pa, found));
+ }
+ free(avs);
+ return found ? 0 : 1;
}
/*
@@ -986,227 +946,229 @@ sa_validate_proto_xf (struct proto *match, struct payload *xf, int phase)
* are the initiator.
*/
int
-sa_add_transform (struct sa *sa, struct payload *xf, int initiator,
- struct proto **protop)
+sa_add_transform(struct sa * sa, struct payload * xf, int initiator,
+ struct proto ** protop)
{
- struct proto *proto;
- struct payload *prop = xf->context;
-
- *protop = 0;
- if (!initiator)
- {
- proto = calloc (1, sizeof *proto);
- if (!proto)
- log_error ("sa_add_transform: calloc (1, %lu) failed",
- (unsigned long)sizeof *proto);
- }
- else
- {
- /*
- * RFC 2408, section 4.2 states the responder SHOULD use the proposal
- * number from the initiator (i.e us), in it's selected proposal to make
- * this lookup easier. Most vendors follow this. One noted exception is
- * the CiscoPIX (and perhaps other Cisco products).
- *
- * We start by matching on the proposal number, as before.
- */
- for (proto = TAILQ_FIRST (&sa->protos);
- proto && proto->no != GET_ISAKMP_PROP_NO (prop->p);
- proto = TAILQ_NEXT (proto, link))
- ;
- /*
- * If we did not find a match, search through all proposals and xforms.
- */
- if (!proto || sa_validate_proto_xf (proto, xf, sa->phase) != 0)
- for (proto = TAILQ_FIRST (&sa->protos);
- proto && sa_validate_proto_xf (proto, xf, sa->phase) != 0;
- proto = TAILQ_NEXT (proto, link))
- ;
- }
- if (!proto)
- return -1;
- *protop = proto;
-
- /* Allocate DOI-specific part. */
- if (!initiator)
- {
- proto->data = calloc (1, sa->doi->proto_size);
- if (!proto->data)
- {
- log_error ("sa_add_transform: calloc (1, %lu) failed",
- (unsigned long)sa->doi->proto_size);
- goto cleanup;
+ struct proto *proto;
+ struct payload *prop = xf->context;
+
+ *protop = 0;
+ if (!initiator) {
+ proto = calloc(1, sizeof *proto);
+ if (!proto)
+ log_error("sa_add_transform: calloc (1, %lu) failed",
+ (unsigned long) sizeof *proto);
+ } else {
+ /*
+ * RFC 2408, section 4.2 states the responder SHOULD use the proposal
+ * number from the initiator (i.e us), in it's selected proposal to make
+ * this lookup easier. Most vendors follow this. One noted exception is
+ * the CiscoPIX (and perhaps other Cisco products).
+ *
+ * We start by matching on the proposal number, as before.
+ */
+ for (proto = TAILQ_FIRST(&sa->protos);
+ proto && proto->no != GET_ISAKMP_PROP_NO(prop->p);
+ proto = TAILQ_NEXT(proto, link))
+ ;
+ /*
+ * If we did not find a match, search through all proposals and xforms.
+ */
+ if (!proto || sa_validate_proto_xf(proto, xf, sa->phase) != 0)
+ for (proto = TAILQ_FIRST(&sa->protos);
+ proto && sa_validate_proto_xf(proto, xf, sa->phase) != 0;
+ proto = TAILQ_NEXT(proto, link))
+ ;
+ }
+ if (!proto)
+ return -1;
+ *protop = proto;
+
+ /* Allocate DOI-specific part. */
+ if (!initiator) {
+ proto->data = calloc(1, sa->doi->proto_size);
+ if (!proto->data) {
+ log_error("sa_add_transform: calloc (1, %lu) failed",
+ (unsigned long) sa->doi->proto_size);
+ goto cleanup;
+ }
}
- }
-
- proto->no = GET_ISAKMP_PROP_NO (prop->p);
- proto->proto = GET_ISAKMP_PROP_PROTO (prop->p);
- proto->spi_sz[0] = GET_ISAKMP_PROP_SPI_SZ (prop->p);
- if (proto->spi_sz[0])
- {
- proto->spi[0] = malloc (proto->spi_sz[0]);
- if (!proto->spi[0])
- goto cleanup;
- memcpy (proto->spi[0], prop->p + ISAKMP_PROP_SPI_OFF, proto->spi_sz[0]);
- }
- proto->chosen = xf;
- proto->sa = sa;
- proto->id = GET_ISAKMP_TRANSFORM_ID (xf->p);
- if (!initiator)
- TAILQ_INSERT_TAIL (&sa->protos, proto, link);
-
- /* Let the DOI get at proto for initializing its own data. */
- if (sa->doi->proto_init)
- sa->doi->proto_init (proto, 0);
-
- LOG_DBG ((LOG_SA, 80,
+ proto->no = GET_ISAKMP_PROP_NO(prop->p);
+ proto->proto = GET_ISAKMP_PROP_PROTO(prop->p);
+ proto->spi_sz[0] = GET_ISAKMP_PROP_SPI_SZ(prop->p);
+ if (proto->spi_sz[0]) {
+ proto->spi[0] = malloc(proto->spi_sz[0]);
+ if (!proto->spi[0])
+ goto cleanup;
+ memcpy(proto->spi[0], prop->p + ISAKMP_PROP_SPI_OFF, proto->spi_sz[0]);
+ }
+ proto->chosen = xf;
+ proto->sa = sa;
+ proto->id = GET_ISAKMP_TRANSFORM_ID(xf->p);
+ if (!initiator)
+ TAILQ_INSERT_TAIL(&sa->protos, proto, link);
+
+ /* Let the DOI get at proto for initializing its own data. */
+ if (sa->doi->proto_init)
+ sa->doi->proto_init(proto, 0);
+
+ LOG_DBG((LOG_SA, 80,
"sa_add_transform: "
"proto %p no %d proto %d chosen %p sa %p id %d",
proto, proto->no, proto->proto, proto->chosen, proto->sa,
proto->id));
- return 0;
-
- cleanup:
- if (!initiator)
- {
- if (proto->data)
- free (proto->data);
- free (proto);
- }
- *protop = 0;
- return -1;
+ return 0;
+
+cleanup:
+ if (!initiator) {
+ if (proto->data)
+ free(proto->data);
+ free(proto);
+ }
+ *protop = 0;
+ return -1;
}
/* Delete an SA. Tell the peer if NOTIFY is set. */
void
-sa_delete (struct sa *sa, int notify)
+sa_delete(struct sa * sa, int notify)
{
- /* Don't bother notifying of Phase 1 SA deletes. */
- if (sa->phase != 1 && notify)
- message_send_delete (sa);
- sa_free (sa);
+ /* Don't bother notifying of Phase 1 SA deletes. */
+ if (sa->phase != 1 && notify)
+ message_send_delete(sa);
+ sa_free(sa);
}
/* Teardown all SAs. */
void
-sa_teardown_all (void)
+sa_teardown_all(void)
{
- int i;
- struct sa *sa, *next = 0;
-
- LOG_DBG ((LOG_SA, 70, "sa_teardown_all:"));
- /* Get Phase 2 SAs. */
- for (i = 0; i <= bucket_mask; i++)
- for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = next)
- {
- next = LIST_NEXT (sa, link);
- if (sa->phase == 2)
- {
- /* Teardown the phase 2 SAs by name, similar to ui_teardown. */
- LOG_DBG ((LOG_SA, 70, "sa_teardown_all: tearing down SA %s",
- sa->name));
- connection_teardown (sa->name);
- sa_delete (sa, 1);
- }
- }
+ int i;
+ struct sa *sa, *next = 0;
+
+ LOG_DBG((LOG_SA, 70, "sa_teardown_all:"));
+ /* Get Phase 2 SAs. */
+ for (i = 0; i <= bucket_mask; i++)
+ for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = next) {
+ next = LIST_NEXT(sa, link);
+ if (sa->phase == 2) {
+ /*
+ * Teardown the phase 2 SAs by name, similar
+ * to ui_teardown.
+ */
+ LOG_DBG((LOG_SA, 70,
+ "sa_teardown_all: tearing down SA %s",
+ sa->name));
+ connection_teardown(sa->name);
+ sa_delete(sa, 1);
+ }
+ }
}
/*
* This function will get called when we are closing in on the death time of SA
*/
static void
-sa_soft_expire (void *v_sa)
+sa_soft_expire(void *v_sa)
{
- struct sa *sa = v_sa;
-
- sa->soft_death = 0;
- sa_release (sa);
-
- if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED))
- == SA_FLAG_STAYALIVE)
- exchange_establish (sa->name, 0, 0);
- else
- /*
- * Start to watch the use of this SA, so a renegotiation can
- * happen as soon as it is shown to be alive.
- */
- sa->flags |= SA_FLAG_FADING;
+ struct sa *sa = v_sa;
+
+ sa->soft_death = 0;
+ sa_release(sa);
+
+ if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) ==
+ SA_FLAG_STAYALIVE)
+ exchange_establish(sa->name, 0, 0);
+ else
+ /*
+ * Start to watch the use of this SA, so a renegotiation can
+ * happen as soon as it is shown to be alive.
+ */
+ sa->flags |= SA_FLAG_FADING;
}
/* SA has passed its best before date. */
static void
-sa_hard_expire (void *v_sa)
+sa_hard_expire(void *v_sa)
{
- struct sa *sa = v_sa;
+ struct sa *sa = v_sa;
- sa->death = 0;
- sa_release (sa);
+ sa->death = 0;
+ sa_release(sa);
- if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED))
- == SA_FLAG_STAYALIVE)
- exchange_establish (sa->name, 0, 0);
+ if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) ==
+ SA_FLAG_STAYALIVE)
+ exchange_establish(sa->name, 0, 0);
- sa_delete (sa, 1);
+ sa_delete(sa, 1);
}
void
-sa_reinit (void)
+sa_reinit(void)
{
- struct sa *sa;
- char *tag;
- int i;
-
- /* For now; only do this if we have the proper tag configured. */
- tag = conf_get_str ("General", "Renegotiate-on-HUP");
- if (!tag)
- return;
-
- LOG_DBG ((LOG_SA, 30, "sa_reinit: renegotiating active connections"));
-
- /* Get phase 2 SAs. Soft expire those without active exchanges. */
- for (i = 0; i <= bucket_mask; i++)
- for (sa = LIST_FIRST (&sa_tab[i]); sa; sa = LIST_NEXT (sa, link))
- if (sa->phase == 2)
- if (exchange_lookup_by_name (sa->name, sa->phase) == 0)
- {
- timer_remove_event (sa->soft_death);
- sa_soft_expire (sa);
- }
+ struct sa *sa;
+ char *tag;
+ int i;
+
+ /* For now; only do this if we have the proper tag configured. */
+ tag = conf_get_str("General", "Renegotiate-on-HUP");
+ if (!tag)
+ return;
+
+ LOG_DBG((LOG_SA, 30, "sa_reinit: renegotiating active connections"));
+
+ /* Get phase 2 SAs. Soft expire those without active exchanges. */
+ for (i = 0; i <= bucket_mask; i++)
+ for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
+ if (sa->phase == 2)
+ if (exchange_lookup_by_name(sa->name, sa->phase) == 0) {
+ timer_remove_event(sa->soft_death);
+ sa_soft_expire(sa);
+ }
}
/*
* Get an SA attribute's flag value out of textual description.
*/
int
-sa_flag (char *attr)
+sa_flag(char *attr)
{
- static struct sa_flag_map {
- char *name;
- int flag;
- } sa_flag_map[] = {
- { "active-only", SA_FLAG_ACTIVE_ONLY },
- /* Below this point are flags that are internal to the implementation. */
- { "__ondemand", SA_FLAG_ONDEMAND },
- { "ikecfg", SA_FLAG_IKECFG },
- };
- size_t i;
-
- for (i = 0; i < sizeof sa_flag_map / sizeof sa_flag_map[0]; i++)
- if (strcasecmp (attr, sa_flag_map[i].name) == 0)
- return sa_flag_map[i].flag;
- log_print ("sa_flag: attribute \"%s\" unknown", attr);
- return 0;
+ static struct sa_flag_map {
+ char *name;
+ int flag;
+ } sa_flag_map[] = {
+ {
+ "active-only", SA_FLAG_ACTIVE_ONLY
+ },
+
+ /*
+ * Below this point are flags that are internal to the
+ * implementation.
+ */
+ {
+ "__ondemand", SA_FLAG_ONDEMAND
+ }, {
+ "ikecfg", SA_FLAG_IKECFG
+ },
+ };
+ size_t i;
+
+ for (i = 0; i < sizeof sa_flag_map / sizeof sa_flag_map[0]; i++)
+ if (strcasecmp(attr, sa_flag_map[i].name) == 0)
+ return sa_flag_map[i].flag;
+ log_print("sa_flag: attribute \"%s\" unknown", attr);
+ return 0;
}
/* Mark SA as replaced. */
void
-sa_mark_replaced (struct sa *sa)
+sa_mark_replaced(struct sa * sa)
{
- LOG_DBG ((LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced",
+ LOG_DBG((LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced",
sa, sa->name ? sa->name : "unnamed"));
- sa->flags |= SA_FLAG_REPLACED;
+ sa->flags |= SA_FLAG_REPLACED;
}
/*
@@ -1216,57 +1178,55 @@ sa_mark_replaced (struct sa *sa)
* stack.
*/
int
-sa_setup_expirations (struct sa *sa)
+sa_setup_expirations(struct sa * sa)
{
- u_int64_t seconds = sa->seconds;
- struct timeval expiration;
-
- /*
- * Set the soft timeout to a random percentage between 85 & 95 of
- * the negotiated lifetime to break strictly synchronized
- * renegotiations. This works better when the randomization is on the
- * order of processing plus network-roundtrip times, or larger.
- * I.e. it depends on configuration and negotiated lifetimes.
- * It is not good to do the decrease on the hard timeout, because then
- * we may drop our SA before our peer.
- * XXX Better scheme to come?
- */
- if (!sa->soft_death)
- {
- gettimeofday (&expiration, 0);
- /* XXX This should probably be configuration controlled somehow. */
- seconds = sa->seconds * (850 + sysdep_random () % 100) / 1000;
- LOG_DBG ((LOG_TIMER, 95,
- "sa_setup_expirations: SA %p soft timeout in %llu seconds",
- sa, seconds));
- expiration.tv_sec += seconds;
- sa->soft_death
- = timer_add_event ("sa_soft_expire", sa_soft_expire, sa, &expiration);
- if (!sa->soft_death)
- {
- /* If we don't give up we might start leaking... */
- sa_delete (sa, 1);
- return -1;
+ u_int64_t seconds = sa->seconds;
+ struct timeval expiration;
+
+ /*
+ * Set the soft timeout to a random percentage between 85 & 95 of
+ * the negotiated lifetime to break strictly synchronized
+ * renegotiations. This works better when the randomization is on the
+ * order of processing plus network-roundtrip times, or larger.
+ * I.e. it depends on configuration and negotiated lifetimes.
+ * It is not good to do the decrease on the hard timeout, because then
+ * we may drop our SA before our peer.
+ * XXX Better scheme to come?
+ */
+ if (!sa->soft_death) {
+ gettimeofday(&expiration, 0);
+ /*
+ * XXX This should probably be configuration controlled
+ * somehow.
+ */
+ seconds = sa->seconds * (850 + sysdep_random() % 100) / 1000;
+ LOG_DBG((LOG_TIMER, 95,
+ "sa_setup_expirations: SA %p soft timeout in %llu seconds",
+ sa, seconds));
+ expiration.tv_sec += seconds;
+ sa->soft_death = timer_add_event("sa_soft_expire",
+ sa_soft_expire, sa, &expiration);
+ if (!sa->soft_death) {
+ /* If we don't give up we might start leaking... */
+ sa_delete(sa, 1);
+ return -1;
+ }
+ sa_reference(sa);
}
- sa_reference (sa);
- }
-
- if (!sa->death)
- {
- gettimeofday (&expiration, 0);
- LOG_DBG ((LOG_TIMER, 95,
- "sa_setup_expirations: SA %p hard timeout in %llu seconds",
- sa, sa->seconds));
- expiration.tv_sec += sa->seconds;
- sa->death
- = timer_add_event ("sa_hard_expire", sa_hard_expire, sa, &expiration);
- if (!sa->death)
- {
- /* If we don't give up we might start leaking... */
- sa_delete (sa, 1);
- return -1;
+ if (!sa->death) {
+ gettimeofday(&expiration, 0);
+ LOG_DBG((LOG_TIMER, 95,
+ "sa_setup_expirations: SA %p hard timeout in %llu seconds",
+ sa, sa->seconds));
+ expiration.tv_sec += sa->seconds;
+ sa->death = timer_add_event("sa_hard_expire",
+ sa_hard_expire, sa, &expiration);
+ if (!sa->death) {
+ /* If we don't give up we might start leaking... */
+ sa_delete(sa, 1);
+ return -1;
+ }
+ sa_reference(sa);
}
- sa_reference (sa);
- }
- return 0;
+ return 0;
}
diff --git a/sbin/isakmpd/sa.h b/sbin/isakmpd/sa.h
index f2c28e55abe..f7071755185 100644
--- a/sbin/isakmpd/sa.h
+++ b/sbin/isakmpd/sa.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: sa.h,v 1.34 2004/02/27 10:16:26 ho Exp $ */
-/* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */
+/* $OpenBSD: sa.h,v 1.35 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -57,142 +57,151 @@ struct transport;
/* A protection suite consists of a set of protocol descriptions like this. */
struct proto {
- /* Link to the next protocol in the suite. */
- TAILQ_ENTRY (proto) link;
+ /* Link to the next protocol in the suite. */
+ TAILQ_ENTRY(proto) link;
- /* The SA we belong to. */
- struct sa *sa;
+ /* The SA we belong to. */
+ struct sa *sa;
- /* The protocol number as found in the proposal payload. */
- u_int8_t no;
+ /* The protocol number as found in the proposal payload. */
+ u_int8_t no;
- /* The protocol this SA is for. */
- u_int8_t proto;
+ /* The protocol this SA is for. */
+ u_int8_t proto;
- /* Security parameter index info. Element 0 - outgoing, 1 - incoming. */
- u_int8_t spi_sz[2];
- u_int8_t *spi[2];
+ /*
+ * Security parameter index info. Element 0 - outgoing, 1 -
+ * incoming.
+ */
+ u_int8_t spi_sz[2];
+ u_int8_t *spi[2];
- /*
- * The chosen transform, only valid while the incoming SA payload that held
- * it is available for duplicate testing.
- */
- struct payload *chosen;
+ /*
+ * The chosen transform, only valid while the incoming SA payload that held
+ * it is available for duplicate testing.
+ */
+ struct payload *chosen;
- /* The chosen transform's ID. */
- u_int8_t id;
+ /* The chosen transform's ID. */
+ u_int8_t id;
- /* DOI-specific data. */
- void *data;
+ /* DOI-specific data. */
+ void *data;
- /* Proposal transforms data, for validating the responders selection. */
- TAILQ_HEAD (proto_attr_head, proto_attr) xfs;
- size_t xf_cnt;
+ /* Proposal transforms data, for validating the responders selection. */
+ TAILQ_HEAD(proto_attr_head, proto_attr) xfs;
+ size_t xf_cnt;
};
struct proto_attr {
- /* Link to next transform. */
- TAILQ_ENTRY (proto_attr) next;
+ /* Link to next transform. */
+ TAILQ_ENTRY(proto_attr) next;
- /* Transform attribute data and size, suitable for attribute_map(). */
- u_int8_t *attrs;
- size_t len;
+ /* Transform attribute data and size, suitable for attribute_map(). */
+ u_int8_t *attrs;
+ size_t len;
};
struct sa {
- /* Link to SAs with the same hash value. */
- LIST_ENTRY (sa) link;
-
- /*
- * When several SA's are being negotiated in one message we connect them
- * through this link.
- */
- TAILQ_ENTRY (sa) next;
-
- /* A name of the major policy deciding offers and acceptable proposals. */
- char *name;
-
- /* The transport this SA got negotiated over. */
- struct transport *transport;
-
- /* Both initiator and responder cookies. */
- u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
-
- /* The message ID signifying non-ISAKMP SAs. */
- u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
-
- /* The protection suite chosen. */
- TAILQ_HEAD (proto_head, proto) protos;
-
- /* The exchange type we should use when rekeying. */
- u_int8_t exch_type;
-
- /* Phase is 1 for ISAKMP SAs, and 2 for application ones. */
- u_int8_t phase;
-
- /* A reference counter for this structure. */
- u_int16_t refcnt;
-
- /* Various flags, look below for descriptions. */
- u_int32_t flags;
-
- /* The DOI that is to handle DOI-specific issues for this SA. */
- struct doi *doi;
-
- /* Crypto info needed to encrypt/decrypt packets protected by this SA. */
- struct crypto_xf *crypto;
- int key_length;
- struct keystate *keystate;
-
- /* IDs from Phase 1 */
- u_int8_t *id_i;
- size_t id_i_len;
- u_int8_t *id_r;
- size_t id_r_len;
-
- /* Set if we were the initiator of the SA/exchange in Phase 1 */
- int initiator;
-
- /* Policy session ID, where applicable, copied over from the exchange */
- int policy_id;
-
- /*
- * The key used to authenticate phase 1, in printable format, used only by
- * KeyNote.
- */
- char *keynote_key;
-
- /*
- * Certificates or other information from Phase 1; these are copied from the
- * exchange, so look at exchange.h for an explanation of their use.
- */
- int recv_certtype, recv_keytype;
- /* Certificate received from peer, native format. */
- void *recv_cert;
- /* Key peer used to authenticate, native format. */
- void *recv_key;
-
- /*
- * Certificates or other information we used to authenticate to the peer,
- * Phase 1.
- */
- int sent_certtype;
- /* Certificate (to be) sent to peer, native format. */
- void *sent_cert;
-
- /* DOI-specific opaque data. */
- void *data;
-
- /* Lifetime data. */
- u_int64_t seconds;
- u_int64_t kilobytes;
-
- /* ACQUIRE sequence number */
- u_int32_t seq;
-
- /* The events that will occur when an SA has timed out. */
- struct event *soft_death;
- struct event *death;
+ /* Link to SAs with the same hash value. */
+ LIST_ENTRY(sa) link;
+
+ /*
+ * When several SA's are being negotiated in one message we connect them
+ * through this link.
+ */
+ TAILQ_ENTRY(sa) next;
+
+ /*
+ * A name of the major policy deciding offers and acceptable
+ * proposals.
+ */
+ char *name;
+
+ /* The transport this SA got negotiated over. */
+ struct transport *transport;
+
+ /* Both initiator and responder cookies. */
+ u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
+
+ /* The message ID signifying non-ISAKMP SAs. */
+ u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN];
+
+ /* The protection suite chosen. */
+ TAILQ_HEAD(proto_head, proto) protos;
+
+ /* The exchange type we should use when rekeying. */
+ u_int8_t exch_type;
+
+ /* Phase is 1 for ISAKMP SAs, and 2 for application ones. */
+ u_int8_t phase;
+
+ /* A reference counter for this structure. */
+ u_int16_t refcnt;
+
+ /* Various flags, look below for descriptions. */
+ u_int32_t flags;
+
+ /* The DOI that is to handle DOI-specific issues for this SA. */
+ struct doi *doi;
+
+ /*
+ * Crypto info needed to encrypt/decrypt packets protected by this
+ * SA.
+ */
+ struct crypto_xf *crypto;
+ int key_length;
+ struct keystate *keystate;
+
+ /* IDs from Phase 1 */
+ u_int8_t *id_i;
+ size_t id_i_len;
+ u_int8_t *id_r;
+ size_t id_r_len;
+
+ /* Set if we were the initiator of the SA/exchange in Phase 1 */
+ int initiator;
+
+ /* Policy session ID, where applicable, copied over from the exchange */
+ int policy_id;
+
+ /*
+ * The key used to authenticate phase 1, in printable format, used only by
+ * KeyNote.
+ */
+ char *keynote_key;
+
+ /*
+ * Certificates or other information from Phase 1; these are copied from the
+ * exchange, so look at exchange.h for an explanation of their use.
+ */
+ int recv_certtype, recv_keytype;
+ /* Certificate received from peer, native format. */
+ void *recv_cert;
+ /* Key peer used to authenticate, native format. */
+ void *recv_key;
+
+ /*
+ * Certificates or other information we used to authenticate to the peer,
+ * Phase 1.
+ */
+ int sent_certtype;
+ /* Certificate (to be) sent to peer, native format. */
+ void *sent_cert;
+
+ /* DOI-specific opaque data. */
+ void *data;
+
+ /* Lifetime data. */
+ u_int64_t seconds;
+ u_int64_t kilobytes;
+
+ /* ACQUIRE sequence number */
+ u_int32_t seq;
+
+ /* The events that will occur when an SA has timed out. */
+ struct event *soft_death;
+ struct event *death;
};
/* This SA is alive. */
@@ -219,32 +228,33 @@ struct sa {
/* Outfile for detailed SA information. */
#define SA_FILE "/var/run/isakmpd_sa"
-extern void proto_free (struct proto *proto);
-extern int sa_add_transform (struct sa *, struct payload *, int,
- struct proto **);
-extern int sa_create (struct exchange *, struct transport *);
-extern int sa_enter (struct sa *);
-extern void sa_delete (struct sa *, int);
-extern void sa_teardown_all (void);
-extern struct sa *sa_find (int (*) (struct sa *, void *), void *);
-extern int sa_flag (char *);
-extern void sa_free (struct sa *);
-extern void sa_init (void);
-extern void sa_reinit (void);
-extern struct sa *sa_isakmp_lookup_by_peer (struct sockaddr *, socklen_t);
-extern void sa_isakmp_upgrade (struct message *);
-extern struct sa *sa_lookup (u_int8_t *, u_int8_t *);
-extern struct sa *sa_lookup_by_peer (struct sockaddr *, socklen_t);
-extern struct sa *sa_lookup_by_header (u_int8_t *, int);
-extern struct sa *sa_lookup_by_name (char *, int);
-extern struct sa *sa_lookup_from_icookie (u_int8_t *);
-extern struct sa *sa_lookup_isakmp_sa (struct sockaddr *, u_int8_t *);
-extern void sa_mark_replaced (struct sa *);
-extern void sa_reference (struct sa *);
-extern void sa_release (struct sa *);
-extern void sa_remove (struct sa *);
-extern void sa_report (void);
-extern void sa_dump (int, int, char *, struct sa *);
-extern void sa_report_all (void);
-extern int sa_setup_expirations (struct sa *);
-#endif /* _SA_H_ */
+extern void proto_free(struct proto * proto);
+extern int
+sa_add_transform(struct sa *, struct payload *, int,
+ struct proto **);
+extern int sa_create(struct exchange *, struct transport *);
+extern int sa_enter(struct sa *);
+extern void sa_delete(struct sa *, int);
+extern void sa_teardown_all(void);
+extern struct sa *sa_find(int (*) (struct sa *, void *), void *);
+extern int sa_flag(char *);
+extern void sa_free(struct sa *);
+extern void sa_init(void);
+extern void sa_reinit(void);
+extern struct sa *sa_isakmp_lookup_by_peer(struct sockaddr *, socklen_t);
+extern void sa_isakmp_upgrade(struct message *);
+extern struct sa *sa_lookup(u_int8_t *, u_int8_t *);
+extern struct sa *sa_lookup_by_peer(struct sockaddr *, socklen_t);
+extern struct sa *sa_lookup_by_header(u_int8_t *, int);
+extern struct sa *sa_lookup_by_name(char *, int);
+extern struct sa *sa_lookup_from_icookie(u_int8_t *);
+extern struct sa *sa_lookup_isakmp_sa(struct sockaddr *, u_int8_t *);
+extern void sa_mark_replaced(struct sa *);
+extern void sa_reference(struct sa *);
+extern void sa_release(struct sa *);
+extern void sa_remove(struct sa *);
+extern void sa_report(void);
+extern void sa_dump(int, int, char *, struct sa *);
+extern void sa_report_all(void);
+extern int sa_setup_expirations(struct sa *);
+#endif /* _SA_H_ */
diff --git a/sbin/isakmpd/sysdep.h b/sbin/isakmpd/sysdep.h
index 3d3b6f79d4c..45e116f88ed 100644
--- a/sbin/isakmpd/sysdep.h
+++ b/sbin/isakmpd/sysdep.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: sysdep.h,v 1.14 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: sysdep.h,v 1.17 2000/12/04 04:46:35 angelos Exp $ */
+/* $OpenBSD: sysdep.h,v 1.15 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: sysdep.h,v 1.17 2000/12/04 04:46:35 angelos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -40,20 +40,23 @@ struct proto;
struct sa;
struct sockaddr;
-extern void sysdep_app_handler (int);
-extern int sysdep_app_open (void);
-extern int sysdep_cleartext (int, int);
-extern void sysdep_connection_check (char *);
-extern int sysdep_ipsec_delete_spi (struct sa *, struct proto *, int);
-extern int sysdep_ipsec_enable_sa (struct sa *, struct sa *);
-extern u_int8_t *sysdep_ipsec_get_spi (size_t *, u_int8_t, struct sockaddr *,
- struct sockaddr *, u_int32_t);
-extern int sysdep_ipsec_group_spis (struct sa *, struct proto *,
- struct proto *, int);
-extern int sysdep_ipsec_set_spi (struct sa *, struct proto *, int,
- struct sa *);
-extern char *sysdep_progname (void);
-extern u_int32_t sysdep_random (void);
-extern u_int8_t sysdep_sa_len (struct sockaddr *);
-
-#endif /* _SYSDEP_H_ */
+extern void sysdep_app_handler(int);
+extern int sysdep_app_open(void);
+extern int sysdep_cleartext(int, int);
+extern void sysdep_connection_check(char *);
+extern int sysdep_ipsec_delete_spi(struct sa *, struct proto *, int);
+extern int sysdep_ipsec_enable_sa(struct sa *, struct sa *);
+extern u_int8_t *
+sysdep_ipsec_get_spi(size_t *, u_int8_t, struct sockaddr *,
+ struct sockaddr *, u_int32_t);
+extern int
+sysdep_ipsec_group_spis(struct sa *, struct proto *,
+ struct proto *, int);
+extern int
+sysdep_ipsec_set_spi(struct sa *, struct proto *, int,
+ struct sa *);
+extern char *sysdep_progname(void);
+extern u_int32_t sysdep_random(void);
+extern u_int8_t sysdep_sa_len(struct sockaddr *);
+
+#endif /* _SYSDEP_H_ */
diff --git a/sbin/isakmpd/sysdep/openbsd/keynote_compat.c b/sbin/isakmpd/sysdep/openbsd/keynote_compat.c
index ce3f1003fea..a4643750fed 100644
--- a/sbin/isakmpd/sysdep/openbsd/keynote_compat.c
+++ b/sbin/isakmpd/sysdep/openbsd/keynote_compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: keynote_compat.c,v 1.5 2003/06/03 14:53:11 ho Exp $ */
+/* $OpenBSD: keynote_compat.c,v 1.6 2004/04/15 18:39:30 deraadt Exp $ */
/* $EOM: keynote_compat.c,v 1.1 2000/10/15 19:18:26 niklas Exp $ */
/*
@@ -42,7 +42,7 @@
* in April-May 1998
*
* Copyright (C) 1998, 1999 by Angelos D. Keromytis.
- *
+ *
* Permission to use, copy, and modify this software 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
@@ -60,23 +60,23 @@
#include <keynote.h>
extern void keynote_free_key(void *, int);
-extern char *keynote_get_private_key (char *);
+extern char *keynote_get_private_key(char *);
/*
* Exportable front-end to keynote_get_private_key().
*/
char *
-_kn_get_string (char *buf)
+_kn_get_string(char *buf)
{
- return keynote_get_private_key (buf);
+ return keynote_get_private_key(buf);
}
/*
* Free a key.
*/
void
-_kn_free_key (struct keynote_deckey *dc)
+_kn_free_key(struct keynote_deckey *dc)
{
- if (dc)
- keynote_free_key (dc->dec_key, dc->dec_algorithm);
+ if (dc)
+ keynote_free_key(dc->dec_key, dc->dec_algorithm);
}
diff --git a/sbin/isakmpd/sysdep/openbsd/sysdep.c b/sbin/isakmpd/sysdep/openbsd/sysdep.c
index 6d3b03e791e..f51393a2e34 100644
--- a/sbin/isakmpd/sysdep/openbsd/sysdep.c
+++ b/sbin/isakmpd/sysdep/openbsd/sysdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: sysdep.c,v 1.25 2003/06/03 14:53:11 ho Exp $ */
-/* $EOM: sysdep.c,v 1.9 2000/12/04 04:46:35 angelos Exp $ */
+/* $OpenBSD: sysdep.c,v 1.26 2004/04/15 18:39:30 deraadt Exp $ */
+/* $EOM: sysdep.c,v 1.9 2000/12/04 04:46:35 angelos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -55,33 +55,33 @@
#endif /* NEED_SYSDEP_APP */
#include "log.h"
-extern char *__progname;
+extern char *__progname;
/*
* An as strong as possible random number generator, reverting to a
* deterministic pseudo-random one if regrand is set.
*/
u_int32_t
-sysdep_random ()
+sysdep_random()
{
- if (!regrand)
- return arc4random ();
- else
- return random();
+ if (!regrand)
+ return arc4random();
+ else
+ return random();
}
/* Return the basename of the command used to invoke us. */
char *
-sysdep_progname ()
+sysdep_progname()
{
- return __progname;
+ return __progname;
}
/* Return the length of the sockaddr struct. */
u_int8_t
-sysdep_sa_len (struct sockaddr *sa)
+sysdep_sa_len(struct sockaddr *sa)
{
- return sa->sa_len;
+ return sa->sa_len;
}
/* As regress/ use this file I protect the sysdep_app_* stuff like this. */
@@ -91,9 +91,9 @@ sysdep_sa_len (struct sockaddr *sa)
* for communication. We return a file descriptor useable to select(2) on.
*/
int
-sysdep_app_open ()
+sysdep_app_open()
{
- return KEY_API(open) ();
+ return KEY_API(open)();
}
/*
@@ -101,16 +101,16 @@ sysdep_app_open ()
* gets called. FD is the file descriptor causing the alarm.
*/
void
-sysdep_app_handler (int fd)
+sysdep_app_handler(int fd)
{
- KEY_API (handler) (fd);
+ KEY_API(handler)(fd);
}
/* Check that the connection named NAME is active, or else make it active. */
void
-sysdep_connection_check (char *name)
+sysdep_connection_check(char *name)
{
- KEY_API (connection_check) (name);
+ KEY_API(connection_check)(name);
}
/*
@@ -118,144 +118,136 @@ sysdep_connection_check (char *name)
* SRC, SRCLEN, DST & DSTLEN. Stash the SPI size in SZ.
*/
u_int8_t *
-sysdep_ipsec_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
- struct sockaddr *dst, u_int32_t seq)
+sysdep_ipsec_get_spi(size_t *sz, u_int8_t proto, struct sockaddr *src,
+ struct sockaddr *dst, u_int32_t seq)
{
- if (app_none)
- {
- *sz = IPSEC_SPI_SIZE;
- /* XXX should be random instead I think. */
- return (u_int8_t *)strdup ("\x12\x34\x56\x78");
- }
- return KEY_API (get_spi) (sz, proto, src, dst, seq);
+ if (app_none) {
+ *sz = IPSEC_SPI_SIZE;
+ /* XXX should be random instead I think. */
+ return (u_int8_t *)strdup("\x12\x34\x56\x78");
+ }
+ return KEY_API(get_spi)(sz, proto, src, dst, seq);
}
/* Force communication on socket FD to go in the clear. */
int
-sysdep_cleartext (int fd, int af)
+sysdep_cleartext(int fd, int af)
{
- int level, sw;
- struct {
- int ip_proto; /* IP protocol */
- int auth_level;
- int esp_trans_level;
- int esp_network_level;
- int ipcomp_level;
- } optsw[] =
- {
- {
- IPPROTO_IP,
- IP_AUTH_LEVEL,
- IP_ESP_TRANS_LEVEL,
- IP_ESP_NETWORK_LEVEL,
+ int level, sw;
+ struct {
+ int ip_proto; /* IP protocol */
+ int auth_level;
+ int esp_trans_level;
+ int esp_network_level;
+ int ipcomp_level;
+ } optsw[] = {
+ {
+ IPPROTO_IP,
+ IP_AUTH_LEVEL,
+ IP_ESP_TRANS_LEVEL,
+ IP_ESP_NETWORK_LEVEL,
#ifdef IP_IPCOMP_LEVEL
- IP_IPCOMP_LEVEL
+ IP_IPCOMP_LEVEL
#else
- 0
+ 0
#endif
- },
- {
- IPPROTO_IPV6,
- IPV6_AUTH_LEVEL,
- IPV6_ESP_TRANS_LEVEL,
- IPV6_ESP_NETWORK_LEVEL,
+ }, {
+ IPPROTO_IPV6,
+ IPV6_AUTH_LEVEL,
+ IPV6_ESP_TRANS_LEVEL,
+ IPV6_ESP_NETWORK_LEVEL,
#ifdef IPV6_IPCOMP_LEVEL
- IPV6_IPCOMP_LEVEL
+ IPV6_IPCOMP_LEVEL
#else
- 0
+ 0
#endif
- },
- };
-
- if (app_none)
- return 0;
-
- switch (af)
- {
- case AF_INET:
- sw = 0;
- break;
- case AF_INET6:
- sw = 1;
- break;
- default:
- log_print ("sysdep_cleartext: unsupported protocol family %d", af);
- return -1;
- }
-
- /*
- * Need to bypass system security policy, so I can send and
- * receive key management datagrams in the clear.
- */
- level = IPSEC_LEVEL_BYPASS;
- if (monitor_setsockopt (fd, optsw[sw].ip_proto, optsw[sw].auth_level,
- (char *)&level, sizeof level) == -1)
- {
- log_error ("sysdep_cleartext: "
- "setsockopt (%d, %d, IP_AUTH_LEVEL, ...) failed", fd,
- optsw[sw].ip_proto);
- return -1;
- }
- if (monitor_setsockopt (fd, optsw[sw].ip_proto, optsw[sw].esp_trans_level,
- (char *)&level, sizeof level) == -1)
- {
- log_error ("sysdep_cleartext: "
- "setsockopt (%d, %d, IP_ESP_TRANS_LEVEL, ...) failed", fd,
- optsw[sw].ip_proto);
- return -1;
- }
- if (monitor_setsockopt (fd, optsw[sw].ip_proto, optsw[sw].esp_network_level,
- (char *)&level, sizeof level) == -1)
- {
- log_error("sysdep_cleartext: "
- "setsockopt (%d, %d, IP_ESP_NETWORK_LEVEL, ...) failed", fd,
- optsw[sw].ip_proto);
- return -1;
- }
- if (optsw[sw].ipcomp_level
- && monitor_setsockopt (fd, optsw[sw].ip_proto, optsw[sw].ipcomp_level,
- (char *)&level, sizeof level) == -1
- && errno != ENOPROTOOPT)
- {
- log_error("sysdep_cleartext: "
- "setsockopt (%d, %d, IP_IPCOMP_LEVEL, ...) failed,", fd,
- optsw[sw].ip_proto);
- return -1;
- }
- return 0;
+ },
+ };
+
+ if (app_none)
+ return 0;
+
+ switch (af) {
+ case AF_INET:
+ sw = 0;
+ break;
+ case AF_INET6:
+ sw = 1;
+ break;
+ default:
+ log_print("sysdep_cleartext: unsupported protocol family %d", af);
+ return -1;
+ }
+
+ /*
+ * Need to bypass system security policy, so I can send and
+ * receive key management datagrams in the clear.
+ */
+ level = IPSEC_LEVEL_BYPASS;
+ if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].auth_level,
+ (char *) &level, sizeof level) == -1) {
+ log_error("sysdep_cleartext: "
+ "setsockopt (%d, %d, IP_AUTH_LEVEL, ...) failed", fd,
+ optsw[sw].ip_proto);
+ return -1;
+ }
+ if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_trans_level,
+ (char *) &level, sizeof level) == -1) {
+ log_error("sysdep_cleartext: "
+ "setsockopt (%d, %d, IP_ESP_TRANS_LEVEL, ...) failed", fd,
+ optsw[sw].ip_proto);
+ return -1;
+ }
+ if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_network_level,
+ (char *) &level, sizeof level) == -1) {
+ log_error("sysdep_cleartext: "
+ "setsockopt (%d, %d, IP_ESP_NETWORK_LEVEL, ...) failed", fd,
+ optsw[sw].ip_proto);
+ return -1;
+ }
+ if (optsw[sw].ipcomp_level &&
+ monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].ipcomp_level,
+ (char *) &level, sizeof level) == -1 &&
+ errno != ENOPROTOOPT) {
+ log_error("sysdep_cleartext: "
+ "setsockopt (%d, %d, IP_IPCOMP_LEVEL, ...) failed,", fd,
+ optsw[sw].ip_proto);
+ return -1;
+ }
+ return 0;
}
int
-sysdep_ipsec_delete_spi (struct sa *sa, struct proto *proto, int incoming)
+sysdep_ipsec_delete_spi(struct sa *sa, struct proto *proto, int incoming)
{
- if (app_none)
- return 0;
- return KEY_API (delete_spi) (sa, proto, incoming);
+ if (app_none)
+ return 0;
+ return KEY_API(delete_spi)(sa, proto, incoming);
}
int
-sysdep_ipsec_enable_sa (struct sa *sa, struct sa *isakmp_sa)
+sysdep_ipsec_enable_sa(struct sa *sa, struct sa *isakmp_sa)
{
- if (app_none)
- return 0;
- return KEY_API (enable_sa) (sa, isakmp_sa);
+ if (app_none)
+ return 0;
+ return KEY_API(enable_sa)(sa, isakmp_sa);
}
int
-sysdep_ipsec_group_spis (struct sa *sa, struct proto *proto1,
- struct proto *proto2, int incoming)
+sysdep_ipsec_group_spis(struct sa *sa, struct proto *proto1,
+ struct proto *proto2, int incoming)
{
- if (app_none)
- return 0;
- return KEY_API (group_spis) (sa, proto1, proto2, incoming);
+ if (app_none)
+ return 0;
+ return KEY_API(group_spis)(sa, proto1, proto2, incoming);
}
int
-sysdep_ipsec_set_spi (struct sa *sa, struct proto *proto, int incoming,
- struct sa *isakmp_sa)
+sysdep_ipsec_set_spi(struct sa *sa, struct proto *proto, int incoming,
+ struct sa *isakmp_sa)
{
- if (app_none)
- return 0;
- return KEY_API (set_spi) (sa, proto, incoming, isakmp_sa);
+ if (app_none)
+ return 0;
+ return KEY_API(set_spi) (sa,proto, incoming, isakmp_sa);
}
#endif
diff --git a/sbin/isakmpd/timer.c b/sbin/isakmpd/timer.c
index aefc84577b4..180ccc823a0 100644
--- a/sbin/isakmpd/timer.c
+++ b/sbin/isakmpd/timer.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: timer.c,v 1.11 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: timer.c,v 1.13 2000/02/20 19:58:42 niklas Exp $ */
+/* $OpenBSD: timer.c,v 1.12 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: timer.c,v 1.13 2000/02/20 19:58:42 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -38,106 +38,100 @@
#include "log.h"
#include "timer.h"
-static TAILQ_HEAD (event_list, event) events;
+static TAILQ_HEAD(event_list, event) events;
void
-timer_init (void)
+timer_init(void)
{
- TAILQ_INIT (&events);
+ TAILQ_INIT(&events);
}
void
-timer_next_event (struct timeval **timeout)
+timer_next_event(struct timeval **timeout)
{
- struct timeval now;
-
- if (TAILQ_FIRST (&events))
- {
- gettimeofday (&now, 0);
- if (timercmp (&now, &TAILQ_FIRST (&events)->expiration, >=))
- timerclear (*timeout);
- else
- timersub (&TAILQ_FIRST (&events)->expiration, &now, *timeout);
- }
- else
- *timeout = 0;
+ struct timeval now;
+
+ if (TAILQ_FIRST(&events)) {
+ gettimeofday(&now, 0);
+ if (timercmp(&now, &TAILQ_FIRST(&events)->expiration, >=))
+ timerclear(*timeout);
+ else
+ timersub(&TAILQ_FIRST(&events)->expiration, &now, *timeout);
+ } else
+ *timeout = 0;
}
void
-timer_handle_expirations (void)
+timer_handle_expirations(void)
{
- struct timeval now;
- struct event *n;
-
- gettimeofday (&now, 0);
- for (n = TAILQ_FIRST (&events); n && timercmp (&now, &n->expiration, >=);
- n = TAILQ_FIRST (&events))
- {
- LOG_DBG ((LOG_TIMER, 10,
- "timer_handle_expirations: event %s(%p)", n->name, n->arg));
- TAILQ_REMOVE (&events, n, link);
- (*n->func) (n->arg);
- free (n);
- }
+ struct timeval now;
+ struct event *n;
+
+ gettimeofday(&now, 0);
+ for (n = TAILQ_FIRST(&events); n && timercmp(&now, &n->expiration, >=);
+ n = TAILQ_FIRST(&events)) {
+ LOG_DBG((LOG_TIMER, 10,
+ "timer_handle_expirations: event %s(%p)", n->name, n->arg));
+ TAILQ_REMOVE(&events, n, link);
+ (*n->func)(n->arg);
+ free(n);
+ }
}
struct event *
-timer_add_event (char *name, void (*func) (void *), void *arg,
- struct timeval *expiration)
+timer_add_event(char *name, void (*func)(void *), void *arg,
+ struct timeval *expiration)
{
- struct event *ev = (struct event *)malloc (sizeof *ev);
- struct event *n;
- struct timeval now;
-
- if (!ev)
- return 0;
- ev->name = name;
- ev->func = func;
- ev->arg = arg;
- gettimeofday (&now, 0);
- memcpy (&ev->expiration, expiration, sizeof *expiration);
- for (n = TAILQ_FIRST (&events);
- n && timercmp (expiration, &n->expiration, >=);
- n = TAILQ_NEXT (n, link))
- ;
- if (n)
- {
- LOG_DBG ((LOG_TIMER, 10,
- "timer_add_event: event %s(%p) added before %s(%p), "
- "expiration in %lds", name,
- arg, n->name, n->arg, expiration->tv_sec - now.tv_sec));
- TAILQ_INSERT_BEFORE (n, ev, link);
- }
- else
- {
- LOG_DBG ((LOG_TIMER, 10, "timer_add_event: event %s(%p) added last, "
- "expiration in %lds", name, arg,
- expiration->tv_sec - now.tv_sec));
- TAILQ_INSERT_TAIL (&events, ev, link);
- }
- return ev;
+ struct event *ev = (struct event *) malloc(sizeof *ev);
+ struct event *n;
+ struct timeval now;
+
+ if (!ev)
+ return 0;
+ ev->name = name;
+ ev->func = func;
+ ev->arg = arg;
+ gettimeofday(&now, 0);
+ memcpy(&ev->expiration, expiration, sizeof *expiration);
+ for (n = TAILQ_FIRST(&events);
+ n && timercmp(expiration, &n->expiration, >=);
+ n = TAILQ_NEXT(n, link))
+ ;
+ if (n) {
+ LOG_DBG((LOG_TIMER, 10,
+ "timer_add_event: event %s(%p) added before %s(%p), "
+ "expiration in %lds", name,
+ arg, n->name, n->arg, expiration->tv_sec - now.tv_sec));
+ TAILQ_INSERT_BEFORE(n, ev, link);
+ } else {
+ LOG_DBG((LOG_TIMER, 10, "timer_add_event: event %s(%p) added last, "
+ "expiration in %lds", name, arg,
+ expiration->tv_sec - now.tv_sec));
+ TAILQ_INSERT_TAIL(&events, ev, link);
+ }
+ return ev;
}
void
-timer_remove_event (struct event *ev)
+timer_remove_event(struct event *ev)
{
- LOG_DBG ((LOG_TIMER, 10, "timer_remove_event: removing event %s(%p)",
+ LOG_DBG((LOG_TIMER, 10, "timer_remove_event: removing event %s(%p)",
ev->name, ev->arg));
- TAILQ_REMOVE (&events, ev, link);
- free (ev);
+ TAILQ_REMOVE(&events, ev, link);
+ free(ev);
}
void
-timer_report (void)
+timer_report(void)
{
- struct event *ev;
- struct timeval now;
+ struct event *ev;
+ struct timeval now;
- gettimeofday (&now, 0);
+ gettimeofday(&now, 0);
- for (ev = TAILQ_FIRST (&events); ev; ev = TAILQ_NEXT (ev, link))
- LOG_DBG ((LOG_REPORT, 0,
- "timer_report: event %s(%p) scheduled in %d seconds",
- (ev->name ? ev->name : "<unknown>"), ev,
- (int)(ev->expiration.tv_sec - now.tv_sec)));
+ for (ev = TAILQ_FIRST(&events); ev; ev = TAILQ_NEXT(ev, link))
+ LOG_DBG((LOG_REPORT, 0,
+ "timer_report: event %s(%p) scheduled in %d seconds",
+ (ev->name ? ev->name : "<unknown>"), ev,
+ (int) (ev->expiration.tv_sec - now.tv_sec)));
}
diff --git a/sbin/isakmpd/timer.h b/sbin/isakmpd/timer.h
index 253f0b63539..a107107e69e 100644
--- a/sbin/isakmpd/timer.h
+++ b/sbin/isakmpd/timer.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: timer.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: timer.h,v 1.6 1999/04/11 22:35:55 ho Exp $ */
+/* $OpenBSD: timer.h,v 1.6 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: timer.h,v 1.6 1999/04/11 22:35:55 ho Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -37,19 +37,19 @@
#include <sys/time.h>
struct event {
- TAILQ_ENTRY (event) link;
- char *name;
- void (*func) (void *);
- void *arg;
- struct timeval expiration;
+ TAILQ_ENTRY(event) link;
+ char *name;
+ void (*func) (void *);
+ void *arg;
+ struct timeval expiration;
};
-extern void timer_init (void);
-extern void timer_next_event (struct timeval **);
-extern void timer_handle_expirations (void);
-extern struct event *timer_add_event (char *, void (*) (void *), void *,
- struct timeval *);
-extern void timer_remove_event (struct event *);
-extern void timer_report (void);
+extern void timer_init(void);
+extern void timer_next_event(struct timeval **);
+extern void timer_handle_expirations(void);
+extern struct event *timer_add_event(char *, void (*) (void *), void *,
+ struct timeval *);
+extern void timer_remove_event(struct event *);
+extern void timer_report(void);
-#endif /* _TIMER_H_ */
+#endif /* _TIMER_H_ */
diff --git a/sbin/isakmpd/transport.c b/sbin/isakmpd/transport.c
index da1cc43d917..ca92f5cda48 100644
--- a/sbin/isakmpd/transport.c
+++ b/sbin/isakmpd/transport.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: transport.c,v 1.23 2003/12/18 02:03:28 ho Exp $ */
-/* $EOM: transport.c,v 1.43 2000/10/10 12:36:39 provos Exp $ */
+/* $OpenBSD: transport.c,v 1.24 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: transport.c,v 1.43 2000/10/10 12:36:39 provos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -47,117 +47,119 @@
/* If no retransmit limit is given, use this as a default. */
#define RETRANSMIT_DEFAULT 10
-LIST_HEAD (transport_list, transport) transport_list;
-LIST_HEAD (transport_method_list, transport_vtbl) transport_method_list;
+LIST_HEAD(transport_list, transport) transport_list;
+LIST_HEAD(transport_method_list, transport_vtbl) transport_method_list;
/* Call the reinit function of the various transports. */
-void
-transport_reinit (void)
+ void
+ transport_reinit(void)
{
- struct transport_vtbl *method;
+ struct transport_vtbl *method;
- for (method = LIST_FIRST (&transport_method_list); method;
- method = LIST_NEXT (method, link))
- method->reinit ();
+ for (method = LIST_FIRST(&transport_method_list); method;
+ method = LIST_NEXT(method, link))
+ method->reinit();
}
/* Initialize the transport maintenance module. */
void
-transport_init (void)
+transport_init(void)
{
- LIST_INIT (&transport_list);
- LIST_INIT (&transport_method_list);
+ LIST_INIT(&transport_list);
+ LIST_INIT(&transport_method_list);
}
/* Register another transport T. */
void
-transport_add (struct transport *t)
+transport_add(struct transport * t)
{
- LOG_DBG ((LOG_TRANSPORT, 70, "transport_add: adding %p", t));
- TAILQ_INIT (&t->sendq);
- TAILQ_INIT (&t->prio_sendq);
- LIST_INSERT_HEAD (&transport_list, t, link);
- t->flags = 0;
- t->refcnt = 0;
+ LOG_DBG((LOG_TRANSPORT, 70, "transport_add: adding %p", t));
+ TAILQ_INIT(&t->sendq);
+ TAILQ_INIT(&t->prio_sendq);
+ LIST_INSERT_HEAD(&transport_list, t, link);
+ t->flags = 0;
+ t->refcnt = 0;
}
/* Add a referer to transport T. */
void
-transport_reference (struct transport *t)
+transport_reference(struct transport * t)
{
- t->refcnt++;
- LOG_DBG ((LOG_TRANSPORT, 95,
- "transport_reference: transport %p now has %d references", t,
- t->refcnt));
+ t->refcnt++;
+ LOG_DBG((LOG_TRANSPORT, 95,
+ "transport_reference: transport %p now has %d references", t,
+ t->refcnt));
}
/*
* Remove a referer from transport T, removing all of T when no referers left.
*/
void
-transport_release (struct transport *t)
+transport_release(struct transport * t)
{
- LOG_DBG ((LOG_TRANSPORT, 95,
- "transport_release: transport %p had %d references", t,
- t->refcnt));
- if (--t->refcnt)
- return;
-
- LOG_DBG ((LOG_TRANSPORT, 70, "transport_release: freeing %p", t));
- LIST_REMOVE (t, link);
- t->vtbl->remove (t);
+ LOG_DBG((LOG_TRANSPORT, 95,
+ "transport_release: transport %p had %d references", t,
+ t->refcnt));
+ if (--t->refcnt)
+ return;
+
+ LOG_DBG((LOG_TRANSPORT, 70, "transport_release: freeing %p", t));
+ LIST_REMOVE(t, link);
+ t->vtbl->remove(t);
}
void
-transport_report (void)
+transport_report(void)
{
- struct transport *t;
- struct message *msg;
-
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- {
- LOG_DBG ((LOG_REPORT, 0,
- "transport_report: transport %p flags %x refcnt %d", t,
- t->flags, t->refcnt));
-
- t->vtbl->report (t);
-
- /* This is the reason message_dump_raw lives outside message.c. */
- for (msg = TAILQ_FIRST (&t->prio_sendq); msg;
- msg = TAILQ_NEXT (msg, link))
- message_dump_raw ("udp_report", msg, LOG_REPORT);
-
- for (msg = TAILQ_FIRST (&t->sendq); msg; msg = TAILQ_NEXT (msg, link))
- message_dump_raw ("udp_report", msg, LOG_REPORT);
- }
+ struct transport *t;
+ struct message *msg;
+
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
+ LOG_DBG((LOG_REPORT, 0,
+ "transport_report: transport %p flags %x refcnt %d", t,
+ t->flags, t->refcnt));
+
+ t->vtbl->report(t);
+
+ /*
+ * This is the reason message_dump_raw lives outside
+ * message.c.
+ */
+ for (msg = TAILQ_FIRST(&t->prio_sendq); msg;
+ msg = TAILQ_NEXT(msg, link))
+ message_dump_raw("udp_report", msg, LOG_REPORT);
+
+ for (msg = TAILQ_FIRST(&t->sendq); msg; msg = TAILQ_NEXT(msg, link))
+ message_dump_raw("udp_report", msg, LOG_REPORT);
+ }
}
int
-transport_prio_sendqs_empty (void)
+transport_prio_sendqs_empty(void)
{
- struct transport *t;
+ struct transport *t;
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- if (TAILQ_FIRST (&t->prio_sendq))
- return 0;
- return 1;
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
+ if (TAILQ_FIRST(&t->prio_sendq))
+ return 0;
+ return 1;
}
/* Register another transport method T. */
void
-transport_method_add (struct transport_vtbl *t)
+transport_method_add(struct transport_vtbl * t)
{
- LIST_INSERT_HEAD (&transport_method_list, t, link);
+ LIST_INSERT_HEAD(&transport_method_list, t, link);
}
/* Apply a function FUNC on all registered transports. */
void
-transport_map (void (*func) (struct transport *))
+transport_map(void (*func) (struct transport *))
{
- struct transport *t;
+ struct transport *t;
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- (*func) (t);
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
+ (*func) (t);
}
/*
@@ -166,20 +168,19 @@ transport_map (void (*func) (struct transport *))
* check in order to cover the ones we setup in here.
*/
int
-transport_fd_set (fd_set *fds)
+transport_fd_set(fd_set * fds)
{
- int n;
- int max = -1;
- struct transport *t;
-
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- if (t->flags & TRANSPORT_LISTEN)
- {
- n = t->vtbl->fd_set (t, fds, 1);
- if (n > max)
- max = n;
- }
- return max + 1;
+ int n;
+ int max = -1;
+ struct transport *t;
+
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
+ if (t->flags & TRANSPORT_LISTEN) {
+ n = t->vtbl->fd_set(t, fds, 1);
+ if (n > max)
+ max = n;
+ }
+ return max + 1;
}
/*
@@ -189,22 +190,20 @@ transport_fd_set (fd_set *fds)
* we setup in here.
*/
int
-transport_pending_wfd_set (fd_set *fds)
+transport_pending_wfd_set(fd_set * fds)
{
- int n;
- int max = -1;
- struct transport *t;
-
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- {
- if (TAILQ_FIRST (&t->sendq) || TAILQ_FIRST (&t->prio_sendq))
- {
- n = t->vtbl->fd_set (t, fds, 1);
- if (n > max)
- max = n;
+ int n;
+ int max = -1;
+ struct transport *t;
+
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
+ if (TAILQ_FIRST(&t->sendq) || TAILQ_FIRST(&t->prio_sendq)) {
+ n = t->vtbl->fd_set(t, fds, 1);
+ if (n > max)
+ max = n;
+ }
}
- }
- return max + 1;
+ return max + 1;
}
/*
@@ -212,13 +211,13 @@ transport_pending_wfd_set (fd_set *fds)
* incoming message and start processing it.
*/
void
-transport_handle_messages (fd_set *fds)
+transport_handle_messages(fd_set * fds)
{
- struct transport *t;
+ struct transport *t;
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- if ((t->flags & TRANSPORT_LISTEN) && (*t->vtbl->fd_isset) (t, fds))
- (*t->vtbl->handle_message) (t);
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
+ if ((t->flags & TRANSPORT_LISTEN) && (*t->vtbl->fd_isset) (t, fds))
+ (*t->vtbl->handle_message) (t);
}
/*
@@ -231,140 +230,134 @@ transport_handle_messages (fd_set *fds)
* be favoured to later ones sharing the file descriptor.
*/
void
-transport_send_messages (fd_set *fds)
+transport_send_messages(fd_set * fds)
{
- struct transport *t, *next;
- struct message *msg;
- struct exchange *exchange;
- struct timeval expiration;
- int expiry, ok_to_drop_message;
-
- /* Reference all transports first so noone will disappear while in use. */
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- transport_reference (t);
-
- for (t = LIST_FIRST (&transport_list); t; t = LIST_NEXT (t, link))
- {
- if ((TAILQ_FIRST (&t->sendq) || TAILQ_FIRST (&t->prio_sendq))
- && t->vtbl->fd_isset (t, fds))
- {
- t->vtbl->fd_set (t, fds, 0);
-
- /* Prefer a message from the prioritized sendq. */
- if (TAILQ_FIRST (&t->prio_sendq))
- {
- msg = TAILQ_FIRST (&t->prio_sendq);
- TAILQ_REMOVE (&t->prio_sendq, msg, link);
- }
- else
- {
- msg = TAILQ_FIRST (&t->sendq);
- TAILQ_REMOVE (&t->sendq, msg, link);
- }
-
- msg->flags &= ~MSG_IN_TRANSIT;
- exchange = msg->exchange;
- exchange->in_transit = 0;
-
- /*
- * We disregard the potential error message here, hoping that the
- * retransmit will go better.
- * XXX Consider a retry/fatal error discriminator.
- */
- t->vtbl->send_message (msg);
- msg->xmits++;
-
- /*
- * This piece of code has been proven to be quite delicate.
- * Think twice for before altering. Here's an outline:
- *
- * If this message is not the one which finishes an exchange,
- * check if we have reached the number of retransmit before
- * queuing it up for another.
- *
- * If it is a finishing message we still may have to keep it
- * around for an on-demand retransmit when seeing a duplicate
- * of our peer's previous message.
- *
- * If we have no previous message from our peer, we need not
- * to keep the message around.
- */
- if ((msg->flags & MSG_LAST) == 0)
- {
- if (msg->xmits > conf_get_num ("General", "retransmits",
- RETRANSMIT_DEFAULT))
- {
- log_print ("transport_send_messages: giving up on "
- "message %p, exchange %s", msg,
- exchange->name ? exchange->name : "<unnamed>");
- /* Be more verbose here. */
- if (exchange->phase == 1)
- {
- log_print ("transport_send_messages: either this "
- "message did not reach the other peer");
- if (exchange->initiator)
- log_print ("transport_send_messages: or the response"
- "message did not reach us back");
- else
- log_print ("transport_send_messages: or this is "
- "an attempted IKE scan");
- }
- exchange->last_sent = 0;
+ struct transport *t, *next;
+ struct message *msg;
+ struct exchange *exchange;
+ struct timeval expiration;
+ int expiry, ok_to_drop_message;
+
+ /*
+ * Reference all transports first so noone will disappear while in
+ * use.
+ */
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
+ transport_reference(t);
+
+ for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
+ if ((TAILQ_FIRST(&t->sendq) || TAILQ_FIRST(&t->prio_sendq))
+ && t->vtbl->fd_isset(t, fds)) {
+ t->vtbl->fd_set(t, fds, 0);
+
+ /* Prefer a message from the prioritized sendq. */
+ if (TAILQ_FIRST(&t->prio_sendq)) {
+ msg = TAILQ_FIRST(&t->prio_sendq);
+ TAILQ_REMOVE(&t->prio_sendq, msg, link);
+ } else {
+ msg = TAILQ_FIRST(&t->sendq);
+ TAILQ_REMOVE(&t->sendq, msg, link);
+ }
+
+ msg->flags &= ~MSG_IN_TRANSIT;
+ exchange = msg->exchange;
+ exchange->in_transit = 0;
+
+ /*
+ * We disregard the potential error message here, hoping that the
+ * retransmit will go better.
+ * XXX Consider a retry/fatal error discriminator.
+ */
+ t->vtbl->send_message(msg);
+ msg->xmits++;
+
+ /*
+ * This piece of code has been proven to be quite delicate.
+ * Think twice for before altering. Here's an outline:
+ *
+ * If this message is not the one which finishes an exchange,
+ * check if we have reached the number of retransmit before
+ * queuing it up for another.
+ *
+ * If it is a finishing message we still may have to keep it
+ * around for an on-demand retransmit when seeing a duplicate
+ * of our peer's previous message.
+ *
+ * If we have no previous message from our peer, we need not
+ * to keep the message around.
+ */
+ if ((msg->flags & MSG_LAST) == 0) {
+ if (msg->xmits > conf_get_num("General", "retransmits",
+ RETRANSMIT_DEFAULT)) {
+ log_print("transport_send_messages: giving up on "
+ "message %p, exchange %s", msg,
+ exchange->name ? exchange->name : "<unnamed>");
+ /* Be more verbose here. */
+ if (exchange->phase == 1) {
+ log_print("transport_send_messages: either this "
+ "message did not reach the other peer");
+ if (exchange->initiator)
+ log_print("transport_send_messages: or the response"
+ "message did not reach us back");
+ else
+ log_print("transport_send_messages: or this is "
+ "an attempted IKE scan");
+ }
+ exchange->last_sent = 0;
+ } else {
+ gettimeofday(&expiration, 0);
+
+ /*
+ * XXX Calculate from round trip timings and a backoff func.
+ */
+ expiry = msg->xmits * 2 + 5;
+ expiration.tv_sec += expiry;
+ LOG_DBG((LOG_TRANSPORT, 30,
+ "transport_send_messages: message %p "
+ "scheduled for retransmission %d in %d secs",
+ msg, msg->xmits, expiry));
+ if (msg->retrans)
+ timer_remove_event(msg->retrans);
+ msg->retrans
+ = timer_add_event("message_send_expire",
+ (void (*) (void *)) message_send_expire,
+ msg, &expiration);
+ /*
+ * If we cannot retransmit, we
+ * cannot...
+ */
+ exchange->last_sent = msg->retrans ? msg : 0;
+ }
+ } else
+ exchange->last_sent = exchange->last_received ? msg : 0;
+
+ /*
+ * If this message is not referred to for later retransmission
+ * it will be ok for us to drop it after the post-send function.
+ * But as the post-send function may remove the exchange, we need
+ * to remember this fact here.
+ */
+ ok_to_drop_message = exchange->last_sent == 0;
+
+ /*
+ * If this is not a retransmit call post-send functions that allows
+ * parallel work to be done while the network and peer does their
+ * share of the job. Note that a post-send function may take
+ * away the exchange we belong to, but only if no retransmits
+ * are possible.
+ */
+ if (msg->xmits == 1)
+ message_post_send(msg);
+
+ if (ok_to_drop_message)
+ message_free(msg);
}
- else
- {
- gettimeofday (&expiration, 0);
-
- /*
- * XXX Calculate from round trip timings and a backoff func.
- */
- expiry = msg->xmits * 2 + 5;
- expiration.tv_sec += expiry;
- LOG_DBG ((LOG_TRANSPORT, 30,
- "transport_send_messages: message %p "
- "scheduled for retransmission %d in %d secs",
- msg, msg->xmits, expiry));
- if (msg->retrans)
- timer_remove_event (msg->retrans);
- msg->retrans
- = timer_add_event ("message_send_expire",
- (void (*) (void *))message_send_expire,
- msg, &expiration);
- /* If we cannot retransmit, we cannot... */
- exchange->last_sent = msg->retrans ? msg : 0;
- }
- }
- else
- exchange->last_sent = exchange->last_received ? msg : 0;
-
- /*
- * If this message is not referred to for later retransmission
- * it will be ok for us to drop it after the post-send function.
- * But as the post-send function may remove the exchange, we need
- * to remember this fact here.
- */
- ok_to_drop_message = exchange->last_sent == 0;
-
- /*
- * If this is not a retransmit call post-send functions that allows
- * parallel work to be done while the network and peer does their
- * share of the job. Note that a post-send function may take
- * away the exchange we belong to, but only if no retransmits
- * are possible.
- */
- if (msg->xmits == 1)
- message_post_send (msg);
-
- if (ok_to_drop_message)
- message_free (msg);
}
- }
- for (t = LIST_FIRST (&transport_list); t; t = next)
- {
- next = LIST_NEXT (t, link);
- transport_release (t);
- }
+ for (t = LIST_FIRST(&transport_list); t; t = next) {
+ next = LIST_NEXT(t, link);
+ transport_release(t);
+ }
}
/*
@@ -373,13 +366,13 @@ transport_send_messages (fd_set *fds)
* specific string format.
*/
struct transport *
-transport_create (char *name, char *addr)
+transport_create(char *name, char *addr)
{
- struct transport_vtbl *method;
+ struct transport_vtbl *method;
- for (method = LIST_FIRST (&transport_method_list); method;
- method = LIST_NEXT (method, link))
- if (strcmp (method->name, name) == 0)
- return (*method->create) (addr);
- return 0;
+ for (method = LIST_FIRST(&transport_method_list); method;
+ method = LIST_NEXT(method, link))
+ if (strcmp(method->name, name) == 0)
+ return (*method->create) (addr);
+ return 0;
}
diff --git a/sbin/isakmpd/transport.h b/sbin/isakmpd/transport.h
index d7f25b5013c..809dea118ca 100644
--- a/sbin/isakmpd/transport.h
+++ b/sbin/isakmpd/transport.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: transport.h,v 1.13 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: transport.h,v 1.16 2000/07/17 18:57:59 provos Exp $ */
+/* $OpenBSD: transport.h,v 1.14 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: transport.h,v 1.16 2000/07/17 18:57:59 provos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -49,79 +49,79 @@ struct transport;
/* This describes a tranport "method" like UDP or similar. */
struct transport_vtbl {
- /* All transport methods are linked together. */
- LIST_ENTRY (transport_vtbl) link;
+ /* All transport methods are linked together. */
+ LIST_ENTRY(transport_vtbl) link;
- /* A textual name of the transport method. */
- char *name;
+ /* A textual name of the transport method. */
+ char *name;
- /* Create a transport instance of this method. */
- struct transport *(*create) (char *);
+ /* Create a transport instance of this method. */
+ struct transport *(*create) (char *);
- /* Reinitialize specific transport. */
- void (*reinit) (void);
+ /* Reinitialize specific transport. */
+ void (*reinit) (void);
- /* Remove a transport instance of this method. */
- void (*remove) (struct transport *);
+ /* Remove a transport instance of this method. */
+ void (*remove) (struct transport *);
- /* Report status of given transport */
- void (*report) (struct transport *);
+ /* Report status of given transport */
+ void (*report) (struct transport *);
- /* Let the given transport set it's bit in the fd_set passed in. */
- int (*fd_set) (struct transport *, fd_set *, int);
+ /* Let the given transport set it's bit in the fd_set passed in. */
+ int (*fd_set) (struct transport *, fd_set *, int);
- /* Is the given transport ready for I/O? */
- int (*fd_isset) (struct transport *, fd_set *);
+ /* Is the given transport ready for I/O? */
+ int (*fd_isset) (struct transport *, fd_set *);
- /*
- * Read a message from the transport's incoming pipe and start
- * handling it.
- */
- void (*handle_message) (struct transport *);
+ /*
+ * Read a message from the transport's incoming pipe and start
+ * handling it.
+ */
+ void (*handle_message) (struct transport *);
- /* Send a message through the outgoing pipe. */
- int (*send_message) (struct message *);
+ /* Send a message through the outgoing pipe. */
+ int (*send_message) (struct message *);
- /*
- * Fill out a sockaddr structure with the transport's destination end's
- * address info.
- */
- void (*get_dst) (struct transport *, struct sockaddr **);
+ /*
+ * Fill out a sockaddr structure with the transport's destination end's
+ * address info.
+ */
+ void (*get_dst) (struct transport *, struct sockaddr **);
- /*
- * Fill out a sockaddr structure with the transport's source end's
- * address info.
- */
- void (*get_src) (struct transport *, struct sockaddr **);
+ /*
+ * Fill out a sockaddr structure with the transport's source end's
+ * address info.
+ */
+ void (*get_src) (struct transport *, struct sockaddr **);
- /*
- * Return a string with decoded src and dst information
- */
- char *(*decode_ids) (struct transport *);
+ /*
+ * Return a string with decoded src and dst information
+ */
+ char *(*decode_ids) (struct transport *);
};
struct transport {
- /* All transports used are linked together. */
- LIST_ENTRY (transport) link;
+ /* All transports used are linked together. */
+ LIST_ENTRY(transport) link;
- /* What transport method is this an instance of? */
- struct transport_vtbl *vtbl;
+ /* What transport method is this an instance of? */
+ struct transport_vtbl *vtbl;
- /* The queue holding messages to send on this transport. */
- struct msg_head sendq;
+ /* The queue holding messages to send on this transport. */
+ struct msg_head sendq;
- /*
- * Prioritized send queue. Messages in this queue will be transmitted
- * before the normal sendq, they will also all be transmitted prior
- * to a daemon shutdown. Currently only used for DELETE notifications.
- */
- struct msg_head prio_sendq;
+ /*
+ * Prioritized send queue. Messages in this queue will be transmitted
+ * before the normal sendq, they will also all be transmitted prior
+ * to a daemon shutdown. Currently only used for DELETE notifications.
+ */
+ struct msg_head prio_sendq;
- /* Flags describing the transport. */
- int flags;
+ /* Flags describing the transport. */
+ int flags;
- /* References counter. */
- int refcnt;
+ /* References counter. */
+ int refcnt;
};
/* Set if this is a transport we want to listen on. */
@@ -129,18 +129,18 @@ struct transport {
/* Used for mark-and-sweep-type garbage collection of transports */
#define TRANSPORT_MARK 2
-extern void transport_add (struct transport *);
-extern struct transport *transport_create (char *, char *);
-extern int transport_fd_set (fd_set *);
-extern void transport_handle_messages (fd_set *);
-extern void transport_init (void);
-extern void transport_map (void (*) (struct transport *));
-extern void transport_method_add (struct transport_vtbl *);
-extern int transport_pending_wfd_set (fd_set *);
-extern void transport_reference (struct transport *);
-extern void transport_release (struct transport *);
-extern void transport_report (void);
-extern void transport_send_messages (fd_set *);
-extern void transport_reinit (void);
-extern int transport_prio_sendqs_empty (void);
-#endif /* _TRANSPORT_H_ */
+extern void transport_add(struct transport *);
+extern struct transport *transport_create(char *, char *);
+extern int transport_fd_set(fd_set *);
+extern void transport_handle_messages(fd_set *);
+extern void transport_init(void);
+extern void transport_map(void (*) (struct transport *));
+extern void transport_method_add(struct transport_vtbl *);
+extern int transport_pending_wfd_set(fd_set *);
+extern void transport_reference(struct transport *);
+extern void transport_release(struct transport *);
+extern void transport_report(void);
+extern void transport_send_messages(fd_set *);
+extern void transport_reinit(void);
+extern int transport_prio_sendqs_empty(void);
+#endif /* _TRANSPORT_H_ */
diff --git a/sbin/isakmpd/udp.c b/sbin/isakmpd/udp.c
index afc63cba16b..f695dd58fa5 100644
--- a/sbin/isakmpd/udp.c
+++ b/sbin/isakmpd/udp.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: udp.c,v 1.68 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: udp.c,v 1.57 2001/01/26 10:09:57 niklas Exp $ */
+/* $OpenBSD: udp.c,v 1.69 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: udp.c,v 1.57 2001/01/26 10:09:57 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -62,204 +62,189 @@
#define UDP_SIZE 65536
-/* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do. */
+/* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do. */
#ifndef SO_REUSEPORT
#define SO_REUSEPORT SO_REUSEADDR
#endif
struct udp_transport {
- struct transport transport;
- struct sockaddr *src;
- struct sockaddr *dst;
- int s;
- LIST_ENTRY (udp_transport) link;
+ struct transport transport;
+ struct sockaddr *src, *dst;
+ int s;
+ LIST_ENTRY(udp_transport) link;
};
-static struct transport *udp_clone (struct udp_transport *, struct sockaddr *);
-static struct transport *udp_create (char *);
-static void udp_reinit (void);
-static void udp_remove (struct transport *);
-static void udp_report (struct transport *);
-static int udp_fd_set (struct transport *, fd_set *, int);
-static int udp_fd_isset (struct transport *, fd_set *);
-static void udp_handle_message (struct transport *);
-static struct transport *udp_make (struct sockaddr *);
-static int udp_send_message (struct message *);
-static void udp_get_dst (struct transport *, struct sockaddr **);
-static void udp_get_src (struct transport *, struct sockaddr **);
-static char *udp_decode_ids (struct transport *);
+static struct transport *udp_clone(struct udp_transport *, struct sockaddr *);
+static struct transport *udp_create(char *);
+static void udp_reinit(void);
+static void udp_remove(struct transport *);
+static void udp_report(struct transport *);
+static int udp_fd_set(struct transport *, fd_set *, int);
+static int udp_fd_isset(struct transport *, fd_set *);
+static void udp_handle_message(struct transport *);
+static struct transport *udp_make(struct sockaddr *);
+static int udp_send_message(struct message *);
+static void udp_get_dst(struct transport *, struct sockaddr **);
+static void udp_get_src(struct transport *, struct sockaddr **);
+static char *udp_decode_ids(struct transport *);
#if 0
-static in_port_t udp_decode_port (char *);
+static in_port_t udp_decode_port(char *);
#endif
static struct transport_vtbl udp_transport_vtbl = {
- { 0 }, "udp",
- udp_create,
- udp_reinit,
- udp_remove,
- udp_report,
- udp_fd_set,
- udp_fd_isset,
- udp_handle_message,
- udp_send_message,
- udp_get_dst,
- udp_get_src,
- udp_decode_ids
+ {0}, "udp",
+ udp_create,
+ udp_reinit,
+ udp_remove,
+ udp_report,
+ udp_fd_set,
+ udp_fd_isset,
+ udp_handle_message,
+ udp_send_message,
+ udp_get_dst,
+ udp_get_src,
+ udp_decode_ids
};
/* A list of UDP transports we listen for messages on. */
-static LIST_HEAD (udp_listen_list, udp_transport) udp_listen_list;
+static
+LIST_HEAD(udp_listen_list, udp_transport) udp_listen_list;
-char *udp_default_port = 0;
-char *udp_bind_port = 0;
-int bind_family = 0;
static struct transport *default_transport, *default_transport6;
+char *udp_default_port = 0;
+char *udp_bind_port = 0;
+int bind_family = 0;
/* Find an UDP transport listening on ADDR:PORT. */
static struct udp_transport *
-udp_listen_lookup (struct sockaddr *addr)
+udp_listen_lookup(struct sockaddr *addr)
{
- struct udp_transport *u;
+ struct udp_transport *u;
- for (u = LIST_FIRST (&udp_listen_list); u; u = LIST_NEXT (u, link))
- if (sysdep_sa_len (u->src) == sysdep_sa_len (addr)
- && memcmp (u->src, addr, sysdep_sa_len (addr)) == 0)
- return u;
- return 0;
+ for (u = LIST_FIRST(&udp_listen_list); u; u = LIST_NEXT(u, link))
+ if (sysdep_sa_len(u->src) == sysdep_sa_len(addr) &&
+ memcmp(u->src, addr, sysdep_sa_len(addr)) == 0)
+ return u;
+ return 0;
}
/* Create a UDP transport structure bound to LADDR just for listening. */
static struct transport *
-udp_make (struct sockaddr *laddr)
+udp_make(struct sockaddr *laddr)
{
- struct udp_transport *t = 0;
- int s, on, wildcardaddress = 0;
-
- t = calloc (1, sizeof *t);
- if (!t)
- {
- log_print ("udp_make: malloc (%lu) failed", (unsigned long)sizeof *t);
- return 0;
- }
-
- s = monitor_socket (laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
- if (s == -1)
- {
- log_error ("udp_make: socket (%d, %d, %d)", laddr->sa_family, SOCK_DGRAM,
- IPPROTO_UDP);
- goto err;
- }
-
- /* Make sure we don't get our traffic encrypted. */
- if (sysdep_cleartext (s, laddr->sa_family) == -1)
- goto err;
-
- /* Wildcard address ? */
- switch (laddr->sa_family)
- {
- case AF_INET:
- if (((struct sockaddr_in *)laddr)->sin_addr.s_addr == INADDR_ANY)
- wildcardaddress = 1;
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)laddr)->sin6_addr))
- wildcardaddress = 1;
- break;
- }
-
- /*
- * In order to have several bound specific address-port combinations
- * with the same port SO_REUSEADDR is needed.
- * If this is a wildcard socket and we are not listening there, but only
- * sending from it make sure it is entirely reuseable with SO_REUSEPORT.
- */
- on = 1;
- if (monitor_setsockopt (s, SOL_SOCKET,
- wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR,
- (void *)&on, sizeof on) == -1)
- {
- log_error ("udp_make: setsockopt (%d, %d, %d, %p, %lu)", s, SOL_SOCKET,
- wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR,
- &on, (unsigned long)sizeof on);
- goto err;
- }
-
- t->transport.vtbl = &udp_transport_vtbl;
- t->src = laddr;
- if (monitor_bind (s, t->src, sysdep_sa_len (t->src)))
- {
- char *tstr;
- if (sockaddr2text (t->src, &tstr, 0))
- log_error ("udp_make: bind (%d, %p, %lu)", s, &t->src,
- (unsigned long)sizeof t->src);
- else
- {
- log_error ("udp_make: bind (%d, %s, %lu)", s, tstr,
- (unsigned long)sizeof t->src);
- free (tstr);
- }
- goto err;
- }
-
- t->s = s;
- transport_add (&t->transport);
- transport_reference (&t->transport);
- t->transport.flags |= TRANSPORT_LISTEN;
- return &t->transport;
+ struct udp_transport *t = 0;
+ int s, on, wildcardaddress = 0;
+
+ t = calloc(1, sizeof *t);
+ if (!t) {
+ log_print("udp_make: malloc (%lu) failed", (unsigned long) sizeof *t);
+ return 0;
+ }
+ s = monitor_socket(laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+ if (s == -1) {
+ log_error("udp_make: socket (%d, %d, %d)", laddr->sa_family,
+ SOCK_DGRAM, IPPROTO_UDP);
+ goto err;
+ }
+ /* Make sure we don't get our traffic encrypted. */
+ if (sysdep_cleartext(s, laddr->sa_family) == -1)
+ goto err;
+
+ /* Wildcard address ? */
+ switch (laddr->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *) laddr)->sin_addr.s_addr == INADDR_ANY)
+ wildcardaddress = 1;
+ break;
+ case AF_INET6:
+ if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *) laddr)->sin6_addr))
+ wildcardaddress = 1;
+ break;
+ }
+
+ /*
+ * In order to have several bound specific address-port combinations
+ * with the same port SO_REUSEADDR is needed.
+ * If this is a wildcard socket and we are not listening there, but only
+ * sending from it make sure it is entirely reuseable with SO_REUSEPORT.
+ */
+ on = 1;
+ if (monitor_setsockopt(s, SOL_SOCKET,
+ wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR,
+ (void *) &on, sizeof on) == -1) {
+ log_error("udp_make: setsockopt (%d, %d, %d, %p, %lu)", s, SOL_SOCKET,
+ wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR,
+ &on, (unsigned long) sizeof on);
+ goto err;
+ }
+ t->transport.vtbl = &udp_transport_vtbl;
+ t->src = laddr;
+ if (monitor_bind(s, t->src, sysdep_sa_len(t->src))) {
+ char *tstr;
+
+ if (sockaddr2text(t->src, &tstr, 0))
+ log_error("udp_make: bind (%d, %p, %lu)", s, &t->src,
+ (unsigned long) sizeof t->src);
+ else {
+ log_error("udp_make: bind (%d, %s, %lu)", s, tstr,
+ (unsigned long) sizeof t->src);
+ free(tstr);
+ }
+ goto err;
+ }
+ t->s = s;
+ transport_add(&t->transport);
+ transport_reference(&t->transport);
+ t->transport.flags |= TRANSPORT_LISTEN;
+ return &t->transport;
err:
- if (s >= 0)
- close (s);
- if (t)
- {
- /* Already closed. */
- t->s = -1;
- udp_remove (&t->transport);
- }
- return 0;
+ if (s >= 0)
+ close(s);
+ if (t) {
+ /* Already closed. */
+ t->s = -1;
+ udp_remove(&t->transport);
+ }
+ return 0;
}
/* Clone a listen transport U, record a destination RADDR for outbound use. */
static struct transport *
-udp_clone (struct udp_transport *u, struct sockaddr *raddr)
+udp_clone(struct udp_transport *u, struct sockaddr *raddr)
{
- struct transport *t;
- struct udp_transport *u2;
-
- t = malloc (sizeof *u);
- if (!t)
- {
- log_error ("udp_clone: malloc (%lu) failed", (unsigned long)sizeof *u);
- return 0;
- }
- u2 = (struct udp_transport *)t;
-
- memcpy (u2, u, sizeof *u);
-
- u2->src = malloc (sysdep_sa_len (u->src));
- if (!u2->src)
- {
- log_error ("udp_clone: malloc (%d) failed", sysdep_sa_len (u->src));
- free (t);
- return 0;
- }
- memcpy (u2->src, u->src, sysdep_sa_len (u->src));
-
- u2->dst = malloc (sysdep_sa_len (raddr));
- if (!u2->dst)
- {
- log_error ("udp_clone: malloc (%d) failed", sysdep_sa_len (raddr));
- free (u2->src);
- free (t);
- return 0;
- }
- memcpy (u2->dst, raddr, sysdep_sa_len (raddr));
-
- t->flags &= ~TRANSPORT_LISTEN;
-
- transport_add (t);
-
- return t;
+ struct udp_transport *u2;
+ struct transport *t;
+
+ t = malloc(sizeof *u);
+ if (!t) {
+ log_error("udp_clone: malloc (%lu) failed", (unsigned long) sizeof *u);
+ return 0;
+ }
+ u2 = (struct udp_transport *) t;
+
+ memcpy(u2, u, sizeof *u);
+
+ u2->src = malloc(sysdep_sa_len(u->src));
+ if (!u2->src) {
+ log_error("udp_clone: malloc (%d) failed", sysdep_sa_len(u->src));
+ free(t);
+ return 0;
+ }
+ memcpy(u2->src, u->src, sysdep_sa_len(u->src));
+
+ u2->dst = malloc(sysdep_sa_len(raddr));
+ if (!u2->dst) {
+ log_error("udp_clone: malloc (%d) failed", sysdep_sa_len(raddr));
+ free(u2->src);
+ free(t);
+ return 0;
+ }
+ memcpy(u2->dst, raddr, sysdep_sa_len(raddr));
+
+ t->flags &= ~TRANSPORT_LISTEN;
+ transport_add(t);
+ return t;
}
/*
@@ -269,15 +254,15 @@ udp_clone (struct udp_transport *u, struct sockaddr *raddr)
* system-wide pools of known ISAKMP transports.
*/
static struct transport *
-udp_bind (const struct sockaddr *addr)
+udp_bind(const struct sockaddr *addr)
{
- struct sockaddr *src = malloc (sysdep_sa_len ((struct sockaddr *)addr));
+ struct sockaddr *src = malloc(sysdep_sa_len((struct sockaddr *) addr));
- if (!src)
- return 0;
+ if (!src)
+ return 0;
- memcpy (src, addr, sysdep_sa_len ((struct sockaddr *)addr));
- return udp_make (src);
+ memcpy(src, addr, sysdep_sa_len((struct sockaddr *) addr));
+ return udp_make(src);
}
/*
@@ -286,179 +271,162 @@ udp_bind (const struct sockaddr *addr)
* Return 0 if successful, -1 otherwise.
*/
static int
-udp_bind_if (char *ifname, struct sockaddr *if_addr, void *arg)
+udp_bind_if(char *ifname, struct sockaddr *if_addr, void *arg)
{
- char *port = (char *)arg;
- struct sockaddr_storage saddr_st;
- struct sockaddr *saddr = (struct sockaddr *)&saddr_st;
- struct conf_list *listen_on;
- struct udp_transport *u;
- struct conf_list_node *address;
- struct sockaddr *addr;
- struct transport *t;
- struct ifreq flags_ifr;
- char *addr_str, *ep;
- int s, error;
- long lport;
-
- /*
- * Well, UDP is an internet protocol after all so drop other ifreqs.
- */
- if ((if_addr->sa_family != AF_INET
- || sysdep_sa_len (if_addr) != sizeof (struct sockaddr_in))
- && (if_addr->sa_family != AF_INET6
- || sysdep_sa_len (if_addr) != sizeof (struct sockaddr_in6)))
- return 0;
-
- /*
- * Only create sockets for families we should listen to.
- */
- if (bind_family)
- switch (if_addr->sa_family)
- {
- case AF_INET:
- if ((bind_family & BIND_FAMILY_INET4) == 0)
- return 0;
- break;
- case AF_INET6:
- if ((bind_family & BIND_FAMILY_INET6) == 0)
- return 0;
- break;
- default:
- return 0;
- }
-
- /*
- * These special addresses are not useable as they have special meaning
- * in the IP stack.
- */
- if (if_addr->sa_family == AF_INET
- && (((struct sockaddr_in *)if_addr)->sin_addr.s_addr == INADDR_ANY
- || (((struct sockaddr_in *)if_addr)->sin_addr.s_addr
- == INADDR_NONE)) )
- return 0;
-
- /*
- * Go through the list of transports and see if we already have this
- * address bound. If so, unmark the transport and skip it; this allows
- * us to call this function when we suspect a new address has appeared.
- */
- if (sysdep_sa_len (if_addr) > sizeof saddr_st)
- return 0;
- memcpy (saddr, if_addr, sysdep_sa_len (if_addr));
- switch (saddr->sa_family) /* Add the port number to the sockaddr. */
- {
- case AF_INET:
- ((struct sockaddr_in *)saddr)->sin_port
- = htons (strtol (port, &ep, 10));
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)saddr)->sin6_port
- = htons (strtol (port, &ep, 10));
- break;
- }
-
- if ((u = udp_listen_lookup (saddr)) != 0)
- {
- u->transport.flags &= ~TRANSPORT_MARK;
- return 0;
- }
-
- /* Don't bother with interfaces that are down. */
- s = monitor_socket (if_addr->sa_family, SOCK_DGRAM, 0);
- if (s == -1)
- {
- log_error ("udp_bind_if: socket (%d, SOCK_DGRAM, 0) failed",
- if_addr->sa_family);
- return -1;
- }
- strlcpy (flags_ifr.ifr_name, ifname, sizeof flags_ifr.ifr_name);
- if (ioctl (s, SIOCGIFFLAGS, (caddr_t)&flags_ifr) == -1)
- {
- log_error ("udp_bind_if: ioctl (%d, SIOCGIFFLAGS, ...) failed", s);
- return -1;
- }
- close (s);
- if (!(flags_ifr.ifr_flags & IFF_UP))
- return 0;
-
- /*
- * Set port.
- * XXX Use getservbyname too.
- */
- lport = strtol (port, &ep, 10);
- if (*ep != '\0' || lport < (long)0 || lport > (long)USHRT_MAX)
- {
- log_print ("udp_bind_if: "
- "port string \"%s\" not convertible to in_port_t", port);
- return -1;
- }
-
- switch (if_addr->sa_family)
- {
- case AF_INET:
- ((struct sockaddr_in *)if_addr)->sin_port = htons (lport);
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)if_addr)->sin6_port = htons (lport);
- break;
- default:
- log_print ("udp_bind_if: unsupported protocol family %d",
- if_addr->sa_family);
- break;
- }
-
- /*
- * If we are explicit about what addresses we can listen to, be sure
- * to respect that option.
- * This is quite wasteful redoing the list-run for every interface,
- * but who cares? This is not an operation that needs to be fast.
- */
- listen_on = conf_get_list ("General", "Listen-on");
- if (listen_on)
- {
- for (address = TAILQ_FIRST (&listen_on->fields); address;
- address = TAILQ_NEXT (address, link))
- {
- if (text2sockaddr (address->field, port, &addr))
- {
- log_print ("udp_bind_if: invalid address %s in \"Listen-on\"",
- address->field);
- continue;
- }
-
- /* If found, take the easy way out. */
- if (memcmp (addr, if_addr, sysdep_sa_len (addr)) == 0)
- {
- free (addr);
- break;
- }
- free (addr);
- }
- conf_free_list (listen_on);
-
- /*
- * If address is zero then we did not find the address among the ones
- * we should listen to.
- * XXX We do not discover if we do not find our listen addresses...
- * Maybe this should be the other way round.
- */
- if (!address)
+ char *port = (char *) arg, *addr_str, *ep;
+ struct sockaddr_storage saddr_st;
+ struct sockaddr *saddr = (struct sockaddr *) & saddr_st;
+ struct conf_list *listen_on;
+ struct udp_transport *u;
+ struct conf_list_node *address;
+ struct sockaddr *addr;
+ struct transport *t;
+ struct ifreq flags_ifr;
+ int s, error;
+ long lport;
+
+ /*
+ * Well, UDP is an internet protocol after all so drop other ifreqs.
+ */
+ if ((if_addr->sa_family != AF_INET ||
+ sysdep_sa_len(if_addr) != sizeof(struct sockaddr_in)) &&
+ (if_addr->sa_family != AF_INET6 ||
+ sysdep_sa_len(if_addr) != sizeof(struct sockaddr_in6)))
+ return 0;
+
+ /*
+ * Only create sockets for families we should listen to.
+ */
+ if (bind_family) {
+ switch (if_addr->sa_family) {
+ case AF_INET:
+ if ((bind_family & BIND_FAMILY_INET4) == 0)
+ return 0;
+ break;
+ case AF_INET6:
+ if ((bind_family & BIND_FAMILY_INET6) == 0)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ /*
+ * These special addresses are not useable as they have special meaning
+ * in the IP stack.
+ */
+ if (if_addr->sa_family == AF_INET &&
+ (((struct sockaddr_in *) if_addr)->sin_addr.s_addr == INADDR_ANY ||
+ (((struct sockaddr_in *) if_addr)->sin_addr.s_addr == INADDR_NONE)))
+ return 0;
+
+ /*
+ * Go through the list of transports and see if we already have this
+ * address bound. If so, unmark the transport and skip it; this allows
+ * us to call this function when we suspect a new address has appeared.
+ */
+ if (sysdep_sa_len(if_addr) > sizeof saddr_st)
+ return 0;
+ memcpy(saddr, if_addr, sysdep_sa_len(if_addr));
+ switch (saddr->sa_family) { /* Add the port number to the sockaddr. */
+ case AF_INET:
+ ((struct sockaddr_in *) saddr)->sin_port =
+ htons(strtol(port, &ep, 10));
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) saddr)->sin6_port =
+ htons(strtol(port, &ep, 10));
+ break;
+ }
+
+ if ((u = udp_listen_lookup(saddr)) != 0) {
+ u->transport.flags &= ~TRANSPORT_MARK;
+ return 0;
+ }
+ /* Don't bother with interfaces that are down. */
+ s = monitor_socket(if_addr->sa_family, SOCK_DGRAM, 0);
+ if (s == -1) {
+ log_error("udp_bind_if: socket (%d, SOCK_DGRAM, 0) failed",
+ if_addr->sa_family);
+ return -1;
+ }
+ strlcpy(flags_ifr.ifr_name, ifname, sizeof flags_ifr.ifr_name);
+ if (ioctl(s, SIOCGIFFLAGS, (caddr_t) & flags_ifr) == -1) {
+ log_error("udp_bind_if: ioctl (%d, SIOCGIFFLAGS, ...) failed", s);
+ return -1;
+ }
+ close(s);
+ if (!(flags_ifr.ifr_flags & IFF_UP))
+ return 0;
+
+ /*
+ * Set port.
+ * XXX Use getservbyname too.
+ */
+ lport = strtol(port, &ep, 10);
+ if (*ep != '\0' || lport < (long) 0 || lport > (long) USHRT_MAX) {
+ log_print("udp_bind_if: "
+ "port string \"%s\" not convertible to in_port_t", port);
+ return -1;
+ }
+ switch (if_addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) if_addr)->sin_port = htons(lport);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) if_addr)->sin6_port = htons(lport);
+ break;
+ default:
+ log_print("udp_bind_if: unsupported protocol family %d",
+ if_addr->sa_family);
+ break;
+ }
+
+ /*
+ * If we are explicit about what addresses we can listen to, be sure
+ * to respect that option.
+ * This is quite wasteful redoing the list-run for every interface,
+ * but who cares? This is not an operation that needs to be fast.
+ */
+ listen_on = conf_get_list("General", "Listen-on");
+ if (listen_on) {
+ for (address = TAILQ_FIRST(&listen_on->fields); address;
+ address = TAILQ_NEXT(address, link)) {
+ if (text2sockaddr(address->field, port, &addr)) {
+ log_print("udp_bind_if: invalid address %s in \"Listen-on\"",
+ address->field);
+ continue;
+ }
+ /* If found, take the easy way out. */
+ if (memcmp(addr, if_addr, sysdep_sa_len(addr)) == 0) {
+ free(addr);
+ break;
+ }
+ free(addr);
+ }
+ conf_free_list(listen_on);
+
+ /*
+ * If address is zero then we did not find the address among the ones
+ * we should listen to.
+ * XXX We do not discover if we do not find our listen addresses...
+ * Maybe this should be the other way round.
+ */
+ if (!address)
+ return 0;
+ }
+ t = udp_bind(if_addr);
+ if (!t) {
+ error = sockaddr2text(if_addr, &addr_str, 0);
+ log_print("udp_bind_if: failed to create a socket on %s:%s",
+ error ? "unknown" : addr_str, port);
+ if (!error)
+ free(addr_str);
+ return -1;
+ }
+ LIST_INSERT_HEAD(&udp_listen_list, (struct udp_transport *) t, link);
return 0;
- }
-
- t = udp_bind (if_addr);
- if (!t)
- {
- error = sockaddr2text (if_addr, &addr_str, 0);
- log_print ("udp_bind_if: failed to create a socket on %s:%s",
- error ? "unknown" : addr_str, port);
- if (!error)
- free (addr_str);
- return -1;
- }
- LIST_INSERT_HEAD (&udp_listen_list, (struct udp_transport *)t, link);
- return 0;
}
/*
@@ -466,119 +434,108 @@ udp_bind_if (char *ifname, struct sockaddr *if_addr, void *arg)
* a transport useable to talk to the peer specified by that name.
*/
static struct transport *
-udp_create (char *name)
+udp_create(char *name)
{
- struct udp_transport *u;
- struct transport *rv;
- struct sockaddr *dst, *addr;
- char *addr_str, *port_str;
-
- port_str = conf_get_str (name, "Port");
- if (!port_str)
- port_str = udp_default_port;
- if (!port_str)
- port_str = "500";
-
- addr_str = conf_get_str (name, "Address");
- if (!addr_str)
- {
- log_print ("udp_create: no address configured for \"%s\"", name);
- return 0;
- }
- if (text2sockaddr (addr_str, port_str, &dst))
- {
- log_print ("udp_create: address \"%s\" not understood", addr_str);
- return 0;
- }
-
- addr_str = conf_get_str (name, "Local-address");
- if (!addr_str)
- addr_str = conf_get_str ("General", "Listen-on");
- if (!addr_str)
- {
- if ((dst->sa_family == AF_INET && !default_transport)
- || (dst->sa_family == AF_INET6 && !default_transport6))
- {
- log_print ("udp_create: no default transport");
- rv = 0;
- goto ret;
- }
- else
- {
- /* XXX Ugly! */
- rv = udp_clone ((struct udp_transport *)(dst->sa_family == AF_INET
- ? default_transport
- : default_transport6), dst);
- goto ret;
- }
- }
-
- if (text2sockaddr (addr_str, port_str, &addr))
- {
- log_print ("udp_create: address \"%s\" not understood", addr_str);
- rv = 0;
- goto ret;
- }
- u = udp_listen_lookup (addr);
- free (addr);
- if (!u)
- {
- log_print ("udp_create: %s:%s must exist as a listener too", addr_str,
- port_str);
- rv = 0;
- goto ret;
- }
- rv = udp_clone (u, dst);
-
- ret:
- free (dst);
- return rv;
+ struct udp_transport *u;
+ struct transport *rv;
+ struct sockaddr *dst, *addr;
+ char *addr_str, *port_str;
+
+ port_str = conf_get_str(name, "Port");
+ if (!port_str)
+ port_str = udp_default_port;
+ if (!port_str)
+ port_str = "500";
+
+ addr_str = conf_get_str(name, "Address");
+ if (!addr_str) {
+ log_print("udp_create: no address configured for \"%s\"", name);
+ return 0;
+ }
+ if (text2sockaddr(addr_str, port_str, &dst)) {
+ log_print("udp_create: address \"%s\" not understood", addr_str);
+ return 0;
+ }
+ addr_str = conf_get_str(name, "Local-address");
+ if (!addr_str)
+ addr_str = conf_get_str("General", "Listen-on");
+ if (!addr_str) {
+ if ((dst->sa_family == AF_INET && !default_transport) ||
+ (dst->sa_family == AF_INET6 && !default_transport6)) {
+ log_print("udp_create: no default transport");
+ rv = 0;
+ goto ret;
+ } else {
+ /* XXX Ugly! */
+ rv = udp_clone((struct udp_transport *)
+ (dst->sa_family == AF_INET ? default_transport :
+ default_transport6), dst);
+ goto ret;
+ }
+ }
+ if (text2sockaddr(addr_str, port_str, &addr)) {
+ log_print("udp_create: address \"%s\" not understood", addr_str);
+ rv = 0;
+ goto ret;
+ }
+ u = udp_listen_lookup(addr);
+ free(addr);
+ if (!u) {
+ log_print("udp_create: %s:%s must exist as a listener too", addr_str,
+ port_str);
+ rv = 0;
+ goto ret;
+ }
+ rv = udp_clone(u, dst);
+
+ret:
+ free(dst);
+ return rv;
}
void
-udp_remove (struct transport *t)
+udp_remove(struct transport * t)
{
- struct udp_transport *u = (struct udp_transport *)t;
-
- if (u->src)
- free (u->src);
- if (u->dst)
- free (u->dst);
- if (t->flags & TRANSPORT_LISTEN)
- {
- if (u->s >= 0)
- close (u->s);
- if (t == default_transport)
- default_transport = 0;
- else if (t == default_transport6)
- default_transport6 = 0;
- if (u->link.le_prev)
- LIST_REMOVE (u, link);
- }
- free (t);
+ struct udp_transport *u = (struct udp_transport *) t;
+
+ if (u->src)
+ free(u->src);
+ if (u->dst)
+ free(u->dst);
+ if (t->flags & TRANSPORT_LISTEN) {
+ if (u->s >= 0)
+ close(u->s);
+ if (t == default_transport)
+ default_transport = 0;
+ else if (t == default_transport6)
+ default_transport6 = 0;
+ if (u->link.le_prev)
+ LIST_REMOVE(u, link);
+ }
+ free(t);
}
-/* Report transport-method specifics of the T transport. */
+/* Report transport-method specifics of the T transport. */
void
-udp_report (struct transport *t)
+udp_report(struct transport * t)
{
- struct udp_transport *u = (struct udp_transport *)t;
- char *src, *dst;
+ struct udp_transport *u = (struct udp_transport *) t;
+ char *src, *dst;
- if (sockaddr2text (u->src, &src, 0))
- goto ret;
+ if (sockaddr2text(u->src, &src, 0))
+ goto ret;
- if (!u->dst || sockaddr2text (u->dst, &dst, 0))
- dst = 0;
+ if (!u->dst || sockaddr2text(u->dst, &dst, 0))
+ dst = 0;
- LOG_DBG ((LOG_REPORT, 0, "udp_report: fd %d src %s dst %s", u->s, src,
+ LOG_DBG((LOG_REPORT, 0, "udp_report: fd %d src %s dst %s", u->s, src,
dst ? dst : "<none>"));
- ret:
- if (dst)
- free (dst);
- if (src)
- free (src);
+ret:
+ if (dst)
+ free(dst);
+ if (src)
+ free(src);
}
/*
@@ -591,42 +548,39 @@ udp_report (struct transport *t)
* transports that have not been unmarked.
*/
static void
-udp_reinit (void)
+udp_reinit(void)
{
- struct udp_transport *u, *u2;
- char *port;
-
- /* Initialize the protocol and port numbers. */
- port = udp_default_port ? udp_default_port : "500";
-
- /* Mark all UDP transports, except the default ones. */
- for (u = LIST_FIRST (&udp_listen_list); u; u = LIST_NEXT (u, link))
- if (&u->transport != default_transport
- && &u->transport != default_transport6)
- u->transport.flags |= TRANSPORT_MARK;
-
- /* Re-probe interface list. */
- if (if_map (udp_bind_if, port) == -1)
- log_print ("udp_init: Could not bind the ISAKMP UDP port %s on all "
- "interfaces", port);
-
- /*
- * Release listening transports for local addresses that no
- * longer exist. udp_bind_if () will have left those still marked.
- */
- u = LIST_FIRST (&udp_listen_list);
- while (u)
- {
- u2 = LIST_NEXT (u, link);
-
- if (u->transport.flags & TRANSPORT_MARK)
- {
- LIST_REMOVE (u, link);
- transport_release (&u->transport);
- }
-
- u = u2;
- }
+ struct udp_transport *u, *u2;
+ char *port;
+
+ /* Initialize the protocol and port numbers. */
+ port = udp_default_port ? udp_default_port : "500";
+
+ /* Mark all UDP transports, except the default ones. */
+ for (u = LIST_FIRST(&udp_listen_list); u; u = LIST_NEXT(u, link))
+ if (&u->transport != default_transport &&
+ &u->transport != default_transport6)
+ u->transport.flags |= TRANSPORT_MARK;
+
+ /* Re-probe interface list. */
+ if (if_map(udp_bind_if, port) == -1)
+ log_print("udp_init: Could not bind the ISAKMP UDP port %s on all "
+ "interfaces", port);
+
+ /*
+ * Release listening transports for local addresses that no
+ * longer exist. udp_bind_if () will have left those still marked.
+ */
+ u = LIST_FIRST(&udp_listen_list);
+ while (u) {
+ u2 = LIST_NEXT(u, link);
+
+ if (u->transport.flags & TRANSPORT_MARK) {
+ LIST_REMOVE(u, link);
+ transport_release(&u->transport);
+ }
+ u = u2;
+ }
}
/*
@@ -635,93 +589,84 @@ udp_reinit (void)
* for the generic case when we are the initiator.
*/
void
-udp_init (void)
+udp_init(void)
{
- struct sockaddr_storage dflt_stor;
- struct sockaddr_in *dflt = (struct sockaddr_in *)&dflt_stor;
- struct conf_list *listen_on;
- char *port;
- long lport;
- char *ep;
-
- /* Initialize the protocol and port numbers. */
- port = udp_default_port ? udp_default_port : "500";
-
- LIST_INIT (&udp_listen_list);
-
- transport_method_add (&udp_transport_vtbl);
-
- /* Bind the ISAKMP UDP port on all network interfaces we have. */
- if (if_map (udp_bind_if, port) == -1)
- log_fatal ("udp_init: Could not bind the ISAKMP UDP port %s on all "
- "interfaces", port);
-
- /* Only listen to the specified address if Listen-on is configured */
- listen_on = conf_get_list ("General", "Listen-on");
- if (listen_on)
- {
- LOG_DBG ((LOG_TRANSPORT, 50,
- "udp_init: not binding ISAKMP UDP port to INADDR_ANY"));
- conf_free_list (listen_on);
- return;
- }
-
- /*
- * Get port.
- * XXX Use getservbyname too.
- */
- lport = strtol (port, &ep, 10);
- if (*ep != '\0' || lport < (long)0 || lport > (long)USHRT_MAX)
- {
- log_print ("udp_init: port string \"%s\" not convertible to in_port_t",
- port);
- return;
- }
-
- /*
- * Bind to INADDR_ANY in case of new addresses popping up.
- * Packet reception on this transport is taken as a hint to reprobe the
- * interface list.
- */
- if (!bind_family || (bind_family & BIND_FAMILY_INET4))
- {
- memset (&dflt_stor, 0, sizeof dflt_stor);
- dflt->sin_family = AF_INET;
+ struct sockaddr_storage dflt_stor;
+ struct sockaddr_in *dflt = (struct sockaddr_in *) & dflt_stor;
+ struct conf_list *listen_on;
+ char *port;
+ long lport;
+ char *ep;
+
+ /* Initialize the protocol and port numbers. */
+ port = udp_default_port ? udp_default_port : "500";
+
+ LIST_INIT(&udp_listen_list);
+
+ transport_method_add(&udp_transport_vtbl);
+
+ /* Bind the ISAKMP UDP port on all network interfaces we have. */
+ if (if_map(udp_bind_if, port) == -1)
+ log_fatal("udp_init: Could not bind the ISAKMP UDP port %s on all "
+ "interfaces", port);
+
+ /* Only listen to the specified address if Listen-on is configured */
+ listen_on = conf_get_list("General", "Listen-on");
+ if (listen_on) {
+ LOG_DBG((LOG_TRANSPORT, 50,
+ "udp_init: not binding ISAKMP UDP port to INADDR_ANY"));
+ conf_free_list(listen_on);
+ return;
+ }
+ /*
+ * Get port.
+ * XXX Use getservbyname too.
+ */
+ lport = strtol(port, &ep, 10);
+ if (*ep != '\0' || lport < (long) 0 || lport > (long) USHRT_MAX) {
+ log_print("udp_init: port string \"%s\" not convertible to in_port_t",
+ port);
+ return;
+ }
+ /*
+ * Bind to INADDR_ANY in case of new addresses popping up.
+ * Packet reception on this transport is taken as a hint to reprobe the
+ * interface list.
+ */
+ if (!bind_family || (bind_family & BIND_FAMILY_INET4)) {
+ memset(&dflt_stor, 0, sizeof dflt_stor);
+ dflt->sin_family = AF_INET;
#if !defined (LINUX_IPSEC)
- ((struct sockaddr_in *)dflt)->sin_len = sizeof (struct sockaddr_in);
+ ((struct sockaddr_in *) dflt)->sin_len = sizeof(struct sockaddr_in);
#endif
- ((struct sockaddr_in *)dflt)->sin_port = htons (lport);
-
- default_transport = udp_bind ((struct sockaddr *)&dflt_stor);
- if (!default_transport)
- {
- log_error ("udp_init: could not allocate default "
- "IPv4 ISAKMP UDP port");
- return;
- }
- LIST_INSERT_HEAD (&udp_listen_list,
- (struct udp_transport *)default_transport, link);
- }
-
- if (!bind_family || (bind_family & BIND_FAMILY_INET6))
- {
- memset (&dflt_stor, 0, sizeof dflt_stor);
- dflt->sin_family = AF_INET6;
+ ((struct sockaddr_in *) dflt)->sin_port = htons(lport);
+
+ default_transport = udp_bind((struct sockaddr *) & dflt_stor);
+ if (!default_transport) {
+ log_error("udp_init: could not allocate default "
+ "IPv4 ISAKMP UDP port");
+ return;
+ }
+ LIST_INSERT_HEAD(&udp_listen_list,
+ (struct udp_transport *) default_transport, link);
+ }
+ if (!bind_family || (bind_family & BIND_FAMILY_INET6)) {
+ memset(&dflt_stor, 0, sizeof dflt_stor);
+ dflt->sin_family = AF_INET6;
#if !defined (LINUX_IPSEC)
- ((struct sockaddr_in6 *)dflt)->sin6_len = sizeof (struct sockaddr_in6);
+ ((struct sockaddr_in6 *) dflt)->sin6_len = sizeof(struct sockaddr_in6);
#endif
- ((struct sockaddr_in6 *)dflt)->sin6_port = htons (lport);
-
- default_transport6 = udp_bind ((struct sockaddr *)&dflt_stor);
- if (!default_transport6)
- {
- log_error ("udp_init: could not allocate default "
- "IPv6 ISAKMP UDP port");
- return;
- }
- LIST_INSERT_HEAD (&udp_listen_list,
- (struct udp_transport *)default_transport6, link);
- }
+ ((struct sockaddr_in6 *) dflt)->sin6_port = htons(lport);
+
+ default_transport6 = udp_bind((struct sockaddr *) & dflt_stor);
+ if (!default_transport6) {
+ log_error("udp_init: could not allocate default "
+ "IPv6 ISAKMP UDP port");
+ return;
+ }
+ LIST_INSERT_HEAD(&udp_listen_list,
+ (struct udp_transport *) default_transport6, link);
+ }
}
/*
@@ -729,25 +674,25 @@ udp_init (void)
* as the number of file descriptors to check.
*/
static int
-udp_fd_set (struct transport *t, fd_set *fds, int bit)
+udp_fd_set(struct transport * t, fd_set * fds, int bit)
{
- struct udp_transport *u = (struct udp_transport *)t;
+ struct udp_transport *u = (struct udp_transport *) t;
- if (bit)
- FD_SET (u->s, fds);
- else
- FD_CLR (u->s, fds);
+ if (bit)
+ FD_SET(u->s, fds);
+ else
+ FD_CLR(u->s, fds);
- return u->s + 1;
+ return u->s + 1;
}
/* Check if transport T's socket is set in FDS. */
static int
-udp_fd_isset (struct transport *t, fd_set *fds)
+udp_fd_isset(struct transport * t, fd_set * fds)
{
- struct udp_transport *u = (struct udp_transport *)t;
+ struct udp_transport *u = (struct udp_transport *) t;
- return FD_ISSET (u->s, fds);
+ return FD_ISSET(u->s, fds);
}
/*
@@ -757,84 +702,78 @@ udp_fd_isset (struct transport *t, fd_set *fds)
* module.
*/
static void
-udp_handle_message (struct transport *t)
+udp_handle_message(struct transport * t)
{
- struct udp_transport *u = (struct udp_transport *)t;
- u_int8_t buf[UDP_SIZE];
- struct sockaddr_storage from;
- u_int32_t len = sizeof from;
- ssize_t n;
- struct message *msg;
-
- n = recvfrom (u->s, buf, UDP_SIZE, 0, (struct sockaddr *)&from, &len);
- if (n == -1)
- {
- log_error ("recvfrom (%d, %p, %d, %d, %p, %p)", u->s, buf, UDP_SIZE, 0,
- &from, &len);
- return;
- }
-
- /*
- * If we received the packet over the default transports, reprobe the
- * interfaces.
- */
- if (t == default_transport || t == default_transport6)
- {
- udp_reinit ();
-
- /*
- * As we don't know the actual destination address of the packet,
- * we can't really deal with it. So, just ignore it and hope we
- * catch the retransmission.
- */
- return;
- }
-
- /*
- * Make a specialized UDP transport structure out of the incoming
- * transport and the address information we got from recvfrom(2).
- */
- t = udp_clone (u, (struct sockaddr *)&from);
- if (!t)
- return;
-
- msg = message_alloc (t, buf, n);
- if (!msg)
- {
- log_error ("failed to allocate message structure, dropping packet "
- "received on transport %p", u);
- return;
- }
- message_recv (msg);
+ struct udp_transport *u = (struct udp_transport *) t;
+ u_int8_t buf[UDP_SIZE];
+ struct sockaddr_storage from;
+ u_int32_t len = sizeof from;
+ ssize_t n;
+ struct message *msg;
+
+ n = recvfrom(u->s, buf, UDP_SIZE, 0, (struct sockaddr *) & from, &len);
+ if (n == -1) {
+ log_error("recvfrom (%d, %p, %d, %d, %p, %p)", u->s, buf, UDP_SIZE, 0,
+ &from, &len);
+ return;
+ }
+ /*
+ * If we received the packet over the default transports, reprobe the
+ * interfaces.
+ */
+ if (t == default_transport || t == default_transport6) {
+ udp_reinit();
+
+ /*
+ * As we don't know the actual destination address of the packet,
+ * we can't really deal with it. So, just ignore it and hope we
+ * catch the retransmission.
+ */
+ return;
+ }
+ /*
+ * Make a specialized UDP transport structure out of the incoming
+ * transport and the address information we got from recvfrom(2).
+ */
+ t = udp_clone(u, (struct sockaddr *) & from);
+ if (!t)
+ return;
+
+ msg = message_alloc(t, buf, n);
+ if (!msg) {
+ log_error("failed to allocate message structure, dropping packet "
+ "received on transport %p", u);
+ return;
+ }
+ message_recv(msg);
}
/* Physically send the message MSG over its associated transport. */
static int
-udp_send_message (struct message *msg)
+udp_send_message(struct message * msg)
{
- struct udp_transport *u = (struct udp_transport *)msg->transport;
- ssize_t n;
- struct msghdr m;
-
- /*
- * Sending on connected sockets requires that no destination address is
- * given, or else EISCONN will occur.
- */
- m.msg_name = (caddr_t)u->dst;
- m.msg_namelen = sysdep_sa_len (u->dst);
- m.msg_iov = msg->iov;
- m.msg_iovlen = msg->iovlen;
- m.msg_control = 0;
- m.msg_controllen = 0;
- m.msg_flags = 0;
- n = sendmsg (u->s, &m, 0);
- if (n == -1)
- {
- /* XXX We should check whether the address has gone away */
- log_error ("sendmsg (%d, %p, %d)", u->s, &m, 0);
- return -1;
- }
- return 0;
+ struct udp_transport *u = (struct udp_transport *) msg->transport;
+ ssize_t n;
+ struct msghdr m;
+
+ /*
+ * Sending on connected sockets requires that no destination address is
+ * given, or else EISCONN will occur.
+ */
+ m.msg_name = (caddr_t) u->dst;
+ m.msg_namelen = sysdep_sa_len(u->dst);
+ m.msg_iov = msg->iov;
+ m.msg_iovlen = msg->iovlen;
+ m.msg_control = 0;
+ m.msg_controllen = 0;
+ m.msg_flags = 0;
+ n = sendmsg(u->s, &m, 0);
+ if (n == -1) {
+ /* XXX We should check whether the address has gone away */
+ log_error("sendmsg (%d, %p, %d)", u->s, &m, 0);
+ return -1;
+ }
+ return 0;
}
/*
@@ -842,9 +781,9 @@ udp_send_message (struct message *msg)
* to by DST.
*/
static void
-udp_get_dst (struct transport *t, struct sockaddr **dst)
+udp_get_dst(struct transport * t, struct sockaddr ** dst)
{
- *dst = ((struct udp_transport *)t)->dst;
+ *dst = ((struct udp_transport *) t)->dst;
}
/*
@@ -852,41 +791,37 @@ udp_get_dst (struct transport *t, struct sockaddr **dst)
* to by SRC. Put its length into SRC_LEN.
*/
static void
-udp_get_src (struct transport *t, struct sockaddr **src)
+udp_get_src(struct transport * t, struct sockaddr ** src)
{
- *src = ((struct udp_transport *)t)->src;
+ *src = ((struct udp_transport *) t)->src;
}
static char *
-udp_decode_ids (struct transport *t)
+udp_decode_ids(struct transport * t)
{
- static char result[1024];
- char idsrc[256], iddst[256];
+ static char result[1024];
+ char idsrc[256], iddst[256];
#ifdef HAVE_GETNAMEINFO
- if (getnameinfo (((struct udp_transport *)t)->src,
- sysdep_sa_len (((struct udp_transport *)t)->src),
- idsrc, sizeof idsrc, NULL, 0, NI_NUMERICHOST) != 0)
- {
- log_print ("udp_decode_ids: getnameinfo () failed for 'src'");
- strlcpy (idsrc, "<error>", 256);
- }
-
- if (getnameinfo (((struct udp_transport *)t)->dst,
- sysdep_sa_len (((struct udp_transport *)t)->dst),
- iddst, sizeof iddst, NULL, 0, NI_NUMERICHOST) != 0)
- {
- log_print ("udp_decode_ids: getnameinfo () failed for 'dst'");
- strlcpy (iddst, "<error>", 256);
- }
+ if (getnameinfo(((struct udp_transport *) t)->src,
+ sysdep_sa_len(((struct udp_transport *) t)->src),
+ idsrc, sizeof idsrc, NULL, 0, NI_NUMERICHOST) != 0) {
+ log_print("udp_decode_ids: getnameinfo () failed for 'src'");
+ strlcpy(idsrc, "<error>", 256);
+ }
+ if (getnameinfo(((struct udp_transport *) t)->dst,
+ sysdep_sa_len(((struct udp_transport *) t)->dst),
+ iddst, sizeof iddst, NULL, 0, NI_NUMERICHOST) != 0) {
+ log_print("udp_decode_ids: getnameinfo () failed for 'dst'");
+ strlcpy(iddst, "<error>", 256);
+ }
#else
- strlcpy (idsrc, inet_ntoa (((struct udp_transport *)t)->src.sin_addr), 256);
- strlcpy (iddst, inet_ntoa (((struct udp_transport *)t)->dst.sin_addr), 256);
-#endif /* HAVE_GETNAMEINFO */
-
- snprintf (result, sizeof result, "src: %s dst: %s", idsrc, iddst);
+ strlcpy(idsrc, inet_ntoa(((struct udp_transport *) t)->src.sin_addr), 256);
+ strlcpy(iddst, inet_ntoa(((struct udp_transport *) t)->dst.sin_addr), 256);
+#endif /* HAVE_GETNAMEINFO */
- return result;
+ snprintf(result, sizeof result, "src: %s dst: %s", idsrc, iddst);
+ return result;
}
#if 0
@@ -896,29 +831,25 @@ udp_decode_ids (struct transport *t)
* XXX Currently unused.
*/
static in_port_t
-udp_decode_port (char *port_str)
+udp_decode_port(char *port_str)
{
- char *port_str_end;
- long port_long;
- struct servent *service;
-
- port_long = ntohl (strtol (port_str, &port_str_end, 0));
- if (port_str == port_str_end)
- {
- service = getservbyname (port_str, "udp");
- if (!service)
- {
- log_print ("udp_decode_port: service \"%s\" unknown", port_str);
- return 0;
- }
- return ntohs (service->s_port);
- }
- else if (port_long < 1 || port_long > 65535)
- {
- log_print ("udp_decode_port: port %ld out of range", port_long);
- return 0;
- }
-
- return port_long;
+ char *port_str_end;
+ long port_long;
+ struct servent *service;
+
+ port_long = ntohl(strtol(port_str, &port_str_end, 0));
+ if (port_str == port_str_end) {
+ service = getservbyname(port_str, "udp");
+ if (!service) {
+ log_print("udp_decode_port: service \"%s\" unknown",
+ port_str);
+ return 0;
+ }
+ return ntohs(service->s_port);
+ } else if (port_long < 1 || port_long > 65535) {
+ log_print("udp_decode_port: port %ld out of range", port_long);
+ return 0;
+ }
+ return port_long;
}
#endif
diff --git a/sbin/isakmpd/udp.h b/sbin/isakmpd/udp.h
index 43fdf419872..923461f3af7 100644
--- a/sbin/isakmpd/udp.h
+++ b/sbin/isakmpd/udp.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: udp.h,v 1.7 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: udp.h,v 1.4 1998/12/22 02:23:43 niklas Exp $ */
+/* $OpenBSD: udp.h,v 1.8 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: udp.h,v 1.4 1998/12/22 02:23:43 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -32,16 +32,16 @@
#ifndef _UDP_H_
#define _UDP_H_
-extern char *udp_default_port;
-extern char *udp_bind_port;
-extern int bind_family;
+extern char *udp_default_port;
+extern char *udp_bind_port;
+extern int bind_family;
#define BIND_FAMILY_INET4 0x0001
#define BIND_FAMILY_INET6 0x0002
#if 0
-extern in_port_t udp_decode_port (char *);
+extern in_port_t udp_decode_port(char *);
#endif
-extern void udp_init (void);
+extern void udp_init(void);
-#endif /* _UDP_H_ */
+#endif /* _UDP_H_ */
diff --git a/sbin/isakmpd/ui.c b/sbin/isakmpd/ui.c
index 9940788f0fb..97207a4a5d2 100644
--- a/sbin/isakmpd/ui.c
+++ b/sbin/isakmpd/ui.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ui.c,v 1.37 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: ui.c,v 1.43 2000/10/05 09:25:12 niklas Exp $ */
+/* $OpenBSD: ui.c,v 1.38 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: ui.c,v 1.43 2000/10/05 09:25:12 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 Niklas Hallqvist. All rights reserved.
@@ -57,48 +57,50 @@
#define BUF_SZ 256
/* from isakmpd.c */
-void daemon_shutdown_now (int);
+void daemon_shutdown_now(int);
/* Report all SA configuration information. */
-void ui_report_sa (char *cmd);
+void ui_report_sa(char *cmd);
-char *ui_fifo = FIFO;
-int ui_socket;
+char *ui_fifo = FIFO;
+int ui_socket;
/* Create and open the FIFO used for user control. */
void
-ui_init (void)
+ui_init(void)
{
- struct stat st;
-
- /* -f- means control messages comes in via stdin. */
- if (strcmp (ui_fifo, "-") == 0)
- ui_socket = 0;
- else
- {
- /* Don't overwrite a file, i.e '-f /etc/isakmpd/isakmpd.conf'. */
+ struct stat st;
+
+ /* -f- means control messages comes in via stdin. */
+ if (strcmp(ui_fifo, "-") == 0) {
+ ui_socket = 0;
+ return;
+ }
+ /*
+ * Don't overwrite a file, i.e '-f
+ * /etc/isakmpd/isakmpd.conf'.
+ */
#if defined (USE_PRIVSEP)
- /* XXX This is a fstat! */
- if (monitor_stat (ui_fifo, &st) == 0)
+ /* XXX This is a fstat! */
+ if (monitor_stat(ui_fifo, &st) == 0) {
#else
- if (lstat (ui_fifo, &st) == 0)
+ if (lstat(ui_fifo, &st) == 0) {
#endif
- if ((st.st_mode & S_IFMT) == S_IFREG)
- {
- errno = EEXIST;
- log_fatal ("ui_init: could not create FIFO \"%s\"", ui_fifo);
- }
-
- /* No need to know about errors. */
- unlink (ui_fifo);
- if (monitor_mkfifo (ui_fifo, 0600) == -1)
- log_fatal ("ui_init: mkfifo (\"%s\", 0600) failed", ui_fifo);
-
- ui_socket = monitor_open (ui_fifo, O_RDWR | O_NONBLOCK, 0);
- if (ui_socket == -1)
- log_fatal ("ui_init: open (\"%s\", O_RDWR | O_NONBLOCK, 0) failed",
- ui_fifo);
- }
+ if ((st.st_mode & S_IFMT) == S_IFREG) {
+ errno = EEXIST;
+ log_fatal("ui_init: could not create FIFO \"%s\"", ui_fifo);
+ }
+ }
+
+ /* No need to know about errors. */
+ unlink(ui_fifo);
+ if (monitor_mkfifo(ui_fifo, 0600) == -1)
+ log_fatal("ui_init: mkfifo (\"%s\", 0600) failed", ui_fifo);
+
+ ui_socket = monitor_open(ui_fifo, O_RDWR | O_NONBLOCK, 0);
+ if (ui_socket == -1)
+ log_fatal("ui_init: open (\"%s\", O_RDWR | O_NONBLOCK, 0) failed",
+ ui_fifo);
}
/*
@@ -106,43 +108,41 @@ ui_init (void)
* XXX Maybe phase 1 works too, but teardown won't work then, fix?
*/
static void
-ui_connect (char *cmd)
+ui_connect(char *cmd)
{
- char name[81];
-
- if (sscanf (cmd, "c %80s", name) != 1)
- {
- log_print ("ui_connect: command \"%s\" malformed", cmd);
- return;
- }
- LOG_DBG ((LOG_UI, 10, "ui_connect: setup connection \"%s\"", name));
- connection_setup (name);
+ char name[81];
+
+ if (sscanf(cmd, "c %80s", name) != 1) {
+ log_print("ui_connect: command \"%s\" malformed", cmd);
+ return;
+ }
+ LOG_DBG((LOG_UI, 10, "ui_connect: setup connection \"%s\"", name));
+ connection_setup(name);
}
/* Tear down a phase 2 connection. */
static void
-ui_teardown (char *cmd)
+ui_teardown(char *cmd)
{
- char name[81];
- struct sa *sa;
-
- if (sscanf (cmd, "t %80s", name) != 1)
- {
- log_print ("ui_teardown: command \"%s\" malformed", cmd);
- return;
- }
- LOG_DBG ((LOG_UI, 10, "ui_teardown: teardown connection \"%s\"", name));
- connection_teardown (name);
- while ((sa = sa_lookup_by_name (name, 2)) != 0)
- sa_delete (sa, 1);
+ char name[81];
+ struct sa *sa;
+
+ if (sscanf(cmd, "t %80s", name) != 1) {
+ log_print("ui_teardown: command \"%s\" malformed", cmd);
+ return;
+ }
+ LOG_DBG((LOG_UI, 10, "ui_teardown: teardown connection \"%s\"", name));
+ connection_teardown(name);
+ while ((sa = sa_lookup_by_name(name, 2)) != 0)
+ sa_delete(sa, 1);
}
/* Tear down all phase 2 connections. */
static void
-ui_teardown_all (char *cmd)
+ui_teardown_all(char *cmd)
{
- /* Skip 'cmd' as arg. */
- sa_teardown_all ();
+ /* Skip 'cmd' as arg. */
+ sa_teardown_all();
}
/*
@@ -151,182 +151,158 @@ ui_teardown_all (char *cmd)
* limit on the parameters?
*/
static void
-ui_config (char *cmd)
+ui_config(char *cmd)
{
- char subcmd[81], section[81], tag[81], value[81], tmp[81];
- int trans = 0, items;
-
- if (sscanf (cmd, "C %80s", subcmd) != 1)
- goto fail;
-
- trans = conf_begin ();
- if (strcasecmp (subcmd, "set") == 0)
- {
- items = sscanf (cmd, "C %*s [%80[^]]]:%80[^=]=%80s %80s", section, tag,
- value, tmp);
- if (!(items == 3 || items == 4))
- goto fail;
- conf_set (trans, section, tag, value, items == 4 ? 1 : 0, 0);
- }
- else if (strcasecmp (subcmd, "rm") == 0)
- {
- if (sscanf (cmd, "C %*s [%80[^]]]:%80s", section, tag) != 2)
- goto fail;
- conf_remove (trans, section, tag);
- }
- else if (strcasecmp (subcmd, "rms") == 0)
- {
- if (sscanf (cmd, "C %*s [%80[^]]]", section) != 1)
- goto fail;
- conf_remove_section (trans, section);
- }
- else
- goto fail;
-
- LOG_DBG ((LOG_UI, 30, "ui_config: \"%s\"", cmd));
- conf_end (trans, 1);
- return;
-
- fail:
- if (trans)
- conf_end (trans, 0);
- log_print ("ui_config: command \"%s\" malformed", cmd);
+ char subcmd[81], section[81], tag[81], value[81], tmp[81];
+ int trans = 0, items;
+
+ if (sscanf(cmd, "C %80s", subcmd) != 1)
+ goto fail;
+
+ trans = conf_begin();
+ if (strcasecmp(subcmd, "set") == 0) {
+ items = sscanf(cmd, "C %*s [%80[^]]]:%80[^=]=%80s %80s",
+ section, tag, value, tmp);
+ if (!(items == 3 || items == 4))
+ goto fail;
+ conf_set(trans, section, tag, value, items == 4 ? 1 : 0, 0);
+ } else if (strcasecmp(subcmd, "rm") == 0) {
+ if (sscanf(cmd, "C %*s [%80[^]]]:%80s", section, tag) != 2)
+ goto fail;
+ conf_remove(trans, section, tag);
+ } else if (strcasecmp(subcmd, "rms") == 0) {
+ if (sscanf(cmd, "C %*s [%80[^]]]", section) != 1)
+ goto fail;
+ conf_remove_section(trans, section);
+ } else
+ goto fail;
+
+ LOG_DBG((LOG_UI, 30, "ui_config: \"%s\"", cmd));
+ conf_end(trans, 1);
+ return;
+
+fail:
+ if (trans)
+ conf_end(trans, 0);
+ log_print("ui_config: command \"%s\" malformed", cmd);
}
static void
-ui_delete (char *cmd)
+ui_delete(char *cmd)
{
- char cookies_str[ISAKMP_HDR_COOKIES_LEN * 2 + 1];
- char message_id_str[ISAKMP_HDR_MESSAGE_ID_LEN * 2 + 1];
- u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
- u_int8_t message_id_buf[ISAKMP_HDR_MESSAGE_ID_LEN];
- u_int8_t *message_id = message_id_buf;
- struct sa *sa;
-
- if (sscanf (cmd, "d %32s %8s", cookies_str, message_id_str) != 2)
- {
- log_print ("ui_delete: command \"%s\" malformed", cmd);
- return;
- }
-
- if (strcmp (message_id_str, "-") == 0)
- message_id = 0;
-
- if (hex2raw (cookies_str, cookies, ISAKMP_HDR_COOKIES_LEN) == -1
- || (message_id && hex2raw (message_id_str, message_id_buf,
- ISAKMP_HDR_MESSAGE_ID_LEN) == -1))
- {
- log_print ("ui_delete: command \"%s\" has bad arguments", cmd);
- return;
- }
-
- sa = sa_lookup (cookies, message_id);
- if (!sa)
- {
- log_print ("ui_delete: command \"%s\" found no SA", cmd);
- return;
- }
- LOG_DBG ((LOG_UI, 20,
+ char cookies_str[ISAKMP_HDR_COOKIES_LEN * 2 + 1];
+ char message_id_str[ISAKMP_HDR_MESSAGE_ID_LEN * 2 + 1];
+ u_int8_t cookies[ISAKMP_HDR_COOKIES_LEN];
+ u_int8_t message_id_buf[ISAKMP_HDR_MESSAGE_ID_LEN];
+ u_int8_t *message_id = message_id_buf;
+ struct sa *sa;
+
+ if (sscanf(cmd, "d %32s %8s", cookies_str, message_id_str) != 2) {
+ log_print("ui_delete: command \"%s\" malformed", cmd);
+ return;
+ }
+ if (strcmp(message_id_str, "-") == 0)
+ message_id = 0;
+
+ if (hex2raw(cookies_str, cookies, ISAKMP_HDR_COOKIES_LEN) == -1 ||
+ (message_id && hex2raw(message_id_str, message_id_buf,
+ ISAKMP_HDR_MESSAGE_ID_LEN) == -1)) {
+ log_print("ui_delete: command \"%s\" has bad arguments", cmd);
+ return;
+ }
+ sa = sa_lookup(cookies, message_id);
+ if (!sa) {
+ log_print("ui_delete: command \"%s\" found no SA", cmd);
+ return;
+ }
+ LOG_DBG((LOG_UI, 20,
"ui_delete: deleting SA for cookie \"%s\" msgid \"%s\"",
cookies_str, message_id_str));
- sa_delete (sa, 1);
+ sa_delete(sa, 1);
}
#ifdef USE_DEBUG
/* Parse the debug command found in CMD. */
static void
-ui_debug (char *cmd)
+ui_debug(char *cmd)
{
- int cls, level;
- char subcmd[3];
-
- if (sscanf (cmd, "D %d %d", &cls, &level) == 2)
- {
- log_debug_cmd (cls, level);
- return;
- }
- else if (sscanf (cmd, "D %2s %d", subcmd, &level) == 2)
- {
- switch (subcmd[0])
- {
- case 'A':
- for (cls = 0; cls < LOG_ENDCLASS; cls++)
- log_debug_cmd (cls, level);
- return;
- }
- }
- else if (sscanf (cmd, "D %2s", subcmd) == 1)
- {
- switch (subcmd[0])
- {
- case 'T':
- log_debug_toggle ();
- return;
+ int cls, level;
+ char subcmd[3];
+
+ if (sscanf(cmd, "D %d %d", &cls, &level) == 2) {
+ log_debug_cmd(cls, level);
+ return;
+ } else if (sscanf(cmd, "D %2s %d", subcmd, &level) == 2) {
+ switch (subcmd[0]) {
+ case 'A':
+ for (cls = 0; cls < LOG_ENDCLASS; cls++)
+ log_debug_cmd(cls, level);
+ return;
+ }
+ } else if (sscanf(cmd, "D %2s", subcmd) == 1) {
+ switch (subcmd[0]) {
+ case 'T':
+ log_debug_toggle();
+ return;
+ }
}
- }
-
- log_print ("ui_debug: command \"%s\" malformed", cmd);
- return;
+ log_print("ui_debug: command \"%s\" malformed", cmd);
+ return;
}
static void
-ui_packetlog (char *cmd)
+ui_packetlog(char *cmd)
{
- char subcmd[81];
-
- if (sscanf (cmd, "p %80s", subcmd) != 1)
- goto fail;
-
- if (strncasecmp (subcmd, "on=", 3) == 0)
- {
- /* Start capture to a new file. */
- if (subcmd[strlen (subcmd) - 1] == '\n')
- subcmd[strlen (subcmd) - 1] = 0;
- log_packet_restart (subcmd + 3);
- }
- else if (strcasecmp (subcmd, "on") == 0)
- log_packet_restart (NULL);
- else if (strcasecmp (subcmd, "off") == 0)
- log_packet_stop ();
-
- return;
-
- fail:
- log_print ("ui_packetlog: command \"%s\" malformed", cmd);
+ char subcmd[81];
+
+ if (sscanf(cmd, "p %80s", subcmd) != 1)
+ goto fail;
+
+ if (strncasecmp(subcmd, "on=", 3) == 0) {
+ /* Start capture to a new file. */
+ if (subcmd[strlen(subcmd) - 1] == '\n')
+ subcmd[strlen(subcmd) - 1] = 0;
+ log_packet_restart(subcmd + 3);
+ } else if (strcasecmp(subcmd, "on") == 0)
+ log_packet_restart(NULL);
+ else if (strcasecmp(subcmd, "off") == 0)
+ log_packet_stop();
+ return;
+
+fail:
+ log_print("ui_packetlog: command \"%s\" malformed", cmd);
}
-#endif /* USE_DEBUG */
+#endif /* USE_DEBUG */
static void
-ui_shutdown_daemon (char *cmd)
+ui_shutdown_daemon(char *cmd)
{
- if (strlen (cmd) == 1)
- {
- log_print ("ui_shutdown_daemon: received shutdown command");
- daemon_shutdown_now (0);
- }
- else
- log_print ("ui_shutdown_daemon: command \"%s\" malformed", cmd);
+ if (strlen(cmd) == 1) {
+ log_print("ui_shutdown_daemon: received shutdown command");
+ daemon_shutdown_now(0);
+ } else
+ log_print("ui_shutdown_daemon: command \"%s\" malformed", cmd);
}
/* Report SAs and ongoing exchanges. */
void
-ui_report (char *cmd)
+ui_report(char *cmd)
{
- /* XXX Skip 'cmd' as arg? */
- sa_report ();
- exchange_report ();
- transport_report ();
- connection_report ();
- timer_report ();
- conf_report ();
+ /* XXX Skip 'cmd' as arg? */
+ sa_report();
+ exchange_report();
+ transport_report();
+ connection_report();
+ timer_report();
+ conf_report();
}
/* Report all SA configuration information. */
void
-ui_report_sa (char *cmd)
+ui_report_sa(char *cmd)
{
- /* Skip 'cmd' as arg? */
- sa_report_all ();
+ /* Skip 'cmd' as arg? */
+ sa_report_all();
}
/*
@@ -334,60 +310,59 @@ ui_report_sa (char *cmd)
* line (the command).
*/
static void
-ui_handle_command (char *line)
+ui_handle_command(char *line)
{
- /* Find out what one-letter command was sent. */
- switch (line[0])
- {
- case 'c':
- ui_connect (line);
- break;
+ /* Find out what one-letter command was sent. */
+ switch (line[0]) {
+ case 'c':
+ ui_connect(line);
+ break;
- case 'C':
- ui_config (line);
- break;
+ case 'C':
+ ui_config(line);
+ break;
- case 'd':
- ui_delete (line);
- break;
+ case 'd':
+ ui_delete(line);
+ break;
#ifdef USE_DEBUG
- case 'D':
- ui_debug (line);
- break;
+ case 'D':
+ ui_debug(line);
+ break;
- case 'p':
- ui_packetlog (line);
- break;
+ case 'p':
+ ui_packetlog(line);
+ break;
#endif
- case 'Q':
- ui_shutdown_daemon (line);
- break;
+ case 'Q':
+ ui_shutdown_daemon(line);
+ break;
- case 'R':
- reinit ();
- break;
+ case 'R':
+ reinit();
+ break;
- case 'S':
- ui_report_sa (line);
- break;
+ case 'S':
+ ui_report_sa(line);
+ break;
- case 'r':
- ui_report (line);
- break;
+ case 'r':
+ ui_report(line);
+ break;
- case 't':
- ui_teardown (line);
- break;
+ case 't':
+ ui_teardown(line);
+ break;
- case 'T':
- ui_teardown_all (line);
- break;
+ case 'T':
+ ui_teardown_all(line);
+ break;
- default:
- log_print ("ui_handle_messages: unrecognized command: '%c'", line[0]);
- }
+ default:
+ log_print("ui_handle_messages: unrecognized command: '%c'", line[0]);
+ }
}
/*
@@ -396,73 +371,64 @@ ui_handle_command (char *line)
* troubles with non-blocking fifos.
*/
void
-ui_handler (void)
+ui_handler(void)
{
- static char *buf = 0;
- static char *p;
- static size_t sz;
- static size_t resid;
- ssize_t n;
- char *new_buf;
-
- /* If no buffer, set it up. */
- if (!buf)
- {
- sz = BUF_SZ;
- buf = malloc (sz);
- if (!buf)
- {
- log_print ("ui_handler: malloc (%lu) failed", (unsigned long)sz);
- return;
+ static char *buf = 0;
+ static char *p;
+ static size_t sz;
+ static size_t resid;
+ ssize_t n;
+ char *new_buf;
+
+ /* If no buffer, set it up. */
+ if (!buf) {
+ sz = BUF_SZ;
+ buf = malloc(sz);
+ if (!buf) {
+ log_print("ui_handler: malloc (%lu) failed",
+ (unsigned long) sz);
+ return;
+ }
+ p = buf;
+ resid = sz;
+ }
+ /* If no place left in the buffer reallocate twice as large. */
+ if (!resid) {
+ new_buf = realloc(buf, sz * 2);
+ if (!new_buf) {
+ log_print("ui_handler: realloc (%p, %lu) failed", buf,
+ (unsigned long) sz * 2);
+ free(buf);
+ buf = 0;
+ return;
+ }
+ buf = new_buf;
+ p = buf + sz;
+ resid = sz;
+ sz *= 2;
}
- p = buf;
- resid = sz;
- }
-
- /* If no place left in the buffer reallocate twice as large. */
- if (!resid)
- {
- new_buf = realloc (buf, sz * 2);
- if (!new_buf)
- {
- log_print ("ui_handler: realloc (%p, %lu) failed", buf,
- (unsigned long)sz * 2);
- free (buf);
- buf = 0;
- return;
+ n = read(ui_socket, p, resid);
+ if (n == -1) {
+ log_error("ui_handler: read (%d, %p, %lu)", ui_socket, p,
+ (unsigned long) resid);
+ return;
}
- buf = new_buf;
- p = buf + sz;
- resid = sz;
- sz *= 2;
- }
-
- n = read (ui_socket, p, resid);
- if (n == -1)
- {
- log_error ("ui_handler: read (%d, %p, %lu)", ui_socket, p,
- (unsigned long)resid);
- return;
- }
-
- if (!n)
- return;
- resid -= n;
- while (n--)
- {
- /*
- * When we find a newline, cut off the line and feed it to the
- * command processor. Then move the rest up-front.
- */
- if (*p == '\n')
- {
- *p = '\0';
- ui_handle_command (buf);
- memcpy (buf, p + 1, n);
- p = buf;
- resid = sz - n;
- continue;
+ if (!n)
+ return;
+ resid -= n;
+ while (n--) {
+ /*
+ * When we find a newline, cut off the line and feed it to the
+ * command processor. Then move the rest up-front.
+ */
+ if (*p == '\n') {
+ *p = '\0';
+ ui_handle_command(buf);
+ memcpy(buf, p + 1, n);
+ p = buf;
+ resid = sz - n;
+ continue;
+ }
+ p++;
}
- p++;
- }
}
diff --git a/sbin/isakmpd/ui.h b/sbin/isakmpd/ui.h
index 9a2ddc0f69f..3876e8d1bdf 100644
--- a/sbin/isakmpd/ui.h
+++ b/sbin/isakmpd/ui.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ui.h,v 1.5 2003/06/03 14:28:16 ho Exp $ */
-/* $EOM: ui.h,v 1.5 1998/12/01 10:20:12 niklas Exp $ */
+/* $OpenBSD: ui.h,v 1.6 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: ui.h,v 1.5 1998/12/01 10:20:12 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -34,11 +34,11 @@
#define FIFO "/var/run/isakmpd.fifo"
-extern char *ui_fifo;
-extern int ui_socket;
+extern char *ui_fifo;
+extern int ui_socket;
-extern void ui_handler (void);
-extern void ui_init (void);
-extern void ui_report (char *);
+extern void ui_handler(void);
+extern void ui_init(void);
+extern void ui_report(char *);
-#endif /* _UI_H_ */
+#endif /* _UI_H_ */
diff --git a/sbin/isakmpd/util.c b/sbin/isakmpd/util.c
index 7e2ec63ce50..c343bd0fec5 100644
--- a/sbin/isakmpd/util.c
+++ b/sbin/isakmpd/util.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: util.c,v 1.36 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: util.c,v 1.23 2000/11/23 12:22:08 niklas Exp $ */
+/* $OpenBSD: util.c,v 1.37 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: util.c,v 1.23 2000/11/23 12:22:08 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -55,41 +55,41 @@
* Set if -N is given, allowing name lookups to be done, possibly stalling
* the daemon for quite a while.
*/
-int allow_name_lookups = 0;
+int allow_name_lookups = 0;
/*
* This is set to true in case of regression-test mode, when it will
* cause predictable random numbers be generated.
*/
-int regrand = 0;
+int regrand = 0;
/*
* If in regression-test mode, this is the seed used.
*/
-unsigned long seed;
+u_long seed;
/*
* XXX These might be turned into inlines or macros, maybe even
* machine-dependent ones, for performance reasons.
*/
u_int16_t
-decode_16 (u_int8_t *cp)
+decode_16(u_int8_t *cp)
{
- return cp[0] << 8 | cp[1];
+ return cp[0] << 8 | cp[1];
}
u_int32_t
-decode_32 (u_int8_t *cp)
+decode_32(u_int8_t *cp)
{
- return cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3];
+ return cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3];
}
u_int64_t
-decode_64 (u_int8_t *cp)
+decode_64(u_int8_t *cp)
{
- return (u_int64_t)cp[0] << 56 | (u_int64_t)cp[1] << 48
- | (u_int64_t)cp[2] << 40 | (u_int64_t)cp[3] << 32
- | cp[4] << 24 | cp[5] << 16 | cp[6] << 8 | cp[7];
+ return (u_int64_t) cp[0] << 56 | (u_int64_t) cp[1] << 48 |
+ (u_int64_t) cp[2] << 40 | (u_int64_t) cp[3] << 32 |
+ cp[4] << 24 | cp[5] << 16 | cp[6] << 8 | cp[7];
}
#if 0
@@ -99,15 +99,15 @@ decode_64 (u_int8_t *cp)
*/
void
-decode_128 (u_int8_t *cp, u_int8_t *cpp)
+decode_128(u_int8_t *cp, u_int8_t *cpp)
{
#if BYTE_ORDER == LITTLE_ENDIAN
- int i;
+ int i;
- for (i = 0; i < 16; i++)
- cpp[i] = cp[15 - i];
+ for (i = 0; i < 16; i++)
+ cpp[i] = cp[15 - i];
#elif BYTE_ORDER == BIG_ENDIAN
- bcopy (cp, cpp, 16);
+ bcopy(cp, cpp, 16);
#else
#error "Byte order unknown!"
#endif
@@ -115,32 +115,32 @@ decode_128 (u_int8_t *cp, u_int8_t *cpp)
#endif
void
-encode_16 (u_int8_t *cp, u_int16_t x)
+encode_16(u_int8_t *cp, u_int16_t x)
{
- *cp++ = x >> 8;
- *cp = x & 0xff;
+ *cp++ = x >> 8;
+ *cp = x & 0xff;
}
void
-encode_32 (u_int8_t *cp, u_int32_t x)
+encode_32(u_int8_t *cp, u_int32_t x)
{
- *cp++ = x >> 24;
- *cp++ = (x >> 16) & 0xff;
- *cp++ = (x >> 8) & 0xff;
- *cp = x & 0xff;
+ *cp++ = x >> 24;
+ *cp++ = (x >> 16) & 0xff;
+ *cp++ = (x >> 8) & 0xff;
+ *cp = x & 0xff;
}
void
-encode_64 (u_int8_t *cp, u_int64_t x)
+encode_64(u_int8_t *cp, u_int64_t x)
{
- *cp++ = x >> 56;
- *cp++ = (x >> 48) & 0xff;
- *cp++ = (x >> 40) & 0xff;
- *cp++ = (x >> 32) & 0xff;
- *cp++ = (x >> 24) & 0xff;
- *cp++ = (x >> 16) & 0xff;
- *cp++ = (x >> 8) & 0xff;
- *cp = x & 0xff;
+ *cp++ = x >> 56;
+ *cp++ = (x >> 48) & 0xff;
+ *cp++ = (x >> 40) & 0xff;
+ *cp++ = (x >> 32) & 0xff;
+ *cp++ = (x >> 24) & 0xff;
+ *cp++ = (x >> 16) & 0xff;
+ *cp++ = (x >> 8) & 0xff;
+ *cp = x & 0xff;
}
#if 0
@@ -150,63 +150,62 @@ encode_64 (u_int8_t *cp, u_int64_t x)
*/
void
-encode_128 (u_int8_t *cp, u_int8_t *cpp)
+encode_128(u_int8_t *cp, u_int8_t *cpp)
{
- decode_128 (cpp, cp);
+ decode_128(cpp, cp);
}
#endif
/* Check a buffer for all zeroes. */
int
-zero_test (const u_int8_t *p, size_t sz)
+zero_test(const u_int8_t *p, size_t sz)
{
- while (sz-- > 0)
- if (*p++ != 0)
- return 0;
- return 1;
+ while (sz-- > 0)
+ if (*p++ != 0)
+ return 0;
+ return 1;
}
/* Check a buffer for all ones. */
int
-ones_test (const u_int8_t *p, size_t sz)
+ones_test(const u_int8_t *p, size_t sz)
{
- while (sz-- > 0)
- if (*p++ != 0xff)
- return 0;
- return 1;
+ while (sz-- > 0)
+ if (*p++ != 0xff)
+ return 0;
+ return 1;
}
/*
* Generate a random data, len bytes long.
*/
u_int8_t *
-getrandom (u_int8_t *buf, size_t len)
+getrandom(u_int8_t *buf, size_t len)
{
- u_int32_t tmp = 0;
- size_t i;
+ u_int32_t tmp = 0;
+ size_t i;
- for (i = 0; i < len; i++)
- {
- if (i % sizeof tmp == 0)
- tmp = sysdep_random ();
+ for (i = 0; i < len; i++) {
+ if (i % sizeof tmp == 0)
+ tmp = sysdep_random();
- buf[i] = tmp & 0xff;
- tmp >>= 8;
- }
+ buf[i] = tmp & 0xff;
+ tmp >>= 8;
+ }
- return buf;
+ return buf;
}
static __inline int
-hex2nibble (char c)
+hex2nibble(char c)
{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
}
/*
@@ -214,99 +213,92 @@ hex2nibble (char c)
* bytes. Return 0 if everything is OK, -1 otherwise.
*/
int
-hex2raw (char *s, u_int8_t *buf, size_t sz)
+hex2raw(char *s, u_int8_t *buf, size_t sz)
{
- char *p;
- u_int8_t *bp;
- int tmp;
-
- if (strlen (s) > sz * 2)
- return -1;
- for (p = s + strlen (s) - 1, bp = &buf[sz - 1]; bp >= buf; bp--)
- {
- *bp = 0;
- if (p >= s)
- {
- tmp = hex2nibble (*p--);
- if (tmp == -1)
- return -1;
- *bp = tmp;
- }
- if (p >= s)
- {
- tmp = hex2nibble (*p--);
- if (tmp == -1)
- return -1;
- *bp |= tmp << 4;
+ u_int8_t *bp;
+ char *p;
+ int tmp;
+
+ if (strlen(s) > sz * 2)
+ return -1;
+ for (p = s + strlen(s) - 1, bp = &buf[sz - 1]; bp >= buf; bp--) {
+ *bp = 0;
+ if (p >= s) {
+ tmp = hex2nibble(*p--);
+ if (tmp == -1)
+ return -1;
+ *bp = tmp;
+ }
+ if (p >= s) {
+ tmp = hex2nibble(*p--);
+ if (tmp == -1)
+ return -1;
+ *bp |= tmp << 4;
+ }
}
- }
- return 0;
+ return 0;
}
int
-text2sockaddr (char *address, char *port, struct sockaddr **sa)
+text2sockaddr(char *address, char *port, struct sockaddr ** sa)
{
#ifdef HAVE_GETNAMEINFO
- struct addrinfo *ai, hints;
+ struct addrinfo *ai, hints;
- memset (&hints, 0, sizeof hints);
- if (!allow_name_lookups)
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
+ memset(&hints, 0, sizeof hints);
+ if (!allow_name_lookups)
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
- if (getaddrinfo (address, port, &hints, &ai))
- return -1;
+ if (getaddrinfo(address, port, &hints, &ai))
+ return -1;
- *sa = malloc (sysdep_sa_len (ai->ai_addr));
- if (!sa)
- return -1;
+ *sa = malloc(sysdep_sa_len(ai->ai_addr));
+ if (!sa)
+ return -1;
- memcpy (*sa, ai->ai_addr, sysdep_sa_len (ai->ai_addr));
- freeaddrinfo (ai);
- return 0;
+ memcpy(*sa, ai->ai_addr, sysdep_sa_len(ai->ai_addr));
+ freeaddrinfo(ai);
+ return 0;
#else
- int af = strchr (address, ':') != NULL ? AF_INET6 : AF_INET;
- size_t sz = af == AF_INET
- ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6);
- long lport;
- struct servent *sp;
- char *ep;
-
- *sa = calloc (1, sz);
- if (!*sa)
- return -1;
+ int af = strchr(address, ':') != NULL ? AF_INET6 : AF_INET;
+ size_t sz = af == AF_INET ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6);
+ long lport;
+ struct servent *sp;
+ char *ep;
+
+ *sa = calloc(1, sz);
+ if (!*sa)
+ return -1;
#ifndef USE_OLD_SOCKADDR
- (*sa)->sa_len = sz;
+ (*sa)->sa_len = sz;
#endif
- (*sa)->sa_family = af;
- if (inet_pton (af, address, sockaddr_addrdata (*sa)) != 1)
- {
- free (*sa);
- return -1;
- }
- if (!port)
- return 0;
- sp = getservbyname (port, "udp");
- if (!sp)
- {
- lport = strtol (port, &ep, 10);
- if (ep == port || lport < 0 || lport > (long)USHRT_MAX)
- {
- free (*sa);
- return -1;
+ (*sa)->sa_family = af;
+ if (inet_pton(af, address, sockaddr_addrdata(*sa)) != 1) {
+ free(*sa);
+ return -1;
}
- lport = htons (lport);
- }
- else
- lport = sp->s_port;
- if ((*sa)->sa_family == AF_INET)
- ((struct sockaddr_in *)*sa)->sin_port = lport;
- else
- ((struct sockaddr_in6 *)*sa)->sin6_port = lport;
- return 0;
+ if (!port)
+ return 0;
+ sp = getservbyname(port, "udp");
+ if (!sp) {
+ lport = strtol(port, &ep, 10);
+ if (ep == port || lport < 0 || lport > (long) USHRT_MAX) {
+ free(*sa);
+ return -1;
+ }
+ lport = htons(lport);
+ } else
+ lport = sp->s_port;
+ if ((*sa)->sa_family == AF_INET)
+ ((struct sockaddr_in *) *sa)->sin_port = lport;
+ else
+ ((struct sockaddr_in6 *) *sa)->sin6_port = lport;
+ return 0;
#endif
}
@@ -315,104 +307,94 @@ text2sockaddr (char *address, char *port, struct sockaddr **sa)
* i.e 10.0.0.10 --> "010.000.000.010"
*/
int
-sockaddr2text (struct sockaddr *sa, char **address, int zflag)
+sockaddr2text(struct sockaddr *sa, char **address, int zflag)
{
- char buf[NI_MAXHOST];
- char *token, *bstart, *ep;
- int addrlen;
- long val;
- int i, j;
+ char buf[NI_MAXHOST], *token, *bstart, *ep;
+ int addrlen, i, j;
+ long val;
#ifdef HAVE_GETNAMEINFO
- if (getnameinfo (sa, sysdep_sa_len (sa), buf, sizeof buf, 0, 0,
- allow_name_lookups ? 0 : NI_NUMERICHOST))
- return -1;
+ if (getnameinfo(sa, sysdep_sa_len(sa), buf, sizeof buf, 0, 0,
+ allow_name_lookups ? 0 : NI_NUMERICHOST))
+ return -1;
#else
- switch (sa->sa_family)
- {
- case AF_INET:
- case AF_INET6:
- if (inet_ntop (sa->sa_family, sa->sa_data, buf, NI_MAXHOST - 1) == NULL)
- {
- log_error ("sockaddr2text: inet_ntop (%d, %p, %p, %d) failed",
- sa->sa_family, sa->sa_data, buf, NI_MAXHOST - 1);
- return -1;
+ switch (sa->sa_family) {
+ case AF_INET:
+ case AF_INET6:
+ if (inet_ntop(sa->sa_family, sa->sa_data, buf, NI_MAXHOST - 1) == NULL) {
+ log_error("sockaddr2text: inet_ntop (%d, %p, %p, %d) failed",
+ sa->sa_family, sa->sa_data, buf, NI_MAXHOST - 1);
+ return -1;
+ }
+ buf[NI_MAXHOST - 1] = '\0';
+ break;
+
+ default:
+ log_print("sockaddr2text: unsupported protocol family %d\n",
+ sa->sa_family);
+ return -1;
}
- buf[NI_MAXHOST - 1] = '\0';
- break;
-
- default:
- log_print ("sockaddr2text: unsupported protocol family %d\n",
- sa->sa_family);
- return -1;
- }
#endif
- if (zflag == 0)
- {
- *address = strdup (buf);
- if (!*address)
- return -1;
- }
- else
- switch (sa->sa_family)
- {
- case AF_INET:
- addrlen = sizeof "000.000.000.000";
- *address = malloc (addrlen);
- if (!*address)
- return -1;
- buf[addrlen] = '\0';
- bstart = buf;
- **address = '\0';
- while ((token = strsep (&bstart, ".")) != NULL)
- {
- if (strlen (*address) > 12)
- {
- free (*address);
- return -1;
- }
- val = strtol (token, &ep, 10);
- if (ep == token || val < (long)0 || val > (long)UCHAR_MAX)
- {
- free (*address);
- return -1;
- }
- snprintf (*address + strlen (*address),
- addrlen - strlen (*address), "%03ld", val);
- if (bstart)
- strlcat (*address, ".", addrlen);
- }
- break;
-
- case AF_INET6:
- /*
- * XXX In the algorithm below there are some magic numbers we
- * probably could give explaining names.
- */
- addrlen = sizeof "0000:0000:0000:0000:0000:0000:0000:0000";
- *address = malloc (addrlen);
- if (!*address)
- return -1;
-
- for (i = 0, j = 0; i < 8; i++)
- {
- snprintf ((*address) + j, addrlen - j, "%02x%02x",
- ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2 * i],
- ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2 * i + 1]);
- j += 4;
- (*address)[j] = (j < (addrlen - 1)) ? ':' : '\0';
- j++;
- }
- break;
-
- default:
- *address = strdup ("<error>");
- if (!*address)
- return -1;
- }
-
- return 0;
+ if (zflag == 0) {
+ *address = strdup(buf);
+ if (!*address)
+ return -1;
+ } else
+ switch (sa->sa_family) {
+ case AF_INET:
+ addrlen = sizeof "000.000.000.000";
+ *address = malloc(addrlen);
+ if (!*address)
+ return -1;
+ buf[addrlen] = '\0';
+ bstart = buf;
+ **address = '\0';
+ while ((token = strsep(&bstart, ".")) != NULL) {
+ if (strlen(*address) > 12) {
+ free(*address);
+ return -1;
+ }
+ val = strtol(token, &ep, 10);
+ if (ep == token || val < (long) 0 ||
+ val > (long) UCHAR_MAX) {
+ free(*address);
+ return -1;
+ }
+ snprintf(*address + strlen(*address),
+ addrlen - strlen(*address), "%03ld", val);
+ if (bstart)
+ strlcat(*address, ".", addrlen);
+ }
+ break;
+
+ case AF_INET6:
+ /*
+ * XXX In the algorithm below there are some magic numbers we
+ * probably could give explaining names.
+ */
+ addrlen = sizeof "0000:0000:0000:0000:0000:0000:0000:0000";
+ *address = malloc(addrlen);
+ if (!*address)
+ return -1;
+
+ for (i = 0, j = 0; i < 8; i++) {
+ snprintf((*address) + j, addrlen - j, "%02x%02x",
+ ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i],
+ ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i + 1]);
+ j += 4;
+ (*address)[j] = (j < (addrlen - 1)) ? ':' : '\0';
+ j++;
+ }
+ break;
+
+ default:
+ *address = strdup("<error>");
+ if (!*address)
+ return -1;
+ }
+
+ return 0;
}
/*
@@ -420,51 +402,48 @@ sockaddr2text (struct sockaddr *sa, char **address, int zflag)
* depending on address family. Useful to keep other code shorter(/clearer?).
*/
int
-sockaddr_addrlen (struct sockaddr *sa)
+sockaddr_addrlen(struct sockaddr *sa)
{
- switch (sa->sa_family)
- {
- case AF_INET6:
- return sizeof ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
- case AF_INET:
- return sizeof ((struct sockaddr_in *)sa)->sin_addr.s_addr;
- default:
- log_print ("sockaddr_addrlen: unsupported protocol family %d",
- sa->sa_family);
- return 0;
- }
+ switch (sa->sa_family) {
+ case AF_INET6:
+ return sizeof((struct sockaddr_in6 *) sa)->sin6_addr.s6_addr;
+ case AF_INET:
+ return sizeof((struct sockaddr_in *) sa)->sin_addr.s_addr;
+ default:
+ log_print("sockaddr_addrlen: unsupported protocol family %d",
+ sa->sa_family);
+ return 0;
+ }
}
u_int8_t *
-sockaddr_addrdata (struct sockaddr *sa)
+sockaddr_addrdata(struct sockaddr *sa)
{
- switch (sa->sa_family)
- {
- case AF_INET6:
- return (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
- case AF_INET:
- return (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr.s_addr;
- default:
- log_print ("sockaddr_addrdata: unsupported protocol family %d",
- sa->sa_family);
- return 0;
- }
+ switch (sa->sa_family) {
+ case AF_INET6:
+ return (u_int8_t *) & ((struct sockaddr_in6 *) sa)->sin6_addr.s6_addr;
+ case AF_INET:
+ return (u_int8_t *) & ((struct sockaddr_in *) sa)->sin_addr.s_addr;
+ default:
+ log_print("sockaddr_addrdata: unsupported protocol family %d",
+ sa->sa_family);
+ return 0;
+ }
}
in_port_t
-sockaddr_port (struct sockaddr *sa)
+sockaddr_port(struct sockaddr *sa)
{
- switch (sa->sa_family)
- {
- case AF_INET6:
- return ((struct sockaddr_in6 *)sa)->sin6_port;
- case AF_INET:
- return ((struct sockaddr_in *)sa)->sin_port;
- default:
- log_print ("sockaddr_port: unsupported protocol family %d",
- sa->sa_family);
- return 0;
- }
+ switch (sa->sa_family) {
+ case AF_INET6:
+ return ((struct sockaddr_in6 *) sa)->sin6_port;
+ case AF_INET:
+ return ((struct sockaddr_in *) sa)->sin_port;
+ default:
+ log_print("sockaddr_port: unsupported protocol family %d",
+ sa->sa_family);
+ return 0;
+ }
}
/*
@@ -472,33 +451,31 @@ sockaddr_port (struct sockaddr *sa)
* to be properly aligned.
*/
void
-util_ntoa (char **buf, int af, u_int8_t *addr)
+util_ntoa(char **buf, int af, u_int8_t *addr)
{
- struct sockaddr_storage from;
- struct sockaddr *sfrom = (struct sockaddr *)&from;
- socklen_t fromlen = sizeof from;
+ struct sockaddr_storage from;
+ struct sockaddr *sfrom = (struct sockaddr *) & from;
+ socklen_t fromlen = sizeof from;
- memset (&from, 0, fromlen);
- sfrom->sa_family = af;
+ memset(&from, 0, fromlen);
+ sfrom->sa_family = af;
#ifndef USE_OLD_SOCKADDR
- switch (af)
- {
- case AF_INET:
- sfrom->sa_len = sizeof (struct sockaddr_in);
- break;
- case AF_INET6:
- sfrom->sa_len = sizeof (struct sockaddr_in6);
- break;
- }
+ switch (af) {
+ case AF_INET:
+ sfrom->sa_len = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ sfrom->sa_len = sizeof(struct sockaddr_in6);
+ break;
+ }
#endif
- memcpy (sockaddr_addrdata (sfrom), addr, sockaddr_addrlen (sfrom));
-
- if (sockaddr2text (sfrom, buf, 0))
- {
- log_print ("util_ntoa: "
- "could not make printable address out of sockaddr %p", sfrom);
- *buf = 0;
- }
+ memcpy(sockaddr_addrdata(sfrom), addr, sockaddr_addrlen(sfrom));
+
+ if (sockaddr2text(sfrom, buf, 0)) {
+ log_print("util_ntoa: "
+ "could not make printable address out of sockaddr %p", sfrom);
+ *buf = 0;
+ }
}
/*
@@ -507,32 +484,28 @@ util_ntoa (char **buf, int af, u_int8_t *addr)
* Also, if FILE_SIZE is a not a null pointer, store file size here.
*/
int
-check_file_secrecy (char *name, size_t *file_size)
+check_file_secrecy(char *name, size_t *file_size)
{
- struct stat st;
-
- if (monitor_stat (name, &st) == -1)
- {
- log_error ("check_file_secrecy: stat (\"%s\") failed", name);
- return -1;
- }
- if (st.st_uid != 0 && st.st_uid != getuid ())
- {
- log_print ("check_file_secrecy: "
- "not loading %s - file owner is not process user", name);
- errno = EPERM;
- return -1;
- }
- if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
- {
- log_print ("conf_file_secrecy: not loading %s - too open permissions",
- name);
- errno = EPERM;
- return -1;
- }
-
- if (file_size)
- *file_size = (size_t)st.st_size;
-
- return 0;
+ struct stat st;
+
+ if (monitor_stat(name, &st) == -1) {
+ log_error("check_file_secrecy: stat (\"%s\") failed", name);
+ return -1;
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_print("check_file_secrecy: "
+ "not loading %s - file owner is not process user", name);
+ errno = EPERM;
+ return -1;
+ }
+ if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
+ log_print("conf_file_secrecy: not loading %s - too open permissions",
+ name);
+ errno = EPERM;
+ return -1;
+ }
+ if (file_size)
+ *file_size = (size_t) st.st_size;
+
+ return 0;
}
diff --git a/sbin/isakmpd/util.h b/sbin/isakmpd/util.h
index d3d94461f30..5c04880e2c5 100644
--- a/sbin/isakmpd/util.h
+++ b/sbin/isakmpd/util.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: util.h,v 1.17 2004/03/10 23:08:49 hshoexer Exp $ */
-/* $EOM: util.h,v 1.10 2000/10/24 13:33:39 niklas Exp $ */
+/* $OpenBSD: util.h,v 1.18 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: util.h,v 1.10 2000/10/24 13:33:39 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -35,35 +35,35 @@
#include <sys/types.h>
-extern int allow_name_lookups;
-extern int regrand;
+extern int allow_name_lookups;
+extern int regrand;
extern unsigned long seed;
struct message;
struct sockaddr;
-extern int check_file_secrecy (char *, size_t *);
-extern u_int16_t decode_16 (u_int8_t *);
-extern u_int32_t decode_32 (u_int8_t *);
-extern u_int64_t decode_64 (u_int8_t *);
+extern int check_file_secrecy(char *, size_t *);
+extern u_int16_t decode_16(u_int8_t *);
+extern u_int32_t decode_32(u_int8_t *);
+extern u_int64_t decode_64(u_int8_t *);
#if 0
-extern void decode_128 (u_int8_t *, u_int8_t *);
+extern void decode_128(u_int8_t *, u_int8_t *);
#endif
-extern void encode_16 (u_int8_t *, u_int16_t);
-extern void encode_32 (u_int8_t *, u_int32_t);
-extern void encode_64 (u_int8_t *, u_int64_t);
+extern void encode_16(u_int8_t *, u_int16_t);
+extern void encode_32(u_int8_t *, u_int32_t);
+extern void encode_64(u_int8_t *, u_int64_t);
#if 0
-extern void encode_128 (u_int8_t *, u_int8_t *);
+extern void encode_128(u_int8_t *, u_int8_t *);
#endif
-extern u_int8_t *getrandom (u_int8_t *, size_t);
-extern int hex2raw (char *, u_int8_t *, size_t);
-extern int ones_test (const u_int8_t *, size_t);
-extern int sockaddr2text (struct sockaddr *, char **, int);
-extern u_int8_t *sockaddr_addrdata (struct sockaddr *);
-extern int sockaddr_addrlen (struct sockaddr *);
-extern in_port_t sockaddr_port (struct sockaddr *);
-extern int text2sockaddr (char *, char *, struct sockaddr **);
-extern void util_ntoa (char **, int, u_int8_t *);
-extern int zero_test (const u_int8_t *, size_t);
+extern u_int8_t *getrandom(u_int8_t *, size_t);
+extern int hex2raw(char *, u_int8_t *, size_t);
+extern int ones_test(const u_int8_t *, size_t);
+extern int sockaddr2text(struct sockaddr *, char **, int);
+extern u_int8_t *sockaddr_addrdata(struct sockaddr *);
+extern int sockaddr_addrlen(struct sockaddr *);
+extern in_port_t sockaddr_port(struct sockaddr *);
+extern int text2sockaddr(char *, char *, struct sockaddr **);
+extern void util_ntoa(char **, int, u_int8_t *);
+extern int zero_test(const u_int8_t *, size_t);
-#endif /* _UTIL_H_ */
+#endif /* _UTIL_H_ */
diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c
index be0f7a88bae..dda7dda0197 100644
--- a/sbin/isakmpd/x509.c
+++ b/sbin/isakmpd/x509.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: x509.c,v 1.87 2004/04/07 22:45:49 ho Exp $ */
-/* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */
+/* $OpenBSD: x509.c,v 1.88 2004/04/15 18:39:26 deraadt Exp $ */
+/* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -47,7 +47,7 @@
#ifdef USE_POLICY
#include <regex.h>
#include <keynote.h>
-#endif /* USE_POLICY */
+#endif /* USE_POLICY */
#include "sysdep.h"
@@ -65,10 +65,10 @@
#include "util.h"
#include "x509.h"
-static u_int16_t x509_hash (u_int8_t *, size_t);
-static void x509_hash_init (void);
-static X509 *x509_hash_find (u_int8_t *, size_t);
-static int x509_hash_enter (X509 *);
+static u_int16_t x509_hash(u_int8_t *, size_t);
+static void x509_hash_init(void);
+static X509 *x509_hash_find(u_int8_t *, size_t);
+static int x509_hash_enter(X509 *);
/*
* X509_STOREs do not support subjectAltNames, so we have to build
@@ -87,15 +87,16 @@ static X509_STORE *x509_cas = 0;
#define INITIAL_BUCKET_BITS 6
struct x509_hash {
- LIST_ENTRY (x509_hash) link;
+ LIST_ENTRY(x509_hash) link;
- X509 *cert;
+ X509 *cert;
};
-static LIST_HEAD (x509_list, x509_hash) *x509_tab = 0;
+static
+LIST_HEAD(x509_list, x509_hash) * x509_tab = 0;
/* Works both as a maximum index and a mask. */
-static int bucket_mask;
+ static int bucket_mask;
#ifdef USE_POLICY
/*
@@ -104,1128 +105,996 @@ static int bucket_mask;
* XXX RSA-specific.
*/
int
-x509_generate_kn (int id, X509 *cert)
+x509_generate_kn(int id, X509 *cert)
{
- char *fmt = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s\"\n"
- "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
- char *ikey, *skey, *buf, isname[256], subname[256];
- char *fmt2 = "Authorizer: \"DN:%s\"\nLicensees: \"DN:%s\"\n"
- "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
- X509_NAME *issuer, *subject;
- struct keynote_deckey dc;
- X509_STORE_CTX csc;
- X509_OBJECT obj;
- X509 *icert;
- RSA *key;
- time_t tt;
- char before[15], after[15];
- ASN1_TIME *tm;
- char *timecomp, *timecomp2;
- int i, buf_len;
-
- LOG_DBG ((LOG_POLICY, 90,
+ char *fmt = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s\"\n"
+ "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
+ char *ikey, *skey, *buf, isname[256], subname[256];
+ char *fmt2 = "Authorizer: \"DN:%s\"\nLicensees: \"DN:%s\"\n"
+ "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
+ X509_NAME *issuer, *subject;
+ struct keynote_deckey dc;
+ X509_STORE_CTX csc;
+ X509_OBJECT obj;
+ X509 *icert;
+ RSA *key;
+ time_t tt;
+ char before[15], after[15], *timecomp, *timecomp2;
+ ASN1_TIME *tm;
+ int i, buf_len;
+
+ LOG_DBG((LOG_POLICY, 90,
"x509_generate_kn: generating KeyNote policy for certificate %p",
cert));
- issuer = X509_get_issuer_name (cert);
- subject = X509_get_subject_name (cert);
-
- /* Missing or self-signed, ignore cert but don't report failure. */
- if (!issuer || !subject || !X509_name_cmp (issuer, subject))
- return 1;
-
- if (!x509_cert_get_key (cert, &key))
- {
- LOG_DBG ((LOG_POLICY, 30,
- "x509_generate_kn: failed to get public key from cert"));
- return 0;
- }
-
- dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
- dc.dec_key = key;
- ikey = kn_encode_key (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
- KEYNOTE_PUBLIC_KEY);
- if (keynote_errno == ERROR_MEMORY)
- {
- log_print ("x509_generate_kn: failed to get memory for public key");
- RSA_free (key);
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: cannot get subject key"));
- return 0;
- }
- if (!ikey)
- {
- RSA_free (key);
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: cannot get subject key"));
- return 0;
- }
- RSA_free (key);
-
- /* Now find issuer's certificate so we can get the public key. */
- X509_STORE_CTX_init (&csc, x509_cas, cert, NULL);
- if (X509_STORE_get_by_subject (&csc, X509_LU_X509, issuer, &obj) !=
- X509_LU_X509)
- {
- X509_STORE_CTX_cleanup (&csc);
- X509_STORE_CTX_init (&csc, x509_certs, cert, NULL);
- if (X509_STORE_get_by_subject (&csc, X509_LU_X509, issuer, &obj) !=
- X509_LU_X509)
- {
- X509_STORE_CTX_cleanup (&csc);
- LOG_DBG ((LOG_POLICY, 30,
- "x509_generate_kn: no certificate found for issuer"));
- return 0;
+ issuer = X509_get_issuer_name(cert);
+ subject = X509_get_subject_name(cert);
+
+ /* Missing or self-signed, ignore cert but don't report failure. */
+ if (!issuer || !subject || !X509_name_cmp(issuer, subject))
+ return 1;
+
+ if (!x509_cert_get_key(cert, &key)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: failed to get public key from cert"));
+ return 0;
}
- }
-
- X509_STORE_CTX_cleanup (&csc);
- icert = obj.data.x509;
-
- if (icert == NULL)
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: "
- "missing certificates, cannot construct X509 chain"));
- free (ikey);
- return 0;
- }
-
- if (!x509_cert_get_key (icert, &key))
- {
- LOG_DBG ((LOG_POLICY, 30,
- "x509_generate_kn: failed to get public key from cert"));
- free (ikey);
- return 0;
- }
-
- X509_OBJECT_free_contents (&obj);
-
- dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
- dc.dec_key = key;
- skey = kn_encode_key (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
- KEYNOTE_PUBLIC_KEY);
- if (keynote_errno == ERROR_MEMORY)
- {
- log_error ("x509_generate_kn: failed to get memory for public key");
- free (ikey);
- RSA_free (key);
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer key"));
- return 0;
- }
-
- if (!skey)
- {
- free (ikey);
- RSA_free (key);
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer key"));
- return 0;
- }
- RSA_free (key);
-
- buf_len = strlen (fmt) + strlen (ikey) + strlen (skey) + 56;
- buf = calloc (buf_len, sizeof (char));
- buf_len *= sizeof (char);
- if (!buf)
- {
- log_error ("x509_generate_kn: "
- "failed to allocate memory for KeyNote credential");
- free (ikey);
- free (skey);
- return 0;
- }
-
- if (((tm = X509_get_notBefore (cert)) == NULL) ||
- (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME))
- {
- tt = time (0);
- strftime (before, 14, "%Y%m%d%H%M%S", localtime (&tt));
- timecomp = "LocalTimeOfDay";
- }
- else
- {
- if (tm->data[tm->length - 1] == 'Z')
- {
- timecomp = "GMTTimeOfDay";
- i = tm->length - 2;
+ dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
+ dc.dec_key = key;
+ ikey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
+ KEYNOTE_PUBLIC_KEY);
+ if (keynote_errno == ERROR_MEMORY) {
+ log_print("x509_generate_kn: failed to get memory for public key");
+ RSA_free(key);
+ LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get subject key"));
+ return 0;
}
- else
- {
- timecomp = "LocalTimeOfDay";
- i = tm->length - 1;
+ if (!ikey) {
+ RSA_free(key);
+ LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get subject key"));
+ return 0;
}
-
- for (; i >= 0; i--)
- {
- if (tm->data[i] < '0' || tm->data[i] > '9')
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid data in "
- "NotValidBefore time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
+ RSA_free(key);
+
+ /* Now find issuer's certificate so we can get the public key. */
+ X509_STORE_CTX_init(&csc, x509_cas, cert, NULL);
+ if (X509_STORE_get_by_subject(&csc, X509_LU_X509, issuer, &obj) !=
+ X509_LU_X509) {
+ X509_STORE_CTX_cleanup(&csc);
+ X509_STORE_CTX_init(&csc, x509_certs, cert, NULL);
+ if (X509_STORE_get_by_subject(&csc, X509_LU_X509, issuer, &obj) !=
+ X509_LU_X509) {
+ X509_STORE_CTX_cleanup(&csc);
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: no certificate found for issuer"));
+ return 0;
+ }
}
-
- if (tm->type == V_ASN1_UTCTIME)
- {
- if ((tm->length < 10) || (tm->length > 13))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid length "
- "of NotValidBefore time field (%d)", tm->length));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Validity checks. */
- if ((tm->data[2] != '0' && tm->data[2] != '1')
- || (tm->data[2] == '0' && tm->data[3] == '0')
- || (tm->data[2] == '1' && tm->data[3] > '2')
- || (tm->data[4] > '3')
- || (tm->data[4] == '0' && tm->data[5] == '0')
- || (tm->data[4] == '3' && tm->data[5] > '1')
- || (tm->data[6] > '2')
- || (tm->data[6] == '2' && tm->data[7] > '3')
- || (tm->data[8] > '5'))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid value in "
- "NotValidBefore time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Stupid UTC tricks. */
- if (tm->data[0] < '5')
- snprintf (before, sizeof before, "20%s", tm->data);
- else
- snprintf (before, sizeof before, "19%s", tm->data);
+ X509_STORE_CTX_cleanup(&csc);
+ icert = obj.data.x509;
+
+ if (icert == NULL) {
+ LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: "
+ "missing certificates, cannot construct X509 chain"));
+ free(ikey);
+ return 0;
}
- else
- { /* V_ASN1_GENERICTIME */
- if ((tm->length < 12) || (tm->length > 15))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid length of "
- "NotValidBefore time field (%d)", tm->length));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Validity checks. */
- if ((tm->data[4] != '0' && tm->data[4] != '1')
- || (tm->data[4] == '0' && tm->data[5] == '0')
- || (tm->data[4] == '1' && tm->data[5] > '2')
- || (tm->data[6] > '3')
- || (tm->data[6] == '0' && tm->data[7] == '0')
- || (tm->data[6] == '3' && tm->data[7] > '1')
- || (tm->data[8] > '2')
- || (tm->data[8] == '2' && tm->data[9] > '3')
- || (tm->data[10] > '5'))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid value in "
- "NotValidBefore time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- snprintf (before, sizeof before, "%s", tm->data);
+ if (!x509_cert_get_key(icert, &key)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: failed to get public key from cert"));
+ free(ikey);
+ return 0;
}
-
- /* Fix missing seconds. */
- if (tm->length < 12)
- {
- before[12] = '0';
- before[13] = '0';
+ X509_OBJECT_free_contents(&obj);
+
+ dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
+ dc.dec_key = key;
+ skey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
+ KEYNOTE_PUBLIC_KEY);
+ if (keynote_errno == ERROR_MEMORY) {
+ log_error("x509_generate_kn: failed to get memory for public key");
+ free(ikey);
+ RSA_free(key);
+ LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer key"));
+ return 0;
}
-
- /* This will overwrite trailing 'Z'. */
- before[14] = '\0';
- }
-
- tm = X509_get_notAfter (cert);
- if (tm == NULL
- && (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME))
- {
- tt = time (0);
- strftime (after, 14, "%Y%m%d%H%M%S", localtime (&tt));
- timecomp2 = "LocalTimeOfDay";
- }
- else
- {
- if (tm->data[tm->length - 1] == 'Z')
- {
- timecomp2 = "GMTTimeOfDay";
- i = tm->length - 2;
+ if (!skey) {
+ free(ikey);
+ RSA_free(key);
+ LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer key"));
+ return 0;
}
- else
- {
- timecomp2 = "LocalTimeOfDay";
- i = tm->length - 1;
+ RSA_free(key);
+
+ buf_len = strlen(fmt) + strlen(ikey) + strlen(skey) + 56;
+ buf = calloc(buf_len, sizeof(char));
+ buf_len *= sizeof(char);
+ if (!buf) {
+ log_error("x509_generate_kn: "
+ "failed to allocate memory for KeyNote credential");
+ free(ikey);
+ free(skey);
+ return 0;
}
-
- for (; i >= 0; i--)
- {
- if (tm->data[i] < '0' || tm->data[i] > '9')
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid data in "
- "NotValidAfter time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
+ if (((tm = X509_get_notBefore(cert)) == NULL) ||
+ (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME)) {
+ tt = time(0);
+ strftime(before, 14, "%Y%m%d%H%M%S", localtime(&tt));
+ timecomp = "LocalTimeOfDay";
+ } else {
+ if (tm->data[tm->length - 1] == 'Z') {
+ timecomp = "GMTTimeOfDay";
+ i = tm->length - 2;
+ } else {
+ timecomp = "LocalTimeOfDay";
+ i = tm->length - 1;
+ }
+
+ for (; i >= 0; i--) {
+ if (tm->data[i] < '0' || tm->data[i] > '9') {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid data in "
+ "NotValidBefore time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ }
+
+ if (tm->type == V_ASN1_UTCTIME) {
+ if ((tm->length < 10) || (tm->length > 13)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid length "
+ "of NotValidBefore time field (%d)", tm->length));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Validity checks. */
+ if ((tm->data[2] != '0' && tm->data[2] != '1') ||
+ (tm->data[2] == '0' && tm->data[3] == '0') ||
+ (tm->data[2] == '1' && tm->data[3] > '2') ||
+ (tm->data[4] > '3') ||
+ (tm->data[4] == '0' && tm->data[5] == '0') ||
+ (tm->data[4] == '3' && tm->data[5] > '1') ||
+ (tm->data[6] > '2') ||
+ (tm->data[6] == '2' && tm->data[7] > '3') ||
+ (tm->data[8] > '5')) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid value in "
+ "NotValidBefore time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Stupid UTC tricks. */
+ if (tm->data[0] < '5')
+ snprintf(before, sizeof before, "20%s", tm->data);
+ else
+ snprintf(before, sizeof before, "19%s", tm->data);
+ } else { /* V_ASN1_GENERICTIME */
+ if ((tm->length < 12) || (tm->length > 15)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid length of "
+ "NotValidBefore time field (%d)", tm->length));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Validity checks. */
+ if ((tm->data[4] != '0' && tm->data[4] != '1') ||
+ (tm->data[4] == '0' && tm->data[5] == '0') ||
+ (tm->data[4] == '1' && tm->data[5] > '2') ||
+ (tm->data[6] > '3') ||
+ (tm->data[6] == '0' && tm->data[7] == '0') ||
+ (tm->data[6] == '3' && tm->data[7] > '1') ||
+ (tm->data[8] > '2') ||
+ (tm->data[8] == '2' && tm->data[9] > '3') ||
+ (tm->data[10] > '5')) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid value in "
+ "NotValidBefore time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ snprintf(before, sizeof before, "%s", tm->data);
+ }
+
+ /* Fix missing seconds. */
+ if (tm->length < 12) {
+ before[12] = '0';
+ before[13] = '0';
+ }
+ /* This will overwrite trailing 'Z'. */
+ before[14] = '\0';
}
- if (tm->type == V_ASN1_UTCTIME)
- {
- if ((tm->length < 10) || (tm->length > 13))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid length of "
- "NotValidAfter time field (%d)", tm->length));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Validity checks. */
- if ((tm->data[2] != '0' && tm->data[2] != '1')
- || (tm->data[2] == '0' && tm->data[3] == '0')
- || (tm->data[2] == '1' && tm->data[3] > '2')
- || (tm->data[4] > '3')
- || (tm->data[4] == '0' && tm->data[5] == '0')
- || (tm->data[4] == '3' && tm->data[5] > '1')
- || (tm->data[6] > '2')
- || (tm->data[6] == '2' && tm->data[7] > '3')
- || (tm->data[8] > '5'))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid value in "
- "NotValidAfter time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Stupid UTC tricks. */
- if (tm->data[0] < '5')
- snprintf (after, sizeof after, "20%s", tm->data);
- else
- snprintf (after, sizeof after, "19%s", tm->data);
+ tm = X509_get_notAfter(cert);
+ if (tm == NULL &&
+ (tm->type != V_ASN1_UTCTIME && tm->type != V_ASN1_GENERALIZEDTIME)) {
+ tt = time(0);
+ strftime(after, 14, "%Y%m%d%H%M%S", localtime(&tt));
+ timecomp2 = "LocalTimeOfDay";
+ } else {
+ if (tm->data[tm->length - 1] == 'Z') {
+ timecomp2 = "GMTTimeOfDay";
+ i = tm->length - 2;
+ } else {
+ timecomp2 = "LocalTimeOfDay";
+ i = tm->length - 1;
+ }
+
+ for (; i >= 0; i--) {
+ if (tm->data[i] < '0' || tm->data[i] > '9') {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid data in "
+ "NotValidAfter time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ }
+
+ if (tm->type == V_ASN1_UTCTIME) {
+ if ((tm->length < 10) || (tm->length > 13)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid length of "
+ "NotValidAfter time field (%d)", tm->length));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Validity checks. */
+ if ((tm->data[2] != '0' && tm->data[2] != '1') ||
+ (tm->data[2] == '0' && tm->data[3] == '0') ||
+ (tm->data[2] == '1' && tm->data[3] > '2') ||
+ (tm->data[4] > '3') ||
+ (tm->data[4] == '0' && tm->data[5] == '0') ||
+ (tm->data[4] == '3' && tm->data[5] > '1') ||
+ (tm->data[6] > '2') ||
+ (tm->data[6] == '2' && tm->data[7] > '3') ||
+ (tm->data[8] > '5')) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid value in "
+ "NotValidAfter time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Stupid UTC tricks. */
+ if (tm->data[0] < '5')
+ snprintf(after, sizeof after, "20%s", tm->data);
+ else
+ snprintf(after, sizeof after, "19%s", tm->data);
+ } else { /* V_ASN1_GENERICTIME */
+ if ((tm->length < 12) || (tm->length > 15)) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid length of "
+ "NotValidAfter time field (%d)", tm->length));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ /* Validity checks. */
+ if ((tm->data[4] != '0' && tm->data[4] != '1') ||
+ (tm->data[4] == '0' && tm->data[5] == '0') ||
+ (tm->data[4] == '1' && tm->data[5] > '2') ||
+ (tm->data[6] > '3') ||
+ (tm->data[6] == '0' && tm->data[7] == '0') ||
+ (tm->data[6] == '3' && tm->data[7] > '1') ||
+ (tm->data[8] > '2') ||
+ (tm->data[8] == '2' && tm->data[9] > '3') ||
+ (tm->data[10] > '5')) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: invalid value in "
+ "NotValidAfter time field"));
+ free(ikey);
+ free(skey);
+ free(buf);
+ return 0;
+ }
+ snprintf(after, sizeof after, "%s", tm->data);
+ }
+
+ /* Fix missing seconds. */
+ if (tm->length < 12) {
+ after[12] = '0';
+ after[13] = '0';
+ }
+ after[14] = '\0'; /* This will overwrite trailing 'Z' */
}
- else
- { /* V_ASN1_GENERICTIME */
- if ((tm->length < 12) || (tm->length > 15))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid length of "
- "NotValidAfter time field (%d)", tm->length));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- /* Validity checks. */
- if ((tm->data[4] != '0' && tm->data[4] != '1')
- || (tm->data[4] == '0' && tm->data[5] == '0')
- || (tm->data[4] == '1' && tm->data[5] > '2')
- || (tm->data[6] > '3')
- || (tm->data[6] == '0' && tm->data[7] == '0')
- || (tm->data[6] == '3' && tm->data[7] > '1')
- || (tm->data[8] > '2')
- || (tm->data[8] == '2' && tm->data[9] > '3')
- || (tm->data[10] > '5'))
- {
- LOG_DBG ((LOG_POLICY, 30, "x509_generate_kn: invalid value in "
- "NotValidAfter time field"));
- free (ikey);
- free (skey);
- free (buf);
- return 0;
- }
-
- snprintf (after, sizeof after, "%s", tm->data);
- }
-
- /* Fix missing seconds. */
- if (tm->length < 12)
- {
- after[12] = '0';
- after[13] = '0';
+
+ snprintf(buf, buf_len, fmt, skey, ikey, timecomp, before, timecomp2, after);
+ free(ikey);
+ free(skey);
+
+ if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: failed to add new KeyNote credential"));
+ free(buf);
+ return 0;
}
+ /* We could print the assertion here, but log_print() truncates... */
+ LOG_DBG((LOG_POLICY, 60, "x509_generate_kn: added credential"));
- after[14] = '\0'; /* This will overwrite trailing 'Z' */
- }
-
- snprintf (buf, buf_len, fmt, skey, ikey, timecomp, before, timecomp2, after);
- free (ikey);
- free (skey);
-
- if (kn_add_assertion (id, buf, strlen (buf), ASSERT_FLAG_LOCAL) == -1)
- {
- LOG_DBG ((LOG_POLICY, 30,
- "x509_generate_kn: failed to add new KeyNote credential"));
- free (buf);
- return 0;
- }
-
- /* We could print the assertion here, but log_print() truncates... */
- LOG_DBG ((LOG_POLICY, 60, "x509_generate_kn: added credential"));
-
- free (buf);
-
- if (!X509_NAME_oneline (issuer, isname, 256))
- {
- LOG_DBG ((LOG_POLICY, 50,
- "x509_generate_kn: X509_NAME_oneline (issuer, ...) failed"));
- return 0;
- }
-
- if (!X509_NAME_oneline (subject, subname, 256))
- {
- LOG_DBG ((LOG_POLICY, 50,
- "x509_generate_kn: X509_NAME_oneline (subject, ...) failed"));
- return 0;
- }
-
- buf_len = strlen (fmt2) + strlen (isname) + strlen (subname) + 56;
- buf = malloc (buf_len);
- if (!buf)
- {
- log_error ("x509_generate_kn: malloc (%d) failed", buf_len);
- return 0;
- }
-
- snprintf (buf, buf_len, fmt2, isname, subname, timecomp, before, timecomp2,
- after);
+ free(buf);
- if (kn_add_assertion (id, buf, strlen (buf), ASSERT_FLAG_LOCAL) == -1)
- {
- LOG_DBG ((LOG_POLICY, 30,
- "x509_generate_kn: failed to add new KeyNote credential"));
- free (buf);
- return 0;
- }
+ if (!X509_NAME_oneline(issuer, isname, 256)) {
+ LOG_DBG((LOG_POLICY, 50,
+ "x509_generate_kn: X509_NAME_oneline (issuer, ...) failed"));
+ return 0;
+ }
+ if (!X509_NAME_oneline(subject, subname, 256)) {
+ LOG_DBG((LOG_POLICY, 50,
+ "x509_generate_kn: X509_NAME_oneline (subject, ...) failed"));
+ return 0;
+ }
+ buf_len = strlen(fmt2) + strlen(isname) + strlen(subname) + 56;
+ buf = malloc(buf_len);
+ if (!buf) {
+ log_error("x509_generate_kn: malloc (%d) failed", buf_len);
+ return 0;
+ }
+ snprintf(buf, buf_len, fmt2, isname, subname, timecomp, before, timecomp2,
+ after);
- LOG_DBG ((LOG_POLICY, 80, "x509_generate_kn: added credential:\n%s", buf));
+ if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
+ LOG_DBG((LOG_POLICY, 30,
+ "x509_generate_kn: failed to add new KeyNote credential"));
+ free(buf);
+ return 0;
+ }
+ LOG_DBG((LOG_POLICY, 80, "x509_generate_kn: added credential:\n%s", buf));
- free (buf);
- return 1;
+ free(buf);
+ return 1;
}
-#endif /* USE_POLICY */
+#endif /* USE_POLICY */
static u_int16_t
-x509_hash (u_int8_t *id, size_t len)
+x509_hash(u_int8_t *id, size_t len)
{
- size_t i;
- u_int16_t bucket = 0;
-
- /* XXX We might resize if we are crossing a certain threshold. */
- for (i = 4; i < (len & ~1); i += 2)
- {
- /* Doing it this way avoids alignment problems. */
- bucket ^= (id[i] + 1) * (id[i + 1] + 257);
- }
- /* Hash in the last character of odd length IDs too. */
- if (i < len)
- bucket ^= (id[i] + 1) * (id[i] + 257);
-
- bucket &= bucket_mask;
-
- return bucket;
+ u_int16_t bucket = 0;
+ size_t i;
+
+ /* XXX We might resize if we are crossing a certain threshold. */
+ for (i = 4; i < (len & ~1); i += 2) {
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= (id[i] + 1) * (id[i + 1] + 257);
+ }
+ /* Hash in the last character of odd length IDs too. */
+ if (i < len)
+ bucket ^= (id[i] + 1) * (id[i] + 257);
+
+ bucket &= bucket_mask;
+ return bucket;
}
static void
-x509_hash_init (void)
+x509_hash_init(void)
{
- struct x509_hash *certh;
- int i;
-
- bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
-
- /* If reinitializing, free existing entries. */
- if (x509_tab)
- {
- for (i = 0; i <= bucket_mask; i++)
- for (certh = LIST_FIRST (&x509_tab[i]); certh;
- certh = LIST_FIRST (&x509_tab[i]))
- {
- LIST_REMOVE (certh, link);
- free (certh);
- }
-
- free (x509_tab);
- }
-
- x509_tab = malloc ((bucket_mask + 1) * sizeof (struct x509_list));
- if (!x509_tab)
- log_fatal ("x509_hash_init: malloc (%lu) failed",
- (bucket_mask + 1) * (unsigned long)sizeof (struct x509_list));
- for (i = 0; i <= bucket_mask; i++)
- {
- LIST_INIT (&x509_tab[i]);
- }
+ struct x509_hash *certh;
+ int i;
+
+ bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
+
+ /* If reinitializing, free existing entries. */
+ if (x509_tab) {
+ for (i = 0; i <= bucket_mask; i++)
+ for (certh = LIST_FIRST(&x509_tab[i]); certh;
+ certh = LIST_FIRST(&x509_tab[i])) {
+ LIST_REMOVE(certh, link);
+ free(certh);
+ }
+ free(x509_tab);
+ }
+ x509_tab = malloc((bucket_mask + 1) * sizeof(struct x509_list));
+ if (!x509_tab)
+ log_fatal("x509_hash_init: malloc (%lu) failed",
+ (bucket_mask + 1) * (unsigned long) sizeof(struct x509_list));
+ for (i = 0; i <= bucket_mask; i++) {
+ LIST_INIT(&x509_tab[i]);
+ }
}
/* Lookup a certificate by an ID blob. */
static X509 *
-x509_hash_find (u_int8_t *id, size_t len)
+x509_hash_find(u_int8_t *id, size_t len)
{
- struct x509_hash *cert;
- u_int8_t **cid;
- u_int32_t *clen;
- int n, i, id_found;
-
- for (cert = LIST_FIRST (&x509_tab[x509_hash (id, len)]); cert;
- cert = LIST_NEXT (cert, link))
- {
- if (!x509_cert_get_subjects (cert->cert, &n, &cid, &clen))
- continue;
-
- id_found = 0;
- for (i = 0; i < n; i++)
- {
- LOG_DBG_BUF ((LOG_CRYPTO, 70, "cert_cmp", id, len));
- LOG_DBG_BUF ((LOG_CRYPTO, 70, "cert_cmp", cid[i], clen[i]));
- /* XXX This identity predicate needs to be understood. */
- if (clen[i] == len && id[0] == cid[i][0]
- && memcmp (id + 4, cid[i] + 4, len - 4) == 0)
- {
- id_found++;
- break;
- }
+ struct x509_hash *cert;
+ u_int8_t **cid;
+ u_int32_t *clen;
+ int n, i, id_found;
+
+ for (cert = LIST_FIRST(&x509_tab[x509_hash(id, len)]); cert;
+ cert = LIST_NEXT(cert, link)) {
+ if (!x509_cert_get_subjects(cert->cert, &n, &cid, &clen))
+ continue;
+
+ id_found = 0;
+ for (i = 0; i < n; i++) {
+ LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", id, len));
+ LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", cid[i], clen[i]));
+ /*
+ * XXX This identity predicate needs to be
+ * understood.
+ */
+ if (clen[i] == len && id[0] == cid[i][0] &&
+ memcmp(id + 4, cid[i] + 4, len - 4) == 0) {
+ id_found++;
+ break;
+ }
+ }
+ cert_free_subjects(n, cid, clen);
+ if (!id_found)
+ continue;
+
+ LOG_DBG((LOG_CRYPTO, 70, "x509_hash_find: return X509 %p",
+ cert->cert));
+ return cert->cert;
}
- cert_free_subjects (n, cid, clen);
- if (!id_found)
- continue;
- LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_find: return X509 %p",
- cert->cert));
- return cert->cert;
- }
-
- LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_find: no certificate matched query"));
- return 0;
+ LOG_DBG((LOG_CRYPTO, 70, "x509_hash_find: no certificate matched query"));
+ return 0;
}
static int
-x509_hash_enter (X509 *cert)
+x509_hash_enter(X509 *cert)
{
- u_int16_t bucket = 0;
- u_int8_t **id;
- u_int32_t *len;
- struct x509_hash *certh;
- int n, i;
-
- if (!x509_cert_get_subjects (cert, &n, &id, &len))
- {
- log_print ("x509_hash_enter: cannot retrieve subjects");
- return 0;
- }
-
- for (i = 0; i < n; i++)
- {
- certh = calloc (1, sizeof *certh);
- if (!certh)
- {
- cert_free_subjects (n, id, len);
- log_error ("x509_hash_enter: calloc (1, %lu) failed",
- (unsigned long)sizeof *certh);
- return 0;
- }
-
- certh->cert = cert;
-
- bucket = x509_hash (id[i], len[i]);
-
- LIST_INSERT_HEAD (&x509_tab[bucket], certh, link);
- LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_enter: cert %p added to bucket %d",
- cert, bucket));
- }
- cert_free_subjects (n, id, len);
-
- return 1;
+ u_int16_t bucket = 0;
+ u_int8_t **id;
+ u_int32_t *len;
+ struct x509_hash *certh;
+ int n, i;
+
+ if (!x509_cert_get_subjects(cert, &n, &id, &len)) {
+ log_print("x509_hash_enter: cannot retrieve subjects");
+ return 0;
+ }
+ for (i = 0; i < n; i++) {
+ certh = calloc(1, sizeof *certh);
+ if (!certh) {
+ cert_free_subjects(n, id, len);
+ log_error("x509_hash_enter: calloc (1, %lu) failed",
+ (unsigned long) sizeof *certh);
+ return 0;
+ }
+ certh->cert = cert;
+
+ bucket = x509_hash(id[i], len[i]);
+
+ LIST_INSERT_HEAD(&x509_tab[bucket], certh, link);
+ LOG_DBG((LOG_CRYPTO, 70, "x509_hash_enter: cert %p added to bucket %d",
+ cert, bucket));
+ }
+ cert_free_subjects(n, id, len);
+
+ return 1;
}
/* X509 Certificate Handling functions. */
int
-x509_read_from_dir (X509_STORE *ctx, char *name, int hash)
+x509_read_from_dir(X509_STORE *ctx, char *name, int hash)
{
- struct dirent *file;
+ struct dirent *file;
#if defined (USE_PRIVSEP)
- struct monitor_dirents *dir;
- FILE *certfp;
+ struct monitor_dirents *dir;
+ FILE *certfp;
#else
- DIR *dir;
- BIO *certh;
+ DIR *dir;
+ BIO *certh;
#endif
- X509 *cert;
- char fullname[PATH_MAX];
- int off, size;
+ X509 *cert;
+ char fullname[PATH_MAX];
+ int off, size;
- if (strlen (name) >= sizeof fullname - 1)
- {
- log_print ("x509_read_from_dir: directory name too long");
- return 0;
- }
+ if (strlen(name) >= sizeof fullname - 1) {
+ log_print("x509_read_from_dir: directory name too long");
+ return 0;
+ }
+ LOG_DBG((LOG_CRYPTO, 40, "x509_read_from_dir: reading certs from %s",
+ name));
+
+ dir = monitor_opendir(name);
+ if (!dir) {
+ LOG_DBG((LOG_CRYPTO, 10,
+ "x509_read_from_dir: opendir (\"%s\") failed: "
+ "%s", name, strerror(errno)));
+ return 0;
+ }
+ strlcpy(fullname, name, sizeof fullname);
+ off = strlen(fullname);
+ size = sizeof fullname - off;
- LOG_DBG ((LOG_CRYPTO, 40, "x509_read_from_dir: reading certs from %s",
- name));
+ while ((file = monitor_readdir(dir)) != NULL) {
+ strlcpy(fullname + off, file->d_name, size);
- dir = monitor_opendir (name);
- if (!dir)
- {
- LOG_DBG ((LOG_CRYPTO, 10, "x509_read_from_dir: opendir (\"%s\") failed: "
- "%s", name, strerror (errno)));
- return 0;
- }
-
- strlcpy (fullname, name, sizeof fullname);
- off = strlen (fullname);
- size = sizeof fullname - off;
-
- while ((file = monitor_readdir (dir)) != NULL)
- {
- strlcpy (fullname + off, file->d_name, size);
-
- if (file->d_type != DT_UNKNOWN)
- {
- if (file->d_type != DT_REG && file->d_type != DT_LNK)
- continue;
- }
- else
- {
- struct stat sb;
-
- if (monitor_stat (fullname, &sb) == -1 || !(sb.st_mode & S_IFREG))
- continue;
- }
-
- LOG_DBG ((LOG_CRYPTO, 60, "x509_read_from_dir: reading certificate %s",
- file->d_name));
+ if (file->d_type != DT_UNKNOWN) {
+ if (file->d_type != DT_REG && file->d_type != DT_LNK)
+ continue;
+ } else {
+ struct stat sb;
-#if defined (USE_PRIVSEP)
- certfp = monitor_fopen (fullname, "r");
- if (!certfp)
- {
- log_error ("x509_read_from_dir: monitor_fopen (\"%s\", \"r\") failed",
- fullname);
- continue;
- }
+ if (monitor_stat(fullname, &sb) == -1 ||
+ !(sb.st_mode & S_IFREG))
+ continue;
+ }
+
+ LOG_DBG((LOG_CRYPTO, 60, "x509_read_from_dir: reading certificate %s",
+ file->d_name));
+#if defined (USE_PRIVSEP)
+ certfp = monitor_fopen(fullname, "r");
+ if (!certfp) {
+ log_error("x509_read_from_dir: monitor_fopen "
+ "(\"%s\", \"r\") failed",
+ fullname);
+ continue;
+ }
#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- cert = PEM_read_X509 (certfp, NULL, NULL, NULL);
+ cert = PEM_read_X509(certfp, NULL, NULL, NULL);
#else
- cert = PEM_read_X509 (certfp, NULL, NULL);
+ cert = PEM_read_X509(certfp, NULL, NULL);
#endif
- fclose (certfp);
+ fclose(certfp);
#else
- certh = BIO_new (BIO_s_file ());
- if (!certh)
- {
- log_error ("x509_read_from_dir: BIO_new (BIO_s_file ()) failed");
- continue;
- }
-
- if (BIO_read_filename (certh, fullname) == -1)
- {
- BIO_free (certh);
- log_error ("x509_read_from_dir: "
- "BIO_read_filename (certh, \"%s\") failed",
- fullname);
- continue;
- }
-
+ certh = BIO_new(BIO_s_file());
+ if (!certh) {
+ log_error("x509_read_from_dir: BIO_new (BIO_s_file ()) failed");
+ continue;
+ }
+ if (BIO_read_filename(certh, fullname) == -1) {
+ BIO_free(certh);
+ log_error("x509_read_from_dir: "
+ "BIO_read_filename (certh, \"%s\") failed",
+ fullname);
+ continue;
+ }
#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- cert = PEM_read_bio_X509 (certh, NULL, NULL, NULL);
+ cert = PEM_read_bio_X509(certh, NULL, NULL, NULL);
#else
- cert = PEM_read_bio_X509 (certh, NULL, NULL);
+ cert = PEM_read_bio_X509(certh, NULL, NULL);
#endif
- BIO_free (certh);
-#endif /* USE_PRIVSEP */
- if (cert == NULL)
- {
- log_print ("x509_read_from_dir: PEM_read_bio_X509 failed for %s",
- file->d_name);
- continue;
- }
-
- if (!X509_STORE_add_cert (ctx, cert))
- {
- /*
- * This is actually expected if we have several certificates only
- * differing in subjectAltName, which is not an something that is
- * strange. Consider multi-homed machines.
- */
- LOG_DBG ((LOG_CRYPTO, 50,
- "x509_read_from_dir: X509_STORE_add_cert failed for %s",
- file->d_name));
+ BIO_free(certh);
+#endif /* USE_PRIVSEP */
+ if (cert == NULL) {
+ log_print("x509_read_from_dir: PEM_read_bio_X509 failed for %s",
+ file->d_name);
+ continue;
+ }
+ if (!X509_STORE_add_cert(ctx, cert)) {
+ /*
+ * This is actually expected if we have several
+ * certificates only differing in subjectAltName, which
+ * is not an something that is strange. Consider
+ * multi-homed machines.
+ */
+ LOG_DBG((LOG_CRYPTO, 50,
+ "x509_read_from_dir: X509_STORE_add_cert failed for %s",
+ file->d_name));
+ }
+ if (hash)
+ if (!x509_hash_enter(cert))
+ log_print("x509_read_from_dir: x509_hash_enter "
+ "(%s) failed",
+ file->d_name);
}
- if (hash)
- if (!x509_hash_enter (cert))
- log_print ("x509_read_from_dir: x509_hash_enter (%s) failed",
- file->d_name);
- }
-
- monitor_closedir (dir);
+ monitor_closedir(dir);
- return 1;
+ return 1;
}
/* XXX share code with x509_read_from_dir() ? */
int
-x509_read_crls_from_dir (X509_STORE *ctx, char *name)
+x509_read_crls_from_dir(X509_STORE *ctx, char *name)
{
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- struct dirent *file;
+ struct dirent *file;
#if defined (USE_PRIVSEP)
- struct monitor_dirents *dir;
- FILE *crlfp;
+ struct monitor_dirents *dir;
+ FILE *crlfp;
#else
- DIR *dir;
- BIO *crlh;
+ DIR *dir;
+ BIO *crlh;
#endif
- X509_CRL *crl;
- char fullname[PATH_MAX];
- int off, size;
+ X509_CRL *crl;
+ char fullname[PATH_MAX];
+ int off, size;
- if (strlen (name) >= sizeof fullname - 1)
- {
- log_print ("x509_read_crls_from_dir: directory name too long");
- return 0;
- }
-
- LOG_DBG ((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs from %s",
+ if (strlen(name) >= sizeof fullname - 1) {
+ log_print("x509_read_crls_from_dir: directory name too long");
+ return 0;
+ }
+ LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs from %s",
name));
- dir = monitor_opendir (name);
- if (!dir)
- {
- LOG_DBG ((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir (\"%s\") "
- "failed: %s", name, strerror (errno)));
- return 0;
- }
-
- strlcpy (fullname, name, sizeof fullname);
- off = strlen (fullname);
- size = sizeof fullname - off;
-
- while ((file = monitor_readdir (dir)) != NULL)
- {
- strlcpy (fullname + off, file->d_name, size);
-
- if (file->d_type != DT_UNKNOWN)
- {
- if (file->d_type != DT_REG && file->d_type != DT_LNK)
- continue;
- }
- else
- {
- struct stat sb;
-
- if (monitor_stat (fullname, &sb) == -1 || !(sb.st_mode & S_IFREG))
- continue;
- }
-
- LOG_DBG ((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading CRL %s",
- file->d_name));
-
-#if defined (USE_PRIVSEP)
- crlfp = monitor_fopen (fullname, "r");
- if (!crlfp)
- {
- log_error ("x509_read_crls_from_dir: monitor_fopen (\"%s\", \"r\") "
- "failed", fullname);
- continue;
+ dir = monitor_opendir(name);
+ if (!dir) {
+ LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir (\"%s\") "
+ "failed: %s", name, strerror(errno)));
+ return 0;
}
+ strlcpy(fullname, name, sizeof fullname);
+ off = strlen(fullname);
+ size = sizeof fullname - off;
- crl = PEM_read_X509_CRL (crlfp, NULL, NULL, NULL);
- fclose (crlfp);
-#else
- crlh = BIO_new (BIO_s_file ());
- if (!crlh)
- {
- log_error ("x509_read_crls_from_dir: "
- "BIO_new (BIO_s_file ()) failed");
- continue;
- }
+ while ((file = monitor_readdir(dir)) != NULL) {
+ strlcpy(fullname + off, file->d_name, size);
- if (BIO_read_filename (crlh, fullname) == -1)
- {
- BIO_free (crlh);
- log_error ("x509_read_crls_from_dir: "
- "BIO_read_filename (crlh, \"%s\") failed", fullname);
- continue;
- }
+ if (file->d_type != DT_UNKNOWN) {
+ if (file->d_type != DT_REG && file->d_type != DT_LNK)
+ continue;
+ } else {
+ struct stat sb;
- crl = PEM_read_bio_X509_CRL (crlh, NULL, NULL, NULL);
+ if (monitor_stat(fullname, &sb) == -1 || !(sb.st_mode & S_IFREG))
+ continue;
+ }
- BIO_free (crlh);
-#endif /* USE_PRIVSEP */
- if (crl == NULL)
- {
- log_print ("x509_read_crls_from_dir: "
- "PEM_read_bio_X509_CRL failed for %s", file->d_name);
- continue;
- }
+ LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading CRL %s",
+ file->d_name));
- if (!X509_STORE_add_crl (ctx, crl))
- {
- LOG_DBG ((LOG_CRYPTO, 50, "x509_read_crls_from_dir: "
- "X509_STORE_add_crl failed for %s", file->d_name));
- continue;
+#if defined (USE_PRIVSEP)
+ crlfp = monitor_fopen(fullname, "r");
+ if (!crlfp) {
+ log_error("x509_read_crls_from_dir: monitor_fopen "
+ "(\"%s\", \"r\") failed", fullname);
+ continue;
+ }
+ crl = PEM_read_X509_CRL(crlfp, NULL, NULL, NULL);
+ fclose(crlfp);
+#else
+ crlh = BIO_new(BIO_s_file());
+ if (!crlh) {
+ log_error("x509_read_crls_from_dir: "
+ "BIO_new (BIO_s_file ()) failed");
+ continue;
+ }
+ if (BIO_read_filename(crlh, fullname) == -1) {
+ BIO_free(crlh);
+ log_error("x509_read_crls_from_dir: "
+ "BIO_read_filename (crlh, \"%s\") failed", fullname);
+ continue;
+ }
+ crl = PEM_read_bio_X509_CRL(crlh, NULL, NULL, NULL);
+
+ BIO_free(crlh);
+#endif /* USE_PRIVSEP */
+ if (crl == NULL) {
+ log_print("x509_read_crls_from_dir: "
+ "PEM_read_bio_X509_CRL failed for %s", file->d_name);
+ continue;
+ }
+ if (!X509_STORE_add_crl(ctx, crl)) {
+ LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: "
+ "X509_STORE_add_crl failed for %s", file->d_name));
+ continue;
+ }
+ /*
+ * XXX This is to make x509_cert_validate set this (and another) flag
+ * XXX when validating certificates. Currently, OpenSSL defaults to
+ * XXX reject an otherwise valid certificate (chain) if these flags
+ * XXX are set but there are no CRLs to check. The current workaround
+ * XXX is to only set the flags if we actually loaded some CRL data.
+ */
+ X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
}
- /*
- * XXX This is to make x509_cert_validate set this (and another) flag
- * XXX when validating certificates. Currently, OpenSSL defaults to
- * XXX reject an otherwise valid certificate (chain) if these flags
- * XXX are set but there are no CRLs to check. The current workaround
- * XXX is to only set the flags if we actually loaded some CRL data.
- */
- X509_STORE_set_flags (ctx, X509_V_FLAG_CRL_CHECK);
- }
-
- monitor_closedir (dir);
-#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
+ monitor_closedir(dir);
+#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
- return 1;
+ return 1;
}
/* Initialize our databases and load our own certificates. */
int
-x509_cert_init (void)
+x509_cert_init(void)
{
- char *dirname;
-
- x509_hash_init ();
-
- /* Process CA certificates we will trust. */
- dirname = conf_get_str ("X509-certificates", "CA-directory");
- if (!dirname)
- {
- log_print ("x509_cert_init: no CA-directory");
- return 0;
- }
-
- /* Free if already initialized. */
- if (x509_cas)
- X509_STORE_free (x509_cas);
-
- x509_cas = X509_STORE_new ();
- if (!x509_cas)
- {
- log_print ("x509_cert_init: creating new X509_STORE failed");
- return 0;
- }
-
- if (!x509_read_from_dir (x509_cas, dirname, 0))
- {
- log_print ("x509_cert_init: x509_read_from_dir failed");
- return 0;
- }
-
- /* Process client certificates we will accept. */
- dirname = conf_get_str ("X509-certificates", "Cert-directory");
- if (!dirname)
- {
- log_print ("x509_cert_init: no Cert-directory");
- return 0;
- }
-
- /* Free if already initialized. */
- if (x509_certs)
- X509_STORE_free (x509_certs);
-
- x509_certs = X509_STORE_new ();
- if (!x509_certs)
- {
- log_print ("x509_cert_init: creating new X509_STORE failed");
- return 0;
- }
-
- if (!x509_read_from_dir (x509_certs, dirname, 1))
- {
- log_print ("x509_cert_init: x509_read_from_dir failed");
- return 0;
- }
-
- return 1;
+ char *dirname;
+
+ x509_hash_init();
+
+ /* Process CA certificates we will trust. */
+ dirname = conf_get_str("X509-certificates", "CA-directory");
+ if (!dirname) {
+ log_print("x509_cert_init: no CA-directory");
+ return 0;
+ }
+ /* Free if already initialized. */
+ if (x509_cas)
+ X509_STORE_free(x509_cas);
+
+ x509_cas = X509_STORE_new();
+ if (!x509_cas) {
+ log_print("x509_cert_init: creating new X509_STORE failed");
+ return 0;
+ }
+ if (!x509_read_from_dir(x509_cas, dirname, 0)) {
+ log_print("x509_cert_init: x509_read_from_dir failed");
+ return 0;
+ }
+ /* Process client certificates we will accept. */
+ dirname = conf_get_str("X509-certificates", "Cert-directory");
+ if (!dirname) {
+ log_print("x509_cert_init: no Cert-directory");
+ return 0;
+ }
+ /* Free if already initialized. */
+ if (x509_certs)
+ X509_STORE_free(x509_certs);
+
+ x509_certs = X509_STORE_new();
+ if (!x509_certs) {
+ log_print("x509_cert_init: creating new X509_STORE failed");
+ return 0;
+ }
+ if (!x509_read_from_dir(x509_certs, dirname, 1)) {
+ log_print("x509_cert_init: x509_read_from_dir failed");
+ return 0;
+ }
+ return 1;
}
int
-x509_crl_init (void)
+x509_crl_init(void)
{
- /*
- * XXX I'm not sure if the method to use CRLs in certificate validation
- * is valid for OpenSSL versions prior to 0.9.7. For now, simply do not
- * support it.
- */
+ /*
+ * XXX I'm not sure if the method to use CRLs in certificate validation
+ * is valid for OpenSSL versions prior to 0.9.7. For now, simply do not
+ * support it.
+ */
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- char *dirname;
- dirname = conf_get_str ("X509-certificates", "CRL-directory");
- if (!dirname)
- {
- log_print ("x509_crl_init: no CRL-directory");
- return 0;
- }
-
- if (!x509_read_crls_from_dir (x509_cas, dirname))
- {
- LOG_DBG ((LOG_MISC, 10, "x509_crl_init: x509_read_crls_from_dir failed"));
- return 0;
- }
+ char *dirname;
+ dirname = conf_get_str("X509-certificates", "CRL-directory");
+ if (!dirname) {
+ log_print("x509_crl_init: no CRL-directory");
+ return 0;
+ }
+ if (!x509_read_crls_from_dir(x509_cas, dirname)) {
+ LOG_DBG((LOG_MISC, 10,
+ "x509_crl_init: x509_read_crls_from_dir failed"));
+ return 0;
+ }
#else
- LOG_DBG ((LOG_CRYPTO, 10, "x509_crl_init: CRL support only "
+ LOG_DBG((LOG_CRYPTO, 10, "x509_crl_init: CRL support only "
"with OpenSSL v0.9.7 or later"));
#endif
- return 1;
+ return 1;
}
void *
-x509_cert_get (u_int8_t *asn, u_int32_t len)
+x509_cert_get(u_int8_t *asn, u_int32_t len)
{
- return x509_from_asn (asn, len);
+ return x509_from_asn(asn, len);
}
int
-x509_cert_validate (void *scert)
+x509_cert_validate(void *scert)
{
- X509_STORE_CTX csc;
- X509_NAME *issuer, *subject;
- X509 *cert = (X509 *)scert;
- EVP_PKEY *key;
- int res, err;
-
- /*
- * Validate the peer certificate by checking with the CA certificates we
- * trust.
- */
- X509_STORE_CTX_init (&csc, x509_cas, cert, NULL);
+ X509_STORE_CTX csc;
+ X509_NAME *issuer, *subject;
+ X509 *cert = (X509 *) scert;
+ EVP_PKEY *key;
+ int res, err;
+
+ /*
+ * Validate the peer certificate by checking with the CA certificates we
+ * trust.
+ */
+ X509_STORE_CTX_init(&csc, x509_cas, cert, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- /* XXX See comment in x509_read_crls_from_dir. */
- if (x509_cas->flags & X509_V_FLAG_CRL_CHECK)
- {
- X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK);
- X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK_ALL);
- }
+ /* XXX See comment in x509_read_crls_from_dir. */
+ if (x509_cas->flags & X509_V_FLAG_CRL_CHECK) {
+ X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK);
+ X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL);
+ }
#endif
- res = X509_verify_cert (&csc);
- err = csc.error;
- X509_STORE_CTX_cleanup (&csc);
-
- /* Return if validation succeeded or self-signed certs are not accepted. */
- if (res)
- return 1;
- else if (!conf_get_str ("X509-certificates", "Accept-self-signed"))
- {
- if (err)
- log_print ("x509_cert_validate: %.100s",
- X509_verify_cert_error_string (err));
- return res;
- }
-
- issuer = X509_get_issuer_name (cert);
- subject = X509_get_subject_name (cert);
-
- if (!issuer || !subject || X509_name_cmp (issuer, subject))
- return 0;
-
- key = X509_get_pubkey (cert);
- if (!key)
- {
- log_print ("x509_cert_validate: could not get public key from "
- "self-signed cert");
- return 0;
- }
-
- if (X509_verify (cert, key) == -1)
- {
- log_print ("x509_cert_validate: self-signed cert is bad");
- return 0;
- }
-
- return 1;
+ res = X509_verify_cert(&csc);
+ err = csc.error;
+ X509_STORE_CTX_cleanup(&csc);
+
+ /*
+ * Return if validation succeeded or self-signed certs are not
+ * accepted.
+ */
+ if (res)
+ return 1;
+ else if (!conf_get_str("X509-certificates", "Accept-self-signed")) {
+ if (err)
+ log_print("x509_cert_validate: %.100s",
+ X509_verify_cert_error_string(err));
+ return res;
+ }
+ issuer = X509_get_issuer_name(cert);
+ subject = X509_get_subject_name(cert);
+
+ if (!issuer || !subject || X509_name_cmp(issuer, subject))
+ return 0;
+
+ key = X509_get_pubkey(cert);
+ if (!key) {
+ log_print("x509_cert_validate: could not get public key from "
+ "self-signed cert");
+ return 0;
+ }
+ if (X509_verify(cert, key) == -1) {
+ log_print("x509_cert_validate: self-signed cert is bad");
+ return 0;
+ }
+ return 1;
}
int
-x509_cert_insert (int id, void *scert)
+x509_cert_insert(int id, void *scert)
{
- X509 *cert;
- int res;
-
- cert = X509_dup ((X509 *)scert);
- if (!cert)
- {
- log_print ("x509_cert_insert: X509_dup failed");
- return 0;
- }
+ X509 *cert;
+ int res;
+ cert = X509_dup((X509 *) scert);
+ if (!cert) {
+ log_print("x509_cert_insert: X509_dup failed");
+ return 0;
+ }
#ifdef USE_POLICY
- if (x509_generate_kn (id, cert) == 0)
- {
- LOG_DBG ((LOG_POLICY, 50,
- "x509_cert_insert: x509_generate_kn failed"));
- X509_free (cert);
- return 0;
- }
-#endif /* USE_POLICY */
-
- res = x509_hash_enter (cert);
- if (!res)
- X509_free (cert);
-
- return res;
+ if (x509_generate_kn(id, cert) == 0) {
+ LOG_DBG((LOG_POLICY, 50,
+ "x509_cert_insert: x509_generate_kn failed"));
+ X509_free(cert);
+ return 0;
+ }
+#endif /* USE_POLICY */
+
+ res = x509_hash_enter(cert);
+ if (!res)
+ X509_free(cert);
+
+ return res;
}
static struct x509_hash *
-x509_hash_lookup (X509 *cert)
+x509_hash_lookup(X509 *cert)
{
- int i;
- struct x509_hash *certh;
-
- for (i = 0; i <= bucket_mask; i++)
- for (certh = LIST_FIRST (&x509_tab[i]); certh;
- certh = LIST_NEXT (certh, link))
- if (certh->cert == cert)
- return certh;
- return 0;
+ int i;
+ struct x509_hash *certh;
+
+ for (i = 0; i <= bucket_mask; i++)
+ for (certh = LIST_FIRST(&x509_tab[i]); certh;
+ certh = LIST_NEXT(certh, link))
+ if (certh->cert == cert)
+ return certh;
+ return 0;
}
void
-x509_cert_free (void *cert)
+x509_cert_free(void *cert)
{
- struct x509_hash *certh = x509_hash_lookup ((X509 *)cert);
+ struct x509_hash *certh = x509_hash_lookup((X509 *) cert);
- if (certh)
- LIST_REMOVE (certh, link);
- X509_free ((X509 *)cert);
+ if (certh)
+ LIST_REMOVE(certh, link);
+ X509_free((X509 *) cert);
}
/* Validate the BER Encoding of a RDNSequence in the CERT_REQ payload. */
int
-x509_certreq_validate (u_int8_t *asn, u_int32_t len)
+x509_certreq_validate(u_int8_t *asn, u_int32_t len)
{
- int res = 1;
+ int res = 1;
#if 0
- struct norm_type name = SEQOF ("issuer", RDNSequence);
-
- if (!asn_template_clone (&name, 1)
- || (asn = asn_decode_sequence (asn, len, &name)) == 0)
- {
- log_print ("x509_certreq_validate: can not decode 'acceptable CA' info");
- res = 0;
- }
- asn_free (&name);
+ struct norm_type name = SEQOF("issuer", RDNSequence);
+
+ if (!asn_template_clone(&name, 1) ||
+ (asn = asn_decode_sequence(asn, len, &name)) == 0) {
+ log_print("x509_certreq_validate: can not decode 'acceptable CA' info");
+ res = 0;
+ }
+ asn_free(&name);
#endif
- /* XXX - not supported directly in SSL - later. */
+ /* XXX - not supported directly in SSL - later. */
- return res;
+ return res;
}
/* Decode the BER Encoding of a RDNSequence in the CERT_REQ payload. */
void *
-x509_certreq_decode (u_int8_t *asn, u_int32_t len)
+x509_certreq_decode(u_int8_t *asn, u_int32_t len)
{
#if 0
- /* XXX This needs to be done later. */
- struct norm_type aca = SEQOF ("aca", RDNSequence);
- struct norm_type *tmp;
- struct x509_aca naca, *ret;
-
- if (!asn_template_clone (&aca, 1)
- || (asn = asn_decode_sequence (asn, len, &aca)) == 0)
- {
- log_print ("x509_certreq_decode: can not decode 'acceptable CA' info");
- goto fail;
- }
- memset (&naca, 0, sizeof (naca));
-
- tmp = asn_decompose ("aca.RelativeDistinguishedName.AttributeValueAssertion",
- &aca);
- if (!tmp)
- goto fail;
- x509_get_attribval (tmp, &naca.name1);
-
- tmp = asn_decompose ("aca.RelativeDistinguishedName[1]"
- ".AttributeValueAssertion", &aca);
- if (tmp)
- x509_get_attribval (tmp, &naca.name2);
-
- asn_free (&aca);
-
- ret = malloc (sizeof (struct x509_aca));
- if (ret)
- memcpy (ret, &naca, sizeof (struct x509_aca));
- else
- {
- log_error ("x509_certreq_decode: malloc (%lu) failed",
- (unsigned long)sizeof (struct x509_aca));
- x509_free_aca (&aca);
- }
-
- return ret;
-
- fail:
- asn_free (&aca);
+ /* XXX This needs to be done later. */
+ struct norm_type aca = SEQOF("aca", RDNSequence);
+ struct norm_type *tmp;
+ struct x509_aca naca, *ret;
+
+ if (!asn_template_clone(&aca, 1) ||
+ (asn = asn_decode_sequence(asn, len, &aca)) == 0) {
+ log_print("x509_certreq_decode: can not decode 'acceptable CA' info");
+ goto fail;
+ }
+ memset(&naca, 0, sizeof(naca));
+
+ tmp = asn_decompose("aca.RelativeDistinguishedName.AttributeValueAssertion",
+ &aca);
+ if (!tmp)
+ goto fail;
+ x509_get_attribval(tmp, &naca.name1);
+
+ tmp = asn_decompose("aca.RelativeDistinguishedName[1]"
+ ".AttributeValueAssertion", &aca);
+ if (tmp)
+ x509_get_attribval(tmp, &naca.name2);
+
+ asn_free(&aca);
+
+ ret = malloc(sizeof(struct x509_aca));
+ if (ret)
+ memcpy(ret, &naca, sizeof(struct x509_aca));
+ else {
+ log_error("x509_certreq_decode: malloc (%lu) failed",
+ (unsigned long) sizeof(struct x509_aca));
+ x509_free_aca(&aca);
+ }
+
+ return ret;
+
+fail:
+ asn_free(&aca);
#endif
- return 0;
+ return 0;
}
void
-x509_free_aca (void *blob)
+x509_free_aca(void *blob)
{
- struct x509_aca *aca = blob;
+ struct x509_aca *aca = blob;
- if (aca->name1.type)
- free (aca->name1.type);
- if (aca->name1.val)
- free (aca->name1.val);
+ if (aca->name1.type)
+ free(aca->name1.type);
+ if (aca->name1.val)
+ free(aca->name1.val);
- if (aca->name2.type)
- free (aca->name2.type);
- if (aca->name2.val)
- free (aca->name2.val);
+ if (aca->name2.type)
+ free(aca->name2.type);
+ if (aca->name2.val)
+ free(aca->name2.val);
}
X509 *
-x509_from_asn (u_char *asn, u_int len)
+x509_from_asn(u_char *asn, u_int len)
{
- BIO *certh;
- X509 *scert = 0;
-
- certh = BIO_new (BIO_s_mem ());
- if (!certh)
- {
- log_error ("x509_from_asn: BIO_new (BIO_s_mem ()) failed");
- return 0;
- }
-
- if (BIO_write (certh, asn, len) == -1)
- {
- log_error ("x509_from_asn: BIO_write failed\n");
- goto end;
- }
-
- scert = d2i_X509_bio (certh, NULL);
- if (!scert)
- {
- log_print ("x509_from_asn: d2i_X509_bio failed\n");
- goto end;
- }
-
- end:
- BIO_free (certh);
- return scert;
+ BIO *certh;
+ X509 *scert = 0;
+
+ certh = BIO_new(BIO_s_mem());
+ if (!certh) {
+ log_error("x509_from_asn: BIO_new (BIO_s_mem ()) failed");
+ return 0;
+ }
+ if (BIO_write(certh, asn, len) == -1) {
+ log_error("x509_from_asn: BIO_write failed\n");
+ goto end;
+ }
+ scert = d2i_X509_bio(certh, NULL);
+ if (!scert) {
+ log_print("x509_from_asn: d2i_X509_bio failed\n");
+ goto end;
+ }
+end:
+ BIO_free(certh);
+ return scert;
}
/*
@@ -1233,338 +1102,304 @@ x509_from_asn (u_char *asn, u_int len)
* XXX We don't check if the certificate we find is from an accepted CA.
*/
int
-x509_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
- u_int32_t *certlen)
+x509_cert_obtain(u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
+ u_int32_t *certlen)
{
- struct x509_aca *aca = data;
- X509 *scert;
-
- if (aca)
- LOG_DBG ((LOG_CRYPTO, 60,
- "x509_cert_obtain: acceptable certificate authorities here"));
-
- /* We need our ID to find a certificate. */
- if (!id)
- {
- log_print ("x509_cert_obtain: ID is missing");
- return 0;
- }
-
- scert = x509_hash_find (id, id_len);
- if (!scert)
- return 0;
-
- x509_serialize (scert, cert, certlen);
- if (!*cert)
- return 0;
- return 1;
+ struct x509_aca *aca = data;
+ X509 *scert;
+
+ if (aca)
+ LOG_DBG((LOG_CRYPTO, 60,
+ "x509_cert_obtain: acceptable certificate authorities here"));
+
+ /* We need our ID to find a certificate. */
+ if (!id) {
+ log_print("x509_cert_obtain: ID is missing");
+ return 0;
+ }
+ scert = x509_hash_find(id, id_len);
+ if (!scert)
+ return 0;
+
+ x509_serialize(scert, cert, certlen);
+ if (!*cert)
+ return 0;
+ return 1;
}
/* Returns a pointer to the subjectAltName information of X509 certificate. */
int
-x509_cert_subjectaltname (X509 *scert, u_int8_t **altname, u_int32_t *len)
+x509_cert_subjectaltname(X509 *scert, u_int8_t **altname, u_int32_t *len)
{
- X509_EXTENSION *subjectaltname;
- u_int8_t *sandata;
- int extpos;
- int santype, sanlen;
-
- extpos = X509_get_ext_by_NID (scert, NID_subject_alt_name, -1);
- if (extpos == -1)
- {
- log_print ("x509_cert_subjectaltname: "
- "certificate does not contain subjectAltName");
- return 0;
- }
-
- subjectaltname = X509_get_ext (scert, extpos);
-
- if (!subjectaltname || !subjectaltname->value
- || !subjectaltname->value->data || subjectaltname->value->length < 4)
- {
- log_print ("x509_cert_subjectaltname: invalid subjectaltname extension");
- return 0;
- }
-
- /* SSL does not handle unknown ASN stuff well, do it by hand. */
- sandata = subjectaltname->value->data;
- santype = sandata[2] & 0x3f;
- sanlen = sandata[3];
- sandata += 4;
-
- if (sanlen + 4 != subjectaltname->value->length)
- {
- log_print ("x509_cert_subjectaltname: subjectaltname invalid length");
- return 0;
- }
-
- *len = sanlen;
- *altname = sandata;
-
- return santype;
+ X509_EXTENSION *subjectaltname;
+ u_int8_t *sandata;
+ int extpos;
+ int santype, sanlen;
+
+ extpos = X509_get_ext_by_NID(scert, NID_subject_alt_name, -1);
+ if (extpos == -1) {
+ log_print("x509_cert_subjectaltname: "
+ "certificate does not contain subjectAltName");
+ return 0;
+ }
+ subjectaltname = X509_get_ext(scert, extpos);
+
+ if (!subjectaltname || !subjectaltname->value ||
+ !subjectaltname->value->data || subjectaltname->value->length < 4) {
+ log_print("x509_cert_subjectaltname: invalid subjectaltname extension");
+ return 0;
+ }
+ /* SSL does not handle unknown ASN stuff well, do it by hand. */
+ sandata = subjectaltname->value->data;
+ santype = sandata[2] & 0x3f;
+ sanlen = sandata[3];
+ sandata += 4;
+
+ if (sanlen + 4 != subjectaltname->value->length) {
+ log_print("x509_cert_subjectaltname: subjectaltname invalid length");
+ return 0;
+ }
+ *len = sanlen;
+ *altname = sandata;
+ return santype;
}
int
-x509_cert_get_subjects (void *scert, int *cnt, u_int8_t ***id,
- u_int32_t **id_len)
+x509_cert_get_subjects(void *scert, int *cnt, u_int8_t ***id,
+ u_int32_t **id_len)
{
- X509 *cert = scert;
- X509_NAME *subject;
- int type;
- u_int8_t *altname;
- u_int32_t altlen;
- u_int8_t *buf = 0;
- unsigned char *ubuf;
- int i;
-
- *id = 0;
- *id_len = 0;
-
- /*
- * XXX There can be a collection of subjectAltNames, but for now
- * I only return the subjectName and a single subjectAltName, if present.
- */
- type = x509_cert_subjectaltname (cert, &altname, &altlen);
- if (!type)
- {
- *cnt = 1;
- altlen = 0;
- }
- else
- *cnt = 2;
-
- *id = calloc (*cnt, sizeof **id);
- if (!*id)
- {
- log_print ("x509_cert_get_subject: malloc (%lu) failed",
- *cnt * (unsigned long)sizeof **id);
- goto fail;
- }
-
- *id_len = malloc (*cnt * sizeof **id_len);
- if (!*id_len)
- {
- log_print ("x509_cert_get_subject: malloc (%lu) failed",
- *cnt * (unsigned long)sizeof **id_len);
- goto fail;
- }
-
- /* Stash the subjectName into the first slot. */
- subject = X509_get_subject_name (cert);
- if (!subject)
- goto fail;
-
- (*id_len)[0] =
- ISAKMP_ID_DATA_OFF + i2d_X509_NAME (subject, NULL) - ISAKMP_GEN_SZ;
- (*id)[0] = malloc ((*id_len)[0]);
- if (!(*id)[0])
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed", (*id_len)[0]);
- goto fail;
- }
- SET_ISAKMP_ID_TYPE ((*id)[0] - ISAKMP_GEN_SZ, IPSEC_ID_DER_ASN1_DN);
- ubuf = (*id)[0] + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
- i2d_X509_NAME (subject, &ubuf);
-
- if (altlen)
- {
- /* Stash the subjectAltName into the second slot. */
- buf = malloc (altlen + ISAKMP_ID_DATA_OFF);
- if (!buf)
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed",
- altlen + ISAKMP_ID_DATA_OFF);
- goto fail;
+ X509 *cert = scert;
+ X509_NAME *subject;
+ int type;
+ u_int8_t *altname;
+ u_int32_t altlen;
+ u_int8_t *buf = 0;
+ unsigned char *ubuf;
+ int i;
+
+ *id = 0;
+ *id_len = 0;
+
+ /*
+ * XXX There can be a collection of subjectAltNames, but for now
+ * I only return the subjectName and a single subjectAltName, if present.
+ */
+ type = x509_cert_subjectaltname(cert, &altname, &altlen);
+ if (!type) {
+ *cnt = 1;
+ altlen = 0;
+ } else
+ *cnt = 2;
+
+ *id = calloc(*cnt, sizeof **id);
+ if (!*id) {
+ log_print("x509_cert_get_subject: malloc (%lu) failed",
+ *cnt * (unsigned long) sizeof **id);
+ goto fail;
}
-
- switch (type)
- {
- case X509v3_DNS_NAME:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_FQDN);
- break;
-
- case X509v3_RFC_NAME:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_USER_FQDN);
- break;
-
- case X509v3_IP_ADDR:
- /*
- * XXX I dislike the numeric constants, but I don't know what we
- * should use otherwise.
- */
- switch (altlen)
- {
- case 4:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
- break;
-
- case 16:
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV6_ADDR);
- break;
-
- default:
- log_print ("x509_cert_get_subject: "
- "invalid subjectAltName IPaddress length %d ", altlen);
- goto fail;
- }
- break;
+ *id_len = malloc(*cnt * sizeof **id_len);
+ if (!*id_len) {
+ log_print("x509_cert_get_subject: malloc (%lu) failed",
+ *cnt * (unsigned long) sizeof **id_len);
+ goto fail;
}
-
- SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- memcpy (buf + ISAKMP_ID_DATA_OFF, altname, altlen);
-
- (*id_len)[1] = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ;
- (*id)[1] = malloc ((*id_len)[1]);
- if (!(*id)[1])
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed",
- (*id_len)[1]);
- goto fail;
+ /* Stash the subjectName into the first slot. */
+ subject = X509_get_subject_name(cert);
+ if (!subject)
+ goto fail;
+
+ (*id_len)[0] =
+ ISAKMP_ID_DATA_OFF + i2d_X509_NAME(subject, NULL) - ISAKMP_GEN_SZ;
+ (*id)[0] = malloc((*id_len)[0]);
+ if (!(*id)[0]) {
+ log_print("x509_cert_get_subject: malloc (%d) failed", (*id_len)[0]);
+ goto fail;
+ }
+ SET_ISAKMP_ID_TYPE((*id)[0] - ISAKMP_GEN_SZ, IPSEC_ID_DER_ASN1_DN);
+ ubuf = (*id)[0] + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ i2d_X509_NAME(subject, &ubuf);
+
+ if (altlen) {
+ /* Stash the subjectAltName into the second slot. */
+ buf = malloc(altlen + ISAKMP_ID_DATA_OFF);
+ if (!buf) {
+ log_print("x509_cert_get_subject: malloc (%d) failed",
+ altlen + ISAKMP_ID_DATA_OFF);
+ goto fail;
+ }
+ switch (type) {
+ case X509v3_DNS_NAME:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_FQDN);
+ break;
+
+ case X509v3_RFC_NAME:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_USER_FQDN);
+ break;
+
+ case X509v3_IP_ADDR:
+ /*
+ * XXX I dislike the numeric constants, but I don't know what we
+ * should use otherwise.
+ */
+ switch (altlen) {
+ case 4:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV4_ADDR);
+ break;
+
+ case 16:
+ SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV6_ADDR);
+ break;
+
+ default:
+ log_print("x509_cert_get_subject: "
+ "invalid subjectAltName IPaddress length %d ",
+ altlen);
+ goto fail;
+ }
+ break;
+ }
+
+ SET_IPSEC_ID_PROTO(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ SET_IPSEC_ID_PORT(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ memcpy(buf + ISAKMP_ID_DATA_OFF, altname, altlen);
+
+ (*id_len)[1] = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ;
+ (*id)[1] = malloc((*id_len)[1]);
+ if (!(*id)[1]) {
+ log_print("x509_cert_get_subject: malloc (%d) failed",
+ (*id_len)[1]);
+ goto fail;
+ }
+ memcpy((*id)[1], buf + ISAKMP_GEN_SZ, (*id_len)[1]);
+
+ free(buf);
+ buf = 0;
}
- memcpy ((*id)[1], buf + ISAKMP_GEN_SZ, (*id_len)[1]);
-
- free (buf);
- buf = 0;
- }
-
- return 1;
-
- fail:
- for (i = 0; i < *cnt; i++)
- if ((*id)[i])
- free ((*id)[i]);
- if (*id)
- free (*id);
- if (*id_len)
- free (*id_len);
- if (buf)
- free (buf);
- return 0;
+ return 1;
+
+fail:
+ for (i = 0; i < *cnt; i++)
+ if ((*id)[i])
+ free((*id)[i]);
+ if (*id)
+ free(*id);
+ if (*id_len)
+ free(*id_len);
+ if (buf)
+ free(buf);
+ return 0;
}
int
-x509_cert_get_key (void *scert, void *keyp)
+x509_cert_get_key(void *scert, void *keyp)
{
- X509 *cert = scert;
- EVP_PKEY *key;
+ X509 *cert = scert;
+ EVP_PKEY *key;
- key = X509_get_pubkey (cert);
+ key = X509_get_pubkey(cert);
- /* Check if we got the right key type. */
- if (key->type != EVP_PKEY_RSA)
- {
- log_print ("x509_cert_get_key: public key is not a RSA key");
- X509_free (cert);
- return 0;
- }
-
- *(RSA **)keyp = RSAPublicKey_dup (key->pkey.rsa);
+ /* Check if we got the right key type. */
+ if (key->type != EVP_PKEY_RSA) {
+ log_print("x509_cert_get_key: public key is not a RSA key");
+ X509_free(cert);
+ return 0;
+ }
+ *(RSA **) keyp = RSAPublicKey_dup(key->pkey.rsa);
- return *(RSA **)keyp == NULL ? 0 : 1;
+ return *(RSA **) keyp == NULL ? 0 : 1;
}
void *
-x509_cert_dup (void *scert)
+x509_cert_dup(void *scert)
{
- return X509_dup (scert);
+ return X509_dup(scert);
}
void
-x509_serialize (void *scert, u_int8_t **data, u_int32_t *datalen)
+x509_serialize(void *scert, u_int8_t **data, u_int32_t *datalen)
{
- u_int8_t *p;
-
- *datalen = i2d_X509 ((X509 *) scert, NULL);
- *data = p = malloc (*datalen);
- if (!p)
- {
- log_error ("x509_serialize: malloc (%d) failed", *datalen);
- return;
- }
+ u_int8_t *p;
- *datalen = i2d_X509 ((X509 *)scert, &p);
+ *datalen = i2d_X509((X509 *) scert, NULL);
+ *data = p = malloc(*datalen);
+ if (!p) {
+ log_error("x509_serialize: malloc (%d) failed", *datalen);
+ return;
+ }
+ *datalen = i2d_X509((X509 *) scert, &p);
}
/* From cert to printable */
char *
-x509_printable (void *cert)
+x509_printable(void *cert)
{
- char *s;
- u_int8_t *data;
- u_int32_t datalen, i;
-
- x509_serialize (cert, &data, &datalen);
- if (!data)
- return 0;
-
- s = malloc (datalen * 2 + 1);
- if (!s)
- {
- free (data);
- log_error ("x509_printable: malloc (%d) failed", datalen * 2 + 1);
- return 0;
- }
-
- for (i = 0; i < datalen; i++)
- snprintf (s + (2 * i), 2 * (datalen - i) + 1, "%02x", data[i]);
- free (data);
- return s;
+ char *s;
+ u_int8_t *data;
+ u_int32_t datalen, i;
+
+ x509_serialize(cert, &data, &datalen);
+ if (!data)
+ return 0;
+
+ s = malloc(datalen * 2 + 1);
+ if (!s) {
+ free(data);
+ log_error("x509_printable: malloc (%d) failed", datalen * 2 + 1);
+ return 0;
+ }
+ for (i = 0; i < datalen; i++)
+ snprintf(s + (2 * i), 2 * (datalen - i) + 1, "%02x", data[i]);
+ free(data);
+ return s;
}
/* From printable to cert */
void *
-x509_from_printable (char *cert)
+x509_from_printable(char *cert)
{
- u_int8_t *buf;
- int plen, ret;
- void *foo;
-
- plen = (strlen (cert) + 1) / 2;
- buf = malloc (plen);
- if (!buf)
- {
- log_error ("x509_from_printable: malloc (%d) failed", plen);
- return 0;
- }
-
- ret = hex2raw (cert, buf, plen);
- if (ret == -1)
- {
- free (buf);
- log_print ("x509_from_printable: badly formatted cert");
- return 0;
- }
-
- foo = x509_cert_get (buf, plen);
- free (buf);
- if (!foo)
- log_print ("x509_from_printable: could not retrieve certificate");
- return foo;
+ u_int8_t *buf;
+ int plen, ret;
+ void *foo;
+
+ plen = (strlen(cert) + 1) / 2;
+ buf = malloc(plen);
+ if (!buf) {
+ log_error("x509_from_printable: malloc (%d) failed", plen);
+ return 0;
+ }
+ ret = hex2raw(cert, buf, plen);
+ if (ret == -1) {
+ free(buf);
+ log_print("x509_from_printable: badly formatted cert");
+ return 0;
+ }
+ foo = x509_cert_get(buf, plen);
+ free(buf);
+ if (!foo)
+ log_print("x509_from_printable: could not retrieve certificate");
+ return foo;
}
char *
-x509_DN_string (u_int8_t *asn1, size_t sz)
+x509_DN_string(u_int8_t *asn1, size_t sz)
{
- X509_NAME *name;
- u_int8_t *p = asn1;
- /* XXX Just a guess at a maximum length. */
- char buf[256];
-
- name = d2i_X509_NAME (NULL, &p, sz);
- if (!name)
- {
- log_print ("x509_DN_string: d2i_X509_NAME failed");
- return 0;
- }
- if (!X509_NAME_oneline (name, buf, sizeof buf - 1))
- {
- log_print ("x509_DN_string: X509_NAME_oneline failed");
- X509_NAME_free (name);
- return 0;
- }
- X509_NAME_free (name);
- buf[sizeof buf - 1] = '\0';
- return strdup (buf);
+ X509_NAME *name;
+ u_int8_t *p = asn1;
+ /* XXX Just a guess at a maximum length. */
+ char buf[256];
+
+ name = d2i_X509_NAME(NULL, &p, sz);
+ if (!name) {
+ log_print("x509_DN_string: d2i_X509_NAME failed");
+ return 0;
+ }
+ if (!X509_NAME_oneline(name, buf, sizeof buf - 1)) {
+ log_print("x509_DN_string: X509_NAME_oneline failed");
+ X509_NAME_free(name);
+ return 0;
+ }
+ X509_NAME_free(name);
+ buf[sizeof buf - 1] = '\0';
+ return strdup(buf);
}
-#endif /* USE_X509 */
+#endif /* USE_X509 */
diff --git a/sbin/isakmpd/x509.h b/sbin/isakmpd/x509.h
index c24e8c9c3d7..3ed64feff86 100644
--- a/sbin/isakmpd/x509.h
+++ b/sbin/isakmpd/x509.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: x509.h,v 1.19 2003/11/06 16:12:08 ho Exp $ */
-/* $EOM: x509.h,v 1.11 2000/09/28 12:53:27 niklas Exp $ */
+/* $OpenBSD: x509.h,v 1.20 2004/04/15 18:39:27 deraadt Exp $ */
+/* $EOM: x509.h,v 1.11 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -41,8 +41,8 @@
#define X509v3_IP_ADDR 7
struct x509_attribval {
- char *type;
- char *val;
+ char *type;
+ char *val;
};
/*
@@ -51,8 +51,8 @@ struct x509_attribval {
* be dynamic but we don't care for now.
*/
struct x509_aca {
- struct x509_attribval name1;
- struct x509_attribval name2;
+ struct x509_attribval name1;
+ struct x509_attribval name2;
};
struct X509;
@@ -60,30 +60,30 @@ struct X509_STORE;
/* Functions provided by cert handler. */
-int x509_certreq_validate (u_int8_t *, u_int32_t);
-void *x509_certreq_decode (u_int8_t *, u_int32_t);
-void x509_cert_free (void *);
-void *x509_cert_get (u_int8_t *, u_int32_t);
-int x509_cert_get_key (void *, void *);
-int x509_cert_get_subjects (void *, int *, u_int8_t ***, u_int32_t **);
-int x509_cert_init (void);
-int x509_crl_init (void);
-int x509_cert_obtain (u_int8_t *, size_t, void *, u_int8_t **, u_int32_t *);
-int x509_cert_validate (void *);
-void x509_free_aca (void *);
-void *x509_cert_dup (void *);
-void x509_serialize (void *, u_int8_t **, u_int32_t *);
-char *x509_printable (void *);
-void *x509_from_printable (char *);
+int x509_certreq_validate(u_int8_t *, u_int32_t);
+void *x509_certreq_decode(u_int8_t *, u_int32_t);
+void x509_cert_free(void *);
+void *x509_cert_get(u_int8_t *, u_int32_t);
+int x509_cert_get_key(void *, void *);
+int x509_cert_get_subjects(void *, int *, u_int8_t ***, u_int32_t **);
+int x509_cert_init(void);
+int x509_crl_init(void);
+int x509_cert_obtain(u_int8_t *, size_t, void *, u_int8_t **, u_int32_t *);
+int x509_cert_validate(void *);
+void x509_free_aca(void *);
+void *x509_cert_dup(void *);
+void x509_serialize(void *, u_int8_t **, u_int32_t *);
+char *x509_printable(void *);
+void *x509_from_printable(char *);
/* Misc. X509 certificate functions. */
-char *x509_DN_string (u_int8_t *, size_t);
-int x509_cert_insert (int, void *);
-int x509_cert_subjectaltname (X509 *cert, u_char **, u_int *);
-X509 *x509_from_asn (u_char *, u_int);
-int x509_generate_kn (int, X509 *);
-int x509_read_from_dir (X509_STORE *, char *, int);
-int x509_read_crls_from_dir (X509_STORE *, char *);
+char *x509_DN_string(u_int8_t *, size_t);
+int x509_cert_insert(int, void *);
+int x509_cert_subjectaltname(X509 * cert, u_char **, u_int *);
+X509 *x509_from_asn(u_char *, u_int);
+int x509_generate_kn(int, X509 *);
+int x509_read_from_dir(X509_STORE *, char *, int);
+int x509_read_crls_from_dir(X509_STORE *, char *);
-#endif /* _X509_H_ */
+#endif /* _X509_H_ */