Commit 6291597c authored by Julien Cristau's avatar 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: default avatarJulien Cristau <jcristau@debian.org>
parent 9a6c24fc
...@@ -238,16 +238,22 @@ main(int argc, char **argv) ...@@ -238,16 +238,22 @@ main(int argc, char **argv)
goto usage; goto usage;
break; break;
case 'g': 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': case 'G':
local_server_port = parse_nat(optarg); if(opt == 'g')
local_server_write = 1; local_server_write = 0;
if(local_server_port <= 0 || local_server_port > 0xFFFF) else
goto usage; 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; break;
case 'l': case 'l':
link_detect = 1; link_detect = 1;
...@@ -526,6 +532,12 @@ main(int argc, char **argv) ...@@ -526,6 +532,12 @@ main(int argc, char **argv)
perror("local_server_socket"); perror("local_server_socket");
goto fail; 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(); init_signals();
...@@ -836,6 +848,10 @@ main(int argc, char **argv) ...@@ -836,6 +848,10 @@ main(int argc, char **argv)
} }
close(fd); close(fd);
} }
if(local_server_socket >= 0 && local_server_path) {
unlink(local_server_path);
free(local_server_path);
}
if(pidfile) if(pidfile)
unlink(pidfile); unlink(pidfile);
debugf("Done.\n"); debugf("Done.\n");
......
...@@ -99,6 +99,7 @@ extern int have_id; ...@@ -99,6 +99,7 @@ extern int have_id;
extern const unsigned char zeroes[16], ones[16]; extern const unsigned char zeroes[16], ones[16];
extern int protocol_port, local_server_port; extern int protocol_port, local_server_port;
extern char *local_server_path;
extern int local_server_write; extern int local_server_write;
extern unsigned char protocol_group[16]; extern unsigned char protocol_group[16];
extern int protocol_socket; extern int protocol_socket;
......
...@@ -109,16 +109,20 @@ requests tracing every message sent or received. A value of ...@@ -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 3 additionally dumps all interactions with the OS kernel. The default
is 0. is 0.
.TP .TP
.BI \-g " port" .BI \-g " port\fR,\fP" " \-g" " path"
Set up a local configuration server on port Set up a local configuration server on port
.I port .I port
or at
.I path
in read-only mode. The protocol is described in the section in read-only mode. The protocol is described in the section
.B Local Configuration Protocol .B Local Configuration Protocol
below. below.
.TP .TP
.BI \-G " port" .BI \-G " port\fR,\fP" " \-G" " path"
Set up a local configuration server on port Set up a local configuration server on port
.I port .I port
or at
.I path
in read-write mode. This allows any local user to change in read-write mode. This allows any local user to change
.BR babeld 's .BR babeld 's
configuration, and may therefore be a security issue. configuration, and may therefore be a security issue.
...@@ -224,10 +228,28 @@ This specifies the TCP port on which ...@@ -224,10 +228,28 @@ This specifies the TCP port on which
.B babeld .B babeld
will listen for connections from a configuration client in read-write mode, will listen for connections from a configuration client in read-write mode,
and is equivalent to the command-line option 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 .BR babeld 's
configuration, and may therefore be a security issue. configuration, and may therefore be a security issue.
.TP .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" .BI export-table " table"
This specifies the kernel routing table to use for routes inserted by This specifies the kernel routing table to use for routes inserted by
.BR babeld , .BR babeld ,
...@@ -554,7 +576,8 @@ it accepts TCP connections from local clients on the given port and address ...@@ -554,7 +576,8 @@ it accepts TCP connections from local clients on the given port and address
.B ::1 .B ::1
(the IPv6 (the IPv6
.B localhost .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 .B babeld
replies with replies with
.B BABEL .B BABEL
......
...@@ -729,9 +729,13 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -729,9 +729,13 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
allow_duplicates = v; allow_duplicates = v;
else if(strcmp(token, "local-port") == 0) { else if(strcmp(token, "local-port") == 0) {
local_server_port = v; local_server_port = v;
free(local_server_path);
local_server_path = NULL;
local_server_write = 0; local_server_write = 0;
} else if(strcmp(token, "local-port-readwrite") == 0) { } else if(strcmp(token, "local-port-readwrite") == 0) {
local_server_port = v; local_server_port = v;
free(local_server_path);
local_server_path = NULL;
local_server_write = 1; local_server_write = 1;
} else if(strcmp(token, "export-table") == 0) } else if(strcmp(token, "export-table") == 0)
export_table = v; export_table = v;
...@@ -776,7 +780,9 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -776,7 +780,9 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
free(group); free(group);
} else if(strcmp(token, "state-file") == 0 || } else if(strcmp(token, "state-file") == 0 ||
strcmp(token, "log-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; char *file;
c = getstring(c, &file, gnc, closure); c = getstring(c, &file, gnc, closure);
if(c < -1) if(c < -1)
...@@ -787,7 +793,17 @@ parse_option(int c, gnc_t gnc, void *closure, char *token) ...@@ -787,7 +793,17 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
logfile = file; logfile = file;
else if(strcmp(token, "pid-file") == 0) else if(strcmp(token, "pid-file") == 0)
pidfile = file; 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(); abort();
} else if(strcmp(token, "debug") == 0) { } else if(strcmp(token, "debug") == 0) {
int d; int d;
......
...@@ -44,6 +44,7 @@ int local_server_socket = -1; ...@@ -44,6 +44,7 @@ int local_server_socket = -1;
struct local_socket local_sockets[MAX_LOCAL_SOCKETS]; struct local_socket local_sockets[MAX_LOCAL_SOCKETS];
int num_local_sockets = 0; int num_local_sockets = 0;
int local_server_port = -1; int local_server_port = -1;
char *local_server_path;
int local_server_write = 0; int local_server_write = 0;
static int static int
......
...@@ -45,6 +45,7 @@ extern int local_server_socket; ...@@ -45,6 +45,7 @@ extern int local_server_socket;
extern struct local_socket local_sockets[MAX_LOCAL_SOCKETS]; extern struct local_socket local_sockets[MAX_LOCAL_SOCKETS];
extern int num_local_sockets; extern int num_local_sockets;
extern int local_server_port; extern int local_server_port;
extern char *local_server_path;
void local_notify_interface(struct interface *ifp, int kind); void local_notify_interface(struct interface *ifp, int kind);
void local_notify_neighbour(struct neighbour *neigh, int kind); void local_notify_neighbour(struct neighbour *neigh, int kind);
......
...@@ -28,6 +28,7 @@ THE SOFTWARE. ...@@ -28,6 +28,7 @@ THE SOFTWARE.
#include <sys/types.h> #include <sys/types.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h> #include <netinet/ip.h>
...@@ -231,3 +232,56 @@ tcp_server_socket(int port, int local) ...@@ -231,3 +232,56 @@ tcp_server_socket(int port, int local)
errno = saved_errno; errno = saved_errno;
return -1; 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, ...@@ -26,3 +26,4 @@ int babel_send(int s,
const void *buf1, int buflen1, const void *buf2, int buflen2, const void *buf1, int buflen1, const void *buf2, int buflen2,
const struct sockaddr *sin, int slen); const struct sockaddr *sin, int slen);
int tcp_server_socket(int port, int local); int tcp_server_socket(int port, int local);
int unix_server_socket(const char *path);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment