Commit a7726a6f authored by runge's avatar runge

x11vnc: more -unixpw work. add -license, etc. options

parent 99921601
2006-07-04 Karl Runge <runge@karlrunge.com>
* configure.ac: add getspnam.
2006-06-08 Karl Runge <runge@karlrunge.com> 2006-06-08 Karl Runge <runge@karlrunge.com>
* prepare_x11vnc_dist.sh: to 0.8.2 * prepare_x11vnc_dist.sh: to 0.8.2
......
...@@ -445,7 +445,7 @@ AC_FUNC_VPRINTF ...@@ -445,7 +445,7 @@ AC_FUNC_VPRINTF
AC_FUNC_FORK AC_FUNC_FORK
AC_CHECK_LIB(nsl,gethostbyname) AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_LIB(socket,socket) AC_CHECK_LIB(socket,socket)
AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mmap mkfifo select socket strchr strcspn strdup strerror strstr setsid setpgrp getpwuid getpwnam 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 waitpid setutxent grantpt])
# check, if shmget is in cygipc.a # check, if shmget is in cygipc.a
AC_CHECK_LIB(cygipc,shmget) AC_CHECK_LIB(cygipc,shmget)
......
2006-07-04 Karl Runge <runge@karlrunge.com>
* x11vnc: 2nd -accept popup with WAIT, and UNIX: info for unixpw
login. Use RFB_CLIENT_ON_HOLD for -unixpw. -unixpw white arrow
-license option. Use getspnam if getpwnam is short.
abbrevs sc=, cm, ck for user:opts.
2006-06-23 Karl Runge <runge@karlrunge.com> 2006-06-23 Karl Runge <runge@karlrunge.com>
* x11vnc: misc cleanup. * x11vnc: misc cleanup.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -48,6 +48,7 @@ void start_client_info_sock(char *host_port_cookie); ...@@ -48,6 +48,7 @@ void start_client_info_sock(char *host_port_cookie);
void send_client_info(char *str); void send_client_info(char *str);
void adjust_grabs(int grab, int quiet); void adjust_grabs(int grab, int quiet);
void check_new_clients(void); void check_new_clients(void);
int accept_client(rfbClientPtr client);
static rfbClientPtr *client_match(char *str); static rfbClientPtr *client_match(char *str);
...@@ -58,7 +59,6 @@ static void ugly_geom(char *p, int *x, int *y); ...@@ -58,7 +59,6 @@ static void ugly_geom(char *p, int *x, int *y);
static int ugly_window(char *addr, char *userhost, int X, int Y, static int ugly_window(char *addr, char *userhost, int X, int Y,
int timeout, char *mode, int accept); int timeout, char *mode, int accept);
static int action_match(char *action, int rc); static int action_match(char *action, int rc);
static int accept_client(rfbClientPtr client);
static void check_connect_file(char *file); static void check_connect_file(char *file);
static void send_client_connect(void); static void send_client_connect(void);
...@@ -133,7 +133,11 @@ char *list_clients(void) { ...@@ -133,7 +133,11 @@ char *list_clients(void) {
char *s = ident_username(cl); char *s = ident_username(cl);
if (s) free(s); if (s) free(s);
} }
if (strstr(cd->username, "UNIX:") == cd->username) {
strcat(list, cd->username + strlen("UNIX:"));
} else {
strcat(list, cd->username); strcat(list, cd->username);
}
strcat(list, ":"); strcat(list, ":");
if (cd->unixname[0] == '\0') { if (cd->unixname[0] == '\0') {
strcat(list, "none"); strcat(list, "none");
...@@ -996,7 +1000,15 @@ static unsigned char t2x2_bits[] = { ...@@ -996,7 +1000,15 @@ static unsigned char t2x2_bits[] = {
XFlush_wr(dpy); XFlush_wr(dpy);
if (accept) { if (accept) {
snprintf(strh, 100, "x11vnc: accept connection from %s?", addr); char *ip = addr;
char *type = "accept";
if (unixpw && strstr(userhost, "UNIX:") != userhost) {
type = "unixpw";
if (openssl_last_ip) {
ip = openssl_last_ip;
}
}
snprintf(strh, 100, "x11vnc: %s connection from %s?", type, ip);
} else { } else {
snprintf(strh, 100, "x11vnc: client disconnected from %s", addr); snprintf(strh, 100, "x11vnc: client disconnected from %s", addr);
} }
...@@ -1282,7 +1294,7 @@ static void ugly_geom(char *p, int *x, int *y) { ...@@ -1282,7 +1294,7 @@ static void ugly_geom(char *p, int *x, int *y) {
* popup: use internal X widgets for prompting. * popup: use internal X widgets for prompting.
* *
*/ */
static int accept_client(rfbClientPtr client) { int accept_client(rfbClientPtr client) {
char xmessage[200], *cmd = NULL; char xmessage[200], *cmd = NULL;
char *addr = client->host; char *addr = client->host;
...@@ -1327,6 +1339,14 @@ static int accept_client(rfbClientPtr client) { ...@@ -1327,6 +1339,14 @@ static int accept_client(rfbClientPtr client) {
mode = "both"; mode = "both";
} }
if (dpy == NULL && use_dpy && strstr(use_dpy, "WAIT:") ==
use_dpy) {
rfbLog("accept_client: warning allowing client under conditions:\n");
rfbLog(" -display WAIT:, dpy == NULL, -accept popup.\n");
rfbLog(" There will be another popup.\n");
return 1;
}
rfbLog("accept_client: using builtin popup for: %s\n", addr); rfbLog("accept_client: using builtin popup for: %s\n", addr);
if ((ret = ugly_window(addr, userhost, x, y, timeout, if ((ret = ugly_window(addr, userhost, x, y, timeout,
mode, 1))) { mode, 1))) {
...@@ -1526,6 +1546,7 @@ static int do_reverse_connect(char *str) { ...@@ -1526,6 +1546,7 @@ static int do_reverse_connect(char *str) {
rfbLog("reverse connections disabled in -ssl mode.\n"); rfbLog("reverse connections disabled in -ssl mode.\n");
return 0; return 0;
} }
if (unixpw_in_progress) return 0;
/* copy in to host */ /* copy in to host */
host = (char *) malloc(len+1); host = (char *) malloc(len+1);
...@@ -1579,11 +1600,15 @@ static int do_reverse_connect(char *str) { ...@@ -1579,11 +1600,15 @@ static int do_reverse_connect(char *str) {
* Break up comma separated list of hosts and call do_reverse_connect() * Break up comma separated list of hosts and call do_reverse_connect()
*/ */
void reverse_connect(char *str) { void reverse_connect(char *str) {
char *p, *tmp = strdup(str); char *p, *tmp;
int sleep_between_host = 300; int sleep_between_host = 300;
int sleep_min = 1500, sleep_max = 4500, n_max = 5; int sleep_min = 1500, sleep_max = 4500, n_max = 5;
int n, tot, t, dt = 100, cnt = 0; int n, tot, t, dt = 100, cnt = 0;
if (unixpw_in_progress) return;
tmp = strdup(str);
p = strtok(tmp, ", \t\r\n"); p = strtok(tmp, ", \t\r\n");
while (p) { while (p) {
if ((n = do_reverse_connect(p)) != 0) { if ((n = do_reverse_connect(p)) != 0) {
...@@ -1887,7 +1912,6 @@ enum rfbNewClientAction new_client(rfbClientPtr client) { ...@@ -1887,7 +1912,6 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
last_event = last_input = time(NULL); last_event = last_input = time(NULL);
if (inetd) { if (inetd) {
/* /*
* Set this so we exit as soon as connection closes, * Set this so we exit as soon as connection closes,
...@@ -2010,6 +2034,12 @@ if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid); ...@@ -2010,6 +2034,12 @@ if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid);
unixpw_last_try_time = time(NULL); unixpw_last_try_time = time(NULL);
unixpw_screen(1); unixpw_screen(1);
unixpw_keystroke(0, 0, 1); unixpw_keystroke(0, 0, 1);
if (!unixpw_in_rfbPE) {
rfbLog("new client: %s in non-unixpw_in_rfbPE.\n",
client->host);
}
/* always put client on hold even if unixpw_in_rfbPE is true */
return(RFB_CLIENT_ON_HOLD);
} }
return(RFB_CLIENT_ACCEPT); return(RFB_CLIENT_ACCEPT);
......
...@@ -31,5 +31,6 @@ extern void start_client_info_sock(char *host_port_cookie); ...@@ -31,5 +31,6 @@ extern void start_client_info_sock(char *host_port_cookie);
extern void send_client_info(char *str); extern void send_client_info(char *str);
extern void adjust_grabs(int grab, int quiet); extern void adjust_grabs(int grab, int quiet);
extern void check_new_clients(void); extern void check_new_clients(void);
extern int accept_client(rfbClientPtr client);
#endif /* _X11VNC_CONNECTIONS_H */ #endif /* _X11VNC_CONNECTIONS_H */
...@@ -30,6 +30,7 @@ int cursor_shape_updates_clients(rfbScreenInfoPtr s); ...@@ -30,6 +30,7 @@ int cursor_shape_updates_clients(rfbScreenInfoPtr s);
int cursor_pos_updates_clients(rfbScreenInfoPtr s); int cursor_pos_updates_clients(rfbScreenInfoPtr s);
void cursor_position(int x, int y); void cursor_position(int x, int y);
void set_no_cursor(void); void set_no_cursor(void);
void set_warrow_cursor(void);
int set_cursor(int x, int y, int which); int set_cursor(int x, int y, int which);
int check_x11_pointer(void); int check_x11_pointer(void);
...@@ -490,6 +491,7 @@ enum cursor_names { ...@@ -490,6 +491,7 @@ enum cursor_names {
CURS_DOT, CURS_DOT,
CURS_ARROW, CURS_ARROW,
CURS_WARROW,
CURS_ROOT, CURS_ROOT,
CURS_WM, CURS_WM,
CURS_TERM, CURS_TERM,
...@@ -657,6 +659,7 @@ static void setup_cursors(void) { ...@@ -657,6 +659,7 @@ static void setup_cursors(void) {
alt_arrow = 1; alt_arrow = 1;
curs_copy(cursors[CURS_ARROW], &cur_arrow); n++; curs_copy(cursors[CURS_ARROW], &cur_arrow); n++;
} }
curs_copy(cursors[CURS_WARROW], &cur_arrow2); n++;
curs_copy(cursors[CURS_ROOT], &cur_root); n++; curs_copy(cursors[CURS_ROOT], &cur_root); n++;
curs_copy(cursors[CURS_WM], &cur_fleur); n++; curs_copy(cursors[CURS_WM], &cur_fleur); n++;
...@@ -1744,6 +1747,10 @@ void set_no_cursor(void) { ...@@ -1744,6 +1747,10 @@ void set_no_cursor(void) {
set_rfb_cursor(CURS_EMPTY); set_rfb_cursor(CURS_EMPTY);
} }
void set_warrow_cursor(void) {
set_rfb_cursor(CURS_WARROW);
}
int set_cursor(int x, int y, int which) { int set_cursor(int x, int y, int which) {
static int last = -1; static int last = -1;
int changed_cursor = 0; int changed_cursor = 0;
......
...@@ -27,6 +27,7 @@ extern int cursor_shape_updates_clients(rfbScreenInfoPtr s); ...@@ -27,6 +27,7 @@ extern int cursor_shape_updates_clients(rfbScreenInfoPtr s);
extern int cursor_pos_updates_clients(rfbScreenInfoPtr s); extern int cursor_pos_updates_clients(rfbScreenInfoPtr s);
extern void cursor_position(int x, int y); extern void cursor_position(int x, int y);
extern void set_no_cursor(void); extern void set_no_cursor(void);
extern void set_warrow_cursor(void);
extern int set_cursor(int x, int y, int which); extern int set_cursor(int x, int y, int which);
extern int check_x11_pointer(void); extern int check_x11_pointer(void);
......
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
/* -- help.h -- */ /* -- help.h -- */
extern void print_help(int mode); extern void print_help(int mode);
extern void print_license(void);
extern void xopen_display_fail_message(char *disp); extern void xopen_display_fail_message(char *disp);
extern void nopassword_warning_msg(int gotloc); extern void nopassword_warning_msg(int gotloc);
......
/* -- inet.c -- */ /* -- inet.c -- */
#include "x11vnc.h" #include "x11vnc.h"
#include "unixpw.h"
#include "sslhelper.h"
/* /*
* Simple utility to map host name to dotted IP address. Ignores aliases. * Simple utility to map host name to dotted IP address. Ignores aliases.
...@@ -22,7 +24,6 @@ int have_ssh_env(void); ...@@ -22,7 +24,6 @@ int have_ssh_env(void);
static int get_port(int sock, int remote); static int get_port(int sock, int remote);
static char *get_host(int sock, int remote); static char *get_host(int sock, int remote);
char *host2ip(char *host) { char *host2ip(char *host) {
struct hostent *hp; struct hostent *hp;
struct sockaddr_in addr; struct sockaddr_in addr;
...@@ -291,7 +292,11 @@ char *ident_username(rfbClientPtr client) { ...@@ -291,7 +292,11 @@ char *ident_username(rfbClientPtr client) {
if (!strcmp(user, "unknown-user") && cd && cd->unixname[0] != '\0') { if (!strcmp(user, "unknown-user") && cd && cd->unixname[0] != '\0') {
user = cd->unixname; user = cd->unixname;
} }
if (unixpw && openssl_last_ip && strstr("UNIX:", user) != user) {
newhost = ip2host(openssl_last_ip);
} else {
newhost = ip2host(client->host); newhost = ip2host(client->host);
}
len = strlen(user) + 1 + strlen(newhost) + 1; len = strlen(user) + 1 + strlen(newhost) + 1;
str = (char *) malloc(len); str = (char *) malloc(len);
sprintf(str, "%s@%s", user, newhost); sprintf(str, "%s@%s", user, newhost);
......
...@@ -617,7 +617,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) { ...@@ -617,7 +617,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
last_x = x; last_x = x;
last_y = y; last_y = y;
} }
if (mask >= 0 && unixpw && unixpw_in_progress) { if (unixpw && unixpw_in_progress) {
return; return;
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "userinput.h" #include "userinput.h"
#include "keyboard.h" #include "keyboard.h"
#include "selection.h" #include "selection.h"
#include "unixpw.h"
int send_remote_cmd(char *cmd, int query, int wait); int send_remote_cmd(char *cmd, int query, int wait);
int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync, int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
...@@ -633,6 +634,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -633,6 +634,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote commands disabled: %s\n", cmd); rfbLog("remote commands disabled: %s\n", cmd);
return NULL; return NULL;
} }
if (unixpw_in_progress) {
rfbLog("skip remote command: %s unixpw_in_progress.\n", cmd);
return NULL;
}
if (!query_default && priv_remote) { if (!query_default && priv_remote) {
if (! remote_control_access_ok()) { if (! remote_control_access_ok()) {
......
...@@ -1294,6 +1294,8 @@ static int copy_tiles(int tx, int ty, int nt) { ...@@ -1294,6 +1294,8 @@ static int copy_tiles(int tx, int ty, int nt) {
char *src, *dst, *s_src, *s_dst, *m_src, *m_dst; char *src, *dst, *s_src, *s_dst, *m_src, *m_dst;
char *h_src, *h_dst; char *h_src, *h_dst;
if (unixpw_in_progress) return 0;
if (! first_line) { if (! first_line) {
/* allocate arrays first time in. */ /* allocate arrays first time in. */
int n = ntiles_x + 1; int n = ntiles_x + 1;
...@@ -1626,6 +1628,8 @@ static int copy_all_tiles(void) { ...@@ -1626,6 +1628,8 @@ static int copy_all_tiles(void) {
int x, y, n, m; int x, y, n, m;
int diffs = 0, ct; int diffs = 0, ct;
if (unixpw_in_progress) return 0;
for (y=0; y < ntiles_y; y++) { for (y=0; y < ntiles_y; y++) {
for (x=0; x < ntiles_x; x++) { for (x=0; x < ntiles_x; x++) {
n = x + y * ntiles_x; n = x + y * ntiles_x;
...@@ -1672,6 +1676,8 @@ static int copy_all_tile_runs(void) { ...@@ -1672,6 +1676,8 @@ static int copy_all_tile_runs(void) {
int in_run = 0, run = 0; int in_run = 0, run = 0;
int ntave = 0, ntcnt = 0; int ntave = 0, ntcnt = 0;
if (unixpw_in_progress) return 0;
for (y=0; y < ntiles_y; y++) { for (y=0; y < ntiles_y; y++) {
for (x=0; x < ntiles_x + 1; x++) { for (x=0; x < ntiles_x + 1; x++) {
n = x + y * ntiles_x; n = x + y * ntiles_x;
...@@ -1742,6 +1748,8 @@ static int copy_tiles_backward_pass(void) { ...@@ -1742,6 +1748,8 @@ static int copy_tiles_backward_pass(void) {
int x, y, n, m; int x, y, n, m;
int diffs = 0, ct; int diffs = 0, ct;
if (unixpw_in_progress) return 0;
for (y = ntiles_y - 1; y >= 0; y--) { for (y = ntiles_y - 1; y >= 0; y--) {
for (x = ntiles_x - 1; x >= 0; x--) { for (x = ntiles_x - 1; x >= 0; x--) {
n = x + y * ntiles_x; /* number of this tile */ n = x + y * ntiles_x; /* number of this tile */
...@@ -1783,6 +1791,8 @@ static int copy_tiles_additional_pass(void) { ...@@ -1783,6 +1791,8 @@ static int copy_tiles_additional_pass(void) {
int x, y, n; int x, y, n;
int diffs = 0, ct; int diffs = 0, ct;
if (unixpw_in_progress) return 0;
for (y=0; y < ntiles_y; y++) { for (y=0; y < ntiles_y; y++) {
for (x=0; x < ntiles_x; x++) { for (x=0; x < ntiles_x; x++) {
n = x + y * ntiles_x; /* number of this tile */ n = x + y * ntiles_x; /* number of this tile */
...@@ -1974,6 +1984,7 @@ int copy_screen(void) { ...@@ -1974,6 +1984,7 @@ int copy_screen(void) {
if (! fs_factor) { if (! fs_factor) {
return 0; return 0;
} }
if (unixpw_in_progress) return 0; if (unixpw_in_progress) return 0;
block_size = (dpy_x * (dpy_y/fs_factor) * pixelsize); block_size = (dpy_x * (dpy_y/fs_factor) * pixelsize);
...@@ -2686,6 +2697,9 @@ int scan_for_updates(int count_only) { ...@@ -2686,6 +2697,9 @@ int scan_for_updates(int count_only) {
*/ */
old_copy_tile = 0; old_copy_tile = 0;
} }
if (unixpw_in_progress) return 0;
if (old_copy_tile) { if (old_copy_tile) {
tile_diffs = copy_all_tiles(); tile_diffs = copy_all_tiles();
} else { } else {
......
...@@ -31,6 +31,7 @@ int openssl_sock = -1; ...@@ -31,6 +31,7 @@ int openssl_sock = -1;
int openssl_port_num = 0; 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;
char *openssl_last_ip = NULL;
void raw_xfer(int csock, int s_in, int s_out); void raw_xfer(int csock, int s_in, int s_out);
...@@ -1030,7 +1031,6 @@ if (db) fprintf(stderr, "waitpid(%d) 2\n", helpers[i]); ...@@ -1030,7 +1031,6 @@ if (db) fprintf(stderr, "waitpid(%d) 2\n", helpers[i]);
} }
} }
/* AUDIT */
static int is_ssl_readable(int s_in, time_t last_https, char *last_get, static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
int mode) { int mode) {
int nfd, db = 0; int nfd, db = 0;
...@@ -1063,7 +1063,7 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get, ...@@ -1063,7 +1063,7 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
*/ */
if (time(NULL) < last_https + 30) { if (time(NULL) < last_https + 30) {
tv.tv_sec = 8; tv.tv_sec = 8;
if (strstr(last_get, "VncViewer")) { if (last_get && strstr(last_get, "VncViewer")) {
tv.tv_sec = 4; tv.tv_sec = 4;
} }
} }
...@@ -1099,6 +1099,9 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) { ...@@ -1099,6 +1099,9 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
if (getenv("ACCEPT_OPENSSL_DEBUG")) { if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG")); db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
} }
if (! buf_a || ! n_a) {
return 0;
}
buf = (char *) calloc((ABSIZE+1), 1); buf = (char *) calloc((ABSIZE+1), 1);
*n_a = 0; *n_a = 0;
...@@ -1137,7 +1140,9 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) { ...@@ -1137,7 +1140,9 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
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 (db) fprintf(stderr, "watch_for_http_traffic readmore: %d\n", n2);
if (n > 0) { if (n > 0) {
...@@ -1180,6 +1185,7 @@ static int wait_conn(int sock) { ...@@ -1180,6 +1185,7 @@ static int wait_conn(int sock) {
int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie, int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie,
int mode) { int mode) {
int sock1, db = 0;
char reply[] = "HTTP/1.1 200 OK\r\n" char reply[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: octet-stream\r\n" "Content-Type: octet-stream\r\n"
"Pragma: no-cache\r\n\r\n"; "Pragma: no-cache\r\n\r\n";
...@@ -1187,7 +1193,6 @@ int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie, ...@@ -1187,7 +1193,6 @@ int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie,
"Content-Type: octet-stream\r\n" "Content-Type: octet-stream\r\n"
"Content-Length: 9\r\n" "Content-Length: 9\r\n"
"Pragma: no-cache\r\n\r\nGO_AHEAD\n"; "Pragma: no-cache\r\n\r\nGO_AHEAD\n";
int sock1, db = 0;
rfbLog("SSL: accept_openssl: detected https proxied connection" rfbLog("SSL: accept_openssl: detected https proxied connection"
" request.\n"); " request.\n");
...@@ -1208,20 +1213,24 @@ int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie, ...@@ -1208,20 +1213,24 @@ int proxy_hack(int vncsock, int listen, int s_in, int s_out, char *cookie,
} else if (mode == OPENSSL_HTTPS) { } else if (mode == OPENSSL_HTTPS) {
listen = https_sock; listen = https_sock;
} else { } else {
/* inetd */
return 0; return 0;
} }
sock1 = wait_conn(listen); sock1 = wait_conn(listen);
if (csock_timeout_sock < 0 || sock1 < 0) { if (csock_timeout_sock < 0 || sock1 < 0) {
close(sock1); close(sock1);
return 0; return 0;
} }
if (db) fprintf(stderr, "got applet input sock1: %d\n", sock1); if (db) fprintf(stderr, "got applet input sock1: %d\n", sock1);
if (! ssl_init(sock1, sock1)) { if (! ssl_init(sock1, sock1)) {
if (db) fprintf(stderr, "ssl_init FAILED\n"); if (db) fprintf(stderr, "ssl_init FAILED\n");
exit(1); exit(1);
} }
SSL_write(ssl, reply, strlen(reply)); SSL_write(ssl, reply, strlen(reply));
{ {
...@@ -1241,21 +1250,23 @@ if (db) fprintf(stderr, "buf: '%s'\n", buf); ...@@ -1241,21 +1250,23 @@ if (db) fprintf(stderr, "buf: '%s'\n", buf);
} }
} }
if (cookie) {
write(vncsock, cookie, strlen(cookie)); write(vncsock, cookie, strlen(cookie));
}
ssl_xfer(vncsock, sock1, sock1, 0); ssl_xfer(vncsock, sock1, sock1, 0);
return 1; return 1;
} }
void accept_openssl(int mode) { void accept_openssl(int mode) {
int sock = -1, cport, csock, vsock, listen = -1; int sock = -1, listen = -1, cport, csock, vsock;
int status, n, i, db = 0; int status, n, i, db = 0;
struct sockaddr_in addr; struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
char cookie[128], rcookie[128], *name;
rfbClientPtr client; rfbClientPtr client;
pid_t pid; pid_t pid;
char uniq[] = "__evilrats__"; char uniq[] = "__evilrats__";
char cookie[128], rcookie[128], *name = NULL;
static time_t last_https = 0; static time_t last_https = 0;
static char last_get[128]; static char last_get[128];
static int first = 1; static int first = 1;
...@@ -1280,26 +1291,35 @@ void accept_openssl(int mode) { ...@@ -1280,26 +1291,35 @@ void accept_openssl(int mode) {
if (mode == OPENSSL_INETD) { if (mode == OPENSSL_INETD) {
ssl_initialized = 1; ssl_initialized = 1;
} else if (mode == OPENSSL_VNC && openssl_sock >= 0) { } else if (mode == OPENSSL_VNC) {
sock = accept(openssl_sock, (struct sockaddr *)&addr, &addrlen); sock = accept(openssl_sock, (struct sockaddr *)&addr, &addrlen);
listen = openssl_sock;
if (sock < 0) { if (sock < 0) {
rfbLog("SSL: accept_openssl: accept connection failed\n"); rfbLog("SSL: accept_openssl: accept connection failed\n");
rfbLogPerror("accept"); rfbLogPerror("accept");
return; return;
} }
listen = openssl_sock;
} else if (mode == OPENSSL_HTTPS && https_sock >= 0) { } else if (mode == OPENSSL_HTTPS) {
sock = accept(https_sock, (struct sockaddr *)&addr, &addrlen); sock = accept(https_sock, (struct sockaddr *)&addr, &addrlen);
listen = https_sock;
if (sock < 0) { if (sock < 0) {
rfbLog("SSL: accept_openssl: accept connection failed\n"); rfbLog("SSL: accept_openssl: accept connection failed\n");
rfbLogPerror("accept"); rfbLogPerror("accept");
return; return;
} }
listen = https_sock;
} }
if (db) fprintf(stderr, "SSL: accept_openssl: sock: %d\n", sock); if (db) fprintf(stderr, "SSL: accept_openssl: sock: %d\n", sock);
if (openssl_last_ip) {
free(openssl_last_ip);
openssl_last_ip = NULL;
}
if (mode == OPENSSL_INETD) {
openssl_last_ip = get_remote_host(fileno(stdin));
} else {
openssl_last_ip = get_remote_host(sock);
}
/* now make a listening socket for child to connect back to us by: */ /* now make a listening socket for child to connect back to us by: */
...@@ -1339,11 +1359,23 @@ void accept_openssl(int mode) { ...@@ -1339,11 +1359,23 @@ void accept_openssl(int mode) {
if (mode != OPENSSL_INETD) { if (mode != OPENSSL_INETD) {
name = get_remote_host(sock); name = get_remote_host(sock);
} else { } else {
name = strdup("inetd-connection"); openssl_last_ip = get_remote_host(fileno(stdin));
if (openssl_last_ip) {
name = strdup(openssl_last_ip);
} else {
name = strdup("unknown");
}
} }
if (name) { if (name) {
rfbLog("SSL: spawning helper process to handle: %s\n", name); if (mode == OPENSSL_INETD) {
rfbLog("SSL: (inetd) spawning helper process "
"to handle: %s\n", name);
} else {
rfbLog("SSL: spawning helper process to handle: "
"%s\n", name);
}
free(name); free(name);
name = NULL;
} }
/* now fork the child to handle the SSL: */ /* now fork the child to handle the SSL: */
...@@ -1361,7 +1393,7 @@ void accept_openssl(int mode) { ...@@ -1361,7 +1393,7 @@ void accept_openssl(int mode) {
} else if (pid == 0) { } else if (pid == 0) {
int s_in, s_out, httpsock = -1; int s_in, s_out, httpsock = -1;
int vncsock, sslsock = sock; int vncsock;
int i, have_httpd = 0; int i, have_httpd = 0;
int f_in = fileno(stdin); int f_in = fileno(stdin);
int f_out = fileno(stdout); int f_out = fileno(stdout);
...@@ -1376,7 +1408,7 @@ void accept_openssl(int mode) { ...@@ -1376,7 +1408,7 @@ void accept_openssl(int mode) {
continue; continue;
} }
} }
if (i == sslsock) { if (i == sock) {
continue; continue;
} }
if (i == 2) { if (i == 2) {
...@@ -1400,7 +1432,6 @@ void accept_openssl(int mode) { ...@@ -1400,7 +1432,6 @@ void accept_openssl(int mode) {
if (vncsock < 0) { if (vncsock < 0) {
rfbLog("SSL: ssl_helper[%d]: could not connect" rfbLog("SSL: ssl_helper[%d]: could not connect"
" back to: %d\n", getpid(), cport); " back to: %d\n", getpid(), cport);
close(vncsock);
exit(1); exit(1);
} }
...@@ -1424,6 +1455,10 @@ void accept_openssl(int mode) { ...@@ -1424,6 +1455,10 @@ void accept_openssl(int mode) {
* SSL socket. * SSL socket.
*/ */
if (! screen) {
close(vncsock);
exit(1);
}
if (screen->httpListenSock >= 0 && screen->httpPort > 0) { if (screen->httpListenSock >= 0 && screen->httpPort > 0) {
have_httpd = 1; have_httpd = 1;
} }
...@@ -1470,6 +1505,7 @@ void accept_openssl(int mode) { ...@@ -1470,6 +1505,7 @@ void accept_openssl(int mode) {
*/ */
if (db) fprintf(stderr, "watch_for_http_traffic\n"); if (db) fprintf(stderr, "watch_for_http_traffic\n");
is_http = watch_for_http_traffic(buf, &n); is_http = watch_for_http_traffic(buf, &n);
if (is_http < 0 || is_http == 0) { if (is_http < 0 || is_http == 0) {
...@@ -1484,7 +1520,9 @@ void accept_openssl(int mode) { ...@@ -1484,7 +1520,9 @@ void accept_openssl(int mode) {
} }
goto wrote_cookie; goto wrote_cookie;
} }
if (db) fprintf(stderr, "is_http: %d n: %d\n", is_http, n);
if (db) fprintf(stderr, "is_http: %d n: %d\n",
is_http, n);
if (db) fprintf(stderr, "buf: '%s'\n", buf); if (db) fprintf(stderr, "buf: '%s'\n", buf);
if (strstr(buf, "/request.https.vnc.connection")) { if (strstr(buf, "/request.https.vnc.connection")) {
...@@ -1497,6 +1535,8 @@ void accept_openssl(int mode) { ...@@ -1497,6 +1535,8 @@ void accept_openssl(int mode) {
* instead of a direct SSL connection. * instead of a direct SSL connection.
*/ */
rfbLog("Handling VNC request via https GET. [%d]\n", getpid()); rfbLog("Handling VNC request via https GET. [%d]\n", getpid());
/* AUDIT */
if (strstr(buf, "/reverse.proxy")) { if (strstr(buf, "/reverse.proxy")) {
char *buf; char *buf;
int n, ptr; int n, ptr;
...@@ -1736,6 +1776,10 @@ if (db) fprintf(stderr, "iface: %s\n", iface); ...@@ -1736,6 +1776,10 @@ if (db) fprintf(stderr, "iface: %s\n", iface);
inetd_client = client; inetd_client = client;
client->clientGoneHook = client_gone; client->clientGoneHook = client_gone;
} }
if (openssl_last_ip &&
strpbrk(openssl_last_ip, "0123456789") == openssl_last_ip) {
client->host = strdup(openssl_last_ip);
}
} else { } else {
rfbLog("SSL: accept_openssl: rfbNewClient failed.\n"); rfbLog("SSL: accept_openssl: rfbNewClient failed.\n");
close(vsock); close(vsock);
......
...@@ -12,6 +12,7 @@ extern int openssl_sock; ...@@ -12,6 +12,7 @@ extern int openssl_sock;
extern int openssl_port_num; extern int openssl_port_num;
extern int https_sock; extern int https_sock;
extern pid_t openssl_last_helper_pid; extern pid_t openssl_last_helper_pid;
extern char *openssl_last_ip;
extern void raw_xfer(int csock, int s_in, int s_out); extern void raw_xfer(int csock, int s_in, int s_out);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
extern int grantpt(int); extern int grantpt(int);
extern int unlockpt(int); extern int unlockpt(int);
extern char *ptsname(int); extern char *ptsname(int);
/* XXX remove need for this */
extern char *crypt(const char*, const char *); extern char *crypt(const char*, const char *);
#endif #endif
...@@ -14,6 +15,8 @@ extern char *crypt(const char*, const char *); ...@@ -14,6 +15,8 @@ extern char *crypt(const char*, const char *);
#include "xinerama.h" #include "xinerama.h"
#include "connections.h" #include "connections.h"
#include "user.h" #include "user.h"
#include "connections.h"
#include "cursor.h"
#include <rfb/default8x16.h> #include <rfb/default8x16.h>
#if LIBVNCSERVER_HAVE_FORK #if LIBVNCSERVER_HAVE_FORK
...@@ -25,6 +28,9 @@ extern char *crypt(const char*, const char *); ...@@ -25,6 +28,9 @@ extern char *crypt(const char*, const char *);
#if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM #if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM
#if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT #if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT
#define UNIXPW_CRYPT #define UNIXPW_CRYPT
#if LIBVNCSERVER_HAVE_GETSPNAM
#include <shadow.h>
#endif
#endif #endif
#endif #endif
...@@ -65,6 +71,7 @@ static void set_db(void); ...@@ -65,6 +71,7 @@ static void set_db(void);
static void unixpw_verify(char *user, char *pass); static void unixpw_verify(char *user, char *pass);
int unixpw_in_progress = 0; int unixpw_in_progress = 0;
int unixpw_in_rfbPE = 0;
int unixpw_login_viewonly = 0; int unixpw_login_viewonly = 0;
time_t unixpw_last_try_time = 0; time_t unixpw_last_try_time = 0;
rfbClientPtr unixpw_client = NULL; rfbClientPtr unixpw_client = NULL;
...@@ -143,6 +150,8 @@ void unixpw_screen(int init) { ...@@ -143,6 +150,8 @@ void unixpw_screen(int init) {
char_y = y; char_y = y;
char_col = strlen(log); char_col = strlen(log);
char_row = 0; char_row = 0;
set_warrow_cursor();
} }
if (scaling) { if (scaling) {
...@@ -347,11 +356,32 @@ int crypt_verify(char *user, char *pass) { ...@@ -347,11 +356,32 @@ int crypt_verify(char *user, char *pass) {
return 0; return 0;
} }
if (db > 1) fprintf(stderr, "realpw='%s'\n", realpw);
if (strlen(realpw) < 10) {
/* e.g. "x", try getspnam(), sometimes root for inetd, etc */
#if LIBVNCSERVER_HAVE_GETSPNAM
struct spwd *sp = getspnam(user);
if (sp != NULL && sp->sp_pwdp != NULL) {
if (db) fprintf(stderr, "using getspnam()\n");
realpw = sp->sp_pwdp;
} else {
if (db) fprintf(stderr, "skipping getspnam()\n");
}
#endif
}
n = strlen(pass); n = strlen(pass);
if (pass[n-1] == '\n') { if (pass[n-1] == '\n') {
pass[n-1] = '\0'; pass[n-1] = '\0';
} }
/* XXX remove need for cast */
cr = (char *) crypt(pass, realpw); cr = (char *) crypt(pass, realpw);
if (db > 1) {
fprintf(stderr, "user='%s' pass='%s' realpw='%s' cr='%s'\n",
user, pass, realpw, cr ? cr : "(null)");
}
if (cr == NULL) { if (cr == NULL) {
return 0; return 0;
} }
...@@ -793,6 +823,7 @@ static void unixpw_verify(char *user, char *pass) { ...@@ -793,6 +823,7 @@ static void unixpw_verify(char *user, char *pass) {
char li[] = "Login incorrect"; char li[] = "Login incorrect";
char log[] = "login: "; char log[] = "login: ";
char *colon = NULL; char *colon = NULL;
ClientData *cd = NULL;
if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********"); if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********");
rfbLog("unixpw_verify: %s\n", user); rfbLog("unixpw_verify: %s\n", user);
...@@ -802,10 +833,23 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "*** ...@@ -802,10 +833,23 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
*colon = '\0'; *colon = '\0';
rfbLog("unixpw_verify: colon: %s\n", user); rfbLog("unixpw_verify: colon: %s\n", user);
} }
if (unixpw_client) {
cd = (ClientData *) unixpw_client->clientData;
if (cd) {
char *str = (char *)malloc(strlen("UNIX:") +
strlen(user) + 1);
sprintf(str, "UNIX:%s", user);
if (cd->username) {
free(cd->username);
}
cd->username = str;
}
}
if (unixpw_nis) { if (unixpw_nis) {
if (crypt_verify(user, pass)) { if (crypt_verify(user, pass)) {
rfbLog("unixpw_verify: crypt_verify login for '%s'"
" succeeded.\n", user);
unixpw_accept(user); unixpw_accept(user);
if (keep_unixpw) { if (keep_unixpw) {
keep_unixpw_user = strdup(user); keep_unixpw_user = strdup(user);
...@@ -818,12 +862,14 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "*** ...@@ -818,12 +862,14 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
} }
if (colon) *colon = ':'; if (colon) *colon = ':';
return; return;
} else {
rfbLog("unixpw_verify: crypt_verify login for %s failed.\n", user);
usleep(3000*1000);
} }
rfbLog("unixpw_verify: crypt_verify login for '%s' failed.\n",
user);
usleep(3000*1000);
} else { } else {
if (su_verify(user, pass, NULL, NULL, NULL)) { if (su_verify(user, pass, NULL, NULL, NULL)) {
rfbLog("unixpw_verify: su_verify login for '%s'"
" succeeded.\n", user);
unixpw_accept(user); unixpw_accept(user);
if (keep_unixpw) { if (keep_unixpw) {
keep_unixpw_user = strdup(user); keep_unixpw_user = strdup(user);
...@@ -837,7 +883,8 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "*** ...@@ -837,7 +883,8 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
if (colon) *colon = ':'; if (colon) *colon = ':';
return; return;
} }
rfbLog("unixpw_verify: su_verify login for %s failed.\n", user); rfbLog("unixpw_verify: su_verify login for '%s' failed.\n",
user);
} }
if (colon) *colon = ':'; if (colon) *colon = ':';
...@@ -1142,6 +1189,17 @@ static void apply_opts (char *user) { ...@@ -1142,6 +1189,17 @@ static void apply_opts (char *user) {
void unixpw_accept(char *user) { void unixpw_accept(char *user) {
apply_opts(user); apply_opts(user);
if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy &&
dpy == NULL) {
/* handled in main() */
unixpw_client->onHold = TRUE;
} else if (! accept_client(unixpw_client)) {
unixpw_deny();
return;
}
}
if (started_as_root == 1 && users_list if (started_as_root == 1 && users_list
&& strstr(users_list, "unixpw=") == users_list) { && strstr(users_list, "unixpw=") == users_list) {
if (getuid() && geteuid()) { if (getuid() && geteuid()) {
......
...@@ -12,6 +12,7 @@ extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_si ...@@ -12,6 +12,7 @@ extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_si
extern int crypt_verify(char *user, char *pass); extern int crypt_verify(char *user, char *pass);
extern int unixpw_in_progress; extern int unixpw_in_progress;
extern int unixpw_in_rfbPE;
extern int unixpw_login_viewonly; extern int unixpw_login_viewonly;
extern time_t unixpw_last_try_time; extern time_t unixpw_last_try_time;
extern rfbClientPtr unixpw_client; extern rfbClientPtr unixpw_client;
......
...@@ -1038,8 +1038,8 @@ void user_supplied_opts(char *opts) { ...@@ -1038,8 +1038,8 @@ void user_supplied_opts(char *opts) {
char *p, *str; char *p, *str;
char *allow[] = { char *allow[] = {
"skip-display", "skip-auth", "skip-shared", "skip-display", "skip-auth", "skip-shared",
"scale", "scale_cursor", "solid", "id", "clear_mods", "scale", "scale_cursor", "sc", "solid", "id",
"clear_keys", "repeat", "speeds", "clear_mods", "cm", "clear_keys", "ck", "repeat", "speeds",
NULL NULL
}; };
...@@ -1067,7 +1067,8 @@ void user_supplied_opts(char *opts) { ...@@ -1067,7 +1067,8 @@ void user_supplied_opts(char *opts) {
i++; i++;
} }
if (! ok && sscanf(p, "%d/%d", &n, &m) == 2) { if (! ok && strpbrk(p, "0123456789") == p &&
sscanf(p, "%d/%d", &n, &m) == 2) {
if (scale_str) free(scale_str); if (scale_str) free(scale_str);
scale_str = strdup(p); scale_str = strdup(p);
} else if (ok) { } else if (ok) {
...@@ -1077,6 +1078,8 @@ void user_supplied_opts(char *opts) { ...@@ -1077,6 +1078,8 @@ void user_supplied_opts(char *opts) {
} else if (strstr(p, "auth=") == p) { } else if (strstr(p, "auth=") == p) {
if (auth_file) free(auth_file); if (auth_file) free(auth_file);
auth_file = strdup(p + strlen("auth=")); auth_file = strdup(p + strlen("auth="));
} else if (!strcmp(p, "shared")) {
shared = 1;
} else if (strstr(p, "scale=") == p) { } else if (strstr(p, "scale=") == p) {
if (scale_str) free(scale_str); if (scale_str) free(scale_str);
scale_str = strdup(p + strlen("scale=")); scale_str = strdup(p + strlen("scale="));
...@@ -1084,8 +1087,9 @@ void user_supplied_opts(char *opts) { ...@@ -1084,8 +1087,9 @@ void user_supplied_opts(char *opts) {
if (scale_cursor_str) free(scale_cursor_str); if (scale_cursor_str) free(scale_cursor_str);
scale_cursor_str = strdup(p + scale_cursor_str = strdup(p +
strlen("scale_cursor=")); strlen("scale_cursor="));
} else if (!strcmp(p, "shared")) { } else if (strstr(p, "sc=") == p) {
shared = 1; if (scale_cursor_str) free(scale_cursor_str);
scale_cursor_str = strdup(p + strlen("sc="));
} else if (!strcmp(p, "solid")) { } else if (!strcmp(p, "solid")) {
use_solid_bg = 1; use_solid_bg = 1;
if (!solid_str) { if (!solid_str) {
...@@ -1103,9 +1107,11 @@ void user_supplied_opts(char *opts) { ...@@ -1103,9 +1107,11 @@ void user_supplied_opts(char *opts) {
subwin = win; subwin = win;
} }
} }
} else if (!strcmp(p, "clear_mods")) { } else if (!strcmp(p, "clear_mods") ||
!strcmp(p, "cm")) {
clear_mods = 1; clear_mods = 1;
} else if (!strcmp(p, "clear_keys")) { } else if (!strcmp(p, "clear_keys") ||
!strcmp(p, "ck")) {
clear_mods = 2; clear_mods = 2;
} else if (!strcmp(p, "repeat")) { } else if (!strcmp(p, "repeat")) {
no_autorepeat = 0; no_autorepeat = 0;
...@@ -1296,12 +1302,18 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1296,12 +1302,18 @@ int wait_for_client(int *argc, char** argv, int http) {
rfbLog("unixpw but no unixpw_in_progress\n"); rfbLog("unixpw but no unixpw_in_progress\n");
clean_up_exit(1); clean_up_exit(1);
} }
if (unixpw_client && unixpw_client->onHold) {
rfbLog("taking unixpw_client off hold.\n");
unixpw_client->onHold = FALSE;
}
while (1) { while (1) {
if (shut_down) { if (shut_down) {
clean_up_exit(0); clean_up_exit(0);
} }
if (! use_threads) { if (! use_threads) {
unixpw_in_rfbPE = 1;
rfbPE(-1); rfbPE(-1);
unixpw_in_rfbPE = 0;
} }
if (unixpw_in_progress) { if (unixpw_in_progress) {
usleep(20 * 1000); usleep(20 * 1000);
......
...@@ -2145,6 +2145,8 @@ static int check_xrecord_keys(void) { ...@@ -2145,6 +2145,8 @@ static int check_xrecord_keys(void) {
RAWFB_RET(0) RAWFB_RET(0)
if (unixpw_in_progress) return 0;
set_repeat_in = set_repeat; set_repeat_in = set_repeat;
set_repeat = 0.0; set_repeat = 0.0;
...@@ -3303,6 +3305,7 @@ int check_wireframe(void) { ...@@ -3303,6 +3305,7 @@ int check_wireframe(void) {
RAWFB_RET(0) RAWFB_RET(0)
if (unixpw_in_progress) return 0; if (unixpw_in_progress) return 0;
if (nofb) { if (nofb) {
return 0; return 0;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "x11vnc.h" #include "x11vnc.h"
#include "cleanup.h" #include "cleanup.h"
#include "win_utils.h" #include "win_utils.h"
#include "unixpw.h"
struct timeval _mysleep; struct timeval _mysleep;
...@@ -407,9 +408,14 @@ double rfac(void) { ...@@ -407,9 +408,14 @@ double rfac(void) {
*/ */
#define USEC_MAX 999999 /* libvncsever assumes < 1 second */ #define USEC_MAX 999999 /* libvncsever assumes < 1 second */
void rfbPE(long usec) { void rfbPE(long usec) {
int uip0 = unixpw_in_progress;
if (! screen) { if (! screen) {
return; return;
} }
if (unixpw && unixpw_in_progress && !unixpw_in_rfbPE) {
rfbLog("unixpw_in_rfbPE: skipping rfbPE\n");
return;
}
if (usec > USEC_MAX) { if (usec > USEC_MAX) {
usec = USEC_MAX; usec = USEC_MAX;
...@@ -417,18 +423,38 @@ void rfbPE(long usec) { ...@@ -417,18 +423,38 @@ void rfbPE(long usec) {
if (! use_threads) { if (! use_threads) {
rfbProcessEvents(screen, usec); rfbProcessEvents(screen, usec);
} }
if (unixpw && unixpw_in_progress && !uip0) {
if (!unixpw_in_rfbPE) {
rfbLog("rfbPE: got new client in non-rfbPE\n");
; /* this is new unixpw client */
}
}
} }
void rfbCFD(long usec) { void rfbCFD(long usec) {
int uip0 = unixpw_in_progress;
if (! screen) { if (! screen) {
return; return;
} }
if (unixpw && unixpw_in_progress && !unixpw_in_rfbPE) {
rfbLog("unixpw_in_rfbPE: skipping rfbCFD\n");
return;
}
if (usec > USEC_MAX) { if (usec > USEC_MAX) {
usec = USEC_MAX; usec = USEC_MAX;
} }
if (! use_threads) { if (! use_threads) {
rfbCheckFds(screen, usec); rfbCheckFds(screen, usec);
} }
if (unixpw && unixpw_in_progress && !uip0) {
if (!unixpw_in_rfbPE) {
rfbLog("rfbCFD: got new client in non-rfbPE\n");
; /* this is new unixpw client */
}
}
} }
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,
......
.\" This file was automatically generated from x11vnc -help output. .\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "June 2006" "x11vnc " "User Commands" .TH X11VNC "1" "July 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-23 version: 0.8.2, lastmod: 2006-07-04
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -37,7 +37,7 @@ In brief: ...@@ -37,7 +37,7 @@ In brief:
.PP .PP
% vncviewer -encodings 'copyrect tight zrle hextile' localhost:0 % vncviewer -encodings 'copyrect tight zrle hextile' localhost:0
.PP .PP
Also, use of a VNC password (-rfbauth or \fB-passwdfile)\fR is strongly recommend. Also, use of a VNC password (-rfbauth or \fB-passwdfile)\fR is strongly recommended.
.PP .PP
For additional info see: http://www.karlrunge.com/x11vnc/ For additional info see: http://www.karlrunge.com/x11vnc/
and http://www.karlrunge.com/x11vnc/#faq and http://www.karlrunge.com/x11vnc/#faq
...@@ -231,11 +231,11 @@ speedup may be achieved via the option "nogetimage". ...@@ -231,11 +231,11 @@ speedup may be achieved via the option "nogetimage".
This enables a scheme were XGetImage() is not used This enables a scheme were XGetImage() is not used
to retrieve the 8bpp data. Instead, it assumes that to retrieve the 8bpp data. Instead, it assumes that
the 8bpp data is in bits 25-32 of the 32bit X pixels. the 8bpp data is in bits 25-32 of the 32bit X pixels.
There is no reason the X server should put the data There is no requirement that the X server should put
there for our poll requests, but some do and so the the data there for our poll requests, but some do and
extra steps to retrieve it can be skipped. Tested with so the extra steps to retrieve it can be skipped.
mga driver with XFree86/Xorg. For the default depth Tested with mga driver with XFree86/Xorg. For the
8 case this option is ignored. default depth 8 case this option is ignored.
.IP .IP
To adjust how often XGetImage() is used to poll the To adjust how often XGetImage() is used to poll the
non-default visual regions for changes, use the option non-default visual regions for changes, use the option
...@@ -373,6 +373,11 @@ Also clients that log in viewonly cannot transfer files. ...@@ -373,6 +373,11 @@ Also clients that log in viewonly cannot transfer files.
However, if the remote control mechanism is used to However, if the remote control mechanism is used to
change the global or per-client viewonly state the change the global or per-client viewonly state the
filetransfer permissions will NOT change. filetransfer permissions will NOT change.
.IP
Note, to *enable* UltraVNC filetransfer (currently
disabled by default, this may change...) and to get it
to work you probably need to supply these libvncserver
options: "\fB-rfbversion\fR \fI3.6 \fB-permitfiletransfer\fR"\fR
.PP .PP
\fB-http\fR \fB-http\fR
.IP .IP
...@@ -437,7 +442,7 @@ out with the "#" character in the usual way. ...@@ -437,7 +442,7 @@ out with the "#" character in the usual way.
.PP .PP
\fB-localhost\fR \fB-localhost\fR
.IP .IP
Same as "\fB-allow\fR \fI127.0.0.1\fR". Basically the same as "\fB-allow\fR \fI127.0.0.1\fR".
.IP .IP
Note: if you want to restrict which network interface Note: if you want to restrict which network interface
x11vnc listens on, see the \fB-listen\fR option below. x11vnc listens on, see the \fB-listen\fR option below.
...@@ -445,11 +450,11 @@ E.g. "\fB-listen\fR \fIlocalhost\fR" or "\fB-listen\fR \fI192.168.3.21\fR". ...@@ -445,11 +450,11 @@ E.g. "\fB-listen\fR \fIlocalhost\fR" or "\fB-listen\fR \fI192.168.3.21\fR".
As a special case, the option "\fB-localhost\fR" implies As a special case, the option "\fB-localhost\fR" implies
"\fB-listen\fR \fIlocalhost\fR". "\fB-listen\fR \fIlocalhost\fR".
.IP .IP
For non-localhost \fB-listen\fR usage, if you use the remote A rare case, but for non-localhost \fB-listen\fR usage, if
control mechanism (-R) to change the \fB-listen\fR interface you use the remote control mechanism (-R) to change
you may need to manually adjust the \fB-allow\fR list (and the \fB-listen\fR interface you may need to manually adjust
vice versa) to avoid situations where no connections the \fB-allow\fR list (and vice versa) to avoid situations
(or too many) are allowed. where no connections (or too many) are allowed.
.PP .PP
\fB-nolookup\fR \fB-nolookup\fR
.IP .IP
...@@ -519,7 +524,7 @@ removed after being read. Perhaps this is useful in ...@@ -519,7 +524,7 @@ removed after being read. Perhaps this is useful in
limiting the readability of the file. In general, limiting the readability of the file. In general,
the password file should not be readable by untrusted the password file should not be readable by untrusted
users (BTW: neither should the VNC \fB-rfbauth\fR file: users (BTW: neither should the VNC \fB-rfbauth\fR file:
it is NOT encrypted). it is NOT encrypted, only obscured).
.IP .IP
If the filename is prefixed with "read:" it will If the filename is prefixed with "read:" it will
periodically be checked for changes and reread. periodically be checked for changes and reread.
...@@ -661,7 +666,7 @@ The user names in the comma separated [list] can have ...@@ -661,7 +666,7 @@ The user names in the comma separated [list] can have
per-user options after a ":", e.g. "fred:opts" per-user options after a ":", e.g. "fred:opts"
where "opts" is a "+" separated list of where "opts" is a "+" separated list of
"viewonly", "fullaccess", "input=XXXX", or "viewonly", "fullaccess", "input=XXXX", or
"deny", e.g. "karl,fred:viewonly,boss:input=M". "deny", e.g. "karl,wally:viewonly,boss:input=M".
For "input=" it is the K,M,B,C described under \fB-input.\fR For "input=" it is the K,M,B,C described under \fB-input.\fR
.IP .IP
If a user in the list is "*" that means those If a user in the list is "*" that means those
...@@ -696,8 +701,10 @@ mode to work (only that ...@@ -696,8 +701,10 @@ mode to work (only that
.IR getpwnam (3) .IR getpwnam (3)
return the encrypted return the encrypted
password is required), but it is unlikely it will work password is required), but it is unlikely it will work
for any other modern environment. All of the \fB-unixpw\fR for any other modern environment unless x11vnc is run
options and contraints apply. as root (which, btw, is often done when running x11vnc
from inetd and xdm/gdm/kdm). All of the \fB-unixpw\fR options
and contraints apply.
.PP .PP
\fB-display\fR \fIWAIT:...\fR \fB-display\fR \fIWAIT:...\fR
.IP .IP
...@@ -726,17 +733,17 @@ output is taken as XAUTHORITY data. It can be either ...@@ -726,17 +733,17 @@ output is taken as XAUTHORITY data. It can be either
of the form XAUTHORITY=<file> or raw xauthority data for of the form XAUTHORITY=<file> or raw xauthority data for
the display (e.g. "xauth extract - $DISPLAY" output). the display (e.g. "xauth extract - $DISPLAY" output).
.IP .IP
In the case of \fB-unixpw,\fR then the above command is run In the case of \fB-unixpw\fR (but not \fB-unixpw_nis),\fR then the
as the user who just authenticated via the login and above command is run as the user who just authenticated
password prompt. via the login and password prompt.
.IP .IP
Also in the case of \fB-unixpw,\fR the user logging in can Also in the case of \fB-unixpw,\fR the user logging in can
place a colon at the end of his username and supply place a colon at the end of his username and supply
a few options: scale=, scale_cursor=, solid, id=, a few options: scale=, scale_cursor= (or sc=), solid,
clear_mods, clear_keys, repeat, or speeds= separated id=, clear_mods (or cm), clear_keys (or ck), repeat, or
by commas if there is more than one. After the user speeds= separated by commas if there is more than one.
logs in successfully, these options will be applied to After the user logs in successfully, these options will
the VNC screen. For example, be applied to the VNC screen. For example,
.IP .IP
login: fred:scale=3/4,repeat login: fred:scale=3/4,repeat
Password: ... Password: ...
...@@ -760,17 +767,19 @@ A nice way to use WAIT:cmd=... is out of ...@@ -760,17 +767,19 @@ A nice way to use WAIT:cmd=... is out of
.IR inetd (8) .IR inetd (8)
(it automatically forks a new x11vnc for each user). (it automatically forks a new x11vnc for each user).
You can have the x11vnc inetd spawned process run as, You can have the x11vnc inetd spawned process run as,
say, root or nobody. When run as root (for either say, root or nobody. When run as root (for either inetd
inetd or display manager), you can also supply the or display manager), you can also supply the option
option "\fB-users\fR \fIunixpw=\fR" to have the x11vnc process "\fB-users\fR \fIunixpw=\fR" to have the x11vnc process switch to
switch to the user as well. Note: there will be a 2nd the user as well. Note: there will be a 2nd SSL helper
SSL helper process that will not switch, but it is only process that will not switch, but it is only encoding
encoding and decoding the stream at that point. and decoding the encrypted stream at that point.
.IP .IP
As a special case, WAIT:cmd=FINDDISPLAY will run As a special case, WAIT:cmd=FINDDISPLAY will run a
a script that works on most Unixes to determine a script that works on most Unixes to determine a user's
user's DISPLAY variable and xauthority data. To have DISPLAY variable and xauthority data (see
this default script printed to stdout (e.g. for .IR who (1)
).
To have this default script printed to stdout (e.g. for
customization) run with WAIT:cmd=FINDDISPLAY-print customization) run with WAIT:cmd=FINDDISPLAY-print
.IP .IP
As another special case, WAIT:cmd=HTTPONCE will allow As another special case, WAIT:cmd=HTTPONCE will allow
...@@ -1399,6 +1408,15 @@ is used. The popup will time out after 120 seconds, ...@@ -1399,6 +1408,15 @@ is used. The popup will time out after 120 seconds,
use "popup:N" to modify the timeout to N seconds use "popup:N" to modify the timeout to N seconds
(use 0 for no timeout). (use 0 for no timeout).
.IP .IP
In the case of "popup" and when the \fB-unixpw\fR option
is specified, then a *second* window will be popped
up after the user successfully logs in via his UNIX
password. This time the user will be identified as
UNIX:username@hostname, the "UNIX:" prefix indicates
which user the viewer logged as via \fB-unixpw.\fR The first
popup is only for whether to allow him to even *try*
to login via unix password.
.IP
If \fIstring\fR is "xmessage" then an If \fIstring\fR is "xmessage" then an
.IR xmessage (1) .IR xmessage (1)
invocation is used for the command. xmessage must be invocation is used for the command. xmessage must be
...@@ -1690,6 +1708,11 @@ Print this help text. ...@@ -1690,6 +1708,11 @@ Print this help text.
.IP .IP
Print program version and last modification date. Print program version and last modification date.
.PP .PP
\fB-license\fR
.IP
Print out license information. Same as \fB-copying\fR and
\fB-warranty.\fR
.PP
\fB-dbg\fR \fB-dbg\fR
.IP .IP
Instead of exiting after cleaning up, run a simple Instead of exiting after cleaning up, run a simple
......
...@@ -407,6 +407,7 @@ static void watch_loop(void) { ...@@ -407,6 +407,7 @@ static void watch_loop(void) {
} }
while (1) { while (1) {
char msg[] = "new client: %s taking unixpw client off hold.\n";
got_user_input = 0; got_user_input = 0;
got_pointer_input = 0; got_pointer_input = 0;
...@@ -418,11 +419,36 @@ static void watch_loop(void) { ...@@ -418,11 +419,36 @@ static void watch_loop(void) {
if (! use_threads) { if (! use_threads) {
dtime0(&tm); dtime0(&tm);
if (! skip_pe) { if (! skip_pe) {
if (unixpw && unixpw_in_progress) {
rfbClientPtr cl = unixpw_client;
if (cl && cl->onHold) {
rfbLog(msg, cl->host);
unixpw_client->onHold = FALSE;
}
} else {
measure_send_rates(1); measure_send_rates(1);
}
unixpw_in_rfbPE = 1;
rfbPE(-1); rfbPE(-1);
unixpw_in_rfbPE = 0;
if (unixpw && unixpw_in_progress) {
/* rfbPE loop until logged in. */
skip_pe = 0;
continue;
} else {
measure_send_rates(0); measure_send_rates(0);
fb_update_sent(NULL); fb_update_sent(NULL);
} }
} else {
if (unixpw && unixpw_in_progress) {
skip_pe = 0;
continue;
}
}
dtr = dtime(&tm); dtr = dtime(&tm);
if (! cursor_shape_updates) { if (! cursor_shape_updates) {
...@@ -432,26 +458,27 @@ static void watch_loop(void) { ...@@ -432,26 +458,27 @@ static void watch_loop(void) {
if (screen && screen->clientHead) { if (screen && screen->clientHead) {
int ret = check_user_input(dt, dtr, int ret = check_user_input(dt, dtr,
tile_diffs, &cnt); tile_diffs, &cnt);
/* true means loop back for more input */ /* true: loop back for more input */
if (ret == 2) { if (ret == 2) {
skip_pe = 1; skip_pe = 1;
} }
if (ret) { if (ret) {
if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
continue; continue;
} }
} }
/* watch for viewonly input piling up: */ /* watch for viewonly input piling up: */
if ((got_pointer_calls > got_pointer_input) if ((got_pointer_calls > got_pointer_input) ||
|| (got_keyboard_calls > got_keyboard_input)) { (got_keyboard_calls > got_keyboard_input)) {
eat_viewonly_input(10, 3); eat_viewonly_input(10, 3);
} }
} else { } else {
#if 0
if (0 && use_xrecord) { if (0 && use_xrecord) {
/* XXX not working */ /* XXX not working */
check_xrecord(); check_xrecord();
} }
#endif
if (wireframe && button_mask) { if (wireframe && button_mask) {
check_wireframe(); check_wireframe();
} }
...@@ -462,6 +489,8 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -462,6 +489,8 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
clean_up_exit(0); clean_up_exit(0);
} }
if (unixpw_in_progress) continue;
if (! urgent_update) { if (! urgent_update) {
if (do_copy_screen) { if (do_copy_screen) {
do_copy_screen = 0; do_copy_screen = 0;
...@@ -540,6 +569,8 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret); ...@@ -540,6 +569,8 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
if (use_xdamage && last_dt > xdamage_thrash) { if (use_xdamage && last_dt > xdamage_thrash) {
clear_xdamage_mark_region(NULL, 0); clear_xdamage_mark_region(NULL, 0);
} }
if (unixpw_in_progress) continue;
dtime0(&tm); dtime0(&tm);
if (use_snapfb) { if (use_snapfb) {
int t, tries = 3; int t, tries = 3;
...@@ -1823,6 +1854,9 @@ int main(int argc, char* argv[]) { ...@@ -1823,6 +1854,9 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) { } else if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) {
fprintf(stdout, "x11vnc: %s\n", lastmod); fprintf(stdout, "x11vnc: %s\n", lastmod);
exit(0); exit(0);
} else if (!strcmp(arg, "-license") ||
!strcmp(arg, "-copying") || !strcmp(arg, "-warranty")) {
print_license();
} else if (!strcmp(arg, "-dbg")) { } else if (!strcmp(arg, "-dbg")) {
crash_debug = 1; crash_debug = 1;
} else if (!strcmp(arg, "-nodbg")) { } else if (!strcmp(arg, "-nodbg")) {
...@@ -2569,6 +2603,12 @@ int main(int argc, char* argv[]) { ...@@ -2569,6 +2603,12 @@ int main(int argc, char* argv[]) {
} }
} }
} }
if (use_threads) {
if (! quiet) {
rfbLog("disabling -threads under -unixpw\n");
}
use_threads = 0;
}
} }
if (use_stunnel && ! got_localhost) { if (use_stunnel && ! got_localhost) {
if (! getenv("STUNNEL_DISABLE_LOCALHOST") && if (! getenv("STUNNEL_DISABLE_LOCALHOST") &&
...@@ -3203,6 +3243,31 @@ int main(int argc, char* argv[]) { ...@@ -3203,6 +3243,31 @@ int main(int argc, char* argv[]) {
if (use_solid_bg && client_count) { if (use_solid_bg && client_count) {
solid_bg(0); solid_bg(0);
} }
if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
rfbClientIteratorPtr iter;
rfbClientPtr cl, cl0 = NULL;
int i = 0;
iter = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(iter)) ) {
i++;
if (i != 1) {
rfbLog("WAIT popup: too many clients\n");
clean_up_exit(1);
}
cl0 = cl;
}
rfbReleaseClientIterator(iter);
if (i != 1 || cl0 == NULL) {
rfbLog("WAIT popup: no clients.\n");
clean_up_exit(1);
}
if (! accept_client(cl0)) {
rfbLog("WAIT popup: denied.\n");
clean_up_exit(1);
}
rfbLog("waited_for_client: popup accepted.\n");
cl0->onHold = FALSE;
}
} }
if (! waited_for_client) { if (! waited_for_client) {
......
...@@ -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-23"; char lastmod[] = "0.8.2 lastmod: 2006-07-04";
/* X display info */ /* X display info */
......
...@@ -1089,7 +1089,10 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) { ...@@ -1089,7 +1089,10 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
RAWFB_RET_VOID RAWFB_RET_VOID
if (unixpw_in_progress) return; if (unixpw_in_progress) {
rfbLog("xcut_receive: unixpw_in_progress, skipping.\n");
return;
}
if (!watch_selection) { if (!watch_selection) {
return; return;
......
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