summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-05-28 18:39:10 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-05-28 18:39:10 +0000
commit831d4b2edaf2875a6f07d2d8f046a52d9b6ce953 (patch)
treeba7afd0f8f3262765c0ab1cc4877949c658fa43e /usr.sbin
parent83d23ae0746114f947c8dd433de3dc7935c7c2bb (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
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/pfkey.c15
-rw-r--r--usr.sbin/bgpd/session.c47
-rw-r--r--usr.sbin/bgpd/session.h13
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 *,