diff options
author | Colin Watson <cjwatson@debian.org> | 2004-03-01 02:25:32 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2004-03-01 02:25:32 +0000 |
commit | ea8116a11e3de70036dbc665ccb0d486cf89cac9 (patch) | |
tree | d73ccdff78d8608e156465af42e6a1b3527fb2d6 /ssh.c | |
parent | e39b311381a5609cc05acf298c42fba196dc524b (diff) | |
parent | f5bda272678ec6dccaa5f29379cf60cb855018e8 (diff) |
Merge 3.8p1 to the trunk. This builds and runs, but I haven't tested it
extensively yet.
ProtocolKeepAlives is now just a compatibility alias for
ServerAliveInterval.
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 111 |
1 files changed, 77 insertions, 34 deletions
@@ -13,7 +13,7 @@ | |||
13 | * called by a name other than "ssh" or "Secure Shell". | 13 | * called by a name other than "ssh" or "Secure Shell". |
14 | * | 14 | * |
15 | * Copyright (c) 1999 Niels Provos. All rights reserved. | 15 | * Copyright (c) 1999 Niels Provos. All rights reserved. |
16 | * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. | 16 | * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved. |
17 | * | 17 | * |
18 | * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> | 18 | * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> |
19 | * in Canada (German citizen). | 19 | * in Canada (German citizen). |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.206 2003/12/16 15:49:51 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -155,6 +155,7 @@ usage(void) | |||
155 | fprintf(stderr, " -A Enable authentication agent forwarding.\n"); | 155 | fprintf(stderr, " -A Enable authentication agent forwarding.\n"); |
156 | fprintf(stderr, " -a Disable authentication agent forwarding (default).\n"); | 156 | fprintf(stderr, " -a Disable authentication agent forwarding (default).\n"); |
157 | fprintf(stderr, " -X Enable X11 connection forwarding.\n"); | 157 | fprintf(stderr, " -X Enable X11 connection forwarding.\n"); |
158 | fprintf(stderr, " -Y Enable trusted X11 connection forwarding.\n"); | ||
158 | fprintf(stderr, " -x Disable X11 connection forwarding (default).\n"); | 159 | fprintf(stderr, " -x Disable X11 connection forwarding (default).\n"); |
159 | fprintf(stderr, " -i file Identity for public key authentication " | 160 | fprintf(stderr, " -i file Identity for public key authentication " |
160 | "(default: ~/.ssh/identity)\n"); | 161 | "(default: ~/.ssh/identity)\n"); |
@@ -204,7 +205,7 @@ main(int ac, char **av) | |||
204 | int i, opt, exit_status; | 205 | int i, opt, exit_status; |
205 | u_short fwd_port, fwd_host_port; | 206 | u_short fwd_port, fwd_host_port; |
206 | char sfwd_port[6], sfwd_host_port[6]; | 207 | char sfwd_port[6], sfwd_host_port[6]; |
207 | char *p, *cp, buf[256]; | 208 | char *p, *cp, *line, buf[256]; |
208 | struct stat st; | 209 | struct stat st; |
209 | struct passwd *pw; | 210 | struct passwd *pw; |
210 | int dummy; | 211 | int dummy; |
@@ -220,7 +221,7 @@ main(int ac, char **av) | |||
220 | */ | 221 | */ |
221 | original_real_uid = getuid(); | 222 | original_real_uid = getuid(); |
222 | original_effective_uid = geteuid(); | 223 | original_effective_uid = geteuid(); |
223 | 224 | ||
224 | /* | 225 | /* |
225 | * Use uid-swapping to give up root privileges for the duration of | 226 | * Use uid-swapping to give up root privileges for the duration of |
226 | * option processing. We will re-instantiate the rights when we are | 227 | * option processing. We will re-instantiate the rights when we are |
@@ -264,7 +265,7 @@ main(int ac, char **av) | |||
264 | 265 | ||
265 | again: | 266 | again: |
266 | while ((opt = getopt(ac, av, | 267 | while ((opt = getopt(ac, av, |
267 | "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) { | 268 | "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVXY")) != -1) { |
268 | switch (opt) { | 269 | switch (opt) { |
269 | case '1': | 270 | case '1': |
270 | options.protocol = SSH_PROTO_1; | 271 | options.protocol = SSH_PROTO_1; |
@@ -291,6 +292,10 @@ again: | |||
291 | case 'X': | 292 | case 'X': |
292 | options.forward_x11 = 1; | 293 | options.forward_x11 = 1; |
293 | break; | 294 | break; |
295 | case 'Y': | ||
296 | options.forward_x11 = 1; | ||
297 | options.forward_x11_trusted = 1; | ||
298 | break; | ||
294 | case 'g': | 299 | case 'g': |
295 | options.gateway_ports = 1; | 300 | options.gateway_ports = 1; |
296 | break; | 301 | break; |
@@ -304,7 +309,7 @@ again: | |||
304 | options.forward_agent = 1; | 309 | options.forward_agent = 1; |
305 | break; | 310 | break; |
306 | case 'k': | 311 | case 'k': |
307 | /* ignored for backward compatibility */ | 312 | options.gss_deleg_creds = 0; |
308 | break; | 313 | break; |
309 | case 'i': | 314 | case 'i': |
310 | if (stat(optarg, &st) < 0) { | 315 | if (stat(optarg, &st) < 0) { |
@@ -464,9 +469,11 @@ again: | |||
464 | break; | 469 | break; |
465 | case 'o': | 470 | case 'o': |
466 | dummy = 1; | 471 | dummy = 1; |
472 | line = xstrdup(optarg); | ||
467 | if (process_config_line(&options, host ? host : "", | 473 | if (process_config_line(&options, host ? host : "", |
468 | optarg, "command-line", 0, &dummy) != 0) | 474 | line, "command-line", 0, &dummy) != 0) |
469 | exit(1); | 475 | exit(1); |
476 | xfree(line); | ||
470 | break; | 477 | break; |
471 | case 's': | 478 | case 's': |
472 | subsystem_flag = 1; | 479 | subsystem_flag = 1; |
@@ -717,7 +724,7 @@ again: | |||
717 | packet_close(); | 724 | packet_close(); |
718 | 725 | ||
719 | /* | 726 | /* |
720 | * Send SIGHUP to proxy command if used. We don't wait() in | 727 | * Send SIGHUP to proxy command if used. We don't wait() in |
721 | * case it hangs and instead rely on init to reap the child | 728 | * case it hangs and instead rely on init to reap the child |
722 | */ | 729 | */ |
723 | if (proxy_command_pid > 1) | 730 | if (proxy_command_pid > 1) |
@@ -726,19 +733,25 @@ again: | |||
726 | return exit_status; | 733 | return exit_status; |
727 | } | 734 | } |
728 | 735 | ||
736 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
737 | |||
729 | static void | 738 | static void |
730 | x11_get_proto(char **_proto, char **_data) | 739 | x11_get_proto(char **_proto, char **_data) |
731 | { | 740 | { |
741 | char cmd[1024]; | ||
732 | char line[512]; | 742 | char line[512]; |
743 | char xdisplay[512]; | ||
733 | static char proto[512], data[512]; | 744 | static char proto[512], data[512]; |
734 | FILE *f; | 745 | FILE *f; |
735 | int got_data = 0, i; | 746 | int got_data = 0, generated = 0, do_unlink = 0, i; |
736 | char *display; | 747 | char *display, *xauthdir, *xauthfile; |
737 | struct stat st; | 748 | struct stat st; |
738 | 749 | ||
750 | xauthdir = xauthfile = NULL; | ||
739 | *_proto = proto; | 751 | *_proto = proto; |
740 | *_data = data; | 752 | *_data = data; |
741 | proto[0] = data[0] = '\0'; | 753 | proto[0] = data[0] = '\0'; |
754 | |||
742 | if (!options.xauth_location || | 755 | if (!options.xauth_location || |
743 | (stat(options.xauth_location, &st) == -1)) { | 756 | (stat(options.xauth_location, &st) == -1)) { |
744 | debug("No xauth program."); | 757 | debug("No xauth program."); |
@@ -747,28 +760,59 @@ x11_get_proto(char **_proto, char **_data) | |||
747 | debug("x11_get_proto: DISPLAY not set"); | 760 | debug("x11_get_proto: DISPLAY not set"); |
748 | return; | 761 | return; |
749 | } | 762 | } |
750 | /* Try to get Xauthority information for the display. */ | 763 | /* |
751 | if (strncmp(display, "localhost:", 10) == 0) | 764 | * Handle FamilyLocal case where $DISPLAY does |
752 | /* | 765 | * not match an authorization entry. For this we |
753 | * Handle FamilyLocal case where $DISPLAY does | 766 | * just try "xauth list unix:displaynum.screennum". |
754 | * not match an authorization entry. For this we | 767 | * XXX: "localhost" match to determine FamilyLocal |
755 | * just try "xauth list unix:displaynum.screennum". | 768 | * is not perfect. |
756 | * XXX: "localhost" match to determine FamilyLocal | 769 | */ |
757 | * is not perfect. | 770 | if (strncmp(display, "localhost:", 10) == 0) { |
758 | */ | 771 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", |
759 | snprintf(line, sizeof line, "%s list unix:%s 2>" | 772 | display + 10); |
760 | _PATH_DEVNULL, options.xauth_location, display+10); | 773 | display = xdisplay; |
761 | else | 774 | } |
762 | snprintf(line, sizeof line, "%s list %.200s 2>" | 775 | if (options.forward_x11_trusted == 0) { |
763 | _PATH_DEVNULL, options.xauth_location, display); | 776 | xauthdir = xmalloc(MAXPATHLEN); |
764 | debug2("x11_get_proto: %s", line); | 777 | xauthfile = xmalloc(MAXPATHLEN); |
765 | f = popen(line, "r"); | 778 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); |
779 | if (mkdtemp(xauthdir) != NULL) { | ||
780 | do_unlink = 1; | ||
781 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
782 | xauthdir); | ||
783 | snprintf(cmd, sizeof(cmd), | ||
784 | "%s -f %s generate %s " SSH_X11_PROTO | ||
785 | " untrusted timeout 120 2>" _PATH_DEVNULL, | ||
786 | options.xauth_location, xauthfile, display); | ||
787 | debug2("x11_get_proto: %s", cmd); | ||
788 | if (system(cmd) == 0) | ||
789 | generated = 1; | ||
790 | } | ||
791 | } | ||
792 | snprintf(cmd, sizeof(cmd), | ||
793 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
794 | options.xauth_location, | ||
795 | generated ? "-f " : "" , | ||
796 | generated ? xauthfile : "", | ||
797 | display); | ||
798 | debug2("x11_get_proto: %s", cmd); | ||
799 | f = popen(cmd, "r"); | ||
766 | if (f && fgets(line, sizeof(line), f) && | 800 | if (f && fgets(line, sizeof(line), f) && |
767 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | 801 | sscanf(line, "%*s %511s %511s", proto, data) == 2) |
768 | got_data = 1; | 802 | got_data = 1; |
769 | if (f) | 803 | if (f) |
770 | pclose(f); | 804 | pclose(f); |
771 | } | 805 | } |
806 | |||
807 | if (do_unlink) { | ||
808 | unlink(xauthfile); | ||
809 | rmdir(xauthdir); | ||
810 | } | ||
811 | if (xauthdir) | ||
812 | xfree(xauthdir); | ||
813 | if (xauthfile) | ||
814 | xfree(xauthfile); | ||
815 | |||
772 | /* | 816 | /* |
773 | * If we didn't get authentication data, just make up some | 817 | * If we didn't get authentication data, just make up some |
774 | * data. The forwarding code will check the validity of the | 818 | * data. The forwarding code will check the validity of the |
@@ -780,12 +824,14 @@ x11_get_proto(char **_proto, char **_data) | |||
780 | if (!got_data) { | 824 | if (!got_data) { |
781 | u_int32_t rand = 0; | 825 | u_int32_t rand = 0; |
782 | 826 | ||
783 | logit("Warning: No xauth data; using fake authentication data for X11 forwarding."); | 827 | logit("Warning: No xauth data; " |
784 | strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); | 828 | "using fake authentication data for X11 forwarding."); |
829 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
785 | for (i = 0; i < 16; i++) { | 830 | for (i = 0; i < 16; i++) { |
786 | if (i % 4 == 0) | 831 | if (i % 4 == 0) |
787 | rand = arc4random(); | 832 | rand = arc4random(); |
788 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff); | 833 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", |
834 | rand & 0xff); | ||
789 | rand >>= 8; | 835 | rand >>= 8; |
790 | } | 836 | } |
791 | } | 837 | } |
@@ -988,16 +1034,13 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt) | |||
988 | } | 1034 | } |
989 | 1035 | ||
990 | void | 1036 | void |
991 | client_global_request_reply(int type, u_int32_t seq, void *ctxt) | 1037 | client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) |
992 | { | 1038 | { |
993 | int i; | 1039 | int i; |
994 | 1040 | ||
995 | i = client_global_request_id++; | 1041 | i = client_global_request_id++; |
996 | if (i >= options.num_remote_forwards) { | 1042 | if (i >= options.num_remote_forwards) |
997 | debug("client_global_request_reply: too many replies %d > %d", | ||
998 | i, options.num_remote_forwards); | ||
999 | return; | 1043 | return; |
1000 | } | ||
1001 | debug("remote forward %s for: listen %d, connect %s:%d", | 1044 | debug("remote forward %s for: listen %d, connect %s:%d", |
1002 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | 1045 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", |
1003 | options.remote_forwards[i].port, | 1046 | options.remote_forwards[i].port, |