| /* |
| Copyright (C) 2002-2010 Karl J. Runge <[email protected]> |
| 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 <http://www.gnu.org/licenses/>. |
| |
| 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); |
| #endif |
| |
| #ifndef DO_NOT_DECLARE_CRYPT |
| 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 "rates.h" |
| #include <rfb/default8x16.h> |
| |
| #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 <shadow.h> |
| #endif |
| #endif |
| #endif |
| |
| #if LIBVNCSERVER_HAVE_SYS_IOCTL_H |
| #include <sys/ioctl.h> |
| #endif |
| #if LIBVNCSERVER_HAVE_TERMIOS_H |
| #include <termios.h> |
| #endif |
| #if LIBVNCSERVER_HAVE_SYS_STROPTS_H |
| #include <sys/stropts.h> |
| #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 (unixpw_system_greeter) { |
| y = (int) (dpy_y / 3); |
| } |
| |
| 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 && pscreen->height >= 480) { |
| 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 a New Session via System Greeter, or"; |
| char moo2[] = "otherwise login here to connect to an 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 |
| |
| if (strlen(slave) > sizeof(slave_str)/2) { |
| rfbLog("get_pty_ptmx: slave string length too long.\n"); |
| close(fd); |
| return NULL; |
| } |
| |
| 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<n; i++) { |
| if (str[i] == '\0') { |
| j = 1; |
| break; |
| } |
| if (!strcmp(name, "password")) { |
| if (str[i] == '\n') { |
| continue; |
| } |
| } |
| if (str[i] < ' ' || str[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 || cr[0] == '\0') { |
| 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[64], cbuf[10]; |
| |
| if (first) { |
| set_db(); |
| first = 0; |
| } |
| rfbLog("su_verify: '%s' for %s.\n", user, cmd ? "command" : "login"); |
| fflush(stderr); |
| |
| 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"); |
| fflush(stderr); |
| 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"); |
| fflush(stderr); |
| return 0; |
| } |
| |
| slave = get_pty(&fd); |
| |
| if (slave == NULL) { |
| rfbLogPerror("get_pty failed."); |
| fflush(stderr); |
| 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"); |
| fflush(stderr); |
| return 0; |
| } |
| |
| fcntl(fd, F_SETFD, 1); |
| |
| pid = fork(); |
| if (pid < 0) { |
| rfbLogPerror("fork"); |
| fflush(stderr); |
| 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< (int) sizeof(instr); 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, problem; |
| |
| cbuf[0] = '\0'; |
| cbuf[1] = '\0'; |
| |
| n = read(fd, cbuf, 1); |
| if (n < 0 && errno == EINTR) { |
| i--; |
| if (i < -1) i = -1; |
| 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 < -1) i = -1; |
| continue; |
| } |
| if (j >= (int) sizeof(instr)-1) { |
| rfbLog("su_verify: problem finding Password:\n"); |
| fflush(stderr); |
| return 0; |
| } |
| instr[j++] = tolower((unsigned char)cbuf[0]); |
| } |
| |
| problem = 0; |
| if (n <= 0) { |
| problem = 1; |
| } else if (strstr(pstr, instr) != pstr) { |
| #ifdef _AIX |
| if (UT.sysname && strstr(UT.sysname, "AIX")) { |
| /* handle: runge's Password: */ |
| char *luser = (char *) malloc(strlen(user) + 10); |
| |
| sprintf(luser, "%s's", user); |
| lowercase(luser); |
| if (db) fprintf(stderr, "\nAIX luser compare: \"%s\" to \"%s\"\n", luser, instr); |
| if (strstr(luser, instr) == luser) { |
| if (db) fprintf(stderr, "AIX luser compare: strstr OK.\n"); |
| if (!strcmp(luser, instr)) { |
| if (db) fprintf(stderr, "AIX luser compare: strings equal.\n"); |
| i = -1; |
| j = 0; |
| memset(instr, 0, sizeof(instr)); |
| free(luser); |
| continue; |
| } else { |
| i--; |
| if (i < -1) i = -1; |
| free(luser); |
| continue; |
| } |
| } else { |
| if (db) fprintf(stderr, "AIX luser compare: problem=1\n"); |
| problem = 1; |
| } |
| free(luser); |
| } else |
| #endif |
| { |
| problem = 1; |
| } |
| } |
| |
| if (problem) { |
| 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) fprintf(stderr, "\nsending passwd: %s\n", db > 2 ? 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<output-of-command> |
| * 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); |
| fflush(stderr); |
| ok = 1; |
| } else { |
| rfbLog("unixpw_verify: cmd_verify login for '%s'" |
| " failed.\n", user); |
| fflush(stderr); |
| 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); |
| fflush(stderr); |
| ok = 1; |
| } else { |
| rfbLog("unixpw_verify: crypt_verify login for '%s'" |
| " failed.\n", user); |
| fflush(stderr); |
| 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); |
| fflush(stderr); |
| ok = 1; |
| } else { |
| rfbLog("unixpw_verify: su_verify login for '%s'" |
| " failed.\n", user); |
| fflush(stderr); |
| /* use su(1)'s sleep */ |
| ok = 0; |
| } |
| } |
| return ok; |
| } |
| |
| static int skip_it = 0; |
| |
| static void progress_skippy(void) { |
| int i, msec = get_net_latency(); /* probabaly not set yet.. */ |
| |
| if (msec > 300) { |
| msec = 300; |
| } else if (msec <= 100) { |
| msec = 100; |
| } |
| |
| skip_it = 1; |
| for (i = 0; i < 5; i++) { |
| if (i == 2) { |
| rfbPE(msec * 1000); |
| } else { |
| rfbPE(-1); |
| } |
| usleep(10*1000); |
| } |
| skip_it = 0; |
| |
| usleep(50*1000); |
| } |
| |
| void check_unixpw_userprefs(void) { |
| char *prefs = getenv("FD_USERPREFS"); |
| if (keep_unixpw_user == NULL || keep_unixpw_opts == NULL) { |
| return; |
| } |
| #if LIBVNCSERVER_HAVE_PWD_H |
| if (prefs != NULL && !strchr(prefs, '/')) { |
| struct passwd *pw = getpwnam(keep_unixpw_user); |
| if (pw != NULL) { |
| char *file; |
| FILE *f; |
| |
| file = (char *) malloc(strlen(pw->pw_dir) + 1 + strlen(prefs) + 1); |
| sprintf(file, "%s/%s", pw->pw_dir, prefs); |
| |
| f = fopen(file, "r"); |
| if (f) { |
| char *t, *q, buf[1024]; |
| memset(buf, 0, sizeof(buf)); |
| |
| fgets(buf, 1024, f); |
| fclose(f); |
| |
| q = strchr(buf, '\n'); |
| if (q) *q = '\0'; |
| q = strchr(buf, '\r'); |
| if (q) *q = '\0'; |
| |
| rfbLog("read user prefs %s: %s\n", file, buf); |
| |
| if (buf[0] == '#') buf[0] = '\0'; |
| |
| t = (char *) malloc(strlen(keep_unixpw_opts) + 1 + strlen(buf) + 1); |
| sprintf(t, "%s,%s", keep_unixpw_opts, buf); |
| free(keep_unixpw_opts); |
| keep_unixpw_opts = t; |
| } else { |
| rfbLog("could not read user prefs %s\n", file); |
| rfbLogPerror("fopen"); |
| } |
| free(file); |
| } |
| } |
| #endif |
| } |
| |
| |
| void unixpw_verify_screen(char *user, char *pass) { |
| int x, y; |
| char li[] = "Login incorrect"; |
| char ls[] = "Login succeeded"; |
| 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); |
| } |
| fflush(stderr); |
| 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) { |
| char_row++; |
| char_col = 0; |
| |
| x = text_x(); |
| y = text_y(); |
| rfbDrawString(pscreen, &default8x16Font, x, y, ls, white_pixel()); |
| unixpw_mark(); |
| |
| progress_skippy(); |
| |
| 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(""); |
| } |
| check_unixpw_userprefs(); |
| } |
| |
| 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, t_cnt = 0, first = 1; |
| static int echo = 1; |
| char keystr[100]; |
| char *str; |
| |
| 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; |
| t_cnt = 0; |
| for (i=0; i<nmax; i++) { |
| user[i] = '\0'; |
| pass[i] = '\0'; |
| } |
| if (keep_unixpw_user) { |
| free(keep_unixpw_user); |
| keep_unixpw_user = NULL; |
| } |
| if (keep_unixpw_pass) { |
| strzero(keep_unixpw_pass); |
| free(keep_unixpw_pass); |
| keep_unixpw_pass = NULL; |
| } |
| if (keep_unixpw_opts) { |
| strzero(keep_unixpw_opts); |
| free(keep_unixpw_opts); |
| keep_unixpw_opts = NULL; |
| } |
| |
| return; |
| } |
| |
| if (unixpw_denied) { |
| rfbLog("unixpw_keystroke: unixpw_denied state: 0x%x\n", (int) keysym); |
| return; |
| } |
| if (keysym <= 0) { |
| rfbLog("unixpw_keystroke: bad keysym1: 0x%x\n", (int) keysym); |
| return; |
| } |
| |
| /* rfbKeySym = uint32_t */ |
| /* KeySym = XID = CARD32 = (unsigned long or unsigned int on LONG64) */ |
| X_LOCK; |
| str = XKeysymToString(keysym); |
| X_UNLOCK; |
| if (str == NULL) { |
| rfbLog("unixpw_keystroke: bad keysym2: 0x%x\n", (int) keysym); |
| return; |
| } |
| |
| rc = snprintf(keystr, 100, "%s", str); |
| if (rc < 1 || rc > 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 || keysym == XK_Tab) { |
| /* let "up" pass down below for Return case */ |
| if (down) { |
| return; |
| } |
| } else if (! down) { |
| return; |
| } |
| if (keysym == XK_F1) { |
| char h1[] = "F1-Help: For 'login:' type in the username and press Enter, then for 'Password:' enter the password."; |
| char hf[] = " Once logged in, username's X session will be searched for and if found then attached to."; |
| char hc[] = " Once logged in, username's X session is sought and attached to, otherwise a new session is created."; |
| char hx[] = " Once logged in, username's X session is sought and attached to, otherwise a login greeter is presented."; |
| 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); tag=...; gnome kde twm fvwm mwm dtwm wmaker"; |
| char h6[] = " xfce lxde enlightenment Xsession failsafe. Examples: fred:3/4,so,cm wilma:geom=1024x768x16,kde"; |
| int ch = 13, p; |
| if (!pscreen || pscreen->width < 640 || pscreen->height < 480) { |
| return; |
| } |
| 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); |
| if (use_dpy == NULL) { |
| ; |
| } else if (strstr(use_dpy, "cmd=FINDDISPLAY")) { |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hf, p); |
| } else if (strstr(use_dpy, "cmd=FINDCREATEDISPLAY")) { |
| if (strstr(use_dpy, "xdmcp")) { |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hx, p); |
| } else { |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hc, p); |
| } |
| } |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+3*ch, h2, p); |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+4*ch, h3, p); |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+5*ch, h4, p); |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+6*ch, h5, p); |
| rfbDrawString(pscreen, &default6x13Font, 8, 2+7*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(""); |
| } |
| check_unixpw_userprefs(); |
| } |
| 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(); |
| |
| progress_skippy(); |
| } |
| unixpw_accept(u); |
| free(u); |
| return; |
| } |
| |
| if (in_login && keysym == XK_Escape && u_cnt == 0) { |
| echo = 0; |
| rfbLog("unixpw_keystroke: echo off.\n"); |
| return; |
| } |
| |
| t_cnt++; |
| |
| 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 || keysym == XK_Tab) { |
| 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; |
| } |
| |
| if (t_cnt == 1) { |
| /* accidental initial return, e.g. from xterm */ |
| 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<nmax; i++) { |
| user[i] = '\0'; |
| pass[i] = '\0'; |
| } |
| unixpw_deny(); |
| return; |
| } |
| |
| #if 0 |
| user[u_cnt++] = keystr[0]; |
| #else |
| user[u_cnt++] = (char) keysym; |
| for (i=0; i < nmax; i++) { |
| /* keep a full copy of username */ |
| user_r[i] = user[i]; |
| } |
| keystr[0] = (char) keysym; |
| #endif |
| keystr[1] = '\0'; |
| |
| x = text_x(); |
| y = text_y(); |
| |
| if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x '%s'\n", u_cnt, x, y, keysym, keystr); |
| |
| if (echo ) { |
| rfbDrawString(pscreen, &default8x16Font, x, y, keystr, white_pixel()); |
| } |
| |
| mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling); |
| char_col++; |
| |
| return; |
| |
| } 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) { |
| 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(); |
| |
| progress_skippy(); |
| } |
| |
| in_login = 0; |
| in_passwd = 0; |
| |
| pass[p_cnt++] = '\n'; |
| unixpw_verify_screen(user, pass); |
| for (i=0; i<nmax; i++) { |
| user[i] = '\0'; |
| pass[i] = '\0'; |
| } |
| return; |
| } |
| |
| if (keysym < ' ' || keysym >= 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; i<nmax; i++) { |
| user[i] = '\0'; |
| pass[i] = '\0'; |
| } |
| unixpw_deny(); |
| return; |
| } |
| |
| pass[p_cnt++] = (char) keysym; |
| |
| return; |
| |
| } else { |
| /* should not happen... anyway clean up a bit. */ |
| u_cnt = 0; |
| p_cnt = 0; |
| for (i=0; i<nmax; i++) { |
| user_r[i] = '\0'; |
| user[i] = '\0'; |
| pass[i] = '\0'; |
| } |
| |
| return; |
| } |
| } |
| |
| static void apply_opts (char *user) { |
| char *p, *q, *str, *opts = NULL, *opts_star = NULL; |
| rfbClientPtr cl; |
| ClientData *cd; |
| int i, notmode = 0; |
| |
| if (! unixpw_client) { |
| rfbLog("apply_opts: unixpw_client is NULL\n"); |
| clean_up_exit(1); |
| } |
| cd = (ClientData *) unixpw_client->clientData; |
| cl = unixpw_client; |
| |
| if (! cd) { |
| rfbLog("apply_opts: no ClientData\n"); |
| } |
| |
| if (user && cd) { |
| if (cd->unixname) { |
| free(cd->unixname); |
| } |
| cd->unixname = strdup(user); |
| rfbLog("apply_opts: set unixname to: %s\n", cd->unixname); |
| } |
| |
| if (! unixpw_list) { |
| return; |
| } |
| 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; |
| /* mutex */ |
| 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; |
| /* mutex */ |
| 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); |
| rfbPE(50 * 1000); |
| rfbPE(-1); |
| usleep(500 * 1000); |
| if (i >= delay) { |
| break; |
| } |
| } |
| } |