diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2004-05-28 18:39:10 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2004-05-28 18:39:10 +0000 |
commit | 831d4b2edaf2875a6f07d2d8f046a52d9b6ce953 (patch) | |
tree | ba7afd0f8f3262765c0ab1cc4877949c658fa43e | |
parent | 83d23ae0746114f947c8dd433de3dc7935c7c2bb (diff) |
detect absence of PF_KEY interface and/or the TCP_MD5SIG setsockopts
at runtime and disable said subsystems if so. helps the guys porting bgpd
to $otherBSD, and is actually the right thing to do. claudio ok
-rw-r--r-- | usr.sbin/bgpd/pfkey.c | 15 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 47 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 13 |
3 files changed, 59 insertions, 16 deletions
diff --git a/usr.sbin/bgpd/pfkey.c b/usr.sbin/bgpd/pfkey.c index a136adf4631..a0b02a883bd 100644 --- a/usr.sbin/bgpd/pfkey.c +++ b/usr.sbin/bgpd/pfkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkey.c,v 1.29 2004/05/06 14:51:11 henning Exp $ */ +/* $OpenBSD: pfkey.c,v 1.30 2004/05/28 18:39:09 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -692,14 +692,17 @@ pfkey_remove(struct peer *p) } int -pfkey_init(void) +pfkey_init(struct bgpd_sysdep *sysdep) { if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1) { - if (errno == EPROTONOSUPPORT) - log_warnx("no kernel support for PF_KEY"); - else + if (errno == EPROTONOSUPPORT) { + log_warnx("PF_KEY not available, disabling ipsec"); + sysdep->no_pfkey = 1; + return (0); + } else { log_warn("PF_KEY socket"); - return (-1); + return (-1); + } } return (0); } diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index d1d87c817d6..603d68c27ac 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.171 2004/05/28 16:33:40 henning Exp $ */ +/* $OpenBSD: session.c,v 1.172 2004/05/28 18:39:09 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -87,6 +87,7 @@ struct peer *getpeerbyid(u_int32_t); static struct sockaddr *addr2sa(struct bgpd_addr *, u_int16_t); struct bgpd_config *conf, *nconf = NULL; +struct bgpd_sysdep sysdep; struct peer *npeers; volatile sig_atomic_t session_quit = 0; int pending_reconf = 0; @@ -124,8 +125,13 @@ setup_listener(struct sockaddr *sa) } opt = 1; - if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, &opt, sizeof(opt)) == -1) - fatal("setsockopt TCP_MD5SIG"); + if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, &opt, sizeof(opt)) == -1) { + if (errno == ENOPROTOOPT) { /* system w/o md5sig support */ + log_warnx("md5 signatures not available, disabling"); + sysdep.no_md5sig = 1; + } else + fatal("setsockopt TCP_MD5SIG"); + } if (bind(fd, sa, sa->sa_len)) { close(fd); @@ -190,7 +196,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers, sock = setup_listener((struct sockaddr *)&conf->listen_addr); sock6 = setup_listener((struct sockaddr *)&conf->listen6_addr); - if (pfkey_init() == -1) + if (pfkey_init(&sysdep) == -1) fatalx("pfkey setup failed"); if (setgroups(1, &pw->pw_gid) || @@ -796,7 +802,23 @@ session_accept(int listenfd) return; } } + + if (p->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) { + log_peer_warnx(&p->conf, + "ipsec or md5sig configured but not available"); + shutdown(connfd, SHUT_RDWR); + close(connfd); + return; + } + if (p->conf.auth.method == AUTH_MD5SIG) { + if (sysdep.no_md5sig) { + log_peer_warnx(&p->conf, + "md5sig configured but not available"); + shutdown(connfd, SHUT_RDWR); + close(connfd); + return; + } len = sizeof(opt); if (getsockopt(connfd, IPPROTO_TCP, TCP_MD5SIG, &opt, &len) == -1) @@ -845,14 +867,27 @@ session_connect(struct peer *peer) return (-1); } - if (peer->conf.auth.method == AUTH_MD5SIG) + if (peer->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) { + log_peer_warnx(&peer->conf, + "ipsec or md5sig configured but not available"); + bgp_fsm(peer, EVNT_CON_OPENFAIL); + return (-1); + } + + if (peer->conf.auth.method == AUTH_MD5SIG) { + if (sysdep.no_md5sig) { + log_peer_warnx(&peer->conf, + "md5sig configured but not available"); + bgp_fsm(peer, EVNT_CON_OPENFAIL); + return (-1); + } if (setsockopt(peer->fd, IPPROTO_TCP, TCP_MD5SIG, &opt, sizeof(opt)) == -1) { log_peer_warn(&peer->conf, "setsockopt md5sig"); bgp_fsm(peer, EVNT_CON_OPENFAIL); return (-1); } - + } peer->wbuf.fd = peer->fd; /* if update source is set we need to bind() */ diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 7c92857285e..23232ab3731 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.52 2004/05/08 18:21:55 henning Exp $ */ +/* $OpenBSD: session.h,v 1.53 2004/05/28 18:39:09 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -123,6 +123,11 @@ struct capa_mp { u_int8_t safi; }; +struct bgpd_sysdep { + u_int8_t no_pfkey; + u_int8_t no_md5sig; +}; + struct ctl_conn { TAILQ_ENTRY(ctl_conn) entries; struct imsgbuf ibuf; @@ -216,9 +221,9 @@ void control_accept(int); void control_close(int); /* pfkey.c */ -int pfkey_establish(struct peer *p); -int pfkey_remove(struct peer *p); -int pfkey_init(void); +int pfkey_establish(struct peer *); +int pfkey_remove(struct peer *); +int pfkey_init(struct bgpd_sysdep *); /* printconf.c */ void print_config(struct bgpd_config *, struct network_head *, struct peer *, |