From 454c1fad652bb9ce8bd4be030dddca887f9afc66 Mon Sep 17 00:00:00 2001
From: runge <runge>
Date: Sat, 24 Dec 2005 16:06:47 +0000
Subject:  x11vnc: enhance -passwdfile features, filetransfer on by default.

---
 ChangeLog        |   3 +
 x11vnc/ChangeLog |   4 +
 x11vnc/README    |  69 ++++++++++----
 x11vnc/x11vnc.1  |  70 +++++++++++----
 x11vnc/x11vnc.c  | 269 ++++++++++++++++++++++++++++++++++++++++---------------
 5 files changed, 312 insertions(+), 103 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b5e5a1a..abf2995 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2005-12-24  Karl Runge <runge@karlrunge.com>
+	* x11vnc: enhance -passwdfile features, filetransfer on by default.
+
 2005-12-19  Dave Stuart <dave@justdave.us>
 	* libvncserver/{main.c,rfbserver.c,cargs.c}, rfb/rfb.h: introduce
 	  deferPtrUpdateTime, which defers the handling of pointer events
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog
index d28a311..143987e 100644
--- a/x11vnc/ChangeLog
+++ b/x11vnc/ChangeLog
@@ -1,3 +1,7 @@
+2005-12-24  Karl Runge <runge@karlrunge.com>
+	* x11vnc: enhance -passwdfile features, filetransfer on by default,
+	  call rfbRegisterTightVNCFileTransferExtension() earlier.
+
 2005-11-28  Karl Runge <runge@karlrunge.com>
 	* x11vnc: add -loop option.
 
diff --git a/x11vnc/README b/x11vnc/README
index 6be4643..c63ef6a 100644
--- a/x11vnc/README
+++ b/x11vnc/README
@@ -1,5 +1,5 @@
 
-x11vnc README file                         Date: Mon Nov 28 10:42:40 EST 2005
+x11vnc README file                         Date: Sat Dec 24 10:14:27 EST 2005
 
 The following information is taken from these URLs:
 
@@ -4757,7 +4757,7 @@ x11vnc: a VNC server for real X displays
    Here are all of x11vnc command line options:
 % x11vnc -opts      (see below for -help long descriptions)
 
-x11vnc: allow VNC connections to real X11 displays. 0.7.3 lastmod: 2005-11-28
+x11vnc: allow VNC connections to real X11 displays. 0.7.3 lastmod: 2005-12-24
 
 x11vnc options:
   -display disp            -auth file             
@@ -4770,7 +4770,7 @@ x11vnc options:
   -shared                  -once                  
   -forever                 -loop                  
   -timeout n               -inetd                 
-  -filexfer                -http                  
+  -nofilexfer              -http                  
   -connect string          -vncconnect            
   -novncconnect            -allow host1[,host2..] 
   -localhost               -nolookup              
@@ -4845,6 +4845,7 @@ libvncserver options:
 -passwd plain-password use authentication 
                        (use plain-password as password, USE AT YOUR RISK)
 -deferupdate time      time in ms to defer updates (default 40)
+-deferptrupdate time   time in ms to defer pointer updates (default none)
 -desktop name          VNC desktop name (default "LibVNCServer")
 -alwaysshared          always treat new clients as shared
 -nevershared           never treat new clients as shared
@@ -4857,11 +4858,16 @@ libvncserver options:
 -listen ipaddr         listen for connections only on network interface with
                        addr ipaddr. '-listen localhost' and hostname work too.
 
+libvncserver-tight-extension options:
+-disablefiletransfer   disable file transfer
+-ftproot string        set ftp root
+
+
 
 
 % x11vnc -help
 
-x11vnc: allow VNC connections to real X11 displays. 0.7.3 lastmod: 2005-11-28
+x11vnc: allow VNC connections to real X11 displays. 0.7.3 lastmod: 2005-12-24
 
 Typical usage is:
 
@@ -5051,7 +5057,13 @@ Options:
                        option, otherwise the stderr goes to the viewer which
                        will cause it to abort.  Specifying both -inetd and -q
                        and no -o will automatically close the stderr.
