summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ldpd/lde.c15
-rw-r--r--usr.sbin/ldpd/ldpd.c80
-rw-r--r--usr.sbin/ldpd/ldpd.conf.541
-rw-r--r--usr.sbin/ldpd/ldpd.h24
-rw-r--r--usr.sbin/ldpd/ldpe.c20
-rw-r--r--usr.sbin/ldpd/ldpe.h15
-rw-r--r--usr.sbin/ldpd/neighbor.c11
-rw-r--r--usr.sbin/ldpd/packet.c4
-rw-r--r--usr.sbin/ldpd/parse.y180
-rw-r--r--usr.sbin/ldpd/pfkey.c99
-rw-r--r--usr.sbin/ldpd/printconf.c36
11 files changed, 399 insertions, 126 deletions
diff --git a/usr.sbin/ldpd/lde.c b/usr.sbin/ldpd/lde.c
index e6b45719700..1bfd701a390 100644
--- a/usr.sbin/ldpd/lde.c
+++ b/usr.sbin/ldpd/lde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lde.c,v 1.73 2017/03/04 00:15:35 renato Exp $ */
+/* $OpenBSD: lde.c,v 1.74 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -480,6 +480,7 @@ lde_dispatch_parent(int fd, short event, void *bula)
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
+ LIST_INIT(&nconf->auth_list);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@@ -534,6 +535,18 @@ lde_dispatch_parent(int fd, short event, void *bula)
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
break;
+ case IMSG_RECONF_CONF_AUTH: {
+ struct ldp_auth *auth;
+
+ auth = malloc(sizeof(*auth));
+ if (auth == NULL)
+ fatal(NULL);
+
+ memcpy(auth, imsg.data, sizeof(*auth));
+
+ LIST_INSERT_HEAD(&nconf->auth_list, auth, entry);
+ break;
+ }
case IMSG_RECONF_END:
merge_config(ldeconf, nconf);
nconf = NULL;
diff --git a/usr.sbin/ldpd/ldpd.c b/usr.sbin/ldpd/ldpd.c
index 901df833a91..7425d2030e5 100644
--- a/usr.sbin/ldpd/ldpd.c
+++ b/usr.sbin/ldpd/ldpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpd.c,v 1.62 2017/03/03 23:36:06 renato Exp $ */
+/* $OpenBSD: ldpd.c,v 1.63 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -60,6 +60,7 @@ static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *);
static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *);
static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *,
struct l2vpn *);
+static void merge_auths(struct ldpd_conf *, struct ldpd_conf *);
struct ldpd_global global;
struct ldpd_conf *ldpd_conf;
@@ -681,11 +682,18 @@ main_imsg_send_config(struct ldpd_conf *xconf)
struct l2vpn *l2vpn;
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
+ struct ldp_auth *auth;
if (main_imsg_compose_both(IMSG_RECONF_CONF, xconf,
sizeof(*xconf)) == -1)
return (-1);
+ LIST_FOREACH(auth, &xconf->auth_list, entry) {
+ if (main_imsg_compose_both(IMSG_RECONF_CONF_AUTH,
+ auth, sizeof(*auth)) == -1)
+ return (-1);
+ }
+
LIST_FOREACH(iface, &xconf->iface_list, entry) {
if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
sizeof(*iface)) == -1)
@@ -747,6 +755,7 @@ void
merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
{
merge_global(conf, xconf);
+ merge_auths(conf, xconf);
merge_af(AF_INET, &conf->ipv4, &xconf->ipv4);
merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6);
merge_ifaces(conf, xconf);
@@ -971,7 +980,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
if (nbr) {
session_shutdown(nbr, S_SHUTDOWN, 0, 0);
- if (pfkey_establish(nbr, xn) == -1)
+ if (pfkey_establish(conf, nbr) == -1)
fatalx("pfkey setup failed");
if (nbr_session_active_role(nbr))
nbr_establish_connection(nbr);
@@ -984,9 +993,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if (nbrp->flags != xn->flags ||
nbrp->keepalive != xn->keepalive ||
nbrp->gtsm_enabled != xn->gtsm_enabled ||
- nbrp->gtsm_hops != xn->gtsm_hops ||
- nbrp->auth.method != xn->auth.method ||
- strcmp(nbrp->auth.md5key, xn->auth.md5key) != 0)
+ nbrp->gtsm_hops != xn->gtsm_hops)
nbrp_changed = 1;
else
nbrp_changed = 0;
@@ -994,10 +1001,6 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
nbrp->keepalive = xn->keepalive;
nbrp->gtsm_enabled = xn->gtsm_enabled;
nbrp->gtsm_hops = xn->gtsm_hops;
- nbrp->auth.method = xn->auth.method;
- strlcpy(nbrp->auth.md5key, xn->auth.md5key,
- sizeof(nbrp->auth.md5key));
- nbrp->auth.md5key_len = xn->auth.md5key_len;
nbrp->flags = xn->flags;
if (ldpd_process == PROC_LDP_ENGINE) {
@@ -1005,7 +1008,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if (nbr && nbrp_changed) {
session_shutdown(nbr, S_SHUTDOWN, 0, 0);
pfkey_remove(nbr);
- if (pfkey_establish(nbr, nbrp) == -1)
+ if (pfkey_establish(conf, nbr) == -1)
fatalx("pfkey setup failed");
if (nbr_session_active_role(nbr))
nbr_establish_connection(nbr);
@@ -1205,6 +1208,62 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
l2vpn->br_ifindex = xl->br_ifindex;
}
+static struct ldp_auth *
+auth_find(struct ldpd_conf *conf, const struct ldp_auth *needle)
+{
+ struct ldp_auth *auth;
+
+ LIST_FOREACH(auth, &conf->auth_list, entry) {
+ in_addr_t mask;
+ if (needle->md5key_len != auth->md5key_len)
+ continue;
+ if (needle->idlen != auth->idlen)
+ continue;
+
+ if (memcmp(needle->md5key, auth->md5key,
+ needle->md5key_len) != 0)
+ continue;
+
+ mask = prefixlen2mask(auth->idlen);
+ if ((needle->id.s_addr & mask) != (auth->id.s_addr & mask))
+ continue;
+
+ return (auth);
+ }
+
+ return (NULL);
+}
+
+static void
+merge_auths(struct ldpd_conf *conf, struct ldpd_conf *xconf)
+{
+ struct ldp_auth *auth, *nauth, *xauth;
+
+ /* find deleted auths */
+ LIST_FOREACH_SAFE(auth, &conf->auth_list, entry, nauth) {
+ xauth = auth_find(xconf, auth);
+ if (xauth == NULL)
+ continue;
+
+ LIST_REMOVE(auth, entry);
+
+ free(auth);
+ }
+
+ /* find new auths */
+ LIST_FOREACH_SAFE(xauth, &xconf->auth_list, entry, nauth) {
+ LIST_REMOVE(xauth, entry);
+
+ auth = auth_find(conf, xauth);
+ if (auth == NULL) {
+ LIST_INSERT_HEAD(&conf->auth_list, xauth, entry);
+ continue;
+ }
+
+ free(xauth);
+ }
+}
+
struct ldpd_conf *
config_new_empty(void)
{
@@ -1218,6 +1277,7 @@ config_new_empty(void)
LIST_INIT(&xconf->tnbr_list);
LIST_INIT(&xconf->nbrp_list);
LIST_INIT(&xconf->l2vpn_list);
+ LIST_INIT(&xconf->auth_list);
return (xconf);
}
diff --git a/usr.sbin/ldpd/ldpd.conf.5 b/usr.sbin/ldpd/ldpd.conf.5
index c9d7706702c..2c797649be6 100644
--- a/usr.sbin/ldpd/ldpd.conf.5
+++ b/usr.sbin/ldpd/ldpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ldpd.conf.5,v 1.36 2018/08/06 17:25:11 mestre Exp $
+.\" $OpenBSD: ldpd.conf.5,v 1.37 2019/01/23 02:02:04 dlg Exp $
.\"
.\" Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
.\" Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -19,7 +19,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 6 2018 $
+.Dd $Mdocdate: January 23 2019 $
.Dt LDPD.CONF 5
.Os
.Sh NAME
@@ -72,14 +72,6 @@ and may contain any of those characters.
Macro names may not be reserved words (for example,
.Ic neighbor ) .
Macros are not expanded inside quotes.
-.Pp
-For example:
-.Bd -literal -offset indent
-peer1="10.0.1.5"
-neighbor $peer1 {
- password "openbsd"
-}
-.Ed
.Sh GLOBAL CONFIGURATION
Several settings can be configured globally or within a more restricted scope,
like per address-family or per interface.
@@ -119,6 +111,27 @@ Set the router ID; in combination with labelspace it forms the LSR-ID.
If not specified, the numerically lowest IP address of the router will be used.
.Pp
.It Xo
+.Ic tcp md5sig password Ar secret
+.Op Ar lsr-id Ns Op / Ns Ar prefix
+.Xc
+.It Xo
+.Ic tcp md5sig key Ar secret
+.Op Ar lsr-id Ns Op / Ns Ar prefix
+.Xc
+.It Xo
+.Ic no tcp md5sig
+.Op Ar lsr-id Ns Op / Ns Ar prefix
+.Xc
+Enable or disable TCP MD5 signatures per RFC 5036.
+The shared secret can either be given as a password or hexadecimal key.
+An optional prefix may be specified to scope the key configuration to a
+set of neighbors with the specified LSR-IDs.
+.Bd -literal -offset indent
+tcp md5sig password mekmitasdigoat 192.168.0.0/24
+no tcp md5sig 192.168.0.25
+.Ed
+.Pp
+.It Xo
.Ic transport-preference
.Pq Ic ipv4 Ns | Ns Ic ipv6
.Xc
@@ -278,8 +291,12 @@ When GTSM is enabled for this neighbor, incoming packets are required to have
a TTL/hop limit of 256 minus this value, ensuring they have not passed
through more than the expected number of hops.
The default value is 1; valid range is 1\-255.
-.It Ic password Ar secret
-Enable TCP MD5 signatures per RFC 5036.
+.It Ic tcp md5sig password Ar secret
+Enable TCP MD5 signatures per RFC 5036 with the specified password.
+.It Ic tcp md5sig key Ar secret
+Enable TCP MD5 signatures per RFC 5036 with the specified hexadecimal key.
+.It Ic no tcp md5sig
+Disable the use of TCP MD5 signatures.
.El
.Sh LAYER 2 VPNS
.Xr ldpd 8
diff --git a/usr.sbin/ldpd/ldpd.h b/usr.sbin/ldpd/ldpd.h
index 6280bde5588..6d2f15c29e0 100644
--- a/usr.sbin/ldpd/ldpd.h
+++ b/usr.sbin/ldpd/ldpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpd.h,v 1.88 2018/02/08 00:17:31 claudio Exp $ */
+/* $OpenBSD: ldpd.h,v 1.89 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -128,6 +128,7 @@ enum imsg_type {
IMSG_RECONF_L2VPN,
IMSG_RECONF_L2VPN_IF,
IMSG_RECONF_L2VPN_PW,
+ IMSG_RECONF_CONF_AUTH,
IMSG_RECONF_END
};
@@ -300,11 +301,6 @@ struct tnbr {
#define F_TNBR_CONFIGURED 0x01
#define F_TNBR_DYNAMIC 0x02
-enum auth_method {
- AUTH_NONE,
- AUTH_MD5SIG
-};
-
/* neighbor specific parameters */
struct nbr_params {
LIST_ENTRY(nbr_params) entry;
@@ -312,11 +308,6 @@ struct nbr_params {
uint16_t keepalive;
int gtsm_enabled;
uint8_t gtsm_hops;
- struct {
- enum auth_method method;
- char md5key[TCP_MD5_KEY_LEN];
- uint8_t md5key_len;
- } auth;
uint8_t flags;
};
#define F_NBRP_KEEPALIVE 0x01
@@ -403,6 +394,16 @@ struct ldpd_af_conf {
#define F_LDPD_AF_EXPNULL 0x0004
#define F_LDPD_AF_NO_GTSM 0x0008
+struct ldp_auth {
+ LIST_ENTRY(ldp_auth) entry;
+ char md5key[TCP_MD5_KEY_LEN];
+ unsigned int md5key_len;
+ struct in_addr id;
+ int idlen;
+};
+
+#define LDP_AUTH_REQUIRED(_a) ((_a)->md5key_len != 0)
+
struct ldpd_conf {
struct in_addr rtr_id;
unsigned int rdomain;
@@ -412,6 +413,7 @@ struct ldpd_conf {
LIST_HEAD(, tnbr) tnbr_list;
LIST_HEAD(, nbr_params) nbrp_list;
LIST_HEAD(, l2vpn) l2vpn_list;
+ LIST_HEAD(, ldp_auth) auth_list;
uint16_t trans_pref;
int flags;
};
diff --git a/usr.sbin/ldpd/ldpe.c b/usr.sbin/ldpd/ldpe.c
index b30ab0f3c96..79084baea1f 100644
--- a/usr.sbin/ldpd/ldpe.c
+++ b/usr.sbin/ldpd/ldpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.c,v 1.74 2017/03/04 00:21:48 renato Exp $ */
+/* $OpenBSD: ldpe.c,v 1.75 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -235,7 +235,6 @@ ldpe_dispatch_main(int fd, short event, void *bula)
static int edisc_socket = -1;
static int session_socket = -1;
struct nbr *nbr;
- struct nbr_params *nbrp;
int n, shut = 0;
if (event & EV_READ) {
@@ -380,8 +379,7 @@ ldpe_dispatch_main(int fd, short event, void *bula)
continue;
nbr->laddr = (ldp_af_conf_get(leconf,
af))->trans_addr;
- nbrp = nbr_params_find(leconf, nbr->id);
- if (nbrp && pfkey_establish(nbr, nbrp) == -1)
+ if (pfkey_establish(nconf, nbr) == -1)
fatalx("pfkey setup failed");
if (nbr_session_active_role(nbr))
nbr_establish_connection(nbr);
@@ -397,6 +395,7 @@ ldpe_dispatch_main(int fd, short event, void *bula)
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
+ LIST_INIT(&nconf->auth_list);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@@ -451,6 +450,19 @@ ldpe_dispatch_main(int fd, short event, void *bula)
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
break;
+ case IMSG_RECONF_CONF_AUTH: {
+ struct ldp_auth *auth;
+
+ auth = malloc(sizeof(*auth));
+ if (auth == NULL)
+ fatal(NULL);
+
+ memcpy(auth, imsg.data, sizeof(*auth));
+
+ LIST_INSERT_HEAD(&nconf->auth_list, auth, entry);
+ break;
+ }
+
case IMSG_RECONF_END:
merge_config(leconf, nconf);
nconf = NULL;
diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h
index 569e8ffc8bc..a4ad7de0440 100644
--- a/usr.sbin/ldpd/ldpe.h
+++ b/usr.sbin/ldpd/ldpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.h,v 1.75 2017/03/04 00:21:48 renato Exp $ */
+/* $OpenBSD: ldpe.h,v 1.76 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -94,13 +94,10 @@ struct nbr {
uint16_t keepalive;
uint16_t max_pdu_len;
- struct {
- uint8_t established;
- uint32_t spi_in;
- uint32_t spi_out;
- enum auth_method method;
- char md5key[TCP_MD5_KEY_LEN];
- } auth;
+ uint32_t auth_spi_in;
+ uint32_t auth_spi_out;
+ int auth_established;
+
int flags;
};
#define F_NBR_GTSM_NEGOTIATED 0x01
@@ -276,7 +273,7 @@ char *pkt_ptr; /* packet buffer */
/* pfkey.c */
int pfkey_read(int, struct sadb_msg *);
-int pfkey_establish(struct nbr *, struct nbr_params *);
+int pfkey_establish(struct ldpd_conf *, struct nbr *);
int pfkey_remove(struct nbr *);
int pfkey_init(void);
diff --git a/usr.sbin/ldpd/neighbor.c b/usr.sbin/ldpd/neighbor.c
index 37d7260fcfb..e41b922b403 100644
--- a/usr.sbin/ldpd/neighbor.c
+++ b/usr.sbin/ldpd/neighbor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: neighbor.c,v 1.79 2017/03/04 00:15:35 renato Exp $ */
+/* $OpenBSD: neighbor.c,v 1.80 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -223,7 +223,6 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
uint32_t scope_id)
{
struct nbr *nbr;
- struct nbr_params *nbrp;
struct adj *adj;
struct pending_conn *pconn;
@@ -272,8 +271,7 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
evtimer_set(&nbr->init_timeout, nbr_itimeout, nbr);
evtimer_set(&nbr->initdelay_timer, nbr_idtimer, nbr);
- nbrp = nbr_params_find(leconf, nbr->id);
- if (nbrp && pfkey_establish(nbr, nbrp) == -1)
+ if (pfkey_establish(leconf, nbr) == -1)
fatalx("pfkey setup failed");
pconn = pending_conn_find(nbr->af, &nbr->raddr);
@@ -581,8 +579,7 @@ nbr_establish_connection(struct nbr *nbr)
return (-1);
}
- nbrp = nbr_params_find(leconf, nbr->id);
- if (nbrp && nbrp->auth.method == AUTH_MD5SIG) {
+ if (nbr->auth_established) {
if (sysdep.no_pfkey || sysdep.no_md5sig) {
log_warnx("md5sig configured but not available");
close(nbr->fd);
@@ -610,6 +607,7 @@ nbr_establish_connection(struct nbr *nbr)
return (-1);
}
+ nbrp = nbr_params_find(leconf, nbr->id);
if (nbr_gtsm_check(nbr->fd, nbr, nbrp)) {
close(nbr->fd);
return (-1);
@@ -761,7 +759,6 @@ nbr_params_new(struct in_addr lsr_id)
fatal(__func__);
nbrp->lsr_id = lsr_id;
- nbrp->auth.method = AUTH_NONE;
return (nbrp);
}
diff --git a/usr.sbin/ldpd/packet.c b/usr.sbin/ldpd/packet.c
index 1e03a09bcee..09c83469778 100644
--- a/usr.sbin/ldpd/packet.c
+++ b/usr.sbin/ldpd/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.70 2017/03/04 00:06:10 renato Exp $ */
+/* $OpenBSD: packet.c,v 1.71 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -391,7 +391,7 @@ session_accept_nbr(struct nbr *nbr, int fd)
return;
}
- if (nbrp && nbrp->auth.method == AUTH_MD5SIG) {
+ if (!LIST_EMPTY(&leconf->auth_list)) {
if (sysdep.no_pfkey || sysdep.no_md5sig) {
log_warnx("md5sig configured but not available");
close(fd);
diff --git a/usr.sbin/ldpd/parse.y b/usr.sbin/ldpd/parse.y
index bfcca083172..4128ba94af8 100644
--- a/usr.sbin/ldpd/parse.y
+++ b/usr.sbin/ldpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.67 2018/11/01 00:18:44 sashan Exp $ */
+/* $OpenBSD: parse.y,v 1.68 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2015, 2016 Renato Westphal <renato@openbsd.org>
@@ -24,6 +24,8 @@
%{
#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
@@ -33,6 +35,8 @@
#include <limits.h>
#include <stdio.h>
#include <syslog.h>
+#include <errno.h>
+#include <netdb.h>
#include "ldpd.h"
#include "ldpe.h"
@@ -76,6 +80,7 @@ typedef struct {
union {
int64_t number;
char *string;
+ struct ldp_auth *auth;
} v;
int lineno;
} YYSTYPE;
@@ -107,6 +112,7 @@ static void clear_config(struct ldpd_conf *xconf);
static uint32_t get_rtr_id(void);
static int get_address(const char *, union ldpd_addr *);
static int get_af_address(const char *, int *, union ldpd_addr *);
+static int str2key(char *, const char *, int);
static struct file *file, *topfile;
static struct files files = TAILQ_HEAD_INITIALIZER(files);
@@ -135,9 +141,10 @@ static struct config_defaults *defs;
%token INTERFACE TNEIGHBOR ROUTERID FIBUPDATE RDOMAIN EXPNULL
%token LHELLOHOLDTIME LHELLOINTERVAL
%token THELLOHOLDTIME THELLOINTERVAL
-%token THELLOACCEPT AF IPV4 IPV6 GTSMENABLE GTSMHOPS
+%token THELLOACCEPT AF IPV4 IPV6 INET INET6 GTSMENABLE GTSMHOPS
%token KEEPALIVE TRANSADDRESS TRANSPREFERENCE DSCISCOINTEROP
-%token NEIGHBOR PASSWORD
+%token NEIGHBOR
+%token TCP MD5SIG PASSWORD KEY
%token L2VPN TYPE VPLS PWTYPE MTU BRIDGE
%token ETHERNET ETHERNETTAGGED STATUSTLV CONTROLWORD
%token PSEUDOWIRE NEIGHBORID NEIGHBORADDR PWID
@@ -149,6 +156,7 @@ static struct config_defaults *defs;
%token <v.number> NUMBER
%type <v.number> yesno ldp_af l2vpn_type pw_type
%type <v.string> string
+%type <v.auth> auth tcpmd5 optnbrprefix
%%
@@ -273,6 +281,9 @@ conf_main : ROUTERID STRING {
else
conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
}
+ | auth {
+ LIST_INSERT_HEAD(&conf->auth_list, $1, entry);
+ }
| af_defaults
| iface_defaults
| tnbr_defaults
@@ -404,6 +415,103 @@ tnbr_defaults : THELLOHOLDTIME NUMBER {
}
;
+tcpmd5 : TCP MD5SIG PASSWORD STRING {
+ size_t len;
+
+ $$ = calloc(1, sizeof(*$$));
+ if ($$ == NULL) {
+ free($4);
+ yyerror("unable to allocate md5 key");
+ YYERROR;
+ }
+
+ len = strlen($4);
+ if (len > sizeof($$->md5key)) {
+ free($$);
+ free($4);
+ yyerror("tcp md5sig password too long: "
+ "max %zu", sizeof($$->md5key));
+ YYERROR;
+ }
+
+ memcpy($$->md5key, $4, len);
+ $$->md5key_len = len;
+
+ free($4);
+ }
+ | TCP MD5SIG KEY STRING {
+ int len;
+
+ $$ = calloc(1, sizeof(*$$));
+ if ($$ == NULL) {
+ free($4);
+ yyerror("unable to allocate md5 key");
+ YYERROR;
+ }
+
+ len = str2key($$->md5key, $4, sizeof($$->md5key));
+ if (len == -1) {
+ free($$);
+ free($4);
+ yyerror("invalid hex string");
+ YYERROR;
+ }
+ if ((size_t)len > sizeof($$->md5key_len)) {
+ free($$);
+ free($4);
+ yyerror("tcp md5sig key too long: %d "
+ "max %zu", len, sizeof($$->md5key));
+ YYERROR;
+ }
+
+ $$->md5key_len = len;
+
+ free($4);
+ }
+ | NO TCP MD5SIG {
+ $$ = calloc(1, sizeof(*$$));
+ if ($$ == NULL) {
+ yyerror("unable to allocate no md5 key");
+ YYERROR;
+ }
+ $$->md5key_len = 0;
+ }
+ ;
+
+optnbrprefix : STRING {
+ $$ = calloc(1, sizeof(*$$));
+ if ($$ == NULL) {
+ yyerror("unable to allocate auth");
+ free($1);
+ YYERROR;
+ }
+
+ $$->idlen = inet_net_pton(AF_INET, $1,
+ &$$->id, sizeof($$->id));
+ if ($$->idlen == -1) {
+ yyerror("%s: %s", $1, strerror(errno));
+ free($1);
+ YYERROR;
+ }
+ }
+ | /* empty */ {
+ $$ = NULL;
+ }
+ ;
+
+auth : tcpmd5 optnbrprefix {
+ $$ = $1;
+ if ($2 != NULL) {
+ $$->id = $2->id;
+ $$->idlen = $2->idlen;
+ free($2);
+ } else {
+ $$->id.s_addr = 0;
+ $$->idlen = 0;
+ }
+ }
+ ;
+
nbr_opts : KEEPALIVE NUMBER {
if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) {
yyerror("keepalive out of range (%d-%d)",
@@ -413,18 +521,11 @@ nbr_opts : KEEPALIVE NUMBER {
nbrp->keepalive = $2;
nbrp->flags |= F_NBRP_KEEPALIVE;
}
- | PASSWORD STRING {
- if (strlcpy(nbrp->auth.md5key, $2,
- sizeof(nbrp->auth.md5key)) >=
- sizeof(nbrp->auth.md5key)) {
- yyerror("tcp md5sig password too long: max %zu",
- sizeof(nbrp->auth.md5key) - 1);
- free($2);
- YYERROR;
- }
- nbrp->auth.md5key_len = strlen($2);
- nbrp->auth.method = AUTH_MD5SIG;
- free($2);
+ | tcpmd5 {
+ /* this is syntactic sugar... */
+ $1->id = nbrp->lsr_id;
+ $1->idlen = 32;
+ LIST_INSERT_HEAD(&conf->auth_list, $1, entry);
}
| GTSMENABLE yesno {
nbrp->flags |= F_NBRP_GTSM;
@@ -835,13 +936,17 @@ lookup(char *s)
{"gtsm-enable", GTSMENABLE},
{"gtsm-hops", GTSMHOPS},
{"include", INCLUDE},
+ {"inet", INET},
+ {"inet6", INET6},
{"interface", INTERFACE},
{"ipv4", IPV4},
{"ipv6", IPV6},
{"keepalive", KEEPALIVE},
+ {"key", KEY},
{"l2vpn", L2VPN},
{"link-hello-holdtime", LHELLOHOLDTIME},
{"link-hello-interval", LHELLOINTERVAL},
+ {"md5sig", MD5SIG},
{"mtu", MTU},
{"neighbor", NEIGHBOR},
{"neighbor-addr", NEIGHBORADDR},
@@ -858,6 +963,7 @@ lookup(char *s)
{"targeted-hello-holdtime", THELLOHOLDTIME},
{"targeted-hello-interval", THELLOINTERVAL},
{"targeted-neighbor", TNEIGHBOR},
+ {"tcp", TCP},
{"transport-address", TRANSADDRESS},
{"transport-preference", TRANSPREFERENCE},
{"type", TYPE},
@@ -1602,3 +1708,47 @@ get_af_address(const char *s, int *family, union ldpd_addr *addr)
return (-1);
}
+
+static int
+hexchar(int ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return (ch - '0');
+ if (ch >= 'a' && ch <= 'f')
+ return (ch - 'a');
+ if (ch >= 'A' && ch <= 'F')
+ return (ch - 'A');
+
+ return (-1);
+}
+
+static int
+str2key(char *dst, const char *src, int dstlen)
+{
+ int i = 0;
+ int digit;
+
+ while (*src != '\0') {
+ digit = hexchar(*src);
+ if (digit == -1)
+ return (-1);
+
+ if (i < dstlen)
+ *dst = digit << 4;
+
+ src++;
+ if (*src == '\0')
+ return (-1);
+ digit = hexchar(*src);
+ if (digit == -1)
+ return (-1);
+
+ if (i < dstlen)
+ *dst |= digit;
+
+ src++;
+ i++;
+ }
+
+ return (i);
+}
diff --git a/usr.sbin/ldpd/pfkey.c b/usr.sbin/ldpd/pfkey.c
index 8e56c138b6e..0af77a85af4 100644
--- a/usr.sbin/ldpd/pfkey.c
+++ b/usr.sbin/ldpd/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.11 2017/04/18 02:29:56 deraadt Exp $ */
+/* $OpenBSD: pfkey.c,v 1.12 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -36,7 +36,7 @@ static int pfkey_sa_add(int, union ldpd_addr *, union ldpd_addr *,
uint8_t, char *, uint32_t *);
static int pfkey_sa_remove(int, union ldpd_addr *, union ldpd_addr *,
uint32_t *);
-static int pfkey_md5sig_establish(struct nbr *, struct nbr_params *nbrp);
+static int pfkey_md5sig_establish(struct nbr *, struct ldp_auth *);
static int pfkey_md5sig_remove(struct nbr *);
#define PFKEY2_CHUNK sizeof(uint64_t)
@@ -367,84 +367,81 @@ pfkey_sa_remove(int af, union ldpd_addr *src, union ldpd_addr *dst,
}
static int
-pfkey_md5sig_establish(struct nbr *nbr, struct nbr_params *nbrp)
+pfkey_md5sig_establish(struct nbr *nbr, struct ldp_auth *auth)
{
sleep(1);
- if (!nbr->auth.spi_out)
- if (pfkey_sa_add(nbr->af, &nbr->laddr, &nbr->raddr,
- nbrp->auth.md5key_len, nbrp->auth.md5key,
- &nbr->auth.spi_out) == -1)
- return (-1);
- if (!nbr->auth.spi_in)
- if (pfkey_sa_add(nbr->af, &nbr->raddr, &nbr->laddr,
- nbrp->auth.md5key_len, nbrp->auth.md5key,
- &nbr->auth.spi_in) == -1)
- return (-1);
+ pfkey_md5sig_remove(nbr);
+
+ if (pfkey_sa_add(nbr->af, &nbr->laddr, &nbr->raddr,
+ auth->md5key_len, auth->md5key, &nbr->auth_spi_out) == -1)
+ return (-1);
+
+ if (pfkey_sa_add(nbr->af, &nbr->raddr, &nbr->laddr,
+ auth->md5key_len, auth->md5key, &nbr->auth_spi_in) == -1)
+ return (-1);
+
+ nbr->auth_established = 1;
- nbr->auth.established = 1;
return (0);
}
static int
pfkey_md5sig_remove(struct nbr *nbr)
{
- if (nbr->auth.spi_out)
+ if (nbr->auth_spi_out) {
if (pfkey_sa_remove(nbr->af, &nbr->laddr, &nbr->raddr,
- &nbr->auth.spi_out) == -1)
+ &nbr->auth_spi_out) == -1)
return (-1);
- if (nbr->auth.spi_in)
+ }
+ if (nbr->auth_spi_in) {
if (pfkey_sa_remove(nbr->af, &nbr->raddr, &nbr->laddr,
- &nbr->auth.spi_in) == -1)
+ &nbr->auth_spi_in) == -1)
return (-1);
+ }
- nbr->auth.established = 0;
- nbr->auth.spi_in = 0;
- nbr->auth.spi_out = 0;
- nbr->auth.method = AUTH_NONE;
- memset(nbr->auth.md5key, 0, sizeof(nbr->auth.md5key));
+ nbr->auth_established = 0;
+ nbr->auth_spi_in = 0;
+ nbr->auth_spi_out = 0;
return (0);
}
-int
-pfkey_establish(struct nbr *nbr, struct nbr_params *nbrp)
+static struct ldp_auth *
+pfkey_find_auth(struct ldpd_conf *conf, struct nbr *nbr)
{
- if (nbrp->auth.method == AUTH_NONE)
- return (0);
+ struct ldp_auth *auth, *match = NULL;
- /*
- * make sure we keep copies of everything we need to
- * remove SAs and flows later again.
- */
- nbr->auth.method = nbrp->auth.method;
-
- switch (nbr->auth.method) {
- case AUTH_MD5SIG:
- strlcpy(nbr->auth.md5key, nbrp->auth.md5key,
- sizeof(nbr->auth.md5key));
- return (pfkey_md5sig_establish(nbr, nbrp));
- default:
- break;
+ LIST_FOREACH(auth, &conf->auth_list, entry) {
+ in_addr_t mask = prefixlen2mask(auth->idlen);
+ if ((auth->id.s_addr & mask) != (nbr->id.s_addr & mask))
+ continue;
+
+ if (match == NULL ||
+ match->idlen < auth->idlen)
+ match = auth;
}
- return (0);
+ return (match);
}
int
-pfkey_remove(struct nbr *nbr)
+pfkey_establish(struct ldpd_conf *conf, struct nbr *nbr)
{
- if (nbr->auth.method == AUTH_NONE || !nbr->auth.established)
- return (0);
+ struct ldp_auth *auth = NULL;
- switch (nbr->auth.method) {
- case AUTH_MD5SIG:
- return (pfkey_md5sig_remove(nbr));
- default:
- break;
- }
+ auth = pfkey_find_auth(conf, nbr);
+ if (auth == NULL || /* no policy */
+ auth->md5key_len == 0) /* "no tcpmd5 sig" */
+ return (0);
+
+ return (pfkey_md5sig_establish(nbr, auth));
+}
- return (0);
+int
+pfkey_remove(struct nbr *nbr)
+{
+ return (pfkey_md5sig_remove(nbr));
}
int
diff --git a/usr.sbin/ldpd/printconf.c b/usr.sbin/ldpd/printconf.c
index e39b43f8336..b622e54d03b 100644
--- a/usr.sbin/ldpd/printconf.c
+++ b/usr.sbin/ldpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.27 2017/03/03 23:36:06 renato Exp $ */
+/* $OpenBSD: printconf.c,v 1.28 2019/01/23 02:02:04 dlg Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -19,8 +19,11 @@
*/
#include <sys/types.h>
+#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
+#include <netdb.h>
+#include <err.h>
#include "ldpd.h"
#include "ldpe.h"
@@ -132,9 +135,6 @@ print_nbrp(struct nbr_params *nbrp)
if (nbrp->flags & F_NBRP_GTSM_HOPS)
printf("\tgtsm-hops %u\n", nbrp->gtsm_hops);
- if (nbrp->auth.method == AUTH_MD5SIG)
- printf("\tpassword XXXXXX\n");
-
printf("}\n");
}
@@ -184,6 +184,31 @@ print_pw(struct l2vpn_pw *pw)
printf("\t}\n");
}
+static void
+print_auth(struct ldpd_conf *conf)
+{
+ struct ldp_auth *auth;
+
+ printf("\n");
+
+ LIST_FOREACH(auth, &conf->auth_list, entry) {
+ if (auth->md5key_len)
+ printf("tcp md5sig key XXX");
+ else
+ printf("no tcp md5sig");
+ if (auth->idlen) {
+ char hbuf[NI_MAXHOST];
+
+ if (inet_net_ntop(AF_INET, &auth->id, auth->idlen,
+ hbuf, sizeof(hbuf)) == NULL)
+ err(1, "inet_net_ntop");
+
+ printf(" %s", hbuf);
+ }
+ printf("\n");
+ }
+}
+
void
print_config(struct ldpd_conf *conf)
{
@@ -192,6 +217,9 @@ print_config(struct ldpd_conf *conf)
print_mainconf(conf);
+ if (!LIST_EMPTY(&conf->auth_list))
+ print_auth(conf);
+
if (conf->ipv4.flags & F_LDPD_AF_ENABLED)
print_af(AF_INET, conf, &conf->ipv4);
if (conf->ipv6.flags & F_LDPD_AF_ENABLED)