/* Copyright (C) 2002-2009 Karl J. Runge All rights reserved. This file is part of x11vnc. x11vnc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. x11vnc is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with x11vnc; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA or see . In addition, as a special exception, Karl J. Runge gives permission to link the code of its release of x11vnc with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ /* -- unixpw.c -- */ #ifdef __linux__ /* some conflict with _XOPEN_SOURCE */ extern int grantpt(int); extern int unlockpt(int); extern char *ptsname(int); /* XXX remove need for this */ extern char *crypt(const char*, const char *); #endif #include "x11vnc.h" #include "scan.h" #include "cleanup.h" #include "xinerama.h" #include "connections.h" #include "user.h" #include "connections.h" #include "sslhelper.h" #include "cursor.h" #include #if LIBVNCSERVER_HAVE_FORK #if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID #define UNIXPW_SU #endif #endif #ifdef IGNORE_GETSPNAM #undef LIBVNCSERVER_HAVE_GETSPNAM #define LIBVNCSERVER_HAVE_GETSPNAM 0 #endif #if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM #if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT #define UNIXPW_CRYPT #if LIBVNCSERVER_HAVE_GETSPNAM #include #endif #endif #endif #if LIBVNCSERVER_HAVE_SYS_IOCTL_H #include #endif #if LIBVNCSERVER_HAVE_TERMIOS_H #include #endif #if LIBVNCSERVER_HAVE_SYS_STROPTS_H #include #endif #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) #define IS_BSD #endif #if (defined(__MACH__) && defined(__APPLE__)) #define IS_BSD #endif int white_pixel(void); void unixpw_screen(int init); void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); void unixpw_accept(char *user); void unixpw_deny(void); void unixpw_msg(char *msg, int delay); int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp); int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n); int crypt_verify(char *user, char *pass); int cmd_verify(char *user, char *pass); void unixpw_verify_screen(char *user, char *pass); static int text_x(void); static int text_y(void); static void set_db(void); int unixpw_in_progress = 0; int unixpw_denied = 0; int unixpw_in_rfbPE = 0; int unixpw_login_viewonly = 0; int unixpw_tightvnc_xfer_save = 0; rfbBool unixpw_file_xfer_save = FALSE; time_t unixpw_last_try_time = 0; rfbClientPtr unixpw_client = NULL; int keep_unixpw = 0; char *keep_unixpw_user = NULL; char *keep_unixpw_pass = NULL; char *keep_unixpw_opts = NULL; /////// static unsigned char default6x13FontData[2899]={ 0x00,0x00,0xA8,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0xA8,0x00,0x00, /* 0 */ 0x00,0x00,0x00,0x00,0x20,0x70,0xF8,0x70,0x20,0x00,0x00,0x00,0x00, /* 1 */ 0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8, /* 2 */ 0x00,0x00,0xA0,0xA0,0xE0,0xA0,0xA0,0x38,0x10,0x10,0x10,0x00,0x00, /* 3 */ 0x00,0x00,0xE0,0x80,0xC0,0x80,0xB8,0x20,0x30,0x20,0x20,0x00,0x00, /* 4 */ 0x00,0x00,0x60,0x80,0x80,0x60,0x30,0x28,0x30,0x28,0x28,0x00,0x00, /* 5 */ 0x00,0x00,0x80,0x80,0x80,0xE0,0x38,0x20,0x30,0x20,0x20,0x00,0x00, /* 6 */ 0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7 */ 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 8 */ 0x00,0x00,0x90,0xD0,0xB0,0x90,0x20,0x20,0x20,0x20,0x38,0x00,0x00, /* 9 */ 0x00,0x00,0xA0,0xA0,0xA0,0x40,0x40,0x38,0x10,0x10,0x10,0x00,0x00, /* 10 */ 0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, /* 11 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 13 */ 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, /* 14 */ 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 15 */ 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 */ 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 17 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 18 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00, /* 19 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, /* 20 */ 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 21 */ 0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 22 */ 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 24 */ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* 25 */ 0x00,0x00,0x00,0x18,0x60,0x80,0x60,0x18,0x00,0xF8,0x00,0x00,0x00, /* 26 */ 0x00,0x00,0x00,0xC0,0x30,0x08,0x30,0xC0,0x00,0xF8,0x00,0x00,0x00, /* 27 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x50,0x50,0x50,0x50,0x50,0x00,0x00, /* 28 */ 0x00,0x00,0x00,0x00,0x00,0x08,0xF8,0x20,0xF8,0x80,0x00,0x00,0x00, /* 29 */ 0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 30 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 */ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, /* 33 */ 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 34 */ 0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00,0x00,0x00, /* 35 */ 0x00,0x00,0x20,0x78,0xA0,0xA0,0x70,0x28,0x28,0xF0,0x20,0x00,0x00, /* 36 */ 0x00,0x00,0x48,0xA8,0x50,0x10,0x20,0x40,0x50,0xA8,0x90,0x00,0x00, /* 37 */ 0x00,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA0,0x98,0x90,0x68,0x00,0x00, /* 38 */ 0x00,0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 39 */ 0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, /* 40 */ 0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, /* 41 */ 0x00,0x00,0x00,0x20,0xA8,0xF8,0x70,0xF8,0xA8,0x20,0x00,0x00,0x00, /* 42 */ 0x00,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00,0x00, /* 43 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x40,0x00, /* 44 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, /* 45 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00, /* 46 */ 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00,0x00, /* 47 */ 0x00,0x00,0x20,0x50,0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x00, /* 48 */ 0x00,0x00,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, /* 49 */ 0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 50 */ 0x00,0x00,0xF8,0x08,0x10,0x20,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 51 */ 0x00,0x00,0x10,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, /* 52 */ 0x00,0x00,0xF8,0x80,0x80,0xB0,0xC8,0x08,0x08,0x88,0x70,0x00,0x00, /* 53 */ 0x00,0x00,0x70,0x88,0x80,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, /* 54 */ 0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, /* 55 */ 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 56 */ 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, /* 57 */ 0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x20,0x70,0x20,0x00, /* 58 */ 0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x30,0x20,0x40,0x00, /* 59 */ 0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, /* 60 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 61 */ 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, /* 62 */ 0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, /* 63 */ 0x00,0x00,0x70,0x88,0x88,0x98,0xA8,0xA8,0xB0,0x80,0x78,0x00,0x00, /* 64 */ 0x00,0x00,0x20,0x50,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0x00, /* 65 */ 0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, /* 66 */ 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, /* 67 */ 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, /* 68 */ 0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF8,0x00,0x00, /* 69 */ 0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 70 */ 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x98,0x88,0x88,0x70,0x00,0x00, /* 71 */ 0x00,0x00,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0x00,0x00, /* 72 */ 0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 73 */ 0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, /* 74 */ 0x00,0x00,0x88,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 75 */ 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00, /* 76 */ 0x00,0x00,0x88,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00,0x00, /* 77 */ 0x00,0x00,0x88,0xC8,0xC8,0xA8,0xA8,0x98,0x98,0x88,0x88,0x00,0x00, /* 78 */ 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 79 */ 0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 80 */ 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0xA8,0x70,0x08,0x00, /* 81 */ 0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 82 */ 0x00,0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 83 */ 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 84 */ 0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 85 */ 0x00,0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00,0x00, /* 86 */ 0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 87 */ 0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0x88,0x00,0x00, /* 88 */ 0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 89 */ 0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0xF8,0x00,0x00, /* 90 */ 0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, /* 91 */ 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00,0x00, /* 92 */ 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, /* 93 */ 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 94 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, /* 95 */ 0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 96 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 97 */ 0x00,0x00,0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0xF0,0x00,0x00, /* 98 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x00,0x00, /* 99 */ 0x00,0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, /* 100 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 101 */ 0x00,0x00,0x30,0x48,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x00,0x00, /* 102 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x88,0x70, /* 103 */ 0x00,0x00,0x80,0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 104 */ 0x00,0x00,0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 105 */ 0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x90,0x60, /* 106 */ 0x00,0x00,0x80,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00,0x00, /* 107 */ 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 108 */ 0x00,0x00,0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x88,0x00,0x00, /* 109 */ 0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 110 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 111 */ 0x00,0x00,0x00,0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80, /* 112 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x08, /* 113 */ 0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x80,0x00,0x00, /* 114 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x60,0x10,0x88,0x70,0x00,0x00, /* 115 */ 0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, /* 116 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 117 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x00,0x00, /* 118 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 119 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 120 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 121 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 122 */ 0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, /* 123 */ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 124 */ 0x00,0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, /* 125 */ 0x00,0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 126 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 */ 0x00,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 161 */ 0x00,0x00,0x20,0x70,0xA8,0xA0,0xA0,0xA8,0x70,0x20,0x00,0x00,0x00, /* 162 */ 0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 163 */ 0x00,0x00,0x00,0x00,0x88,0x70,0x50,0x50,0x70,0x88,0x00,0x00,0x00, /* 164 */ 0x00,0x00,0x88,0x88,0x50,0x50,0xF8,0x20,0xF8,0x20,0x20,0x00,0x00, /* 165 */ 0x00,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, /* 166 */ 0x00,0x30,0x48,0x40,0x30,0x48,0x48,0x30,0x08,0x48,0x30,0x00,0x00, /* 167 */ 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168 */ 0x00,0x70,0x88,0xA8,0xD8,0xC8,0xD8,0xA8,0x88,0x70,0x00,0x00,0x00, /* 169 */ 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0xF8,0x00,0x00,0x00,0x00, /* 170 */ 0x00,0x00,0x00,0x00,0x28,0x50,0xA0,0xA0,0x50,0x28,0x00,0x00,0x00, /* 171 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00, /* 172 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00, /* 173 */ 0x00,0x70,0x88,0xE8,0xD8,0xD8,0xE8,0xD8,0x88,0x70,0x00,0x00,0x00, /* 174 */ 0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 175 */ 0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 */ 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 177 */ 0x00,0x40,0xA0,0x20,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 178 */ 0x00,0x40,0xA0,0x40,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 179 */ 0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 180 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0xE8,0x80,0x80, /* 181 */ 0x00,0x00,0x78,0xE8,0xE8,0xE8,0xE8,0x68,0x28,0x28,0x28,0x00,0x00, /* 182 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20, /* 184 */ 0x00,0x40,0xC0,0x40,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 185 */ 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0xF8,0x00,0x00,0x00,0x00, /* 186 */ 0x00,0x00,0x00,0x00,0xA0,0x50,0x28,0x28,0x50,0xA0,0x00,0x00,0x00, /* 187 */ 0x00,0x40,0xC0,0x40,0x40,0xE0,0x08,0x18,0x28,0x38,0x08,0x00,0x00, /* 188 */ 0x00,0x40,0xC0,0x40,0x40,0xE0,0x10,0x28,0x08,0x10,0x38,0x00,0x00, /* 189 */ 0x00,0x40,0xA0,0x40,0x20,0xA0,0x48,0x18,0x28,0x38,0x08,0x00,0x00, /* 190 */ 0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x80,0x88,0x88,0x70,0x00,0x00, /* 191 */ 0x00,0x40,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 192 */ 0x00,0x10,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 193 */ 0x00,0x30,0x48,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 194 */ 0x00,0x28,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 195 */ 0x00,0x50,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 196 */ 0x00,0x20,0x50,0x20,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 197 */ 0x00,0x00,0x58,0xA0,0xA0,0xA0,0xB0,0xE0,0xA0,0xA0,0xB8,0x00,0x00, /* 198 */ 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x20,0x40, /* 199 */ 0x00,0x40,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 200 */ 0x00,0x10,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 201 */ 0x00,0x30,0x48,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 202 */ 0x00,0x50,0x50,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 203 */ 0x00,0x40,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 204 */ 0x00,0x10,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 205 */ 0x00,0x30,0x48,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 206 */ 0x00,0x50,0x50,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 207 */ 0x00,0x00,0xF0,0x48,0x48,0x48,0xE8,0x48,0x48,0x48,0xF0,0x00,0x00, /* 208 */ 0x00,0x28,0x50,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00,0x00, /* 209 */ 0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 210 */ 0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 211 */ 0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 212 */ 0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 213 */ 0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 214 */ 0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00, /* 215 */ 0x00,0x08,0x70,0x98,0x98,0xA8,0xA8,0xA8,0xC8,0xC8,0x70,0x80,0x00, /* 216 */ 0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 217 */ 0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 218 */ 0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 219 */ 0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 220 */ 0x00,0x10,0x20,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, /* 221 */ 0x00,0x00,0x80,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x00,0x00, /* 222 */ 0x00,0x00,0x60,0x90,0x90,0xA0,0xA0,0x90,0x88,0x88,0xB0,0x00,0x00, /* 223 */ 0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 224 */ 0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 225 */ 0x00,0x00,0x30,0x48,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 226 */ 0x00,0x00,0x28,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 227 */ 0x00,0x00,0x50,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 228 */ 0x00,0x30,0x48,0x30,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 229 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x28,0x70,0xA0,0xA8,0x50,0x00,0x00, /* 230 */ 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x20,0x40, /* 231 */ 0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 232 */ 0x00,0x00,0x10,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 233 */ 0x00,0x00,0x30,0x48,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 234 */ 0x00,0x00,0x50,0x50,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 235 */ 0x00,0x00,0x40,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 236 */ 0x00,0x00,0x10,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 237 */ 0x00,0x00,0x30,0x48,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 238 */ 0x00,0x00,0x50,0x50,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 239 */ 0x00,0x50,0x20,0x60,0x10,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 240 */ 0x00,0x00,0x28,0x50,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 241 */ 0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 242 */ 0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 243 */ 0x00,0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 244 */ 0x00,0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 245 */ 0x00,0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 246 */ 0x00,0x00,0x00,0x20,0x20,0x00,0xF8,0x00,0x20,0x20,0x00,0x00,0x00, /* 247 */ 0x00,0x00,0x00,0x00,0x08,0x70,0x98,0xA8,0xA8,0xC8,0x70,0x80,0x00, /* 248 */ 0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 249 */ 0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 250 */ 0x00,0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 251 */ 0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 252 */ 0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 253 */ 0x00,0x00,0x00,0x80,0x80,0xB0,0xC8,0x88,0x88,0xC8,0xB0,0x80,0x80, /* 254 */ 0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 255 */ }; static int default6x13FontMetaData[256*5]={ 0,6,13,0,-2,13,6,13,0,-2,26,6,13,0,-2,39,6,13,0,-2,52,6,13,0,-2,65,6,13,0,-2,78,6,13,0,-2,91,6,13,0,-2,104,6,13,0,-2,117,6,13,0,-2,130,6,13,0,-2,143,6,13,0,-2,156,6,13,0,-2,169,6,13,0,-2,182,6,13,0,-2,195,6,13,0,-2,208,6,13,0,-2,221,6,13,0,-2,234,6,13,0,-2,247,6,13,0,-2,260,6,13,0,-2,273,6,13,0,-2,286,6,13,0,-2,299,6,13,0,-2,312,6,13,0,-2,325,6,13,0,-2,338,6,13,0,-2,351,6,13,0,-2,364,6,13,0,-2,377,6,13,0,-2,390,6,13,0,-2,403,6,13,0,-2,416,6,13,0,-2,429,6,13,0,-2,442,6,13,0,-2,455,6,13,0,-2,468,6,13,0,-2,481,6,13,0,-2,494,6,13,0,-2,507,6,13,0,-2,520,6,13,0,-2,533,6,13,0,-2,546,6,13,0,-2,559,6,13,0,-2,572,6,13,0,-2,585,6,13,0,-2,598,6,13,0,-2,611,6,13,0,-2,624,6,13,0,-2,637,6,13,0,-2,650,6,13,0,-2,663,6,13,0,-2,676,6,13,0,-2,689,6,13,0,-2,702,6,13,0,-2,715,6,13,0,-2,728,6,13,0,-2,741,6,13,0,-2,754,6,13,0,-2,767,6,13,0,-2,780,6,13,0,-2,793,6,13,0,-2,806,6,13,0,-2,819,6,13,0,-2,832,6,13,0,-2,845,6,13,0,-2,858,6,13,0,-2,871,6,13,0,-2,884,6,13,0,-2,897,6,13,0,-2,910,6,13,0,-2,923,6,13,0,-2,936,6,13,0,-2,949,6,13,0,-2,962,6,13,0,-2,975,6,13,0,-2,988,6,13,0,-2,1001,6,13,0,-2,1014,6,13,0,-2,1027,6,13,0,-2,1040,6,13,0,-2,1053,6,13,0,-2,1066,6,13,0,-2,1079,6,13,0,-2,1092,6,13,0,-2,1105,6,13,0,-2,1118,6,13,0,-2,1131,6,13,0,-2,1144,6,13,0,-2,1157,6,13,0,-2,1170,6,13,0,-2,1183,6,13,0,-2,1196,6,13,0,-2,1209,6,13,0,-2,1222,6,13,0,-2,1235,6,13,0,-2,1248,6,13,0,-2,1261,6,13,0,-2,1274,6,13,0,-2,1287,6,13,0,-2,1300,6,13,0,-2,1313,6,13,0,-2,1326,6,13,0,-2,1339,6,13,0,-2,1352,6,13,0,-2,1365,6,13,0,-2,1378,6,13,0,-2,1391,6,13,0,-2,1404,6,13,0,-2,1417,6,13,0,-2,1430,6,13,0,-2,1443,6,13,0,-2,1456,6,13,0,-2,1469,6,13,0,-2,1482,6,13,0,-2,1495,6,13,0,-2,1508,6,13,0,-2,1521,6,13,0,-2,1534,6,13,0,-2,1547,6,13,0,-2,1560,6,13,0,-2,1573,6,13,0,-2,1586,6,13,0,-2,1599,6,13,0,-2,1612,6,13,0,-2,1625,6,13,0,-2,1638,6,13,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1651,6,13,0,-2,1664,6,13,0,-2,1677,6,13,0,-2,1690,6,13,0,-2,1703,6,13,0,-2,1716,6,13,0,-2,1729,6,13,0,-2,1742,6,13,0,-2,1755,6,13,0,-2,1768,6,13,0,-2,1781,6,13,0,-2,1794,6,13,0,-2,1807,6,13,0,-2,1820,6,13,0,-2,1833,6,13,0,-2,1846,6,13,0,-2,1859,6,13,0,-2,1872,6,13,0,-2,1885,6,13,0,-2,1898,6,13,0,-2,1911,6,13,0,-2,1924,6,13,0,-2,1937,6,13,0,-2,1950,6,13,0,-2,1963,6,13,0,-2,1976,6,13,0,-2,1989,6,13,0,-2,2002,6,13,0,-2,2015,6,13,0,-2,2028,6,13,0,-2,2041,6,13,0,-2,2054,6,13,0,-2,2067,6,13,0,-2,2080,6,13,0,-2,2093,6,13,0,-2,2106,6,13,0,-2,2119,6,13,0,-2,2132,6,13,0,-2,2145,6,13,0,-2,2158,6,13,0,-2,2171,6,13,0,-2,2184,6,13,0,-2,2197,6,13,0,-2,2210,6,13,0,-2,2223,6,13,0,-2,2236,6,13,0,-2,2249,6,13,0,-2,2262,6,13,0,-2,2275,6,13,0,-2,2288,6,13,0,-2,2301,6,13,0,-2,2314,6,13,0,-2,2327,6,13,0,-2,2340,6,13,0,-2,2353,6,13,0,-2,2366,6,13,0,-2,2379,6,13,0,-2,2392,6,13,0,-2,2405,6,13,0,-2,2418,6,13,0,-2,2431,6,13,0,-2,2444,6,13,0,-2,2457,6,13,0,-2,2470,6,13,0,-2,2483,6,13,0,-2,2496,6,13,0,-2,2509,6,13,0,-2,2522,6,13,0,-2,2535,6,13,0,-2,2548,6,13,0,-2,2561,6,13,0,-2,2574,6,13,0,-2,2587,6,13,0,-2,2600,6,13,0,-2,2613,6,13,0,-2,2626,6,13,0,-2,2639,6,13,0,-2,2652,6,13,0,-2,2665,6,13,0,-2,2678,6,13,0,-2,2691,6,13,0,-2,2704,6,13,0,-2,2717,6,13,0,-2,2730,6,13,0,-2,2743,6,13,0,-2,2756,6,13,0,-2,2769,6,13,0,-2,2782,6,13,0,-2,2795,6,13,0,-2,2808,6,13,0,-2,2821,6,13,0,-2,2834,6,13,0,-2,2847,6,13,0,-2,2860,6,13,0,-2,2873,6,13,0,-2,2886,6,13,0,-2,}; static rfbFontData default6x13Font={default6x13FontData, default6x13FontMetaData}; /////// 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 db = 0; int white_pixel(void) { static unsigned long black_pix = 0, white_pix = 1, set = 0; RAWFB_RET(0xffffff) 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; } } int black_pixel(void) { static unsigned long black_pix = 0, white_pix = 1, set = 0; RAWFB_RET(0x000000) 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) black_pix; } else if (depth < 24) { return 0x0000; } else { return 0x000000; } } static void unixpw_mark(void) { if (scaling) { mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1); } else { mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); } } static int text_x(void) { return char_x + char_col * char_w; } static int text_y(void) { return char_y + char_row * char_h; } static rfbScreenInfo fscreen; static rfbScreenInfoPtr pscreen; static int f1_help = 0; void unixpw_screen(int init) { if (unixpw_cmd) { ; /* OK */ } else if (unixpw_nis) { #ifndef UNIXPW_CRYPT rfbLog("-unixpw_nis is not supported on this OS/machine\n"); clean_up_exit(1); #endif } else { #ifndef UNIXPW_SU 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); mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x); y = (int) (dpy_y / 3.5); if (scaling) { x = (int) (x * scale_fac_x); y = (int) (y * scale_fac_y); x = nfix(x, scaled_x); y = nfix(y, scaled_y); } if (rotating) { fscreen.serverFormat.bitsPerPixel = bpp; fscreen.paddedWidthInBytes = rfb_bytes_per_line; fscreen.frameBuffer = rfb_fb; pscreen = &fscreen; } else { pscreen = screen; } if (pscreen && pscreen->width >= 640) { rfbDrawString(pscreen, &default6x13Font, 8, 2+1*13, "F1-Help:", white_pixel()); } f1_help = 0; if (unixpw_system_greeter) { unixpw_system_greeter_active = 0; if (use_dpy && strstr(use_dpy, "xdmcp")) { if (getenv("X11VNC_SYSTEM_GREETER1")) { char moo[] = "Press 'Escape' for System Greeter"; rfbDrawString(pscreen, &default8x16Font, x-90, y-30, moo, white_pixel()); } else { char moo1[] = "Press 'Escape' for New Session via System Greeter,"; char moo2[] = "or otherwise login here for Existing Session: "; rfbDrawString(pscreen, &default6x13Font, x-110, y-38, moo1, white_pixel()); rfbDrawString(pscreen, &default6x13Font, x-110, y-25, moo2, white_pixel()); } set_env("X11VNC_XDM_ONLY", "0"); unixpw_system_greeter_active = 1; } } rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel()); char_x = x; char_y = y; char_col = strlen(log); char_row = 0; set_warrow_cursor(); } unixpw_mark(); } #ifdef MAXPATHLEN static char slave_str[MAXPATHLEN]; #else static char slave_str[4096]; #endif static int used_get_pty_ptmx = 0; char *get_pty_ptmx(int *fd_p) { char *slave; int fd = -1, i, ndevs = 4, tmp; char *devs[] = { "/dev/ptmx", "/dev/ptm/clone", "/dev/ptc", "/dev/ptmx_bsd" }; *fd_p = -1; #if LIBVNCSERVER_HAVE_GRANTPT for (i=0; i < ndevs; i++) { #ifdef O_NOCTTY fd = open(devs[i], O_RDWR|O_NOCTTY); #else fd = open(devs[i], O_RDWR); #endif if (fd >= 0) { break; } } if (fd < 0) { rfbLogPerror("open /dev/ptmx"); return NULL; } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCPKT) tmp = 0; ioctl(fd, TIOCPKT, (char *) &tmp); #endif if (grantpt(fd) != 0) { rfbLogPerror("grantpt"); close(fd); return NULL; } if (unlockpt(fd) != 0) { rfbLogPerror("unlockpt"); close(fd); return NULL; } slave = ptsname(fd); if (! slave) { rfbLogPerror("ptsname"); close(fd); return NULL; } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH) ioctl(fd, TIOCFLUSH, (char *) 0); #endif strcpy(slave_str, slave); *fd_p = fd; return slave_str; #else return NULL; #endif /* GRANTPT */ } char *get_pty_loop(int *fd_p) { char master_str[16]; int fd = -1, i; char c; *fd_p = -1; /* for *BSD loop over /dev/ptyXY */ for (c = 'p'; c <= 'z'; c++) { for (i=0; i < 16; i++) { sprintf(master_str, "/dev/pty%c%x", c, i); #ifdef O_NOCTTY fd = open(master_str, O_RDWR|O_NOCTTY); #else fd = open(master_str, O_RDWR); #endif if (fd >= 0) { break; } } if (fd >= 0) { break; } } if (fd < 0) { return NULL; } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH) ioctl(fd, TIOCFLUSH, (char *) 0); #endif sprintf(slave_str, "/dev/tty%c%x", c, i); *fd_p = fd; return slave_str; } char *get_pty(int *fd_p) { used_get_pty_ptmx = 0; if (getenv("BSD_PTY")) { return get_pty_loop(fd_p); } #ifdef IS_BSD return get_pty_loop(fd_p); #else #if LIBVNCSERVER_HAVE_GRANTPT used_get_pty_ptmx = 1; return get_pty_ptmx(fd_p); #else return get_pty_loop(fd_p); #endif #endif } void try_to_be_nobody(void) { #if LIBVNCSERVER_HAVE_PWD_H struct passwd *pw; pw = getpwnam("nobody"); if (pw) { #if LIBVNCSERVER_HAVE_SETUID setuid(pw->pw_uid); #endif #if LIBVNCSERVER_HAVE_SETEUID seteuid(pw->pw_uid); #endif #if LIBVNCSERVER_HAVE_SETGID setgid(pw->pw_gid); #endif #if LIBVNCSERVER_HAVE_SETEGID setegid(pw->pw_gid); #endif } #endif /* PWD_H */ } static int slave_fd = -1, alarm_fired = 0; static void close_alarm (int sig) { if (slave_fd >= 0) { close(slave_fd); } alarm_fired = 1; if (0) sig = 0; /* compiler warning */ } static void kill_child (pid_t pid, int fd) { int status; slave_fd = -1; alarm_fired = 0; if (fd >= 0) { close(fd); } kill(pid, SIGTERM); waitpid(pid, &status, WNOHANG); } static int scheck(char *str, int n, char *name) { int j, i; if (! str) { return 0; } j = 0; for (i=0; i= 0x7f) { rfbLog("scheck: invalid character in %s.\n", name); return 0; } } if (j == 0) { rfbLog("scheck: unterminated string in %s.\n", name); return 0; } return 1; } int unixpw_list_match(char *user) { if (! unixpw_list || unixpw_list[0] == '\0') { return 1; } else { char *p, *q, *str = strdup(unixpw_list); int ok = 0; int notmode = 0; if (str[0] == '!') { notmode = 1; ok = 1; p = strtok(str+1, ","); } else { p = strtok(str, ","); } while (p) { if ( (q = strchr(p, ':')) != NULL ) { *q = '\0'; /* get rid of options. */ } if (!strcmp(user, p)) { if (notmode) { ok = 0; } else { ok = 1; } break; } if (!notmode && !strcmp("*", p)) { ok = 1; break; } p = strtok(NULL, ","); } free(str); if (! ok) { rfbLog("unixpw_list_match: fail for '%s'\n", user); return 0; } else { rfbLog("unixpw_list_match: OK for '%s'\n", user); return 1; } } } int crypt_verify(char *user, char *pass) { #ifndef UNIXPW_CRYPT return 0; #else struct passwd *pwd; char *realpw, *cr; int n; if (! scheck(user, 100, "username")) { return 0; } if (! scheck(pass, 100, "password")) { return 0; } if (! unixpw_list_match(user)) { return 0; } pwd = getpwnam(user); if (! pwd) { return 0; } realpw = pwd->pw_passwd; if (realpw == NULL || realpw[0] == '\0') { return 0; } if (db > 1) fprintf(stderr, "realpw='%s'\n", realpw); if (strlen(realpw) < 12) { /* 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); if (pass[n-1] == '\n') { pass[n-1] = '\0'; } /* XXX remove need for cast */ 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) { return 0; } if (!strcmp(cr, realpw)) { return 1; } else { return 0; } #endif /* UNIXPW_CRYPT */ } int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n) { int i, len, rc; char *str; FILE *out; if (! user || ! pass) { return 0; } if (! unixpw_cmd || *unixpw_cmd == '\0') { return 0; } if (! scheck(user, 100, "username")) { return 0; } if (! scheck(pass, 100, "password")) { return 0; } if (! unixpw_list_match(user)) { return 0; } if (cmd == NULL) { cmd = ""; } len = strlen(user) + 1 + strlen(pass) + 1 + 1; str = (char *) malloc(len); if (! str) { return 0; } str[0] = '\0'; strcat(str, user); strcat(str, "\n"); strcat(str, pass); if (!strchr(pass, '\n')) { strcat(str, "\n"); } out = tmpfile(); if (out == NULL) { rfbLog("unixpw_cmd_run tmpfile() failed.\n"); clean_up_exit(1); } set_env("RFB_UNIXPW_CMD_RUN", cmd); rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify", str, strlen(str), out); set_env("RFB_UNIXPW_CMD_RUN", ""); for (i=0; i < len; i++) { str[i] = '\0'; } free(str); fflush(out); rewind(out); for (i=0; i < (*n) - 1; i++) { int c = fgetc(out); if (c == EOF) { break; } line[i] = (char) c; } fclose(out); *n = i; if (rc == 0) { return 1; } else { return 0; } } int cmd_verify(char *user, char *pass) { int i, len, rc; char *str; if (! user || ! pass) { return 0; } if (! unixpw_cmd || *unixpw_cmd == '\0') { return 0; } if (! scheck(user, 100, "username")) { return 0; } if (! scheck(pass, 100, "password")) { return 0; } if (! unixpw_list_match(user)) { return 0; } if (unixpw_client) { ClientData *cd = (ClientData *) unixpw_client->clientData; if (cd) { cd->username = strdup(user); } } len = strlen(user) + 1 + strlen(pass) + 1 + 1; str = (char *) malloc(len); if (! str) { return 0; } str[0] = '\0'; strcat(str, user); strcat(str, "\n"); strcat(str, pass); if (!strchr(pass, '\n')) { strcat(str, "\n"); } rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify", str, strlen(str), NULL); for (i=0; i < len; i++) { str[i] = '\0'; } free(str); if (rc == 0) { return 1; } else { return 0; } } int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp) { #ifndef UNIXPW_SU return 0; #else int i, j, status, fd = -1, sfd, tfd, drain_size = 65536, rsize = 0; int slow_pw = 1; char *slave, *bin_true = NULL, *bin_su = NULL; pid_t pid, pidw; struct stat sbuf; static int first = 1; char instr[32], cbuf[10]; if (first) { set_db(); first = 0; } rfbLog("su_verify: '%s' for %s.\n", user, cmd ? "command" : "login"); if (! scheck(user, 100, "username")) { return 0; } if (! scheck(pass, 100, "password")) { return 0; } if (! unixpw_list_match(user)) { return 0; } /* unixpw */ if (no_external_cmds || !cmd_ok("unixpw")) { rfbLog("su_verify: cannot run external commands.\n"); clean_up_exit(1); } #define SU_DEBUG 0 #if SU_DEBUG if (stat("/su", &sbuf) == 0) { bin_su = "/su"; /* Freesbie read-only-fs /bin/su not suid! */ #else if (0) { ; #endif } else if (stat("/bin/su", &sbuf) == 0) { bin_su = "/bin/su"; } else if (stat("/usr/bin/su", &sbuf) == 0) { bin_su = "/usr/bin/su"; } if (bin_su == NULL) { rfbLogPerror("existence /bin/su"); return 0; } if (stat("/bin/true", &sbuf) == 0) { bin_true = "/bin/true"; } if (stat("/usr/bin/true", &sbuf) == 0) { bin_true = "/usr/bin/true"; } if (cmd != NULL && cmd[0] != '\0') { /* this is for ext. cmd su -c "my cmd" after login */ bin_true = cmd; } if (bin_true == NULL) { rfbLogPerror("existence /bin/true"); return 0; } slave = get_pty(&fd); if (slave == NULL) { rfbLogPerror("get_pty failed."); return 0; } if (db) fprintf(stderr, "cmd is: %s\n", cmd); if (db) fprintf(stderr, "slave is: %s fd=%d\n", slave, fd); if (fd < 0) { rfbLogPerror("get_pty fd < 0"); return 0; } fcntl(fd, F_SETFD, 1); pid = fork(); if (pid < 0) { rfbLogPerror("fork"); close(fd); return 0; } if (pid == 0) { /* child */ int ttyfd; ttyfd = -1; /* compiler warning */ #if LIBVNCSERVER_HAVE_SETSID if (setsid() == -1) { perror("setsid"); exit(1); } #else if (setpgrp() == -1) { perror("setpgrp"); exit(1); } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCNOTTY) ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { (void) ioctl(ttyfd, TIOCNOTTY, (char *) 0); close(ttyfd); } #endif #endif /* SETSID */ close(0); close(1); close(2); sfd = open(slave, O_RDWR); if (sfd < 0) { exit(1); } /* streams options fixups, handle cases as they are found: */ #if defined(__hpux) #if LIBVNCSERVER_HAVE_SYS_STROPTS_H #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(I_PUSH) if (used_get_pty_ptmx) { ioctl(sfd, I_PUSH, "ptem"); ioctl(sfd, I_PUSH, "ldterm"); ioctl(sfd, I_PUSH, "ttcompat"); } #endif #endif #endif /* n.b. sfd will be 0 since we closed 0. so dup it to 1 and 2 */ if (fcntl(sfd, F_DUPFD, 1) == -1) { exit(1); } if (fcntl(sfd, F_DUPFD, 2) == -1) { exit(1); } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSCTTY) ioctl(sfd, TIOCSCTTY, (char *) 0); #endif if (db > 2) { char nam[256]; unlink("/tmp/isatty"); tfd = open("/tmp/isatty", O_CREAT|O_WRONLY, 0600); if (isatty(sfd)) { close(tfd); sprintf(nam, "stty -a < %s > /tmp/isatty 2>&1", slave); system(nam); } else { write(tfd, "NOTTTY\n", 7); close(tfd); } } chdir("/"); try_to_be_nobody(); #if LIBVNCSERVER_HAVE_GETUID if (getuid() == 0 || geteuid() == 0) { exit(1); } #else exit(1); #endif set_env("LC_ALL", "C"); set_env("LANG", "C"); set_env("SHELL", "/bin/sh"); if (nodisp) { /* this will cause timeout problems with pam_xauth */ int k; for (k=0; k<3; k++) { if (getenv("DISPLAY")) { char *s = getenv("DISPLAY"); if (s) *(s-2) = '_'; /* quite... */ } if (getenv("XAUTHORITY")) { char *s = getenv("XAUTHORITY"); if (s) *(s-2) = '_'; /* quite... */ } } } /* synchronize with parent: */ write(2, "C", 1); if (cmd) { execlp(bin_su, bin_su, "-", user, "-c", bin_true, (char *) NULL); } else { execlp(bin_su, bin_su, user, "-c", bin_true, (char *) NULL); } exit(1); } /* parent */ if (db) fprintf(stderr, "pid: %d\n", pid); /* * set an alarm for blocking read() to close the master * (presumably terminating the child. SIGTERM too...) */ slave_fd = fd; alarm_fired = 0; signal(SIGALRM, close_alarm); alarm(10); /* synchronize with child: */ cbuf[0] = '\0'; cbuf[1] = '\0'; for (i=0; i<10; i++) { int n; cbuf[0] = '\0'; cbuf[1] = '\0'; n = read(fd, cbuf, 1); if (n < 0 && errno == EINTR) { continue; } else { break; } } if (db) { fprintf(stderr, "read from child: '%s'\n", cbuf); } alarm(0); signal(SIGALRM, SIG_DFL); if (alarm_fired) { kill_child(pid, fd); return 0; } #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCTRAP) { int control = 1; ioctl(fd, TIOCTRAP, &control); } #endif /* * In addition to checking exit code below, we watch for the * appearance of the string "Password:". BSD does not seem to * ask for a password trying to su to yourself. This is the * setting in /etc/pam.d/su: * auth sufficient pam_self.so * it may be commented out without problem. */ for (i=0; i<32; i++) { instr[i] = '\0'; } alarm_fired = 0; signal(SIGALRM, close_alarm); alarm(10); j = 0; for (i=0; i < (int) strlen("Password:"); i++) { char pstr[] = "password:"; int n; cbuf[0] = '\0'; cbuf[1] = '\0'; n = read(fd, cbuf, 1); if (n < 0 && errno == EINTR) { i--; if (i < 0) i = 0; continue; } if (db) { fprintf(stderr, "%s", cbuf); if (db > 3 && n == 1 && cbuf[0] == ':') { char cmd0[32]; usleep( 100 * 1000 ); fprintf(stderr, "\n\n"); sprintf(cmd0, "ps wu %d", pid); system(cmd0); sprintf(cmd0, "stty -a < %s", slave); system(cmd0); fprintf(stderr, "\n\n"); } } if (n == 1) { if (isspace((unsigned char) cbuf[0])) { i--; if (i < 0) i = 0; continue; } if (j >= 32-1) { rfbLog("su_verify: problem finding Password:\n"); return 0; } instr[j++] = tolower((unsigned char)cbuf[0]); } if (n <= 0 || strstr(pstr, instr) != pstr) { if (db) { fprintf(stderr, "\"Password:\" did not " "appear: '%s'" " n=%d\n", instr, n); if (db > 3 && n == 1 && j < 32) { continue; } } alarm(0); signal(SIGALRM, SIG_DFL); kill_child(pid, fd); return 0; } } alarm(0); signal(SIGALRM, SIG_DFL); if (alarm_fired) { kill_child(pid, fd); return 0; } if (db > 2) fprintf(stderr, "\nsending passwd: %s\n", pass); usleep(100 * 1000); if (slow_pw) { unsigned int k; for (k = 0; k < strlen(pass); k++) { write(fd, pass+k, 1); usleep(100 * 1000); } } else { write(fd, pass, strlen(pass)); } alarm_fired = 0; signal(SIGALRM, close_alarm); alarm(15); /* * try to drain the output, hopefully never as much as 4096 (motd?) * if we don't drain we may block at waitpid. If we close(fd), the * make cause child to die by signal. */ if (rbuf && *rbuf_size > 0) { /* asked to return output of command */ drain_size = *rbuf_size; rsize = 0; } if (db) fprintf(stderr, "\ndraining:\n"); for (i = 0; i< drain_size; i++) { int n; cbuf[0] = '\0'; cbuf[1] = '\0'; n = read(fd, cbuf, 1); if (n < 0 && errno == EINTR) { if (db) fprintf(stderr, "\nEINTR n=%d i=%d --", n, i); i--; if (i < 0) i = 0; continue; } if (db) fprintf(stderr, "\nn=%d i=%d errno=%d %.6f '%s'", n, i, errno, dnowx(), cbuf); if (n <= 0) { break; } if (rbuf && *rbuf_size > 0) { rbuf[rsize++] = cbuf[0]; } } if (db && rbuf) fprintf(stderr, "\nrbuf: '%s'\n", rbuf); if (rbuf && *rbuf_size > 0) { char *s = rbuf; char *p = strdup(pass); int n, o = 0; n = strlen(p); if (p[n-1] == '\n') { p[n-1] = '\0'; } /* * usually is: Password: mypassword\r\n\r\n * and output will have \n -> \r\n */ if (rbuf[0] == ' ') { s++; o++; } if (strstr(s, p) == s) { s += strlen(p); o += strlen(p); for (n = 0; n < 4; n++) { if (s[0] == '\r' || s[0] == '\n') { s++; o++; } } } if (o > 0) { int i = 0; rsize -= o; while (o < drain_size) { rbuf[i++] = rbuf[o++]; } } *rbuf_size = rsize; strzero(p); free(p); } if (db) fprintf(stderr, "\n--\n"); alarm(0); signal(SIGALRM, SIG_DFL); if (alarm_fired) { kill_child(pid, fd); return 0; } slave_fd = -1; pidw = waitpid(pid, &status, 0); close(fd); if (pid != pidw) { return 0; } if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { return 1; /* this is the only return of success. */ } else { return 0; } #endif /* UNIXPW_SU */ } int unixpw_verify(char *user, char *pass) { int ok = 0; if (unixpw_cmd) { if (cmd_verify(user, pass)) { rfbLog("unixpw_verify: cmd_verify login for '%s'" " succeeded.\n", user); ok = 1; } else { rfbLog("unixpw_verify: cmd_verify login for '%s'" " failed.\n", user); usleep(3000*1000); ok = 0; } } else if (unixpw_nis) { if (crypt_verify(user, pass)) { rfbLog("unixpw_verify: crypt_verify login for '%s'" " succeeded.\n", user); ok = 1; } else { rfbLog("unixpw_verify: crypt_verify login for '%s'" " failed.\n", user); usleep(3000*1000); ok = 0; } } else { if (su_verify(user, pass, NULL, NULL, NULL, 1)) { rfbLog("unixpw_verify: su_verify login for '%s'" " succeeded.\n", user); ok = 1; } else { rfbLog("unixpw_verify: su_verify login for '%s'" " failed.\n", user); /* use su(1)'s sleep */ ok = 0; } } return ok; } void unixpw_verify_screen(char *user, char *pass) { int x, y; char li[] = "Login incorrect"; char log[] = "login: "; char *colon = NULL; ClientData *cd = NULL; int ok; if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********"); rfbLog("unixpw_verify: '%s'\n", user ? user : "(null)"); if (user) { colon = strchr(user, ':'); } if (colon) { *colon = '\0'; 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; } } ok = unixpw_verify(user, pass); if (ok) { unixpw_accept(user); if (keep_unixpw) { keep_unixpw_user = strdup(user); keep_unixpw_pass = strdup(pass); if (colon) { keep_unixpw_opts = strdup(colon+1); } else { keep_unixpw_opts = strdup(""); } } if (colon) *colon = ':'; return; } if (colon) *colon = ':'; if (tries < 2) { char_row++; char_col = 0; x = text_x(); y = text_y(); rfbDrawString(pscreen, &default8x16Font, x, y, li, white_pixel()); char_row += 2; x = text_x(); y = text_y(); rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel()); char_col = strlen(log); unixpw_mark(); unixpw_last_try_time = time(NULL); unixpw_keystroke(0, 0, 2); tries++; } else { unixpw_deny(); } } static void set_db(void) { if (getenv("DEBUG_UNIXPW")) { db = atoi(getenv("DEBUG_UNIXPW")); rfbLog("DEBUG_UNIXPW: %d\n", db); } } void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) { int x, y, i, rc, nmax = 100; static char user_r[100], user[100], pass[100]; static int u_cnt = 0, p_cnt = 0, first = 1; static int echo = 1; char keystr[100]; char *str; static int skip_it = 0; if (skip_it) { return; } if (first) { set_db(); first = 0; for (i=0; i < nmax; i++) { user_r[i] = '\0'; user[i] = '\0'; pass[i] = '\0'; } } if (init) { in_login = 1; in_passwd = 0; unixpw_denied = 0; echo = 1; if (init == 1) { tries = 0; } u_cnt = 0; p_cnt = 0; for (i=0; i 90) { rfbLog("unixpw_keystroke: bad keysym3: 0x%x\n", (int) keysym); return; } if (db > 2) { fprintf(stderr, "%s / %s 0x%x %s\n", in_login ? "login":"pass ", down ? "down":"up ", keysym, keystr); } if (keysym == XK_Return || keysym == XK_Linefeed) { /* let "up" pass down below for Return case */ if (down) { return; } } else if (! down) { return; } if (keysym == XK_F1 && pscreen && pscreen->width >= 640) { char h1[] = "F1-Help: For 'login:' type in the username and press Enter, then for 'Password:' type in the password."; char h2[] = " Specify options after a ':' like this: username:opt,opt=val,... Where an opt may be any of:"; char h3[] = " scale=... (n/m); scale_cursor=... (sc=); solid (so); id=; repeat; clear_mods (cm); clear_keys (ck);"; char h4[] = " clear_all (ca); speeds=... (sp=); readtimeout=... (rd=) rotate=... (ro=); noncache (nc) (nc=n);"; char h5[] = " geom=WxHxD (ge=); nodisplay=... (nd=); viewonly (vo); gnome kde twm fvwm mwm dtwm wmaker xfce"; char h6[] = " enlightenment Xsession failsafe. Examples: fred:3/4,so,cm wilma:geom=1024x768x16,kde"; int ch = 13, p; if (f1_help) { p = black_pixel(); f1_help = 0; } else { p = white_pixel(); f1_help = 1; unixpw_last_try_time = time(NULL) + 45; } rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, h1, p); rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, h2, p); rfbDrawString(pscreen, &default6x13Font, 8, 2+3*ch, h3, p); rfbDrawString(pscreen, &default6x13Font, 8, 2+4*ch, h4, p); rfbDrawString(pscreen, &default6x13Font, 8, 2+5*ch, h5, p); rfbDrawString(pscreen, &default6x13Font, 8, 2+6*ch, h6, p); if (!f1_help) { rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, "F1-Help:", white_pixel()); } unixpw_mark(); return; } if (unixpw_system_greeter_active && keysym == XK_Escape) { char *u = get_user_name(); if (keep_unixpw) { char *colon = strchr(user, ':'); keep_unixpw_user = strdup(u); keep_unixpw_pass = strdup(""); if (colon) { keep_unixpw_opts = strdup(colon+1); } else { keep_unixpw_opts = strdup(""); } } unixpw_system_greeter_active = 2; set_env("X11VNC_XDM_ONLY", "1"); rfbLog("unixpw_system_greeter: VNC client pressed 'Escape'. Allowing\n"); rfbLog("unixpw_system_greeter: a *FREE* (no password) connection to\n"); rfbLog("unixpw_system_greeter: the system XDM/GDM/KDM login greeter.\n"); if (1) { char msg[] = " Please wait... "; rfbDrawString(pscreen, &default8x16Font, text_x(), text_y(), msg, white_pixel()); unixpw_mark(); skip_it = 1; rfbPE(-1); rfbPE(-1); rfbPE(-1); skip_it = 0; usleep(10*1000); } unixpw_accept(u); free(u); return; } if (in_login && keysym == XK_Escape && u_cnt == 0) { echo = 0; rfbLog("unixpw_keystroke: echo off.\n"); return; } if (in_login) { if (keysym == XK_BackSpace || keysym == XK_Delete) { if (u_cnt > 0) { user[u_cnt-1] = '\0'; u_cnt--; x = text_x(); y = text_y(); if (scaling) { int x2 = x / scale_fac_x; int y2 = y / scale_fac_y; int w2 = char_w / scale_fac_x; int h2 = char_h / scale_fac_y; x2 = nfix(x2, dpy_x); y2 = nfix(y2, dpy_y); zero_fb(x2 - w2, y2 - h2, x2, y2); mark_rect_as_modified(x2 - w2, y2 - h2, x2, y2, 0); } else { 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--; } return; } if (keysym == XK_Return || keysym == XK_Linefeed) { char pw[] = "Password: "; if (down) { /* * require Up so the Return Up is not processed * by the normal session after login. * (actually we already returned above) */ return; } in_login = 0; in_passwd = 1; char_row++; char_col = 0; x = text_x(); y = text_y(); rfbDrawString(pscreen, &default8x16Font, x, y, pw, white_pixel()); char_col = strlen(pw); unixpw_mark(); return; } if (u_cnt == 0 && keysym == XK_Up) { /* * Allow user to hit Up arrow at beginning to * regain their username plus any options. */ int i; for (i=0; i < nmax; i++) { user[i] = '\0'; } for (i=0; i < nmax; i++) { char str[10]; user[u_cnt++] = user_r[i]; if (user_r[i] == '\0') { break; } str[0] = (char) user_r[i]; str[1] = '\0'; x = text_x(); y = text_y(); if (echo) { rfbDrawString(pscreen, &default8x16Font, x, y, str, white_pixel()); } mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling); char_col++; usleep(10*1000); } return; } if (keysym < ' ' || keysym >= 0x7f) { /* require normal keyboard characters for username */ rfbLog("unixpw_keystroke: bad keysym4: 0x%x\n", (int) keysym); return; } if (u_cnt >= nmax - 1) { /* user[u_cnt=99] will be '\0' */ rfbLog("unixpw_deny: username too long: %d\n", u_cnt); for (i=0; i 0) { pass[p_cnt-1] = '\0'; p_cnt--; } return; } if (keysym == XK_Return || keysym == XK_Linefeed) { if (down) { /* * require Up so the Return Up is not processed * by the normal session after login. * (actually we already returned above) */ return; } if (1) { char msg[] = " Please wait... "; rfbDrawString(pscreen, &default8x16Font, text_x(), text_y(), msg, white_pixel()); unixpw_mark(); skip_it = 1; rfbPE(-1); rfbPE(-1); rfbPE(-1); skip_it = 0; usleep(10*1000); } in_login = 0; in_passwd = 0; pass[p_cnt++] = '\n'; unixpw_verify_screen(user, pass); for (i=0; i= 0x7f) { /* require normal keyboard characters for password */ return; } if (p_cnt >= nmax - 2) { /* pass[u_cnt=98] will be '\n' */ /* pass[u_cnt=99] will be '\0' */ rfbLog("unixpw_deny: password too long: %d\n", p_cnt); for (i=0; iclientData; cl = unixpw_client; if (! cd) { rfbLog("apply_opts: no ClientData\n"); } if (user && cd) { if (cd->unixname) { free(cd->unixname); } cd->unixname = strdup(user); } str = strdup(unixpw_list); /* apply any per-user options. */ if (str[0] == '!') { p = strtok(str+1, ","); notmode = 1; } else { p = strtok(str, ","); } while (p) { if ( (q = strchr(p, ':')) != NULL ) { *q = '\0'; /* get rid of options. */ } else { p = strtok(NULL, ","); continue; } if (user && !strcmp(user, p)) { /* will not happen in notmode */ opts = strdup(q+1); } if (!strcmp("*", p)) { opts_star = strdup(q+1); } p = strtok(NULL, ","); } free(str); for (i=0; i < 2; i++) { char *s = (i == 0) ? opts_star : opts; if (s == NULL) { continue; } p = strtok(s, "+"); while (p) { if (!strcmp(p, "viewonly")) { cl->viewOnly = TRUE; if (cd) { strncpy(cd->input, "-", CILEN); } } else if (!strcmp(p, "fullaccess")) { cl->viewOnly = FALSE; if (cd) { strncpy(cd->input, "-", CILEN); } } else if ((q = strstr(p, "input=")) == p) { q += strlen("input="); if (cd) { strncpy(cd->input, q, CILEN); } } else if (!strcmp(p, "deny")) { cl->viewOnly = TRUE; unixpw_deny(); break; } p = strtok(NULL, "+"); } free(s); } } void unixpw_accept(char *user) { apply_opts(user); if (!use_stunnel) { ssl_helper_pid(0, -2); /* waitall */ } 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 && strstr(users_list, "unixpw=") == users_list) { if (getuid() && geteuid()) { rfbLog("unixpw_accept: unixpw= but not root\n"); started_as_root = 2; } else { char *u = (char *)malloc(strlen(user)+1); u[0] = '\0'; if (!strcmp(users_list, "unixpw=")) { sprintf(u, "+%s", user); } else { char *p, *str = strdup(users_list); p = strtok(str + strlen("unixpw="), ","); while (p) { if (!strcmp(p, user)) { sprintf(u, "+%s", user); break; } p = strtok(NULL, ","); } free(str); } if (u[0] == '\0') { rfbLog("unixpw_accept skipping switch to user: %s\n", user); } else if (switch_user(u, 0)) { rfbLog("unixpw_accept switched to user: %s\n", user); } else { rfbLog("unixpw_accept failed to switch to user: %s\n", user); } free(u); } } if (unixpw_login_viewonly) { unixpw_client->viewOnly = TRUE; } unixpw_in_progress = 0; screen->permitFileTransfer = unixpw_file_xfer_save; if ((tightfilexfer = unixpw_tightvnc_xfer_save)) { /* this doesn't work: the current client is never registered! */ #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER rfbLog("rfbRegisterTightVNCFileTransferExtension: 1\n"); rfbRegisterTightVNCFileTransferExtension(); #endif } unixpw_client = NULL; mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (macosx_console) { refresh_screen(1); } } void unixpw_deny(void) { int x, y, i; char pd[] = "Permission denied."; rfbLog("unixpw_deny: %d, %d\n", unixpw_denied, unixpw_in_progress); if (! unixpw_denied) { unixpw_denied = 1; char_row += 2; char_col = 0; x = char_x + char_col * char_w; y = char_y + char_row * char_h; rfbDrawString(pscreen, &default8x16Font, x, y, pd, white_pixel()); unixpw_mark(); for (i=0; i<5; i++) { rfbPE(-1); rfbPE(-1); usleep(500 * 1000); } } if (unixpw_client) { rfbCloseClient(unixpw_client); rfbClientConnectionGone(unixpw_client); rfbPE(-1); } unixpw_in_progress = 0; screen->permitFileTransfer = unixpw_file_xfer_save; if ((tightfilexfer = unixpw_tightvnc_xfer_save)) { #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER rfbLog("rfbRegisterTightVNCFileTransferExtension: 2\n"); rfbRegisterTightVNCFileTransferExtension(); #endif } unixpw_client = NULL; copy_screen(); } void unixpw_msg(char *msg, int delay) { int x, y, i; char_row += 2; char_col = 0; x = char_x + char_col * char_w; y = char_y + char_row * char_h; rfbDrawString(pscreen, &default8x16Font, x, y, msg, white_pixel()); unixpw_mark(); for (i=0; i<5; i++) { rfbPE(-1); rfbPE(-1); usleep(500 * 1000); if (i >= delay) { break; } } }