1 /*
2 Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3 All rights reserved.
4
5 This file is part of x11vnc.
6
7 x11vnc is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at
10 your option) any later version.
11
12 x11vnc is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with x11vnc; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20 or see <http://www.gnu.org/licenses/>.
21
22 In addition, as a special exception, Karl J. Runge
23 gives permission to link the code of its release of x11vnc with the
24 OpenSSL project's "OpenSSL" library (or with modified versions of it
25 that use the same license as the "OpenSSL" library), and distribute
26 the linked executables. You must obey the GNU General Public License
27 in all respects for all of the code used other than "OpenSSL". If you
28 modify this file, you may extend this exception to your version of the
29 file, but you are not obligated to do so. If you do not wish to do
30 so, delete this exception statement from your version.
31 */
32
33 /* -- unixpw.c -- */
34
35 #ifdef __linux__
36 /* some conflict with _XOPEN_SOURCE */
37 extern int grantpt(int);
38 extern int unlockpt(int);
39 extern char *ptsname(int);
40 #endif
41
42 #ifndef DO_NOT_DECLARE_CRYPT
43 extern char *crypt(const char*, const char *);
44 #endif
45
46 #include "x11vnc.h"
47 #include "scan.h"
48 #include "cleanup.h"
49 #include "xinerama.h"
50 #include "connections.h"
51 #include "user.h"
52 #include "connections.h"
53 #include "sslhelper.h"
54 #include "cursor.h"
55 #include "rates.h"
56 #include <rfb/default8x16.h>
57
58 #if LIBVNCSERVER_HAVE_FORK
59 #if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
60 #define UNIXPW_SU
61 #endif
62 #endif
63
64 #ifdef IGNORE_GETSPNAM
65 #undef LIBVNCSERVER_HAVE_GETSPNAM
66 #define LIBVNCSERVER_HAVE_GETSPNAM 0
67 #endif
68
69 #if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM
70 #if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT
71 #define UNIXPW_CRYPT
72 #if LIBVNCSERVER_HAVE_GETSPNAM
73 #include <shadow.h>
74 #endif
75 #endif
76 #endif
77
78 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H
79 #include <sys/ioctl.h>
80 #endif
81 #if LIBVNCSERVER_HAVE_TERMIOS_H
82 #include <termios.h>
83 #endif
84 #if LIBVNCSERVER_HAVE_SYS_STROPTS_H
85 #include <sys/stropts.h>
86 #endif
87
88 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
89 #define IS_BSD
90 #endif
91 #if (defined(__MACH__) && defined(__APPLE__))
92 #define IS_BSD
93 #endif
94
95 int white_pixel(void);
96 void unixpw_screen(int init);
97 void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
98 void unixpw_accept(char *user);
99 void unixpw_deny(void);
100 void unixpw_msg(char *msg, int delay);
101 int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp);
102 int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n);
103 int crypt_verify(char *user, char *pass);
104 int cmd_verify(char *user, char *pass);
105 void unixpw_verify_screen(char *user, char *pass);
106
107 static int text_x(void);
108 static int text_y(void);
109 static void set_db(void);
110
111 int unixpw_in_progress = 0;
112 int unixpw_denied = 0;
113 int unixpw_in_rfbPE = 0;
114 int unixpw_login_viewonly = 0;
115 int unixpw_tightvnc_xfer_save = 0;
116 rfbBool unixpw_file_xfer_save = FALSE;
117 time_t unixpw_last_try_time = 0;
118 rfbClientPtr unixpw_client = NULL;
119
120 int keep_unixpw = 0;
121 char *keep_unixpw_user = NULL;
122 char *keep_unixpw_pass = NULL;
123 char *keep_unixpw_opts = NULL;
124
125 static unsigned char default6x13FontData[2899]={
126 0x00,0x00,0xA8,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0xA8,0x00,0x00, /* 0 */
127 0x00,0x00,0x00,0x00,0x20,0x70,0xF8,0x70,0x20,0x00,0x00,0x00,0x00, /* 1 */
128 0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8, /* 2 */
129 0x00,0x00,0xA0,0xA0,0xE0,0xA0,0xA0,0x38,0x10,0x10,0x10,0x00,0x00, /* 3 */
130 0x00,0x00,0xE0,0x80,0xC0,0x80,0xB8,0x20,0x30,0x20,0x20,0x00,0x00, /* 4 */
131 0x00,0x00,0x60,0x80,0x80,0x60,0x30,0x28,0x30,0x28,0x28,0x00,0x00, /* 5 */
132 0x00,0x00,0x80,0x80,0x80,0xE0,0x38,0x20,0x30,0x20,0x20,0x00,0x00, /* 6 */
133 0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7 */
134 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 8 */
135 0x00,0x00,0x90,0xD0,0xB0,0x90,0x20,0x20,0x20,0x20,0x38,0x00,0x00, /* 9 */
136 0x00,0x00,0xA0,0xA0,0xA0,0x40,0x40,0x38,0x10,0x10,0x10,0x00,0x00, /* 10 */
137 0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, /* 11 */
138 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 12 */
139 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 13 */
140 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, /* 14 */
141 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 15 */
142 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 */
143 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 17 */
144 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 18 */
145 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00, /* 19 */
146 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, /* 20 */
147 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 21 */
148 0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 22 */
149 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 23 */
150 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 24 */
151 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* 25 */
152 0x00,0x00,0x00,0x18,0x60,0x80,0x60,0x18,0x00,0xF8,0x00,0x00,0x00, /* 26 */
153 0x00,0x00,0x00,0xC0,0x30,0x08,0x30,0xC0,0x00,0xF8,0x00,0x00,0x00, /* 27 */
154 0x00,0x00,0x00,0x00,0x00,0xF8,0x50,0x50,0x50,0x50,0x50,0x00,0x00, /* 28 */
155 0x00,0x00,0x00,0x00,0x00,0x08,0xF8,0x20,0xF8,0x80,0x00,0x00,0x00, /* 29 */
156 0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 30 */
157 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 31 */
158 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 */
159 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, /* 33 */
160 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 34 */
161 0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00,0x00,0x00, /* 35 */
162 0x00,0x00,0x20,0x78,0xA0,0xA0,0x70,0x28,0x28,0xF0,0x20,0x00,0x00, /* 36 */
163 0x00,0x00,0x48,0xA8,0x50,0x10,0x20,0x40,0x50,0xA8,0x90,0x00,0x00, /* 37 */
164 0x00,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA0,0x98,0x90,0x68,0x00,0x00, /* 38 */
165 0x00,0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 39 */
166 0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, /* 40 */
167 0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, /* 41 */
168 0x00,0x00,0x00,0x20,0xA8,0xF8,0x70,0xF8,0xA8,0x20,0x00,0x00,0x00, /* 42 */
169 0x00,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00,0x00, /* 43 */
170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x40,0x00, /* 44 */
171 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, /* 45 */
172 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00, /* 46 */
173 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00,0x00, /* 47 */
174 0x00,0x00,0x20,0x50,0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x00, /* 48 */
175 0x00,0x00,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, /* 49 */
176 0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 50 */
177 0x00,0x00,0xF8,0x08,0x10,0x20,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 51 */
178 0x00,0x00,0x10,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, /* 52 */
179 0x00,0x00,0xF8,0x80,0x80,0xB0,0xC8,0x08,0x08,0x88,0x70,0x00,0x00, /* 53 */
180 0x00,0x00,0x70,0x88,0x80,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, /* 54 */
181 0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, /* 55 */
182 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 56 */
183 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, /* 57 */
184 0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x20,0x70,0x20,0x00, /* 58 */
185 0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x30,0x20,0x40,0x00, /* 59 */
186 0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, /* 60 */
187 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 61 */
188 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, /* 62 */
189 0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, /* 63 */
190 0x00,0x00,0x70,0x88,0x88,0x98,0xA8,0xA8,0xB0,0x80,0x78,0x00,0x00, /* 64 */
191 0x00,0x00,0x20,0x50,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0x00, /* 65 */
192 0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, /* 66 */
193 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, /* 67 */
194 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, /* 68 */
195 0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF8,0x00,0x00, /* 69 */
196 0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 70 */
197 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x98,0x88,0x88,0x70,0x00,0x00, /* 71 */
198 0x00,0x00,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0x00,0x00, /* 72 */
199 0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 73 */
200 0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, /* 74 */
201 0x00,0x00,0x88,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 75 */
202 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00, /* 76 */
203 0x00,0x00,0x88,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00,0x00, /* 77 */
204 0x00,0x00,0x88,0xC8,0xC8,0xA8,0xA8,0x98,0x98,0x88,0x88,0x00,0x00, /* 78 */
205 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 79 */
206 0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 80 */
207 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0xA8,0x70,0x08,0x00, /* 81 */
208 0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 82 */
209 0x00,0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 83 */
210 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 84 */
211 0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 85 */
212 0x00,0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00,0x00, /* 86 */
213 0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 87 */
214 0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0x88,0x00,0x00, /* 88 */
215 0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 89 */
216 0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0xF8,0x00,0x00, /* 90 */
217 0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, /* 91 */
218 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00,0x00, /* 92 */
219 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, /* 93 */
220 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 94 */
221 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, /* 95 */
222 0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 96 */
223 0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 97 */
224 0x00,0x00,0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0xF0,0x00,0x00, /* 98 */
225 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x00,0x00, /* 99 */
226 0x00,0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, /* 100 */
227 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 101 */
228 0x00,0x00,0x30,0x48,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x00,0x00, /* 102 */
229 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x88,0x70, /* 103 */
230 0x00,0x00,0x80,0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 104 */
231 0x00,0x00,0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 105 */
232 0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x90,0x60, /* 106 */
233 0x00,0x00,0x80,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00,0x00, /* 107 */
234 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 108 */
235 0x00,0x00,0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x88,0x00,0x00, /* 109 */
236 0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 110 */
237 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 111 */
238 0x00,0x00,0x00,0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80, /* 112 */
239 0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x08, /* 113 */
240 0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x80,0x00,0x00, /* 114 */
241 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x60,0x10,0x88,0x70,0x00,0x00, /* 115 */
242 0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, /* 116 */
243 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 117 */
244 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x00,0x00, /* 118 */
245 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 119 */
246 0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 120 */
247 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 121 */
248 0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 122 */
249 0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, /* 123 */
250 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 124 */
251 0x00,0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, /* 125 */
252 0x00,0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 126 */
253 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 */
254 0x00,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 161 */
255 0x00,0x00,0x20,0x70,0xA8,0xA0,0xA0,0xA8,0x70,0x20,0x00,0x00,0x00, /* 162 */
256 0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 163 */
257 0x00,0x00,0x00,0x00,0x88,0x70,0x50,0x50,0x70,0x88,0x00,0x00,0x00, /* 164 */
258 0x00,0x00,0x88,0x88,0x50,0x50,0xF8,0x20,0xF8,0x20,0x20,0x00,0x00, /* 165 */
259 0x00,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, /* 166 */
260 0x00,0x30,0x48,0x40,0x30,0x48,0x48,0x30,0x08,0x48,0x30,0x00,0x00, /* 167 */
261 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168 */
262 0x00,0x70,0x88,0xA8,0xD8,0xC8,0xD8,0xA8,0x88,0x70,0x00,0x00,0x00, /* 169 */
263 0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0xF8,0x00,0x00,0x00,0x00, /* 170 */
264 0x00,0x00,0x00,0x00,0x28,0x50,0xA0,0xA0,0x50,0x28,0x00,0x00,0x00, /* 171 */
265 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00, /* 172 */
266 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00, /* 173 */
267 0x00,0x70,0x88,0xE8,0xD8,0xD8,0xE8,0xD8,0x88,0x70,0x00,0x00,0x00, /* 174 */
268 0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 175 */
269 0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 */
270 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 177 */
271 0x00,0x40,0xA0,0x20,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 178 */
272 0x00,0x40,0xA0,0x40,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 179 */
273 0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 180 */
274 0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0xE8,0x80,0x80, /* 181 */
275 0x00,0x00,0x78,0xE8,0xE8,0xE8,0xE8,0x68,0x28,0x28,0x28,0x00,0x00, /* 182 */
276 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 183 */
277 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20, /* 184 */
278 0x00,0x40,0xC0,0x40,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 185 */
279 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0xF8,0x00,0x00,0x00,0x00, /* 186 */
280 0x00,0x00,0x00,0x00,0xA0,0x50,0x28,0x28,0x50,0xA0,0x00,0x00,0x00, /* 187 */
281 0x00,0x40,0xC0,0x40,0x40,0xE0,0x08,0x18,0x28,0x38,0x08,0x00,0x00, /* 188 */
282 0x00,0x40,0xC0,0x40,0x40,0xE0,0x10,0x28,0x08,0x10,0x38,0x00,0x00, /* 189 */
283 0x00,0x40,0xA0,0x40,0x20,0xA0,0x48,0x18,0x28,0x38,0x08,0x00,0x00, /* 190 */
284 0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x80,0x88,0x88,0x70,0x00,0x00, /* 191 */
285 0x00,0x40,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 192 */
286 0x00,0x10,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 193 */
287 0x00,0x30,0x48,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 194 */
288 0x00,0x28,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 195 */
289 0x00,0x50,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 196 */
290 0x00,0x20,0x50,0x20,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 197 */
291 0x00,0x00,0x58,0xA0,0xA0,0xA0,0xB0,0xE0,0xA0,0xA0,0xB8,0x00,0x00, /* 198 */
292 0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x20,0x40, /* 199 */
293 0x00,0x40,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 200 */
294 0x00,0x10,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 201 */
295 0x00,0x30,0x48,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 202 */
296 0x00,0x50,0x50,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 203 */
297 0x00,0x40,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 204 */
298 0x00,0x10,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 205 */
299 0x00,0x30,0x48,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 206 */
300 0x00,0x50,0x50,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 207 */
301 0x00,0x00,0xF0,0x48,0x48,0x48,0xE8,0x48,0x48,0x48,0xF0,0x00,0x00, /* 208 */
302 0x00,0x28,0x50,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00,0x00, /* 209 */
303 0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 210 */
304 0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 211 */
305 0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 212 */
306 0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 213 */
307 0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 214 */
308 0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00, /* 215 */
309 0x00,0x08,0x70,0x98,0x98,0xA8,0xA8,0xA8,0xC8,0xC8,0x70,0x80,0x00, /* 216 */
310 0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 217 */
311 0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 218 */
312 0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 219 */
313 0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 220 */
314 0x00,0x10,0x20,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, /* 221 */
315 0x00,0x00,0x80,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x00,0x00, /* 222 */
316 0x00,0x00,0x60,0x90,0x90,0xA0,0xA0,0x90,0x88,0x88,0xB0,0x00,0x00, /* 223 */
317 0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 224 */
318 0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 225 */
319 0x00,0x00,0x30,0x48,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 226 */
320 0x00,0x00,0x28,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 227 */
321 0x00,0x00,0x50,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 228 */
322 0x00,0x30,0x48,0x30,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 229 */
323 0x00,0x00,0x00,0x00,0x00,0x70,0x28,0x70,0xA0,0xA8,0x50,0x00,0x00, /* 230 */
324 0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x20,0x40, /* 231 */
325 0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 232 */
326 0x00,0x00,0x10,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 233 */
327 0x00,0x00,0x30,0x48,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 234 */
328 0x00,0x00,0x50,0x50,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 235 */
329 0x00,0x00,0x40,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 236 */
330 0x00,0x00,0x10,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 237 */
331 0x00,0x00,0x30,0x48,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 238 */
332 0x00,0x00,0x50,0x50,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 239 */
333 0x00,0x50,0x20,0x60,0x10,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 240 */
334 0x00,0x00,0x28,0x50,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 241 */
335 0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 242 */
336 0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 243 */
337 0x00,0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 244 */
338 0x00,0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 245 */
339 0x00,0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 246 */
340 0x00,0x00,0x00,0x20,0x20,0x00,0xF8,0x00,0x20,0x20,0x00,0x00,0x00, /* 247 */
341 0x00,0x00,0x00,0x00,0x08,0x70,0x98,0xA8,0xA8,0xC8,0x70,0x80,0x00, /* 248 */
342 0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 249 */
343 0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 250 */
344 0x00,0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 251 */
345 0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 252 */
346 0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 253 */
347 0x00,0x00,0x00,0x80,0x80,0xB0,0xC8,0x88,0x88,0xC8,0xB0,0x80,0x80, /* 254 */
348 0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 255 */
349 };
350 static int default6x13FontMetaData[256*5]={
351 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,};
352 static rfbFontData default6x13Font={default6x13FontData, default6x13FontMetaData};
353
354 static int in_login = 0, in_passwd = 0, tries = 0;
355 static int char_row = 0, char_col = 0;
356 static int char_x = 0, char_y = 0, char_w = 8, char_h = 16;
357
358 static int db = 0;
359
white_pixel(void)360 int white_pixel(void) {
361 static unsigned long black_pix = 0, white_pix = 1, set = 0;
362
363 RAWFB_RET(0xffffff)
364
365 if (depth <= 8 && ! set) {
366 X_LOCK;
367 black_pix = BlackPixel(dpy, scr);
368 white_pix = WhitePixel(dpy, scr);
369 X_UNLOCK;
370 set = 1;
371 }
372 if (depth <= 8) {
373 return (int) white_pix;
374 } else if (depth < 24) {
375 return 0xffff;
376 } else {
377 return 0xffffff;
378 }
379 }
380
black_pixel(void)381 int black_pixel(void) {
382 static unsigned long black_pix = 0, white_pix = 1, set = 0;
383
384 RAWFB_RET(0x000000)
385
386 if (depth <= 8 && ! set) {
387 X_LOCK;
388 black_pix = BlackPixel(dpy, scr);
389 white_pix = WhitePixel(dpy, scr);
390 X_UNLOCK;
391 set = 1;
392 }
393 if (depth <= 8) {
394 return (int) black_pix;
395 } else if (depth < 24) {
396 return 0x0000;
397 } else {
398 return 0x000000;
399 }
400 }
401
unixpw_mark(void)402 static void unixpw_mark(void) {
403 if (scaling) {
404 mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1);
405 } else {
406 mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
407 }
408 }
409
text_x(void)410 static int text_x(void) {
411 return char_x + char_col * char_w;
412 }
413
text_y(void)414 static int text_y(void) {
415 return char_y + char_row * char_h;
416 }
417
418 static rfbScreenInfo fscreen;
419 static rfbScreenInfoPtr pscreen;
420
421 static int f1_help = 0;
422
unixpw_screen(int init)423 void unixpw_screen(int init) {
424 if (unixpw_cmd) {
425 ; /* OK */
426 } else if (unixpw_nis) {
427 #ifndef UNIXPW_CRYPT
428 rfbLog("-unixpw_nis is not supported on this OS/machine\n");
429 clean_up_exit(1);
430 #endif
431 } else {
432 #ifndef UNIXPW_SU
433 rfbLog("-unixpw is not supported on this OS/machine\n");
434 clean_up_exit(1);
435 #endif
436 }
437 if (init) {
438 int x, y;
439 char log[] = "login: ";
440
441 zero_fb(0, 0, dpy_x, dpy_y);
442
443 mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
444
445 x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x);
446 y = (int) (dpy_y / 3.5);
447 if (unixpw_system_greeter) {
448 y = (int) (dpy_y / 3);
449 }
450
451 if (scaling) {
452 x = (int) (x * scale_fac_x);
453 y = (int) (y * scale_fac_y);
454 x = nfix(x, scaled_x);
455 y = nfix(y, scaled_y);
456 }
457
458 if (rotating) {
459 fscreen.serverFormat.bitsPerPixel = bpp;
460 fscreen.paddedWidthInBytes = rfb_bytes_per_line;
461 fscreen.frameBuffer = rfb_fb;
462 pscreen = &fscreen;
463 } else {
464 pscreen = screen;
465 }
466
467 if (pscreen && pscreen->width >= 640 && pscreen->height >= 480) {
468 rfbDrawString(pscreen, &default6x13Font, 8, 2+1*13, "F1-Help:", white_pixel());
469 }
470 f1_help = 0;
471
472 if (unixpw_system_greeter) {
473 unixpw_system_greeter_active = 0;
474 if (use_dpy && strstr(use_dpy, "xdmcp")) {
475 if (getenv("X11VNC_SYSTEM_GREETER1")) {
476 char moo[] = "Press 'Escape' for System Greeter";
477 rfbDrawString(pscreen, &default8x16Font, x-90, y-30, moo, white_pixel());
478 } else {
479 char moo1[] = "Press 'Escape' for a New Session via System Greeter, or";
480 char moo2[] = "otherwise login here to connect to an Existing Session:";
481 rfbDrawString(pscreen, &default6x13Font, x-110, y-38, moo1, white_pixel());
482 rfbDrawString(pscreen, &default6x13Font, x-110, y-25, moo2, white_pixel());
483 }
484 set_env("X11VNC_XDM_ONLY", "0");
485 unixpw_system_greeter_active = 1;
486 }
487 }
488
489 rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
490
491 char_x = x;
492 char_y = y;
493 char_col = strlen(log);
494 char_row = 0;
495
496 set_warrow_cursor();
497 }
498
499 unixpw_mark();
500 }
501
502
503 #ifdef MAXPATHLEN
504 static char slave_str[MAXPATHLEN];
505 #else
506 static char slave_str[4096];
507 #endif
508
509 static int used_get_pty_ptmx = 0;
510
get_pty_ptmx(int * fd_p)511 char *get_pty_ptmx(int *fd_p) {
512 char *slave;
513 int fd = -1, i, ndevs = 4, tmp;
514 char *devs[] = {
515 "/dev/ptmx",
516 "/dev/ptm/clone",
517 "/dev/ptc",
518 "/dev/ptmx_bsd"
519 };
520
521 *fd_p = -1;
522
523 #if LIBVNCSERVER_HAVE_GRANTPT
524
525 for (i=0; i < ndevs; i++) {
526 #ifdef O_NOCTTY
527 fd = open(devs[i], O_RDWR|O_NOCTTY);
528 #else
529 fd = open(devs[i], O_RDWR);
530 #endif
531 if (fd >= 0) {
532 break;
533 }
534 }
535
536 if (fd < 0) {
537 rfbLogPerror("open /dev/ptmx");
538 return NULL;
539 }
540
541 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCPKT)
542 tmp = 0;
543 ioctl(fd, TIOCPKT, (char *) &tmp);
544 #endif
545
546 if (grantpt(fd) != 0) {
547 rfbLogPerror("grantpt");
548 close(fd);
549 return NULL;
550 }
551 if (unlockpt(fd) != 0) {
552 rfbLogPerror("unlockpt");
553 close(fd);
554 return NULL;
555 }
556
557 slave = ptsname(fd);
558 if (! slave) {
559 rfbLogPerror("ptsname");
560 close(fd);
561 return NULL;
562 }
563
564 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH)
565 ioctl(fd, TIOCFLUSH, (char *) 0);
566 #endif
567
568 if (strlen(slave) > sizeof(slave_str)/2) {
569 rfbLog("get_pty_ptmx: slave string length too long.\n");
570 close(fd);
571 return NULL;
572 }
573
574 strcpy(slave_str, slave);
575 *fd_p = fd;
576 return slave_str;
577
578 #else
579 return NULL;
580
581 #endif /* GRANTPT */
582 }
583
584
get_pty_loop(int * fd_p)585 char *get_pty_loop(int *fd_p) {
586 char master_str[16];
587 int fd = -1, i;
588 char c;
589
590 *fd_p = -1;
591
592 /* for *BSD loop over /dev/ptyXY */
593
594 for (c = 'p'; c <= 'z'; c++) {
595 for (i=0; i < 16; i++) {
596 sprintf(master_str, "/dev/pty%c%x", c, i);
597 #ifdef O_NOCTTY
598 fd = open(master_str, O_RDWR|O_NOCTTY);
599 #else
600 fd = open(master_str, O_RDWR);
601 #endif
602 if (fd >= 0) {
603 break;
604 }
605 }
606 if (fd >= 0) {
607 break;
608 }
609 }
610 if (fd < 0) {
611 return NULL;
612 }
613
614 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH)
615 ioctl(fd, TIOCFLUSH, (char *) 0);
616 #endif
617
618 sprintf(slave_str, "/dev/tty%c%x", c, i);
619 *fd_p = fd;
620 return slave_str;
621 }
622
get_pty(int * fd_p)623 char *get_pty(int *fd_p) {
624 used_get_pty_ptmx = 0;
625 if (getenv("BSD_PTY")) {
626 return get_pty_loop(fd_p);
627 }
628 #ifdef IS_BSD
629 return get_pty_loop(fd_p);
630 #else
631 #if LIBVNCSERVER_HAVE_GRANTPT
632 used_get_pty_ptmx = 1;
633 return get_pty_ptmx(fd_p);
634 #else
635 return get_pty_loop(fd_p);
636 #endif
637 #endif
638 }
639
try_to_be_nobody(void)640 void try_to_be_nobody(void) {
641
642 #if LIBVNCSERVER_HAVE_PWD_H
643 struct passwd *pw;
644 pw = getpwnam("nobody");
645
646 if (pw) {
647 #if LIBVNCSERVER_HAVE_SETUID
648 setuid(pw->pw_uid);
649 #endif
650 #if LIBVNCSERVER_HAVE_SETEUID
651 seteuid(pw->pw_uid);
652 #endif
653 #if LIBVNCSERVER_HAVE_SETGID
654 setgid(pw->pw_gid);
655 #endif
656 #if LIBVNCSERVER_HAVE_SETEGID
657 setegid(pw->pw_gid);
658 #endif
659 }
660 #endif /* PWD_H */
661 }
662
663
664 static int slave_fd = -1, alarm_fired = 0;
665
close_alarm(int sig)666 static void close_alarm (int sig) {
667 if (slave_fd >= 0) {
668 close(slave_fd);
669 }
670 alarm_fired = 1;
671 if (0) sig = 0; /* compiler warning */
672 }
673
kill_child(pid_t pid,int fd)674 static void kill_child (pid_t pid, int fd) {
675 int status;
676
677 slave_fd = -1;
678 alarm_fired = 0;
679 if (fd >= 0) {
680 close(fd);
681 }
682 kill(pid, SIGTERM);
683 waitpid(pid, &status, WNOHANG);
684 }
685
scheck(char * str,int n,char * name)686 static int scheck(char *str, int n, char *name) {
687 int j, i;
688
689 if (! str) {
690 return 0;
691 }
692 j = 0;
693 for (i=0; i<n; i++) {
694 if (str[i] == '\0') {
695 j = 1;
696 break;
697 }
698 if (!strcmp(name, "password")) {
699 if (str[i] == '\n') {
700 continue;
701 }
702 }
703 if (str[i] < ' ' || str[i] >= 0x7f) {
704 rfbLog("scheck: invalid character in %s.\n", name);
705 return 0;
706 }
707 }
708 if (j == 0) {
709 rfbLog("scheck: unterminated string in %s.\n", name);
710 return 0;
711 }
712 return 1;
713 }
714
unixpw_list_match(char * user)715 int unixpw_list_match(char *user) {
716 if (! unixpw_list || unixpw_list[0] == '\0') {
717 return 1;
718 } else {
719 char *p, *q, *str = strdup(unixpw_list);
720 int ok = 0;
721 int notmode = 0;
722
723 if (str[0] == '!') {
724 notmode = 1;
725 ok = 1;
726 p = strtok(str+1, ",");
727 } else {
728 p = strtok(str, ",");
729 }
730 while (p) {
731 if ( (q = strchr(p, ':')) != NULL ) {
732 *q = '\0'; /* get rid of options. */
733 }
734 if (!strcmp(user, p)) {
735 if (notmode) {
736 ok = 0;
737 } else {
738 ok = 1;
739 }
740 break;
741 }
742 if (!notmode && !strcmp("*", p)) {
743 ok = 1;
744 break;
745 }
746 p = strtok(NULL, ",");
747 }
748 free(str);
749 if (! ok) {
750 rfbLog("unixpw_list_match: fail for '%s'\n", user);
751 return 0;
752 } else {
753 rfbLog("unixpw_list_match: OK for '%s'\n", user);
754 return 1;
755 }
756 }
757 }
758
crypt_verify(char * user,char * pass)759 int crypt_verify(char *user, char *pass) {
760 #ifndef UNIXPW_CRYPT
761 return 0;
762 #else
763 struct passwd *pwd;
764 char *realpw, *cr;
765 int n;
766
767 if (! scheck(user, 100, "username")) {
768 return 0;
769 }
770 if (! scheck(pass, 100, "password")) {
771 return 0;
772 }
773 if (! unixpw_list_match(user)) {
774 return 0;
775 }
776
777 pwd = getpwnam(user);
778 if (! pwd) {
779 return 0;
780 }
781
782 realpw = pwd->pw_passwd;
783 if (realpw == NULL || realpw[0] == '\0') {
784 return 0;
785 }
786
787 if (db > 1) fprintf(stderr, "realpw='%s'\n", realpw);
788
789 if (strlen(realpw) < 12) {
790 /* e.g. "x", try getspnam(), sometimes root for inetd, etc */
791 #if LIBVNCSERVER_HAVE_GETSPNAM
792 struct spwd *sp = getspnam(user);
793 if (sp != NULL && sp->sp_pwdp != NULL) {
794 if (db) fprintf(stderr, "using getspnam()\n");
795 realpw = sp->sp_pwdp;
796 } else {
797 if (db) fprintf(stderr, "skipping getspnam()\n");
798 }
799 #endif
800 }
801
802 n = strlen(pass);
803 if (pass[n-1] == '\n') {
804 pass[n-1] = '\0';
805 }
806
807 /* XXX remove need for cast */
808 cr = (char *) crypt(pass, realpw);
809 if (db > 1) {
810 fprintf(stderr, "user='%s' pass='%s' realpw='%s' cr='%s'\n",
811 user, pass, realpw, cr ? cr : "(null)");
812 }
813 if (cr == NULL || cr[0] == '\0') {
814 return 0;
815 }
816 if (!strcmp(cr, realpw)) {
817 return 1;
818 } else {
819 return 0;
820 }
821 #endif /* UNIXPW_CRYPT */
822 }
823
unixpw_cmd_run(char * user,char * pass,char * cmd,char * line,int * n)824 int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n) {
825 int i, len, rc;
826 char *str;
827 FILE *out;
828
829 if (! user || ! pass) {
830 return 0;
831 }
832 if (! unixpw_cmd || *unixpw_cmd == '\0') {
833 return 0;
834 }
835
836 if (! scheck(user, 100, "username")) {
837 return 0;
838 }
839 if (! scheck(pass, 100, "password")) {
840 return 0;
841 }
842 if (! unixpw_list_match(user)) {
843 return 0;
844 }
845 if (cmd == NULL) {
846 cmd = "";
847 }
848
849 len = strlen(user) + 1 + strlen(pass) + 1 + 1;
850 str = (char *) malloc(len);
851 if (! str) {
852 return 0;
853 }
854 str[0] = '\0';
855 strcat(str, user);
856 strcat(str, "\n");
857 strcat(str, pass);
858 if (!strchr(pass, '\n')) {
859 strcat(str, "\n");
860 }
861
862 out = tmpfile();
863 if (out == NULL) {
864 rfbLog("unixpw_cmd_run tmpfile() failed.\n");
865 clean_up_exit(1);
866 }
867
868 set_env("RFB_UNIXPW_CMD_RUN", cmd);
869
870 rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify",
871 str, strlen(str), out);
872
873 set_env("RFB_UNIXPW_CMD_RUN", "");
874
875 for (i=0; i < len; i++) {
876 str[i] = '\0';
877 }
878 free(str);
879
880 fflush(out);
881 rewind(out);
882 for (i=0; i < (*n) - 1; i++) {
883 int c = fgetc(out);
884 if (c == EOF) {
885 break;
886 }
887 line[i] = (char) c;
888 }
889 fclose(out);
890 *n = i;
891
892 if (rc == 0) {
893 return 1;
894 } else {
895 return 0;
896 }
897 }
898
899
cmd_verify(char * user,char * pass)900 int cmd_verify(char *user, char *pass) {
901 int i, len, rc;
902 char *str;
903
904 if (! user || ! pass) {
905 return 0;
906 }
907 if (! unixpw_cmd || *unixpw_cmd == '\0') {
908 return 0;
909 }
910
911 if (! scheck(user, 100, "username")) {
912 return 0;
913 }
914 if (! scheck(pass, 100, "password")) {
915 return 0;
916 }
917 if (! unixpw_list_match(user)) {
918 return 0;
919 }
920
921 if (unixpw_client) {
922 ClientData *cd = (ClientData *) unixpw_client->clientData;
923 if (cd) {
924 cd->username = strdup(user);
925 }
926 }
927
928 len = strlen(user) + 1 + strlen(pass) + 1 + 1;
929 str = (char *) malloc(len);
930 if (! str) {
931 return 0;
932 }
933 str[0] = '\0';
934 strcat(str, user);
935 strcat(str, "\n");
936 strcat(str, pass);
937 if (!strchr(pass, '\n')) {
938 strcat(str, "\n");
939 }
940
941 rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify",
942 str, strlen(str), NULL);
943
944 for (i=0; i < len; i++) {
945 str[i] = '\0';
946 }
947 free(str);
948
949 if (rc == 0) {
950 return 1;
951 } else {
952 return 0;
953 }
954 }
955
su_verify(char * user,char * pass,char * cmd,char * rbuf,int * rbuf_size,int nodisp)956 int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp) {
957 #ifndef UNIXPW_SU
958 return 0;
959 #else
960 int i, j, status, fd = -1, sfd, tfd, drain_size = 65536, rsize = 0;
961 int slow_pw = 1;
962 char *slave, *bin_true = NULL, *bin_su = NULL;
963 pid_t pid, pidw;
964 struct stat sbuf;
965 static int first = 1;
966 char instr[64], cbuf[10];
967
968 if (first) {
969 set_db();
970 first = 0;
971 }
972 rfbLog("su_verify: '%s' for %s.\n", user, cmd ? "command" : "login");
973 fflush(stderr);
974
975 if (! scheck(user, 100, "username")) {
976 return 0;
977 }
978 if (! scheck(pass, 100, "password")) {
979 return 0;
980 }
981 if (! unixpw_list_match(user)) {
982 return 0;
983 }
984
985 /* unixpw */
986 if (no_external_cmds || !cmd_ok("unixpw")) {
987 rfbLog("su_verify: cannot run external commands.\n");
988 clean_up_exit(1);
989 }
990
991 #define SU_DEBUG 0
992 #if SU_DEBUG
993 if (stat("/su", &sbuf) == 0) {
994 bin_su = "/su"; /* Freesbie read-only-fs /bin/su not suid! */
995 #else
996 if (0) {
997 ;
998 #endif
999 } else if (stat("/bin/su", &sbuf) == 0) {
1000 bin_su = "/bin/su";
1001 } else if (stat("/usr/bin/su", &sbuf) == 0) {
1002 bin_su = "/usr/bin/su";
1003 }
1004 if (bin_su == NULL) {
1005 rfbLogPerror("existence /bin/su");
1006 fflush(stderr);
1007 return 0;
1008 }
1009
1010 if (stat("/bin/true", &sbuf) == 0) {
1011 bin_true = "/bin/true";
1012 } if (stat("/usr/bin/true", &sbuf) == 0) {
1013 bin_true = "/usr/bin/true";
1014 }
1015 if (cmd != NULL && cmd[0] != '\0') {
1016 /* this is for ext. cmd su -c "my cmd" after login */
1017 bin_true = cmd;
1018 }
1019 if (bin_true == NULL) {
1020 rfbLogPerror("existence /bin/true");
1021 fflush(stderr);
1022 return 0;
1023 }
1024
1025 slave = get_pty(&fd);
1026
1027 if (slave == NULL) {
1028 rfbLogPerror("get_pty failed.");
1029 fflush(stderr);
1030 return 0;
1031 }
1032
1033 if (db) fprintf(stderr, "cmd is: %s\n", cmd);
1034 if (db) fprintf(stderr, "slave is: %s fd=%d\n", slave, fd);
1035
1036 if (fd < 0) {
1037 rfbLogPerror("get_pty fd < 0");
1038 fflush(stderr);
1039 return 0;
1040 }
1041
1042 fcntl(fd, F_SETFD, 1);
1043
1044 pid = fork();
1045 if (pid < 0) {
1046 rfbLogPerror("fork");
1047 fflush(stderr);
1048 close(fd);
1049 return 0;
1050 }
1051
1052 if (pid == 0) {
1053 /* child */
1054
1055 int ttyfd;
1056 ttyfd = -1; /* compiler warning */
1057
1058 #if LIBVNCSERVER_HAVE_SETSID
1059 if (setsid() == -1) {
1060 perror("setsid");
1061 exit(1);
1062 }
1063 #else
1064 if (setpgrp() == -1) {
1065 perror("setpgrp");
1066 exit(1);
1067 }
1068 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCNOTTY)
1069 ttyfd = open("/dev/tty", O_RDWR);
1070 if (ttyfd >= 0) {
1071 (void) ioctl(ttyfd, TIOCNOTTY, (char *) 0);
1072 close(ttyfd);
1073 }
1074 #endif
1075
1076 #endif /* SETSID */
1077
1078 close(0);
1079 close(1);
1080 close(2);
1081
1082 sfd = open(slave, O_RDWR);
1083 if (sfd < 0) {
1084 exit(1);
1085 }
1086
1087 /* streams options fixups, handle cases as they are found: */
1088 #if defined(__hpux)
1089 #if LIBVNCSERVER_HAVE_SYS_STROPTS_H
1090 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(I_PUSH)
1091 if (used_get_pty_ptmx) {
1092 ioctl(sfd, I_PUSH, "ptem");
1093 ioctl(sfd, I_PUSH, "ldterm");
1094 ioctl(sfd, I_PUSH, "ttcompat");
1095 }
1096 #endif
1097 #endif
1098 #endif
1099
1100 /* n.b. sfd will be 0 since we closed 0. so dup it to 1 and 2 */
1101 if (fcntl(sfd, F_DUPFD, 1) == -1) {
1102 exit(1);
1103 }
1104 if (fcntl(sfd, F_DUPFD, 2) == -1) {
1105 exit(1);
1106 }
1107
1108 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSCTTY)
1109 ioctl(sfd, TIOCSCTTY, (char *) 0);
1110 #endif
1111
1112 if (db > 2) {
1113 char nam[256];
1114 unlink("/tmp/isatty");
1115 tfd = open("/tmp/isatty", O_CREAT|O_WRONLY, 0600);
1116 if (isatty(sfd)) {
1117 close(tfd);
1118 sprintf(nam, "stty -a < %s > /tmp/isatty 2>&1",
1119 slave);
1120 system(nam);
1121 } else {
1122 write(tfd, "NOTTTY\n", 7);
1123 close(tfd);
1124 }
1125 }
1126
1127 chdir("/");
1128
1129 try_to_be_nobody();
1130 #if LIBVNCSERVER_HAVE_GETUID
1131 if (getuid() == 0 || geteuid() == 0) {
1132 exit(1);
1133 }
1134 #else
1135 exit(1);
1136 #endif
1137
1138 set_env("LC_ALL", "C");
1139 set_env("LANG", "C");
1140 set_env("SHELL", "/bin/sh");
1141 if (nodisp) {
1142 /* this will cause timeout problems with pam_xauth */
1143 int k;
1144 for (k=0; k<3; k++) {
1145 if (getenv("DISPLAY")) {
1146 char *s = getenv("DISPLAY");
1147 if (s) *(s-2) = '_'; /* quite... */
1148 }
1149 if (getenv("XAUTHORITY")) {
1150 char *s = getenv("XAUTHORITY");
1151 if (s) *(s-2) = '_'; /* quite... */
1152 }
1153 }
1154 }
1155
1156 /* synchronize with parent: */
1157 write(2, "C", 1);
1158
1159 if (cmd) {
1160 execlp(bin_su, bin_su, "-", user, "-c",
1161 bin_true, (char *) NULL);
1162 } else {
1163 execlp(bin_su, bin_su, user, "-c",
1164 bin_true, (char *) NULL);
1165 }
1166 exit(1);
1167 }
1168 /* parent */
1169
1170 if (db) fprintf(stderr, "pid: %d\n", pid);
1171
1172 /*
1173 * set an alarm for blocking read() to close the master
1174 * (presumably terminating the child. SIGTERM too...)
1175 */
1176 slave_fd = fd;
1177 alarm_fired = 0;
1178 signal(SIGALRM, close_alarm);
1179 alarm(10);
1180
1181 /* synchronize with child: */
1182 cbuf[0] = '\0';
1183 cbuf[1] = '\0';
1184 for (i=0; i<10; i++) {
1185 int n;
1186 cbuf[0] = '\0';
1187 cbuf[1] = '\0';
1188 n = read(fd, cbuf, 1);
1189 if (n < 0 && errno == EINTR) {
1190 continue;
1191 } else {
1192 break;
1193 }
1194 }
1195
1196 if (db) {
1197 fprintf(stderr, "read from child: '%s'\n", cbuf);
1198 }
1199
1200 alarm(0);
1201 signal(SIGALRM, SIG_DFL);
1202 if (alarm_fired) {
1203 kill_child(pid, fd);
1204 return 0;
1205 }
1206
1207 #if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCTRAP)
1208 {
1209 int control = 1;
1210 ioctl(fd, TIOCTRAP, &control);
1211 }
1212 #endif
1213
1214 /*
1215 * In addition to checking exit code below, we watch for the
1216 * appearance of the string "Password:". BSD does not seem to
1217 * ask for a password trying to su to yourself. This is the
1218 * setting in /etc/pam.d/su:
1219 * auth sufficient pam_self.so
1220 * it may be commented out without problem.
1221 */
1222 for (i=0; i< (int) sizeof(instr); i++) {
1223 instr[i] = '\0';
1224 }
1225
1226 alarm_fired = 0;
1227 signal(SIGALRM, close_alarm);
1228 alarm(10);
1229
1230 j = 0;
1231 for (i=0; i < (int) strlen("Password:"); i++) {
1232 char pstr[] = "password:";
1233 int n, problem;
1234
1235 cbuf[0] = '\0';
1236 cbuf[1] = '\0';
1237
1238 n = read(fd, cbuf, 1);
1239 if (n < 0 && errno == EINTR) {
1240 i--;
1241 if (i < -1) i = -1;
1242 continue;
1243 }
1244
1245 if (db) {
1246 fprintf(stderr, "%s", cbuf);
1247 if (db > 3 && n == 1 && cbuf[0] == ':') {
1248 char cmd0[32];
1249 usleep( 100 * 1000 );
1250 fprintf(stderr, "\n\n");
1251 sprintf(cmd0, "ps wu %d", pid);
1252 system(cmd0);
1253 sprintf(cmd0, "stty -a < %s", slave);
1254 system(cmd0);
1255 fprintf(stderr, "\n\n");
1256 }
1257 }
1258
1259 if (n == 1) {
1260 if (isspace((unsigned char) cbuf[0])) {
1261 i--;
1262 if (i < -1) i = -1;
1263 continue;
1264 }
1265 if (j >= (int) sizeof(instr)-1) {
1266 rfbLog("su_verify: problem finding Password:\n");
1267 fflush(stderr);
1268 return 0;
1269 }
1270 instr[j++] = tolower((unsigned char)cbuf[0]);
1271 }
1272
1273 problem = 0;
1274 if (n <= 0) {
1275 problem = 1;
1276 } else if (strstr(pstr, instr) != pstr) {
1277 #ifdef _AIX
1278 if (UT.sysname && strstr(UT.sysname, "AIX")) {
1279 /* handle: runge's Password: */
1280 char *luser = (char *) malloc(strlen(user) + 10);
1281
1282 sprintf(luser, "%s's", user);
1283 lowercase(luser);
1284 if (db) fprintf(stderr, "\nAIX luser compare: \"%s\" to \"%s\"\n", luser, instr);
1285 if (strstr(luser, instr) == luser) {
1286 if (db) fprintf(stderr, "AIX luser compare: strstr OK.\n");
1287 if (!strcmp(luser, instr)) {
1288 if (db) fprintf(stderr, "AIX luser compare: strings equal.\n");
1289 i = -1;
1290 j = 0;
1291 memset(instr, 0, sizeof(instr));
1292 free(luser);
1293 continue;
1294 } else {
1295 i--;
1296 if (i < -1) i = -1;
1297 free(luser);
1298 continue;
1299 }
1300 } else {
1301 if (db) fprintf(stderr, "AIX luser compare: problem=1\n");
1302 problem = 1;
1303 }
1304 free(luser);
1305 } else
1306 #endif
1307 {
1308 problem = 1;
1309 }
1310 }
1311
1312 if (problem) {
1313 if (db) {
1314 fprintf(stderr, "\"Password:\" did not "
1315 "appear: '%s'" " n=%d\n", instr, n);
1316 if (db > 3 && n == 1 && j < 32) {
1317 continue;
1318 }
1319 }
1320 alarm(0);
1321 signal(SIGALRM, SIG_DFL);
1322 kill_child(pid, fd);
1323 return 0;
1324 }
1325 }
1326
1327 alarm(0);
1328 signal(SIGALRM, SIG_DFL);
1329 if (alarm_fired) {
1330 kill_child(pid, fd);
1331 return 0;
1332 }
1333
1334 if (db) fprintf(stderr, "\nsending passwd: %s\n", db > 2 ? pass : "****");
1335 usleep(100 * 1000);
1336 if (slow_pw) {
1337 unsigned int k;
1338 for (k = 0; k < strlen(pass); k++) {
1339 write(fd, pass+k, 1);
1340 usleep(100 * 1000);
1341 }
1342 } else {
1343 write(fd, pass, strlen(pass));
1344 }
1345
1346 alarm_fired = 0;
1347 signal(SIGALRM, close_alarm);
1348 alarm(15);
1349
1350 /*
1351 * try to drain the output, hopefully never as much as 4096 (motd?)
1352 * if we don't drain we may block at waitpid. If we close(fd), the
1353 * make cause child to die by signal.
1354 */
1355 if (rbuf && *rbuf_size > 0) {
1356 /* asked to return output of command */
1357 drain_size = *rbuf_size;
1358 rsize = 0;
1359 }
1360 if (db) fprintf(stderr, "\ndraining:\n");
1361 for (i = 0; i< drain_size; i++) {
1362 int n;
1363
1364 cbuf[0] = '\0';
1365 cbuf[1] = '\0';
1366
1367 n = read(fd, cbuf, 1);
1368 if (n < 0 && errno == EINTR) {
1369 if (db) fprintf(stderr, "\nEINTR n=%d i=%d --", n, i);
1370 i--;
1371 if (i < 0) i = 0;
1372 continue;
1373 }
1374
1375 if (db) fprintf(stderr, "\nn=%d i=%d errno=%d %.6f '%s'", n, i, errno, dnowx(), cbuf);
1376
1377 if (n <= 0) {
1378 break;
1379 }
1380 if (rbuf && *rbuf_size > 0) {
1381 rbuf[rsize++] = cbuf[0];
1382 }
1383 }
1384 if (db && rbuf) fprintf(stderr, "\nrbuf: '%s'\n", rbuf);
1385
1386 if (rbuf && *rbuf_size > 0) {
1387 char *s = rbuf;
1388 char *p = strdup(pass);
1389 int n, o = 0;
1390
1391 n = strlen(p);
1392 if (p[n-1] == '\n') {
1393 p[n-1] = '\0';
1394 }
1395 /*
1396 * usually is: Password: mypassword\r\n\r\n<output-of-command>
1397 * and output will have \n -> \r\n
1398 */
1399 if (rbuf[0] == ' ') {
1400 s++;
1401 o++;
1402 }
1403 if (strstr(s, p) == s) {
1404 s += strlen(p);
1405 o += strlen(p);
1406 for (n = 0; n < 4; n++) {
1407 if (s[0] == '\r' || s[0] == '\n') {
1408 s++;
1409 o++;
1410 }
1411 }
1412 }
1413 if (o > 0) {
1414 int i = 0;
1415 rsize -= o;
1416 while (o < drain_size) {
1417 rbuf[i++] = rbuf[o++];
1418 }
1419 }
1420 *rbuf_size = rsize;
1421 strzero(p);
1422 free(p);
1423 }
1424
1425 if (db) fprintf(stderr, "\n--\n");
1426
1427 alarm(0);
1428 signal(SIGALRM, SIG_DFL);
1429 if (alarm_fired) {
1430 kill_child(pid, fd);
1431 return 0;
1432 }
1433
1434 slave_fd = -1;
1435
1436 pidw = waitpid(pid, &status, 0);
1437 close(fd);
1438
1439 if (pid != pidw) {
1440 return 0;
1441 }
1442
1443 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
1444 return 1; /* this is the only return of success. */
1445 } else {
1446 return 0;
1447 }
1448 #endif /* UNIXPW_SU */
1449 }
1450
1451 int unixpw_verify(char *user, char *pass) {
1452 int ok = 0;
1453 if (unixpw_cmd) {
1454 if (cmd_verify(user, pass)) {
1455 rfbLog("unixpw_verify: cmd_verify login for '%s'"
1456 " succeeded.\n", user);
1457 fflush(stderr);
1458 ok = 1;
1459 } else {
1460 rfbLog("unixpw_verify: cmd_verify login for '%s'"
1461 " failed.\n", user);
1462 fflush(stderr);
1463 usleep(3000*1000);
1464 ok = 0;
1465 }
1466 } else if (unixpw_nis) {
1467 if (crypt_verify(user, pass)) {
1468 rfbLog("unixpw_verify: crypt_verify login for '%s'"
1469 " succeeded.\n", user);
1470 fflush(stderr);
1471 ok = 1;
1472 } else {
1473 rfbLog("unixpw_verify: crypt_verify login for '%s'"
1474 " failed.\n", user);
1475 fflush(stderr);
1476 usleep(3000*1000);
1477 ok = 0;
1478 }
1479 } else {
1480 if (su_verify(user, pass, NULL, NULL, NULL, 1)) {
1481 rfbLog("unixpw_verify: su_verify login for '%s'"
1482 " succeeded.\n", user);
1483 fflush(stderr);
1484 ok = 1;
1485 } else {
1486 rfbLog("unixpw_verify: su_verify login for '%s'"
1487 " failed.\n", user);
1488 fflush(stderr);
1489 /* use su(1)'s sleep */
1490 ok = 0;
1491 }
1492 }
1493 return ok;
1494 }
1495
1496 static int skip_it = 0;
1497
1498 static void progress_skippy(void) {
1499 int i, msec = get_net_latency(); /* probabaly not set yet.. */
1500
1501 if (msec > 300) {
1502 msec = 300;
1503 } else if (msec <= 100) {
1504 msec = 100;
1505 }
1506
1507 skip_it = 1;
1508 for (i = 0; i < 5; i++) {
1509 if (i == 2) {
1510 rfbPE(msec * 1000);
1511 } else {
1512 rfbPE(-1);
1513 }
1514 usleep(10*1000);
1515 }
1516 skip_it = 0;
1517
1518 usleep(50*1000);
1519 }
1520
1521 void check_unixpw_userprefs(void) {
1522 char *prefs = getenv("FD_USERPREFS");
1523 if (keep_unixpw_user == NULL || keep_unixpw_opts == NULL) {
1524 return;
1525 }
1526 #if LIBVNCSERVER_HAVE_PWD_H
1527 if (prefs != NULL && !strchr(prefs, '/')) {
1528 struct passwd *pw = getpwnam(keep_unixpw_user);
1529 if (pw != NULL) {
1530 char *file;
1531 FILE *f;
1532
1533 file = (char *) malloc(strlen(pw->pw_dir) + 1 + strlen(prefs) + 1);
1534 sprintf(file, "%s/%s", pw->pw_dir, prefs);
1535
1536 f = fopen(file, "r");
1537 if (f) {
1538 char *t, *q, buf[1024];
1539 memset(buf, 0, sizeof(buf));
1540
1541 fgets(buf, 1024, f);
1542 fclose(f);
1543
1544 q = strchr(buf, '\n');
1545 if (q) *q = '\0';
1546 q = strchr(buf, '\r');
1547 if (q) *q = '\0';
1548
1549 rfbLog("read user prefs %s: %s\n", file, buf);
1550
1551 if (buf[0] == '#') buf[0] = '\0';
1552
1553 t = (char *) malloc(strlen(keep_unixpw_opts) + 1 + strlen(buf) + 1);
1554 sprintf(t, "%s,%s", keep_unixpw_opts, buf);
1555 free(keep_unixpw_opts);
1556 keep_unixpw_opts = t;
1557 } else {
1558 rfbLog("could not read user prefs %s\n", file);
1559 rfbLogPerror("fopen");
1560 }
1561 free(file);
1562 }
1563 }
1564 #endif
1565 }
1566
1567
1568 void unixpw_verify_screen(char *user, char *pass) {
1569 int x, y;
1570 char li[] = "Login incorrect";
1571 char ls[] = "Login succeeded";
1572 char log[] = "login: ";
1573 char *colon = NULL;
1574 ClientData *cd = NULL;
1575 int ok;
1576
1577 if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********");
1578 rfbLog("unixpw_verify: '%s'\n", user ? user : "(null)");
1579
1580 if (user) {
1581 colon = strchr(user, ':');
1582 }
1583 if (colon) {
1584 *colon = '\0';
1585 rfbLog("unixpw_verify: colon: '%s'\n", user);
1586 }
1587 fflush(stderr);
1588 if (unixpw_client) {
1589 cd = (ClientData *) unixpw_client->clientData;
1590 if (cd) {
1591 char *str = (char *)malloc(strlen("UNIX:") +
1592 strlen(user) + 1);
1593 sprintf(str, "UNIX:%s", user);
1594 if (cd->username) {
1595 free(cd->username);
1596 }
1597 cd->username = str;
1598 }
1599 }
1600
1601 ok = unixpw_verify(user, pass);
1602
1603 if (ok) {
1604 char_row++;
1605 char_col = 0;
1606
1607 x = text_x();
1608 y = text_y();
1609 rfbDrawString(pscreen, &default8x16Font, x, y, ls, white_pixel());
1610 unixpw_mark();
1611
1612 progress_skippy();
1613
1614 unixpw_accept(user);
1615
1616 if (keep_unixpw) {
1617 keep_unixpw_user = strdup(user);
1618 keep_unixpw_pass = strdup(pass);
1619 if (colon) {
1620 keep_unixpw_opts = strdup(colon+1);
1621 } else {
1622 keep_unixpw_opts = strdup("");
1623 }
1624 check_unixpw_userprefs();
1625 }
1626
1627 if (colon) *colon = ':';
1628
1629 return;
1630 }
1631 if (colon) *colon = ':';
1632
1633 if (tries < 2) {
1634 char_row++;
1635 char_col = 0;
1636
1637 x = text_x();
1638 y = text_y();
1639 rfbDrawString(pscreen, &default8x16Font, x, y, li, white_pixel());
1640
1641 char_row += 2;
1642
1643 x = text_x();
1644 y = text_y();
1645 rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
1646
1647 char_col = strlen(log);
1648
1649 unixpw_mark();
1650
1651 unixpw_last_try_time = time(NULL);
1652 unixpw_keystroke(0, 0, 2);
1653 tries++;
1654 } else {
1655 unixpw_deny();
1656 }
1657 }
1658
1659 static void set_db(void) {
1660 if (getenv("DEBUG_UNIXPW")) {
1661 db = atoi(getenv("DEBUG_UNIXPW"));
1662 rfbLog("DEBUG_UNIXPW: %d\n", db);
1663 }
1664 }
1665
1666 void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
1667 int x, y, i, rc, nmax = 100;
1668 static char user_r[100], user[100], pass[100];
1669 static int u_cnt = 0, p_cnt = 0, t_cnt = 0, first = 1;
1670 static int echo = 1;
1671 char keystr[100];
1672 char *str;
1673
1674 if (skip_it) {
1675 return;
1676 }
1677
1678 if (first) {
1679 set_db();
1680 first = 0;
1681 for (i=0; i < nmax; i++) {
1682 user_r[i] = '\0';
1683 user[i] = '\0';
1684 pass[i] = '\0';
1685 }
1686 }
1687
1688 if (init) {
1689 in_login = 1;
1690 in_passwd = 0;
1691 unixpw_denied = 0;
1692 echo = 1;
1693 if (init == 1) {
1694 tries = 0;
1695 }
1696
1697 u_cnt = 0;
1698 p_cnt = 0;
1699 t_cnt = 0;
1700 for (i=0; i<nmax; i++) {
1701 user[i] = '\0';
1702 pass[i] = '\0';
1703 }
1704 if (keep_unixpw_user) {
1705 free(keep_unixpw_user);
1706 keep_unixpw_user = NULL;
1707 }
1708 if (keep_unixpw_pass) {
1709 strzero(keep_unixpw_pass);
1710 free(keep_unixpw_pass);
1711 keep_unixpw_pass = NULL;
1712 }
1713 if (keep_unixpw_opts) {
1714 strzero(keep_unixpw_opts);
1715 free(keep_unixpw_opts);
1716 keep_unixpw_opts = NULL;
1717 }
1718
1719 return;
1720 }
1721
1722 if (unixpw_denied) {
1723 rfbLog("unixpw_keystroke: unixpw_denied state: 0x%x\n", (int) keysym);
1724 return;
1725 }
1726 if (keysym <= 0) {
1727 rfbLog("unixpw_keystroke: bad keysym1: 0x%x\n", (int) keysym);
1728 return;
1729 }
1730
1731 /* rfbKeySym = uint32_t */
1732 /* KeySym = XID = CARD32 = (unsigned long or unsigned int on LONG64) */
1733 X_LOCK;
1734 str = XKeysymToString(keysym);
1735 X_UNLOCK;
1736 if (str == NULL) {
1737 rfbLog("unixpw_keystroke: bad keysym2: 0x%x\n", (int) keysym);
1738 return;
1739 }
1740
1741 rc = snprintf(keystr, 100, "%s", str);
1742 if (rc < 1 || rc > 90) {
1743 rfbLog("unixpw_keystroke: bad keysym3: 0x%x\n", (int) keysym);
1744 return;
1745 }
1746
1747 if (db > 2) {
1748 fprintf(stderr, "%s / %s 0x%x %s\n", in_login ? "login":"pass ",
1749 down ? "down":"up ", keysym, keystr);
1750 }
1751
1752 if (keysym == XK_Return || keysym == XK_Linefeed || keysym == XK_Tab) {
1753 /* let "up" pass down below for Return case */
1754 if (down) {
1755 return;
1756 }
1757 } else if (! down) {
1758 return;
1759 }
1760 if (keysym == XK_F1) {
1761 char h1[] = "F1-Help: For 'login:' type in the username and press Enter, then for 'Password:' enter the password.";
1762 char hf[] = " Once logged in, username's X session will be searched for and if found then attached to.";
1763 char hc[] = " Once logged in, username's X session is sought and attached to, otherwise a new session is created.";
1764 char hx[] = " Once logged in, username's X session is sought and attached to, otherwise a login greeter is presented.";
1765 char h2[] = " Specify options after a ':' like this: username:opt,opt=val,... Where an opt may be any of:";
1766 char h3[] = " scale=... (n/m); scale_cursor=... (sc=); solid (so); id=; repeat; clear_mods (cm); clear_keys (ck);";
1767 char h4[] = " clear_all (ca); speeds=... (sp=); readtimeout=... (rd=) rotate=... (ro=); noncache (nc) (nc=n);";
1768 char h5[] = " geom=WxHxD (ge=); nodisplay=... (nd=); viewonly (vo); tag=...; gnome kde twm fvwm mwm dtwm wmaker";
1769 char h6[] = " xfce lxde enlightenment Xsession failsafe. Examples: fred:3/4,so,cm wilma:geom=1024x768x16,kde";
1770 int ch = 13, p;
1771 if (!pscreen || pscreen->width < 640 || pscreen->height < 480) {
1772 return;
1773 }
1774 if (f1_help) {
1775 p = black_pixel();
1776 f1_help = 0;
1777 } else {
1778 p = white_pixel();
1779 f1_help = 1;
1780 unixpw_last_try_time = time(NULL) + 45;
1781 }
1782 rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, h1, p);
1783 if (use_dpy == NULL) {
1784 ;
1785 } else if (strstr(use_dpy, "cmd=FINDDISPLAY")) {
1786 rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hf, p);
1787 } else if (strstr(use_dpy, "cmd=FINDCREATEDISPLAY")) {
1788 if (strstr(use_dpy, "xdmcp")) {
1789 rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hx, p);
1790 } else {
1791 rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hc, p);
1792 }
1793 }
1794 rfbDrawString(pscreen, &default6x13Font, 8, 2+3*ch, h2, p);
1795 rfbDrawString(pscreen, &default6x13Font, 8, 2+4*ch, h3, p);
1796 rfbDrawString(pscreen, &default6x13Font, 8, 2+5*ch, h4, p);
1797 rfbDrawString(pscreen, &default6x13Font, 8, 2+6*ch, h5, p);
1798 rfbDrawString(pscreen, &default6x13Font, 8, 2+7*ch, h6, p);
1799 if (!f1_help) {
1800 rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, "F1-Help:", white_pixel());
1801 }
1802 unixpw_mark();
1803 return;
1804 }
1805 if (unixpw_system_greeter_active && keysym == XK_Escape) {
1806 char *u = get_user_name();
1807 if (keep_unixpw) {
1808 char *colon = strchr(user, ':');
1809 keep_unixpw_user = strdup(u);
1810 keep_unixpw_pass = strdup("");
1811 if (colon) {
1812 keep_unixpw_opts = strdup(colon+1);
1813 } else {
1814 keep_unixpw_opts = strdup("");
1815 }
1816 check_unixpw_userprefs();
1817 }
1818 unixpw_system_greeter_active = 2;
1819 set_env("X11VNC_XDM_ONLY", "1");
1820 rfbLog("unixpw_system_greeter: VNC client pressed 'Escape'. Allowing\n");
1821 rfbLog("unixpw_system_greeter: a *FREE* (no password) connection to\n");
1822 rfbLog("unixpw_system_greeter: the system XDM/GDM/KDM login greeter.\n");
1823 if (1) {
1824 char msg[] = " Please wait... ";
1825 rfbDrawString(pscreen, &default8x16Font,
1826 text_x(), text_y(), msg, white_pixel());
1827 unixpw_mark();
1828
1829 progress_skippy();
1830 }
1831 unixpw_accept(u);
1832 free(u);
1833 return;
1834 }
1835
1836 if (in_login && keysym == XK_Escape && u_cnt == 0) {
1837 echo = 0;
1838 rfbLog("unixpw_keystroke: echo off.\n");
1839 return;
1840 }
1841
1842 t_cnt++;
1843
1844 if (in_login) {
1845 if (keysym == XK_BackSpace || keysym == XK_Delete) {
1846 if (u_cnt > 0) {
1847 user[u_cnt-1] = '\0';
1848 u_cnt--;
1849
1850 x = text_x();
1851 y = text_y();
1852 if (scaling) {
1853 int x2 = x / scale_fac_x;
1854 int y2 = y / scale_fac_y;
1855 int w2 = char_w / scale_fac_x;
1856 int h2 = char_h / scale_fac_y;
1857
1858 x2 = nfix(x2, dpy_x);
1859 y2 = nfix(y2, dpy_y);
1860
1861 zero_fb(x2 - w2, y2 - h2, x2, y2);
1862 mark_rect_as_modified(x2 - w2,
1863 y2 - h2, x2, y2, 0);
1864 } else {
1865 zero_fb(x - char_w, y - char_h, x, y);
1866 mark_rect_as_modified(x - char_w,
1867 y - char_h, x, y, 0);
1868 }
1869 char_col--;
1870 }
1871
1872 return;
1873 }
1874
1875 if (keysym == XK_Return || keysym == XK_Linefeed || keysym == XK_Tab) {
1876 char pw[] = "Password: ";
1877
1878 if (down) {
1879 /*
1880 * require Up so the Return Up is not processed
1881 * by the normal session after login.
1882 * (actually we already returned above)
1883 */
1884 return;
1885 }
1886
1887 if (t_cnt == 1) {
1888 /* accidental initial return, e.g. from xterm */
1889 return;
1890 }
1891
1892 in_login = 0;
1893 in_passwd = 1;
1894
1895 char_row++;
1896 char_col = 0;
1897
1898 x = text_x();
1899 y = text_y();
1900 rfbDrawString(pscreen, &default8x16Font, x, y, pw,
1901 white_pixel());
1902
1903 char_col = strlen(pw);
1904 unixpw_mark();
1905 return;
1906 }
1907
1908 if (u_cnt == 0 && keysym == XK_Up) {
1909 /*
1910 * Allow user to hit Up arrow at beginning to
1911 * regain their username plus any options.
1912 */
1913 int i;
1914 for (i=0; i < nmax; i++) {
1915 user[i] = '\0';
1916 }
1917 for (i=0; i < nmax; i++) {
1918 char str[10];
1919 user[u_cnt++] = user_r[i];
1920 if (user_r[i] == '\0') {
1921 break;
1922 }
1923 str[0] = (char) user_r[i];
1924 str[1] = '\0';
1925
1926 x = text_x();
1927 y = text_y();
1928 if (echo) {
1929 rfbDrawString(pscreen, &default8x16Font, x, y,
1930 str, white_pixel());
1931 }
1932 mark_rect_as_modified(x, y-char_h, x+char_w,
1933 y, scaling);
1934 char_col++;
1935 usleep(10*1000);
1936 }
1937 return;
1938 }
1939
1940 if (keysym < ' ' || keysym >= 0x7f) {
1941 /* require normal keyboard characters for username */
1942 rfbLog("unixpw_keystroke: bad keysym4: 0x%x\n", (int) keysym);
1943 return;
1944 }
1945
1946 if (u_cnt >= nmax - 1) {
1947 /* user[u_cnt=99] will be '\0' */
1948 rfbLog("unixpw_deny: username too long: %d\n", u_cnt);
1949 for (i=0; i<nmax; i++) {
1950 user[i] = '\0';
1951 pass[i] = '\0';
1952 }
1953 unixpw_deny();
1954 return;
1955 }
1956
1957 #if 0
1958 user[u_cnt++] = keystr[0];
1959 #else
1960 user[u_cnt++] = (char) keysym;
1961 for (i=0; i < nmax; i++) {
1962 /* keep a full copy of username */
1963 user_r[i] = user[i];
1964 }
1965 keystr[0] = (char) keysym;
1966 #endif
1967 keystr[1] = '\0';
1968
1969 x = text_x();
1970 y = text_y();
1971
1972 if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x '%s'\n", u_cnt, x, y, keysym, keystr);
1973
1974 if (echo ) {
1975 rfbDrawString(pscreen, &default8x16Font, x, y, keystr, white_pixel());
1976 }
1977
1978 mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling);
1979 char_col++;
1980
1981 return;
1982
1983 } else if (in_passwd) {
1984 if (keysym == XK_BackSpace || keysym == XK_Delete) {
1985 if (p_cnt > 0) {
1986 pass[p_cnt-1] = '\0';
1987 p_cnt--;
1988 }
1989 return;
1990 }
1991 if (keysym == XK_Return || keysym == XK_Linefeed) {
1992 if (down) {
1993 /*
1994 * require Up so the Return Up is not processed
1995 * by the normal session after login.
1996 * (actually we already returned above)
1997 */
1998 return;
1999 }
2000
2001 if (1) {
2002 char msg[] = " Please wait... ";
2003 rfbDrawString(pscreen, &default8x16Font,
2004 text_x(), text_y(), msg, white_pixel());
2005 unixpw_mark();
2006
2007 progress_skippy();
2008 }
2009
2010 in_login = 0;
2011 in_passwd = 0;
2012
2013 pass[p_cnt++] = '\n';
2014 unixpw_verify_screen(user, pass);
2015 for (i=0; i<nmax; i++) {
2016 user[i] = '\0';
2017 pass[i] = '\0';
2018 }
2019 return;
2020 }
2021
2022 if (keysym < ' ' || keysym >= 0x7f) {
2023 /* require normal keyboard characters for password */
2024 return;
2025 }
2026
2027 if (p_cnt >= nmax - 2) {
2028 /* pass[u_cnt=98] will be '\n' */
2029 /* pass[u_cnt=99] will be '\0' */
2030 rfbLog("unixpw_deny: password too long: %d\n", p_cnt);
2031 for (i=0; i<nmax; i++) {
2032 user[i] = '\0';
2033 pass[i] = '\0';
2034 }
2035 unixpw_deny();
2036 return;
2037 }
2038
2039 pass[p_cnt++] = (char) keysym;
2040
2041 return;
2042
2043 } else {
2044 /* should not happen... anyway clean up a bit. */
2045 u_cnt = 0;
2046 p_cnt = 0;
2047 for (i=0; i<nmax; i++) {
2048 user_r[i] = '\0';
2049 user[i] = '\0';
2050 pass[i] = '\0';
2051 }
2052
2053 return;
2054 }
2055 }
2056
2057 static void apply_opts (char *user) {
2058 char *p, *q, *str, *opts = NULL, *opts_star = NULL;
2059 rfbClientPtr cl;
2060 ClientData *cd;
2061 int i, notmode = 0;
2062
2063 if (! unixpw_client) {
2064 rfbLog("apply_opts: unixpw_client is NULL\n");
2065 clean_up_exit(1);
2066 }
2067 cd = (ClientData *) unixpw_client->clientData;
2068 cl = unixpw_client;
2069
2070 if (! cd) {
2071 rfbLog("apply_opts: no ClientData\n");
2072 }
2073
2074 if (user && cd) {
2075 if (cd->unixname) {
2076 free(cd->unixname);
2077 }
2078 cd->unixname = strdup(user);
2079 rfbLog("apply_opts: set unixname to: %s\n", cd->unixname);
2080 }
2081
2082 if (! unixpw_list) {
2083 return;
2084 }
2085 str = strdup(unixpw_list);
2086
2087 /* apply any per-user options. */
2088 if (str[0] == '!') {
2089 p = strtok(str+1, ",");
2090 notmode = 1;
2091 } else {
2092 p = strtok(str, ",");
2093 }
2094 while (p) {
2095 if ( (q = strchr(p, ':')) != NULL ) {
2096 *q = '\0'; /* get rid of options. */
2097 } else {
2098 p = strtok(NULL, ",");
2099 continue;
2100 }
2101 if (user && !strcmp(user, p)) {
2102 /* will not happen in notmode */
2103 opts = strdup(q+1);
2104 }
2105 if (!strcmp("*", p)) {
2106 opts_star = strdup(q+1);
2107 }
2108 p = strtok(NULL, ",");
2109 }
2110 free(str);
2111
2112 for (i=0; i < 2; i++) {
2113 char *s = (i == 0) ? opts_star : opts;
2114 if (s == NULL) {
2115 continue;
2116 }
2117 p = strtok(s, "+");
2118 while (p) {
2119 if (!strcmp(p, "viewonly")) {
2120 cl->viewOnly = TRUE;
2121 if (cd) {
2122 strncpy(cd->input, "-", CILEN);
2123 }
2124 } else if (!strcmp(p, "fullaccess")) {
2125 cl->viewOnly = FALSE;
2126 if (cd) {
2127 strncpy(cd->input, "-", CILEN);
2128 }
2129 } else if ((q = strstr(p, "input=")) == p) {
2130 q += strlen("input=");
2131 if (cd) {
2132 strncpy(cd->input, q, CILEN);
2133 }
2134 } else if (!strcmp(p, "deny")) {
2135 cl->viewOnly = TRUE;
2136 unixpw_deny();
2137 break;
2138 }
2139 p = strtok(NULL, "+");
2140 }
2141 free(s);
2142 }
2143 }
2144
2145 void unixpw_accept(char *user) {
2146 apply_opts(user);
2147
2148 if (!use_stunnel) {
2149 ssl_helper_pid(0, -2); /* waitall */
2150 }
2151
2152 if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
2153 if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy &&
2154 dpy == NULL) {
2155 /* handled in main() */
2156 unixpw_client->onHold = TRUE;
2157 } else if (! accept_client(unixpw_client)) {
2158 unixpw_deny();
2159 return;
2160 }
2161 }
2162
2163 if (started_as_root == 1 && users_list
2164 && strstr(users_list, "unixpw=") == users_list) {
2165 if (getuid() && geteuid()) {
2166 rfbLog("unixpw_accept: unixpw= but not root\n");
2167 started_as_root = 2;
2168 } else {
2169 char *u = (char *)malloc(strlen(user)+1);
2170
2171 u[0] = '\0';
2172 if (!strcmp(users_list, "unixpw=")) {
2173 sprintf(u, "+%s", user);
2174 } else {
2175 char *p, *str = strdup(users_list);
2176 p = strtok(str + strlen("unixpw="), ",");
2177 while (p) {
2178 if (!strcmp(p, user)) {
2179 sprintf(u, "+%s", user);
2180 break;
2181 }
2182 p = strtok(NULL, ",");
2183 }
2184 free(str);
2185 }
2186
2187 if (u[0] == '\0') {
2188 rfbLog("unixpw_accept skipping switch to user: %s\n", user);
2189 } else if (switch_user(u, 0)) {
2190 rfbLog("unixpw_accept switched to user: %s\n", user);
2191 } else {
2192 rfbLog("unixpw_accept failed to switch to user: %s\n", user);
2193 }
2194 free(u);
2195 }
2196 }
2197
2198 if (unixpw_login_viewonly) {
2199 unixpw_client->viewOnly = TRUE;
2200 }
2201 unixpw_in_progress = 0;
2202 /* mutex */
2203 screen->permitFileTransfer = unixpw_file_xfer_save;
2204 if ((tightfilexfer = unixpw_tightvnc_xfer_save)) {
2205 /* this doesn't work: the current client is never registered! */
2206 #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
2207 rfbLog("rfbRegisterTightVNCFileTransferExtension: 1\n");
2208 rfbRegisterTightVNCFileTransferExtension();
2209 #endif
2210 }
2211 unixpw_client = NULL;
2212 mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
2213 if (macosx_console) {
2214 refresh_screen(1);
2215 }
2216 }
2217
2218 void unixpw_deny(void) {
2219 int x, y, i;
2220 char pd[] = "Permission denied.";
2221
2222 rfbLog("unixpw_deny: %d, %d\n", unixpw_denied, unixpw_in_progress);
2223 if (! unixpw_denied) {
2224 unixpw_denied = 1;
2225
2226 char_row += 2;
2227 char_col = 0;
2228 x = char_x + char_col * char_w;
2229 y = char_y + char_row * char_h;
2230
2231 rfbDrawString(pscreen, &default8x16Font, x, y, pd, white_pixel());
2232 unixpw_mark();
2233
2234 for (i=0; i<5; i++) {
2235 rfbPE(-1);
2236 rfbPE(-1);
2237 usleep(500 * 1000);
2238 }
2239 }
2240
2241 if (unixpw_client) {
2242 rfbCloseClient(unixpw_client);
2243 rfbClientConnectionGone(unixpw_client);
2244 rfbPE(-1);
2245 }
2246
2247 unixpw_in_progress = 0;
2248 /* mutex */
2249 screen->permitFileTransfer = unixpw_file_xfer_save;
2250 if ((tightfilexfer = unixpw_tightvnc_xfer_save)) {
2251 #ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
2252 rfbLog("rfbRegisterTightVNCFileTransferExtension: 2\n");
2253 rfbRegisterTightVNCFileTransferExtension();
2254 #endif
2255 }
2256 unixpw_client = NULL;
2257 copy_screen();
2258 }
2259
2260 void unixpw_msg(char *msg, int delay) {
2261 int x, y, i;
2262
2263 char_row += 2;
2264 char_col = 0;
2265 x = char_x + char_col * char_w;
2266 y = char_y + char_row * char_h;
2267
2268 rfbDrawString(pscreen, &default8x16Font, x, y, msg, white_pixel());
2269 unixpw_mark();
2270
2271 for (i=0; i<5; i++) {
2272 rfbPE(-1);
2273 rfbPE(-1);
2274 rfbPE(50 * 1000);
2275 rfbPE(-1);
2276 usleep(500 * 1000);
2277 if (i >= delay) {
2278 break;
2279 }
2280 }
2281 }
2282