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

@@ -1,5 +1,7 @@
[Changes 1.2.2]
* Simplify handling of /DETACH socket path. (caf)
* Remove netfinger client code (no-one is running fingerd anymore) and
repurpose /FINGER command to send a CTCP FINGER instead. (caf)

View File

@@ -344,7 +344,7 @@ extern short ospeed;
#endif
void reattach_tty(char *, char *);
void init_socketpath(void);
const char *init_socketpath(void);
void kill_attached_if_needed(int);
void setup_pid();

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());
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;

View File

@@ -165,7 +165,6 @@ char *invite_channel = NULL, /* last channel of an INVITE */
realname[REALNAME_LEN + 1], /* real name of user */
username[NAME_LEN + 1], /* usernameof user */
attach_ttyname[500], /* ttyname for this term */
socket_path[500], /* ttyname for this term */
*forwardnick = NULL, /* used for /forward */
*send_umode = NULL, /* sent umode */
*args_str = NULL, /* list of command line args */
@@ -1502,7 +1501,6 @@ int main(int argc, char *argv[], char *envp[])
channel = parse_args(argv, argc, envp);
check_pid();
init_socketpath();
#ifdef WANT_TCL
tcl_interp = Tcl_CreateInterp();

View File

@@ -2871,38 +2871,16 @@ char *BX_stripdev(char *ttynam)
return ttynam;
}
void init_socketpath(void)
const char *init_socketpath(void)
{
#if !defined(__EMX__) && !defined(WINNT)
struct stat st;
extern char socket_path[], attach_ttyname[];
static char socket_path[BIG_BUFFER_SIZE];
snprintf(socket_path, sizeof socket_path, "%s/.BitchX/screens", my_path);
sprintf(socket_path, "%s/.BitchX/screens", my_path);
if (access(socket_path, F_OK))
{
if (mkdir(socket_path, 0700) != -1)
(void) chown(socket_path, getuid(), getgid());
else
return;
}
if (stat(socket_path, &st) != -1)
{
char host[BIG_BUFFER_SIZE+1];
char *ap;
if (!S_ISDIR(st.st_mode))
return;
gethostname(host, BIG_BUFFER_SIZE);
if ((ap = strchr(host, '.')))
*ap = 0;
ap = &socket_path[strlen(socket_path)];
sprintf(ap, "/%%d.%s.%s", stripdev(attach_ttyname), host);
ap++;
for ( ; *ap; ap++)
if (*ap == '/')
*ap = '-';
}
#endif
(void)chown(socket_path, getuid(), getgid());
return socket_path;
}
/*

View File

@@ -44,9 +44,7 @@ unsigned char transToClient[256]; /* Server to client translation. */
int dumb_mode = 0;
int already_detached = 1;
int do_check_pid = 0;
char socket_path[500];
char attach_ttyname[500];
char *my_path;
struct param
{
@@ -177,22 +175,18 @@ char *q;
return ttypath;
}
void display_socket_list(char *path, int unl, char *arg)
void display_socket_list(const char *path, int unl, char *arg)
{
DIR *dptr;
struct dirent *dir;
struct stat st;
char buffer[2000];
char *new_path, *p;
int count = 0;
int doit = 0;
DIR *dptr;
struct dirent *dir;
struct stat st;
char buffer[2000];
int count = 0;
int doit = 0;
new_path = LOCAL_COPY(path);
if ((p = strrchr(new_path, '/')))
*p = 0;
if (!(dptr = opendir(new_path)))
if (!(dptr = opendir(path)))
{
fprintf(stderr, "No such directory %s\r\n ", new_path);
fprintf(stderr, "No such directory %s\n", path);
exit(1);
}
while ((dir = readdir(dptr)))
@@ -202,7 +196,7 @@ int doit = 0;
continue;
if (dir->d_name[0] == '.')
continue;
sprintf(buffer, "%s/%s", new_path, dir->d_name);
sprintf(buffer, "%s/%s", path, dir->d_name);
if ((stat(buffer, &st) == -1))
continue;
if (arg && strstr(dir->d_name, arg))
@@ -229,20 +223,15 @@ int doit = 0;
exit(1);
}
char *find_detach_socket(char *path, char *name)
char *find_detach_socket(const char *path, char *name)
{
char *new_path;
DIR *dptr;
struct dirent *dir;
struct stat st;
char *ret = NULL, *p;
int count = 0;
new_path = LOCAL_COPY(path);
if ((p = strrchr(new_path, '/')))
*p = 0;
else
return NULL;
if (!(dptr = opendir(new_path)))
DIR *dptr;
struct dirent *dir;
struct stat st;
char *ret = NULL, *p;
int count = 0;
if (!(dptr = opendir(path)))
return NULL;
ret = malloc(2000);
*ret = 0;
@@ -253,7 +242,7 @@ int count = 0;
continue;
if (dir->d_name[0] == '.')
continue;
sprintf(ret, "%s/%s", new_path, dir->d_name);
sprintf(ret, "%s/%s", path, dir->d_name);
p = strrchr(ret, '/'); p++;
if ((stat(ret, &st) == -1) || (st.st_uid != getuid()) || S_ISDIR(st.st_mode))
{
@@ -320,7 +309,7 @@ SIGNAL_HANDLER(handle_pipe)
term_cr();
term_clear_to_eol();
term_reset2();
fprintf(stdout, "\rdetached from %s. To re-attach type scr-bx %s\n\r", attach_ttyname, old_pass? "password":"");
fprintf(stdout, "\rdetached from %s. To re-attach type scr-bx %s\n\r", ttyname(0), old_pass? "password":"");
fflush(stdout);
exit(0);
}
@@ -377,25 +366,27 @@ char *get_cookie(char *name)
void reattach_tty(char *tty, char *password)
{
int s = -1;
char *name;
struct sockaddr_in addr;
struct hostent *hp;
int len = 0;
fd_set rd_fd;
struct timeval tm = {0};
char chr_c[] = "\003";
int s = -1;
char *name;
struct sockaddr_in addr;
struct hostent *hp;
int len = 0;
fd_set rd_fd;
struct timeval tm = {0};
char chr_c[] = "\003";
/*
/*
* this buffer has to be big enough to handle a full screen of
* information from the detached process.
*/
unsigned char buffer[6 * BIG_BUFFER_SIZE+1];
char *p;
int port = 0;
unsigned char buffer[6 * BIG_BUFFER_SIZE+1];
char *p;
int port = 0;
#if defined (TIOCGWINSZ)
struct winsize window;
struct winsize window;
#endif
const char *socket_path = init_socketpath();
memset(&parm, 0, sizeof(struct param));
if (!(name = find_detach_socket(socket_path, tty)))
@@ -528,54 +519,18 @@ struct winsize window;
return; /* error return */
}
char *stripdev(char *ttynam)
const char *init_socketpath(void)
{
if (ttynam == NULL)
return NULL;
#ifdef SVR4
/* unixware has /dev/pts012 as synonym for /dev/pts/12 */
if (!strncmp(ttynam, "/dev/pts", 8) && ttynam[8] >= '0' && ttynam[8] <= '9')
{
static char b[13];
sprintf(b, "pts/%d", atoi(ttynam + 8));
return b;
}
#endif /* SVR4 */
if (!strncmp(ttynam, "/dev/", 5))
return ttynam + 5;
return ttynam;
static char socket_path[BIG_BUFFER_SIZE];
snprintf(socket_path, sizeof socket_path, "%s/.BitchX/screens", my_path);
if (mkdir(socket_path, 0700) != -1)
(void)chown(socket_path, getuid(), getgid());
return socket_path;
}
void init_socketpath(void)
{
#if !defined(__EMX__) && !defined(WINNT)
struct stat st;
extern char socket_path[], attach_ttyname[];
sprintf(socket_path, "%s/.BitchX/screens", getenv("HOME"));
if (access(socket_path, F_OK))
return;
if (stat(socket_path, &st) != -1)
{
char host[BIG_BUFFER_SIZE+1];
char *ap;
if (!S_ISDIR(st.st_mode))
return;
gethostname(host, BIG_BUFFER_SIZE);
if ((ap = strchr(host, '.')))
*ap = 0;
ap = &socket_path[strlen(socket_path)];
sprintf(ap, "/%%d.%s.%s", stripdev(attach_ttyname), host);
ap++;
for ( ; *ap; ap++)
if (*ap == '/')
*ap = '-';
}
#endif
}
char *old_tty = NULL;
void parse_args(int argc, char **argv)
{
@@ -618,7 +573,7 @@ int disp_sock = 0;
}
}
if (disp_sock)
display_socket_list(socket_path, disp_sock - 1, old_tty);
display_socket_list(init_socketpath(), disp_sock - 1, old_tty);
}
@@ -627,9 +582,7 @@ int main(int argc, char **argv)
#ifdef MEM_DEBUG
dmalloc_debug(0x1df47dfb);
#endif
*socket_path = 0;
strcpy(attach_ttyname, ttyname(0));
init_socketpath();
my_path = getenv("HOME");
parse_args(argc, argv);
chdir(getenv("HOME"));
reattach_tty(old_tty, old_pass);