parent
b7773ea6e6
commit
79310af7e7
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,236 @@
|
||||
/* -- sslcmds.c -- */
|
||||
|
||||
#include "x11vnc.h"
|
||||
#include "inet.h"
|
||||
#include "cleanup.h"
|
||||
|
||||
#if LIBVNCSERVER_HAVE_FORK
|
||||
#if LIBVNCSERVER_HAVE_SYS_WAIT_H
|
||||
#if LIBVNCSERVER_HAVE_WAITPID
|
||||
#define SSLCMDS
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
int start_stunnel(int stunnel_port, int x11vnc_port);
|
||||
void stop_stunnel(void);
|
||||
void setup_stunnel(int rport, int *argc, char **argv);
|
||||
|
||||
static pid_t stunnel_pid = 0;
|
||||
|
||||
int start_stunnel(int stunnel_port, int x11vnc_port) {
|
||||
#ifdef SSLCMDS
|
||||
char extra[] = ":/usr/sbin:/usr/local/sbin";
|
||||
char *path, *p, *exe;
|
||||
char *stunnel_path = NULL;
|
||||
int status;
|
||||
|
||||
if (stunnel_pid) {
|
||||
stop_stunnel();
|
||||
}
|
||||
stunnel_pid = 0;
|
||||
|
||||
path = getenv("PATH");
|
||||
if (! path) {
|
||||
path = strdup(extra);
|
||||
} else {
|
||||
path = (char *) malloc(strlen(path)+strlen(extra)+1);
|
||||
if (! path) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(path, getenv("PATH"));
|
||||
strcat(path, extra);
|
||||
}
|
||||
|
||||
exe = (char *) malloc(strlen(path) + strlen("stunnel") + 1);
|
||||
|
||||
p = strtok(path, ":");
|
||||
|
||||
exe[0] = '\0';
|
||||
|
||||
while (p) {
|
||||
struct stat sbuf;
|
||||
|
||||
sprintf(exe, "%s/%s", p, "stunnel");
|
||||
if (! stunnel_path && stat(exe, &sbuf) == 0) {
|
||||
if (! S_ISDIR(sbuf.st_mode)) {
|
||||
stunnel_path = exe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = strtok(NULL, ":");
|
||||
}
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
|
||||
if (! stunnel_path) {
|
||||
return 0;
|
||||
}
|
||||
if (stunnel_path[0] == '\0') {
|
||||
free(stunnel_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! quiet) {
|
||||
rfbLog("\n");
|
||||
rfbLog("starting ssl tunnel: %s %d -> %d\n", stunnel_path,
|
||||
stunnel_port, x11vnc_port);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fprintf(stderr, "foreground = yes\n");
|
||||
fprintf(stderr, "pid =\n");
|
||||
fprintf(stderr, ";debug = 7\n");
|
||||
fprintf(stderr, "[x11vnc_stunnel]\n");
|
||||
fprintf(stderr, "accept = %d\n", stunnel_port);
|
||||
fprintf(stderr, "connect = %d\n", x11vnc_port);
|
||||
}
|
||||
|
||||
stunnel_pid = fork();
|
||||
|
||||
if (stunnel_pid < 0) {
|
||||
stunnel_pid = 0;
|
||||
free(stunnel_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stunnel_pid == 0) {
|
||||
FILE *in;
|
||||
char fd[20];
|
||||
int i;
|
||||
|
||||
for (i=3; i<256; i++) {
|
||||
close(i);
|
||||
}
|
||||
|
||||
if (use_stunnel == 3) {
|
||||
char sp[20], xp[20];
|
||||
|
||||
sprintf(sp, "%d", stunnel_port);
|
||||
sprintf(xp, "%d", x11vnc_port);
|
||||
|
||||
if (stunnel_pem) {
|
||||
execlp(stunnel_path, stunnel_path, "-f", "-d",
|
||||
sp, "-r", xp, "-P", "none", "-p",
|
||||
stunnel_pem, (char *) NULL);
|
||||
} else {
|
||||
execlp(stunnel_path, stunnel_path, "-f", "-d",
|
||||
sp, "-r", xp, "-P", "none", (char *) NULL);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in = tmpfile();
|
||||
if (! in) {
|
||||
exit(1);
|
||||
}
|
||||
fprintf(in, "foreground = yes\n");
|
||||
fprintf(in, "pid =\n");
|
||||
if (stunnel_pem) {
|
||||
fprintf(in, "cert = %s\n", stunnel_pem);
|
||||
}
|
||||
fprintf(in, ";debug = 7\n");
|
||||
fprintf(in, "[x11vnc_stunnel]\n");
|
||||
fprintf(in, "accept = %d\n", stunnel_port);
|
||||
fprintf(in, "connect = %d\n", x11vnc_port);
|
||||
|
||||
fflush(in);
|
||||
rewind(in);
|
||||
|
||||
sprintf(fd, "%d", fileno(in));
|
||||
execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL);
|
||||
exit(1);
|
||||
}
|
||||
free(stunnel_path);
|
||||
usleep(500 * 1000);
|
||||
|
||||
waitpid(stunnel_pid, &status, WNOHANG);
|
||||
if (kill(stunnel_pid, 0) != 0) {
|
||||
waitpid(stunnel_pid, &status, WNOHANG);
|
||||
stunnel_pid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! quiet) {
|
||||
rfbLog("stunnel pid is: %d\n", (int) stunnel_pid);
|
||||
}
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_stunnel(void) {
|
||||
int status;
|
||||
if (! stunnel_pid) {
|
||||
return;
|
||||
}
|
||||
#ifdef SSLCMDS
|
||||
kill(stunnel_pid, SIGTERM);
|
||||
usleep (150 * 1000);
|
||||
kill(stunnel_pid, SIGKILL);
|
||||
usleep (50 * 1000);
|
||||
waitpid(stunnel_pid, &status, WNOHANG);
|
||||
#endif
|
||||
stunnel_pid = 0;
|
||||
}
|
||||
|
||||
void setup_stunnel(int rport, int *argc, char **argv) {
|
||||
int i, xport = 0;
|
||||
if (! rport) {
|
||||
for (i=0; i< *argc; i++) {
|
||||
if (!strcmp(argv[i], "-rfbport")) {
|
||||
if (i < *argc - 1) {
|
||||
rport = atoi(argv[i+1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! rport) {
|
||||
/* we do our own autoprobing then... */
|
||||
rport = find_free_port(5900, 5999);
|
||||
if (! rport) {
|
||||
goto stunnel_fail;
|
||||
}
|
||||
}
|
||||
xport = find_free_port(5950, 5999);
|
||||
if (! xport) {
|
||||
goto stunnel_fail;
|
||||
}
|
||||
if (start_stunnel(rport, xport)) {
|
||||
int tweaked = 0;
|
||||
char tmp[10];
|
||||
sprintf(tmp, "%d", xport);
|
||||
if (argv) {
|
||||
for (i=0; i< *argc; i++) {
|
||||
if (!strcmp(argv[i], "-rfbport")) {
|
||||
if (i < *argc - 1) {
|
||||
argv[i+i] = strdup(tmp);
|
||||
tweaked = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! tweaked) {
|
||||
i = *argc;
|
||||
argv[i] = strdup("-rfbport");
|
||||
argv[i+1] = strdup(tmp);
|
||||
*argc += 2;
|
||||
got_rfbport = 1;
|
||||
}
|
||||
}
|
||||
stunnel_port = rport;
|
||||
return;
|
||||
}
|
||||
|
||||
stunnel_fail:
|
||||
rfbLog("failed to start stunnel.\n");
|
||||
clean_up_exit(1);
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#ifndef _X11VNC_SSLCMDS_H
|
||||
#define _X11VNC_SSLCMDS_H
|
||||
|
||||
/* -- sslcmds.h -- */
|
||||
|
||||
extern int start_stunnel(int stunnel_port, int x11vnc_port);
|
||||
extern void stop_stunnel(void);
|
||||
extern void setup_stunnel(int rport, int *argc, char **argv);
|
||||
|
||||
|
||||
#endif /* _X11VNC_SSLCMDS_H */
|
@ -0,0 +1,442 @@
|
||||
/* -- unixpw.c -- */
|
||||
|
||||
#ifdef __linux__
|
||||
/* some conflict with _XOPEN_SOURCE */
|
||||
extern int grantpt(int);
|
||||
extern int unlockpt(int);
|
||||
extern char *ptsname(int);
|
||||
#endif
|
||||
|
||||
#include "x11vnc.h"
|
||||
#include "scan.h"
|
||||
#include "cleanup.h"
|
||||
#include "xinerama.h"
|
||||
#include <rfb/default8x16.h>
|
||||
|
||||
/* much to do for it to work on *BSD ... */
|
||||
|
||||
#if LIBVNCSERVER_HAVE_FORK
|
||||
#if LIBVNCSERVER_HAVE_SETSID
|
||||
#if LIBVNCSERVER_HAVE_SYS_WAIT_H
|
||||
#if LIBVNCSERVER_HAVE_PWD_H
|
||||
#if LIBVNCSERVER_HAVE_SETUID
|
||||
#if LIBVNCSERVER_HAVE_WAITPID
|
||||
#if LIBVNCSERVER_HAVE_TERMIOS_H
|
||||
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
|
||||
#if LIBVNCSERVER_HAVE_GRANTPT
|
||||
#define UNIXPW
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void unixpw_screen(int init);
|
||||
void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
|
||||
void unixpw_accept(void);
|
||||
void unixpw_deny(void);
|
||||
|
||||
static int white(void);
|
||||
static int text_x(void);
|
||||
static int text_y(void);
|
||||
static int su_verify(char *user, char *pass);
|
||||
static void unixpw_verify(char *user, char *pass);
|
||||
|
||||
int unixpw_in_progress = 0;
|
||||
time_t unixpw_last_try_time = 0;
|
||||
rfbClientPtr unixpw_client = NULL;
|
||||
|
||||
static int in_login = 0, in_passwd = 0, tries = 0;
|
||||
static int char_row = 0, char_col = 0;
|
||||
static int char_x = 0, char_y = 0, char_w = 8, char_h = 16;
|
||||
|
||||
static int white(void) {
|
||||
static unsigned long black_pix = 0, white_pix = 1, set = 0;
|
||||
|
||||
if (depth <= 8 && ! set) {
|
||||
X_LOCK;
|
||||
black_pix = BlackPixel(dpy, scr);
|
||||
white_pix = WhitePixel(dpy, scr);
|
||||
X_UNLOCK;
|
||||
set = 1;
|
||||
}
|
||||
if (depth <= 8) {
|
||||
return (int) white_pix;
|
||||
} else if (depth < 24) {
|
||||
return 0xffff;
|
||||
} else {
|
||||
return 0xffffff;
|
||||
}
|
||||
}
|
||||
|
||||
static int text_x(void) {
|
||||
return char_x + char_col * char_w;
|
||||
}
|
||||
|
||||
static int text_y(void) {
|
||||
return char_y + char_row * char_h;
|
||||
}
|
||||
|
||||
void unixpw_screen(int init) {
|
||||
#ifndef UNIXPW
|
||||
rfbLog("-unixpw is not supported on this OS/machine\n");
|
||||
clean_up_exit(1);
|
||||
#endif
|
||||
if (init) {
|
||||
int x, y;
|
||||
char log[] = "login: ";
|
||||
|
||||
zero_fb(0, 0, dpy_x, dpy_y);
|
||||
|
||||
x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x);
|
||||
y = dpy_y / 4;
|
||||
|
||||
rfbDrawString(screen, &default8x16Font, x, y, log, white());
|
||||
|
||||
char_x = x;
|
||||
char_y = y;
|
||||
char_col = strlen(log);
|
||||
char_row = 0;
|
||||
}
|
||||
|
||||
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
|
||||
}
|
||||
|
||||
static int su_verify(char *user, char *pass) {
|
||||
#ifdef UNIXPW
|
||||
int status, fd, sfd;
|
||||
char *slave;
|
||||
pid_t pid, pidw;
|
||||
struct stat sbuf;
|
||||
|
||||
if (unixpw_list) {
|
||||
char *p, *str = strdup(unixpw_list);
|
||||
int ok = 0;
|
||||
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
if (!strcmp(user, p)) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
free(str);
|
||||
if (! ok) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (stat("/bin/su", &sbuf) != 0) {
|
||||
rfbLogPerror("existence /bin/su");
|
||||
return 0;
|
||||
}
|
||||
if (stat("/bin/true", &sbuf) != 0) {
|
||||
rfbLogPerror("existence /bin/true");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open("/dev/ptmx", O_RDWR|O_NOCTTY);
|
||||
|
||||
if (fd < 0) {
|
||||
rfbLogPerror("open /dev/ptmx");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grantpt(fd) != 0) {
|
||||
rfbLogPerror("grantpt");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (unlockpt(fd) != 0) {
|
||||
rfbLogPerror("unlockpt");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
slave = ptsname(fd);
|
||||
if (! slave) {
|
||||
rfbLogPerror("ptsname");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
rfbLogPerror("fork");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
int ttyfd;
|
||||
struct passwd *pw;
|
||||
|
||||
close(fd);
|
||||
|
||||
pw = getpwnam("nobody");
|
||||
|
||||
if (pw) {
|
||||
setuid(pw->pw_uid);
|
||||
#if LIBVNCSERVER_HAVE_SETEUID
|
||||
seteuid(pw->pw_uid);
|
||||
#endif
|
||||
setgid(pw->pw_gid);
|
||||
#if LIBVNCSERVER_HAVE_SETEGID
|
||||
setegid(pw->pw_gid);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
fprintf(stderr, "could not switch to user nobody.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsid() == -1) {
|
||||
perror("setsid");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef TIOCNOTTY
|
||||
ttyfd = open("/dev/tty", O_RDWR);
|
||||
if (ttyfd >= 0) {
|
||||
(void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
|
||||
close(ttyfd);
|
||||
}
|
||||
#endif
|
||||
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
sfd = open(slave, O_RDWR);
|
||||
if (sfd < 0) {
|
||||
fprintf(stderr, "failed: %s\n", slave);
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef TIOCSCTTY
|
||||
if (ioctl(sfd, TIOCSCTTY, (char *) 0) != 0) {
|
||||
perror("ioctl");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
execlp("/bin/su", "/bin/su", user, "-c", "/bin/true",
|
||||
(char *) NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
usleep( 500 * 1000 );
|
||||
write(fd, pass, strlen(pass));
|
||||
|
||||
pidw = waitpid(pid, &status, 0);
|
||||
close(fd);
|
||||
|
||||
if (pid != pidw) {
|
||||
return 0;
|
||||
}
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int db = 0;
|
||||
|
||||
static void unixpw_verify(char *user, char *pass) {
|
||||
int x, y;
|
||||
char li[] = "Login incorrect";
|
||||
char log[] = "login: ";
|
||||
|
||||
if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********");
|
||||
|
||||
if (su_verify(user, pass)) {
|
||||
unixpw_accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tries < 2) {
|
||||
char_row++;
|
||||
char_col = 0;
|
||||
|
||||
x = text_x();
|
||||
y = text_y();
|
||||
rfbDrawString(screen, &default8x16Font, x, y, li, white());
|
||||
|
||||
char_row += 2;
|
||||
|
||||
x = text_x();
|
||||
y = text_y();
|
||||
rfbDrawString(screen, &default8x16Font, x, y, log, white());
|
||||
|
||||
char_col = strlen(log);
|
||||
|
||||
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
|
||||
|
||||
unixpw_last_try_time = time(0);
|
||||
unixpw_keystroke(0, 0, 2);
|
||||
tries++;
|
||||
} else {
|
||||
unixpw_deny();
|
||||
}
|
||||
}
|
||||
|
||||
void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
|
||||
int x, y, i, nmax = 100;
|
||||
static char user[100], pass[100];
|
||||
static int u_cnt = 0, p_cnt = 0, first = 1;
|
||||
char str[100];
|
||||
|
||||
if (first) {
|
||||
if (getenv("DEBUG_UNIXPW")) {
|
||||
db = atoi(getenv("DEBUG_UNIXPW"));
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (init) {
|
||||
in_login = 1;
|
||||
in_passwd = 0;
|
||||
if (init == 1) {
|
||||
tries = 0;
|
||||
}
|
||||
|
||||
u_cnt = 0;
|
||||
p_cnt = 0;
|
||||
for (i=0; i<nmax; i++) {
|
||||
user[i] = '\0';
|
||||
pass[i] = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (down) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_login) {
|
||||
if (keysym == XK_BackSpace || keysym == XK_Delete) {
|
||||
if (u_cnt > 0) {
|
||||
user[u_cnt-1] = '\0';
|
||||
x = text_x();
|
||||
y = text_y();
|
||||
zero_fb(x - char_w, y - char_h, x, y);
|
||||
mark_rect_as_modified(x - char_w, y - char_h,
|
||||
x, y, 0);
|
||||
char_col--;
|
||||
u_cnt--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (keysym == XK_Return || keysym == XK_Linefeed) {
|
||||
char pw[] = "Password: ";
|
||||
|
||||
in_login = 0;
|
||||
in_passwd = 1;
|
||||
|
||||
char_row++;
|
||||
char_col = 0;
|
||||
|
||||
x = text_x();
|
||||
y = text_y();
|
||||
rfbDrawString(screen, &default8x16Font, x, y, pw,
|
||||
white());
|
||||
|
||||
char_col = strlen(pw);
|
||||
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
|
||||
return;
|
||||
}
|
||||
if (keysym <= ' ' || keysym >= 0x7f) {
|
||||
return;
|
||||
}
|
||||
if (u_cnt >= nmax - 1) {
|
||||
rfbLog("unixpw_deny: username too long\n");
|
||||
unixpw_deny();
|
||||
return;
|
||||
}
|
||||
|
||||
X_LOCK;
|
||||
sprintf(str, "%s", XKeysymToString(keysym));
|
||||
X_UNLOCK;
|
||||
|
||||
user[u_cnt++] = str[0];
|
||||
|
||||
x = text_x();
|
||||
y = text_y();
|
||||
|
||||
if (db) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x %s\n", u_cnt, x, y, keysym, str);
|
||||
|
||||
str[1] = '\0';
|
||||
rfbDrawString(screen, &default8x16Font, x, y, str, white());
|
||||
|
||||
mark_rect_as_modified(x, y-char_h, x+char_w, y, 0);
|
||||
char_col++;
|
||||
|
||||
} else if (in_passwd) {
|
||||
if (keysym == XK_BackSpace || keysym == XK_Delete) {
|
||||
if (p_cnt > 0) {
|
||||
pass[p_cnt-1] = '\0';
|
||||
p_cnt--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (keysym == XK_Return || keysym == XK_Linefeed) {
|
||||
in_login = 0;
|
||||
in_passwd = 0;
|
||||
pass[p_cnt++] = '\n';
|
||||
unixpw_verify(user, pass);
|
||||
return;
|
||||
}
|
||||
if (keysym <= ' ' || keysym >= 0x7f) {
|
||||
return;
|
||||
}
|
||||
if (p_cnt >= nmax - 2) {
|
||||
rfbLog("unixpw_deny: password too long\n");
|
||||
unixpw_deny();
|
||||
return;
|
||||
}
|
||||
pass[p_cnt++] = (char) keysym;
|
||||
}
|
||||
}
|
||||
|
||||
void unixpw_accept(void) {
|
||||
unixpw_in_progress = 0;
|
||||
unixpw_client = NULL;
|
||||
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
|
||||
}
|
||||
|
||||
void unixpw_deny(void) {
|
||||
int x, y, i;
|
||||
char pd[] = "Permission denied.";
|
||||
|
||||
char_row += 2;
|
||||
char_col = 0;
|
||||
x = char_x + char_col * char_w;
|
||||
y = char_y + char_row * char_h;
|
||||
|
||||
rfbDrawString(screen, &default8x16Font, x, y, pd, white());
|
||||
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
rfbPE(-1);
|
||||
usleep(500 * 1000);
|
||||
}
|
||||
|
||||
rfbCloseClient(unixpw_client);
|
||||
rfbClientConnectionGone(unixpw_client);
|
||||
rfbPE(-1);
|
||||
|
||||
unixpw_in_progress = 0;
|
||||
unixpw_client = NULL;
|
||||
copy_screen();
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
#ifndef _X11VNC_UNIXPW_H
|
||||
#define _X11VNC_UNIXPW_H
|
||||
|
||||
/* -- unixpw.h -- */
|
||||
|
||||
extern void unixpw_screen(int init);
|
||||
extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
|
||||
extern void unixpw_accept(void);
|
||||
extern void unixpw_deny(void);
|
||||
|
||||
extern int unixpw_in_progress;
|
||||
extern time_t unixpw_last_try_time;
|
||||
extern rfbClientPtr unixpw_client;
|
||||
|
||||
#endif /* _X11VNC_UNIXPW_H */
|
Loading…
Reference in new issue