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 75a0d9b23..a64f1e2dc 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 if (options.log_level == SYSLOG_LEVEL_QUIET) { 353 if (options.log_level == SYSLOG_LEVEL_QUIET) {
342 options.log_level = SYSLOG_LEVEL_SILENT; 354 options.log_level = SYSLOG_LEVEL_SILENT;
@@ -357,7 +369,7 @@ again:
357 else { 369 else {
358 fprintf(stderr, "Bad escape character '%s'.\n", 370 fprintf(stderr, "Bad escape character '%s'.\n",
359 optarg); 371 optarg);
360 exit(1); 372 exit(255);
361 } 373 }
362 break; 374 break;
363 case 'c': 375 case 'c':
@@ -372,7 +384,7 @@ again:
372 fprintf(stderr, 384 fprintf(stderr,
373 "Unknown cipher type '%s'\n", 385 "Unknown cipher type '%s'\n",
374 optarg); 386 optarg);
375 exit(1); 387 exit(255);
376 } 388 }
377 if (options.cipher == SSH_CIPHER_3DES) 389 if (options.cipher == SSH_CIPHER_3DES)
378 options.ciphers = "3des-cbc"; 390 options.ciphers = "3des-cbc";
@@ -388,7 +400,7 @@ again:
388 else { 400 else {
389 fprintf(stderr, "Unknown mac type '%s'\n", 401 fprintf(stderr, "Unknown mac type '%s'\n",
390 optarg); 402 optarg);
391 exit(1); 403 exit(255);
392 } 404 }
393 break; 405 break;
394 case 'M': 406 case 'M':
@@ -401,7 +413,7 @@ again:
401 options.port = a2port(optarg); 413 options.port = a2port(optarg);
402 if (options.port == 0) { 414 if (options.port == 0) {
403 fprintf(stderr, "Bad port '%s'\n", optarg); 415 fprintf(stderr, "Bad port '%s'\n", optarg);
404 exit(1); 416 exit(255);
405 } 417 }
406 break; 418 break;
407 case 'l': 419 case 'l':
@@ -415,7 +427,7 @@ again:
415 fprintf(stderr, 427 fprintf(stderr,
416 "Bad local forwarding specification '%s'\n", 428 "Bad local forwarding specification '%s'\n",
417 optarg); 429 optarg);
418 exit(1); 430 exit(255);
419 } 431 }
420 break; 432 break;
421 433
@@ -426,7 +438,7 @@ again:
426 fprintf(stderr, 438 fprintf(stderr,
427 "Bad remote forwarding specification " 439 "Bad remote forwarding specification "
428 "'%s'\n", optarg); 440 "'%s'\n", optarg);
429 exit(1); 441 exit(255);
430 } 442 }
431 break; 443 break;
432 444
@@ -437,7 +449,7 @@ again:
437 if ((fwd.listen_host = hpdelim(&cp)) == NULL) { 449 if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
438 fprintf(stderr, "Bad dynamic forwarding " 450 fprintf(stderr, "Bad dynamic forwarding "
439 "specification '%.100s'\n", optarg); 451 "specification '%.100s'\n", optarg);
440 exit(1); 452 exit(255);
441 } 453 }
442 if (cp != NULL) { 454 if (cp != NULL) {
443 fwd.listen_port = a2port(cp); 455 fwd.listen_port = a2port(cp);
@@ -450,7 +462,7 @@ again:
450 if (fwd.listen_port == 0) { 462 if (fwd.listen_port == 0) {
451 fprintf(stderr, "Bad dynamic port '%s'\n", 463 fprintf(stderr, "Bad dynamic port '%s'\n",
452 optarg); 464 optarg);
453 exit(1); 465 exit(255);
454 } 466 }
455 add_local_forward(&options, &fwd); 467 add_local_forward(&options, &fwd);
456 xfree(p); 468 xfree(p);
@@ -471,7 +483,7 @@ again:
471 line = xstrdup(optarg); 483 line = xstrdup(optarg);
472 if (process_config_line(&options, host ? host : "", 484 if (process_config_line(&options, host ? host : "",
473 line, "command-line", 0, &dummy) != 0) 485 line, "command-line", 0, &dummy) != 0)
474 exit(1); 486 exit(255);
475 xfree(line); 487 xfree(line);
476 break; 488 break;
477 case 's': 489 case 's':
@@ -647,7 +659,7 @@ again:
647 original_effective_uid == 0 && options.use_privileged_port, 659 original_effective_uid == 0 && options.use_privileged_port,
648#endif 660#endif
649 options.proxy_command) != 0) 661 options.proxy_command) != 0)
650 exit(1); 662 exit(255);
651 663
652 /* 664 /*
653 * If we successfully made the connection, load the host private key 665 * If we successfully made the connection, load the host private key
@@ -700,7 +712,7 @@ again:
700 712
701 /* 713 /*
702 * Now that we are back to our own permissions, create ~/.ssh 714 * Now that we are back to our own permissions, create ~/.ssh
703 * directory if it doesn\'t already exist. 715 * directory if it doesn't already exist.
704 */ 716 */
705 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 717 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
706 if (stat(buf, &st) < 0) 718 if (stat(buf, &st) < 0)
@@ -796,8 +808,7 @@ ssh_init_forwarding(void)
796 debug("Remote connections from %.200s:%d forwarded to " 808 debug("Remote connections from %.200s:%d forwarded to "
797 "local address %.200s:%d", 809 "local address %.200s:%d",
798 (options.remote_forwards[i].listen_host == NULL) ? 810 (options.remote_forwards[i].listen_host == NULL) ?
799 (options.gateway_ports ? "*" : "LOCALHOST") : 811 "LOCALHOST" : options.remote_forwards[i].listen_host,
800 options.remote_forwards[i].listen_host,
801 options.remote_forwards[i].listen_port, 812 options.remote_forwards[i].listen_port,
802 options.remote_forwards[i].connect_host, 813 options.remote_forwards[i].connect_host,
803 options.remote_forwards[i].connect_port); 814 options.remote_forwards[i].connect_port);
@@ -813,7 +824,7 @@ static void
813check_agent_present(void) 824check_agent_present(void)
814{ 825{
815 if (options.forward_agent) { 826 if (options.forward_agent) {
816 /* Clear agent forwarding if we don\'t have an agent. */ 827 /* Clear agent forwarding if we don't have an agent. */
817 if (!ssh_agent_present()) 828 if (!ssh_agent_present())
818 options.forward_agent = 0; 829 options.forward_agent = 0;
819 } 830 }
@@ -1015,7 +1026,7 @@ ssh_control_listener(void)
1015 fatal("ControlPath too long"); 1026 fatal("ControlPath too long");
1016 1027
1017 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 1028 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1018 fatal("%s socket(): %s\n", __func__, strerror(errno)); 1029 fatal("%s socket(): %s", __func__, strerror(errno));
1019 1030
1020 old_umask = umask(0177); 1031 old_umask = umask(0177);
1021 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { 1032 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
@@ -1024,12 +1035,12 @@ ssh_control_listener(void)
1024 fatal("ControlSocket %s already exists", 1035 fatal("ControlSocket %s already exists",
1025 options.control_path); 1036 options.control_path);
1026 else 1037 else
1027 fatal("%s bind(): %s\n", __func__, strerror(errno)); 1038 fatal("%s bind(): %s", __func__, strerror(errno));
1028 } 1039 }
1029 umask(old_umask); 1040 umask(old_umask);
1030 1041
1031 if (listen(control_fd, 64) == -1) 1042 if (listen(control_fd, 64) == -1)
1032 fatal("%s listen(): %s\n", __func__, strerror(errno)); 1043 fatal("%s listen(): %s", __func__, strerror(errno));
1033 1044
1034 set_nonblock(control_fd); 1045 set_nonblock(control_fd);
1035} 1046}
@@ -1062,6 +1073,33 @@ ssh_session2_setup(int id, void *arg)
1062 packet_send(); 1073 packet_send();
1063 } 1074 }
1064 1075
1076 if (options.tun_open != SSH_TUNMODE_NO) {
1077 Channel *c;
1078 int fd;
1079
1080 debug("Requesting tun.");
1081 if ((fd = tun_open(options.tun_local,
1082 options.tun_open)) >= 0) {
1083 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
1084 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1085 0, "tun", 1);
1086 c->datagram = 1;
1087#if defined(SSH_TUN_FILTER)
1088 if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
1089 channel_register_filter(c->self, sys_tun_infilter,
1090 sys_tun_outfilter);
1091#endif
1092 packet_start(SSH2_MSG_CHANNEL_OPEN);
1093 packet_put_cstring("tun@openssh.com");
1094 packet_put_int(c->self);
1095 packet_put_int(c->local_window_max);
1096 packet_put_int(c->local_maxpacket);
1097 packet_put_int(options.tun_open);
1098 packet_put_int(options.tun_remote);
1099 packet_send();
1100 }
1101 }
1102
1065 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1103 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1066 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); 1104 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
1067 1105
@@ -1126,6 +1164,11 @@ ssh_session2(void)
1126 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1164 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1127 id = ssh_session2_open(); 1165 id = ssh_session2_open();
1128 1166
1167 /* Execute a local command */
1168 if (options.local_command != NULL &&
1169 options.permit_local_command)
1170 ssh_local_cmd(options.local_command);
1171
1129 /* If requested, let ssh continue in the background. */ 1172 /* If requested, let ssh continue in the background. */
1130 if (fork_after_authentication_flag) 1173 if (fork_after_authentication_flag)
1131 if (daemon(1, 1) < 0) 1174 if (daemon(1, 1) < 0)