? ldpd.conf Index: Makefile =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/Makefile,v retrieving revision 1.12 diff -u -p -r1.12 Makefile --- Makefile 20 Jan 2017 12:19:18 -0000 1.12 +++ Makefile 19 Jan 2019 04:05:25 -0000 @@ -16,5 +16,6 @@ CFLAGS+= -Wsign-compare YFLAGS= LDADD+= -levent -lutil DPADD+= ${LIBEVENT} ${LIBUTIL} +DEBUG=-g .include Index: lde.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/lde.c,v retrieving revision 1.73 diff -u -p -r1.73 lde.c --- lde.c 4 Mar 2017 00:15:35 -0000 1.73 +++ lde.c 19 Jan 2019 04:05:25 -0000 @@ -480,6 +480,7 @@ lde_dispatch_parent(int fd, short event, LIST_INIT(&nconf->tnbr_list); LIST_INIT(&nconf->nbrp_list); LIST_INIT(&nconf->l2vpn_list); + nconf->auth = NULL; break; case IMSG_RECONF_IFACE: if ((niface = malloc(sizeof(struct iface))) == NULL) @@ -534,6 +535,19 @@ lde_dispatch_parent(int fd, short event, 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)); + auth->refs = 1; /* XXX */ + + nconf->auth = auth; + break; + } case IMSG_RECONF_END: merge_config(ldeconf, nconf); nconf = NULL; Index: ldpd.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/ldpd.c,v retrieving revision 1.62 diff -u -p -r1.62 ldpd.c --- ldpd.c 3 Mar 2017 23:36:06 -0000 1.62 +++ ldpd.c 19 Jan 2019 04:05:25 -0000 @@ -721,6 +721,12 @@ main_imsg_send_config(struct ldpd_conf * } } + if (xconf->auth) { + if (main_imsg_compose_both(IMSG_RECONF_CONF_AUTH, + xconf->auth, sizeof(*xconf->auth)) == -1) + return (-1); + } + if (main_imsg_compose_both(IMSG_RECONF_END, NULL, 0) == -1) return (-1); @@ -788,6 +794,7 @@ merge_global(struct ldpd_conf *conf, str } conf->flags = xconf->flags; + conf->auth = xconf->auth; /* move ref */ } static void @@ -971,7 +978,7 @@ merge_nbrps(struct ldpd_conf *conf, stru 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(nbr) == -1) fatalx("pfkey setup failed"); if (nbr_session_active_role(nbr)) nbr_establish_connection(nbr); @@ -984,9 +991,7 @@ merge_nbrps(struct ldpd_conf *conf, stru 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 +999,6 @@ merge_nbrps(struct ldpd_conf *conf, stru 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 +1006,7 @@ merge_nbrps(struct ldpd_conf *conf, stru if (nbr && nbrp_changed) { session_shutdown(nbr, S_SHUTDOWN, 0, 0); pfkey_remove(nbr); - if (pfkey_establish(nbr, nbrp) == -1) + if (pfkey_establish(nbr) == -1) fatalx("pfkey setup failed"); if (nbr_session_active_role(nbr)) nbr_establish_connection(nbr); Index: ldpd.conf.5 =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/ldpd.conf.5,v retrieving revision 1.36 diff -u -p -r1.36 ldpd.conf.5 --- ldpd.conf.5 6 Aug 2018 17:25:11 -0000 1.36 +++ ldpd.conf.5 19 Jan 2019 04:05:25 -0000 @@ -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. @@ -118,6 +110,15 @@ Table 0 is the default table. 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 Ic tcp md5sig password Ar secret +.It Ic tcp md5sig key Ar secret +Enable TCP MD5 signatures per RFC 5036. +The shared secret can either be given as a password or hexadecimal key. +.Bd -literal -offset indent +tcp md5sig password mekmitasdigoat +tcp md5sig key deadbeef +.Ed +.Pp .It Xo .Ic transport-preference .Pq Ic ipv4 Ns | Ns Ic ipv6 @@ -278,8 +279,6 @@ When GTSM is enabled for this neighbor, 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. .El .Sh LAYER 2 VPNS .Xr ldpd 8 Index: ldpd.h =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/ldpd.h,v retrieving revision 1.88 diff -u -p -r1.88 ldpd.h --- ldpd.h 8 Feb 2018 00:17:31 -0000 1.88 +++ ldpd.h 19 Jan 2019 04:05:25 -0000 @@ -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 }; @@ -248,6 +249,12 @@ struct notify_msg { #define F_NOTIF_FEC 0x02 /* fec tlv present */ #define F_NOTIF_RETURNED_TLVS 0x04 /* returned tlvs present */ +struct ldp_auth { + char md5key[TCP_MD5_KEY_LEN]; + unsigned int md5key_len; + unsigned int refs; +}; + struct if_addr { LIST_ENTRY(if_addr) entry; int af; @@ -263,6 +270,7 @@ struct iface_af { int enabled; int state; LIST_HEAD(, adj) adj_list; + struct ldp_auth auth; time_t uptime; struct event hello_timer; uint16_t hello_holdtime; @@ -289,6 +297,7 @@ struct tnbr { LIST_ENTRY(tnbr) entry; struct event hello_timer; struct adj *adj; + struct ldp_auth auth; int af; union ldpd_addr addr; int state; @@ -300,11 +309,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 +316,7 @@ 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; + struct ldp_auth auth; uint8_t flags; }; #define F_NBRP_KEEPALIVE 0x01 @@ -396,6 +396,7 @@ struct ldpd_af_conf { uint16_t thello_holdtime; uint16_t thello_interval; union ldpd_addr trans_addr; + struct ldp_auth auth; int flags; }; #define F_LDPD_AF_ENABLED 0x0001 @@ -408,6 +409,7 @@ struct ldpd_conf { unsigned int rdomain; struct ldpd_af_conf ipv4; struct ldpd_af_conf ipv6; + struct ldp_auth *auth; LIST_HEAD(, iface) iface_list; LIST_HEAD(, tnbr) tnbr_list; LIST_HEAD(, nbr_params) nbrp_list; Index: ldpe.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/ldpe.c,v retrieving revision 1.74 diff -u -p -r1.74 ldpe.c --- ldpe.c 4 Mar 2017 00:21:48 -0000 1.74 +++ ldpe.c 19 Jan 2019 04:05:25 -0000 @@ -380,8 +380,7 @@ ldpe_dispatch_main(int fd, short event, 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(nbr) == -1) fatalx("pfkey setup failed"); if (nbr_session_active_role(nbr)) nbr_establish_connection(nbr); @@ -397,6 +396,8 @@ ldpe_dispatch_main(int fd, short event, LIST_INIT(&nconf->tnbr_list); LIST_INIT(&nconf->nbrp_list); LIST_INIT(&nconf->l2vpn_list); + + nconf->auth = NULL; break; case IMSG_RECONF_IFACE: if ((niface = malloc(sizeof(struct iface))) == NULL) @@ -451,6 +452,20 @@ ldpe_dispatch_main(int fd, short event, 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)); + auth->refs = 1; /* XXX */ + + nconf->auth = auth; + break; + } + case IMSG_RECONF_END: merge_config(leconf, nconf); nconf = NULL; Index: ldpe.h =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/ldpe.h,v retrieving revision 1.75 diff -u -p -r1.75 ldpe.h --- ldpe.h 4 Mar 2017 00:21:48 -0000 1.75 +++ ldpe.h 19 Jan 2019 04:05:25 -0000 @@ -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; + struct ldp_auth *auth; + uint32_t auth_spi_in; + uint32_t auth_spi_out; + int flags; }; #define F_NBR_GTSM_NEGOTIATED 0x01 @@ -276,9 +273,16 @@ 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 nbr *); int pfkey_remove(struct nbr *); int pfkey_init(void); + +struct ldp_auth * + ldp_auth_new(const char *, size_t); +struct ldp_auth * + ldp_auth_take(struct ldp_auth *); +void ldp_auth_rele(struct ldp_auth *); +int ldp_auth_eq(const struct ldp_auth *, const struct ldp_auth *); /* l2vpn.c */ void ldpe_l2vpn_init(struct l2vpn *); Index: neighbor.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/neighbor.c,v retrieving revision 1.79 diff -u -p -r1.79 neighbor.c --- neighbor.c 4 Mar 2017 00:15:35 -0000 1.79 +++ neighbor.c 19 Jan 2019 04:05:25 -0000 @@ -223,7 +223,6 @@ nbr_new(struct in_addr id, int af, int d 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 d 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(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 (leconf->auth) { 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); } Index: packet.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/packet.c,v retrieving revision 1.70 diff -u -p -r1.70 packet.c --- packet.c 4 Mar 2017 00:06:10 -0000 1.70 +++ packet.c 19 Jan 2019 04:05:25 -0000 @@ -391,7 +391,7 @@ session_accept_nbr(struct nbr *nbr, int return; } - if (nbrp && nbrp->auth.method == AUTH_MD5SIG) { + if (leconf->auth) { if (sysdep.no_pfkey || sysdep.no_md5sig) { log_warnx("md5sig configured but not available"); close(fd); Index: parse.y =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/parse.y,v retrieving revision 1.67 diff -u -p -r1.67 parse.y --- parse.y 1 Nov 2018 00:18:44 -0000 1.67 +++ parse.y 19 Jan 2019 04:05:25 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include "ldpd.h" #include "ldpe.h" @@ -76,6 +77,7 @@ typedef struct { union { int64_t number; char *string; + struct ldp_auth *auth; } v; int lineno; } YYSTYPE; @@ -107,6 +109,7 @@ static void clear_config(struct ldpd_c 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); @@ -137,7 +140,8 @@ static struct config_defaults *defs; %token THELLOHOLDTIME THELLOINTERVAL %token THELLOACCEPT AF IPV4 IPV6 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 +153,7 @@ static struct config_defaults *defs; %token NUMBER %type yesno ldp_af l2vpn_type pw_type %type string +%type tcpmd5 %% @@ -273,6 +278,13 @@ conf_main : ROUTERID STRING { else conf->flags &= ~F_LDPD_DS_CISCO_INTEROP; } + | tcpmd5 { + if (conf->auth != NULL) { + yyerror("tcp md5sig already configured"); + YYERROR; + } + conf->auth = $1; + } | af_defaults | iface_defaults | tnbr_defaults @@ -292,6 +304,11 @@ af : AF ldp_af { YYERROR; } + /* + * ldp_auth_rele(af_conf->auth); + * af_conf->auth = ldp_auth_take(conf->auth); + */ + afdefs = *defs; defs = &afdefs; } af_block { @@ -337,6 +354,9 @@ afoptsl : TRANSADDRESS STRING { if ($2 == 0) defs->afflags |= F_LDPD_AF_NO_GTSM; } +/* + | tcpmd5 { } +*/ | af_defaults | iface_defaults | tnbr_defaults @@ -404,6 +424,50 @@ tnbr_defaults : THELLOHOLDTIME NUMBER { } ; +tcpmd5 : TCP MD5SIG PASSWORD string { + $$ = ldp_auth_new($4, strlen($4)); + free($4); + if ($$ == NULL) { + if (errno == EFBIG) { + yyerror("md5sig password too long: " + "max %zu", sizeof($$->md5key)); + } else + yyerror("unable to allocate md5sig"); + + YYERROR; + } + } + | TCP MD5SIG KEY string { + char key[sizeof($$->md5key)]; + int len; + + len = str2key(key, $4, sizeof(key)); + free($4); + if (len == -1) { + yyerror("invalid hex string"); + YYERROR; + } + /* ldp_auth_new does the len > sizeof(key) check */ + + $$ = ldp_auth_new(key, len); + if ($$ == NULL) { + if (errno == EFBIG) { + yyerror("md5sig password too long: " + "max %zu", sizeof($$->md5key)); + } else + yyerror("unable to allocate md5sig"); + + YYERROR; + } + } +/* + | NO TCP MD5SIG { + $$ = NULL; + } +*/ + ; + + nbr_opts : KEEPALIVE NUMBER { if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) { yyerror("keepalive out of range (%d-%d)", @@ -413,19 +477,6 @@ 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); - } | GTSMENABLE yesno { nbrp->flags |= F_NBRP_GTSM; nbrp->gtsm_enabled = $2; @@ -677,6 +728,11 @@ interface : INTERFACE STRING { } ia->enabled = 1; + /* + * assert(ia->auth == NULL); + * ia->auth = ldp_auth_take(af_conf->auth); + */ + ifacedefs = *defs; defs = &ifacedefs; } interface_block { @@ -692,10 +748,16 @@ interface_block : '{' optnl interfaceopt | /* nothing */ ; -interfaceopts_l : interfaceopts_l iface_defaults nl +interfaceopts_l : interfaceopts_l interfaceopt nl | iface_defaults optnl ; +interfaceopt : iface_defaults +/* + | tcpmd5 { } +*/ + ; + tneighbor : TNEIGHBOR STRING { union ldpd_addr addr; @@ -736,10 +798,16 @@ tneighbor_block : '{' optnl tneighboropt | /* nothing */ ; -tneighboropts_l : tneighboropts_l tnbr_defaults nl +tneighboropts_l : tneighboropts_l tneighboropt nl | tnbr_defaults optnl ; +tneighboropt : tnbr_defaults +/* + | tcpmd5 { } +*/ + ; + neighbor : NEIGHBOR STRING { struct in_addr addr; @@ -839,9 +907,11 @@ lookup(char *s) {"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 +928,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}, @@ -1235,7 +1306,6 @@ parse_config(char *filename) return (NULL); } topfile = file; - yyparse(); errors = file->errors; popfile(); @@ -1601,4 +1671,48 @@ get_af_address(const char *s, int *famil } 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); } Index: pfkey.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/pfkey.c,v retrieving revision 1.11 diff -u -p -r1.11 pfkey.c --- pfkey.c 18 Apr 2017 02:29:56 -0000 1.11 +++ pfkey.c 19 Jan 2019 04:05:25 -0000 @@ -36,7 +36,7 @@ static int pfkey_sa_add(int, union ldpd 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,67 @@ pfkey_sa_remove(int af, union ldpd_addr } 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 (!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) + auth->md5key_len, auth->md5key, + &nbr->auth_spi_out) == -1) return (-1); - if (!nbr->auth.spi_in) + } + 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) + auth->md5key_len, auth->md5key, + &nbr->auth_spi_in) == -1) { + /* XXX remove auth_spi_out? */ return (-1); + } + } - nbr->auth.established = 1; + nbr->auth = ldp_auth_take(auth); 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_spi_in = 0; + nbr->auth_spi_out = 0; + ldp_auth_rele(nbr->auth); + nbr->auth = NULL; return (0); } int -pfkey_establish(struct nbr *nbr, struct nbr_params *nbrp) +pfkey_establish(struct nbr *nbr) { - if (nbrp->auth.method == AUTH_NONE) + if (leconf->auth == NULL) return (0); - /* - * 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; - } - - return (0); + return (pfkey_md5sig_establish(nbr, leconf->auth)); } int pfkey_remove(struct nbr *nbr) { - if (nbr->auth.method == AUTH_NONE || !nbr->auth.established) + if (nbr->auth == NULL) return (0); - switch (nbr->auth.method) { - case AUTH_MD5SIG: - return (pfkey_md5sig_remove(nbr)); - default: - break; - } - - return (0); + return (pfkey_md5sig_remove(nbr)); } int @@ -460,4 +443,62 @@ pfkey_init(void) fatal("pfkey setup failed"); } return (fd); +} + +struct ldp_auth * +ldp_auth_new(const char *key, size_t keylen) +{ + struct ldp_auth *auth; + + if (keylen > sizeof(auth->md5key)) { + errno = EFBIG; /* ? */ + return (NULL); + } + + auth = malloc(sizeof(*auth)); + if (auth == NULL) + return (NULL); + + memcpy(auth->md5key, key, keylen); + auth->md5key_len = keylen; + auth->refs = 1; + + return (auth); +} + +struct ldp_auth * +ldp_auth_take(struct ldp_auth *auth) +{ + if (auth == NULL) + return (NULL); + + auth->refs++; + + return (auth); +} + +void +ldp_auth_rele(struct ldp_auth *auth) +{ + if (auth == NULL) + return; + + if (--auth->refs == 0) { + explicit_bzero(auth, sizeof(*auth)); + free(auth); + } +} + +int +ldp_auth_eq(const struct ldp_auth *a, const struct ldp_auth *b) +{ + if (a == NULL && b == NULL) + return (1); + if (b == NULL || a == NULL) + return (0); + + if (a->md5key_len != b->md5key_len) + return (0); + + return (memcmp(a->md5key, b->md5key, a->md5key_len) == 0); } Index: printconf.c =================================================================== RCS file: /cvs/src/usr.sbin/ldpd/printconf.c,v retrieving revision 1.27 diff -u -p -r1.27 printconf.c --- printconf.c 3 Mar 2017 23:36:06 -0000 1.27 +++ printconf.c 19 Jan 2019 04:05:25 -0000 @@ -132,9 +132,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"); } @@ -191,6 +188,9 @@ print_config(struct ldpd_conf *conf) struct l2vpn *l2vpn; print_mainconf(conf); + + if (conf->auth) + printf("tcp md5sig key XXXXXX\n"); if (conf->ipv4.flags & F_LDPD_AF_ENABLED) print_af(AF_INET, conf, &conf->ipv4);