Commit 76d88e31 authored by runge's avatar runge

x11vnc: add groups handling for -users mode.

parent 6378acec
......@@ -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)
......
2007-05-05 Karl Runge <runge@karlrunge.com>
* x11vnc: add groups handling for -users mode.
2007-05-01 Karl Runge <runge@karlrunge.com>
* ssl: update to java viewer and utility scripts (add onetimekey).
* x11vnc: setsid() for -gone mode. setpgrp for -create script and
......
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=
......
......@@ -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"
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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; i<n; i++) {
did[i] = 0;
}
}
i = 0;
while (user2group[i] != NULL) {
if (strstr(user2group[i], user) == user2group[i]) {
char *w = user2group[i] + strlen(user);
if (*w == '.') {
struct group* gr = getgrnam(++w);
if (! gr) {
rfbLog("Invalid group: %s\n", w);
clean_up_exit(1);
}
*gid = gr->gr_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;
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 */
......
......@@ -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=
......
......@@ -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<n; i++) {
user2group[i] = NULL;
}
i = 0;
p = strtok(str, ",");
if (db) fprintf(stderr, "users_list: %s\n", users_list);
while (p) {
if (tmp[0] != '\0') {
strcat(tmp, ",");
}
q = strchr(p, '.');
if (q) {
char *s = strchr(p, '=');
if (! s) {
s = p;
} else {
s++;
}
if (s[0] == '+') s++;
user2group[i++] = strdup(s);
if (db) fprintf(stderr, "u2g: %s\n", s);
*q = '\0';
}
strcat(tmp, p);
p = strtok(NULL, ",");
}
free(str);
users_list = tmp;
if (db) fprintf(stderr, "users_list: %s\n", users_list);
}
if (unixpw) {
if (inetd) {
use_stunnel = 0;
......
......@@ -260,6 +260,7 @@ extern int h_errno;
#if LIBVNCSERVER_HAVE_PWD_H
#include <pwd.h>
#include <grp.h>
#endif
#if LIBVNCSERVER_HAVE_SYS_WAIT_H
#include <sys/wait.h>
......
......@@ -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 */
......
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