diff options
author | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
commit | 1383bd8eb91a8ec9c8d283679faec5925b0ccc42 (patch) | |
tree | f71278df6c50983ea3dad850ae79c45c340d9362 /ssh.c | |
parent | 74a333bbe11f67c59c559e0f424d5945eb438577 (diff) |
- OpenBSD CVS update:
- [channels.c]
close efd on eof
- [clientloop.c compat.c ssh.c sshconnect.c myproposal.h]
ssh2 client implementation, interops w/ ssh.com and lsh servers.
- [sshconnect.c]
missing free.
- [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c]
remove unused argument, split cipher_mask()
- [clientloop.c]
re-order: group ssh1 vs. ssh2
- Make Redhat spec require openssl >= 0.9.5a
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 162 |
1 files changed, 147 insertions, 15 deletions
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $"); | 14 | RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "ssh.h" | 17 | #include "ssh.h" |
@@ -20,6 +20,9 @@ RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $"); | |||
20 | #include "authfd.h" | 20 | #include "authfd.h" |
21 | #include "readconf.h" | 21 | #include "readconf.h" |
22 | #include "uidswap.h" | 22 | #include "uidswap.h" |
23 | |||
24 | #include "ssh2.h" | ||
25 | #include "compat.h" | ||
23 | #include "channels.h" | 26 | #include "channels.h" |
24 | 27 | ||
25 | #ifdef HAVE___PROGNAME | 28 | #ifdef HAVE___PROGNAME |
@@ -41,6 +44,10 @@ int debug_flag = 0; | |||
41 | 44 | ||
42 | int tty_flag = 0; | 45 | int tty_flag = 0; |
43 | 46 | ||
47 | /* don't exec a shell */ | ||
48 | int no_shell_flag = 0; | ||
49 | int no_tty_flag = 0; | ||
50 | |||
44 | /* | 51 | /* |
45 | * Flag indicating that nothing should be read from stdin. This can be set | 52 | * Flag indicating that nothing should be read from stdin. This can be set |
46 | * on the command line. | 53 | * on the command line. |
@@ -90,6 +97,9 @@ RSA *host_private_key = NULL; | |||
90 | /* Original real UID. */ | 97 | /* Original real UID. */ |
91 | uid_t original_real_uid; | 98 | uid_t original_real_uid; |
92 | 99 | ||
100 | /* command to be executed */ | ||
101 | Buffer command; | ||
102 | |||
93 | /* Prints a help message to the user. This function never returns. */ | 103 | /* Prints a help message to the user. This function never returns. */ |
94 | 104 | ||
95 | void | 105 | void |
@@ -104,9 +114,9 @@ usage() | |||
104 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); | 114 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); |
105 | #endif /* AFS */ | 115 | #endif /* AFS */ |
106 | fprintf(stderr, " -x Disable X11 connection forwarding.\n"); | 116 | fprintf(stderr, " -x Disable X11 connection forwarding.\n"); |
107 | fprintf(stderr, " -X Enable X11 connection forwarding.\n"); | ||
108 | fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); | 117 | fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); |
109 | fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); | 118 | fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); |
119 | fprintf(stderr, " -T Do not allocate a tty.\n"); | ||
110 | fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); | 120 | fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); |
111 | fprintf(stderr, " -V Display version number only.\n"); | 121 | fprintf(stderr, " -V Display version number only.\n"); |
112 | fprintf(stderr, " -P Don't allocate a privileged port.\n"); | 122 | fprintf(stderr, " -P Don't allocate a privileged port.\n"); |
@@ -123,6 +133,7 @@ usage() | |||
123 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); | 133 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); |
124 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); | 134 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); |
125 | fprintf(stderr, " -C Enable compression.\n"); | 135 | fprintf(stderr, " -C Enable compression.\n"); |
136 | fprintf(stderr, " -N Do not execute a shell or command.\n"); | ||
126 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); | 137 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); |
127 | fprintf(stderr, " -4 Use IPv4 only.\n"); | 138 | fprintf(stderr, " -4 Use IPv4 only.\n"); |
128 | fprintf(stderr, " -6 Use IPv6 only.\n"); | 139 | fprintf(stderr, " -6 Use IPv6 only.\n"); |
@@ -168,23 +179,22 @@ rsh_connect(char *host, char *user, Buffer * command) | |||
168 | exit(1); | 179 | exit(1); |
169 | } | 180 | } |
170 | 181 | ||
182 | int ssh_session(void); | ||
183 | int ssh_session2(void); | ||
184 | |||
171 | /* | 185 | /* |
172 | * Main program for the ssh client. | 186 | * Main program for the ssh client. |
173 | */ | 187 | */ |
174 | int | 188 | int |
175 | main(int ac, char **av) | 189 | main(int ac, char **av) |
176 | { | 190 | { |
177 | int i, opt, optind, type, exit_status, ok, authfd; | 191 | int i, opt, optind, exit_status, ok; |
178 | u_short fwd_port, fwd_host_port; | 192 | u_short fwd_port, fwd_host_port; |
179 | char *optarg, *cp, buf[256]; | 193 | char *optarg, *cp, buf[256]; |
180 | Buffer command; | ||
181 | struct winsize ws; | ||
182 | struct stat st; | 194 | struct stat st; |
183 | struct passwd *pw, pwcopy; | 195 | struct passwd *pw, pwcopy; |
184 | int interactive = 0, dummy; | 196 | int dummy; |
185 | int have_pty = 0; | ||
186 | uid_t original_effective_uid; | 197 | uid_t original_effective_uid; |
187 | int plen; | ||
188 | 198 | ||
189 | /* | 199 | /* |
190 | * Save the original real uid. It will be needed later (uid-swapping | 200 | * Save the original real uid. It will be needed later (uid-swapping |
@@ -328,7 +338,7 @@ main(int ac, char **av) | |||
328 | case 'V': | 338 | case 'V': |
329 | fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", | 339 | fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", |
330 | SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); | 340 | SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); |
331 | fprintf(stderr, "Compiled with SSL.\n"); | 341 | fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); |
332 | if (opt == 'V') | 342 | if (opt == 'V') |
333 | exit(0); | 343 | exit(0); |
334 | debug_flag = 1; | 344 | debug_flag = 1; |
@@ -397,6 +407,15 @@ main(int ac, char **av) | |||
397 | options.compression = 1; | 407 | options.compression = 1; |
398 | break; | 408 | break; |
399 | 409 | ||
410 | case 'N': | ||
411 | no_shell_flag = 1; | ||
412 | no_tty_flag = 1; | ||
413 | break; | ||
414 | |||
415 | case 'T': | ||
416 | no_tty_flag = 1; | ||
417 | break; | ||
418 | |||
400 | case 'o': | 419 | case 'o': |
401 | dummy = 1; | 420 | dummy = 1; |
402 | if (process_config_line(&options, host ? host : "", optarg, | 421 | if (process_config_line(&options, host ? host : "", optarg, |
@@ -455,6 +474,10 @@ main(int ac, char **av) | |||
455 | fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); | 474 | fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); |
456 | tty_flag = 0; | 475 | tty_flag = 0; |
457 | } | 476 | } |
477 | /* force */ | ||
478 | if (no_tty_flag) | ||
479 | tty_flag = 0; | ||
480 | |||
458 | /* Get user data. */ | 481 | /* Get user data. */ |
459 | pw = getpwuid(original_real_uid); | 482 | pw = getpwuid(original_real_uid); |
460 | if (!pw) { | 483 | if (!pw) { |
@@ -620,6 +643,23 @@ main(int ac, char **av) | |||
620 | if (host_private_key_loaded) | 643 | if (host_private_key_loaded) |
621 | RSA_free(host_private_key); /* Destroys contents safely */ | 644 | RSA_free(host_private_key); /* Destroys contents safely */ |
622 | 645 | ||
646 | exit_status = compat20 ? ssh_session2() : ssh_session(); | ||
647 | packet_close(); | ||
648 | return exit_status; | ||
649 | } | ||
650 | |||
651 | int | ||
652 | ssh_session(void) | ||
653 | { | ||
654 | int type; | ||
655 | int i; | ||
656 | int plen; | ||
657 | int interactive = 0; | ||
658 | int have_tty = 0; | ||
659 | struct winsize ws; | ||
660 | int authfd; | ||
661 | char *cp; | ||
662 | |||
623 | /* Enable compression if requested. */ | 663 | /* Enable compression if requested. */ |
624 | if (options.compression) { | 664 | if (options.compression) { |
625 | debug("Requesting compression at level %d.", options.compression_level); | 665 | debug("Requesting compression at level %d.", options.compression_level); |
@@ -673,7 +713,7 @@ main(int ac, char **av) | |||
673 | type = packet_read(&plen); | 713 | type = packet_read(&plen); |
674 | if (type == SSH_SMSG_SUCCESS) { | 714 | if (type == SSH_SMSG_SUCCESS) { |
675 | interactive = 1; | 715 | interactive = 1; |
676 | have_pty = 1; | 716 | have_tty = 1; |
677 | } else if (type == SSH_SMSG_FAILURE) | 717 | } else if (type == SSH_SMSG_FAILURE) |
678 | log("Warning: Remote host failed or refused to allocate a pseudo tty."); | 718 | log("Warning: Remote host failed or refused to allocate a pseudo tty."); |
679 | else | 719 | else |
@@ -802,11 +842,103 @@ main(int ac, char **av) | |||
802 | } | 842 | } |
803 | 843 | ||
804 | /* Enter the interactive session. */ | 844 | /* Enter the interactive session. */ |
805 | exit_status = client_loop(have_pty, tty_flag ? options.escape_char : -1); | 845 | return client_loop(have_tty, tty_flag ? options.escape_char : -1); |
846 | } | ||
806 | 847 | ||
807 | /* Close the connection to the remote host. */ | 848 | void |
808 | packet_close(); | 849 | init_local_fwd(void) |
850 | { | ||
851 | int i; | ||
852 | /* Initiate local TCP/IP port forwardings. */ | ||
853 | for (i = 0; i < options.num_local_forwards; i++) { | ||
854 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | ||
855 | options.local_forwards[i].port, | ||
856 | options.local_forwards[i].host, | ||
857 | options.local_forwards[i].host_port); | ||
858 | channel_request_local_forwarding(options.local_forwards[i].port, | ||
859 | options.local_forwards[i].host, | ||
860 | options.local_forwards[i].host_port, | ||
861 | options.gateway_ports); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | extern void client_set_session_ident(int id); | ||
866 | |||
867 | void | ||
868 | client_init(int id, void *arg) | ||
869 | { | ||
870 | int len; | ||
871 | debug("client_init id %d arg %d", id, (int)arg); | ||
872 | |||
873 | if (no_shell_flag) | ||
874 | goto done; | ||
875 | |||
876 | if (tty_flag) { | ||
877 | struct winsize ws; | ||
878 | char *cp; | ||
879 | cp = getenv("TERM"); | ||
880 | if (!cp) | ||
881 | cp = ""; | ||
882 | /* Store window size in the packet. */ | ||
883 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) | ||
884 | memset(&ws, 0, sizeof(ws)); | ||
885 | |||
886 | channel_request_start(id, "pty-req", 0); | ||
887 | packet_put_cstring(cp); | ||
888 | packet_put_int(ws.ws_col); | ||
889 | packet_put_int(ws.ws_row); | ||
890 | packet_put_int(ws.ws_xpixel); | ||
891 | packet_put_int(ws.ws_ypixel); | ||
892 | packet_put_cstring(""); /* XXX: encode terminal modes */ | ||
893 | packet_send(); | ||
894 | /* XXX wait for reply */ | ||
895 | } | ||
896 | len = buffer_len(&command); | ||
897 | if (len > 0) { | ||
898 | if (len > 900) | ||
899 | len = 900; | ||
900 | debug("Sending command: %.*s", len, buffer_ptr(&command)); | ||
901 | channel_request_start(id, "exec", 0); | ||
902 | packet_put_string(buffer_ptr(&command), len); | ||
903 | packet_send(); | ||
904 | } else { | ||
905 | channel_request(id, "shell", 0); | ||
906 | } | ||
907 | /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ | ||
908 | done: | ||
909 | /* register different callback, etc. XXX */ | ||
910 | client_set_session_ident(id); | ||
911 | } | ||
912 | |||
913 | int | ||
914 | ssh_session2(void) | ||
915 | { | ||
916 | int window, packetmax, id; | ||
917 | int in = dup(STDIN_FILENO); | ||
918 | int out = dup(STDOUT_FILENO); | ||
919 | int err = dup(STDERR_FILENO); | ||
920 | |||
921 | if (in < 0 || out < 0 || err < 0) | ||
922 | fatal("dump in/out/err failed"); | ||
923 | |||
924 | /* should be pre-session */ | ||
925 | init_local_fwd(); | ||
926 | |||
927 | window = 32*1024; | ||
928 | if (tty_flag) { | ||
929 | packetmax = window/8; | ||
930 | } else { | ||
931 | window *= 2; | ||
932 | packetmax = window/2; | ||
933 | } | ||
934 | |||
935 | id = channel_new( | ||
936 | "session", SSH_CHANNEL_OPENING, in, out, err, | ||
937 | window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); | ||
938 | |||
939 | |||
940 | channel_open(id); | ||
941 | channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); | ||
809 | 942 | ||
810 | /* Exit with the status returned by the program on the remote side. */ | 943 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1); |
811 | exit(exit_status); | ||
812 | } | 944 | } |