From e1863d0a47bfbc91878ca9b2652b406343ca9b09 Mon Sep 17 00:00:00 2001 From: zodiac Date: Wed, 18 Mar 2009 18:15:28 +0000 Subject: [PATCH] More IE6 tweaks. Allow root to listen on privileged ports. git-svn-id: https://shellinabox.googlecode.com/svn/trunk@80 0da03de8-d603-11dd-86c2-0f8696b7b6f9 --- ChangeLog | 4 +++ config.h | 2 +- libhttp/server.c | 62 ++++++++++------------------------- libhttp/server.h | 2 +- shellinabox/shell_in_a_box.js | 54 +++++++++++++++--------------- shellinabox/shellinaboxd.c | 5 +-- 6 files changed, 53 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b5828f..32c14af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-03-17 Markus Gutschke + + * Allow root to bind to privileged port. + 2009-03-17 Markus Gutschke * Fixed IE6 support. diff --git a/config.h b/config.h index 3ea32b0..a386fe4 100644 --- a/config.h +++ b/config.h @@ -95,7 +95,7 @@ #define STDC_HEADERS 1 /* Most recent revision number in the version control system */ -#define VCS_REVISION "78" +#define VCS_REVISION "80" /* Version number of package */ #define VERSION "2.4" diff --git a/libhttp/server.c b/libhttp/server.c index 92de1b3..302fb85 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -171,8 +171,24 @@ static int serverQuitHandler(struct HttpConnection *http, void *arg) { } struct Server *newCGIServer(int portMin, int portMax, int timeout) { - struct Server *server = newServer(0); + struct Server *server; + check(server = malloc(sizeof(struct Server))); + initServer(server, portMin, portMax, timeout); + return server; +} + +struct Server *newServer(int port) { + return newCGIServer(port, port, -1); +} + +void initServer(struct Server *server, int portMin, int portMax, int timeout) { + server->looping = 0; + server->exitAll = 0; server->serverTimeout = timeout; + server->numericHosts = 0; + server->connections = NULL; + server->numConnections = 0; + int true = 1; server->serverFd = socket(PF_INET, SOCK_STREAM, 0); check(server->serverFd >= 0); @@ -219,26 +235,6 @@ struct Server *newCGIServer(int portMin, int portMax, int timeout) { server->pollFds->fd = server->serverFd; server->pollFds->events = POLLIN; - return server; -} - -struct Server *newServer(int port) { - struct Server *server; - check(server = malloc(sizeof(struct Server))); - initServer(server, port); - return server; -} - -void initServer(struct Server *server, int port) { - server->port = port; - server->looping = 0; - server->exitAll = 0; - server->serverTimeout = -1; - server->serverFd = -1; - server->numericHosts = 0; - server->pollFds = NULL; - server->connections = NULL; - server->numConnections = 0; initTrie(&server->handlers, serverDestroyHandlers, NULL); serverRegisterStreamingHttpHandler(server, "/quit", serverQuitHandler, NULL); initSSL(&server->ssl); @@ -370,29 +366,7 @@ void serverExitLoop(struct Server *server, int exitAll) { } void serverLoop(struct Server *server) { - if (server->serverFd < 0) { - int true = 1; - server->serverFd = socket(PF_INET, SOCK_STREAM, 0); - check(server->serverFd >= 0); - check(!setsockopt(server->serverFd, SOL_SOCKET, SO_REUSEADDR, - &true, sizeof(true))); - struct sockaddr_in serverAddr = { 0 }; - serverAddr.sin_family = AF_INET; - serverAddr.sin_addr.s_addr = INADDR_ANY; - serverAddr.sin_port = htons(server->port); - if (bind(server->serverFd, (struct sockaddr *)&serverAddr, - sizeof(serverAddr))) { - fatal("Failed to bind to port %d. Maybe, another server is already " - "running?", server->port); - } - check(!listen(server->serverFd, SOMAXCONN)); - info("Listening on port %d", server->port); - check(!server->pollFds); - check(!server->numConnections); - check(server->pollFds = malloc(sizeof(struct pollfd))); - server->pollFds->fd = server->serverFd; - server->pollFds->events = POLLIN; - } + check(server->serverFd >= 0); time_t lastTime; currentTime = time(&lastTime); int loopDepth = ++server->looping; diff --git a/libhttp/server.h b/libhttp/server.h index 98da282..be1bd67 100644 --- a/libhttp/server.h +++ b/libhttp/server.h @@ -80,7 +80,7 @@ struct Server { struct Server *newCGIServer(int portMin, int portMax, int timeout); struct Server *newServer(int port); -void initServer(struct Server *server, int port); +void initServer(struct Server *server, int portMin, int portMax, int timeout); void destroyServer(struct Server *server); void deleteServer(struct Server *server); int serverGetListeningPort(struct Server *server); diff --git a/shellinabox/shell_in_a_box.js b/shellinabox/shell_in_a_box.js index ab02e4d..29c49e4 100644 --- a/shellinabox/shell_in_a_box.js +++ b/shellinabox/shell_in_a_box.js @@ -120,15 +120,18 @@ function ShellInABox(url, container) { extend(ShellInABox, VT100); ShellInABox.prototype.sessionClosed = function() { - this.connected = false; - if (this.session) { - this.session = undefined; - if (this.cursorX > 0) { - this.vt100('\r\n'); + try { + this.connected = false; + if (this.session) { + this.session = undefined; + if (this.cursorX > 0) { + this.vt100('\r\n'); + } + this.vt100('Session closed.'); } - this.vt100('Session closed.'); + this.showReconnect(true); + } catch (e) { } - this.showReconnect(true); }; ShellInABox.prototype.reconnect = function() { @@ -158,17 +161,15 @@ ShellInABox.prototype.sendRequest = function(request) { if (request == undefined) { request = new XMLHttpRequest(); } - request.open(this.session ? 'POST' : 'GET', this.url, true); + request.open('POST', this.url + '?', true); + request.setRequestHeader('Cache-Control', 'no-cache'); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); - var content = this.session ? - ('width=' + this.terminalWidth + - '&height=' + this.terminalHeight + - '&session=' + - encodeURIComponent(this.session)) : ''; - if (this.session) { - request.setRequestHeader('Content-Length', content.length); - } + var content = 'width=' + this.terminalWidth + + '&height=' + this.terminalHeight + + (this.session ? '&session=' + + encodeURIComponent(this.session) : ''); + request.setRequestHeader('Content-Length', content.length); request.onreadystatechange = function(shellInABox) { return function() { @@ -179,11 +180,7 @@ ShellInABox.prototype.sendRequest = function(request) { } } }(this); - if (this.session) { - request.send(content); - } else { - request.send(''); - } + request.send(content); }; ShellInABox.prototype.onReadyStateChange = function(request) { @@ -191,7 +188,6 @@ ShellInABox.prototype.onReadyStateChange = function(request) { if (request.status == 200) { this.connected = true; var response = eval('(' + request.responseText + ')'); - if (response.data) { this.vt100(response.data); } @@ -223,9 +219,15 @@ ShellInABox.prototype.sendKeys = function(keys) { keys = this.pendingKeys + keys; this.pendingKeys = ''; var request = new XMLHttpRequest(); - request.open('POST', this.url, true); + request.open('POST', this.url + '?', true); + request.setRequestHeader('Cache-Control', 'no-cache'); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); + var content = 'width=' + this.terminalWidth + + '&height=' + this.terminalHeight + + '&session=' +encodeURIComponent(this.session)+ + '&keys=' + encodeURIComponent(keys); + request.setRequestHeader('Content-Length', content.length); request.onreadystatechange = function(shellInABox) { return function() { try { @@ -234,11 +236,7 @@ ShellInABox.prototype.sendKeys = function(keys) { } } }(this); - request.send( - 'width=' + this.terminalWidth + - '&height=' + this.terminalHeight + - "&session=" + encodeURIComponent(this.session) + - "&keys=" + encodeURIComponent(keys)); + request.send(content); } }; diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index b76efb2..f35234f 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -466,7 +466,7 @@ static int shellInABoxHttpHandler(HttpConnection *http, void *arg, endPathInfo++) { } int pathInfoLength = endPathInfo - pathInfo; - + // The root page either serves the AJAX application or redirects to the // secure HTTPS URL. if (!pathInfoLength || @@ -943,7 +943,6 @@ int main(int argc, char * const argv[]) { // Fork the launcher process, allowing us to drop privileges in the main // process. int launcherFd = forkLauncher(); - dropPrivileges(); // Make sure that our timestamps will print in the standard format setlocale(LC_TIME, "POSIX"); @@ -952,12 +951,14 @@ int main(int argc, char * const argv[]) { Server *server; if (port) { check(server = newServer(port)); + dropPrivileges(); setUpSSL(server); } else { // For CGI operation we fork the new server, so that it runs in the // background. pid_t pid; int fds[2]; + dropPrivileges(); check(!pipe(fds)); check((pid = fork()) >= 0); if (pid) {