summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2009-12-29 21:32:03 +0000
committerColin Watson <cjwatson@debian.org>2009-12-29 21:32:03 +0000
commit04942aa41fa94ec6f2c3ce1d348f600f31bb7c78 (patch)
treeaf8e928bd79d3f2d0219bb5b2c78b573ec31d94c /ssh.c
parent9ad7b718d42e43f3a285fcbc8f91193931fce324 (diff)
parent16704d57999d987fb8d9ba53379841a79f016d67 (diff)
import openssh-4.2p1-gsskex-20050926-2.patch
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c238
1 files changed, 96 insertions, 142 deletions
diff --git a/ssh.c b/ssh.c
index 9acec3082..c9e5aac7a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: ssh.c,v 1.233 2005/03/01 17:22:06 jmc Exp $"); 43RCSID("$OpenBSD: ssh.c,v 1.249 2005/07/30 01:26:16 djm Exp $");
44 44
45#include <openssl/evp.h> 45#include <openssl/evp.h>
46#include <openssl/err.h> 46#include <openssl/err.h>
@@ -145,7 +145,7 @@ pid_t proxy_command_pid = 0;
145int control_fd = -1; 145int control_fd = -1;
146 146
147/* Multiplexing control command */ 147/* Multiplexing control command */
148static u_int mux_command = SSHMUX_COMMAND_OPEN; 148static u_int mux_command = 0;
149 149
150/* Only used in control client mode */ 150/* Only used in control client mode */
151volatile sig_atomic_t control_client_terminate = 0; 151volatile sig_atomic_t control_client_terminate = 0;
@@ -185,6 +185,7 @@ main(int ac, char **av)
185 int dummy; 185 int dummy;
186 extern int optind, optreset; 186 extern int optind, optreset;
187 extern char *optarg; 187 extern char *optarg;
188 struct servent *sp;
188 Forward fwd; 189 Forward fwd;
189 190
190 __progname = ssh_get_progname(av[0]); 191 __progname = ssh_get_progname(av[0]);
@@ -386,8 +387,10 @@ again:
386 } 387 }
387 break; 388 break;
388 case 'M': 389 case 'M':
389 options.control_master = 390 if (options.control_master == SSHCTL_MASTER_YES)
390 (options.control_master >= 1) ? 2 : 1; 391 options.control_master = SSHCTL_MASTER_ASK;
392 else
393 options.control_master = SSHCTL_MASTER_YES;
391 break; 394 break;
392 case 'p': 395 case 'p':
393 options.port = a2port(optarg); 396 options.port = a2port(optarg);
@@ -436,7 +439,7 @@ again:
436 fwd.listen_host = cleanhostname(fwd.listen_host); 439 fwd.listen_host = cleanhostname(fwd.listen_host);
437 } else { 440 } else {
438 fwd.listen_port = a2port(fwd.listen_host); 441 fwd.listen_port = a2port(fwd.listen_host);
439 fwd.listen_host = ""; 442 fwd.listen_host = NULL;
440 } 443 }
441 444
442 if (fwd.listen_port == 0) { 445 if (fwd.listen_port == 0) {
@@ -550,7 +553,7 @@ again:
550 if (no_tty_flag) 553 if (no_tty_flag)
551 tty_flag = 0; 554 tty_flag = 0;
552 /* Do not allocate a tty if stdin is not a tty. */ 555 /* Do not allocate a tty if stdin is not a tty. */
553 if (!isatty(fileno(stdin)) && !force_tty_flag) { 556 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
554 if (tty_flag) 557 if (tty_flag)
555 logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); 558 logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
556 tty_flag = 0; 559 tty_flag = 0;
@@ -604,16 +607,31 @@ again:
604 *p = tolower(*p); 607 *p = tolower(*p);
605 } 608 }
606 609
610 /* Get default port if port has not been set. */
611 if (options.port == 0) {
612 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
613 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
614 }
615
607 if (options.proxy_command != NULL && 616 if (options.proxy_command != NULL &&
608 strcmp(options.proxy_command, "none") == 0) 617 strcmp(options.proxy_command, "none") == 0)
609 options.proxy_command = NULL; 618 options.proxy_command = NULL;
619 if (options.control_path != NULL &&
620 strcmp(options.control_path, "none") == 0)
621 options.control_path = NULL;
610 622
611 if (options.control_path != NULL) { 623 if (options.control_path != NULL) {
612 options.control_path = tilde_expand_filename( 624 snprintf(buf, sizeof(buf), "%d", options.port);
613 options.control_path, original_real_uid); 625 cp = tilde_expand_filename(options.control_path,
626 original_real_uid);
627 options.control_path = percent_expand(cp, "p", buf, "h", host,
628 "r", options.user, (char *)NULL);
629 xfree(cp);
614 } 630 }
615 if (options.control_path != NULL && options.control_master == 0) 631 if (mux_command != 0 && options.control_path == NULL)
616 control_client(options.control_path); /* This doesn't return */ 632 fatal("No ControlPath specified for \"-O\" command");
633 if (options.control_path != NULL)
634 control_client(options.control_path);
617 635
618 /* Open a connection to the remote host. */ 636 /* Open a connection to the remote host. */
619 if (ssh_connect(host, &hostaddr, options.port, 637 if (ssh_connect(host, &hostaddr, options.port,
@@ -742,110 +760,6 @@ again:
742 return exit_status; 760 return exit_status;
743} 761}
744 762
745#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
746
747static void
748x11_get_proto(char **_proto, char **_data)
749{
750 char cmd[1024];
751 char line[512];
752 char xdisplay[512];
753 static char proto[512], data[512];
754 FILE *f;
755 int got_data = 0, generated = 0, do_unlink = 0, i;
756 char *display, *xauthdir, *xauthfile;
757 struct stat st;
758
759 xauthdir = xauthfile = NULL;
760 *_proto = proto;
761 *_data = data;
762 proto[0] = data[0] = '\0';
763
764 if (!options.xauth_location ||
765 (stat(options.xauth_location, &st) == -1)) {
766 debug("No xauth program.");
767 } else {
768 if ((display = getenv("DISPLAY")) == NULL) {
769 debug("x11_get_proto: DISPLAY not set");
770 return;
771 }
772 /*
773 * Handle FamilyLocal case where $DISPLAY does
774 * not match an authorization entry. For this we
775 * just try "xauth list unix:displaynum.screennum".
776 * XXX: "localhost" match to determine FamilyLocal
777 * is not perfect.
778 */
779 if (strncmp(display, "localhost:", 10) == 0) {
780 snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
781 display + 10);
782 display = xdisplay;
783 }
784 if (options.forward_x11_trusted == 0) {
785 xauthdir = xmalloc(MAXPATHLEN);
786 xauthfile = xmalloc(MAXPATHLEN);
787 strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
788 if (mkdtemp(xauthdir) != NULL) {
789 do_unlink = 1;
790 snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
791 xauthdir);
792 snprintf(cmd, sizeof(cmd),
793 "%s -f %s generate %s " SSH_X11_PROTO
794 " untrusted timeout 1200 2>" _PATH_DEVNULL,
795 options.xauth_location, xauthfile, display);
796 debug2("x11_get_proto: %s", cmd);
797 if (system(cmd) == 0)
798 generated = 1;
799 }
800 }
801 snprintf(cmd, sizeof(cmd),
802 "%s %s%s list %s . 2>" _PATH_DEVNULL,
803 options.xauth_location,
804 generated ? "-f " : "" ,
805 generated ? xauthfile : "",
806 display);
807 debug2("x11_get_proto: %s", cmd);
808 f = popen(cmd, "r");
809 if (f && fgets(line, sizeof(line), f) &&
810 sscanf(line, "%*s %511s %511s", proto, data) == 2)
811 got_data = 1;
812 if (f)
813 pclose(f);
814 }
815
816 if (do_unlink) {
817 unlink(xauthfile);
818 rmdir(xauthdir);
819 }
820 if (xauthdir)
821 xfree(xauthdir);
822 if (xauthfile)
823 xfree(xauthfile);
824
825 /*
826 * If we didn't get authentication data, just make up some
827 * data. The forwarding code will check the validity of the
828 * response anyway, and substitute this data. The X11
829 * server, however, will ignore this fake data and use
830 * whatever authentication mechanisms it was using otherwise
831 * for the local connection.
832 */
833 if (!got_data) {
834 u_int32_t rnd = 0;
835
836 logit("Warning: No xauth data; "
837 "using fake authentication data for X11 forwarding.");
838 strlcpy(proto, SSH_X11_PROTO, sizeof proto);
839 for (i = 0; i < 16; i++) {
840 if (i % 4 == 0)
841 rnd = arc4random();
842 snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
843 rnd & 0xff);
844 rnd >>= 8;
845 }
846 }
847}
848
849static void 763static void
850ssh_init_forwarding(void) 764ssh_init_forwarding(void)
851{ 765{
@@ -856,8 +770,8 @@ ssh_init_forwarding(void)
856 for (i = 0; i < options.num_local_forwards; i++) { 770 for (i = 0; i < options.num_local_forwards; i++) {
857 debug("Local connections to %.200s:%d forwarded to remote " 771 debug("Local connections to %.200s:%d forwarded to remote "
858 "address %.200s:%d", 772 "address %.200s:%d",
859 (options.local_forwards[i].listen_host == NULL) ? 773 (options.local_forwards[i].listen_host == NULL) ?
860 (options.gateway_ports ? "*" : "LOCALHOST") : 774 (options.gateway_ports ? "*" : "LOCALHOST") :
861 options.local_forwards[i].listen_host, 775 options.local_forwards[i].listen_host,
862 options.local_forwards[i].listen_port, 776 options.local_forwards[i].listen_port,
863 options.local_forwards[i].connect_host, 777 options.local_forwards[i].connect_host,
@@ -876,6 +790,8 @@ ssh_init_forwarding(void)
876 for (i = 0; i < options.num_remote_forwards; i++) { 790 for (i = 0; i < options.num_remote_forwards; i++) {
877 debug("Remote connections from %.200s:%d forwarded to " 791 debug("Remote connections from %.200s:%d forwarded to "
878 "local address %.200s:%d", 792 "local address %.200s:%d",
793 (options.remote_forwards[i].listen_host == NULL) ?
794 (options.gateway_ports ? "*" : "LOCALHOST") :
879 options.remote_forwards[i].listen_host, 795 options.remote_forwards[i].listen_host,
880 options.remote_forwards[i].listen_port, 796 options.remote_forwards[i].listen_port,
881 options.remote_forwards[i].connect_host, 797 options.remote_forwards[i].connect_host,
@@ -906,6 +822,7 @@ ssh_session(void)
906 int have_tty = 0; 822 int have_tty = 0;
907 struct winsize ws; 823 struct winsize ws;
908 char *cp; 824 char *cp;
825 const char *display;
909 826
910 /* Enable compression if requested. */ 827 /* Enable compression if requested. */
911 if (options.compression) { 828 if (options.compression) {
@@ -967,13 +884,15 @@ ssh_session(void)
967 packet_disconnect("Protocol error waiting for pty request response."); 884 packet_disconnect("Protocol error waiting for pty request response.");
968 } 885 }
969 /* Request X11 forwarding if enabled and DISPLAY is set. */ 886 /* Request X11 forwarding if enabled and DISPLAY is set. */
970 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 887 display = getenv("DISPLAY");
888 if (options.forward_x11 && display != NULL) {
971 char *proto, *data; 889 char *proto, *data;
972 /* Get reasonable local authentication information. */ 890 /* Get reasonable local authentication information. */
973 x11_get_proto(&proto, &data); 891 client_x11_get_proto(display, options.xauth_location,
892 options.forward_x11_trusted, &proto, &data);
974 /* Request forwarding with authentication spoofing. */ 893 /* Request forwarding with authentication spoofing. */
975 debug("Requesting X11 forwarding with authentication spoofing."); 894 debug("Requesting X11 forwarding with authentication spoofing.");
976 x11_request_forwarding_with_spoofing(0, proto, data); 895 x11_request_forwarding_with_spoofing(0, display, proto, data);
977 896
978 /* Read response from the server. */ 897 /* Read response from the server. */
979 type = packet_read(); 898 type = packet_read();
@@ -1075,9 +994,12 @@ ssh_control_listener(void)
1075 mode_t old_umask; 994 mode_t old_umask;
1076 int addr_len; 995 int addr_len;
1077 996
1078 if (options.control_path == NULL || options.control_master <= 0) 997 if (options.control_path == NULL ||
998 options.control_master == SSHCTL_MASTER_NO)
1079 return; 999 return;
1080 1000
1001 debug("setting up multiplex master socket");
1002
1081 memset(&addr, '\0', sizeof(addr)); 1003 memset(&addr, '\0', sizeof(addr));
1082 addr.sun_family = AF_UNIX; 1004 addr.sun_family = AF_UNIX;
1083 addr_len = offsetof(struct sockaddr_un, sun_path) + 1005 addr_len = offsetof(struct sockaddr_un, sun_path) +
@@ -1093,7 +1015,7 @@ ssh_control_listener(void)
1093 old_umask = umask(0177); 1015 old_umask = umask(0177);
1094 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { 1016 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
1095 control_fd = -1; 1017 control_fd = -1;
1096 if (errno == EINVAL) 1018 if (errno == EINVAL || errno == EADDRINUSE)
1097 fatal("ControlSocket %s already exists", 1019 fatal("ControlSocket %s already exists",
1098 options.control_path); 1020 options.control_path);
1099 else 1021 else
@@ -1112,15 +1034,18 @@ static void
1112ssh_session2_setup(int id, void *arg) 1034ssh_session2_setup(int id, void *arg)
1113{ 1035{
1114 extern char **environ; 1036 extern char **environ;
1115 1037 const char *display;
1116 int interactive = tty_flag; 1038 int interactive = tty_flag;
1117 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 1039
1040 display = getenv("DISPLAY");
1041 if (options.forward_x11 && display != NULL) {
1118 char *proto, *data; 1042 char *proto, *data;
1119 /* Get reasonable local authentication information. */ 1043 /* Get reasonable local authentication information. */
1120 x11_get_proto(&proto, &data); 1044 client_x11_get_proto(display, options.xauth_location,
1045 options.forward_x11_trusted, &proto, &data);
1121 /* Request forwarding with authentication spoofing. */ 1046 /* Request forwarding with authentication spoofing. */
1122 debug("Requesting X11 forwarding with authentication spoofing."); 1047 debug("Requesting X11 forwarding with authentication spoofing.");
1123 x11_request_forwarding_with_spoofing(id, proto, data); 1048 x11_request_forwarding_with_spoofing(id, display, proto, data);
1124 interactive = 1; 1049 interactive = 1;
1125 /* XXX wait for reply */ 1050 /* XXX wait for reply */
1126 } 1051 }
@@ -1288,13 +1213,18 @@ control_client(const char *path)
1288 extern char **environ; 1213 extern char **environ;
1289 u_int flags; 1214 u_int flags;
1290 1215
1291 if (stdin_null_flag) { 1216 if (mux_command == 0)
1292 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) 1217 mux_command = SSHMUX_COMMAND_OPEN;
1293 fatal("open(/dev/null): %s", strerror(errno)); 1218
1294 if (dup2(fd, STDIN_FILENO) == -1) 1219 switch (options.control_master) {
1295 fatal("dup2: %s", strerror(errno)); 1220 case SSHCTL_MASTER_AUTO:
1296 if (fd > STDERR_FILENO) 1221 case SSHCTL_MASTER_AUTO_ASK:
1297 close(fd); 1222 debug("auto-mux: Trying existing master");
1223 /* FALLTHROUGH */
1224 case SSHCTL_MASTER_NO:
1225 break;
1226 default:
1227 return;
1298 } 1228 }
1299 1229
1300 memset(&addr, '\0', sizeof(addr)); 1230 memset(&addr, '\0', sizeof(addr));
@@ -1309,31 +1239,55 @@ control_client(const char *path)
1309 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 1239 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1310 fatal("%s socket(): %s", __func__, strerror(errno)); 1240 fatal("%s socket(): %s", __func__, strerror(errno));
1311 1241
1312 if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) 1242 if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
1313 fatal("Couldn't connect to %s: %s", path, strerror(errno)); 1243 if (mux_command != SSHMUX_COMMAND_OPEN) {
1244 fatal("Control socket connect(%.100s): %s", path,
1245 strerror(errno));
1246 }
1247 if (errno == ENOENT)
1248 debug("Control socket \"%.100s\" does not exist", path);
1249 else {
1250 error("Control socket connect(%.100s): %s", path,
1251 strerror(errno));
1252 }
1253 close(sock);
1254 return;
1255 }
1256
1257 if (stdin_null_flag) {
1258 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1259 fatal("open(/dev/null): %s", strerror(errno));
1260 if (dup2(fd, STDIN_FILENO) == -1)
1261 fatal("dup2: %s", strerror(errno));
1262 if (fd > STDERR_FILENO)
1263 close(fd);
1264 }
1314 1265
1315 if ((term = getenv("TERM")) == NULL) 1266 term = getenv("TERM");
1316 term = "";
1317 1267
1318 flags = 0; 1268 flags = 0;
1319 if (tty_flag) 1269 if (tty_flag)
1320 flags |= SSHMUX_FLAG_TTY; 1270 flags |= SSHMUX_FLAG_TTY;
1321 if (subsystem_flag) 1271 if (subsystem_flag)
1322 flags |= SSHMUX_FLAG_SUBSYS; 1272 flags |= SSHMUX_FLAG_SUBSYS;
1273 if (options.forward_x11)
1274 flags |= SSHMUX_FLAG_X11_FWD;
1275 if (options.forward_agent)
1276 flags |= SSHMUX_FLAG_AGENT_FWD;
1323 1277
1324 buffer_init(&m); 1278 buffer_init(&m);
1325 1279
1326 /* Send our command to server */ 1280 /* Send our command to server */
1327 buffer_put_int(&m, mux_command); 1281 buffer_put_int(&m, mux_command);
1328 buffer_put_int(&m, flags); 1282 buffer_put_int(&m, flags);
1329 if (ssh_msg_send(sock, /* version */1, &m) == -1) 1283 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1330 fatal("%s: msg_send", __func__); 1284 fatal("%s: msg_send", __func__);
1331 buffer_clear(&m); 1285 buffer_clear(&m);
1332 1286
1333 /* Get authorisation status and PID of controlee */ 1287 /* Get authorisation status and PID of controlee */
1334 if (ssh_msg_recv(sock, &m) == -1) 1288 if (ssh_msg_recv(sock, &m) == -1)
1335 fatal("%s: msg_recv", __func__); 1289 fatal("%s: msg_recv", __func__);
1336 if (buffer_get_char(&m) != 1) 1290 if (buffer_get_char(&m) != SSHMUX_VER)
1337 fatal("%s: wrong version", __func__); 1291 fatal("%s: wrong version", __func__);
1338 if (buffer_get_int(&m) != 1) 1292 if (buffer_get_int(&m) != 1)
1339 fatal("Connection to master denied"); 1293 fatal("Connection to master denied");
@@ -1343,7 +1297,7 @@ control_client(const char *path)
1343 1297
1344 switch (mux_command) { 1298 switch (mux_command) {
1345 case SSHMUX_COMMAND_ALIVE_CHECK: 1299 case SSHMUX_COMMAND_ALIVE_CHECK:
1346 fprintf(stderr, "Master running (pid=%d)\r\n", 1300 fprintf(stderr, "Master running (pid=%d)\r\n",
1347 control_server_pid); 1301 control_server_pid);
1348 exit(0); 1302 exit(0);
1349 case SSHMUX_COMMAND_TERMINATE: 1303 case SSHMUX_COMMAND_TERMINATE:
@@ -1357,7 +1311,7 @@ control_client(const char *path)
1357 } 1311 }
1358 1312
1359 /* SSHMUX_COMMAND_OPEN */ 1313 /* SSHMUX_COMMAND_OPEN */
1360 buffer_put_cstring(&m, term); 1314 buffer_put_cstring(&m, term ? term : "");
1361 buffer_append(&command, "\0", 1); 1315 buffer_append(&command, "\0", 1);
1362 buffer_put_cstring(&m, buffer_ptr(&command)); 1316 buffer_put_cstring(&m, buffer_ptr(&command));
1363 1317
@@ -1379,7 +1333,7 @@ control_client(const char *path)
1379 } 1333 }
1380 } 1334 }
1381 1335
1382 if (ssh_msg_send(sock, /* version */1, &m) == -1) 1336 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1383 fatal("%s: msg_send", __func__); 1337 fatal("%s: msg_send", __func__);
1384 1338
1385 mm_send_fd(sock, STDIN_FILENO); 1339 mm_send_fd(sock, STDIN_FILENO);
@@ -1390,7 +1344,7 @@ control_client(const char *path)
1390 buffer_clear(&m); 1344 buffer_clear(&m);
1391 if (ssh_msg_recv(sock, &m) == -1) 1345 if (ssh_msg_recv(sock, &m) == -1)
1392 fatal("%s: msg_recv", __func__); 1346 fatal("%s: msg_recv", __func__);
1393 if (buffer_get_char(&m) != 1) 1347 if (buffer_get_char(&m) != SSHMUX_VER)
1394 fatal("%s: wrong version", __func__); 1348 fatal("%s: wrong version", __func__);
1395 buffer_free(&m); 1349 buffer_free(&m);
1396 1350