--filexfer              Enable the TightVNC file transfer extension.
+-nofilexfer            Disable the TightVNC file transfer extension.  (same as
+                       -disablefiletransfer).  Note that when the -viewonly
+                       option is supplied all file transfers are disabled.
+                       Also clients that log in viewonly cannot transfer files.
+                       However, if the remote control mechanism is used to
+                       change the global or per-client viewonly state the
+                       filetransfer permissions will NOT change.
 -http                  Instead of using -httpdir (see below) to specify
                        where the Java vncviewer applet is, have x11vnc try
                        to *guess* where the directory is by looking relative
@@ -5114,18 +5126,40 @@ Options:
                        anything and enables view-only users to move the mouse.
                        This option is ignored when a global -viewonly is in
                        effect (all input is discarded in that case).
+
 -viewpasswd string     Supply a 2nd password for view-only logins.  The -passwd
                        (full-access) password must also be supplied.
--passwdfile filename   Specify libvncserver -passwd via the first line of the
-                       file "filename" instead of via command line (where
-                       others might see it via ps(1)).  If a second non blank
-                       line exists in the file it is taken as a view-only
-                       password (i.e. -viewpasswd) To supply an empty password
-                       for either field the string "__EMPTY__" may be used.
-                       Note: -passwdfile is a simple plaintext passwd, see
-                       also -rfbauth and -storepasswd below for obfuscated
-                       VNC password files.  Neither file should be readable
-                       by untrusted users.
+
+-passwdfile filename   Specify the libvncserver password via the first line
+                       of the file "filename" (instead of via -passwd on
+                       the command line where others might see it via ps(1)).
+
+                       If the filename is prefixed with "rm:" it will be
+                       removed after being read.  In general, the password file
+                       should not be readable by untrusted users (BTW: neither
+                       should the VNC -rfbauth file: it is NOT encrypted).
+
+                       Note that only the first 8 characters of a password
+                       are used.
+
+                       If multiple non-blank lines exist in the file they are
+                       all taken as valid passwords.  Blank lines are ignored.
+                       Password lines may be "commented out" (ignored) if
+                       they begin with the charactor "#" or the line contains
+                       the string "__SKIP__".  Lines may be annotated by use
+                       of the "__COMM__" string: from it to the end of the
+                       line is ignored.  An empty password may be specified
+                       via the "__EMPTY__" string on a line by itself (note
+                       your viewer might not accept empty passwords).
+
+                       If the string "__BEGIN_VIEWONLY__" appears on a
+                       line by itself, the remaining passwords are used for
+                       viewonly access.  For compatibility, as a special case
+                       if the file contains only two password lines the 2nd
+                       one is automatically taken as the viewonly password.
+                       Otherwise the "__BEGIN_VIEWONLY__" token must be used
+                       to have viewonly passwords.  (tip: make it the 3rd and
+                       last line to have 2 full-access passwords)
 -nopw                  Disable the big warning message when you use x11vnc
                        without some sort of password.
 -storepasswd pass file Store password "pass" as the VNC password in the
@@ -6758,6 +6792,7 @@ These options are passed to libvncserver:
 -passwd plain-password use authentication
                        (use plain-password as password, USE AT YOUR RISK)
 -deferupdate time      time in ms to defer updates (default 40)
+-deferptrupdate time   time in ms to defer pointer updates (default none)
 -desktop name          VNC desktop name (default "LibVNCServer")
 -alwaysshared          always treat new clients as shared
 -nevershared           never treat new clients as shared
@@ -6770,6 +6805,10 @@ These options are passed to libvncserver:
 -listen ipaddr         listen for connections only on network interface with
                        addr ipaddr. '-listen localhost' and hostname work too.
 
+libvncserver-tight-extension options:
+-disablefiletransfer   disable file transfer
+-ftproot string        set ftp root
+
    Pretty wild huh? [1]Contact me if you have any questions or problems.
 
    Personally, I use:
diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1
index 383bd9c..05f5cad 100644
--- a/x11vnc/x11vnc.1
+++ b/x11vnc/x11vnc.1
@@ -1,8 +1,8 @@
 .\" This file was automatically generated from x11vnc -help output.
