[Babel-users] [PATCH v2] Add support for unix-domain local socket
Julien Cristau
jcristau at debian.org
Sat Feb 13 14:13:28 UTC 2016
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 <jcristau at debian.org>
---
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
More information about the Babel-users
mailing list