diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 12 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 9 | ||||
-rw-r--r-- | usr.sbin/bgpd/config.c | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/control.c | 71 | ||||
-rw-r--r-- | usr.sbin/bgpd/log.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 27 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 10 |
7 files changed, 95 insertions, 42 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index a3a2235fc19..ec73429e23a 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.129 2006/01/03 16:49:23 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.130 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -86,7 +86,7 @@ usage(void) extern char *__progname; fprintf(stderr, "usage: %s [-dnv] ", __progname); - fprintf(stderr, "[-D macro=value] [-f file]\n"); + fprintf(stderr, "[-D macro=value] [-f file] [-r path]\n"); exit(1); } @@ -131,7 +131,7 @@ main(int argc, char *argv[]) TAILQ_INIT(rules_l); peer_l = NULL; - while ((ch = getopt(argc, argv, "dD:f:nv")) != -1) { + while ((ch = getopt(argc, argv, "dD:f:nr:v")) != -1) { switch (ch) { case 'd': debug = 1; @@ -152,6 +152,9 @@ main(int argc, char *argv[]) conf.opts |= BGPD_OPT_VERBOSE2; conf.opts |= BGPD_OPT_VERBOSE; break; + case 'r': + conf.rcsock = optarg; + break; default: usage(); /* NOTREACHED */ @@ -352,7 +355,8 @@ main(int argc, char *argv[]) } free(rules_l); - control_cleanup(); + control_cleanup(SOCKET_NAME); + control_cleanup(conf.rcsock); kr_shutdown(); pftable_clear_all(); free(conf.listen_addrs); diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 9337fd548be..af774aa802e 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.187 2006/01/20 16:40:17 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.188 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -142,6 +142,7 @@ struct bgpd_config { struct filter_set_head staticset; struct filter_set_head staticset6; struct listen_addrs *listen_addrs; + char *rcsock; int opts; int flags; int log; @@ -334,7 +335,8 @@ struct imsg { enum ctl_results { CTL_RES_OK, - CTL_RES_NOSUCHPEER + CTL_RES_NOSUCHPEER, + CTL_RES_DENIED }; /* needed for session.h parse prototype */ @@ -730,8 +732,7 @@ void inet6applymask(struct in6_addr *, const struct in6_addr *, int); /* control.c */ -int control_init(void); -void control_cleanup(void); +void control_cleanup(const char *); int control_imsg_relay(struct imsg *); /* pftable.c */ diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c index fbee85d0421..d65a3af6c51 100644 --- a/usr.sbin/bgpd/config.c +++ b/usr.sbin/bgpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.46 2005/07/14 09:24:38 dlg Exp $ */ +/* $OpenBSD: config.c,v 1.47 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -47,6 +47,7 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf, /* preserve cmd line opts */ conf->opts = xconf->opts; + conf->rcsock = xconf->rcsock; if (!conf->as) { log_warnx("configuration error: AS not given"); diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c index b2cb2418c67..6c498c1c642 100644 --- a/usr.sbin/bgpd/control.c +++ b/usr.sbin/bgpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.46 2006/01/03 22:49:17 claudio Exp $ */ +/* $OpenBSD: control.c,v 1.47 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -32,6 +32,7 @@ struct { int fd; + int restricted_fd; } control_state; struct ctl_conn *control_connbyfd(int); @@ -40,11 +41,11 @@ int control_close(int); void control_result(struct ctl_conn *, u_int); int -control_init(void) +control_init(int restricted, char *path) { struct sockaddr_un sun; int fd; - mode_t old_umask; + mode_t old_umask, mode; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { log_warn("control_init: socket"); @@ -53,18 +54,25 @@ control_init(void) bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; - strlcpy(sun.sun_path, SOCKET_NAME, sizeof(sun.sun_path)); + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); - if (unlink(SOCKET_NAME) == -1) + if (unlink(path) == -1) if (errno != ENOENT) { - log_warn("unlink %s", SOCKET_NAME); + log_warn("unlink %s", path); close(fd); return (-1); } - old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); + if (restricted) { + old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH); + mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + } else { + old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); + mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP; + } + if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { - log_warn("control_init: bind: %s", SOCKET_NAME); + log_warn("control_init: bind: %s", path); close(fd); umask(old_umask); return (-1); @@ -72,44 +80,44 @@ control_init(void) umask(old_umask); - if (chmod(SOCKET_NAME, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) { - log_warn("control_init chmod"); + if (chmod(path, mode) == -1) { + log_warn("control_init: chmod: %s", path); close(fd); - (void)unlink(SOCKET_NAME); + unlink(path); return (-1); } session_socket_blockmode(fd, BM_NONBLOCK); - control_state.fd = fd; return (fd); } int -control_listen(void) +control_listen(int fd) { - if (listen(control_state.fd, CONTROL_BACKLOG) == -1) { + if (fd != -1 && listen(fd, CONTROL_BACKLOG) == -1) { log_warn("control_listen: listen"); return (-1); } - return (control_state.fd); + return (0); } void -control_shutdown(void) +control_shutdown(int fd) { - close(control_state.fd); + close(fd); } void -control_cleanup(void) +control_cleanup(const char *path) { - unlink(SOCKET_NAME); + if (path) + unlink(path); } int -control_accept(int listenfd) +control_accept(int listenfd, int restricted) { int connfd; socklen_t len; @@ -132,6 +140,7 @@ control_accept(int listenfd) } imsg_init(&ctl_conn->ibuf, connfd); + ctl_conn->restricted = restricted; TAILQ_INSERT_TAIL(&ctl_conns, ctl_conn, entry); @@ -218,7 +227,29 @@ control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt) if (n == 0) break; + if (c->restricted) { + switch (imsg.hdr.type) { + case IMSG_CTL_SHOW_NEIGHBOR: + case IMSG_CTL_SHOW_NEXTHOP: + case IMSG_CTL_SHOW_INTERFACE: + case IMSG_CTL_SHOW_RIB: + case IMSG_CTL_SHOW_RIB_AS: + case IMSG_CTL_SHOW_RIB_PREFIX: + case IMSG_CTL_SHOW_RIB_MEM: + case IMSG_CTL_SHOW_NETWORK: + break; + default: + /* clear imsg type to prevent processing */ + imsg.hdr.type = IMSG_NONE; + control_result(c, CTL_RES_DENIED); + break; + } + } + switch (imsg.hdr.type) { + case IMSG_NONE: + /* message was filtered out, nothing to do */ + break; case IMSG_CTL_SHOW_NEIGHBOR: c->ibuf.pid = imsg.hdr.pid; if (imsg.hdr.len == IMSG_HEADER_SIZE + diff --git a/usr.sbin/bgpd/log.h b/usr.sbin/bgpd/log.h index a8387e00957..61ad86f3c30 100644 --- a/usr.sbin/bgpd/log.h +++ b/usr.sbin/bgpd/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.5 2005/10/19 12:32:16 henning Exp $ */ +/* $OpenBSD: log.h,v 1.6 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -106,5 +106,6 @@ static const char * const procnames[] = { static const char * const ctl_res_strerror[] = { "no error", - "no such neighbor" + "no such neighbor", + "permission denied" }; diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 15e8622e408..ca5a675c196 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.241 2006/01/03 22:49:17 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.242 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -46,7 +46,8 @@ #define PFD_PIPE_MAIN 0 #define PFD_PIPE_ROUTE 1 #define PFD_SOCK_CTL 2 -#define PFD_LISTENERS_START 3 +#define PFD_SOCK_RCTL 3 +#define PFD_LISTENERS_START 4 void session_sighdlr(int); int setup_listeners(u_int *); @@ -91,7 +92,7 @@ struct bgpd_sysdep sysdep; struct peer *npeers; volatile sig_atomic_t session_quit = 0; int pending_reconf = 0; -int csock = -1; +int csock = -1, rcsock = -1; u_int peer_cnt; struct imsgbuf *ibuf_rde; struct imsgbuf *ibuf_main; @@ -193,7 +194,10 @@ session_main(struct bgpd_config *config, struct peer *cpeers, } /* control socket is outside chroot */ - if ((csock = control_init()) == -1) + if ((csock = control_init(0, SOCKET_NAME)) == -1) + fatalx("control socket setup failed"); + if (conf->rcsock != NULL && + (rcsock = control_init(1, conf->rcsock)) == -1) fatalx("control socket setup failed"); if ((pw = getpwnam(BGPD_USER)) == NULL) @@ -233,7 +237,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers, imsg_init(ibuf_rde, pipe_s2r[0]); imsg_init(ibuf_main, pipe_m2s[1]); TAILQ_INIT(&ctl_conns); - csock = control_listen(); + control_listen(csock); + control_listen(rcsock); LIST_INIT(&mrthead); peer_cnt = 0; ctl_cnt = 0; @@ -351,6 +356,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers, pfd[PFD_PIPE_ROUTE].events |= POLLOUT; pfd[PFD_SOCK_CTL].fd = csock; pfd[PFD_SOCK_CTL].events = POLLIN; + pfd[PFD_SOCK_RCTL].fd = rcsock; + pfd[PFD_SOCK_RCTL].events = POLLIN; nextaction = time(NULL) + 240; /* loop every 240s at least */ i = PFD_LISTENERS_START; @@ -463,7 +470,12 @@ session_main(struct bgpd_config *config, struct peer *cpeers, if (nfds > 0 && pfd[PFD_SOCK_CTL].revents & POLLIN) { nfds--; - ctl_cnt += control_accept(csock); + ctl_cnt += control_accept(csock, 0); + } + + if (nfds > 0 && pfd[PFD_SOCK_RCTL].revents & POLLIN) { + nfds--; + ctl_cnt += control_accept(rcsock, 1); } for (j = PFD_LISTENERS_START; nfds > 0 && j < idx_listeners; @@ -516,7 +528,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers, msgbuf_clear(&ibuf_main->w); free(ibuf_main); - control_shutdown(); + control_shutdown(csock); + control_shutdown(rcsock); log_info("session engine exiting"); _exit(0); } diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index a310266573a..0322a0ffcb4 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.80 2006/01/03 22:19:59 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.81 2006/01/24 10:03:44 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -128,6 +128,7 @@ struct bgpd_sysdep { struct ctl_conn { TAILQ_ENTRY(ctl_conn) entry; struct imsgbuf ibuf; + int restricted; }; TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns; @@ -214,10 +215,11 @@ pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *, struct filter_head *, struct mrt_head *, int[2], int[2], int[2]); /* control.c */ -int control_listen(void); -void control_shutdown(void); +int control_init(int, char *); +int control_listen(int); +void control_shutdown(int); int control_dispatch_msg(struct pollfd *, u_int *); -int control_accept(int); +int control_accept(int, int); /* pfkey.c */ int pfkey_establish(struct peer *); |