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] [Changes 1.2.2]
* Simplify handling of /DETACH socket path. (caf)
* Remove netfinger client code (no-one is running fingerd anymore) and * Remove netfinger client code (no-one is running fingerd anymore) and
repurpose /FINGER command to send a CTCP FINGER instead. (caf) repurpose /FINGER command to send a CTCP FINGER instead. (caf)

View File

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

View File

@@ -2379,7 +2379,6 @@ extern HMQ hmq;
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI) && defined(WANT_DETACH) #if !defined(__EMX__) && !defined(WINNT) && !defined(GUI) && defined(WANT_DETACH)
#ifndef PUBLIC_ACCESS #ifndef PUBLIC_ACCESS
extern char socket_path[];
extern char *old_pass; extern char *old_pass;
int displays = 0; int displays = 0;
@@ -2531,11 +2530,12 @@ void make_cookie(void)
static int create_ipc_socket(void) static int create_ipc_socket(void)
{ {
int s = -1, u = -1; int s, u;
unsigned short port = 0; unsigned short port = 0;
char buf[BIG_BUFFER_SIZE+1]; char buf[BIG_BUFFER_SIZE];
char host[BIG_BUFFER_SIZE];
init_socketpath(); char *p;
const char *socket_path = init_socketpath();
if ((s = connect_by_number("127.0.0.1", &port, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0) 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; return 1;
} }
sprintf(buf, socket_path, port); gethostname(host, sizeof host);
if ((u = open(buf, O_CREAT|O_WRONLY, 0600)) != -1) 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); bitchsay("Error creating IPC file: %s", strerror(errno));
chown(buf, getuid(), getgid()); new_close(s);
return 1;
}
fchmod(u, SOCKMODE);
fchown(u, getuid(), getgid());
make_cookie(); make_cookie();
write(u, connect_cookie, strlen(connect_cookie)); write(u, connect_cookie, strlen(connect_cookie));
write(u, "\n", 1); write(u, "\n", 1);
close(u); close(u);
}
set_non_blocking(s); 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; save_ipc = s;
return 0; 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 */ realname[REALNAME_LEN + 1], /* real name of user */
username[NAME_LEN + 1], /* usernameof user */ username[NAME_LEN + 1], /* usernameof user */
attach_ttyname[500], /* ttyname for this term */ attach_ttyname[500], /* ttyname for this term */
socket_path[500], /* ttyname for this term */
*forwardnick = NULL, /* used for /forward */ *forwardnick = NULL, /* used for /forward */
*send_umode = NULL, /* sent umode */ *send_umode = NULL, /* sent umode */
*args_str = NULL, /* list of command line args */ *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); channel = parse_args(argv, argc, envp);
check_pid(); check_pid();
init_socketpath();
#ifdef WANT_TCL #ifdef WANT_TCL
tcl_interp = Tcl_CreateInterp(); tcl_interp = Tcl_CreateInterp();

View File

@@ -2871,38 +2871,16 @@ char *BX_stripdev(char *ttynam)
return ttynam; return ttynam;
} }
const char *init_socketpath(void)
void init_socketpath(void)
{ {
#if !defined(__EMX__) && !defined(WINNT) static char socket_path[BIG_BUFFER_SIZE];
struct stat st;
extern char socket_path[], attach_ttyname[]; 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) if (mkdir(socket_path, 0700) != -1)
(void) chown(socket_path, getuid(), getgid()); (void)chown(socket_path, getuid(), getgid());
else
return; return socket_path;
}
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
} }
/* /*

View File

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