diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/clientloop.c b/clientloop.c index ae4dce820..ee36cc9e5 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.137 2005/06/08 11:25:09 djm Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.138 2005/06/16 03:38:36 djm Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -208,6 +208,109 @@ get_current_time(void) | |||
208 | return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; | 208 | return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; |
209 | } | 209 | } |
210 | 210 | ||
211 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
212 | void | ||
213 | client_x11_get_proto(const char *display, const char *xauth_path, | ||
214 | u_int trusted, char **_proto, char **_data) | ||
215 | { | ||
216 | char cmd[1024]; | ||
217 | char line[512]; | ||
218 | char xdisplay[512]; | ||
219 | static char proto[512], data[512]; | ||
220 | FILE *f; | ||
221 | int got_data = 0, generated = 0, do_unlink = 0, i; | ||
222 | char *xauthdir, *xauthfile; | ||
223 | struct stat st; | ||
224 | |||
225 | xauthdir = xauthfile = NULL; | ||
226 | *_proto = proto; | ||
227 | *_data = data; | ||
228 | proto[0] = data[0] = '\0'; | ||
229 | |||
230 | if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { | ||
231 | debug("No xauth program."); | ||
232 | } else { | ||
233 | if (display == NULL) { | ||
234 | debug("x11_get_proto: DISPLAY not set"); | ||
235 | return; | ||
236 | } | ||
237 | /* | ||
238 | * Handle FamilyLocal case where $DISPLAY does | ||
239 | * not match an authorization entry. For this we | ||
240 | * just try "xauth list unix:displaynum.screennum". | ||
241 | * XXX: "localhost" match to determine FamilyLocal | ||
242 | * is not perfect. | ||
243 | */ | ||
244 | if (strncmp(display, "localhost:", 10) == 0) { | ||
245 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", | ||
246 | display + 10); | ||
247 | display = xdisplay; | ||
248 | } | ||
249 | if (trusted == 0) { | ||
250 | xauthdir = xmalloc(MAXPATHLEN); | ||
251 | xauthfile = xmalloc(MAXPATHLEN); | ||
252 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); | ||
253 | if (mkdtemp(xauthdir) != NULL) { | ||
254 | do_unlink = 1; | ||
255 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
256 | xauthdir); | ||
257 | snprintf(cmd, sizeof(cmd), | ||
258 | "%s -f %s generate %s " SSH_X11_PROTO | ||
259 | " untrusted timeout 1200 2>" _PATH_DEVNULL, | ||
260 | xauth_path, xauthfile, display); | ||
261 | debug2("x11_get_proto: %s", cmd); | ||
262 | if (system(cmd) == 0) | ||
263 | generated = 1; | ||
264 | } | ||
265 | } | ||
266 | snprintf(cmd, sizeof(cmd), | ||
267 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
268 | xauth_path, | ||
269 | generated ? "-f " : "" , | ||
270 | generated ? xauthfile : "", | ||
271 | display); | ||
272 | debug2("x11_get_proto: %s", cmd); | ||
273 | f = popen(cmd, "r"); | ||
274 | if (f && fgets(line, sizeof(line), f) && | ||
275 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | ||
276 | got_data = 1; | ||
277 | if (f) | ||
278 | pclose(f); | ||
279 | } | ||
280 | |||
281 | if (do_unlink) { | ||
282 | unlink(xauthfile); | ||
283 | rmdir(xauthdir); | ||
284 | } | ||
285 | if (xauthdir) | ||
286 | xfree(xauthdir); | ||
287 | if (xauthfile) | ||
288 | xfree(xauthfile); | ||
289 | |||
290 | /* | ||
291 | * If we didn't get authentication data, just make up some | ||
292 | * data. The forwarding code will check the validity of the | ||
293 | * response anyway, and substitute this data. The X11 | ||
294 | * server, however, will ignore this fake data and use | ||
295 | * whatever authentication mechanisms it was using otherwise | ||
296 | * for the local connection. | ||
297 | */ | ||
298 | if (!got_data) { | ||
299 | u_int32_t rnd = 0; | ||
300 | |||
301 | logit("Warning: No xauth data; " | ||
302 | "using fake authentication data for X11 forwarding."); | ||
303 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
304 | for (i = 0; i < 16; i++) { | ||
305 | if (i % 4 == 0) | ||
306 | rnd = arc4random(); | ||
307 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", | ||
308 | rnd & 0xff); | ||
309 | rnd >>= 8; | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | |||
211 | /* | 314 | /* |
212 | * This is called when the interactive is entered. This checks if there is | 315 | * This is called when the interactive is entered. This checks if there is |
213 | * an EOF coming on stdin. We must check this explicitly, as select() does | 316 | * an EOF coming on stdin. We must check this explicitly, as select() does |