- Added the --css command line option to make incremental changes to the style sheet without having to load a full replacement with the --static-file option. Added an example that enables white text on a black background.

- Added Debian specific documentation to the manual page.


git-svn-id: https://shellinabox.googlecode.com/svn/trunk@158 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-07-30 17:40:54 +00:00
parent 37c51363d6
commit e35cf266da
15 changed files with 148 additions and 20 deletions

View file

@ -1,3 +1,12 @@
2009-07-30 Markus Gutschke <markus@shellinabox.com>
* Added the --css command line option to make incremental changes
to the style sheet without having to load a full replacement with
the --static-file option. Added an example that enables white text
on a black background.
* Added Debian specific documentation to the manual page.
2009-07-29 Markus Gutschke <markus@shellinabox.com> 2009-07-29 Markus Gutschke <markus@shellinabox.com>
* Allow unprivileged users to run the daemon. This requires * Allow unprivileged users to run the daemon. This requires

View file

@ -15,7 +15,8 @@ dist_doc_DATA = AUTHORS \
INSTALL \ INSTALL \
NEWS \ NEWS \
README \ README \
TODO TODO \
shellinabox/white-on-black.css
EXTRA_DIST = demo/beep.wav \ EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \ demo/favicon.ico \
demo/demo.html \ demo/demo.html \
@ -153,6 +154,11 @@ shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
else \ else \
sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \ sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \
fi | \ fi | \
if [ -n "${DPKGBUILD}" ]; then \
sed -e '/^#ifndef *DPKGBUILD$$/,/^#endif$$/d'; \
else \
sed -e '/^#ifdef *DPKGBUILD$$/,/^#endif$$/d'; \
fi | \
sed -e '/^#/d' >"$@" sed -e '/^#/d' >"$@"
@out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \ @out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \
man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}" man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}"

View file

@ -253,7 +253,8 @@ dist_doc_DATA = AUTHORS \
INSTALL \ INSTALL \
NEWS \ NEWS \
README \ README \
TODO TODO \
shellinabox/white-on-black.css
EXTRA_DIST = demo/beep.wav \ EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \ demo/favicon.ico \
@ -1067,6 +1068,11 @@ shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
else \ else \
sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \ sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \
fi | \ fi | \
if [ -n "${DPKGBUILD}" ]; then \
sed -e '/^#ifndef *DPKGBUILD$$/,/^#endif$$/d'; \
else \
sed -e '/^#ifdef *DPKGBUILD$$/,/^#endif$$/d'; \
fi | \
sed -e '/^#/d' >"$@" sed -e '/^#/d' >"$@"
@out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \ @out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \
man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}" man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}"

View file

@ -135,7 +135,7 @@
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Most recent revision number in the version control system */ /* Most recent revision number in the version control system */
#define VCS_REVISION "157" #define VCS_REVISION "158"
/* Version number of package */ /* Version number of package */
#define VERSION "2.9" #define VERSION "2.9"

2
configure vendored
View file

@ -2037,7 +2037,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_compiler_gnu=$ac_cv_c_compiler_gnu
VCS_REVISION=157 VCS_REVISION=158
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF

View file

@ -2,7 +2,7 @@ AC_PREREQ(2.57)
dnl This is the one location where the authoritative version number is stored dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.9, markus@shellinabox.com) AC_INIT(shellinabox, 2.9, markus@shellinabox.com)
VCS_REVISION=157 VCS_REVISION=158
AC_SUBST(VCS_REVISION) AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}", AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system]) [Most recent revision number in the version control system])

1
debian/docs vendored
View file

@ -5,3 +5,4 @@ INSTALL
NEWS NEWS
README README
TODO TODO
shellinabox/white-on-black.css

2
debian/rules vendored
View file

@ -46,7 +46,7 @@ build: build-stamp
build-stamp: config.status build-stamp: config.status
dh_testdir dh_testdir
@# Add here commands to compile the package. @# Add here commands to compile the package.
$(MAKE) $(MAKE) DPKGBUILD=true
touch build-stamp touch build-stamp

View file

@ -1693,7 +1693,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 157)" + alert("VT100 Terminal Emulator " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };

View file

