Allow ``set server closed'' to close the diagnostic socket.

Allow ``set server open'' to re-open the diagnostic socket.
Handle SIGUSR1 by re-opening the diagnostic socket
When receiving SIGUSR2 (and in ``set server none''), don't forget the
socket details so that ``set server open'' and SIGUSR1 open it again.

Don't create the diagnostic socket as uid 0 !  It's far to dangerous.
This commit is contained in:
Brian Somers 2001-01-26 01:41:34 +00:00
parent 283028861e
commit 74457d3d43
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71657
9 changed files with 258 additions and 85 deletions

View File

@ -96,6 +96,7 @@
#include "datalink.h"
#include "ip.h"
#include "iface.h"
#include "server.h"
#define SCATTER_SEGMENTS 7 /* version, datalink, name, physical,
throughput, throughput, device */
@ -1177,18 +1178,29 @@ bundle_ShowStatus(struct cmdargs const *arg)
arg->bundle->cfg.ifqueue);
prompt_Printf(arg->prompt, "\nDefaults:\n");
prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label);
prompt_Printf(arg->prompt, " Auth name: %s\n",
prompt_Printf(arg->prompt, " Label: %s\n",
arg->bundle->cfg.label);
prompt_Printf(arg->prompt, " Auth name: %s\n",
arg->bundle->cfg.auth.name);
prompt_Printf(arg->prompt, " Diagnostic socket: ");
if (*server.cfg.sockname != '\0')
prompt_Printf(arg->prompt, "%s, mask 0%03o%s\n",
server.cfg.sockname, (int)server.cfg.mask,
server.fd == -1 ? " (not open)" : "");
else if (server.cfg.port != 0)
prompt_Printf(arg->prompt, "TCP port %d%s\n", server.cfg.port,
server.fd == -1 ? " (not open)" : "");
else
prompt_Printf(arg->prompt, "none\n");
prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
arg->bundle->cfg.choked.timeout);
#ifndef NORADIUS
radius_Show(&arg->bundle->radius, arg->prompt);
#endif
prompt_Printf(arg->prompt, " Idle Timer: ");
prompt_Printf(arg->prompt, " Idle Timer: ");
if (arg->bundle->cfg.idle.timeout) {
prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle.timeout);
if (arg->bundle->cfg.idle.min_timeout)
@ -1200,13 +1212,13 @@ bundle_ShowStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "\n");
} else
prompt_Printf(arg->prompt, "disabled\n");
prompt_Printf(arg->prompt, " MTU: ");
prompt_Printf(arg->prompt, " MTU: ");
if (arg->bundle->cfg.mtu)
prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
else
prompt_Printf(arg->prompt, "unspecified\n");
prompt_Printf(arg->prompt, " sendpipe: ");
prompt_Printf(arg->prompt, " sendpipe: ");
if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
prompt_Printf(arg->prompt, "%-20ld", arg->bundle->ncp.ipcp.cfg.sendpipe);
else
@ -1217,29 +1229,29 @@ bundle_ShowStatus(struct cmdargs const *arg)
else
prompt_Printf(arg->prompt, "unspecified\n");
prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s",
prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s",
optval(arg->bundle, OPT_SROUTES));
prompt_Printf(arg->prompt, " Filter Decap: %s\n",
prompt_Printf(arg->prompt, " Filter Decap: %s\n",
optval(arg->bundle, OPT_FILTERDECAP));
prompt_Printf(arg->prompt, " ID check: %-20.20s",
prompt_Printf(arg->prompt, " ID check: %-20.20s",
optval(arg->bundle, OPT_IDCHECK));
prompt_Printf(arg->prompt, " Keep-Session: %s\n",
prompt_Printf(arg->prompt, " Keep-Session: %s\n",
optval(arg->bundle, OPT_KEEPSESSION));
prompt_Printf(arg->prompt, " Loopback: %-20.20s",
prompt_Printf(arg->prompt, " Loopback: %-20.20s",
optval(arg->bundle, OPT_LOOPBACK));
prompt_Printf(arg->prompt, " PasswdAuth: %s\n",
prompt_Printf(arg->prompt, " PasswdAuth: %s\n",
optval(arg->bundle, OPT_PASSWDAUTH));
prompt_Printf(arg->prompt, " Proxy: %-20.20s",
prompt_Printf(arg->prompt, " Proxy: %-20.20s",
optval(arg->bundle, OPT_PROXY));
prompt_Printf(arg->prompt, " Proxyall: %s\n",
prompt_Printf(arg->prompt, " Proxyall: %s\n",
optval(arg->bundle, OPT_PROXYALL));
prompt_Printf(arg->prompt, " TCPMSS Fixup: %-20.20s",
prompt_Printf(arg->prompt, " TCPMSS Fixup: %-20.20s",
optval(arg->bundle, OPT_TCPMSSFIXUP));
prompt_Printf(arg->prompt, " Throughput: %s\n",
prompt_Printf(arg->prompt, " Throughput: %s\n",
optval(arg->bundle, OPT_THROUGHPUT));
prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
optval(arg->bundle, OPT_UTMP));
prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
optval(arg->bundle, OPT_IFACEALIAS));
return 0;

View File

@ -1287,14 +1287,35 @@ SetServer(struct cmdargs const *arg)
return -1;
}
} else if (strcasecmp(port, "none") == 0) {
if (server_Clear(arg->bundle))
log_Printf(LogPHASE, "Disabled server socket\n");
return 0;
} else if (strcasecmp(port, "open") == 0) {
switch (server_Reopen(arg->bundle)) {
case SERVER_OK:
return 0;
case SERVER_FAILED:
log_Printf(LogPHASE, "Failed to reopen server port\n");
return 1;
case SERVER_UNSET:
log_Printf(LogPHASE, "Cannot reopen unset server socket\n");
return 1;
default:
break;
}
return -1;
} else if (strcasecmp(port, "closed") == 0) {
if (server_Close(arg->bundle))
log_Printf(LogPHASE, "Disabled server port.\n");
log_Printf(LogPHASE, "Closed server socket\n");
else
log_Printf(LogWARN, "Server socket not open\n");
return 0;
} else
return -1;
strncpy(server.passwd, passwd, sizeof server.passwd - 1);
server.passwd[sizeof server.passwd - 1] = '\0';
strncpy(server.cfg.passwd, passwd, sizeof server.cfg.passwd - 1);
server.cfg.passwd[sizeof server.cfg.passwd - 1] = '\0';
if (*port == '/') {
mode_t imask;
@ -2060,8 +2081,8 @@ static struct cmdtab const SetCommands[] = {
"Redial timeout", "set redial secs[+inc[-incmax]][.next] [attempts]"},
{"sendpipe", NULL, SetVariable, LOCAL_AUTH,
"SENDPIPE value", "set sendpipe value", (const void *)VAR_SENDPIPE},
{"server", "socket", SetServer, LOCAL_AUTH,
"server port", "set server|socket TcpPort|LocalName|none password [mask]"},
{"server", "socket", SetServer, LOCAL_AUTH, "diagnostic port",
"set server|socket TcpPort|LocalName|none|open|closed [password [mask]]"},
{"speed", NULL, SetModemSpeed, LOCAL_AUTH | LOCAL_CX,
"physical speed", "set speed value|sync"},
{"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH | LOCAL_CX,

View File

@ -162,7 +162,15 @@ static void
BringDownServer(int signo)
{
/* Drops all child prompts too ! */
server_Close(SignalBundle);
if (server_Close(SignalBundle))
log_Printf(LogPHASE, "Closed server socket\n");
}
static void
RestartServer(int signo)
{
/* Drops all child prompts and re-opens the socket */
server_Reopen(SignalBundle);
}
static void
@ -371,6 +379,7 @@ main(int argc, char **argv)
if (sw.mode == PHYS_INTERACTIVE)
sig_signal(SIGTSTP, TerminalStop);
sig_signal(SIGUSR1, RestartServer);
sig_signal(SIGUSR2, BringDownServer);
lastlabel = argv[argc - 1];

View File

@ -2351,11 +2351,18 @@ mode.
These signals tell
.Nm
to exit.
.It USR1
This signal, tells
.Nm
to re-open any existing server socket, dropping all existing diagnostic
connections. Sockets that couldn't previously be opened will be retried.
.It USR2
This signal, tells
.Nm
to close any existing server socket, dropping all existing diagnostic
connections.
.Dv SIGUSR1
can still be used to re-open the socket.
.El
.Pp
.Sh MULTI-LINK PPP
@ -5141,7 +5148,7 @@ The optimum value is just over twice the MTU value.
If
.Ar value
is unspecified or zero, the default kernel controlled value is used.
.It set server|socket Ar TcpPort|LocalName|none password Op Ar mask
.It set server|socket Ar TcpPort|LocalName|none|open|closed Op password Op Ar mask
This command tells
.Nm
to listen on the given socket or
@ -5152,7 +5159,17 @@ The word
.Ar none
instructs
.Nm
to close any existing socket.
to close any existing socket and clear the socket configuration.
The word
.Ar open
instructs
.Nm
to attempt to re-open the port.
The word
.Ar closed
instructs
.Nm
to close the open port.
.Pp
If you wish to specify a local domain socket,
.Ar LocalName
@ -5169,7 +5186,7 @@ for details of how to translate TCP port names.
You must also specify the password that must be entered by the client
(using the
.Dq passwd
command above) when connecting to this socket.
variable above) when connecting to this socket.
If the password is
specified as an empty string, no password is required for connecting clients.
.Pp
@ -5194,7 +5211,13 @@ Currently,
.Xr telnet 1
can also be used, but link encryption may be implemented in the future, so
.Xr telnet 1
should not be relied upon.
should be avoided.
.Pp
Note;
.Dv SIGUSR1
and
.Dv SIGUSR2
interact with the diagnostic socket.
.It set speed Ar value
This sets the speed of the serial device.
If speed is specified as

View File

@ -2351,11 +2351,18 @@ mode.
These signals tell
.Nm
to exit.
.It USR1
This signal, tells
.Nm
to re-open any existing server socket, dropping all existing diagnostic
connections. Sockets that couldn't previously be opened will be retried.
.It USR2
This signal, tells
.Nm
to close any existing server socket, dropping all existing diagnostic
connections.
.Dv SIGUSR1
can still be used to re-open the socket.
.El
.Pp
.Sh MULTI-LINK PPP
@ -5141,7 +5148,7 @@ The optimum value is just over twice the MTU value.
If
.Ar value
is unspecified or zero, the default kernel controlled value is used.
.It set server|socket Ar TcpPort|LocalName|none password Op Ar mask
.It set server|socket Ar TcpPort|LocalName|none|open|closed Op password Op Ar mask
This command tells
.Nm
to listen on the given socket or
@ -5152,7 +5159,17 @@ The word
.Ar none
instructs
.Nm
to close any existing socket.
to close any existing socket and clear the socket configuration.
The word
.Ar open
instructs
.Nm
to attempt to re-open the port.
The word
.Ar closed
instructs
.Nm
to close the open port.
.Pp
If you wish to specify a local domain socket,
.Ar LocalName
@ -5169,7 +5186,7 @@ for details of how to translate TCP port names.
You must also specify the password that must be entered by the client
(using the
.Dq passwd
command above) when connecting to this socket.
variable above) when connecting to this socket.
If the password is
specified as an empty string, no password is required for connecting clients.
.Pp
@ -5194,7 +5211,13 @@ Currently,
.Xr telnet 1
can also be used, but link encryption may be implemented in the future, so
.Xr telnet 1
should not be relied upon.
should be avoided.
.Pp
Note;
.Dv SIGUSR1
and
.Dv SIGUSR2
interact with the diagnostic socket.
.It set speed Ar value
This sets the speed of the serial device.
If speed is specified as

View File

@ -330,7 +330,7 @@ prompt_Create(struct server *s, struct bundle *bundle, int fd)
p->fd_in = p->fd_out = fd;
p->Term = fdopen(fd, "a+");
p->owner = s;
p->auth = *s->passwd ? LOCAL_NO_AUTH : LOCAL_AUTH;
p->auth = *s->cfg.passwd ? LOCAL_NO_AUTH : LOCAL_AUTH;
p->src.type = "unknown";
*p->src.from = '\0';
}
@ -518,7 +518,7 @@ PasswdCommand(struct cmdargs const *arg)
else
pass = arg->argv[arg->argn];
if (!strcmp(arg->prompt->owner->passwd, pass))
if (!strcmp(arg->prompt->owner->cfg.passwd, pass))
arg->prompt->auth = LOCAL_AUTH;
else
arg->prompt->auth = LOCAL_NO_AUTH;

View File

@ -628,14 +628,15 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl,
void
radius_Show(struct radius *r, struct prompt *p)
{
prompt_Printf(p, " Radius config: %s", *r->cfg.file ? r->cfg.file : "none");
prompt_Printf(p, " Radius config: %s",
*r->cfg.file ? r->cfg.file : "none");
if (r->valid) {
prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip));
prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask));
prompt_Printf(p, " MTU: %lu\n", r->mtu);
prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis");
prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip));
prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask));
prompt_Printf(p, " MTU: %lu\n", r->mtu);
prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis");
if (r->routes)
route_ShowSticky(p, r->routes, " Routes", 16);
route_ShowSticky(p, r->routes, " Routes", 16);
} else
prompt_Printf(p, " (not authenticated)\n");
}

