summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clientloop.c114
-rw-r--r--clientloop.h4
-rw-r--r--mux.c22
-rw-r--r--ssh.c23
4 files changed, 93 insertions, 70 deletions
diff --git a/clientloop.c b/clientloop.c
index f55545194..c0386d56b 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.278 2015/12/26 07:46:03 semarie Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.279 2016/01/13 23:04:47 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -288,6 +288,9 @@ client_x11_display_valid(const char *display)
288{ 288{
289 size_t i, dlen; 289 size_t i, dlen;
290 290
291 if (display == NULL)
292 return 0;
293
291 dlen = strlen(display); 294 dlen = strlen(display);
292 for (i = 0; i < dlen; i++) { 295 for (i = 0; i < dlen; i++) {
293 if (!isalnum((u_char)display[i]) && 296 if (!isalnum((u_char)display[i]) &&
@@ -301,34 +304,33 @@ client_x11_display_valid(const char *display)
301 304
302#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 305#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
303#define X11_TIMEOUT_SLACK 60 306#define X11_TIMEOUT_SLACK 60
304void 307int
305client_x11_get_proto(const char *display, const char *xauth_path, 308client_x11_get_proto(const char *display, const char *xauth_path,
306 u_int trusted, u_int timeout, char **_proto, char **_data) 309 u_int trusted, u_int timeout, char **_proto, char **_data)
307{ 310{
308 char cmd[1024]; 311 char cmd[1024], line[512], xdisplay[512];
309 char line[512]; 312 char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
310 char xdisplay[512];
311 static char proto[512], data[512]; 313 static char proto[512], data[512];
312 FILE *f; 314 FILE *f;
313 int got_data = 0, generated = 0, do_unlink = 0, i; 315 int got_data = 0, generated = 0, do_unlink = 0, i, r;
314 char xauthdir[PATH_MAX] = "", xauthfile[PATH_MAX] = "";
315 struct stat st; 316 struct stat st;
316 u_int now, x11_timeout_real; 317 u_int now, x11_timeout_real;
317 318
318 *_proto = proto; 319 *_proto = proto;
319 *_data = data; 320 *_data = data;
320 proto[0] = data[0] = '\0'; 321 proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0';
321 322
322 if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { 323 if (!client_x11_display_valid(display)) {
323 debug("No xauth program."); 324 logit("DISPLAY \"%s\" invalid; disabling X11 forwarding",
324 } else if (!client_x11_display_valid(display)) {
325 logit("DISPLAY '%s' invalid, falling back to fake xauth data",
326 display); 325 display);
327 } else { 326 return -1;
328 if (display == NULL) { 327 }
329 debug("x11_get_proto: DISPLAY not set"); 328 if (xauth_path != NULL && stat(xauth_path, &st) == -1) {
330 return; 329 debug("No xauth program.");
331 } 330 xauth_path = NULL;
331 }
332
333 if (xauth_path != NULL) {
332 /* 334 /*
333 * Handle FamilyLocal case where $DISPLAY does 335 * Handle FamilyLocal case where $DISPLAY does
334 * not match an authorization entry. For this we 336 * not match an authorization entry. For this we
@@ -337,43 +339,60 @@ client_x11_get_proto(const char *display, const char *xauth_path,
337 * is not perfect. 339 * is not perfect.
338 */ 340 */
339 if (strncmp(display, "localhost:", 10) == 0) { 341 if (strncmp(display, "localhost:", 10) == 0) {
340 snprintf(xdisplay, sizeof(xdisplay), "unix:%s", 342 if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
341 display + 10); 343 display + 10)) < 0 ||
344 (size_t)r >= sizeof(xdisplay)) {
345 error("%s: display name too long", __func__);
346 return -1;
347 }
342 display = xdisplay; 348 display = xdisplay;
343 } 349 }
344 if (trusted == 0) { 350 if (trusted == 0) {
345 mktemp_proto(xauthdir, PATH_MAX);
346 /* 351 /*
352 * Generate an untrusted X11 auth cookie.
353 *
347 * The authentication cookie should briefly outlive 354 * The authentication cookie should briefly outlive
348 * ssh's willingness to forward X11 connections to 355 * ssh's willingness to forward X11 connections to
349 * avoid nasty fail-open behaviour in the X server. 356 * avoid nasty fail-open behaviour in the X server.
350 */ 357 */
358 mktemp_proto(xauthdir, sizeof(xauthdir));
359 if (mkdtemp(xauthdir) == NULL) {
360 error("%s: mkdtemp: %s",
361 __func__, strerror(errno));
362 return -1;
363 }
364 do_unlink = 1;
365 if ((r = snprintf(xauthfile, sizeof(xauthfile),
366 "%s/xauthfile", xauthdir)) < 0 ||
367 (size_t)r >= sizeof(xauthfile)) {
368 error("%s: xauthfile path too long", __func__);
369 unlink(xauthfile);
370 rmdir(xauthdir);
371 return -1;
372 }
373
351 if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) 374 if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK)
352 x11_timeout_real = UINT_MAX; 375 x11_timeout_real = UINT_MAX;
353 else 376 else
354 x11_timeout_real = timeout + X11_TIMEOUT_SLACK; 377 x11_timeout_real = timeout + X11_TIMEOUT_SLACK;
355 if (mkdtemp(xauthdir) != NULL) { 378 if ((r = snprintf(cmd, sizeof(cmd),
356 do_unlink = 1; 379 "%s -f %s generate %s " SSH_X11_PROTO
357 snprintf(xauthfile, PATH_MAX, "%s/xauthfile", 380 " untrusted timeout %u 2>" _PATH_DEVNULL,
358 xauthdir); 381 xauth_path, xauthfile, display,
359 snprintf(cmd, sizeof(cmd), 382 x11_timeout_real)) < 0 ||
360 "%s -f %s generate %s " SSH_X11_PROTO 383 (size_t)r >= sizeof(cmd))
361 " untrusted timeout %u 2>" _PATH_DEVNULL, 384 fatal("%s: cmd too long", __func__);
362 xauth_path, xauthfile, display, 385 debug2("%s: %s", __func__, cmd);
363 x11_timeout_real); 386 if (x11_refuse_time == 0) {
364 debug2("x11_get_proto: %s", cmd); 387 now = monotime() + 1;
365 if (x11_refuse_time == 0) { 388 if (UINT_MAX - timeout < now)
366 now = monotime() + 1; 389 x11_refuse_time = UINT_MAX;
367 if (UINT_MAX - timeout < now) 390 else
368 x11_refuse_time = UINT_MAX; 391 x11_refuse_time = now + timeout;
369 else 392 channel_set_x11_refuse_time(x11_refuse_time);
370 x11_refuse_time = now + timeout;
371 channel_set_x11_refuse_time(
372 x11_refuse_time);
373 }
374 if (system(cmd) == 0)
375 generated = 1;
376 } 393 }
394 if (system(cmd) == 0)
395 generated = 1;
377 } 396 }
378 397
379 /* 398 /*
@@ -395,9 +414,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
395 got_data = 1; 414 got_data = 1;
396 if (f) 415 if (f)
397 pclose(f); 416 pclose(f);
398 } else 417 }
399 error("Warning: untrusted X11 forwarding setup failed: "
400 "xauth key data not generated");
401 } 418 }
402 419
403 if (do_unlink) { 420 if (do_unlink) {
@@ -405,6 +422,13 @@ client_x11_get_proto(const char *display, const char *xauth_path,
405 rmdir(xauthdir); 422 rmdir(xauthdir);
406 } 423 }
407 424
425 /* Don't fall back to fake X11 data for untrusted forwarding */
426 if (!trusted && !got_data) {
427 error("Warning: untrusted X11 forwarding setup failed: "
428 "xauth key data not generated");
429 return -1;
430 }
431
408 /* 432 /*
409 * If we didn't get authentication data, just make up some 433 * If we didn't get authentication data, just make up some
410 * data. The forwarding code will check the validity of the 434 * data. The forwarding code will check the validity of the
@@ -427,6 +451,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
427 rnd >>= 8; 451 rnd >>= 8;
428 } 452 }
429 } 453 }
454
455 return 0;
430} 456}
431 457
432/* 458/*
diff --git a/clientloop.h b/clientloop.h
index 338d45186..f4d4c69b7 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.31 2013/06/02 23:36:29 dtucker Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.32 2016/01/13 23:04:47 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -39,7 +39,7 @@
39 39
40/* Client side main loop for the interactive session. */ 40/* Client side main loop for the interactive session. */
41int client_loop(int, int, int); 41int client_loop(int, int, int);
42void client_x11_get_proto(const char *, const char *, u_int, u_int, 42int client_x11_get_proto(const char *, const char *, u_int, u_int,
43 char **, char **); 43 char **, char **);
44void client_global_request_reply_fwd(int, u_int32_t, void *); 44void client_global_request_reply_fwd(int, u_int32_t, void *);
45void client_session2_setup(int, int, int, const char *, struct termios *, 45void client_session2_setup(int, int, int, const char *, struct termios *,
diff --git a/mux.c b/mux.c
index f9c3af651..6bf53ebd9 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.57 2015/12/26 07:46:03 semarie Exp $ */ 1/* $OpenBSD: mux.c,v 1.58 2016/01/13 23:04:47 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg)
1354 char *proto, *data; 1354 char *proto, *data;
1355 1355
1356 /* Get reasonable local authentication information. */ 1356 /* Get reasonable local authentication information. */
1357 client_x11_get_proto(display, options.xauth_location, 1357 if (client_x11_get_proto(display, options.xauth_location,
1358 options.forward_x11_trusted, options.forward_x11_timeout, 1358 options.forward_x11_trusted, options.forward_x11_timeout,
1359 &proto, &data); 1359 &proto, &data) == 0) {
1360 /* Request forwarding with authentication spoofing. */ 1360 /* Request forwarding with authentication spoofing. */
1361 debug("Requesting X11 forwarding with authentication " 1361 debug("Requesting X11 forwarding with authentication "
1362 "spoofing."); 1362 "spoofing.");
1363 x11_request_forwarding_with_spoofing(id, display, proto, 1363 x11_request_forwarding_with_spoofing(id, display, proto,
1364 data, 1); 1364 data, 1);
1365 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); 1365 /* XXX exit_on_forward_failure */
1366 /* XXX exit_on_forward_failure */ 1366 client_expect_confirm(id, "X11 forwarding",
1367 CONFIRM_WARN);
1368 }
1367 } 1369 }
1368 1370
1369 if (cctx->want_agent_fwd && options.forward_agent) { 1371 if (cctx->want_agent_fwd && options.forward_agent) {
diff --git a/ssh.c b/ssh.c
index 81704ab31..096c5b5d7 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.432 2015/12/11 03:20:09 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.433 2016/01/13 23:04:47 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1626,6 +1626,7 @@ ssh_session(void)
1626 struct winsize ws; 1626 struct winsize ws;
1627 char *cp; 1627 char *cp;
1628 const char *display; 1628 const char *display;
1629 char *proto = NULL, *data = NULL;
1629 1630
1630 /* Enable compression if requested. */ 1631 /* Enable compression if requested. */
1631 if (options.compression) { 1632 if (options.compression) {
@@ -1696,13 +1697,9 @@ ssh_session(void)
1696 display = getenv("DISPLAY"); 1697 display = getenv("DISPLAY");
1697 if (display == NULL && options.forward_x11) 1698 if (display == NULL && options.forward_x11)
1698 debug("X11 forwarding requested but DISPLAY not set"); 1699 debug("X11 forwarding requested but DISPLAY not set");
1699 if (options.forward_x11 && display != NULL) { 1700 if (options.forward_x11 && client_x11_get_proto(display,
1700 char *proto, *data; 1701 options.xauth_location, options.forward_x11_trusted,
1701 /* Get reasonable local authentication information. */ 1702 options.forward_x11_timeout, &proto, &data) == 0) {
1702 client_x11_get_proto(display, options.xauth_location,
1703 options.forward_x11_trusted,
1704 options.forward_x11_timeout,
1705 &proto, &data);
1706 /* Request forwarding with authentication spoofing. */ 1703 /* Request forwarding with authentication spoofing. */
1707 debug("Requesting X11 forwarding with authentication " 1704 debug("Requesting X11 forwarding with authentication "
1708 "spoofing."); 1705 "spoofing.");
@@ -1792,6 +1789,7 @@ ssh_session2_setup(int id, int success, void *arg)
1792 extern char **environ; 1789 extern char **environ;
1793 const char *display; 1790 const char *display;
1794 int interactive = tty_flag; 1791 int interactive = tty_flag;
1792 char *proto = NULL, *data = NULL;
1795 1793
1796 if (!success) 1794 if (!success)
1797 return; /* No need for error message, channels code sens one */ 1795 return; /* No need for error message, channels code sens one */
@@ -1799,12 +1797,9 @@ ssh_session2_setup(int id, int success, void *arg)
1799 display = getenv("DISPLAY"); 1797 display = getenv("DISPLAY");
1800 if (display == NULL && options.forward_x11) 1798 if (display == NULL && options.forward_x11)
1801 debug("X11 forwarding requested but DISPLAY not set"); 1799 debug("X11 forwarding requested but DISPLAY not set");
1802 if (options.forward_x11 && display != NULL) { 1800 if (options.forward_x11 && client_x11_get_proto(display,
1803 char *proto, *data; 1801 options.xauth_location, options.forward_x11_trusted,
1804 /* Get reasonable local authentication information. */ 1802 options.forward_x11_timeout, &proto, &data) == 0) {
1805 client_x11_get_proto(display, options.xauth_location,
1806 options.forward_x11_trusted,
1807 options.forward_x11_timeout, &proto, &data);
1808 /* Request forwarding with authentication spoofing. */ 1803 /* Request forwarding with authentication spoofing. */
1809 debug("Requesting X11 forwarding with authentication " 1804 debug("Requesting X11 forwarding with authentication "
1810 "spoofing."); 1805 "spoofing.");