Commit 6291597c by Julien Cristau Committed by Juliusz Chroboczek

Add support for unix-domain local socket

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@debian.org>
1 parent 9a6c24fc
......@@ -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");
......
......@@ -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;
......
......@@ -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.
......@@ -224,10 +228,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 ,
......@@ -554,7 +576,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
......
......@@ -729,9 +729,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;
......@@ -776,7 +780,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)
......@@ -787,7 +793,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;
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
}
......@@ -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);
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!