Commit 06a401f8 authored by runge's avatar runge

x11vnc: -display WAIT:cmd=FINDDISPLAY, HTTPONCE, -http_ssl option, Java fixes.

parent 7a3e2363
...@@ -73,8 +73,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto ...@@ -73,8 +73,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto
serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSLSocketToMe.java diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSLSocketToMe.java
--- vnc_javasrc.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500 --- vnc_javasrc.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
+++ vnc_javasrc/SSLSocketToMe.java 2006-04-16 11:21:30.000000000 -0400 +++ vnc_javasrc/SSLSocketToMe.java 2006-06-12 00:00:28.000000000 -0400
@@ -0,0 +1,1204 @@ @@ -0,0 +1,1276 @@
+/* +/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer. + * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ * + *
...@@ -212,8 +212,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -212,8 +212,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ "No Trust url Certs."); + "No Trust url Certs.");
+ } + }
+ if (trusturlCerts.length > 1) { + if (trusturlCerts.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < trusturlCerts.length - 1; i++) {
+ if (! trusturlCerts[i].equals(trusturlCerts[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException( + throw new CertificateException(
+ "Too many Trust url Certs."); + "Too many Trust url Certs: "
+ + trusturlCerts.length
+ );
+ }
+ } + }
+ if (certs == null) { + if (certs == null) {
+ throw new CertificateException( + throw new CertificateException(
...@@ -224,8 +235,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -224,8 +235,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ "No this-certs Certs."); + "No this-certs Certs.");
+ } + }
+ if (certs.length > 1) { + if (certs.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < certs.length - 1; i++) {
+ if (! certs[i].equals(certs[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException( + throw new CertificateException(
+ "Too many this-certs."); + "Too many this-certs: "
+ + certs.length
+ );
+ }
+ } + }
+ if (! trusturlCerts[0].equals(certs[0])) { + if (! trusturlCerts[0].equals(certs[0])) {
+ throw new CertificateException( + throw new CertificateException(
...@@ -262,8 +284,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -262,8 +284,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ "No Trust All Server Certs."); + "No Trust All Server Certs.");
+ } + }
+ if (trustallCerts.length > 1) { + if (trustallCerts.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < trustallCerts.length - 1; i++) {
+ if (! trustallCerts[i].equals(trustallCerts[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException( + throw new CertificateException(
+ "Too many Trust All Server Certs."); + "Too many Trust All Server Certs: "
+ + trustallCerts.length
+ );
+ }
+ } + }
+ if (certs == null) { + if (certs == null) {
+ throw new CertificateException( + throw new CertificateException(
...@@ -274,8 +307,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -274,8 +307,19 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ "No this-certs Certs."); + "No this-certs Certs.");
+ } + }
+ if (certs.length > 1) { + if (certs.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < certs.length - 1; i++) {
+ if (! certs[i].equals(certs[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException( + throw new CertificateException(
+ "Too many this-certs."); + "Too many this-certs: "
+ + certs.length
+ );
+ }
+ } + }
+ if (! trustallCerts[0].equals(certs[0])) { + if (! trustallCerts[0].equals(certs[0])) {
+ throw new CertificateException( + throw new CertificateException(
...@@ -920,17 +964,26 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -920,17 +964,26 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
++ "\n" ++ "\n"
++ "This may be due to:\n" ++ "This may be due to:\n"
++ "\n" ++ "\n"
++ " - Your requesting to View the Certificate before accepting.\n"
++ "\n"
++ " - The VNC server using a Self-Signed Certificate.\n" ++ " - The VNC server using a Self-Signed Certificate.\n"
++ "\n" ++ "\n"
++ " - The VNC server using a Certificate Authority not recognized by your\n" ++ " - The VNC server using a Certificate Authority not recognized by your\n"
++ " Java applet runtime.\n" ++ " Browser or Java Plugin runtime.\n"
++ "\n"
++ " - The use of an Apache SSL portal employing CONNECT proxying and the\n"
++ " Apache web server has a certificate different from the VNC server's. \n"
++ "\n" ++ "\n"
++ " - A Man-In-The-Middle attack impersonating as the VNC server you wish\n" ++ " - A Man-In-The-Middle attack impersonating as the VNC server you wish\n"
++ " to connect to.\n" ++ " to connect to. (Wouldn't that be exciting!!)\n"
++ "\n" ++ "\n"
++ "By copying the VNC server's Certificate (or using a common Certificate\n" ++ "By safely copying the VNC server's Certificate (or using a common\n"
++ "Authority certificate) you can configure your Java applet runtime to\n" ++ "Certificate Authority certificate) you can configure your Web Browser or\n"
++ "automatically authenticate the Server.\n" ++ "Java Plugin to automatically authenticate this Server.\n"
++ "\n"
++ "If you do so, then you will only have to click \"Yes\" when this VNC\n"
++ "Viewer applet asks you whether to trust your Browser/Java Plugin's\n"
++ "acceptance of the certificate. (except for the Apache portal case above.)\n"
+; +;
+ +
+ /* the accept / do-not-accept radio buttons: */ + /* the accept / do-not-accept radio buttons: */
...@@ -966,7 +1019,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -966,7 +1019,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ label.setFont(new Font("Helvetica", Font.BOLD, 16)); + label.setFont(new Font("Helvetica", Font.BOLD, 16));
+ +
+ /* textarea in the middle */ + /* textarea in the middle */
+ textarea = new TextArea(text, 28, 64, + textarea = new TextArea(text, 36, 64,
+ TextArea.SCROLLBARS_VERTICAL_ONLY); + TextArea.SCROLLBARS_VERTICAL_ONLY);
+ textarea.setEditable(false); + textarea.setEditable(false);
+ +
...@@ -1188,13 +1241,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL ...@@ -1188,13 +1241,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ +
+ dialog = new Dialog(frame, true); + dialog = new Dialog(frame, true);
+ +
+ String m = "\nShould this VNC Viewer applet use your Browser/JVM certs to\n"; + String m = "";
+ m += "authenticate the VNC Server:\n"; +m += "\n";
+ m += "\n " + hostport + "\n\n " + vncServer + "\n\n"; +m += "This VNC Viewer applet does not have its own keystore to track\n";
+ m += "(NOTE: this *includes* any certs you have Just Now accepted in a\n"; +m += "SSL certificates, and so cannot authenticate the certificate\n";
+ m += "dialog box with your Web Browser or Java Applet Plugin)\n\n"; +m += "of the VNC Server:\n";
+ +m += "\n";
+ TextArea textarea = new TextArea(m, 12, 64, +m += " " + hostport + "\n\n " + vncServer + "\n";
+m += "\n";
+m += "on its own.\n";
+m += "\n";
+m += "However, it has noticed that your Web Browser or Java VM Plugin\n";
+m += "has previously accepted the same certificate. You may have set\n";
+m += "this up permanently or just for this session, or the server\n";
+m += "certificate was signed by a CA cert that your Web Browser or\n";
+m += "Java VM Plugin has.\n";
+m += "\n";
+m += "Should this VNC Viewer applet now connect to the above VNC server?\n";
+m += "\n";
+
+// String m = "\nShould this VNC Viewer applet use your Browser/JVM certs to\n";
+// m += "authenticate the VNC Server:\n";
+// m += "\n " + hostport + "\n\n " + vncServer + "\n\n";
+// m += "(NOTE: this *includes* any certs you have Just Now accepted in a\n";
+// m += "dialog box with your Web Browser or Java Applet Plugin)\n\n";
+
+ TextArea textarea = new TextArea(m, 20, 64,
+ TextArea.SCROLLBARS_VERTICAL_ONLY); + TextArea.SCROLLBARS_VERTICAL_ONLY);
+ textarea.setEditable(false); + textarea.setEditable(false);
+ yes = new Button("Yes"); + yes = new Button("Yes");
......
2006-06-12 Karl Runge <runge@karlrunge.com>
* x11vnc: word tune SSL Java viewer; fix multi-certs bug. Add
-display WAIT:cmd=FINDDISPLAY builtin script and cmd=HTTPONCE
action. -http_ssl option for ssl subdir only. Add -rawfb RAND
test case. improve raw_xfer() for use in inetd https transfer.
fix bug SSH + -unixpw -> -localhost. fix bug setup cursors
in WAIT mode. Mac OS X pty tweak.
2006-06-09 Karl Runge <runge@karlrunge.com> 2006-06-09 Karl Runge <runge@karlrunge.com>
* x11vnc: make -display WAIT + -unixpw work on Solaris. * x11vnc: make -display WAIT + -unixpw work on Solaris.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -316,7 +316,10 @@ void print_help(int mode) { ...@@ -316,7 +316,10 @@ void print_help(int mode) {
" where the Java vncviewer applet is, have x11vnc try\n" " where the Java vncviewer applet is, have x11vnc try\n"
" to *guess* where the directory is by looking relative\n" " to *guess* where the directory is by looking relative\n"
" to the program location and in standard locations\n" " to the program location and in standard locations\n"
" (/usr/local/share/x11vnc/classes, etc).\n" " (/usr/local/share/x11vnc/classes, etc). Under -ssl or\n"
" -stunnel the ssl classes subdirectory is sought.\n"
"-http_ssl As -http, but force lookup for ssl classes subdir.\n"
"\n"
"-connect string For use with \"vncviewer -listen\" reverse connections.\n" "-connect string For use with \"vncviewer -listen\" reverse connections.\n"
" If \"string\" has the form \"host\" or \"host:port\"\n" " If \"string\" has the form \"host\" or \"host:port\"\n"
" the connection is made once at startup. Use commas\n" " the connection is made once at startup. Use commas\n"
...@@ -602,9 +605,22 @@ void print_help(int mode) { ...@@ -602,9 +605,22 @@ void print_help(int mode) {
" SSL helper process that will not switch, but it is only\n" " SSL helper process that will not switch, but it is only\n"
" encoding and decoding the stream at that point.\n" " encoding and decoding the stream at that point.\n"
"\n" "\n"
" As a special case, WAIT:cmd=FINDDISPLAY will run a\n" " As a special case, WAIT:cmd=FINDDISPLAY will run\n"
" script that works on most Unixes to determine a user's\n" " a script that works on most Unixes to determine a\n"
" DISPLAY variable and xauthority data. this is TBD.\n" " user's DISPLAY variable and xauthority data. To have\n"
" this default script printed to stdout (e.g. for\n"
" customization) run with WAIT:cmd=FINDDISPLAY-print\n"
"\n"
" As another special case, WAIT:cmd=HTTPONCE will allow\n"
" x11vnc to service one http request and then exit.\n"
" This is usually done in -inetd mode to run on, say,\n"
" port 5800 and allow the Java vncviewer to be downloaded\n"
" by client web browsers. For example:\n"
"\n"
" 5815 stream tcp nowait root /usr/sbin/tcpd .../x11vnc \\\n"
" -inetd -q -http_ssl -display WAIT:cmd=HTTPONCE\n"
"\n"
" Is used in the Apache SSL-portal example (see FAQ).\n"
"\n" "\n"
" Finally, one can insert a geometry between colons,\n" " Finally, one can insert a geometry between colons,\n"
" e.g. WAIT:1280x1024:... to set the size of the display\n" " e.g. WAIT:1280x1024:... to set the size of the display\n"
...@@ -1122,11 +1138,6 @@ void print_help(int mode) { ...@@ -1122,11 +1138,6 @@ void print_help(int mode) {
" the -rfbauth option. If none of these succeed x11vnc\n" " the -rfbauth option. If none of these succeed x11vnc\n"
" exits immediately.\n" " exits immediately.\n"
"\n" "\n"
#ifndef REL81
" Note: -unixpw currently does not count as a password\n"
" method by this option.\n"
"\n"
#endif
"-storepasswd pass file Store password \"pass\" as the VNC password in the\n" "-storepasswd pass file Store password \"pass\" as the VNC password in the\n"
" file \"file\". Once the password is stored the\n" " file \"file\". Once the password is stored the\n"
" program exits. Use the password via \"-rfbauth file\"\n" " program exits. Use the password via \"-rfbauth file\"\n"
......
...@@ -23,6 +23,7 @@ int use_stunnel = 0; /* -stunnel */ ...@@ -23,6 +23,7 @@ int use_stunnel = 0; /* -stunnel */
int stunnel_port = 0; int stunnel_port = 0;
char *stunnel_pem = NULL; char *stunnel_pem = NULL;
int use_openssl = 0; int use_openssl = 0;
int http_ssl = 0;
char *openssl_pem = NULL; char *openssl_pem = NULL;
char *ssl_certs_dir = NULL; char *ssl_certs_dir = NULL;
int https_port_num = -1; int https_port_num = -1;
......
...@@ -23,6 +23,7 @@ extern int use_stunnel; ...@@ -23,6 +23,7 @@ extern int use_stunnel;
extern int stunnel_port; extern int stunnel_port;
extern char *stunnel_pem; extern char *stunnel_pem;
extern int use_openssl; extern int use_openssl;
extern int http_ssl;
extern char *openssl_pem; extern char *openssl_pem;
extern char *ssl_certs_dir; extern char *ssl_certs_dir;
extern int https_port_num; extern int https_port_num;
......
...@@ -268,7 +268,7 @@ void check_black_fb(void) { ...@@ -268,7 +268,7 @@ void check_black_fb(void) {
} }
int check_httpdir(void) { int check_httpdir(void) {
if (http_dir) { if (http_dir && http_dir[0] != '\0') {
return 1; return 1;
} else { } else {
char *prog = NULL, *httpdir, *q; char *prog = NULL, *httpdir, *q;
...@@ -324,7 +324,7 @@ int check_httpdir(void) { ...@@ -324,7 +324,7 @@ int check_httpdir(void) {
len = strlen(prog) + 21 + 1; len = strlen(prog) + 21 + 1;
*q = '\0'; *q = '\0';
httpdir = (char *) malloc(len); httpdir = (char *) malloc(len);
if (use_openssl || use_stunnel) { if (use_openssl || use_stunnel || http_ssl) {
snprintf(httpdir, len, "%s/../share/x11vnc/classes/ssl", prog); snprintf(httpdir, len, "%s/../share/x11vnc/classes/ssl", prog);
} else { } else {
snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog); snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog);
...@@ -351,7 +351,7 @@ int check_httpdir(void) { ...@@ -351,7 +351,7 @@ int check_httpdir(void) {
"/usr/share/x11vnc/classes/ssl", "/usr/share/x11vnc/classes/ssl",
NULL NULL
}; };
if (use_openssl || use_stunnel) { if (use_openssl || use_stunnel || http_ssl) {
use = ssllist; use = ssllist;
} else { } else {
use = list; use = list;
...@@ -392,8 +392,8 @@ void http_connections(int on) { ...@@ -392,8 +392,8 @@ void http_connections(int on) {
} }
} }
screen->httpInitDone = FALSE; screen->httpInitDone = FALSE;
screen->httpDir = http_dir;
if (check_httpdir()) { if (check_httpdir()) {
screen->httpDir = http_dir;
rfbHttpInitSockets(screen); rfbHttpInitSockets(screen);
} }
} else { } else {
......
...@@ -874,6 +874,9 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n"); ...@@ -874,6 +874,9 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
if (!strcasecmp(raw_fb_str, "NULL") || !strcasecmp(raw_fb_str, "ZERO")) { if (!strcasecmp(raw_fb_str, "NULL") || !strcasecmp(raw_fb_str, "ZERO")) {
raw_fb_str = strdup("map:/dev/zero@640x480x32"); raw_fb_str = strdup("map:/dev/zero@640x480x32");
} }
if (!strcasecmp(raw_fb_str, "RAND")) {
raw_fb_str = strdup("file:/dev/urandom@128x128x16");
}
if ( (q = strstr(raw_fb_str, "setup:")) == raw_fb_str) { if ( (q = strstr(raw_fb_str, "setup:")) == raw_fb_str) {
FILE *pipe; FILE *pipe;
......
...@@ -32,6 +32,8 @@ int openssl_port_num = 0; ...@@ -32,6 +32,8 @@ int openssl_port_num = 0;
int https_sock = -1; int https_sock = -1;
pid_t openssl_last_helper_pid = 0; pid_t openssl_last_helper_pid = 0;
void raw_xfer(int csock, int s_in, int s_out);
#if !LIBVNCSERVER_HAVE_LIBSSL #if !LIBVNCSERVER_HAVE_LIBSSL
int openssl_present(void) {return 0;} int openssl_present(void) {return 0;}
static void badnews(void) { static void badnews(void) {
...@@ -76,7 +78,6 @@ static void sslerrexit(void); ...@@ -76,7 +78,6 @@ static void sslerrexit(void);
static char *get_input(char *tag, char **in); static char *get_input(char *tag, char **in);
static char *create_tmp_pem(char *path, int prompt); static char *create_tmp_pem(char *path, int prompt);
static int ssl_init(int s_in, int s_out); static int ssl_init(int s_in, int s_out);
static void raw_xfer(int csock, int s_in, int s_out);
static void ssl_xfer(int csock, int s_in, int s_out, int is_https); static void ssl_xfer(int csock, int s_in, int s_out, int is_https);
#ifndef FORK_OK #ifndef FORK_OK
...@@ -1057,6 +1058,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) { ...@@ -1057,6 +1058,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
strncpy(buf_a, buf, n); strncpy(buf_a, buf, n);
*n_a = n; *n_a = n;
} }
if (db) fprintf(stderr, "watch_for_http_traffic ssl err: %d/%d\n", err, n);
return -1; return -1;
} }
...@@ -1071,21 +1073,29 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) { ...@@ -1071,21 +1073,29 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
} else if (!strncmp("CO", buf, 2)) { } else if (!strncmp("CO", buf, 2)) {
is_http = 1; is_http = 1;
} }
if (db) fprintf(stderr, "read: '%s'\n", buf); if (db) fprintf(stderr, "watch_for_http_traffic read: '%s' %d\n", buf, n);
/* /*
* better read all we can and fwd it along to avoid blocking * better read all we can and fwd it along to avoid blocking
* in ssl_xfer(). * in ssl_xfer().
*/ */
n2 = SSL_read(ssl, buf + n, ABSIZE - n); n2 = SSL_read(ssl, buf + n, ABSIZE - n);
if (n2 >= 0) { if (n2 >= 0) {
n += n2; n += n2;
} }
*n_a = n; *n_a = n;
if (db) fprintf(stderr, "watch_for_http_traffic readmore: %d\n", n2);
if (n > 0) { if (n > 0) {
/* XXX memcpy? */ memcpy(buf_a, buf, n);
strncpy(buf_a, buf, n);
} }
if (db > 1) {
fprintf(stderr, "watch_for_http_traffic readmore: ");
write(2, buf_a, *n_a);
fprintf(stderr, "\n");
}
if (db) fprintf(stderr, "watch_for_http_traffic return: %d\n", is_http);
return is_http; return is_http;
} }
...@@ -1814,61 +1824,6 @@ if (db > 1) fprintf(stderr, "ssl_init: 4\n"); ...@@ -1814,61 +1824,6 @@ if (db > 1) fprintf(stderr, "ssl_init: 4\n");
return 1; return 1;
} }
static void raw_xfer(int csock, int s_in, int s_out) {
char buf[8192];
int sz = 8192, n, m, status;
pid_t pid = fork();
int db = 1;
/* this is for testing, no SSL just socket redir */
if (pid < 0) {
exit(1);
}
if (pid) {
if (db) fprintf(stderr, "raw_xfer start: %d -> %d/%d\n", csock, s_in, s_out);
while (1) {
n = read(csock, buf, sz);
if (n == 0 || (n < 0 && errno != EINTR) ) {
break;
} else if (n > 0) {
m = write(s_out, buf, n);
if (db > 1) write(2, buf, n);
if (m != n) {
if (db) fprintf(stderr, "raw_xfer bad write: %d -> %d | %d/%d\n", csock, s_out, m, n);
break;
}
}
}
kill(pid, SIGTERM);
waitpid(pid, &status, WNOHANG);
if (db) fprintf(stderr, "raw_xfer done: %d -> %d\n", csock, s_out);
} else {
if (db) fprintf(stderr, "raw_xfer start: %d <- %d\n", csock, s_in);
while (1) {
n = read(s_in, buf, sz);
if (n == 0 || (n < 0 && errno != EINTR) ) {
break;
} else if (n > 0) {
m = write(csock, buf, n);
if (db > 1) write(2, buf, n);
if (m != n) {
if (db) fprintf(stderr, "raw_xfer bad write: %d <- %d | %d/%d\n", csock, s_in, m, n);
break;
}
}
}
if (db) fprintf(stderr, "raw_xfer done: %d <- %d\n", csock, s_in);
}
close(csock);
close(s_in);
close(s_out);
}
static void ssl_xfer(int csock, int s_in, int s_out, int is_https) { static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err; int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err;
char cbuf[ABSIZE], sbuf[ABSIZE]; char cbuf[ABSIZE], sbuf[ABSIZE];
...@@ -2306,3 +2261,79 @@ static void init_prng(void) { ...@@ -2306,3 +2261,79 @@ static void init_prng(void) {
#endif /* FORK_OK */ #endif /* FORK_OK */
#endif /* LIBVNCSERVER_HAVE_LIBSSL */ #endif /* LIBVNCSERVER_HAVE_LIBSSL */
void raw_xfer(int csock, int s_in, int s_out) {
char buf[8192];
int sz = 8192, n, m, status;
#ifdef FORK_OK
pid_t pid = fork();
int db = 1;
/* this is for testing, no SSL just socket redir */
if (pid < 0) {
exit(1);
}
if (pid) {
if (db) fprintf(stderr, "raw_xfer start: %d -> %d/%d\n", csock, s_in, s_out);
while (1) {
n = read(csock, buf, sz);
if (n == 0 || (n < 0 && errno != EINTR) ) {
break;
} else if (n > 0) {
int len = n;
char *src = buf;
if (db > 1) write(2, buf, n);
while (len > 0) {
m = write(s_out, src, len);
if (m > 0) {
src += m;
len -= m;
continue;
}
if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
continue;
}
if (db) fprintf(stderr, "raw_xfer bad write: %d -> %d | %d/%d errno=%d\n", csock, s_out, m, n, errno);
break;
}
}
}
kill(pid, SIGTERM);
waitpid(pid, &status, WNOHANG);
if (db) fprintf(stderr, "raw_xfer done: %d -> %d\n", csock, s_out);
} else {
if (db) fprintf(stderr, "raw_xfer start: %d <- %d\n", csock, s_in);
while (1) {
n = read(s_in, buf, sz);
if (n == 0 || (n < 0 && errno != EINTR) ) {
break;
} else if (n > 0) {
int len = n;
char *src = buf;
if (db > 1) write(2, buf, n);
while (len > 0) {
m = write(csock, src, len);
if (m > 0) {
src += m;
len -= m;
continue;
}
if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
continue;
}
if (db) fprintf(stderr, "raw_xfer bad write: %d <- %d | %d/%d errno=%d\n", csock, s_in, m, n, errno);
break;
}
}
}
if (db) fprintf(stderr, "raw_xfer done: %d <- %d\n", csock, s_in);
}
close(csock);
close(s_in);
close(s_out);
#endif
}
...@@ -676,4 +676,75 @@ char genCert[] = ...@@ -676,4 +676,75 @@ char genCert[] =
"sign_key\n" "sign_key\n"
; ;
char find_display[] =
"#!/bin/sh\n"
"#\n"
"# Script for use in -display WAIT:cmd=FINDDISPLAY -unixpw mode.\n"
"# Attempts to find 1) DISPLAY and 2) XAUTH data for the user and\n"
"# returns them to caller.\n"
"#\n"
"# The idea is this script is run via su - user -c ... and returns\n"
"# display + xauth info to caller (x11vnc running as root or nobody).\n"
"# x11vnc then uses the info to open the display.\n"
"#\n"
"\n"
"#env; set -xv\n"
"PATH=$PATH:/bin:/usr/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/ucb\n"
"export PATH\n"
"\n"
"# -n means no xauth, -f prescribes file to use.\n"
"showxauth=1\n"
"if [ \"X$1\" = \"X-n\" ]; then\n"
" showxauth=\"\"\n"
" shift\n"
"elif [ \"X$1\" = \"X-f\" ]; then\n"
" shift\n"
" showxauth=\"$1\"\n"
" shift\n"
"fi\n"
"\n"
"user=\"$1\" # cmd line arg takes precedence\n"
"if [ \"X$user\" = \"X\" ]; then\n"
" user=$X11VNC_USER # then X11VNC_USER\n"
"fi\n"
"if [ \"X$user\" = \"X\" ]; then\n"
" user=$USER # then USER\n"
"fi\n"
"if [ \"X$user\" = \"X\" ]; then\n"
" user=$LOGNAME # then LOGNAME\n"
"fi\n"
"if [ \"X$user\" = \"X\" ]; then\n"
" user=`whoami 2>/dev/null` # desperation whoami\n"
"fi\n"
"if [ \"X$user\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
"fi\n"
"\n"
"# Now try to match X DISPLAY to user:\n"
"\n"
"# who(1) output column 2:\n"
"display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | head -1 | awk '{print $2}'`\n"
"\n"
"if [ \"X$display\" = \"X\" ]; then\n"
" # who(1) output, last column:\n"
" display=`who | grep \"^${user}[ ]\" | awk '{print $NF}' | grep '(:[0-9]' | sed -e 's/[()]//g' | head -1`\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
" fi\n"
"fi\n"
"\n"
"echo \"DISPLAY=$display\"\n"
"if [ \"X$showxauth\" != \"X\" ]; then\n"
" if [ \"X$showxauth\" = \"X1\" ]; then\n"
" xauth extract - \"$display\" 2>/dev/null\n"
" else\n"
" xauth -f \"$showxauth\" extract - \"$display\" 2>/dev/null\n"
" fi\n"
"fi\n"
"\n"
"exit 0\n"
;
#endif /* _SSLTOOLS_H */ #endif /* _SSLTOOLS_H */
...@@ -39,6 +39,9 @@ extern char *crypt(const char*, const char *); ...@@ -39,6 +39,9 @@ extern char *crypt(const char*, const char *);
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
#define IS_BSD #define IS_BSD
#endif #endif
#if (defined(__MACH__) && defined(__APPLE__))
#define IS_BSD
#endif
#ifdef REL81 #ifdef REL81
#undef UNIXPW_SU #undef UNIXPW_SU
...@@ -49,6 +52,7 @@ void unixpw_screen(int init); ...@@ -49,6 +52,7 @@ void unixpw_screen(int init);
void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
void unixpw_accept(char *user); void unixpw_accept(char *user);
void unixpw_deny(void); void unixpw_deny(void);
void unixpw_msg(char *msg, int delay);
int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size); int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
int crypt_verify(char *user, char *pass); int crypt_verify(char *user, char *pass);
...@@ -1195,3 +1199,26 @@ void unixpw_deny(void) { ...@@ -1195,3 +1199,26 @@ void unixpw_deny(void) {
copy_screen(); copy_screen();
} }
void unixpw_msg(char *msg, int delay) {
int x, y, i;
char_row += 2;
char_col = 0;
x = char_x + char_col * char_w;
y = char_y + char_row * char_h;
rfbDrawString(screen, &default8x16Font, x, y, msg, white());
if (scaling) {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 1);
} else {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
for (i=0; i<5; i++) {
rfbPE(-1);
usleep(500 * 1000);
if (i >= delay) {
break;
}
}
}
...@@ -7,6 +7,7 @@ extern void unixpw_screen(int init); ...@@ -7,6 +7,7 @@ extern void unixpw_screen(int init);
extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
extern void unixpw_accept(char *user); extern void unixpw_accept(char *user);
extern void unixpw_deny(void); extern void unixpw_deny(void);
extern void unixpw_msg(char *msg, int delay);
extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size); extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
extern int crypt_verify(char *user, char *pass); extern int crypt_verify(char *user, char *pass);
......
...@@ -943,6 +943,94 @@ void check_new_passwds(void) { ...@@ -943,6 +943,94 @@ void check_new_passwds(void) {
} }
} }
static void handle_one_http_request(void) {
rfbLog("handle_one_http_request: begin.\n");
if (screen->httpPort == 0) {
int port = find_free_port(5800, 5850);
if (port) {
screen->httpPort = port;
} else {
rfbLog("handle_one_http_request: no http port.\n");
clean_up_exit(1);
}
}
screen->autoPort = FALSE;
screen->port = 0;
http_connections(1);
rfbInitServer(screen);
if (! inetd) {
int conn = 0;
while (1) {
if (0) fprintf(stderr, "%d %d %d %d\n", conn, screen->listenSock, screen->httpSock, screen->httpListenSock);
usleep(10 * 1000);
rfbHttpCheckFds(screen);
if (conn) {
if (screen->httpSock < 0) {
break;
}
} else {
if (screen->httpSock >= 0) {
conn = 1;
}
}
if (!screen->httpDir) {
break;
}
if (screen->httpListenSock < 0) {
break;
}
}
rfbLog("handle_one_http_request: finished.\n");
return;
} else {
#if LIBVNCSERVER_HAVE_FORK
pid_t pid;
int s_in = screen->inetdSock;
if (s_in < 0) {
rfbLog("handle_one_http_request: inetdSock not set up.\n");
clean_up_exit(1);
}
pid = fork();
if (pid < 0) {
rfbLog("handle_one_http_request: could not fork.\n");
clean_up_exit(1);
} else if (pid > 0) {
int status;
pid_t pidw;
while (1) {
rfbHttpCheckFds(screen);
pidw = waitpid(pid, &status, WNOHANG);
if (pidw == pid && WIFEXITED(status)) {
break;
} else if (pidw < 0) {
break;
}
}
rfbLog("handle_one_http_request: finished.\n");
return;
} else {
int sock = rfbConnectToTcpAddr("127.0.0.1",
screen->httpPort);
if (sock < 0) {
exit(1);
}
raw_xfer(sock, s_in, s_in);
exit(0);
}
#else
rfbLog("handle_one_http_request: fork not supported.\n");
clean_up_exit(1);
#endif
}
}
extern char find_display[];
int wait_for_client(int *argc, char** argv, int http) { int wait_for_client(int *argc, char** argv, int http) {
static XImage ximage_struct; static XImage ximage_struct;
XImage* fb_image; XImage* fb_image;
...@@ -952,50 +1040,69 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -952,50 +1040,69 @@ int wait_for_client(int *argc, char** argv, int http) {
char *str, *q, *p; char *str, *q, *p;
char *cmd = NULL; char *cmd = NULL;
int db = 0; int db = 0;
char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
int tmp_fd = -1, dt = 0;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) { if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0; return 0;
} }
rfbLog("into wait_for_client.\n"); for (i=0; i< *argc; i++) {
if (!strcmp(argv[i], "-desktop")) {
dt = 1;
}
if (0) fprintf(stderr, "args %d %s\n", i, argv[i]);
}
str = strdup(use_dpy); str = strdup(use_dpy);
str += strlen("WAIT:"); str += strlen("WAIT");
q = strchr(str, ':');
/* get any leading geometry: */ /* get any leading geometry: */
if (q) *q = '\0'; q = strchr(str+1, ':');
if (sscanf(str, "%dx%d", &w0, &h0) == 2) { if (q) {
*q = '\0';
if (sscanf(str+1, "%dx%d", &w0, &h0) == 2) {
w = w0; w = w0;
h = h0; h = h0;
rfbLog("wait_for_client set: w=%d h=%d\n", w, h);
} }
if (q) *q = ':'; *q = ':';
str = q;
q = strchr(str, ':');
if (! q) {
if (strstr(str, "cmd=") != str) {
str = strdup(":0");
} }
/* str currently begins with a ':' */
if (strstr(str, ":cmd=") == str) {
/* cmd=/path/to/mycommand */
str++;
} else if (strpbrk(str, "0123456789") == str+1) {
/* :0.0 */
;
} else { } else {
str = q; /* hostname:0.0 */
str++;
} }
if (db) fprintf(stderr, "str: %s\n", str); if (db) fprintf(stderr, "str: %s\n", str);
if (strstr(str, "cmd=") == str) { if (strstr(str, "cmd=") == str) {
cmd = str + strlen("cmd=");
if (db) fprintf(stderr, "cmd: %s\n", cmd);
/* WAIT */
if (no_external_cmds) { if (no_external_cmds) {
rfbLog("wait_for_client external cmds not allowed:" rfbLog("wait_for_client external cmds not allowed:"
" %s\n", use_dpy); " %s\n", use_dpy);
clean_up_exit(1); clean_up_exit(1);
} }
cmd = str + strlen("cmd=");
if (!strcmp(str, "FINDDISPLAY-print")) {
fprintf(stdout, "%s", find_display);
clean_up_exit(0);
}
if (db) fprintf(stderr, "cmd: %s\n", cmd);
} }
if (fake_fb) { if (fake_fb) {
free(fake_fb); free(fake_fb);
} }
fake_fb = (char *) calloc(w*h*b/4, 1); fake_fb = (char *) calloc(w*h*b/8, 1);
fb_image = &ximage_struct; fb_image = &ximage_struct;
fb_image->data = fake_fb; fb_image->data = fake_fb;
...@@ -1017,10 +1124,39 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1017,10 +1124,39 @@ int wait_for_client(int *argc, char** argv, int http) {
off_x = 0; off_x = 0;
off_y = 0; off_y = 0;
if (! dt) {
char *s;
argv[*argc] = strdup("-desktop");
(*argc)++;
if (cmd) {
char *q;
s = choose_title(":0");
q = strstr(s, ":0");
if (q) {
*q = '\0';
}
} else {
s = choose_title(str);
}
rfb_desktop_name = strdup(s);
argv[*argc] = s;
(*argc)++;
}
initialize_allowed_input(); initialize_allowed_input();
initialize_cursors_mode();
initialize_screen(argc, argv, fb_image); initialize_screen(argc, argv, fb_image);
initialize_signals();
if (!strcmp(cmd, "HTTPONCE")) {
handle_one_http_request();
clean_up_exit(0);
}
if (http && check_httpdir()) { if (http && check_httpdir()) {
http_connections(1); http_connections(1);
} }
...@@ -1081,11 +1217,28 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1081,11 +1217,28 @@ int wait_for_client(int *argc, char** argv, int http) {
memset(line1, 0, 1024); memset(line1, 0, 1024);
memset(line2, 0, 16384); memset(line2, 0, 16384);
if (!strcmp(cmd, "FINDDISPLAY")) {
tmp_fd = mkstemp(tmp);
if (tmp_fd < 0) {
rfbLog("wait_for_client: open failed: %s\n", tmp);
rfbLogPerror("mkstemp");
clean_up_exit(1);
}
write(tmp_fd, find_display, strlen(find_display));
close(tmp_fd);
chmod(tmp, 0644);
cmd = (char *) malloc(strlen(tmp) + strlen("/bin/sh ") + 1);
sprintf(cmd, "/bin/sh %s", tmp);
}
rfbLog("wait_for_client: running: %s\n", cmd);
if (unixpw) { if (unixpw) {
int res = 0, k, j, i; int res = 0, k, j, i;
char line[18000]; char line[18000];
memset(line, 0, 18000); memset(line, 0, 18000);
if (0) unixpw_msg("Looking up DISPLAY", 0);
if (keep_unixpw_user && keep_unixpw_pass) { if (keep_unixpw_user && keep_unixpw_pass) {
n = 18000; n = 18000;
...@@ -1096,8 +1249,15 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1096,8 +1249,15 @@ int wait_for_client(int *argc, char** argv, int http) {
} }
keep_unixpw = 0; keep_unixpw = 0;
if (tmp_fd >= 0) {
unlink(tmp);
}
if (db) write(2, line, n); write(2, "\n", 1);
if (! res) { if (! res) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd); rfbLog("wait_for_client: cmd failed: %s\n", cmd);
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1); clean_up_exit(1);
} }
...@@ -1135,19 +1295,31 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1135,19 +1295,31 @@ int wait_for_client(int *argc, char** argv, int http) {
if (! p) { if (! p) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd); rfbLog("wait_for_client: cmd failed: %s\n", cmd);
rfbLogPerror("popen"); rfbLogPerror("popen");
if (tmp_fd >= 0) {
unlink(tmp);
}
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1); clean_up_exit(1);
} }
if (fgets(line1, 1024, p) == NULL) { if (fgets(line1, 1024, p) == NULL) {
rfbLog("wait_for_client: read failed: %s\n", cmd); rfbLog("wait_for_client: read failed: %s\n", cmd);
rfbLogPerror("fgets"); rfbLogPerror("fgets");
if (tmp_fd >= 0) {
unlink(tmp);
}
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1); clean_up_exit(1);
} }
n = fread(line2, 1, 16384, p); n = fread(line2, 1, 16384, p);
pclose(p); pclose(p);
if (tmp_fd >= 0) {
unlink(tmp);
}
} }
if (strstr(line1, "DISPLAY=") != line1) { if (strstr(line1, "DISPLAY=") != line1) {
rfbLog("wait_for_client: bad reply %s\n", line1); rfbLog("wait_for_client: bad reply %s\n", line1);
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1); clean_up_exit(1);
} }
...@@ -1158,7 +1330,6 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1158,7 +1330,6 @@ int wait_for_client(int *argc, char** argv, int http) {
q++; q++;
} }
if (db) fprintf(stderr, "use_dpy: %s n: %d\n", use_dpy, n); if (db) fprintf(stderr, "use_dpy: %s n: %d\n", use_dpy, n);
if (0) write(2, line2, n);
if (line2[0] != '\0') { if (line2[0] != '\0') {
if (strstr(line2, "XAUTHORITY=") == line2) { if (strstr(line2, "XAUTHORITY=") == line2) {
q = line2; q = line2;
...@@ -1176,12 +1347,13 @@ if (0) write(2, line2, n); ...@@ -1176,12 +1347,13 @@ if (0) write(2, line2, n);
xauth_raw_len = n; xauth_raw_len = n;
memcpy(xauth_raw_data, line2, n); memcpy(xauth_raw_data, line2, n);
if (db) fprintf(stderr, "xauth_raw_len: %d\n", n); if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
if (0) {
write(2, xauth_raw_data, xauth_raw_len);
fprintf(stderr, "\n");
}
} }
} }
if (unixpw) {
char str[32];
snprintf(str, 30, "Using DISPLAY %s", use_dpy);
unixpw_msg(str, 2);
}
} else { } else {
use_dpy = strdup(str); use_dpy = strdup(str);
} }
......
...@@ -47,6 +47,8 @@ void rfbCFD(long usec); ...@@ -47,6 +47,8 @@ void rfbCFD(long usec);
double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1, double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
int X2, int Y2); int X2, int Y2);
char *choose_title(char *display);
/* /*
* routine to keep 0 <= i < n, should use in more places... * routine to keep 0 <= i < n, should use in more places...
...@@ -448,3 +450,32 @@ double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1, ...@@ -448,3 +450,32 @@ double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
return o; return o;
} }
/*
* choose a desktop name
*/
char *choose_title(char *display) {
static char title[(MAXN+10)];
strcpy(title, "x11vnc");
if (display == NULL) {
display = getenv("DISPLAY");
}
if (display == NULL) {
return title;
}
title[0] = '\0';
if (display[0] == ':') {
if (this_host() != NULL) {
strncpy(title, this_host(), MAXN - strlen(title));
}
}
strncat(title, display, MAXN - strlen(title));
if (subwin && valid_window(subwin, NULL, 0)) {
char *name;
if (dpy && XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
}
}
return title;
}
...@@ -35,6 +35,7 @@ extern void rfbPE(long usec); ...@@ -35,6 +35,7 @@ extern void rfbPE(long usec);
extern void rfbCFD(long usec); extern void rfbCFD(long usec);
extern double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1, extern double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
int X2, int Y2); int X2, int Y2);
extern char *choose_title(char *display);
#define NONUL(x) ((x) ? (x) : "") #define NONUL(x) ((x) ? (x) : "")
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "June 2006" "x11vnc " "User Commands" .TH X11VNC "1" "June 2006" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.2, lastmod: 2006-06-08 version: 0.8.2, lastmod: 2006-06-12
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -380,7 +380,12 @@ Instead of using \fB-httpdir\fR (see below) to specify ...@@ -380,7 +380,12 @@ Instead of using \fB-httpdir\fR (see below) to specify
where the Java vncviewer applet is, have x11vnc try where the Java vncviewer applet is, have x11vnc try
to *guess* where the directory is by looking relative to *guess* where the directory is by looking relative
to the program location and in standard locations to the program location and in standard locations
(/usr/local/share/x11vnc/classes, etc). (/usr/local/share/x11vnc/classes, etc). Under \fB-ssl\fR or
\fB-stunnel\fR the ssl classes subdirectory is sought.
.PP
\fB-http_ssl\fR
.IP
As \fB-http,\fR but force lookup for ssl classes subdir.
.PP .PP
\fB-connect\fR \fIstring\fR \fB-connect\fR \fIstring\fR
.IP .IP
...@@ -718,9 +723,22 @@ switch to the user as well. Note: there will be a 2nd ...@@ -718,9 +723,22 @@ switch to the user as well. Note: there will be a 2nd
SSL helper process that will not switch, but it is only SSL helper process that will not switch, but it is only
encoding and decoding the stream at that point. encoding and decoding the stream at that point.
.IP .IP
As a special case, WAIT:cmd=FINDDISPLAY will run a As a special case, WAIT:cmd=FINDDISPLAY will run
script that works on most Unixes to determine a user's a script that works on most Unixes to determine a
DISPLAY variable and xauthority data. this is TBD. user's DISPLAY variable and xauthority data. To have
this default script printed to stdout (e.g. for
customization) run with WAIT:cmd=FINDDISPLAY-print
.IP
As another special case, WAIT:cmd=HTTPONCE will allow
x11vnc to service one http request and then exit.
This is usually done in \fB-inetd\fR mode to run on, say,
port 5800 and allow the Java vncviewer to be downloaded
by client web browsers. For example:
.IP
5815 stream tcp nowait root /usr/sbin/tcpd .../x11vnc \\
\fB-inetd\fR \fB-q\fR \fB-http_ssl\fR \fB-display\fR WAIT:cmd=HTTPONCE
.IP
Is used in the Apache SSL-portal example (see FAQ).
.IP .IP
Finally, one can insert a geometry between colons, Finally, one can insert a geometry between colons,
e.g. WAIT:1280x1024:... to set the size of the display e.g. WAIT:1280x1024:... to set the size of the display
...@@ -1274,9 +1292,6 @@ use it with \fB-passwdfile;\fR otherwise, prompt the user ...@@ -1274,9 +1292,6 @@ use it with \fB-passwdfile;\fR otherwise, prompt the user
for a password to create ~/.vnc/passwd and use it with for a password to create ~/.vnc/passwd and use it with
the \fB-rfbauth\fR option. If none of these succeed x11vnc the \fB-rfbauth\fR option. If none of these succeed x11vnc
exits immediately. exits immediately.
.IP
Note: \fB-unixpw\fR currently does not count as a password
method by this option.
.PP .PP
\fB-storepasswd\fR \fIpass\fR \fIfile\fR \fB-storepasswd\fR \fIpass\fR \fIfile\fR
.IP .IP
......
...@@ -148,13 +148,10 @@ ...@@ -148,13 +148,10 @@
* main routine for the x11vnc program * main routine for the x11vnc program
*/ */
static void check_cursor_changes(void); static void check_cursor_changes(void);
static void record_last_fb_update(void); static void record_last_fb_update(void);
static int choose_delay(double dt); static int choose_delay(double dt);
static void watch_loop(void); static void watch_loop(void);
static char *choose_title(char *display);
static int limit_shm(void); static int limit_shm(void);
static void check_rcfile(int argc, char **argv); static void check_rcfile(int argc, char **argv);
static void immediate_switch_user(int argc, char* argv[]); static void immediate_switch_user(int argc, char* argv[]);
...@@ -581,36 +578,6 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -581,36 +578,6 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
} }
} }
/*
* choose a desktop name
*/
static char *choose_title(char *display) {
static char title[(MAXN+10)];
strcpy(title, "x11vnc");
if (display == NULL) {
display = getenv("DISPLAY");
}
if (display == NULL) {
return title;
}
title[0] = '\0';
if (display[0] == ':') {
if (this_host() != NULL) {
strncpy(title, this_host(), MAXN - strlen(title));
}
}
strncat(title, display, MAXN - strlen(title));
if (subwin && valid_window(subwin, NULL, 0)) {
char *name;
if (dpy && XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
}
}
return title;
}
/* /*
* check blacklist for OSs with tight shm limits. * check blacklist for OSs with tight shm limits.
*/ */
...@@ -1193,6 +1160,7 @@ static void print_settings(int try_http, int bg, char *gui_str) { ...@@ -1193,6 +1160,7 @@ static void print_settings(int try_http, int bg, char *gui_str) {
fprintf(stderr, " safer: %d\n", more_safe); fprintf(stderr, " safer: %d\n", more_safe);
fprintf(stderr, " nocmds: %d\n", no_external_cmds); fprintf(stderr, " nocmds: %d\n", no_external_cmds);
fprintf(stderr, " deny_all: %d\n", deny_all); fprintf(stderr, " deny_all: %d\n", deny_all);
fprintf(stderr, " pid: %d\n", getpid());
fprintf(stderr, "\n"); fprintf(stderr, "\n");
#endif #endif
rfbLog("x11vnc version: %s\n", lastmod); rfbLog("x11vnc version: %s\n", lastmod);
...@@ -1371,7 +1339,7 @@ static void store_homedir_passwd(char *file) { ...@@ -1371,7 +1339,7 @@ static void store_homedir_passwd(char *file) {
#define SHOW_NO_PASSWORD_WARNING \ #define SHOW_NO_PASSWORD_WARNING \
(!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \ (!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \
&& !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \ && !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \
&& ! ssl_verify) && ! ssl_verify && !inetd)
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -1393,7 +1361,8 @@ int main(int argc, char* argv[]) { ...@@ -1393,7 +1361,8 @@ int main(int argc, char* argv[]) {
XImage *fb0 = NULL; XImage *fb0 = NULL;
/* used to pass args we do not know about to rfbGetScreen(): */ /* used to pass args we do not know about to rfbGetScreen(): */
int argc_vnc = 1; char *argv_vnc[128]; int argc_vnc_max = 1024;
int argc_vnc = 1; char *argv_vnc[2048];
/* check for -loop mode: */ /* check for -loop mode: */
check_loop_mode(argc, argv); check_loop_mode(argc, argv);
...@@ -1472,6 +1441,13 @@ int main(int argc, char* argv[]) { ...@@ -1472,6 +1441,13 @@ int main(int argc, char* argv[]) {
if (!strcmp(arg, "-display")) { if (!strcmp(arg, "-display")) {
CHECK_ARGC CHECK_ARGC
use_dpy = strdup(argv[++i]); use_dpy = strdup(argv[++i]);
if (strstr(use_dpy, "WAIT")) {
extern find_display[];
if (strstr(use_dpy, "cmd=FINDDISPLAY-print")) {
fprintf(stdout, "%s", find_display);
exit(0);
}
}
} else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) { } else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC CHECK_ARGC
auth_file = strdup(argv[++i]); auth_file = strdup(argv[++i]);
...@@ -1568,6 +1544,9 @@ int main(int argc, char* argv[]) { ...@@ -1568,6 +1544,9 @@ int main(int argc, char* argv[]) {
filexfer = 1; filexfer = 1;
} else if (!strcmp(arg, "-http")) { } else if (!strcmp(arg, "-http")) {
try_http = 1; try_http = 1;
} else if (!strcmp(arg, "-http_ssl")) {
try_http = 1;
http_ssl = 1;
} else if (!strcmp(arg, "-connect")) { } else if (!strcmp(arg, "-connect")) {
CHECK_ARGC CHECK_ARGC
if (strchr(argv[++i], '/')) { if (strchr(argv[++i], '/')) {
...@@ -2239,8 +2218,11 @@ int main(int argc, char* argv[]) { ...@@ -2239,8 +2218,11 @@ int main(int argc, char* argv[]) {
listen_str = strdup(argv[i+1]); listen_str = strdup(argv[i+1]);
} }
/* otherwise copy it for libvncserver use below. */ /* otherwise copy it for libvncserver use below. */
if (argc_vnc < 100) { if (argc_vnc < argc_vnc_max) {
argv_vnc[argc_vnc++] = strdup(arg); argv_vnc[argc_vnc++] = strdup(arg);
} else {
rfbLog("too many arguments.\n");
exit(1);
} }
} }
} }
...@@ -2340,7 +2322,7 @@ int main(int argc, char* argv[]) { ...@@ -2340,7 +2322,7 @@ int main(int argc, char* argv[]) {
} }
} }
if (usepw && ! got_rfbauth && ! got_passwd && ! got_passwdfile) { if (usepw && ! got_rfbauth && ! got_passwd && ! got_passwdfile && !unixpw) {
char *f, *h = getenv("HOME"); char *f, *h = getenv("HOME");
struct stat sbuf; struct stat sbuf;
int found = 0, set_rfbauth = 0; int found = 0, set_rfbauth = 0;
...@@ -2523,7 +2505,11 @@ int main(int argc, char* argv[]) { ...@@ -2523,7 +2505,11 @@ int main(int argc, char* argv[]) {
" -unixpw\n"); " -unixpw\n");
rfbLog("mode, assuming your SSH encryption" rfbLog("mode, assuming your SSH encryption"
" is: %s\n", s); " is: %s\n", s);
rfbLog("Setting -localhost in SSH + -unixpw"
" mode.\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
allow_list = strdup("127.0.0.1");
got_localhost = 1;
if (! nopw) { if (! nopw) {
usleep(2000*1000); usleep(2000*1000);
} }
...@@ -2536,7 +2522,8 @@ int main(int argc, char* argv[]) { ...@@ -2536,7 +2522,8 @@ int main(int argc, char* argv[]) {
rfbLog("set -ssl in -unixpw mode.\n"); rfbLog("set -ssl in -unixpw mode.\n");
use_openssl = 1; use_openssl = 1;
} else if (inetd) { } else if (inetd) {
rfbLog("could not set -ssl in -inetd + -unixpw mode.\n"); rfbLog("could not set -ssl in -inetd"
" + -unixpw mode.\n");
exit(1); exit(1);
} else { } else {
rfbLog("set -stunnel in -unixpw mode.\n"); rfbLog("set -stunnel in -unixpw mode.\n");
......
...@@ -287,6 +287,7 @@ extern int h_errno; ...@@ -287,6 +287,7 @@ extern int h_errno;
__FreeBSD__ __FreeBSD__
__NetBSD__ __NetBSD__
__linux__ __linux__
(defined(__MACH__) && defined(__APPLE__))
_AIX _AIX
*/ */
......
...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0; ...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.2 lastmod: 2006-06-08"; char lastmod[] = "0.8.2 lastmod: 2006-06-12";
/* X display info */ /* X display info */
...@@ -150,4 +150,3 @@ char *program_cmdline = NULL; ...@@ -150,4 +150,3 @@ char *program_cmdline = NULL;
struct utsname UT; struct utsname UT;
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