diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 92 |
1 files changed, 68 insertions, 24 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.202 2003/10/11 08:24:08 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"); |
@@ -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; |
@@ -721,19 +726,25 @@ again: | |||
721 | return exit_status; | 726 | return exit_status; |
722 | } | 727 | } |
723 | 728 | ||
729 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
730 | |||
724 | static void | 731 | static void |
725 | x11_get_proto(char **_proto, char **_data) | 732 | x11_get_proto(char **_proto, char **_data) |
726 | { | 733 | { |
734 | char cmd[1024]; | ||
727 | char line[512]; | 735 | char line[512]; |
736 | char xdisplay[512]; | ||
728 | static char proto[512], data[512]; | 737 | static char proto[512], data[512]; |
729 | FILE *f; | 738 | FILE *f; |
730 | int got_data = 0, i; | 739 | int got_data = 0, generated = 0, do_unlink = 0, i; |
731 | char *display; | 740 | char *display, *xauthdir, *xauthfile; |
732 | struct stat st; | 741 | struct stat st; |
733 | 742 | ||
743 | xauthdir = xauthfile = NULL; | ||
734 | *_proto = proto; | 744 | *_proto = proto; |
735 | *_data = data; | 745 | *_data = data; |
736 | proto[0] = data[0] = '\0'; | 746 | proto[0] = data[0] = '\0'; |
747 | |||
737 | if (!options.xauth_location || | 748 | if (!options.xauth_location || |
738 | (stat(options.xauth_location, &st) == -1)) { | 749 | (stat(options.xauth_location, &st) == -1)) { |
739 | debug("No xauth program."); | 750 | debug("No xauth program."); |
@@ -742,28 +753,59 @@ x11_get_proto(char **_proto, char **_data) | |||
742 | debug("x11_get_proto: DISPLAY not set"); | 753 | debug("x11_get_proto: DISPLAY not set"); |
743 | return; | 754 | return; |
744 | } | 755 | } |
745 | /* Try to get Xauthority information for the display. */ | 756 | /* |
746 | if (strncmp(display, "localhost:", 10) == 0) | 757 | * Handle FamilyLocal case where $DISPLAY does |
747 | /* | 758 | * not match an authorization entry. For this we |
748 | * Handle FamilyLocal case where $DISPLAY does | 759 | * just try "xauth list unix:displaynum.screennum". |
749 | * not match an authorization entry. For this we | 760 | * XXX: "localhost" match to determine FamilyLocal |
750 | * just try "xauth list unix:displaynum.screennum". | 761 | * is not perfect. |
751 | * XXX: "localhost" match to determine FamilyLocal | 762 | */ |
752 | * is not perfect. | 763 | if (strncmp(display, "localhost:", 10) == 0) { |
753 | */ | 764 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", |
754 | snprintf(line, sizeof line, "%s list unix:%s 2>" | 765 | display + 10); |
755 | _PATH_DEVNULL, options.xauth_location, display+10); | 766 | display = xdisplay; |
756 | else | 767 | } |
757 | snprintf(line, sizeof line, "%s list %.200s 2>" | 768 | if (options.forward_x11_trusted == 0) { |
758 | _PATH_DEVNULL, options.xauth_location, display); | 769 | xauthdir = xmalloc(MAXPATHLEN); |
759 | debug2("x11_get_proto: %s", line); | 770 | xauthfile = xmalloc(MAXPATHLEN); |
760 | f = popen(line, "r"); | 771 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); |
772 | if (mkdtemp(xauthdir) != NULL) { | ||
773 | do_unlink = 1; | ||
774 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
775 | xauthdir); | ||
776 | snprintf(cmd, sizeof(cmd), | ||
777 | "%s -f %s generate %s " SSH_X11_PROTO | ||
778 | " untrusted timeout 120 2>" _PATH_DEVNULL, | ||
779 | options.xauth_location, xauthfile, display); | ||
780 | debug2("x11_get_proto: %s", cmd); | ||
781 | if (system(cmd) == 0) | ||
782 | generated = 1; | ||
783 | } | ||
784 | } | ||
785 | snprintf(cmd, sizeof(cmd), | ||
786 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
787 | options.xauth_location, | ||
788 | generated ? "-f " : "" , | ||
789 | generated ? xauthfile : "", | ||
790 | display); | ||
791 | debug2("x11_get_proto: %s", cmd); | ||
792 | f = popen(cmd, "r"); | ||
761 | if (f && fgets(line, sizeof(line), f) && | 793 | if (f && fgets(line, sizeof(line), f) && |
762 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | 794 | sscanf(line, "%*s %511s %511s", proto, data) == 2) |
763 | got_data = 1; | 795 | got_data = 1; |
764 | if (f) | 796 | if (f) |
765 | pclose(f); | 797 | pclose(f); |
766 | } | 798 | } |
799 | |||
800 | if (do_unlink) { | ||
801 | unlink(xauthfile); | ||
802 | rmdir(xauthdir); | ||
803 | } | ||
804 | if (xauthdir) | ||
805 | xfree(xauthdir); | ||
806 | if (xauthfile) | ||
807 | xfree(xauthfile); | ||
808 | |||
767 | /* | 809 | /* |
768 | * If we didn't get authentication data, just make up some | 810 | * If we didn't get authentication data, just make up some |
769 | * data. The forwarding code will check the validity of the | 811 | * data. The forwarding code will check the validity of the |
@@ -775,12 +817,14 @@ x11_get_proto(char **_proto, char **_data) | |||
775 | if (!got_data) { | 817 | if (!got_data) { |
776 | u_int32_t rand = 0; | 818 | u_int32_t rand = 0; |
777 | 819 | ||
778 | logit("Warning: No xauth data; using fake authentication data for X11 forwarding."); | 820 | logit("Warning: No xauth data; " |
779 | strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); | 821 | "using fake authentication data for X11 forwarding."); |
822 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
780 | for (i = 0; i < 16; i++) { | 823 | for (i = 0; i < 16; i++) { |
781 | if (i % 4 == 0) | 824 | if (i % 4 == 0) |
782 | rand = arc4random(); | 825 | rand = arc4random(); |
783 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff); | 826 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", |
827 | rand & 0xff); | ||
784 | rand >>= 8; | 828 | rand >>= 8; |
785 | } | 829 | } |
786 | } | 830 | } |