diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 72 |
1 files changed, 47 insertions, 25 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.315 2008/06/12 04:06:00 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.316 2008/06/12 04:24:06 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -107,7 +107,7 @@ | |||
107 | 107 | ||
108 | extern char *__progname; | 108 | extern char *__progname; |
109 | 109 | ||
110 | /* Flag indicating whether debug mode is on. This can be set on the command line. */ | 110 | /* Flag indicating whether debug mode is on. May be set on the command line. */ |
111 | int debug_flag = 0; | 111 | int debug_flag = 0; |
112 | 112 | ||
113 | /* Flag indicating whether a tty should be allocated */ | 113 | /* Flag indicating whether a tty should be allocated */ |
@@ -261,15 +261,18 @@ main(int ac, char **av) | |||
261 | */ | 261 | */ |
262 | umask(022); | 262 | umask(022); |
263 | 263 | ||
264 | /* Initialize option structure to indicate that no values have been set. */ | 264 | /* |
265 | * Initialize option structure to indicate that no values have been | ||
266 | * set. | ||
267 | */ | ||
265 | initialize_options(&options); | 268 | initialize_options(&options); |
266 | 269 | ||
267 | /* Parse command-line arguments. */ | 270 | /* Parse command-line arguments. */ |
268 | host = NULL; | 271 | host = NULL; |
269 | 272 | ||
270 | again: | 273 | again: |
271 | while ((opt = getopt(ac, av, | 274 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" |
272 | "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { | 275 | "ACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { |
273 | switch (opt) { | 276 | switch (opt) { |
274 | case '1': | 277 | case '1': |
275 | options.protocol = SSH_PROTO_1; | 278 | options.protocol = SSH_PROTO_1; |
@@ -374,7 +377,8 @@ main(int ac, char **av) | |||
374 | options.tun_open = SSH_TUNMODE_DEFAULT; | 377 | options.tun_open = SSH_TUNMODE_DEFAULT; |
375 | options.tun_local = a2tun(optarg, &options.tun_remote); | 378 | options.tun_local = a2tun(optarg, &options.tun_remote); |
376 | if (options.tun_local == SSH_TUNID_ERR) { | 379 | if (options.tun_local == SSH_TUNID_ERR) { |
377 | fprintf(stderr, "Bad tun device '%s'\n", optarg); | 380 | fprintf(stderr, |
381 | "Bad tun device '%s'\n", optarg); | ||
378 | exit(255); | 382 | exit(255); |
379 | } | 383 | } |
380 | break; | 384 | break; |
@@ -477,7 +481,8 @@ main(int ac, char **av) | |||
477 | } | 481 | } |
478 | if (cp != NULL) { | 482 | if (cp != NULL) { |
479 | fwd.listen_port = a2port(cp); | 483 | fwd.listen_port = a2port(cp); |
480 | fwd.listen_host = cleanhostname(fwd.listen_host); | 484 | fwd.listen_host = |
485 | cleanhostname(fwd.listen_host); | ||
481 | } else { | 486 | } else { |
482 | fwd.listen_port = a2port(fwd.listen_host); | 487 | fwd.listen_port = a2port(fwd.listen_host); |
483 | fwd.listen_host = NULL; | 488 | fwd.listen_host = NULL; |
@@ -583,8 +588,10 @@ main(int ac, char **av) | |||
583 | } | 588 | } |
584 | 589 | ||
585 | /* Cannot fork to background if no command. */ | 590 | /* Cannot fork to background if no command. */ |
586 | if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) | 591 | if (fork_after_authentication_flag && buffer_len(&command) == 0 && |
587 | fatal("Cannot fork into background without a command to execute."); | 592 | !no_shell_flag) |
593 | fatal("Cannot fork into background without a command " | ||
594 | "to execute."); | ||
588 | 595 | ||
589 | /* Allocate a tty by default if no command specified. */ | 596 | /* Allocate a tty by default if no command specified. */ |
590 | if (buffer_len(&command) == 0) | 597 | if (buffer_len(&command) == 0) |
@@ -596,7 +603,8 @@ main(int ac, char **av) | |||
596 | /* Do not allocate a tty if stdin is not a tty. */ | 603 | /* Do not allocate a tty if stdin is not a tty. */ |
597 | if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { | 604 | if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { |
598 | if (tty_flag) | 605 | if (tty_flag) |
599 | logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); | 606 | logit("Pseudo-terminal will not be allocated because " |
607 | "stdin is not a terminal."); | ||
600 | tty_flag = 0; | 608 | tty_flag = 0; |
601 | } | 609 | } |
602 | 610 | ||
@@ -604,7 +612,8 @@ main(int ac, char **av) | |||
604 | * Initialize "log" output. Since we are the client all output | 612 | * Initialize "log" output. Since we are the client all output |
605 | * actually goes to stderr. | 613 | * actually goes to stderr. |
606 | */ | 614 | */ |
607 | log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, | 615 | log_init(av[0], |
616 | options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, | ||
608 | SYSLOG_FACILITY_USER, 1); | 617 | SYSLOG_FACILITY_USER, 1); |
609 | 618 | ||
610 | /* | 619 | /* |
@@ -753,7 +762,8 @@ main(int ac, char **av) | |||
753 | * Now that we are back to our own permissions, create ~/.ssh | 762 | * Now that we are back to our own permissions, create ~/.ssh |
754 | * directory if it doesn't already exist. | 763 | * directory if it doesn't already exist. |
755 | */ | 764 | */ |
756 | snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); | 765 | snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, |
766 | strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); | ||
757 | if (stat(buf, &st) < 0) | 767 | if (stat(buf, &st) < 0) |
758 | if (mkdir(buf, 0700) < 0) | 768 | if (mkdir(buf, 0700) < 0) |
759 | error("Could not create directory '%.200s'.", buf); | 769 | error("Could not create directory '%.200s'.", buf); |
@@ -774,7 +784,7 @@ main(int ac, char **av) | |||
774 | 784 | ||
775 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ | 785 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ |
776 | 786 | ||
777 | /* Log into the remote system. This never returns if the login fails. */ | 787 | /* Log into the remote system. Never returns if the login fails. */ |
778 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, | 788 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, |
779 | pw, timeout_ms); | 789 | pw, timeout_ms); |
780 | 790 | ||
@@ -925,10 +935,13 @@ ssh_session(void) | |||
925 | 935 | ||
926 | /* Enable compression if requested. */ | 936 | /* Enable compression if requested. */ |
927 | if (options.compression) { | 937 | if (options.compression) { |
928 | debug("Requesting compression at level %d.", options.compression_level); | 938 | debug("Requesting compression at level %d.", |
939 | options.compression_level); | ||
929 | 940 | ||
930 | if (options.compression_level < 1 || options.compression_level > 9) | 941 | if (options.compression_level < 1 || |
931 | fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); | 942 | options.compression_level > 9) |
943 | fatal("Compression level must be from 1 (fast) to " | ||
944 | "9 (slow, best)."); | ||
932 | 945 | ||
933 | /* Send the request. */ | 946 | /* Send the request. */ |
934 | packet_start(SSH_CMSG_REQUEST_COMPRESSION); | 947 | packet_start(SSH_CMSG_REQUEST_COMPRESSION); |
@@ -941,7 +954,8 @@ ssh_session(void) | |||
941 | else if (type == SSH_SMSG_FAILURE) | 954 | else if (type == SSH_SMSG_FAILURE) |
942 | logit("Warning: Remote host refused compression."); | 955 | logit("Warning: Remote host refused compression."); |
943 | else | 956 | else |
944 | packet_disconnect("Protocol error waiting for compression response."); | 957 | packet_disconnect("Protocol error waiting for " |
958 | "compression response."); | ||
945 | } | 959 | } |
946 | /* Allocate a pseudo tty if appropriate. */ | 960 | /* Allocate a pseudo tty if appropriate. */ |
947 | if (tty_flag) { | 961 | if (tty_flag) { |
@@ -978,9 +992,11 @@ ssh_session(void) | |||
978 | interactive = 1; | 992 | interactive = 1; |
979 | have_tty = 1; | 993 | have_tty = 1; |
980 | } else if (type == SSH_SMSG_FAILURE) | 994 | } else if (type == SSH_SMSG_FAILURE) |
981 | logit("Warning: Remote host failed or refused to allocate a pseudo tty."); | 995 | logit("Warning: Remote host failed or refused to " |
996 | "allocate a pseudo tty."); | ||
982 | else | 997 | else |
983 | packet_disconnect("Protocol error waiting for pty request response."); | 998 | packet_disconnect("Protocol error waiting for pty " |
999 | "request response."); | ||
984 | } | 1000 | } |
985 | /* Request X11 forwarding if enabled and DISPLAY is set. */ | 1001 | /* Request X11 forwarding if enabled and DISPLAY is set. */ |
986 | display = getenv("DISPLAY"); | 1002 | display = getenv("DISPLAY"); |
@@ -990,7 +1006,8 @@ ssh_session(void) | |||
990 | client_x11_get_proto(display, options.xauth_location, | 1006 | client_x11_get_proto(display, options.xauth_location, |
991 | options.forward_x11_trusted, &proto, &data); | 1007 | options.forward_x11_trusted, &proto, &data); |
992 | /* Request forwarding with authentication spoofing. */ | 1008 | /* Request forwarding with authentication spoofing. */ |
993 | debug("Requesting X11 forwarding with authentication spoofing."); | 1009 | debug("Requesting X11 forwarding with authentication " |
1010 | "spoofing."); | ||
994 | x11_request_forwarding_with_spoofing(0, display, proto, data); | 1011 | x11_request_forwarding_with_spoofing(0, display, proto, data); |
995 | 1012 | ||
996 | /* Read response from the server. */ | 1013 | /* Read response from the server. */ |
@@ -1000,7 +1017,8 @@ ssh_session(void) | |||
1000 | } else if (type == SSH_SMSG_FAILURE) { | 1017 | } else if (type == SSH_SMSG_FAILURE) { |
1001 | logit("Warning: Remote host denied X11 forwarding."); | 1018 | logit("Warning: Remote host denied X11 forwarding."); |
1002 | } else { | 1019 | } else { |
1003 | packet_disconnect("Protocol error waiting for X11 forwarding"); | 1020 | packet_disconnect("Protocol error waiting for X11 " |
1021 | "forwarding"); | ||
1004 | } | 1022 | } |
1005 | } | 1023 | } |
1006 | /* Tell the packet module whether this is an interactive session. */ | 1024 | /* Tell the packet module whether this is an interactive session. */ |
@@ -1041,7 +1059,8 @@ ssh_session(void) | |||
1041 | int len = buffer_len(&command); | 1059 | int len = buffer_len(&command); |
1042 | if (len > 900) | 1060 | if (len > 900) |
1043 | len = 900; | 1061 | len = 900; |
1044 | debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); | 1062 | debug("Sending command: %.*s", len, |
1063 | (u_char *)buffer_ptr(&command)); | ||
1045 | packet_start(SSH_CMSG_EXEC_CMD); | 1064 | packet_start(SSH_CMSG_EXEC_CMD); |
1046 | packet_put_string(buffer_ptr(&command), buffer_len(&command)); | 1065 | packet_put_string(buffer_ptr(&command), buffer_len(&command)); |
1047 | packet_send(); | 1066 | packet_send(); |
@@ -1073,7 +1092,8 @@ ssh_session2_setup(int id, void *arg) | |||
1073 | client_x11_get_proto(display, options.xauth_location, | 1092 | client_x11_get_proto(display, options.xauth_location, |
1074 | options.forward_x11_trusted, &proto, &data); | 1093 | options.forward_x11_trusted, &proto, &data); |
1075 | /* Request forwarding with authentication spoofing. */ | 1094 | /* Request forwarding with authentication spoofing. */ |
1076 | debug("Requesting X11 forwarding with authentication spoofing."); | 1095 | debug("Requesting X11 forwarding with authentication " |
1096 | "spoofing."); | ||
1077 | x11_request_forwarding_with_spoofing(id, display, proto, data); | 1097 | x11_request_forwarding_with_spoofing(id, display, proto, data); |
1078 | interactive = 1; | 1098 | interactive = 1; |
1079 | /* XXX wait for reply */ | 1099 | /* XXX wait for reply */ |
@@ -1193,9 +1213,11 @@ load_public_identity_files(void) | |||
1193 | int count = 0; | 1213 | int count = 0; |
1194 | for (i = 0; keys[i] != NULL; i++) { | 1214 | for (i = 0; keys[i] != NULL; i++) { |
1195 | count++; | 1215 | count++; |
1196 | memmove(&options.identity_files[1], &options.identity_files[0], | 1216 | memmove(&options.identity_files[1], |
1217 | &options.identity_files[0], | ||
1197 | sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); | 1218 | sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); |
1198 | memmove(&options.identity_keys[1], &options.identity_keys[0], | 1219 | memmove(&options.identity_keys[1], |
1220 | &options.identity_keys[0], | ||
1199 | sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); | 1221 | sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); |
1200 | options.num_identity_files++; | 1222 | options.num_identity_files++; |
1201 | options.identity_keys[0] = keys[i]; | 1223 | options.identity_keys[0] = keys[i]; |