-.TH X11VNC "1" "November 2005" "x11vnc " "User Commands"
+.TH X11VNC "1" "December 2005" "x11vnc " "User Commands"
 .SH NAME
 x11vnc - allow VNC connections to real X11 displays
-         version: 0.7.3, lastmod: 2005-11-28
+         version: 0.7.3, lastmod: 2005-12-24
 .SH SYNOPSIS
 .B x11vnc
 [OPTION]...
@@ -264,9 +264,15 @@ option, otherwise the stderr goes to the viewer which
 will cause it to abort.  Specifying both \fB-inetd\fR and \fB-q\fR
 and no \fB-o\fR will automatically close the stderr.
 .PP
-\fB-filexfer\fR
+\fB-nofilexfer\fR
 .IP
-Enable the TightVNC file transfer extension.
+Disable the TightVNC file transfer extension.  (same as
+\fB-disablefiletransfer).\fR  Note that when the \fB-viewonly\fR
+option is supplied all file transfers are disabled.
+Also clients that log in viewonly cannot transfer files.
+However, if the remote control mechanism is used to
+change the global or per-client viewonly state the
+filetransfer permissions will NOT change.
 .PP
 \fB-http\fR
 .IP
@@ -361,18 +367,38 @@ Supply a 2nd password for view-only logins.  The \fB-passwd\fR
 .PP
 \fB-passwdfile\fR \fIfilename\fR
 .IP
-Specify libvncserver \fB-passwd\fR via the first line of the
-file \fIfilename\fR instead of via command line (where
-others might see it via 
+Specify the libvncserver password via the first line
+of the file \fIfilename\fR (instead of via \fB-passwd\fR on
+the command line where others might see it via 
 .IR ps (1)
-).  If a second non blank
-line exists in the file it is taken as a view-only
-password (i.e. \fB-viewpasswd)\fR To supply an empty password
-for either field the string "__EMPTY__" may be used.
-Note: \fB-passwdfile\fR is a simple plaintext passwd, see
-also \fB-rfbauth\fR and \fB-storepasswd\fR below for obfuscated
-VNC password files.  Neither file should be readable
-by untrusted users.
+).
+.IP
+If the filename is prefixed with "rm:" it will be
+removed after being read.  In general, the password file
+should not be readable by untrusted users (BTW: neither
+should the VNC \fB-rfbauth\fR file: it is NOT encrypted).
+.IP
+Note that only the first 8 characters of a password
+are used.
+.IP
+If multiple non-blank lines exist in the file they are
+all taken as valid passwords.  Blank lines are ignored.
+Password lines may be "commented out" (ignored) if
+they begin with the charactor "#" or the line contains
+the string "__SKIP__".  Lines may be annotated by use
+of the "__COMM__" string: from it to the end of the
+line is ignored.  An empty password may be specified
+via the "__EMPTY__" string on a line by itself (note
+your viewer might not accept empty passwords).
+.IP
+If the string "__BEGIN_VIEWONLY__" appears on a
+line by itself, the remaining passwords are used for
+viewonly access.  For compatibility, as a special case
+if the file contains only two password lines the 2nd
+one is automatically taken as the viewonly password.
+Otherwise the "__BEGIN_VIEWONLY__" token must be used
+to have viewonly passwords.  (tip: make it the 3rd and
+last line to have 2 full-access passwords)
 .PP
 \fB-nopw\fR
 .IP
@@ -2534,6 +2560,10 @@ use authentication
 .IP
 time in ms to defer updates (default 40)
 .PP
+\fB-deferptrupdate\fR \fItime\fR
+.IP
+time in ms to defer pointer updates (default none)
+.PP
 \fB-desktop\fR \fIname\fR
 .IP
 VNC desktop name (default "LibVNCServer")
@@ -2571,6 +2601,16 @@ enable progressive updating for slow links
 .IP
 listen for connections only on network interface with
 addr ipaddr. '-listen localhost' and hostname work too.
