The absolute path to the socket can be passed to the -g/-G command line options, or to the new local-path/local-path-readwrite config file directives.
Signed-off-by: Julien Cristau <[email protected]> --- babeld.c | 34 +++++++++++++++++++++++++--------- babeld.h | 1 + babeld.man | 31 +++++++++++++++++++++++++++---- configuration.c | 20 ++++++++++++++++++-- local.c | 1 + local.h | 1 + net.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ net.h | 1 + 8 files changed, 128 insertions(+), 15 deletions(-) Changes in v2: - use consistent style for ifs - local_server_path is a pointer, dynamically allocated, instead of a static array - avoid code duplication between -g and -G flag handling diff --git a/babeld.c b/babeld.c index 203e195..f975ac0 100644 --- a/babeld.c +++ b/babeld.c @@ -238,16 +238,22 @@ main(int argc, char **argv) goto usage; break; case 'g': - local_server_port = parse_nat(optarg); - local_server_write = 0; - if(local_server_port <= 0 || local_server_port > 0xFFFF) - goto usage; - break; case 'G': - local_server_port = parse_nat(optarg); - local_server_write = 1; - if(local_server_port <= 0 || local_server_port > 0xFFFF) - goto usage; + if(opt == 'g') + local_server_write = 0; + else + local_server_write = 1; + if(optarg[0] == '/') { + local_server_port = -1; + free(local_server_path); + local_server_path = strdup(optarg); + } else { + local_server_port = parse_nat(optarg); + free(local_server_path); + local_server_path = NULL; + if(local_server_port <= 0 || local_server_port > 0xFFFF) + goto usage; + } break; case 'l': link_detect = 1; @@ -526,6 +532,12 @@ main(int argc, char **argv) perror("local_server_socket"); goto fail; } + } else if(local_server_path) { + local_server_socket = unix_server_socket(local_server_path); + if(local_server_socket < 0) { + perror("local_server_socket"); + goto fail; + } } init_signals(); @@ -836,6 +848,10 @@ main(int argc, char **argv) } close(fd); } + if(local_server_socket >= 0 && local_server_path) { + unlink(local_server_path); + free(local_server_path); + } if(pidfile) unlink(pidfile); debugf("Done.\n"); diff --git a/babeld.h b/babeld.h index 102408d..1c21b4f 100644 --- a/babeld.h +++ b/babeld.h @@ -99,6 +99,7 @@ extern int have_id; extern const unsigned char zeroes[16], ones[16]; extern int protocol_port, local_server_port; +extern char *local_server_path; extern int local_server_write; extern unsigned char protocol_group[16]; extern int protocol_socket; diff --git a/babeld.man b/babeld.man index d799d24..a7c316a 100644 --- a/babeld.man +++ b/babeld.man @@ -109,16 +109,20 @@ requests tracing every message sent or received. A value of 3 additionally dumps all interactions with the OS kernel. The default is 0. .TP -.BI \-g " port" +.BI \-g " port\fR,\fP" " \-g" " path" Set up a local configuration server on port .I port +or at +.I path in read-only mode. The protocol is described in the section .B Local Configuration Protocol below. .TP -.BI \-G " port" +.BI \-G " port\fR,\fP" " \-G" " path" Set up a local configuration server on port .I port +or at +.I path in read-write mode. This allows any local user to change .BR babeld 's configuration, and may therefore be a security issue. @@ -223,10 +227,28 @@ This specifies the TCP port on which .B babeld will listen for connections from a configuration client in read-write mode, and is equivalent to the command-line option -.BR \-G . This allows any local user to change +.BR \-G . +This allows any local user to change .BR babeld 's configuration, and may therefore be a security issue. .TP +.BI local-path " path" +This specifies the filesystem path to a socket on which +.B babeld +will listen for connections from a configuration client in read-only mode, +and is equivalent to the command-line option +.BR \-g . +.TP +.BI local-path-readwrite " path" +This specifies the filesystem path to a socket on which +.B babeld +will listen for connections from a configuration client in read-write mode, +and is equivalent to the command-line option +.BR \-G . +Any user with write access to that socket will be able to change +.BR babeld 's +configuration. +.TP .BI export-table " table" This specifies the kernel routing table to use for routes inserted by .BR babeld , @@ -553,7 +575,8 @@ it accepts TCP connections from local clients on the given port and address .B ::1 (the IPv6 .B localhost -address). When a client connects, +address), or on the given UNIX-domain socket path if the argument starts with +\[oq]/\[cq]. When a client connects, .B babeld replies with .B BABEL diff --git a/configuration.c b/configuration.c index 852df07..f2d7b76 100644 --- a/configuration.c +++ b/configuration.c @@ -725,9 +725,13 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) allow_duplicates = v; else if(strcmp(token, "local-port") == 0) { local_server_port = v; + free(local_server_path); + local_server_path = NULL; local_server_write = 0; } else if(strcmp(token, "local-port-readwrite") == 0) { local_server_port = v; + free(local_server_path); + local_server_path = NULL; local_server_write = 1; } else if(strcmp(token, "export-table") == 0) export_table = v; @@ -772,7 +776,9 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) free(group); } else if(strcmp(token, "state-file") == 0 || strcmp(token, "log-file") == 0 || - strcmp(token, "pid-file") == 0) { + strcmp(token, "pid-file") == 0 || + strcmp(token, "local-path") == 0 || + strcmp(token, "local-path-readwrite") == 0) { char *file; c = getstring(c, &file, gnc, closure); if(c < -1) @@ -783,7 +789,17 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) logfile = file; else if(strcmp(token, "pid-file") == 0) pidfile = file; - else + else if(strcmp(token, "local-path") == 0) { + local_server_port = -1; + free(local_server_path); + local_server_path = file; + local_server_write = 0; + } else if(strcmp(token, "local-path-readwrite") == 0) { + local_server_port = -1; + free(local_server_path); + local_server_path = file; + local_server_write = 1; + } else abort(); } else if(strcmp(token, "debug") == 0) { int d; diff --git a/local.c b/local.c index 372b418..d3db62f 100644 --- a/local.c +++ b/local.c @@ -44,6 +44,7 @@ int local_server_socket = -1; struct local_socket local_sockets[MAX_LOCAL_SOCKETS]; int num_local_sockets = 0; int local_server_port = -1; +char *local_server_path; int local_server_write = 0; static int diff --git a/local.h b/local.h index b2fe26b..2316111 100644 --- a/local.h +++ b/local.h @@ -45,6 +45,7 @@ extern int local_server_socket; extern struct local_socket local_sockets[MAX_LOCAL_SOCKETS]; extern int num_local_sockets; extern int local_server_port; +extern char *local_server_path; void local_notify_interface(struct interface *ifp, int kind); void local_notify_neighbour(struct neighbour *neigh, int kind); diff --git a/net.c b/net.c index d1e404a..1e5890d 100644 --- a/net.c +++ b/net.c @@ -28,6 +28,7 @@ THE SOFTWARE. #include <sys/types.h> #include <sys/uio.h> #include <sys/socket.h> +#include <sys/un.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -231,3 +232,56 @@ tcp_server_socket(int port, int local) errno = saved_errno; return -1; } + +int +unix_server_socket(const char *path) +{ + struct sockaddr_un sun; + int s, rc, saved_errno; + + if(strlen(path) >= sizeof(sun.sun_path)) + return -1; + + s = socket(PF_UNIX, SOCK_STREAM, 0); + if(s < 0) + return -1; + + rc = fcntl(s, F_GETFL, 0); + if(rc < 0) + goto fail; + + rc = fcntl(s, F_SETFL, rc | O_NONBLOCK); + if(rc < 0) + goto fail; + + rc = fcntl(s, F_GETFD, 0); + if(rc < 0) + goto fail; + + rc = fcntl(s, F_SETFD, rc | FD_CLOEXEC); + if(rc < 0) + goto fail; + + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_UNIX; + strncpy(sun.sun_path, path, sizeof(sun.sun_path)); + rc = bind(s, (struct sockaddr *)&sun, sizeof(sun)); + if(rc < 0) + goto fail; + + rc = listen(s, 2); + if(rc < 0) + goto fail_unlink; + + return s; + +fail_unlink: + saved_errno = errno; + unlink(path); + errno = saved_errno; +fail: + saved_errno = errno; + close(s); + errno = saved_errno; + return -1; +} diff --git a/net.h b/net.h index aa20b86..56c1bb2 100644 --- a/net.h +++ b/net.h @@ -26,3 +26,4 @@ int babel_send(int s, const void *buf1, int buflen1, const void *buf2, int buflen2, const struct sockaddr *sin, int slen); int tcp_server_socket(int port, int local); +int unix_server_socket(const char *path); -- 2.7.0 _______________________________________________ Babel-users mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/babel-users

