diff --git a/libhttp/server.c b/libhttp/server.c index 04d3152..eab64a7 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -304,7 +304,7 @@ void initServer(struct Server *server, int localhostOnly, int portMin, struct sockaddr_un serverAddr = { 0 }; serverAddr.sun_family = AF_UNIX; - strcpy(serverAddr.sun_path, unixDomainPath); + memcpy(serverAddr.sun_path, unixDomainPath, sizeof(serverAddr.sun_path)); int servlen = sizeof(serverAddr.sun_family) + strlen(unixDomainPath); diff --git a/misc/embedded.html b/misc/embedded.html index ebdbc8c..b009604 100644 --- a/misc/embedded.html +++ b/misc/embedded.html @@ -40,15 +40,30 @@ Following types of message can be sent to shellinabox: - input - writes content of data field to terminal - output - enables passing of output to parent window (data field must be set - to enable, disable or toggle) - session - request sessions status + * input + writes content of data field to terminal + + * output + enables passing of output to parent window (data field must be set + to enable, disable or toggle) + + * session + request sessions status + + * onsessionchange + enables passing session status to parent window (data field must be + set to enable, disable or toggle) + + * reconnect + reconnects the terminal Following types of messages can be received from shellinabox: - output - data field contains terminal output - session - data field contains session status (active or closed) + * output + data field contains terminal output + + * session + data field contains session status (alive or closed) Example for passing command to Shell In A Box frame: @@ -99,7 +114,9 @@ + +
Session status: ???
@@ -164,6 +181,23 @@ iframe.contentWindow.postMessage(message, url); }); + document.getElementById("session-toggle").addEventListener("click", function() { + // Toggles shellinabox session status reporting + var message = JSON.stringify({ + type : 'onsessionchange', + data : 'toggle' + }); + iframe.contentWindow.postMessage(message, url); + }); + + document.getElementById("reconnect").addEventListener("click", function() { + // Request shellianbox session status + var message = JSON.stringify({ + type : 'reconnect' + }); + iframe.contentWindow.postMessage(message, url); + }); + // Receive response from shellinabox window.addEventListener("message", function(message) { diff --git a/shellinabox/shell_in_a_box.jspp b/shellinabox/shell_in_a_box.jspp index 952decc..8f9c5aa 100644 --- a/shellinabox/shell_in_a_box.jspp +++ b/shellinabox/shell_in_a_box.jspp @@ -109,7 +109,8 @@ function ShellInABox(url, container) { this.pendingKeys = ''; this.keysInFlight = false; this.connected = false; - this.replayOutput = false; + this.replayOnOutput = false; + this.replayOnSession = false; this.superClass.constructor.call(this, container); @@ -135,6 +136,9 @@ ShellInABox.prototype.sessionClosed = function() { this.vt100('Session closed.'); } this.showReconnect(true); + if (this.replayOnSession) { + this.messageReplay('session', 'closed'); + } } catch (e) { } }; @@ -195,7 +199,7 @@ ShellInABox.prototype.onReadyStateChange = function(request) { this.connected = true; var response = eval('(' + request.responseText + ')'); if (response.data) { - if (this.replayOutput) { + if (this.replayOnOutput) { this.messageReplay('output', response.data); } this.vt100(response.data); @@ -205,6 +209,9 @@ ShellInABox.prototype.onReadyStateChange = function(request) { this.session && this.session != response.session) { this.sessionClosed(); } else { + if (this.replayOnSession && !this.session && response.session) { + this.messageReplay('session', 'alive'); + } this.session = response.session; this.sendRequest(request); } @@ -425,18 +432,27 @@ ShellInABox.prototype.messageReceive = function (message) { break; case 'output' : // Enable, disable or toggle passing terminal output to parent window. - if (decoded.data === 'enable') { - this.replayOutput = true; - } else if (decoded.data === 'disable') { - this.replayOutput = false; - } else if (decoded.data === 'toggle') { - this.replayOutput = !this.replayOutput; + switch (decoded.data) { + case 'enable' : this.replayOnOutput = true; break; + case 'disable' : this.replayOnOutput = false; break; + case 'toggle' : this.replayOnOutput = !this.replayOnOutput; break; } break; case 'session': // Replay with session status. this.messageReplay('session', this.session ? 'alive' : 'closed'); break; + case 'onsessionchange': + // Enable, disable or toggle passing session status to parent window. + switch (decoded.data) { + case 'enable' : this.replayOnSession = true; break; + case 'disable' : this.replayOnSession = false; break; + case 'toggle' : this.replayOnSession = !this.replayOnSession; break; + } + break; + case 'reconnect': + this.reconnect(); + break; } }; diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index 53c58c9..7fc591e 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -1172,7 +1172,7 @@ static void parseArgs(int argc, char * const argv[]) { if (strlen(ptr) == 1) { fatal("Syntax error in unixdomain-only chmod definition \"%s\".", optarg); } - unixDomainChmod = strtol(s, NULL, 0); + unixDomainChmod = strtol(s, NULL, 8); } else if (!idx--) { // User