@ -772,6 +772,11 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp,
check(!uname(&uts)); check(!uname(&uts));
hostname = uts.nodename; hostname = uts.nodename;
} }
check(hostname = strdup(hostname));
char *dot = strchr(hostname, '.');
if (dot) {
*dot = '\000';
}
const struct passwd *pw; const struct passwd *pw;
pam_handle_t *pam = NULL; pam_handle_t *pam = NULL;
@ -786,12 +791,7 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp,
_exit(1); _exit(1);
} }
free(prompt); free(prompt);
char *localhost = strstr(service->cmdline, "@localhost"); char *cmdline = stringPrintf(NULL, service->cmdline, user);
if (localhost) {
memcpy(localhost+1, "%s", 3);
}
char *cmdline = stringPrintf(NULL, service->cmdline, user,
hostname);
free(user); free(user);
free((void *)service->cmdline); free((void *)service->cmdline);
service->cmdline = cmdline; service->cmdline = cmdline;
@ -892,6 +892,7 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp,
pw = getPWEnt(service->uid); pw = getPWEnt(service->uid);
#endif #endif
} }
free((void *)hostname);
if (restricted && if (restricted &&
(service->uid != restricted || service->gid != pw->pw_gid)) { (service->uid != restricted || service->gid != pw->pw_gid)) {

View file

@ -355,7 +355,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
}; };
ShellInABox.prototype.about = function() { ShellInABox.prototype.about = function() {
alert("Shell In A Box version " + "2.9 (revision 157)" + alert("Shell In A Box version " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com" + "For more information check http://shellinabox.com" +
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ? (typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?

View file

@ -91,6 +91,7 @@ static HashMap *externalFiles;
static Server *cgiServer; static Server *cgiServer;
static char *cgiSessionKey; static char *cgiSessionKey;
static int cgiSessions; static int cgiSessions;
static char *cssStyleSheet;
static char *jsonEscape(const char *buf, int len) { static char *jsonEscape(const char *buf, int len) {
static const char *hexDigit = "0123456789ABCDEF"; static const char *hexDigit = "0123456789ABCDEF";
@ -548,9 +549,8 @@ static int shellInABoxHttpHandler(HttpConnection *http, void *arg,
httpTransfer(http, response, headerLength + contentLength); httpTransfer(http, response, headerLength + contentLength);
} else if (pathInfoLength == 10 && !memcmp(pathInfo, "styles.css", 10)) { } else if (pathInfoLength == 10 && !memcmp(pathInfo, "styles.css", 10)) {
// Serve the style sheet. // Serve the style sheet.
extern char stylesStart[]; serveStaticFile(http, "text/css; charset=utf-8",
extern char stylesEnd[]; cssStyleSheet, strrchr(cssStyleSheet, '\000'));
serveStaticFile(http, "text/css; charset=utf-8", stylesStart, stylesEnd);
} else { } else {
httpSendReply(http, 404, "File not found", NO_MSG); httpSendReply(http, 404, "File not found", NO_MSG);
} }
@ -589,6 +589,7 @@ static void usage(void) {
"List of command line options:\n" "List of command line options:\n"
" -b, --background[=PIDFILE] run in background\n" " -b, --background[=PIDFILE] run in background\n"
"%s" "%s"
" --css=FILE attach contents to CSS style sheet\n"
" --cgi[=PORTMIN-PORTMAX] run as CGI\n" " --cgi[=PORTMIN-PORTMAX] run as CGI\n"
" -d, --debug enable debug mode\n" " -d, --debug enable debug mode\n"
" -f, --static-file=URL:FILE serve static file from URL path\n" " -f, --static-file=URL:FILE serve static file from URL path\n"
@ -655,6 +656,12 @@ static void parseArgs(int argc, char * const argv[]) {
int verbosity = MSG_DEFAULT; int verbosity = MSG_DEFAULT;
externalFiles = newHashMap(destroyExternalFileHashEntry, NULL); externalFiles = newHashMap(destroyExternalFileHashEntry, NULL);
HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL); HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL);
extern char stylesStart[];
extern char stylesEnd[];
check(cssStyleSheet = malloc(stylesEnd - stylesStart));
memcpy(cssStyleSheet, stylesStart, stylesEnd - stylesStart);
cssStyleSheet[stylesEnd - stylesStart] = '\000';
for (;;) { for (;;) {
static const char optstring[] = "+hb::c:df:g:np:s:tqu:v"; static const char optstring[] = "+hb::c:df:g:np:s:tqu:v";
static struct option options[] = { static struct option options[] = {
@ -662,6 +669,7 @@ static void parseArgs(int argc, char * const argv[]) {
{ "background", 2, 0, 'b' }, { "background", 2, 0, 'b' },
{ "cert", 1, 0, 'c' }, { "cert", 1, 0, 'c' },
{ "cert-fd", 1, 0, 0 }, { "cert-fd", 1, 0, 0 },
{ "css", 1, 0, 0 },
{ "cgi", 2, 0, 0 }, { "cgi", 2, 0, 0 },
{ "debug", 0, 0, 'd' }, { "debug", 0, 0, 'd' },
{ "static-file", 1, 0, 'f' }, { "static-file", 1, 0, 'f' },
@ -707,7 +715,7 @@ static void parseArgs(int argc, char * const argv[]) {
if (optarg && pidfile) { if (optarg && pidfile) {
fatal("Only one pidfile can be given"); fatal("Only one pidfile can be given");
} }
if (optarg) { if (optarg && *optarg) {
pidfile = strdup(optarg); pidfile = strdup(optarg);
} }
} else if (!idx--) { } else if (!idx--) {
@ -721,6 +729,10 @@ static void parseArgs(int argc, char * const argv[]) {
if (certificateDir) { if (certificateDir) {
fatal("Only one certificate directory can be selected"); fatal("Only one certificate directory can be selected");
} }
struct stat st;
if (!optarg || !*optarg || stat(optarg, &st) || !S_ISDIR(st.st_mode)) {
fatal("\"--cert\" expects a directory name");
}
check(certificateDir = strdup(optarg)); check(certificateDir = strdup(optarg));
} else if (!idx--) { } else if (!idx--) {
// Certificate file descriptor // Certificate file descriptor
@ -733,12 +745,35 @@ static void parseArgs(int argc, char * const argv[]) {
if (certificateFd >= 0) { if (certificateFd >= 0) {
fatal("Only one certificate file handle can be provided"); fatal("Only one certificate file handle can be provided");
} }
if (!optarg || *optarg < '0' || *optarg > '9') {
fatal("\"--cert-fd\" expects a valid file handle");
}
int tmpFd = strtoint(optarg, 3, INT_MAX); int tmpFd = strtoint(optarg, 3, INT_MAX);
certificateFd = dup(tmpFd); certificateFd = dup(tmpFd);
if (certificateFd < 0) { if (certificateFd < 0) {
fatal("Invalid certificate file handle"); fatal("Invalid certificate file handle");
} }
check(!NOINTR(close(tmpFd))); check(!NOINTR(close(tmpFd)));
} else if (!idx--) {
// CSS
struct stat st;
if (!optarg || !*optarg || stat(optarg, &st) || !S_ISREG(st.st_mode)) {
fatal("\"--css\" expects a file name");
}
FILE *css = fopen(optarg, "r");
if (!css) {
fatal("Cannot read style sheet \"%s\"", optarg);
} else {
check(cssStyleSheet= realloc(cssStyleSheet, strlen(cssStyleSheet) +
st.st_size + 2));
char *newData = strrchr(cssStyleSheet, '\000');
*newData++ = '\n';
if (fread(newData, 1, st.st_size, css) != st.st_size) {
fatal("Failed to read style sheet \"%s\"", optarg);
}
newData[st.st_size]= '\000';
fclose(css);
}
} else if (!idx--) { } else if (!idx--) {
// CGI // CGI
if (demonize) { if (demonize) {
@ -748,7 +783,7 @@ static void parseArgs(int argc, char * const argv[]) {
fatal("Cannot specify a port for CGI operation"); fatal("Cannot specify a port for CGI operation");
} }
cgi = 1; cgi = 1;
if (optarg) { if (optarg && *optarg) {
char *ptr = strchr(optarg, '-'); char *ptr = strchr(optarg, '-');
if (!ptr) { if (!ptr) {
fatal("Syntax error in port range specification"); fatal("Syntax error in port range specification");
@ -784,6 +819,9 @@ static void parseArgs(int argc, char * const argv[]) {
if (runAsGroup >= 0) { if (runAsGroup >= 0) {
fatal("Duplicate --group option."); fatal("Duplicate --group option.");
} }
if (!optarg || !*optarg) {
fatal("\"--group\" expects a group name.");
}
runAsGroup = parseGroup(optarg, NULL); runAsGroup = parseGroup(optarg, NULL);
} else if (!idx--) { } else if (!idx--) {
// Linkify // Linkify
@ -814,6 +852,9 @@ static void parseArgs(int argc, char * const argv[]) {
if (cgi) { if (cgi) {
fatal("Cannot specifiy a port for CGI operation"); fatal("Cannot specifiy a port for CGI operation");
} }
if (!optarg || *optarg < '0' || *optarg > '9') {
fatal("\"--port\" expects a port number.");
}
port = strtoint(optarg, 1, 65535); port = strtoint(optarg, 1, 65535);
} else if (!idx--) { } else if (!idx--) {
// Service // Service
@ -848,6 +889,9 @@ static void parseArgs(int argc, char * const argv[]) {
if (runAsUser >= 0) { if (runAsUser >= 0) {
fatal("Duplicate --user option."); fatal("Duplicate --user option.");
} }
if (!optarg || !*optarg) {
fatal("\"--user\" expects a user name.");
}
runAsUser = parseUser(optarg, NULL); runAsUser = parseUser(optarg, NULL);
} else if (!idx--) { } else if (!idx--) {
// Verbose // Verbose

View file

@ -55,6 +55,7 @@ shellinaboxd \- publish command line shell through AJAX interface
[\ \fB-c\fP\ | \fB--cert=\fP\fIcertdir\fP\ ] [\ \fB-c\fP\ | \fB--cert=\fP\fIcertdir\fP\ ]
#endif #endif
[\ \fB--cert-fd=\fP\fIfd\fP\ ] [\ \fB--cert-fd=\fP\fIfd\fP\ ]
[\ \fB--css=\fP\fIfilename\fP\ ]
[\ \fB--cgi\fP[\fB=\fP\fIportrange\fP]\ ] [\ \fB--cgi\fP[\fB=\fP\fIportrange\fP]\ ]
[\ \fB-d\fP\ | \fB--debug\fP\ ] [\ \fB-d\fP\ | \fB--debug\fP\ ]
[\ \fB-f\fP\ | \fB--static-file=\fP\fIurl\fP:\fIfile\fP\ ] [\ \fB-f\fP\ | \fB--static-file=\fP\fIurl\fP:\fIfile\fP\ ]
@ -158,6 +159,19 @@ support, it does offer an alternative solution for securely providing
the private key data to the daemon. the private key data to the daemon.
#endif #endif
.TP .TP
\fB--css=\fP\fIfilename\fP
Sometimes, it is not necessary to replace the entire style sheet using the
.B --static-file
option. But instead a small incremental change should be made to the visual
appearance of the terminal. The
.B --css
option provides a means to append additional style rules to the end of
the default
.B styles.css
sheet. More than one
.B --css
option can be given on the same command line.
.TP
\fB--cgi\fP[\fB=\fP\fIportrange\fP] \fB--cgi\fP[\fB=\fP\fIportrange\fP]
Instead of running Instead of running
.B shellinaboxd .B shellinaboxd
@ -540,6 +554,22 @@ terminal, publish a
.B Wyse 60\*(Tm .B Wyse 60\*(Tm
terminal. Again, this command should be run as terminal. Again, this command should be run as
.BR root . .BR root .
.TP
#ifndef DPKGBUILD
.B shellinaboxd --css white-on-black.css
#endif
#ifdef DPKGBUILD
.B shellinaboxd --css /usr/share/doc/shellinabox/white-on-black.css
#endif
Loads the
.B white-on-black.css
style sheet
#ifndef DPKGBUILD
from the current directory
#endif
and appends it to the built-in
.B styles.css
sheet. This causes the terminal to render white text on a black background.
.P .P
.SH DIAGNOSTICS .SH DIAGNOSTICS
The daemon returns a non-zero exit code in case of failure. With the The daemon returns a non-zero exit code in case of failure. With the
@ -553,6 +583,31 @@ Common failure conditions are reusing a port that is already in use,
lack of sufficient privileges to run a service, failure to find lack of sufficient privileges to run a service, failure to find
SSL/TLS certificates, and failure to write newly generated SSL/TLS certificates, and failure to write newly generated
certificates to the certification directory. certificates to the certification directory.
#ifdef DPKGBUILD
.SH FILES
.TP 10
.I /etc/default/shellinabox
The system-wide installation of
.B shellinaboxd
can be configured by editing this file. After making any changes, restart
the daemon with \fBsudo service shellinabox restart\fP.
.TP
.I /etc/init.d/shellinabox
This is the system-wide service definition. Usually, there is no need to
edit this file.
.TP
.I /var/lib/shellinabox
This directory contains the certificate files that
.B shellinaboxd
uses when serving encrypted SSL sessions. If suitable files do not exist, yet,
it tries to populate the directory with self-signed certificates the first
time a particular certificate is needed. Over time, it should contain
\fBcertificate.pem\fP, \fBcertificate-localhost.pem\fP, and
\fBcertificate-\fP\fIHOSTNAME\fP\fB.pem\fP.
.TP
.I /var/run/shellinaboxd.pid
This file is created any time the system-wide service gets started.
#endif
.SH "SEE ALSO" .SH "SEE ALSO"
.BR chmod (1), .BR chmod (1),
.BR last (1), .BR last (1),

View file

@ -1693,7 +1693,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 157)" + alert("VT100 Terminal Emulator " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };

View file

@ -0,0 +1,6 @@
#vt100 #scrollable {
color: white;
background-color: black;
}
#vt100 #ansi0 { background-color: #ffffff; }
#vt100 #ansi15 { background-color: #000000; }