diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 126 |
1 files changed, 14 insertions, 112 deletions
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.242 2005/06/08 11:25:09 djm Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.243 2005/06/16 03:38:36 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -750,110 +750,6 @@ again: | |||
750 | return exit_status; | 750 | return exit_status; |
751 | } | 751 | } |
752 | 752 | ||
753 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
754 | |||
755 | static void | ||
756 | x11_get_proto(char **_proto, char **_data) | ||
757 | { | ||
758 | char cmd[1024]; | ||
759 | char line[512]; | ||
760 | char xdisplay[512]; | ||
761 | static char proto[512], data[512]; | ||
762 | FILE *f; | ||
763 | int got_data = 0, generated = 0, do_unlink = 0, i; | ||
764 | char *display, *xauthdir, *xauthfile; | ||
765 | struct stat st; | ||
766 | |||
767 | xauthdir = xauthfile = NULL; | ||
768 | *_proto = proto; | ||
769 | *_data = data; | ||
770 | proto[0] = data[0] = '\0'; | ||
771 | |||
772 | if (!options.xauth_location || | ||
773 | (stat(options.xauth_location, &st) == -1)) { | ||
774 | debug("No xauth program."); | ||
775 | } else { | ||
776 | if ((display = getenv("DISPLAY")) == NULL) { | ||
777 | debug("x11_get_proto: DISPLAY not set"); | ||
778 | return; | ||
779 | } | ||
780 | /* | ||
781 | * Handle FamilyLocal case where $DISPLAY does | ||
782 | * not match an authorization entry. For this we | ||
783 | * just try "xauth list unix:displaynum.screennum". | ||
784 | * XXX: "localhost" match to determine FamilyLocal | ||
785 | * is not perfect. | ||
786 | */ | ||
787 | if (strncmp(display, "localhost:", 10) == 0) { | ||
788 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", | ||
789 | display + 10); | ||
790 | display = xdisplay; | ||
791 | } | ||
792 | if (options.forward_x11_trusted == 0) { | ||
793 | xauthdir = xmalloc(MAXPATHLEN); | ||
794 | xauthfile = xmalloc(MAXPATHLEN); | ||
795 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); | ||
796 | if (mkdtemp(xauthdir) != NULL) { | ||
797 | do_unlink = 1; | ||
798 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
799 | xauthdir); | ||
800 | snprintf(cmd, sizeof(cmd), | ||
801 | "%s -f %s generate %s " SSH_X11_PROTO | ||
802 | " untrusted timeout 1200 2>" _PATH_DEVNULL, | ||
803 | options.xauth_location, xauthfile, display); | ||
804 | debug2("x11_get_proto: %s", cmd); | ||
805 | if (system(cmd) == 0) | ||
806 | generated = 1; | ||
807 | } | ||
808 | } | ||
809 | snprintf(cmd, sizeof(cmd), | ||
810 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
811 | options.xauth_location, | ||
812 | generated ? "-f " : "" , | ||
813 | generated ? xauthfile : "", | ||
814 | display); | ||
815 | debug2("x11_get_proto: %s", cmd); | ||
816 | f = popen(cmd, "r"); | ||
817 | if (f && fgets(line, sizeof(line), f) && | ||
818 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | ||
819 | got_data = 1; | ||
820 | if (f) | ||
821 | pclose(f); | ||
822 | } | ||
823 | |||
824 | if (do_unlink) { | ||
825 | unlink(xauthfile); | ||
826 | rmdir(xauthdir); | ||
827 | } | ||
828 | if (xauthdir) | ||
829 | xfree(xauthdir); | ||
830 | if (xauthfile) | ||
831 | xfree(xauthfile); | ||
832 | |||
833 | /* | ||
834 | * If we didn't get authentication data, just make up some | ||
835 | * data. The forwarding code will check the validity of the | ||
836 | * response anyway, and substitute this data. The X11 | ||
837 | * server, however, will ignore this fake data and use | ||
838 | * whatever authentication mechanisms it was using otherwise | ||
839 | * for the local connection. | ||
840 | */ | ||
841 | if (!got_data) { | ||
842 | u_int32_t rnd = 0; | ||
843 | |||
844 | logit("Warning: No xauth data; " | ||
845 | "using fake authentication data for X11 forwarding."); | ||
846 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
847 | for (i = 0; i < 16; i++) { | ||
848 | if (i % 4 == 0) | ||
849 | rnd = arc4random(); | ||
850 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", | ||
851 | rnd & 0xff); | ||
852 | rnd >>= 8; | ||
853 | } | ||
854 | } | ||
855 | } | ||
856 | |||
857 | static void | 753 | static void |
858 | ssh_init_forwarding(void) | 754 | ssh_init_forwarding(void) |
859 | { | 755 | { |
@@ -916,6 +812,7 @@ ssh_session(void) | |||
916 | int have_tty = 0; | 812 | int have_tty = 0; |
917 | struct winsize ws; | 813 | struct winsize ws; |
918 | char *cp; | 814 | char *cp; |
815 | const char *display; | ||
919 | 816 | ||
920 | /* Enable compression if requested. */ | 817 | /* Enable compression if requested. */ |
921 | if (options.compression) { | 818 | if (options.compression) { |
@@ -977,13 +874,15 @@ ssh_session(void) | |||
977 | packet_disconnect("Protocol error waiting for pty request response."); | 874 | packet_disconnect("Protocol error waiting for pty request response."); |
978 | } | 875 | } |
979 | /* Request X11 forwarding if enabled and DISPLAY is set. */ | 876 | /* Request X11 forwarding if enabled and DISPLAY is set. */ |
980 | if (options.forward_x11 && getenv("DISPLAY") != NULL) { | 877 | display = getenv("DISPLAY"); |
878 | if (options.forward_x11 && display != NULL) { | ||
981 | char *proto, *data; | 879 | char *proto, *data; |
982 | /* Get reasonable local authentication information. */ | 880 | /* Get reasonable local authentication information. */ |
983 | x11_get_proto(&proto, &data); | 881 | client_x11_get_proto(display, options.xauth_location, |
882 | options.forward_x11_trusted, &proto, &data); | ||
984 | /* Request forwarding with authentication spoofing. */ | 883 | /* Request forwarding with authentication spoofing. */ |
985 | debug("Requesting X11 forwarding with authentication spoofing."); | 884 | debug("Requesting X11 forwarding with authentication spoofing."); |
986 | x11_request_forwarding_with_spoofing(0, proto, data); | 885 | x11_request_forwarding_with_spoofing(0, display, proto, data); |
987 | 886 | ||
988 | /* Read response from the server. */ | 887 | /* Read response from the server. */ |
989 | type = packet_read(); | 888 | type = packet_read(); |
@@ -1125,15 +1024,18 @@ static void | |||
1125 | ssh_session2_setup(int id, void *arg) | 1024 | ssh_session2_setup(int id, void *arg) |
1126 | { | 1025 | { |
1127 | extern char **environ; | 1026 | extern char **environ; |
1128 | 1027 | const char *display; | |
1129 | int interactive = tty_flag; | 1028 | int interactive = tty_flag; |
1130 | if (options.forward_x11 && getenv("DISPLAY") != NULL) { | 1029 | |
1030 | display = getenv("DISPLAY"); | ||
1031 | if (options.forward_x11 && display != NULL) { | ||
1131 | char *proto, *data; | 1032 | char *proto, *data; |
1132 | /* Get reasonable local authentication information. */ | 1033 | /* Get reasonable local authentication information. */ |
1133 | x11_get_proto(&proto, &data); | 1034 | client_x11_get_proto(display, options.xauth_location, |
1035 | options.forward_x11_trusted, &proto, &data); | ||
1134 | /* Request forwarding with authentication spoofing. */ | 1036 | /* Request forwarding with authentication spoofing. */ |
1135 | debug("Requesting X11 forwarding with authentication spoofing."); | 1037 | debug("Requesting X11 forwarding with authentication spoofing."); |
1136 | x11_request_forwarding_with_spoofing(id, proto, data); | 1038 | x11_request_forwarding_with_spoofing(id, display, proto, data); |
1137 | interactive = 1; | 1039 | interactive = 1; |
1138 | /* XXX wait for reply */ | 1040 | /* XXX wait for reply */ |
1139 | } | 1041 | } |