diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | channels.c | 67 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | includes.h | 1 | ||||
-rw-r--r-- | session.c | 93 |
5 files changed, 108 insertions, 75 deletions
@@ -1,3 +1,19 @@ | |||
1 | 20011219 | ||
2 | - (stevesk) OpenBSD CVS sync X11 localhost display | ||
3 | - stevesk@cvs.openbsd.org 2001/11/29 14:10:51 | ||
4 | [channels.h channels.c session.c] | ||
5 | sshd X11 fake server will now listen on localhost by default: | ||
6 | $ echo $DISPLAY | ||
7 | localhost:12.0 | ||
8 | $ netstat -an|grep 6012 | ||
9 | tcp 0 0 127.0.0.1.6012 *.* LISTEN | ||
10 | tcp6 0 0 ::1.6012 *.* LISTEN | ||
11 | sshd_config gatewayports=yes can be used to revert back to the old | ||
12 | behavior. will control this with another option later. ok markus@ | ||
13 | - stevesk@cvs.openbsd.org 2001/12/19 08:43:11 | ||
14 | [includes.h session.c] | ||
15 | handle utsname.nodename case for FamilyLocal X authorization; ok markus@ | ||
16 | |||
1 | 20011207 | 17 | 20011207 |
2 | - (bal) PCRE no longer required. Banished from the source along with | 18 | - (bal) PCRE no longer required. Banished from the source along with |
3 | fake-regex.h | 19 | fake-regex.h |
@@ -7009,4 +7025,4 @@ | |||
7009 | - Wrote replacements for strlcpy and mkdtemp | 7025 | - Wrote replacements for strlcpy and mkdtemp |
7010 | - Released 1.0pre1 | 7026 | - Released 1.0pre1 |
7011 | 7027 | ||
7012 | $Id: ChangeLog,v 1.1691 2001/12/07 17:28:34 mouring Exp $ | 7028 | $Id: ChangeLog,v 1.1692 2001/12/19 17:58:01 stevesk Exp $ |
diff --git a/channels.c b/channels.c index 694b7cc78..40a86dccb 100644 --- a/channels.c +++ b/channels.c | |||
@@ -2400,19 +2400,17 @@ channel_connect_to(const char *host, u_short port) | |||
2400 | 2400 | ||
2401 | /* | 2401 | /* |
2402 | * Creates an internet domain socket for listening for X11 connections. | 2402 | * Creates an internet domain socket for listening for X11 connections. |
2403 | * Returns a suitable value for the DISPLAY variable, or NULL if an error | 2403 | * Returns a suitable display number for the DISPLAY variable, or -1 if |
2404 | * occurs. | 2404 | * an error occurs. |
2405 | */ | 2405 | */ |
2406 | char * | 2406 | int |
2407 | x11_create_display_inet(int screen_number, int x11_display_offset) | 2407 | x11_create_display_inet(int x11_display_offset, int gateway_ports) |
2408 | { | 2408 | { |
2409 | int display_number, sock; | 2409 | int display_number, sock; |
2410 | u_short port; | 2410 | u_short port; |
2411 | struct addrinfo hints, *ai, *aitop; | 2411 | struct addrinfo hints, *ai, *aitop; |
2412 | char strport[NI_MAXSERV]; | 2412 | char strport[NI_MAXSERV]; |
2413 | int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; | 2413 | int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; |
2414 | char display[512]; | ||
2415 | char hostname[MAXHOSTNAMELEN]; | ||
2416 | 2414 | ||
2417 | for (display_number = x11_display_offset; | 2415 | for (display_number = x11_display_offset; |
2418 | display_number < MAX_DISPLAYS; | 2416 | display_number < MAX_DISPLAYS; |
@@ -2420,12 +2418,12 @@ x11_create_display_inet(int screen_number, int x11_display_offset) | |||
2420 | port = 6000 + display_number; | 2418 | port = 6000 + display_number; |
2421 | memset(&hints, 0, sizeof(hints)); | 2419 | memset(&hints, 0, sizeof(hints)); |
2422 | hints.ai_family = IPv4or6; | 2420 | hints.ai_family = IPv4or6; |
2423 | hints.ai_flags = AI_PASSIVE; /* XXX loopback only ? */ | 2421 | hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; |
2424 | hints.ai_socktype = SOCK_STREAM; | 2422 | hints.ai_socktype = SOCK_STREAM; |
2425 | snprintf(strport, sizeof strport, "%d", port); | 2423 | snprintf(strport, sizeof strport, "%d", port); |
2426 | if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { | 2424 | if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { |
2427 | error("getaddrinfo: %.100s", gai_strerror(gaierr)); | 2425 | error("getaddrinfo: %.100s", gai_strerror(gaierr)); |
2428 | return NULL; | 2426 | return -1; |
2429 | } | 2427 | } |
2430 | for (ai = aitop; ai; ai = ai->ai_next) { | 2428 | for (ai = aitop; ai; ai = ai->ai_next) { |
2431 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) | 2429 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
@@ -2434,7 +2432,7 @@ x11_create_display_inet(int screen_number, int x11_display_offset) | |||
2434 | if (sock < 0) { | 2432 | if (sock < 0) { |
2435 | if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { | 2433 | if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { |
2436 | error("socket: %.100s", strerror(errno)); | 2434 | error("socket: %.100s", strerror(errno)); |
2437 | return NULL; | 2435 | return -1; |
2438 | } else { | 2436 | } else { |
2439 | debug("x11_create_display_inet: Socket family %d not supported", | 2437 | debug("x11_create_display_inet: Socket family %d not supported", |
2440 | ai->ai_family); | 2438 | ai->ai_family); |
@@ -2468,7 +2466,7 @@ x11_create_display_inet(int screen_number, int x11_display_offset) | |||
2468 | } | 2466 | } |
2469 | if (display_number >= MAX_DISPLAYS) { | 2467 | if (display_number >= MAX_DISPLAYS) { |
2470 | error("Failed to allocate internet-domain X11 display socket."); | 2468 | error("Failed to allocate internet-domain X11 display socket."); |
2471 | return NULL; | 2469 | return -1; |
2472 | } | 2470 | } |
2473 | /* Start listening for connections on the socket. */ | 2471 | /* Start listening for connections on the socket. */ |
2474 | for (n = 0; n < num_socks; n++) { | 2472 | for (n = 0; n < num_socks; n++) { |
@@ -2476,52 +2474,9 @@ x11_create_display_inet(int screen_number, int x11_display_offset) | |||
2476 | if (listen(sock, 5) < 0) { | 2474 | if (listen(sock, 5) < 0) { |
2477 | error("listen: %.100s", strerror(errno)); | 2475 | error("listen: %.100s", strerror(errno)); |
2478 | close(sock); | 2476 | close(sock); |
2479 | return NULL; | 2477 | return -1; |
2480 | } | ||
2481 | } | ||
2482 | |||
2483 | /* Set up a suitable value for the DISPLAY variable. */ | ||
2484 | if (gethostname(hostname, sizeof(hostname)) < 0) | ||
2485 | fatal("gethostname: %.100s", strerror(errno)); | ||
2486 | |||
2487 | #ifdef IPADDR_IN_DISPLAY | ||
2488 | /* | ||
2489 | * HPUX detects the local hostname in the DISPLAY variable and tries | ||
2490 | * to set up a shared memory connection to the server, which it | ||
2491 | * incorrectly supposes to be local. | ||
2492 | * | ||
2493 | * The workaround - as used in later $$H and other programs - is | ||
2494 | * is to set display to the host's IP address. | ||
2495 | */ | ||
2496 | { | ||
2497 | struct hostent *he; | ||
2498 | struct in_addr my_addr; | ||
2499 | |||
2500 | he = gethostbyname(hostname); | ||
2501 | if (he == NULL) { | ||
2502 | error("[X11-broken-fwd-hostname-workaround] Could not get " | ||
2503 | "IP address for hostname %s.", hostname); | ||
2504 | |||
2505 | packet_send_debug("[X11-broken-fwd-hostname-workaround]" | ||
2506 | "Could not get IP address for hostname %s.", hostname); | ||
2507 | |||
2508 | shutdown(sock, SHUT_RDWR); | ||
2509 | close(sock); | ||
2510 | |||
2511 | return NULL; | ||
2512 | } | 2478 | } |
2513 | |||
2514 | memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); | ||
2515 | |||
2516 | /* Set DISPLAY to <ip address>:screen.display */ | ||
2517 | snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr), | ||
2518 | display_number, screen_number); | ||
2519 | } | 2479 | } |
2520 | #else /* IPADDR_IN_DISPLAY */ | ||
2521 | /* Just set DISPLAY to hostname:screen.display */ | ||
2522 | snprintf(display, sizeof display, "%.400s:%d.%d", hostname, | ||
2523 | display_number, screen_number); | ||
2524 | #endif /* IPADDR_IN_DISPLAY */ | ||
2525 | 2480 | ||
2526 | /* Allocate a channel for each socket. */ | 2481 | /* Allocate a channel for each socket. */ |
2527 | for (n = 0; n < num_socks; n++) { | 2482 | for (n = 0; n < num_socks; n++) { |
@@ -2532,8 +2487,8 @@ x11_create_display_inet(int screen_number, int x11_display_offset) | |||
2532 | 0, xstrdup("X11 inet listener"), 1); | 2487 | 0, xstrdup("X11 inet listener"), 1); |
2533 | } | 2488 | } |
2534 | 2489 | ||
2535 | /* Return a suitable value for the DISPLAY environment variable. */ | 2490 | /* Return the display number for the DISPLAY environment variable. */ |
2536 | return xstrdup(display); | 2491 | return display_number; |
2537 | } | 2492 | } |
2538 | 2493 | ||
2539 | #ifndef X_UNIX_PATH | 2494 | #ifndef X_UNIX_PATH |
diff --git a/channels.h b/channels.h index f58c7283c..840268fcf 100644 --- a/channels.h +++ b/channels.h | |||
@@ -32,7 +32,7 @@ | |||
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | 34 | */ |
35 | /* RCSID("$OpenBSD: channels.h,v 1.52 2001/11/29 19:06:39 stevesk Exp $"); */ | 35 | /* RCSID("$OpenBSD: channels.h,v 1.53 2001/11/29 21:10:51 stevesk Exp $"); */ |
36 | 36 | ||
37 | #ifndef CHANNEL_H | 37 | #ifndef CHANNEL_H |
38 | #define CHANNEL_H | 38 | #define CHANNEL_H |
@@ -197,7 +197,7 @@ channel_request_forwarding(const char *, u_short, const char *, u_short, int, | |||
197 | /* x11 forwarding */ | 197 | /* x11 forwarding */ |
198 | 198 | ||
199 | int x11_connect_display(void); | 199 | int x11_connect_display(void); |
200 | char *x11_create_display_inet(int, int); | 200 | int x11_create_display_inet(int, int); |
201 | void x11_input_open(int, int, void *); | 201 | void x11_input_open(int, int, void *); |
202 | void x11_request_forwarding(void); | 202 | void x11_request_forwarding(void); |
203 | void x11_request_forwarding_with_spoofing(int, const char *, const char *); | 203 | void x11_request_forwarding_with_spoofing(int, const char *, const char *); |
diff --git a/includes.h b/includes.h index f9cf9c73e..96366cb59 100644 --- a/includes.h +++ b/includes.h | |||
@@ -28,6 +28,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } | |||
28 | #include <sys/ioctl.h> | 28 | #include <sys/ioctl.h> |
29 | #include <sys/wait.h> | 29 | #include <sys/wait.h> |
30 | #include <sys/resource.h> | 30 | #include <sys/resource.h> |
31 | #include <sys/utsname.h> | ||
31 | 32 | ||
32 | #include <netinet/tcp.h> | 33 | #include <netinet/tcp.h> |
33 | #include <arpa/inet.h> | 34 | #include <arpa/inet.h> |
@@ -108,8 +108,10 @@ struct Session { | |||
108 | int row, col, xpixel, ypixel; | 108 | int row, col, xpixel, ypixel; |
109 | char tty[TTYSZ]; | 109 | char tty[TTYSZ]; |
110 | /* X11 */ | 110 | /* X11 */ |
111 | int display_number; | ||
111 | char *display; | 112 | char *display; |
112 | int screen; | 113 | int screen; |
114 | char *auth_display[2]; | ||
113 | char *auth_proto; | 115 | char *auth_proto; |
114 | char *auth_data; | 116 | char *auth_data; |
115 | int single_connection; | 117 | int single_connection; |
@@ -1418,32 +1420,28 @@ do_child(Session *s, const char *command) | |||
1418 | _PATH_SSH_SYSTEM_RC); | 1420 | _PATH_SSH_SYSTEM_RC); |
1419 | } else if (do_xauth && options.xauth_location != NULL) { | 1421 | } else if (do_xauth && options.xauth_location != NULL) { |
1420 | /* Add authority data to .Xauthority if appropriate. */ | 1422 | /* Add authority data to .Xauthority if appropriate. */ |
1421 | char *screen = strchr(s->display, ':'); | ||
1422 | |||
1423 | if (debug_flag) { | 1423 | if (debug_flag) { |
1424 | fprintf(stderr, | 1424 | fprintf(stderr, |
1425 | "Running %.100s add " | 1425 | "Running %.100s add " |
1426 | "%.100s %.100s %.100s\n", | 1426 | "%.100s %.100s %.100s\n", |
1427 | options.xauth_location, s->display, | 1427 | options.xauth_location, s->auth_display[0], |
1428 | s->auth_proto, s->auth_data); | 1428 | s->auth_proto, s->auth_data); |
1429 | if (screen != NULL) | 1429 | if (s->auth_display[1]) |
1430 | fprintf(stderr, | 1430 | fprintf(stderr, |
1431 | "Adding %.*s/unix%s %s %s\n", | 1431 | "add %.100s %.100s %.100s\n", |
1432 | (int)(screen - s->display), | 1432 | s->auth_display[1], |
1433 | s->display, screen, | ||
1434 | s->auth_proto, s->auth_data); | 1433 | s->auth_proto, s->auth_data); |
1435 | } | 1434 | } |
1436 | snprintf(cmd, sizeof cmd, "%s -q -", | 1435 | snprintf(cmd, sizeof cmd, "%s -q -", |
1437 | options.xauth_location); | 1436 | options.xauth_location); |
1438 | f = popen(cmd, "w"); | 1437 | f = popen(cmd, "w"); |
1439 | if (f) { | 1438 | if (f) { |
1440 | fprintf(f, "add %s %s %s\n", s->display, | 1439 | fprintf(f, "add %s %s %s\n", |
1441 | s->auth_proto, s->auth_data); | 1440 | s->auth_display[0], s->auth_proto, |
1442 | if (screen != NULL) | 1441 | s->auth_data); |
1443 | fprintf(f, "add %.*s/unix%s %s %s\n", | 1442 | if (s->auth_display[1]) |
1444 | (int)(screen - s->display), | 1443 | fprintf(f, "add %s %s %s\n", |
1445 | s->display, screen, | 1444 | s->auth_display[1], s->auth_proto, |
1446 | s->auth_proto, | ||
1447 | s->auth_data); | 1445 | s->auth_data); |
1448 | pclose(f); | 1446 | pclose(f); |
1449 | } else { | 1447 | } else { |
@@ -1943,6 +1941,10 @@ session_close(Session *s) | |||
1943 | xfree(s->term); | 1941 | xfree(s->term); |
1944 | if (s->display) | 1942 | if (s->display) |
1945 | xfree(s->display); | 1943 | xfree(s->display); |
1944 | if (s->auth_display[0]) | ||
1945 | xfree(s->auth_display[0]); | ||
1946 | if (s->auth_display[1]) | ||
1947 | xfree(s->auth_display[1]); | ||
1946 | if (s->auth_data) | 1948 | if (s->auth_data) |
1947 | xfree(s->auth_data); | 1949 | xfree(s->auth_data); |
1948 | if (s->auth_proto) | 1950 | if (s->auth_proto) |
@@ -2038,6 +2040,8 @@ int | |||
2038 | session_setup_x11fwd(Session *s) | 2040 | session_setup_x11fwd(Session *s) |
2039 | { | 2041 | { |
2040 | struct stat st; | 2042 | struct stat st; |
2043 | char display[512], auth_display[512]; | ||
2044 | char hostname[MAXHOSTNAMELEN]; | ||
2041 | 2045 | ||
2042 | if (no_x11_forwarding_flag) { | 2046 | if (no_x11_forwarding_flag) { |
2043 | packet_send_debug("X11 forwarding disabled in user configuration file."); | 2047 | packet_send_debug("X11 forwarding disabled in user configuration file."); |
@@ -2061,11 +2065,68 @@ session_setup_x11fwd(Session *s) | |||
2061 | debug("X11 display already set."); | 2065 | debug("X11 display already set."); |
2062 | return 0; | 2066 | return 0; |
2063 | } | 2067 | } |
2064 | s->display = x11_create_display_inet(s->screen, options.x11_display_offset); | 2068 | s->display_number = x11_create_display_inet(options.x11_display_offset, |
2065 | if (s->display == NULL) { | 2069 | options.gateway_ports); |
2070 | if (s->display_number == -1) { | ||
2066 | debug("x11_create_display_inet failed."); | 2071 | debug("x11_create_display_inet failed."); |
2067 | return 0; | 2072 | return 0; |
2068 | } | 2073 | } |
2074 | |||
2075 | /* Set up a suitable value for the DISPLAY variable. */ | ||
2076 | if (gethostname(hostname, sizeof(hostname)) < 0) | ||
2077 | fatal("gethostname: %.100s", strerror(errno)); | ||
2078 | /* | ||
2079 | * auth_display must be used as the displayname when the | ||
2080 | * authorization entry is added with xauth(1). This will be | ||
2081 | * different than the DISPLAY string for localhost displays. | ||
2082 | */ | ||
2083 | s->auth_display[1] = NULL; | ||
2084 | if (!options.gateway_ports) { | ||
2085 | struct utsname uts; | ||
2086 | |||
2087 | snprintf(display, sizeof display, "localhost:%d.%d", | ||
2088 | s->display_number, s->screen); | ||
2089 | snprintf(auth_display, sizeof auth_display, "%.400s/unix:%d.%d", | ||
2090 | hostname, s->display_number, s->screen); | ||
2091 | s->display = xstrdup(display); | ||
2092 | s->auth_display[0] = xstrdup(auth_display); | ||
2093 | /* | ||
2094 | * Xlib may use gethostbyname() or uname() hostname to | ||
2095 | * look up authorization data for FamilyLocal; see: | ||
2096 | * xc/lib/xtrans/Xtrans.c:TRANS(GetHostname) | ||
2097 | * We just add authorization entries with both | ||
2098 | * hostname and nodename if they are different. | ||
2099 | */ | ||
2100 | if (uname(&uts) == -1) | ||
2101 | fatal("uname: %.100s", strerror(errno)); | ||
2102 | if (strcmp(hostname, uts.nodename) != 0) { | ||
2103 | snprintf(auth_display, sizeof auth_display, | ||
2104 | "%.400s/unix:%d.%d", uts.nodename, | ||
2105 | s->display_number, s->screen); | ||
2106 | s->auth_display[1] = xstrdup(auth_display); | ||
2107 | } | ||
2108 | } else { | ||
2109 | #ifdef IPADDR_IN_DISPLAY | ||
2110 | struct hostent *he; | ||
2111 | struct in_addr my_addr; | ||
2112 | |||
2113 | he = gethostbyname(hostname); | ||
2114 | if (he == NULL) { | ||
2115 | error("Can't get IP address for X11 DISPLAY."); | ||
2116 | packet_send_debug("Can't get IP address for X11 DISPLAY."); | ||
2117 | return 0; | ||
2118 | } | ||
2119 | memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); | ||
2120 | snprintf(display, sizeof display, "%.50s:%d.%d", inet_ntoa(my_addr), | ||
2121 | s->display_number, s->screen); | ||
2122 | #else | ||
2123 | snprintf(display, sizeof display, "%.400s:%d.%d", hostname, | ||
2124 | s->display_number, s->screen); | ||
2125 | #endif | ||
2126 | s->display = xstrdup(display); | ||
2127 | s->auth_display[0] = xstrdup(display); | ||
2128 | } | ||
2129 | |||
2069 | return 1; | 2130 | return 1; |
2070 | } | 2131 | } |
2071 | 2132 | ||