View File

@ -26,7 +26,8 @@
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -138,7 +139,7 @@ server_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
switch (sa->sa_family) {
case AF_LOCAL:
p->src.type = "local";
strncpy(p->src.from, s->rm, sizeof p->src.from - 1);
strncpy(p->src.from, s->cfg.sockname, sizeof p->src.from - 1);
p->src.from[sizeof p->src.from - 1] = '\0';
break;
case AF_INET:
@ -180,70 +181,115 @@ struct server server = {
-1
};
int
enum server_stat
server_Reopen(struct bundle *bundle)
{
char name[sizeof server.cfg.sockname];
u_short port;
mode_t mask;
enum server_stat ret;
if (server.cfg.sockname[0] != '\0') {
strcpy(name, server.cfg.sockname);
mask = server.cfg.mask;
server_Close(bundle);
if (server.cfg.sockname[0] != '\0')
/* blow it away - and hope nobody else is using it */
unlink(server.cfg.sockname);
ret = server_LocalOpen(bundle, name, mask);
} else if (server.cfg.port != 0) {
port = server.cfg.port;
server_Close(bundle);
ret = server_TcpOpen(bundle, port);
} else
ret = SERVER_UNSET;
return ret;
}
enum server_stat
server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask)
{
struct sockaddr_un ifsun;
mode_t oldmask;
int s;
if (server.rm && !strcmp(server.rm, name)) {
if (chmod(server.rm, 0777 & ~mask))
log_Printf(LogERROR, "Local: chmod: %s\n", strerror(errno));
return 0;
}
oldmask = (mode_t)-1; /* Silence compiler */
memset(&server.ifsun, '\0', sizeof server.ifsun);
server.ifsun.sun_len = strlen(name);
if (server.ifsun.sun_len > sizeof server.ifsun.sun_path - 1) {
if (server.cfg.sockname && !strcmp(server.cfg.sockname, name))
server_Close(bundle);
memset(&ifsun, '\0', sizeof ifsun);
ifsun.sun_len = strlen(name);
if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
log_Printf(LogERROR, "Local: %s: Path too long\n", name);
return 2;
return SERVER_INVALID;
}
server.ifsun.sun_family = AF_LOCAL;
strcpy(server.ifsun.sun_path, name);
ifsun.sun_family = AF_LOCAL;
strcpy(ifsun.sun_path, name);
s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
s = socket(PF_LOCAL, SOCK_STREAM, 0);
if (s < 0) {
log_Printf(LogERROR, "Local: socket: %s\n", strerror(errno));
return 3;
goto failed;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
if (mask != (mode_t)-1)
mask = umask(mask);
if (bind(s, (struct sockaddr *)&server.ifsun, sizeof server.ifsun) < 0) {
oldmask = umask(mask);
if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) {
if (mask != (mode_t)-1)
umask(mask);
umask(oldmask);
log_Printf(LogWARN, "Local: bind: %s\n", strerror(errno));
close(s);
return 4;
goto failed;
}
if (mask != (mode_t)-1)
umask(mask);
umask(oldmask);
if (listen(s, 5) != 0) {
log_Printf(LogERROR, "Local: Unable to listen to socket -"
" BUNDLE overload?\n");
close(s);
ID0unlink(name);
return 5;
unlink(name);
goto failed;
}
server_Close(bundle);
server.fd = s;
server.rm = server.ifsun.sun_path;
server.cfg.port = 0;
strncpy(server.cfg.sockname, ifsun.sun_path, sizeof server.cfg.sockname - 1);
server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0';
server.cfg.mask = mask;
log_Printf(LogPHASE, "Listening at local socket %s.\n", name);
return 0;
return SERVER_OK;
failed:
if (server.fd == -1) {
server.fd = -1;
server.cfg.port = 0;
strncpy(server.cfg.sockname, ifsun.sun_path,
sizeof server.cfg.sockname - 1);
server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0';
server.cfg.mask = mask;
}
return SERVER_FAILED;
}
int
server_TcpOpen(struct bundle *bundle, int port)
enum server_stat
server_TcpOpen(struct bundle *bundle, u_short port)
{
struct sockaddr_in ifsin;
int s;
if (server.port == port)
return 0;
if (server.cfg.port == port)
server_Close(bundle);
s = ID0socket(PF_INET, SOCK_STREAM, 0);
if (port == 0)
return SERVER_INVALID;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
log_Printf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
return 7;
goto failed;
}
memset(&ifsin, '\0', sizeof ifsin);
ifsin.sin_family = AF_INET;
@ -253,40 +299,66 @@ server_TcpOpen(struct bundle *bundle, int port)
if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) {
log_Printf(LogWARN, "Tcp: bind: %s\n", strerror(errno));
close(s);
return 8;
goto failed;
}
if (listen(s, 5) != 0) {
log_Printf(LogERROR, "Tcp: Unable to listen to socket: %s\n",
strerror(errno));
close(s);
return 9;
goto failed;
}
server_Close(bundle);
server.fd = s;
server.port = port;
server.cfg.port = port;
*server.cfg.sockname = '\0';
server.cfg.mask = 0;
log_Printf(LogPHASE, "Listening at port %d.\n", port);
return 0;
return SERVER_OK;
failed:
if (server.fd == -1) {
server.fd = -1;
server.cfg.port = port;
*server.cfg.sockname = '\0';
server.cfg.mask = 0;
}
return SERVER_FAILED;
}
int
server_Close(struct bundle *bundle)
{
if (server.fd >= 0) {
if (server.rm) {
if (*server.cfg.sockname != '\0') {
struct sockaddr_un un;
int sz = sizeof un;
if (getsockname(server.fd, (struct sockaddr *)&un, &sz) == 0 &&
un.sun_family == AF_LOCAL && sz == sizeof un)
ID0unlink(un.sun_path);
server.rm = NULL;
unlink(un.sun_path);
}
close(server.fd);
server.fd = -1;
server.port = 0;
/* Drop associated prompts */
log_DestroyPrompts(&server);
return 1;
}
return 0;
}
int
server_Clear(struct bundle *bundle)
{
int ret;
ret = server_Close(bundle);
server.fd = -1;
server.cfg.port = 0;
*server.cfg.sockname = '\0';
server.cfg.mask = 0;
return ret;
}

View File

@ -31,12 +31,22 @@ struct bundle;
struct server {
struct fdescriptor desc;
int fd;
char passwd[50];
struct sockaddr_un ifsun; /* local socket */
char *rm; /* Points to local socket path */
struct {
char passwd[50];
u_short port; /* tcp socket */
char sockname[MAXPATHLEN]; /* Points to local socket path */
mode_t mask;
u_short port; /* tcp socket */
} cfg;
};
enum server_stat {
SERVER_OK, /* Diagnostic socket available */
SERVER_INVALID, /* Bad args, can't be set up */
SERVER_FAILED, /* Failed - lack of resources */
SERVER_UNSET /* Not already set up */
};
#define descriptor2server(d) \
@ -44,6 +54,8 @@ struct server {
extern struct server server;
extern int server_LocalOpen(struct bundle *, const char *, mode_t);
extern int server_TcpOpen(struct bundle *, int);
extern enum server_stat server_LocalOpen(struct bundle *, const char *, mode_t);
extern enum server_stat server_TcpOpen(struct bundle *, u_short);
extern enum server_stat server_Reopen(struct bundle *);
extern int server_Close(struct bundle *);
extern int server_Clear(struct bundle *);