Simplify handling of /DETACH socket path

init_socketpath() was building a sprintf() format string intended to be used by /DETACH to create the socket
file name.  This included the actual socket path, plus a %d for the port, plus the sanitised tty name and
hostname.

Only one caller needed all this though - the /DETACH command - and the other callers (in scr-bx.c) just
wanted to truncate it to the actual socket path.  The format string also wasn't safe - if the home directory
path, hostname or ttyname contained % characters these werent being escaped.

It simplifies things to have init_socketpath() just return the actual socket path, after creating the 'screens'
directory if necessary.  This lets the code in scr-bx.c use it as-is, and removes the need for the global
socket_path variable.  The code to include the sanitised tty name and hostname in the socket file name can
be moved to the create_ipc_socket() function.

There's no need to check access() for the socket path before trying to create it - just call mkdir() regardless,
since it will fail if the path already exists, which is fine.

This commit also adds error handling to the create_ipc_socket() function for the case where creation of the
socket file fails, and switches the chmod() and chown() for the opened file to the more appropriate fchmod()
and fchown().
This commit is contained in:
Kevin Easton
2017-05-03 00:13:24 +10:00
parent aa04e465f3
commit 492d5658d1
6 changed files with 90 additions and 145 deletions

View File

@@ -2379,7 +2379,6 @@ extern HMQ hmq;
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI) && defined(WANT_DETACH)
#ifndef PUBLIC_ACCESS
extern char socket_path[];
extern char *old_pass;
int displays = 0;
@@ -2531,11 +2530,12 @@ void make_cookie(void)
static int create_ipc_socket(void)
{
int s = -1, u = -1;
int s, u;
unsigned short port = 0;
char buf[BIG_BUFFER_SIZE+1];
init_socketpath();
char buf[BIG_BUFFER_SIZE];
char host[BIG_BUFFER_SIZE];
char *p;
const char *socket_path = init_socketpath();
if ((s = connect_by_number("127.0.0.1", &port, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0)
{
@@ -2543,19 +2543,33 @@ static int create_ipc_socket(void)
return 1;
}
sprintf(buf, socket_path, port);
if ((u = open(buf, O_CREAT|O_WRONLY, 0600)) != -1)
gethostname(host, sizeof host);
if ((p = strchr(host, '.')))
*p = 0;
snprintf(buf, sizeof buf, "%s/%u.%s.%s", socket_path, (unsigned)port, stripdev(attach_ttyname), host);
if (strlen(socket_path) + 1 < sizeof buf)
for (p = buf + strlen(socket_path) + 1; *p; p++)
if (*p == '/')
*p = '-';
if ((u = open(buf, O_CREAT|O_WRONLY, 0600)) < 0)
{
chmod(buf, SOCKMODE);
chown(buf, getuid(), getgid());
make_cookie();
write(u, connect_cookie, strlen(connect_cookie));
write(u, "\n", 1);
close(u);
bitchsay("Error creating IPC file: %s", strerror(errno));
new_close(s);
return 1;
}
fchmod(u, SOCKMODE);
fchown(u, getuid(), getgid());
make_cookie();
write(u, connect_cookie, strlen(connect_cookie));
write(u, "\n", 1);
close(u);
set_non_blocking(s);
add_socketread(s, port, 0, socket_path, handle_reconnect, NULL);
add_socketread(s, port, 0, NULL, handle_reconnect, NULL);
save_ipc = s;
return 0;