summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c89
1 files changed, 66 insertions, 23 deletions
diff --git a/ssh.c b/ssh.c
index c9e5aac7a..3940dabfd 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.249 2005/07/30 01:26:16 djm Exp $"); 43RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $");
44 44
45#include <openssl/evp.h> 45#include <openssl/evp.h>
46#include <openssl/err.h> 46#include <openssl/err.h>
@@ -158,13 +158,13 @@ usage(void)
158{ 158{
159 fprintf(stderr, 159 fprintf(stderr,
160"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" 160"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
161" [-D port] [-e escape_char] [-F configfile]\n" 161" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
162" [-i identity_file] [-L [bind_address:]port:host:hostport]\n" 162" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
163" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" 163" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
164" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" 164" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
165" [user@]hostname [command]\n" 165" [-w tunnel:tunnel] [user@]hostname [command]\n"
166 ); 166 );
167 exit(1); 167 exit(255);
168} 168}
169 169
170static int ssh_session(void); 170static int ssh_session(void);
@@ -188,6 +188,9 @@ main(int ac, char **av)
188 struct servent *sp; 188 struct servent *sp;
189 Forward fwd; 189 Forward fwd;
190 190
191 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
192 sanitise_stdfd();
193
191 __progname = ssh_get_progname(av[0]); 194 __progname = ssh_get_progname(av[0]);
192 init_rng(); 195 init_rng();
193 196
@@ -220,7 +223,7 @@ main(int ac, char **av)
220 pw = getpwuid(original_real_uid); 223 pw = getpwuid(original_real_uid);
221 if (!pw) { 224 if (!pw) {
222 logit("You don't exist, go away!"); 225 logit("You don't exist, go away!");
223 exit(1); 226 exit(255);
224 } 227 }
225 /* Take a copy of the returned structure. */ 228 /* Take a copy of the returned structure. */
226 pw = pwcopy(pw); 229 pw = pwcopy(pw);
@@ -241,7 +244,7 @@ main(int ac, char **av)
241 244
242again: 245again:
243 while ((opt = getopt(ac, av, 246 while ((opt = getopt(ac, av,
244 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { 247 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
245 switch (opt) { 248 switch (opt) {
246 case '1': 249 case '1':
247 options.protocol = SSH_PROTO_1; 250 options.protocol = SSH_PROTO_1;
@@ -337,6 +340,15 @@ again:
337 if (opt == 'V') 340 if (opt == 'V')
338 exit(0); 341 exit(0);
339 break; 342 break;
343 case 'w':
344 if (options.tun_open == -1)
345 options.tun_open = SSH_TUNMODE_DEFAULT;
346 options.tun_local = a2tun(optarg, &options.tun_remote);
347 if (options.tun_local == SSH_TUNID_ERR) {
348 fprintf(stderr, "Bad tun device '%s'\n", optarg);
349 exit(255);
350 }
351 break;
340 case 'q': 352 case 'q':
341 options.log_level = SYSLOG_LEVEL_QUIET; 353 options.log_level = SYSLOG_LEVEL_QUIET;
342 break; 354 break;
@@ -352,7 +364,7 @@ again:
352 else { 364 else {
353 fprintf(stderr, "Bad escape character '%s'.\n", 365 fprintf(stderr, "Bad escape character '%s'.\n",
354 optarg); 366 optarg);
355 exit(1); 367 exit(255);
356 } 368 }
357 break; 369 break;
358 case 'c': 370 case 'c':
@@ -367,7 +379,7 @@ again:
367 fprintf(stderr, 379 fprintf(stderr,
368 "Unknown cipher type '%s'\n", 380 "Unknown cipher type '%s'\n",
369 optarg); 381 optarg);
370 exit(1); 382 exit(255);
371 } 383 }
372 if (options.cipher == SSH_CIPHER_3DES) 384 if (options.cipher == SSH_CIPHER_3DES)
373 options.ciphers = "3des-cbc"; 385 options.ciphers = "3des-cbc";
@@ -383,7 +395,7 @@ again:
383 else { 395 else {
384 fprintf(stderr, "Unknown mac type '%s'\n", 396 fprintf(stderr, "Unknown mac type '%s'\n",
385 optarg); 397 optarg);
386 exit(1); 398 exit(255);
387 } 399 }
388 break; 400 break;
389 case 'M': 401 case 'M':
@@ -396,7 +408,7 @@ again:
396 options.port = a2port(optarg); 408 options.port = a2port(optarg);
397 if (options.port == 0) { 409 if (options.port == 0) {
398 fprintf(stderr, "Bad port '%s'\n", optarg); 410 fprintf(stderr, "Bad port '%s'\n", optarg);
399 exit(1); 411 exit(255);
400 } 412 }
401 break; 413 break;
402 case 'l': 414 case 'l':
@@ -410,7 +422,7 @@ again:
410 fprintf(stderr, 422 fprintf(stderr,
411 "Bad local forwarding specification '%s'\n", 423 "Bad local forwarding specification '%s'\n",
412 optarg); 424 optarg);
413 exit(1); 425 exit(255);
414 } 426 }
415 break; 427 break;
416 428
@@ -421,7 +433,7 @@ again:
421 fprintf(stderr, 433 fprintf(stderr,
422 "Bad remote forwarding specification " 434 "Bad remote forwarding specification "
423 "'%s'\n", optarg); 435 "'%s'\n", optarg);
424 exit(1); 436 exit(255);
425 } 437 }
426 break; 438 break;
427 439
@@ -432,7 +444,7 @@ again:
432 if ((fwd.listen_host = hpdelim(&cp)) == NULL) { 444 if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
433 fprintf(stderr, "Bad dynamic forwarding " 445 fprintf(stderr, "Bad dynamic forwarding "
434 "specification '%.100s'\n", optarg); 446 "specification '%.100s'\n", optarg);
435 exit(1); 447 exit(255);
436 } 448 }
437 if (cp != NULL) { 449 if (cp != NULL) {
438 fwd.listen_port = a2port(cp); 450 fwd.listen_port = a2port(cp);
@@ -445,7 +457,7 @@ again:
445 if (fwd.listen_port == 0) { 457 if (fwd.listen_port == 0) {
446 fprintf(stderr, "Bad dynamic port '%s'\n", 458 fprintf(stderr, "Bad dynamic port '%s'\n",
447 optarg); 459 optarg);
448 exit(1); 460 exit(255);
449 } 461 }
450 add_local_forward(&options, &fwd); 462 add_local_forward(&options, &fwd);
451 xfree(p); 463 xfree(p);
@@ -466,7 +478,7 @@ again:
466 line = xstrdup(optarg); 478 line = xstrdup(optarg);
467 if (process_config_line(&options, host ? host : "", 479 if (process_config_line(&options, host ? host : "",
468 line, "command-line", 0, &dummy) != 0) 480 line, "command-line", 0, &dummy) != 0)
469 exit(1); 481 exit(255);
470 xfree(line); 482 xfree(line);
471 break; 483 break;
472 case 's': 484 case 's':
@@ -642,7 +654,7 @@ again:
642 original_effective_uid == 0 && options.use_privileged_port, 654 original_effective_uid == 0 && options.use_privileged_port,
643#endif 655#endif
644 options.proxy_command) != 0) 656 options.proxy_command) != 0)
645 exit(1); 657 exit(255);
646 658
647 /* 659 /*
648 * If we successfully made the connection, load the host private key 660 * If we successfully made the connection, load the host private key
@@ -695,7 +707,7 @@ again:
695 707
696 /* 708 /*
697 * Now that we are back to our own permissions, create ~/.ssh 709 * Now that we are back to our own permissions, create ~/.ssh
698 * directory if it doesn\'t already exist. 710 * directory if it doesn't already exist.
699 */ 711 */
700 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 712 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
701 if (stat(buf, &st) < 0) 713 if (stat(buf, &st) < 0)
@@ -791,8 +803,7 @@ ssh_init_forwarding(void)
791 debug("Remote connections from %.200s:%d forwarded to " 803 debug("Remote connections from %.200s:%d forwarded to "
792 "local address %.200s:%d", 804 "local address %.200s:%d",
793 (options.remote_forwards[i].listen_host == NULL) ? 805 (options.remote_forwards[i].listen_host == NULL) ?
794 (options.gateway_ports ? "*" : "LOCALHOST") : 806 "LOCALHOST" : options.remote_forwards[i].listen_host,
795 options.remote_forwards[i].listen_host,
796 options.remote_forwards[i].listen_port, 807 options.remote_forwards[i].listen_port,
797 options.remote_forwards[i].connect_host, 808 options.remote_forwards[i].connect_host,
798 options.remote_forwards[i].connect_port); 809 options.remote_forwards[i].connect_port);
@@ -808,7 +819,7 @@ static void
808check_agent_present(void) 819check_agent_present(void)
809{ 820{
810 if (options.forward_agent) { 821 if (options.forward_agent) {
811 /* Clear agent forwarding if we don\'t have an agent. */ 822 /* Clear agent forwarding if we don't have an agent. */
812 if (!ssh_agent_present()) 823 if (!ssh_agent_present())
813 options.forward_agent = 0; 824 options.forward_agent = 0;
814 } 825 }
@@ -1010,7 +1021,7 @@ ssh_control_listener(void)
1010 fatal("ControlPath too long"); 1021 fatal("ControlPath too long");
1011 1022
1012 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 1023 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1013 fatal("%s socket(): %s\n", __func__, strerror(errno)); 1024 fatal("%s socket(): %s", __func__, strerror(errno));
1014 1025
1015 old_umask = umask(0177); 1026 old_umask = umask(0177);
1016 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { 1027 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
@@ -1019,12 +1030,12 @@ ssh_control_listener(void)
1019 fatal("ControlSocket %s already exists", 1030 fatal("ControlSocket %s already exists",
1020 options.control_path); 1031 options.control_path);
1021 else 1032 else
1022 fatal("%s bind(): %s\n", __func__, strerror(errno)); 1033 fatal("%s bind(): %s", __func__, strerror(errno));
1023 } 1034 }
1024 umask(old_umask); 1035 umask(old_umask);
1025 1036
1026 if (listen(control_fd, 64) == -1) 1037 if (listen(control_fd, 64) == -1)
1027 fatal("%s listen(): %s\n", __func__, strerror(errno)); 1038 fatal("%s listen(): %s", __func__, strerror(errno));
1028 1039
1029 set_nonblock(control_fd); 1040 set_nonblock(control_fd);
1030} 1041}
@@ -1057,6 +1068,33 @@ ssh_session2_setup(int id, void *arg)
1057 packet_send(); 1068 packet_send();
1058 } 1069 }
1059 1070
1071 if (options.tun_open != SSH_TUNMODE_NO) {
1072 Channel *c;
1073 int fd;
1074
1075 debug("Requesting tun.");
1076 if ((fd = tun_open(options.tun_local,
1077 options.tun_open)) >= 0) {
1078 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
1079 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1080 0, "tun", 1);
1081 c->datagram = 1;
1082#if defined(SSH_TUN_FILTER)
1083 if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
1084 channel_register_filter(c->self, sys_tun_infilter,
1085 sys_tun_outfilter);
1086#endif
1087 packet_start(SSH2_MSG_CHANNEL_OPEN);
1088 packet_put_cstring("tun@openssh.com");
1089 packet_put_int(c->self);
1090 packet_put_int(c->local_window_max);
1091 packet_put_int(c->local_maxpacket);
1092 packet_put_int(options.tun_open);
1093 packet_put_int(options.tun_remote);
1094 packet_send();
1095 }
1096 }
1097
1060 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1098 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1061 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); 1099 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
1062 1100
@@ -1121,6 +1159,11 @@ ssh_session2(void)
1121 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1159 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1122 id = ssh_session2_open(); 1160 id = ssh_session2_open();
1123 1161
1162 /* Execute a local command */
1163 if (options.local_command != NULL &&
1164 options.permit_local_command)
1165 ssh_local_cmd(options.local_command);
1166
1124 /* If requested, let ssh continue in the background. */ 1167 /* If requested, let ssh continue in the background. */
1125 if (fork_after_authentication_flag) 1168 if (fork_after_authentication_flag)
1126 if (daemon(1, 1) < 0) 1169 if (daemon(1, 1) < 0)