summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c111
1 files changed, 77 insertions, 34 deletions
diff --git a/ssh.c b/ssh.c
index ca279fbb8..05960af98 100644
--- a/ssh.c
+++ b/ssh.c
@@ -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"
43RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $"); 43RCSID("$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
265again: 266again:
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
729static void 738static void
730x11_get_proto(char **_proto, char **_data) 739x11_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
990void 1036void
991client_global_request_reply(int type, u_int32_t seq, void *ctxt) 1037client_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,