+.PP
+libvncserver-tight-extension options:
+.PP
+\fB-disablefiletransfer\fR
+.IP
+disable file transfer
+.PP
+\fB-ftproot\fR \fIstring\fR
+.IP
+set ftp root
 .SH "FILES"
 .IR $HOME/.x11vncrc ,
 .IR $HOME/.Xauthority
diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c
index 9987ed8..c25d364 100644
--- a/x11vnc/x11vnc.c
+++ b/x11vnc/x11vnc.c
@@ -163,7 +163,7 @@
  * -DREMOTE_DEFAULT=0  to disable remote-control on by default (-yesremote).
  * -DREMOTE_CONTROL=0  to disable remote-control mechanism completely.
  * -DEXTERNAL_COMMANDS=0  to disable the running of all external commands.
- * -DFILEXFER=1  enable -filexfer as the default.
+ * -DFILEXFER=0  disable filexfer.
  *
  * -DHARDWIRE_PASSWD=...      hardwired passwords, quoting necessary.
  * -DHARDWIRE_VIEWPASSWD=...
@@ -398,7 +398,7 @@ double xdamage_scheduled_mark = 0.0;
 sraRegionPtr xdamage_scheduled_mark_region = NULL;
 
 /*               date +'lastmod: %Y-%m-%d' */
-char lastmod[] = "0.7.3 lastmod: 2005-11-28";
+char lastmod[] = "0.7.3 lastmod: 2005-12-24";
 int hack_val = 0;
 
 /* X display info */
@@ -866,9 +866,11 @@ char *allowed_input_view_only = NULL;
 char *allowed_input_normal = NULL;
 char *allowed_input_str = NULL;
 char *viewonly_passwd = NULL;	/* view only passwd. */
+char **passwd_list = NULL;	/* for -passwdfile */
+int begin_viewonly = -1;
 int inetd = 0;			/* spawned from inetd(1) */
 #ifndef FILEXFER
-#define FILEXFER 0
+#define FILEXFER 1
 #endif
 int filexfer = FILEXFER; 
 int first_conn_timeout = 0;	/* -timeout */
@@ -20433,11 +20435,6 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
 	screen->ptrAddEvent = pointer;
 	screen->setXCutText = xcut_receive;
 
-	if (filexfer) {
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
-		rfbRegisterTightVNCFileTransferExtension();
-#endif
-	}
 	rfbInitServer(screen);
 
 	if (viewonly_passwd) {
@@ -20448,6 +20445,16 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
 		passwds_new[1] = viewonly_passwd;
 		passwds_new[2] = NULL;
 		screen->authPasswdData = (void*) passwds_new;
+	} else if (passwd_list) {
+		int i = 0;
+		while(passwd_list[i] != NULL) {
+			i++;
+		}
+		if (begin_viewonly < 0) {
+			begin_viewonly = i+1;
+		}
+		screen->authPasswdData = (void*) passwd_list;
+		screen->authPasswdFirstViewOnly = begin_viewonly;
 	}
 }
 
