Commit 0ef122b6 authored by runge's avatar runge

Apache SSL gateway. More web proxy cases for Java and ssl_vncviewer.

parent d14cf0a8
#!/bin/sh
#
# ssl_vncviewer: wrapper for vncviewer to use stunnel SSL tunnel.
# ssl_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel.
#
# Copyright (c) 2006 by Karl J. Runge <runge@karlrunge.com>
#
# You must have stunnel(8) installed on the system and in your
# PATH (n.b. stunnel is usually in an sbin subdir).
......@@ -16,6 +18,7 @@
# [cert-args] can be:
# -verify /path/to/cacert.pem
# -mycert /path/to/mycert.pem
# -proxy host:port
#
# -verify specifies a CA cert PEM file (or a self-signed one) for
# authenticating the VNC server.
......@@ -23,12 +26,19 @@
# -mycert specifies this client's cert+key PEM file for the VNC server to
# authenticate this client.
#
# -proxy try host:port as a Web proxy to use the CONNECT method
# to reach the VNC server (e.g. your firewall requires a proxy).
# For the "double proxy" case use -proxy host1:port1,host2:port2
#
#
# set VNCVIEWERCMD to whatever vncviewer command you want to use:
#
VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
VNCVIEWERCMD="vncviewer"
PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH
help() {
head -26 $0 | tail +2
head -36 $0 | tail +2
}
# grab our cmdline options:
......@@ -39,6 +49,8 @@ do
;;
"-mycert") shift; mycert="$1"
;;
"-proxy") shift; proxy="$1"
;;
"-h"*) help; exit 0
;;
*) break
......@@ -59,12 +71,19 @@ host=`echo "$orig" | awk -F: '{print $1}'`
disp=`echo "$orig" | awk -F: '{print $2}'`
if [ $disp -lt 200 ]; then
port=`expr $disp + 5900`
else
port=$disp
fi
# try to find an open listening port via netstat(1):
use=""
inuse=""
if uname | grep Linux > /dev/null; then
inuse=`netstat -ant | grep LISTEN | awk '{print $4}' | sed 's/^.*://'`
elif uname | grep SunOS > /dev/null; then
inuse=`netstat -an -f inet -P tcp | grep LISTEN | awk '{print $1}' | sed 's/^.*\.//'`
fi
if [ "x$inuse" != "x" ]; then
try=5920
while [ $try -lt 6000 ]
do
......@@ -95,6 +114,145 @@ if [ "X$mycert" != "X" ]; then
cert="cert = $mycert"
fi
pcode() {
tf=$1
SSL_VNC_PROXY=$proxy; export SSL_VNC_PROXY
SSL_VNC_DEST="$host:$port"; export SSL_VNC_DEST
cod='#!/usr/bin/perl
# A hack to glue stunnel to a Web proxy for client connections.
use IO::Socket::INET;
my ($first, $second) = split(/,/, $ENV{SSL_VNC_PROXY});
my ($proxy_host, $proxy_port) = split(/:/, $first);
my $connect = $ENV{SSL_VNC_DEST};
print STDERR "\nperl script for web proxing:\n";
print STDERR "proxy_host: $proxy_host\n";
print STDERR "proxy_port: $proxy_port\n";
print STDERR "proxy_connect: $connect\n";
my $sock = IO::Socket::INET->new(
PeerAddr => $proxy_host,
PeerPort => $proxy_port,
Proto => "tcp");
if (! $sock) {
unlink($0);
die "perl proxy: $!\n";
}
my $con = "";
if ($second ne "") {
$con = "CONNECT $second HTTP/1.1\r\n";
$con .= "Host: $second\r\n\r\n";
} else {
$con = "CONNECT $connect HTTP/1.1\r\n";
$con .= "Host: $connect\r\n\r\n";
}
print STDERR "proxy_request1:\n$con";
print $sock $con;
unlink($0);
my $rep = "";
while ($rep !~ /\r\n\r\n/) {
my $c = getc($sock);
print STDERR $c;
$rep .= $c;
}
if ($rep !~ m,HTTP/.* 200,) {
die "proxy error: $rep\n";
}
if ($second ne "") {
$con = "CONNECT $connect HTTP/1.1\r\n";
$con .= "Host: $connect\r\n\r\n";
print STDERR "proxy_request2:\n$con";
print $sock $con;
$rep = "";
while ($rep !~ /\r\n\r\n/) {
my $c = getc($sock);
print STDERR $c;
$rep .= $c;
}
if ($rep !~ m,HTTP/.* 200,) {
die "proxy error: $rep\n";
}
}
if (fork) {
print STDERR "parent\[$$] STDIN -> socket\n\n";
xfer(STDIN, $sock);
} else {
print STDERR "child \[$$] socket -> STDOUT\n\n";
xfer($sock, STDOUT);
}
exit;
sub xfer {
my($in, $out) = @_;
$RIN = $WIN = $EIN = "";
$ROUT = "";
vec($RIN, fileno($in), 1) = 1;
vec($WIN, fileno($in), 1) = 1;
$EIN = $RIN | $WIN;
while (1) {
my $nf = 0;
while (! $nf) {
$nf = select($ROUT=$RIN, undef, undef, undef);
}
my $len = sysread($in, $buf, 8192);
if (! defined($len)) {
next if $! =~ /^Interrupted/;
print STDERR "perl proxy\[$$]: $!\n";
last;
} elsif ($len == 0) {
print STDERR "perl proxy\[$$]: Input is EOF.\n";
last;
}
my $offset = 0;
my $quit = 0;
while ($len) {
my $written = syswrite($out, $buf, $len, $offset);
if (! defined $written) {
print STDERR "perl proxy\[$$]: Output is EOF. $!\n";
$quit = 1;
last;
}
$len -= $written;
$offset += $written;
}
last if $quit;
}
close($in);
close($out);
}
'
rm -f $tf
if [ -f $tf ]; then
echo "$tf still exists!"
exit 1
fi
echo "$cod" > $tf
chmod 700 $tf
}
ptmp=""
if [ "X$proxy" != "X" ]; then
ptmp="/tmp/ssl_vncviewer.$$.pl"
pcode $ptmp
connect="exec = $ptmp"
else
connect="connect = $host:$port"
fi
##debug = 7
tmp=/tmp/ssl_vncviewer.$$
cat > $tmp <<END
......@@ -106,12 +264,13 @@ $cert
[vnc_stunnel]
accept = $use
connect= $host:$port
$connect
END
echo ""
echo "Using this stunnel configuration:"
cat $tmp
echo ""
cat $tmp | uniq
echo ""
sleep 1
......@@ -140,3 +299,4 @@ else
fi
kill $pid
sleep 1
2006-04-16 Karl Runge <runge@karlrunge.com>
* x11vnc: More web proxy work for Java SSL applet and wrapper
script ssl_vncviewer. Apache SSL gateway support for
incoming x11vnc connections. Handle "double proxy" case.
2006-04-05 Karl Runge <runge@karlrunge.com>
* x11vnc: add FBPM support (-fbpm) for Suns. -rawfb ZERO for
testing. Basic key+cert management utilities: -sslGenCA,
......
This diff is collapsed.
......@@ -122,6 +122,11 @@ void clean_up_exit (int ret) {
/* remove the shm areas: */
clean_shm(0);
stop_stunnel();
if (use_openssl) {
ssl_helper_pid(0, 0); /* killall */
}
if (! dpy) exit(ret); /* raw_rb hack */
/* X keyboard cleanups */
......@@ -139,11 +144,6 @@ void clean_up_exit (int ret) {
if (use_solid_bg) {
solid_bg(1);
}
stop_stunnel();
if (use_openssl) {
ssl_helper_pid(0, 0); /* killall */
}
X_LOCK;
XTestDiscard_wr(dpy);
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
......
......@@ -632,10 +632,8 @@ void print_help(int mode) {
" filesystem to prevent network snooping (for example\n"
" -ssldir /var/lib/x11vnc-certs).\n"
"\n"
" -ssldir effects the other -ssl* options. In the case\n"
" of maintenance commands where the VNC server is not run\n"
" (e.g. -sslGenCA), the -ssldir option must precede the\n"
" command. E.g. x11vnc -ssldir ~/mydir -sslCertInfo LIST\n"
" -ssldir affects nearly all of the other -ssl* options,\n"
" e.g. -ssl SAVE, -sslGenCert, etc..\n"
"\n"
"-sslverify [path] For either of the -ssl or -stunnel modes, use [path]\n"
" to provide certificates to authenticate incoming VNC\n"
......
......@@ -51,7 +51,7 @@ void check_stunnel(void) {
int start_stunnel(int stunnel_port, int x11vnc_port) {
#ifdef SSLCMDS
char extra[] = ":/usr/sbin:/usr/local/sbin";
char extra[] = ":/usr/sbin:/usr/local/sbin:/dist/sbin";
char *path, *p, *exe;
char *stunnel_path = NULL;
struct stat verify_buf;
......@@ -119,6 +119,15 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
stunnel_port, x11vnc_port);
}
if (stunnel_pem && strstr(stunnel_pem, "SAVE") == stunnel_pem) {
stunnel_pem = get_saved_pem(stunnel_pem, 1);
if (! stunnel_pem) {
rfbLog("start_stunnel: could not create or open"
" saved PEM:\n", stunnel_pem);
clean_up_exit(1);
}
}
if (ssl_verify) {
if (stat(ssl_verify, &verify_buf) != 0) {
rfbLog("stunnel: %s does not exist.\n", ssl_verify);
......@@ -510,30 +519,30 @@ void sslEncKey(char *path, int mode) {
sprintf(tca, "%s/CA/cacert.pem", cdir);
path = tca;
} else if (info_only && (!strcasecmp(path, "LIST") ||
} else if (info_only && (!strcasecmp(path, "LIST") || !strcasecmp(path, "LS") ||
!strcasecmp(path, "ALL"))) {
if (! cdir || strchr(cdir, '\'')) {
fprintf(stderr, "bad certdir char: %s\n", cdir ? cdir : "null");
exit(1);
}
tca = (char *) malloc(2*strlen(cdir) + strlen(program_name) + 1000);
sprintf(tca, "find '%s' -type f | egrep '\\.(crt|pem|key|req)$' "
sprintf(tca, "find '%s' | egrep '/(CA|tmp|clients)$|\\.(crt|pem|key|req)$' "
"| grep -v CA/newcerts", cdir);
if (!strcasecmp(path, "ALL")) {
/* ugh.. */
strcat(tca, " | grep -v private/cakey.pem | xargs -n1 ");
strcat(tca, " | egrep -v 'private/cakey.pem|(CA|tmp|clients)$' | xargs -n1 ");
strcat(tca, program_name);
strcat(tca, " -ssldir '");
strcat(tca, cdir);
strcat(tca, "' -sslCertInfo 2>&1 ");
} else if (listlong) {
strcat(tca, " | xargs ls -l ");
strcat(tca, " | xargs ls -ld ");
}
system(tca);
return;
} else if (info_only && (!strcasecmp(path, "HASHON") ||
!strcasecmp(path, "HASHOFF"))) {
} else if (info_only && (!strcasecmp(path, "HASHON")
|| !strcasecmp(path, "HASHOFF"))) {
tmp_fd = mkstemp(tmp);
if (tmp_fd < 0) {
......
......@@ -122,7 +122,9 @@ char *get_saved_pem(char *save, int create) {
char *new = NULL;
if (create) {
new = create_tmp_pem(path, prompt);
sslEncKey(new, 0);
if (! getenv("X11VNC_SSL_NO_PASSPHRASE") && ! inetd) {
sslEncKey(new, 0);
}
}
return new;
} else {
......@@ -977,6 +979,11 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
int nfd, db = 0;
struct timeval tv;
fd_set rd;
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
/*
* we'll do a select() on s_in for reading. this is not an
* absolute proof that SSL_read is ready (XXX use SSL utility).
......@@ -984,6 +991,7 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
tv.tv_sec = 2;
tv.tv_usec = 0;
if (mode == OPENSSL_INETD) {
/*
* https via inetd is icky because x11vnc is restarted
......@@ -1003,7 +1011,7 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
tv.tv_sec = 4;
}
}
if (1) fprintf(stderr, "tv_sec: %d - %s\n", (int) tv.tv_sec, last_get);
if (db) fprintf(stderr, "tv_sec: %d - %s\n", (int) tv.tv_sec, last_get);
FD_ZERO(&rd);
FD_SET(s_in, &rd);
......@@ -1024,7 +1032,7 @@ if (1) fprintf(stderr, "tv_sec: %d - %s\n", (int) tv.tv_sec, last_get);
static int watch_for_http_traffic(char *buf_a, int *n_a) {
int is_http, err, n, n2;
char *buf;
int db = 1;
int db = 0;
/*
* sniff the first couple bytes of the stream and try to see
* if it is http or not. if we read them OK, we must read the
......@@ -1032,6 +1040,9 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
* what has be read is returned in buf_a and n_a.
* *buf_a is BSIZE+1 long and zeroed.
*/
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
buf = (char *) calloc(sizeof(BSIZE+1), 1);
*n_a = 0;
......@@ -1076,6 +1087,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
}
static int csock_timeout_sock = -1;
static void csock_timeout (int sig) {
rfbLog("sig: %d, csock_timeout.\n", sig);
if (csock_timeout_sock >= 0) {
......@@ -1114,6 +1126,10 @@ int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie,
rfbLog("SSL: accept_openssl: detected https proxied connection"
" request.\n");
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
SSL_write(ssl, reply0, strlen(reply0));
SSL_shutdown(ssl);
SSL_shutdown(ssl);
......@@ -1192,6 +1208,10 @@ void accept_openssl(int mode) {
}
first = 0;
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
/* do INETD, VNC, or HTTPS cases (result is client socket or pipe) */
if (mode == OPENSSL_INETD) {
ssl_initialized = 1;
......@@ -1314,7 +1334,8 @@ void accept_openssl(int mode) {
/* now connect back to parent socket: */
vncsock = rfbConnectToTcpAddr("127.0.0.1", cport);
if (vncsock < 0) {
rfbLog("SSL: ssl_helper: could not connect back to: %d\n", cport);
rfbLog("SSL: ssl_helper[%d]: could not connect"
" back to: %d\n", getpid(), cport);
close(vncsock);
exit(1);
}
......@@ -1327,6 +1348,7 @@ void accept_openssl(int mode) {
} else {
s_in = s_out = sock;
}
if (! ssl_init(s_in, s_out)) {
close(vncsock);
exit(1);
......@@ -1342,8 +1364,8 @@ void accept_openssl(int mode) {
have_httpd = 1;
}
if (mode == OPENSSL_HTTPS && ! have_httpd) {
rfbLog("SSL: accept_openssl: no httpd socket for "
"-https mode\n");
rfbLog("SSL: accept_openssl[%d]: no httpd socket for "
"-https mode\n", getpid());
close(vncsock);
exit(1);
}
......@@ -1371,7 +1393,6 @@ void accept_openssl(int mode) {
* Check if there is stuff to read from remote end
* if so it is likely a GET or HEAD.
*/
if (1) fprintf(stderr, "is_ssl_readable\n");
if (! is_ssl_readable(s_in, last_https, last_get,
mode)) {
goto write_cookie;
......@@ -1384,7 +1405,7 @@ void accept_openssl(int mode) {
* is ever sent. So often we timeout here.
*/
if (1) fprintf(stderr, "watch_for_http_traffic\n");
if (db) fprintf(stderr, "watch_for_http_traffic\n");
is_http = watch_for_http_traffic(buf, &n);
if (is_http < 0 || is_http == 0) {
......@@ -1392,27 +1413,47 @@ void accept_openssl(int mode) {
* error or http not detected, fall back
* to normal VNC socket.
*/
if (db) fprintf(stderr, "is_http err: %d n: %d\n", is_http, n);
write(vncsock, cookie, strlen(cookie));
if (n > 0) {
write(vncsock, buf, n);
}
goto wrote_cookie;
}
if (1) fprintf(stderr, "buf: '%s'\n", buf);
if (db) fprintf(stderr, "is_http: %d n: %d\n", is_http, n);
if (db) fprintf(stderr, "buf: '%s'\n", buf);
if (strstr(buf, "/request.https.proxy.connection")) {
if (strstr(buf, "/request.https.vnc.connection")) {
char reply[] = "HTTP/1.0 200 OK\r\n"
"Content-Type: octet-stream\r\n"
"Connection: Keep-Alive\r\n"
"Pragma: no-cache\r\n\r\n";
/*
* special case proxy coming thru https
* instead of a direct SSL connection.
*/
if (! proxy_hack(vncsock, listen, s_in, s_out,
cookie, mode)) {
strcpy(tbuf, uniq);
strcat(tbuf, cookie);
write(vncsock, tbuf, strlen(tbuf));
close(vncsock);
rfbLog("Handling VNC request via https GET. [%d]\n", getpid());
if (strstr(buf, "/reverse.proxy")) {
char *buf;
int n, ptr;
SSL_write(ssl, reply, strlen(reply));
buf = (char *) calloc((8192+1), 1);
n = 0;
ptr = 0;
while (ptr < 8192) {
n = SSL_read(ssl, buf + ptr, 1);
if (n > 0) {
ptr += n;
}
if (db) fprintf(stderr, "buf2: '%s'\n", buf);
if (strstr(buf, "\r\n\r\n")) {
break;
}
}
}
exit(0);
goto write_cookie;
} else if (strstr(buf, "/check.https.proxy.connection")) {
char reply[] = "HTTP/1.0 200 OK\r\n"
......@@ -1491,7 +1532,8 @@ if (db) fprintf(stderr, "iface: %s\n", iface);
rfbLog("Could not connect to httpd socket!\n");
exit(1);
}
if (db) fprintf(stderr, "ssl_helper: httpsock: %d %d\n", httpsock, n);
if (db) fprintf(stderr, "ssl_helper[%d]: httpsock: %d %d\n",
getpid(), httpsock, n);
/*
* send what we read to httpd, and then connect
......@@ -1651,11 +1693,14 @@ static void ssl_timeout (int sig) {
static int ssl_init(int s_in, int s_out) {
unsigned char *sid = (unsigned char *) "x11vnc SID";
char *name;
int db = 1, rc, err;
int db = 0, rc, err;
int ssock = s_in;
double start = dnow();
int timeout = 20;
if (getenv("SSL_DEBUG")) {
db = atoi(getenv("SSL_DEBUG"));
}
if (db) fprintf(stderr, "ssl_init: %d/%d\n", s_in, s_out);
ssl = SSL_new(ctx);
......@@ -1749,7 +1794,7 @@ if (db > 1) fprintf(stderr, "d\n");
usleep(10 * 1000);
}
rfbLog("SSL: ssl_helper: SSL_accept() succeeded for: %s\n", name);
rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s\n", getpid(), name);
free(name);
return 1;
......@@ -1816,14 +1861,39 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
int cptr, sptr, c_rd, c_wr, s_rd, s_wr;
fd_set rd, wr;
struct timeval tv;
int ssock;
int ssock, cnt = 0;
/*
* we want to switch to a longer timeout for long term VNC
* connections (in case the network is not working for short
* periods), but we also want the timeout shorter at the beginning
* in case the client went away.
*/
time_t start;
int tv_https_early = 60;
int tv_https_later = 20;
int tv_vnc_early = 25;
int tv_vnc_later = 300;
int tv_cutover = 120;
int tv_use;
if (dbxfer) {
raw_xfer(csock, s_in, s_out);
return;
}
if (getenv("SSL_DEBUG")) {
db = atoi(getenv("SSL_DEBUG"));
}
if (db) fprintf(stderr, "ssl_xfer begin\n");
if (db) fprintf(stderr, "ssl_xfer begin\n");
start = time(0);
if (is_https) {
tv_use = tv_https_early;
} else {
tv_use = tv_vnc_early;
}
/*
* csock: clear text socket with libvncserver. "C"
......@@ -1890,6 +1960,7 @@ if (db) fprintf(stderr, "ssl_xfer begin\n");
*/
break;
}
cnt++;
/* set up the fd sets for the two sockets for read & write: */
......@@ -1927,11 +1998,15 @@ if (db) fprintf(stderr, "ssl_xfer begin\n");
}
}
if (is_https) {
tv.tv_sec = 50;
} else {
tv.tv_sec = 35;
if (tv_cutover && time(0) > start + tv_cutover) {
tv_cutover = 0;
if (is_https) {
tv_use = tv_https_later;
} else {
tv_use = tv_vnc_later;
}
}
tv.tv_sec = tv_use;
tv.tv_usec = 0;
/* do the select, repeat if interrupted */
......@@ -1939,7 +2014,7 @@ if (db) fprintf(stderr, "ssl_xfer begin\n");
nfd = select(fdmax+1, &rd, &wr, NULL, &tv);
} while (nfd < 0 && errno == EINTR);
if (db) fprintf(stderr, "nfd: %d\n", nfd);
if (db > 1) fprintf(stderr, "nfd: %d\n", nfd);
if (nfd < 0) {
rfbLog("SSL: ssl_xfer[%d]: select error: %d\n", getpid(), nfd);
......
......@@ -267,15 +267,20 @@ char genCert[] =
"\n"
"direrror() {\n"
" echo \"\"\n"
" echo \"You need first to run:\"\n"
" echo \"\"\n"
" if echo \"$DIR\" | grep '/\\.vnc/certs' > /dev/null; then\n"
" echo \"You need first to run: x11vnc -sslGenCA\"\n"
" echo \" x11vnc -sslGenCA\"\n"
" else\n"
" echo \"You need first to run: x11vnc -sslGenCA $DIR\"\n"
" echo \" x11vnc -sslGenCA $DIR\"\n"
" fi\n"
" echo \"\"\n"
" echo \"to create the CA cert file and other needed config files and directories.\"\n"
" echo \"\"\n"
" echo \"Then you can run: x11vnc -sslGenCert $type $name0\"\n"
" echo \"\"\n"
" if [ \"X$1\" != \"X\" ]; then\n"
" echo \"(missing: $1)\"\n"
" echo \"(missing file/dir: $1)\"\n"
" echo \"\"\n"
" fi\n"
" exit 1\n"
......
......@@ -2,7 +2,7 @@
.TH X11VNC "1" "April 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.1, lastmod: 2006-04-05
version: 0.8.1, lastmod: 2006-04-16
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -755,10 +755,8 @@ might want your certificates and keys to be on a local
filesystem to prevent network snooping (for example
\fB-ssldir\fR /var/lib/x11vnc-certs).
.IP
\fB-ssldir\fR effects the other \fB-ssl*\fR options. In the case
of maintenance commands where the VNC server is not run
(e.g. \fB-sslGenCA),\fR the \fB-ssldir\fR option must precede the
command. E.g. x11vnc \fB-ssldir\fR ~/mydir \fB-sslCertInfo\fR LIST
\fB-ssldir\fR affects nearly all of the other \fB-ssl*\fR options,
e.g. \fB-ssl\fR SAVE, \fB-sslGenCert,\fR etc..
.PP
\fB-sslverify\fR \fI[path]\fR
.IP
......
......@@ -1439,6 +1439,21 @@ int main(int argc, char* argv[]) {
exit(1); \
}
/*
* do a quick check for parameters that apply to "utility"
* commands, i.e. ones that do not run the server.
*/
for (i=1; i < argc; i++) {
arg = argv[i];
if (strstr(arg, "--") == arg) {
arg++;
}
if (!strcmp(arg, "-ssldir")) {
CHECK_ARGC
ssl_certs_dir = strdup(argv[++i]);
}
}
for (i=1; i < argc; i++) {
/* quick-n-dirty --option handling. */
arg = argv[i];
......
......@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-04-05";
char lastmod[] = "0.8.1 lastmod: 2006-04-16";
/* X display info */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment