From 76d88e31114b5cc0f66f90e76eb9c734bbc9bf4b Mon Sep 17 00:00:00 2001 From: runge Date: Sat, 5 May 2007 14:53:21 +0000 Subject: [PATCH] x11vnc: add groups handling for -users mode. --- configure.ac | 2 +- x11vnc/ChangeLog | 3 ++ x11vnc/README | 49 ++++++++++++++++++++++---------- x11vnc/help.c | 42 +++++++++++++++++++-------- x11vnc/options.c | 1 + x11vnc/options.h | 1 + x11vnc/user.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- x11vnc/x11vnc.1 | 48 ++++++++++++++++++++++--------- x11vnc/x11vnc.c | 50 ++++++++++++++++++++++++++++++++- x11vnc/x11vnc.h | 1 + x11vnc/x11vnc_defs.c | 2 +- 11 files changed, 220 insertions(+), 46 deletions(-) diff --git a/configure.ac b/configure.ac index f27fda6..1044987 100644 --- a/configure.ac +++ b/configure.ac @@ -548,7 +548,7 @@ if test "x$uname_s" = "xHP-UX"; then LDFLAGS="$LDFLAGS -lsec" fi -AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mmap mkfifo select socket strchr strcspn strdup strerror strstr setsid setpgrp getpwuid getpwnam getspnam getuid geteuid setuid setgid seteuid setegid waitpid setutxent grantpt]) +AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mmap mkfifo select socket strchr strcspn strdup strerror strstr setsid setpgrp getpwuid getpwnam getspnam getuid geteuid setuid setgid seteuid setegid initgroups waitpid setutxent grantpt]) # check, if shmget is in cygipc.a AC_CHECK_LIB(cygipc,shmget) diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog index b3d839d..b5875e0 100644 --- a/x11vnc/ChangeLog +++ b/x11vnc/ChangeLog @@ -1,3 +1,6 @@ +2007-05-05 Karl Runge + * x11vnc: add groups handling for -users mode. + 2007-05-01 Karl Runge * ssl: update to java viewer and utility scripts (add onetimekey). * x11vnc: setsid() for -gone mode. setpgrp for -create script and diff --git a/x11vnc/README b/x11vnc/README index 3fa8ac4..61b40f0 100644 --- a/x11vnc/README +++ b/x11vnc/README @@ -1,5 +1,5 @@ -x11vnc README file Date: Thu May 3 23:21:57 EDT 2007 +x11vnc README file Date: Sat May 5 10:47:52 EDT 2007 The following information is taken from these URLs: @@ -10747,7 +10747,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.9.1 lastmod: 2007-05-03 +x11vnc: allow VNC connections to real X11 displays. 0.9.1 lastmod: 2007-05-05 x11vnc options: -display disp -auth file -N @@ -10861,7 +10861,7 @@ libvncserver-tight-extension options: % x11vnc -help -x11vnc: allow VNC connections to real X11 displays. 0.9.1 lastmod: 2007-05-03 +x11vnc: allow VNC connections to real X11 displays. 0.9.1 lastmod: 2007-05-05 (type "x11vnc -opts" to just list the options.) @@ -12443,9 +12443,10 @@ Options: Since this option switches userid it also affects the userid used to run the processes for the -accept and -gone options. It also affects the ability to read - files for options such as -connect, -allow, and -remap. - Note that the -connect file is also sometimes written - to. + files for options such as -connect, -allow, and -remap + and also the ultra and tight filetransfer feature if + enabled. Note that the -connect file is also sometimes + written to. So be careful with this option since in some situations its use can decrease security. @@ -12454,9 +12455,10 @@ Options: if the display can still be successfully opened as that user (this is primarily to try to guess the actual owner of the session). Example: "-users fred,wilma,betty". - Note that a malicious user "barney" by quickly using - "xhost +" when logging in may possibly get the x11vnc - process to switch to user "fred". What happens next? + Note that a malicious local user "barney" by + quickly using "xhost +" when logging in may possibly + get the x11vnc process to switch to user "fred". + What happens next? Under display managers it may be a long time before the switch succeeds (i.e. a user logs in). To instead @@ -12468,29 +12470,46 @@ Options: "nobody") is probably the only use of this option that increases security. + Use the following notation to associate a group with + a user: user1.group1,user2.group2,... Note that + initgroups(2) will still be called first to try to + switch to ALL of a user's groups (primary and additional + groups). Only if that fails or it is not available + then the single group specified as above (or the user's + primary group if not specified) is switched to with + setgid(2). Use -env X11VNC_SINGLE_GROUP=1 to prevent + trying initgroups(2) and only switch to the single + group. This sort of setting is only really needed to + make the ultra or tight filetransfer permissions work + properly. This format applies to any comma separated lis +t + of users, even the special "=" modes described below. + In -unixpw mode, if "-users unixpw=" is supplied then after a user authenticates himself via the -unixpw mechanism, x11vnc will try to switch to that user as though "-users +username" had been supplied. If you want to limit which users this will be done for, provide them as a comma separated list after "unixpw=" + Groups can also be specified as described above. Similarly, in -ssl mode, if "-users sslpeer=" is supplied then after an SSL client authenticates with his cert (the -sslverify option is required for this) x11vnc will extract a UNIX username from the "emailAddress" - field (username@hostname.com) of the "Subject" in the + field (username@hostname.com) of the "Subject" of the x509 SSL cert and then try to switch to that user as though "-users +username" had been supplied. If you want to limit which users this will be done for, provide them as a comma separated list after "sslpeer=". Set the env. var X11VNC_SSLPEER_CN to use the Common Name (normally a hostname) instead of the Email field. - NOTE: the x11vnc administrator must take great care - that any client certs he adds to -sslverify have the - correct UNIX username in the "emailAddress" field - of the cert. Otherwise a user may be able to log in - as another. The following command can be of use in + + NOTE: for sslpeer= mode the x11vnc administrator must + take care that any client certs he adds to -sslverify + have the intended UNIX username in the "emailAddress" + field of the cert. Otherwise a user may be able to + log in as another. This command can be of use in checking: "openssl x509 -text -in file.crt", see the "Subject:" line. Also, along with the normal RFB_* env. vars. (see -accept) passed to external cmd= diff --git a/x11vnc/help.c b/x11vnc/help.c index 548d81f..b465773 100644 --- a/x11vnc/help.c +++ b/x11vnc/help.c @@ -1619,9 +1619,10 @@ void print_help(int mode) { " Since this option switches userid it also affects the\n" " userid used to run the processes for the -accept and\n" " -gone options. It also affects the ability to read\n" -" files for options such as -connect, -allow, and -remap.\n" -" Note that the -connect file is also sometimes written\n" -" to.\n" +" files for options such as -connect, -allow, and -remap\n" +" and also the ultra and tight filetransfer feature if\n" +" enabled. Note that the -connect file is also sometimes\n" +" written to.\n" "\n" " So be careful with this option since in some situations\n" " its use can decrease security.\n" @@ -1630,9 +1631,10 @@ void print_help(int mode) { " if the display can still be successfully opened as that\n" " user (this is primarily to try to guess the actual owner\n" " of the session). Example: \"-users fred,wilma,betty\".\n" -" Note that a malicious user \"barney\" by quickly using\n" -" \"xhost +\" when logging in may possibly get the x11vnc\n" -" process to switch to user \"fred\". What happens next?\n" +" Note that a malicious local user \"barney\" by\n" +" quickly using \"xhost +\" when logging in may possibly\n" +" get the x11vnc process to switch to user \"fred\".\n" +" What happens next?\n" "\n" " Under display managers it may be a long time before\n" " the switch succeeds (i.e. a user logs in). To instead\n" @@ -1644,29 +1646,45 @@ void print_help(int mode) { " \"nobody\") is probably the only use of this option\n" " that increases security.\n" "\n" +" Use the following notation to associate a group with\n" +" a user: user1.group1,user2.group2,... Note that\n" +" initgroups(2) will still be called first to try to\n" +" switch to ALL of a user's groups (primary and additional\n" +" groups). Only if that fails or it is not available\n" +" then the single group specified as above (or the user's\n" +" primary group if not specified) is switched to with\n" +" setgid(2). Use -env X11VNC_SINGLE_GROUP=1 to prevent\n" +" trying initgroups(2) and only switch to the single\n" +" group. This sort of setting is only really needed to\n" +" make the ultra or tight filetransfer permissions work\n" +" properly. This format applies to any comma separated list\n" +" of users, even the special \"=\" modes described below.\n" +"\n" " In -unixpw mode, if \"-users unixpw=\" is supplied\n" " then after a user authenticates himself via the\n" " -unixpw mechanism, x11vnc will try to switch to that\n" " user as though \"-users +username\" had been supplied.\n" " If you want to limit which users this will be done for,\n" " provide them as a comma separated list after \"unixpw=\"\n" +" Groups can also be specified as described above.\n" "\n" " Similarly, in -ssl mode, if \"-users sslpeer=\" is\n" " supplied then after an SSL client authenticates with his\n" " cert (the -sslverify option is required for this) x11vnc\n" " will extract a UNIX username from the \"emailAddress\"\n" -" field (username@hostname.com) of the \"Subject\" in the\n" +" field (username@hostname.com) of the \"Subject\" of the\n" " x509 SSL cert and then try to switch to that user as\n" " though \"-users +username\" had been supplied. If you\n" " want to limit which users this will be done for, provide\n" " them as a comma separated list after \"sslpeer=\".\n" " Set the env. var X11VNC_SSLPEER_CN to use the Common\n" " Name (normally a hostname) instead of the Email field.\n" -" NOTE: the x11vnc administrator must take great care\n" -" that any client certs he adds to -sslverify have the\n" -" correct UNIX username in the \"emailAddress\" field\n" -" of the cert. Otherwise a user may be able to log in\n" -" as another. The following command can be of use in\n" +"\n" +" NOTE: for sslpeer= mode the x11vnc administrator must\n" +" take care that any client certs he adds to -sslverify\n" +" have the intended UNIX username in the \"emailAddress\"\n" +" field of the cert. Otherwise a user may be able to\n" +" log in as another. This command can be of use in\n" " checking: \"openssl x509 -text -in file.crt\", see the\n" " \"Subject:\" line. Also, along with the normal RFB_*\n" " env. vars. (see -accept) passed to external cmd=\n" diff --git a/x11vnc/options.c b/x11vnc/options.c index a03e069..6c48b58 100644 --- a/x11vnc/options.c +++ b/x11vnc/options.c @@ -84,6 +84,7 @@ char *allowed_external_cmds = NULL; int started_as_root = 0; int host_lookup = 1; char *users_list = NULL; /* -users */ +char **user2group = NULL; char *allow_list = NULL; /* for -allow and -localhost */ char *listen_str = NULL; char *allow_once = NULL; /* one time -allow */ diff --git a/x11vnc/options.h b/x11vnc/options.h index 75feba4..6ac01a4 100644 --- a/x11vnc/options.h +++ b/x11vnc/options.h @@ -65,6 +65,7 @@ extern char *allowed_external_cmds; extern int started_as_root; extern int host_lookup; extern char *users_list; +extern char **user2group; extern char *allow_list; extern char *listen_str; extern char *allow_once; diff --git a/x11vnc/user.c b/x11vnc/user.c index 25d818a..4fe39ce 100644 --- a/x11vnc/user.c +++ b/x11vnc/user.c @@ -237,7 +237,7 @@ static char **user_list(char *user_str) { } static void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **home) { - int numerical = 1; + int numerical = 1, gotgroup = 0; char *q; *uid = (uid_t) -1; @@ -252,6 +252,46 @@ static void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **hom } } + if (user2group != NULL) { + static int *did = NULL; + int i; + + if (did == NULL) { + int n = 0; + i = 0; + while (user2group[i] != NULL) { + n++; + i++; + } + did = (int *) malloc((n+1) * sizeof(int)); + i = 0; + for (i=0; igr_gid; + if (! did[i]) { + rfbLog("user2uid: using group %s (%d) for %s\n", + w, (int) *gid, user); + did[i] = 1; + } + gotgroup = 1; + } + } + i++; + } + } + if (numerical) { int u = atoi(user); @@ -271,7 +311,9 @@ static void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **hom } if (pw) { *uid = pw->pw_uid; - *gid = pw->pw_gid; + if (! gotgroup) { + *gid = pw->pw_gid; + } *name = pw->pw_name; /* n.b. use immediately */ *home = pw->pw_dir; } @@ -650,6 +692,7 @@ static int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_ /* NO strtoks */ char *xauth; int reset_fb = 0; + int grp_ok = 0; #if !LIBVNCSERVER_HAVE_SETUID return 0; @@ -663,13 +706,31 @@ static int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_ clean_shm(0); free_tiles(); } - if (setgid(gid) != 0) { +#if LIBVNCSERVER_HAVE_INITGROUPS +#if LIBVNCSERVER_HAVE_PWD_H + if (getpwuid(uid) != NULL && getenv("X11VNC_SINGLE_GROUP") == NULL) { + struct passwd *p = getpwuid(uid); + if (initgroups(p->pw_name, gid) == 0) { + grp_ok = 1; + } else { + rfbLogPerror("initgroups"); + } + } +#endif +#endif + if (! grp_ok) { + if (setgid(gid) == 0) { + grp_ok = 1; + } + } + if (! grp_ok) { if (reset_fb) { /* 2 means we did clean_shm and free_tiles */ do_new_fb(2); } return 0; } + if (setuid(uid) != 0) { if (reset_fb) { /* 2 means we did clean_shm and free_tiles */ diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1 index 99305a7..462a9a7 100644 --- a/x11vnc/x11vnc.1 +++ b/x11vnc/x11vnc.1 @@ -2,7 +2,7 @@ .TH X11VNC "1" "May 2007" "x11vnc " "User Commands" .SH NAME x11vnc - allow VNC connections to real X11 displays - version: 0.9.1, lastmod: 2007-05-03 + version: 0.9.1, lastmod: 2007-05-05 .SH SYNOPSIS .B x11vnc [OPTION]... @@ -1842,9 +1842,10 @@ must be run as the user owning the desktop session. Since this option switches userid it also affects the userid used to run the processes for the \fB-accept\fR and \fB-gone\fR options. It also affects the ability to read -files for options such as \fB-connect,\fR \fB-allow,\fR and \fB-remap.\fR -Note that the \fB-connect\fR file is also sometimes written -to. +files for options such as \fB-connect,\fR \fB-allow,\fR and \fB-remap\fR +and also the ultra and tight filetransfer feature if +enabled. Note that the \fB-connect\fR file is also sometimes +written to. .IP So be careful with this option since in some situations its use can decrease security. @@ -1853,9 +1854,10 @@ In general the switch to a user will only take place if the display can still be successfully opened as that user (this is primarily to try to guess the actual owner of the session). Example: "\fB-users\fR \fIfred,wilma,betty\fR". -Note that a malicious user "barney" by quickly using -"xhost +" when logging in may possibly get the x11vnc -process to switch to user "fred". What happens next? +Note that a malicious local user "barney" by +quickly using "xhost +" when logging in may possibly +get the x11vnc process to switch to user "fred". +What happens next? .IP Under display managers it may be a long time before the switch succeeds (i.e. a user logs in). To instead @@ -1867,29 +1869,49 @@ The latter (i.e. switching immediately to user "nobody") is probably the only use of this option that increases security. .IP +Use the following notation to associate a group with +a user: user1.group1,user2.group2,... Note that +.IR initgroups (2) +will still be called first to try to +switch to ALL of a user's groups (primary and additional +groups). Only if that fails or it is not available +then the single group specified as above (or the user's +primary group if not specified) is switched to with +.IR setgid (2). +Use \fB-env\fR X11VNC_SINGLE_GROUP=1 to prevent +trying +.IR initgroups (2) +and only switch to the single +group. This sort of setting is only really needed to +make the ultra or tight filetransfer permissions work +properly. This format applies to any comma separated list +of users, even the special "=" modes described below. +.IP In \fB-unixpw\fR mode, if "\fB-users\fR \fIunixpw=\fR" is supplied then after a user authenticates himself via the \fB-unixpw\fR mechanism, x11vnc will try to switch to that user as though "\fB-users\fR \fI+username\fR" had been supplied. If you want to limit which users this will be done for, provide them as a comma separated list after "unixpw=" +Groups can also be specified as described above. .IP Similarly, in \fB-ssl\fR mode, if "\fB-users\fR \fIsslpeer=\fR" is supplied then after an SSL client authenticates with his cert (the \fB-sslverify\fR option is required for this) x11vnc will extract a UNIX username from the "emailAddress" -field (username@hostname.com) of the "Subject" in the +field (username@hostname.com) of the "Subject" of the x509 SSL cert and then try to switch to that user as though "\fB-users\fR \fI+username\fR" had been supplied. If you want to limit which users this will be done for, provide them as a comma separated list after "sslpeer=". Set the env. var X11VNC_SSLPEER_CN to use the Common Name (normally a hostname) instead of the Email field. -NOTE: the x11vnc administrator must take great care -that any client certs he adds to \fB-sslverify\fR have the -correct UNIX username in the "emailAddress" field -of the cert. Otherwise a user may be able to log in -as another. The following command can be of use in +.IP +NOTE: for sslpeer= mode the x11vnc administrator must +take care that any client certs he adds to \fB-sslverify\fR +have the intended UNIX username in the "emailAddress" +field of the cert. Otherwise a user may be able to +log in as another. This command can be of use in checking: "openssl x509 \fB-text\fR \fB-in\fR file.crt", see the "Subject:" line. Also, along with the normal RFB_* env. vars. (see \fB-accept)\fR passed to external cmd= diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c index b8733fc..b9abaf3 100644 --- a/x11vnc/x11vnc.c +++ b/x11vnc/x11vnc.c @@ -963,7 +963,7 @@ static void immediate_switch_user(int argc, char* argv[]) { } } for (i=1; i < argc; i++) { - char *u; + char *u, *q; if (strcmp(argv[i], "-users")) { continue; @@ -979,6 +979,13 @@ static void immediate_switch_user(int argc, char* argv[]) { /* wants an immediate switch: =bob */ u = strdup(argv[i+1]); *u = '+'; + q = strchr(u, '.'); + if (q) { + user2group = (char **) malloc(2*sizeof(char *)); + user2group[0] = strdup(u+1); + user2group[1] = NULL; + *q = '\0'; + } if (strstr(u, "+guess") == u) { fprintf(stderr, "invalid user: %s\n", u+1); exit(1); @@ -2934,6 +2941,47 @@ int main(int argc, char* argv[]) { launch_gui = 0; } + if (users_list && strchr(users_list, '.')) { + char *p, *q, *tmp = (char *) malloc(strlen(users_list)+1); + char *str = strdup(users_list); + int i, n, db = 1; + + tmp[0] = '\0'; + + n = strlen(users_list) + 1; + user2group = (char **) malloc(n * sizeof(char *)); + for (i=0; i +#include #endif #if LIBVNCSERVER_HAVE_SYS_WAIT_H #include diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c index ba12eea..a179f63 100644 --- a/x11vnc/x11vnc_defs.c +++ b/x11vnc/x11vnc_defs.c @@ -15,7 +15,7 @@ int xtrap_base_event_type = 0; int xdamage_base_event_type = 0; /* date +'lastmod: %Y-%m-%d' */ -char lastmod[] = "0.9.1 lastmod: 2007-05-03"; +char lastmod[] = "0.9.1 lastmod: 2007-05-05"; /* X display info */