@@ -30344,7 +30351,13 @@ static void print_help(int mode) {
 "                       option, otherwise the stderr goes to the viewer which\n"
 "                       will cause it to abort.  Specifying both -inetd and -q\n"
 "                       and no -o will automatically close the stderr.\n"
-"-filexfer              Enable the TightVNC file transfer extension.\n"
+"-nofilexfer            Disable the TightVNC file transfer extension.  (same as\n"
+"                       -disablefiletransfer).  Note that when the -viewonly\n"
+"                       option is supplied all file transfers are disabled.\n"
+"                       Also clients that log in viewonly cannot transfer files.\n"
+"                       However, if the remote control mechanism is used to\n"
+"                       change the global or per-client viewonly state the\n"
+"                       filetransfer permissions will NOT change.\n"
 "-http                  Instead of using -httpdir (see below) to specify\n"
 "                       where the Java vncviewer applet is, have x11vnc try\n"
 "                       to *guess* where the directory is by looking relative\n"
@@ -30407,18 +30420,41 @@ static void print_help(int mode) {
 "                       anything and enables view-only users to move the mouse.\n"
 "                       This option is ignored when a global -viewonly is in\n"
 "                       effect (all input is discarded in that case).\n"
+"\n"
 "-viewpasswd string     Supply a 2nd password for view-only logins.  The -passwd\n"
 "                       (full-access) password must also be supplied.\n"
-"-passwdfile filename   Specify libvncserver -passwd via the first line of the\n"
-"                       file \"filename\" instead of via command line (where\n"
-"                       others might see it via ps(1)).  If a second non blank\n"
-"                       line exists in the file it is taken as a view-only\n"
-"                       password (i.e. -viewpasswd) To supply an empty password\n"
-"                       for either field the string \"__EMPTY__\" may be used.\n"
-"                       Note: -passwdfile is a simple plaintext passwd, see\n"
-"                       also -rfbauth and -storepasswd below for obfuscated\n"
-"                       VNC password files.  Neither file should be readable\n"
-"                       by untrusted users.\n"
+"\n"
+"-passwdfile filename   Specify the libvncserver password via the first line\n"
+"                       of the file \"filename\" (instead of via -passwd on\n"
+"                       the command line where others might see it via ps(1)).\n"
+"\n"
+"                       If the filename is prefixed with \"rm:\" it will be\n"
+"                       removed after being read.  In general, the password file\n"
+"                       should not be readable by untrusted users (BTW: neither\n"
+"                       should the VNC -rfbauth file: it is NOT encrypted).\n"
+"\n"
+"                       Note that only the first 8 characters of a password\n"
+"                       are used.\n"
+"\n"
+"                       If multiple non-blank lines exist in the file they are\n"
+"                       all taken as valid passwords.  Blank lines are ignored.\n"
+"                       Password lines may be \"commented out\" (ignored) if\n"
+"                       they begin with the charactor \"#\" or the line contains\n"
+"                       the string \"__SKIP__\".  Lines may be annotated by use\n"
+"                       of the \"__COMM__\" string: from it to the end of the\n"
+"                       line is ignored.  An empty password may be specified\n"
+"                       via the \"__EMPTY__\" string on a line by itself (note\n"
+"                       your viewer might not accept empty passwords).\n"
+"\n"
+"                       If the string \"__BEGIN_VIEWONLY__\" appears on a\n"
+"                       line by itself, the remaining passwords are used for\n"
+"                       viewonly access.  For compatibility, as a special case\n"
+"                       if the file contains only two password lines the 2nd\n"
+"                       one is automatically taken as the viewonly password.\n"
+"                       Otherwise the \"__BEGIN_VIEWONLY__\" token must be used\n"
+"                       to have viewonly passwords.  (tip: make it the 3rd and\n"
+"                       last line to have 2 full-access passwords)\n"
+
 "-nopw                  Disable the big warning message when you use x11vnc\n"
 "                       without some sort of password.\n"
 "-storepasswd pass file Store password \"pass\" as the VNC password in the\n"
@@ -32062,6 +32098,11 @@ static void print_help(int mode) {
 	/* have both our help and rfbUsage to stdout for more(1), etc. */
 	dup2(1, 2);
 
+	/* register extention(s) to get their help output */
+#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
+	rfbRegisterTightVNCFileTransferExtension();
+#endif
+
 	if (mode == 1) {
 		char *p;	
 		int l = 0;
@@ -33116,6 +33157,8 @@ int main(int argc, char* argv[]) {
 			users_list = strdup(argv[++i]);
 		} else if (!strcmp(arg, "-inetd")) {
 			inetd = 1;
+		} else if (!strcmp(arg, "-nofilexfer")) {
+			filexfer = 0;
 		} else if (!strcmp(arg, "-filexfer")) {
 			filexfer = 1;
 		} else if (!strcmp(arg, "-http")) {
@@ -33737,6 +33780,16 @@ int main(int argc, char* argv[]) {
 		}
 	}
 
+	if (got_rfbauth && (got_passwd || got_viewpasswd || got_passwdfile)) {
+		fprintf(stderr, "option -rfbauth is incompatible with:\n");
+		fprintf(stderr, "            -passwd, -viewpasswd, and -passwdfile\n");
+		exit(1);
+	}
+	if (got_passwdfile && (got_passwd || got_viewpasswd)) {
+		fprintf(stderr, "option -passwdfile is incompatible with:\n");
+		fprintf(stderr, "            -passwd and -viewpasswd\n");
+		exit(1);
+	}
 
 	/*
 	 * If -passwd was used, clear it out of argv.  This does not
@@ -33753,72 +33806,129 @@ int main(int argc, char* argv[]) {
 			}
 		}
 	} else if (passwdfile) {
-		/* read passwd from file */
+		/* read passwd(s) from file */
 		char line[1024];
+		char *filename;
+		int remove = 0;
+		struct stat sbuf;
+		int linecount = 0, i, max;
 		FILE *in;
-		in = fopen(passwdfile, "r");
+
+		filename = passwdfile;
+		if (strstr(filename, "rm:") == filename) {
+			filename += strlen("rm:");
+			remove = 1;
+		}
+
+		if (stat(filename, &sbuf) == 0) {
+			/* upper bound to number of lines... */
+			max = (int) sbuf.st_size;
+		} else {
+			max = 16;
+		}
+
+		/* create 1 more than max to have it be the ending NULL */
+		passwd_list = (char **) malloc( (max+1) * (sizeof(char *)) );
+		for (i=0; i<max+1; i++) {
+			passwd_list[i] = NULL;
+		}
+		
+		in = fopen(filename, "r");
 		if (in == NULL) {
 			rfbLog("cannot open passwdfile: %s\n", passwdfile);
 			rfbLogPerror("fopen");
+			if (remove) {
+				unlink(filename);
+			}
 			exit(1);
 		}
-		if (fgets(line, 1024, in) != NULL) {
-			char *q;
+
+		while (fgets(line, 1024, in) != NULL) {
+			char *p;
+			int blank = 1;
 			int len = strlen(line); 
-			if (len > 0 && line[len-1] == '\n') {
+
+			if (len == 0) {
+				continue;
+			} else if (line[len-1] == '\n') {
 				line[len-1] = '\0';
 			}
-			argv_vnc[argc_vnc++] = strdup("-passwd");
-			got_passwd = 1;
-			if (!strcmp(line, "__EMPTY__")) {
-				argv_vnc[argc_vnc++] = strdup("");
-			} else if ((q = strstr(line, "__ENDPASSWD__")) !=NULL) {
-				*q = '\0';
-				argv_vnc[argc_vnc++] = strdup(line);
-			} else {
-				argv_vnc[argc_vnc++] = strdup(line);
+			if (line[0] == '\0') {
+				continue;
 			}
-			pw_loc = 100;	/* just for pw_loc check below */
-			if (fgets(line, 1024, in) != NULL) {
-				/* try to read viewonly passwd from file */
-				int ok = 0;
-				len = strlen(line); 
-				if (len > 0 && line[len-1] == '\n') {
-					line[len-1] = '\0';
-				}
-				if (strlen(line) > 0) {
-					char *p = line;
-					/* check for non-blank line */
-					while (*p != '\0') {
-						if (! isspace(*p)) {
-							ok = 1;
-						}
-						p++;
-					}
+			if (strstr(line, "__SKIP__") != NULL) {
+				continue;
+			}
+			if (strstr(line, "__COMM__") == line) {
+				continue;
+			}
+			if (!strcmp(line, "__BEGIN_VIEWONLY__")) {
+				if (begin_viewonly < 0) {
+					begin_viewonly = linecount;
 				}
-				if (ok) {
-					if (!strcmp(line, "__EMPTY__")) {
-						viewonly_passwd = strdup("");
-					} else if ((q = strstr(line,
-					    "__ENDPASSWD__")) != NULL) {
-						*q = '\0';
-						viewonly_passwd = strdup(line);
-					} else {
-						viewonly_passwd = strdup(line);
-					}
-				} else {
-					rfbLog("*** not setting"
-					    " viewonly password to the 2nd"
-					    " line of %s. (blank or other"
-					    " problem)\n", passwdfile);
+				continue;
+			}
+			if (line[0] == '#') {
+				/* commented out, cannot have password beginning with # */
+				continue;
+			}
+			p = line;
+			while (*p != '\0') {
+				if (! isspace(*p)) {
+					blank = 0;
+					break;
 				}
+				p++;
 			}
-		} else {
-			rfbLog("cannot read a line from passwdfile: %s\n",
+			if (blank) {
+				continue;
+			}
+
+			passwd_list[linecount++] = strdup(line);
+
+			if (linecount >= max) {
+				break;
+			}
+		}
+		fclose(in);
+
+		for (i=0; i<1024; i++) {
+			line[i] = '\0';
+		}
+
+		if (remove) {
+			unlink(filename);
+		}
+
+		if (! linecount) {
+			rfbLog("cannot read a valid line from passwdfile: %s\n",
 			    passwdfile);
 			exit(1);
 		}
-		fclose(in);
+
+		for (i=0; i<linecount; i++) {
+			char *q, *p = passwd_list[i];
+			if (!strcmp(p, "__EMPTY__")) {
+				*p = '\0';
+			} else if ((q = strstr(p, "__COMM__")) != NULL) {
+				*q = '\0';
+			}
+			passwd_list[i] = strdup(p);
+			while (*p != '\0') {
+				*p = '\0'; p++;
+			}
+		}
+		argv_vnc[argc_vnc++] = strdup("-passwd");
+		argv_vnc[argc_vnc++] = strdup(passwd_list[0]);
+		got_passwd = 1;
+		pw_loc = 100;	/* just for pw_loc check below */
+
+		if (begin_viewonly < 0 && linecount == 2) {
+			/* for compatibility with previous 2-line usage: */
+			viewonly_passwd = strdup(passwd_list[1]);
+			begin_viewonly = 1;
+		}
+
 	}
 	if (vpw_loc > 0) {
 		int i;
@@ -33832,7 +33942,7 @@ int main(int argc, char* argv[]) {
 		}
 	} 
 #ifdef HARDWIRE_PASSWD
-	if (! got_rfbauth && ! got_passwd) {
+	if (!got_rfbauth && !got_passwd) {
 		argv_vnc[argc_vnc++] = strdup("-passwd");
 		argv_vnc[argc_vnc++] = strdup(HARDWIRE_PASSWD);
 		got_passwd = 1;
@@ -33840,7 +33950,7 @@ int main(int argc, char* argv[]) {
 	}
 #endif
 #ifdef HARDWIRE_VIEWPASSWD
-	if (! got_rfbauth && got_passwd && ! viewonly_passwd) {
+	if (!got_rfbauth && got_passwd && !viewonly_passwd && !passwd_list) {
 		viewonly_passwd = strdup(HARDWIRE_VIEWPASSWD);
 	}
 #endif
@@ -33849,8 +33959,8 @@ int main(int argc, char* argv[]) {
 		exit(1);
 	}
 
-	if (!got_passwd && !got_rfbauth && !got_passwdfile &&
-	    !query_cmd && !remote_cmd) {
+	if (!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list)
+	    && !query_cmd && !remote_cmd) {
 		char message[] =
 		    "-rfbauth, -passwdfile, or -passwd password required.";
 		if (! nopw) {
@@ -33866,7 +33976,7 @@ int main(int argc, char* argv[]) {
 			exit(1);
 		}
 #endif
-		if (0) message[0] = '\0';
+		message[0] = '\0';	/* avoid compiler warning */
 	}
 
 	if (more_safe) {
@@ -33914,6 +34024,13 @@ int main(int argc, char* argv[]) {
 		alpha_remove = 0;
 	}
 
+	if (filexfer && view_only) {
+		if (! quiet) {
+			rfbLog("setting -nofilexfer in -viewonly mode.\n");
+		}
+		filexfer = 0;
+	}
+
 	if (inetd) {
 		shared = 0;
 		connect_once = 1;
@@ -34427,6 +34544,12 @@ int main(int argc, char* argv[]) {
 	}
 #endif
 
+	if (filexfer) {
+#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
+		rfbRegisterTightVNCFileTransferExtension();
+#endif
+	}
+
 	if (! quiet) {
 		rfbLog("--------------------------------------------------------\n");
 		rfbLog("\n");
-- 
cgit v1.2.3

