diff --git a/libhttp/server.c b/libhttp/server.c index 5aca767..04d3152 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -141,11 +141,10 @@ int x_poll(struct pollfd *fds, nfds_t nfds, int timeout) { #endif time_t currentTime; - -int unixDomainUser; -int unixDomainGroup; -int unixDomainChmod; -char unixDomainSocket[UNIX_PATH_MAX]; +char *unixDomainPath = NULL; +int unixDomainUser = 0; +int unixDomainGroup = 0; +int unixDomainChmod = 0; struct PayLoad { int (*handler)(struct HttpConnection *, void *, const char *, int); @@ -291,7 +290,7 @@ void initServer(struct Server *server, int localhostOnly, int portMin, int true = 1; - if (*unixDomainSocket) { + if (unixDomainPath && *unixDomainPath) { server->serverFd = socket(AF_UNIX, SOCK_STREAM, 0); check(server->serverFd >= 0); @@ -299,28 +298,30 @@ void initServer(struct Server *server, int localhostOnly, int portMin, &true, sizeof(true))); struct stat st; - if (!stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) { - unlink(unixDomainSocket); + if (!stat(unixDomainPath, &st) && S_ISSOCK(st.st_mode)) { + unlink(unixDomainPath); } struct sockaddr_un serverAddr = { 0 }; serverAddr.sun_family = AF_UNIX; - strcpy(serverAddr.sun_path, unixDomainSocket); + strcpy(serverAddr.sun_path, unixDomainPath); int servlen = sizeof(serverAddr.sun_family) - + strlen(unixDomainSocket); + + strlen(unixDomainPath); if (bind(server->serverFd, (struct sockaddr *)&serverAddr, servlen)) { fatal("Failed to bind to unix socket! [%d: %s]", errno, strerror(errno)); } - if (chown(unixDomainSocket, unixDomainUser, unixDomainGroup)) { - fatal("Unable to change ownership on unix socket!"); + if (chown(unixDomainPath, unixDomainUser, unixDomainGroup)) { + fatal("Unable to change ownership on unix socket! [%d: %s]", + errno, strerror(errno)); } - if (chmod(unixDomainSocket, unixDomainChmod)) { - fatal("Unable to change premission on unix socket!"); + if (chmod(unixDomainPath, unixDomainChmod)) { + fatal("Unable to change premission on unix socket! [%d: %s)", + errno, strerror(errno)); } check(!listen(server->serverFd, SOMAXCONN)); - info("Listening on unix domain socket %s", unixDomainSocket); + info("Listening on unix domain socket %s", unixDomainPath); check(server->pollFds = malloc(sizeof(struct pollfd))); server->pollFds->fd = server->serverFd; server->pollFds->events = POLLIN; @@ -396,9 +397,12 @@ void destroyServer(struct Server *server) { destroyTrie(&server->handlers); destroySSL(&server->ssl); - struct stat st; - if (*unixDomainSocket && !stat(unixDomainSocket, &st) && S_ISSOCK(st.st_mode)) { - unlink(unixDomainSocket); + if (unixDomainPath) { + struct stat st; + if (*unixDomainPath && !stat(unixDomainPath, &st) && S_ISSOCK(st.st_mode)) { + unlink(unixDomainPath); + } + free(unixDomainPath); } } } diff --git a/libhttp/server.h b/libhttp/server.h index ae7cc1b..2653771 100644 --- a/libhttp/server.h +++ b/libhttp/server.h @@ -56,10 +56,6 @@ #define UNIX_PATH_MAX 108 #endif -extern int unixDomainUser; -extern int unixDomainGroup; -extern int unixDomainChmod; -extern char unixDomainSocket[UNIX_PATH_MAX]; struct Server; @@ -130,5 +126,9 @@ void serverSetNumericHosts(struct Server *server, int numericHosts); struct Trie *serverGetHttpHandlers(struct Server *server); extern time_t currentTime; +extern char *unixDomainPath; +extern int unixDomainUser; +extern int unixDomainGroup; +extern int unixDomainChmod; #endif diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index 3a69ac1..53c58c9 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -1139,35 +1139,40 @@ static void parseArgs(int argc, char * const argv[]) { } char *ptr, *s, *tmp; - s = optarg; - ptr = strchr(s, ':'); - if (ptr == NULL) { - fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); + // Unix domain path + s = optarg; + ptr = strchr(s, ':'); + if (ptr == NULL || ptr == s || ptr - s >= UNIX_PATH_MAX) { + fatal("Syntax error in unixdomain-only path definition \"%s\".", optarg); } - check(ptr - s < UNIX_PATH_MAX); - memcpy(unixDomainSocket, s, ptr - s); - unixDomainSocket[ptr - s] = '\000'; + check(unixDomainPath = strndup(s, ptr - s)); - s = ptr + 1; - ptr = strchr(s, ':'); - if (ptr == NULL) { - fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); + // Unix domain user + s = ptr + 1; + ptr = strchr(s, ':'); + if (ptr == NULL || ptr == s) { + fatal("Syntax error in unixdomain-only user definition \"%s\".", optarg); } - check(tmp = strndup(s, ptr - s)); - unixDomainUser = parseUserArg(tmp, NULL); + check(tmp = strndup(s, ptr - s)); + unixDomainUser = parseUserArg(tmp, NULL); free(tmp); - s = ptr + 1; - ptr = strchr(s, ':'); - if (ptr == NULL) { - fatal("Syntax error in unixdomain-only definition \"%s\".", optarg); + // Unix domain group + s = ptr + 1; + ptr = strchr(s, ':'); + if (ptr == NULL || ptr == s) { + fatal("Syntax error in unixdomain-only group definition \"%s\".", optarg); } - check(tmp = strndup(s, ptr - s)); - unixDomainGroup = parseGroupArg(tmp, NULL); + check(tmp = strndup(s, ptr - s)); + unixDomainGroup = parseGroupArg(tmp, NULL); free(tmp); - s = ptr + 1; - unixDomainChmod = strtol(s, NULL, 0); + // Unix domain chmod + s = ptr + 1; + if (strlen(ptr) == 1) { + fatal("Syntax error in unixdomain-only chmod definition \"%s\".", optarg); + } + unixDomainChmod = strtol(s, NULL, 0); } else if (!idx--) { // User