diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 193 |
1 files changed, 106 insertions, 87 deletions
@@ -39,11 +39,12 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.69 2000/10/27 07:32:19 markus Exp $"); | 42 | RCSID("$OpenBSD: ssh.c,v 1.72 2000/11/12 19:50:38 markus Exp $"); |
43 | 43 | ||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include <openssl/dsa.h> | 45 | #include <openssl/dsa.h> |
46 | #include <openssl/rsa.h> | 46 | #include <openssl/rsa.h> |
47 | #include <openssl/err.h> | ||
47 | 48 | ||
48 | #include "xmalloc.h" | 49 | #include "xmalloc.h" |
49 | #include "ssh.h" | 50 | #include "ssh.h" |
@@ -218,8 +219,9 @@ rsh_connect(char *host, char *user, Buffer * command) | |||
218 | exit(1); | 219 | exit(1); |
219 | } | 220 | } |
220 | 221 | ||
221 | int ssh_session(void); | 222 | int ssh_session(void); |
222 | int ssh_session2(void); | 223 | int ssh_session2(void); |
224 | int guess_identity_file_type(const char *filename); | ||
223 | 225 | ||
224 | /* | 226 | /* |
225 | * Main program for the ssh client. | 227 | * Main program for the ssh client. |
@@ -370,14 +372,13 @@ main(int ac, char **av) | |||
370 | case 'i': | 372 | case 'i': |
371 | if (stat(optarg, &st) < 0) { | 373 | if (stat(optarg, &st) < 0) { |
372 | fprintf(stderr, "Warning: Identity file %s does not exist.\n", | 374 | fprintf(stderr, "Warning: Identity file %s does not exist.\n", |
373 | optarg); | 375 | optarg); |
374 | break; | 376 | break; |
375 | } | 377 | } |
376 | if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) | 378 | if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) |
377 | fatal("Too many identity files specified (max %d)", | 379 | fatal("Too many identity files specified (max %d)", |
378 | SSH_MAX_IDENTITY_FILES); | 380 | SSH_MAX_IDENTITY_FILES); |
379 | options.identity_files[options.num_identity_files++] = | 381 | options.identity_files[options.num_identity_files++] = xstrdup(optarg); |
380 | xstrdup(optarg); | ||
381 | break; | 382 | break; |
382 | case 't': | 383 | case 't': |
383 | tty_flag = 1; | 384 | tty_flag = 1; |
@@ -487,6 +488,7 @@ main(int ac, char **av) | |||
487 | usage(); | 488 | usage(); |
488 | 489 | ||
489 | SSLeay_add_all_algorithms(); | 490 | SSLeay_add_all_algorithms(); |
491 | ERR_load_crypto_strings(); | ||
490 | 492 | ||
491 | /* Initialize the command to execute on remote host. */ | 493 | /* Initialize the command to execute on remote host. */ |
492 | buffer_init(&command); | 494 | buffer_init(&command); |
@@ -563,20 +565,6 @@ main(int ac, char **av) | |||
563 | /* reinit */ | 565 | /* reinit */ |
564 | log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); | 566 | log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); |
565 | 567 | ||
566 | /* check if RSA support exists */ | ||
567 | if ((options.protocol & SSH_PROTO_1) && | ||
568 | rsa_alive() == 0) { | ||
569 | log("%s: no RSA support in libssl and libcrypto. See ssl(8).", | ||
570 | __progname); | ||
571 | log("Disabling protocol version 1"); | ||
572 | options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED); | ||
573 | } | ||
574 | if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { | ||
575 | fprintf(stderr, "%s: No protocol version available.\n", | ||
576 | __progname); | ||
577 | exit(1); | ||
578 | } | ||
579 | |||
580 | if (options.user == NULL) | 568 | if (options.user == NULL) |
581 | options.user = xstrdup(pw->pw_name); | 569 | options.user = xstrdup(pw->pw_name); |
582 | 570 | ||
@@ -589,6 +577,8 @@ main(int ac, char **av) | |||
589 | if (!options.use_privileged_port) { | 577 | if (!options.use_privileged_port) { |
590 | #else | 578 | #else |
591 | if (original_effective_uid != 0 || !options.use_privileged_port) { | 579 | if (original_effective_uid != 0 || !options.use_privileged_port) { |
580 | debug("Rhosts Authentication methods disabled, " | ||
581 | "originating port will not be trusted."); | ||
592 | #endif | 582 | #endif |
593 | options.rhosts_authentication = 0; | 583 | options.rhosts_authentication = 0; |
594 | options.rhosts_rsa_authentication = 0; | 584 | options.rhosts_rsa_authentication = 0; |
@@ -635,7 +625,7 @@ main(int ac, char **av) | |||
635 | if (ok && (options.protocol & SSH_PROTO_1)) { | 625 | if (ok && (options.protocol & SSH_PROTO_1)) { |
636 | Key k; | 626 | Key k; |
637 | host_private_key = RSA_new(); | 627 | host_private_key = RSA_new(); |
638 | k.type = KEY_RSA; | 628 | k.type = KEY_RSA1; |
639 | k.rsa = host_private_key; | 629 | k.rsa = host_private_key; |
640 | if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) | 630 | if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) |
641 | host_private_key_loaded = 1; | 631 | host_private_key_loaded = 1; |
@@ -682,23 +672,23 @@ main(int ac, char **av) | |||
682 | } | 672 | } |
683 | exit(1); | 673 | exit(1); |
684 | } | 674 | } |
685 | /* Expand ~ in options.identity_files. */ | 675 | /* Expand ~ in options.identity_files, known host file names. */ |
686 | /* XXX mem-leaks */ | 676 | /* XXX mem-leaks */ |
687 | for (i = 0; i < options.num_identity_files; i++) | 677 | for (i = 0; i < options.num_identity_files; i++) { |
688 | options.identity_files[i] = | 678 | options.identity_files[i] = |
689 | tilde_expand_filename(options.identity_files[i], original_real_uid); | 679 | tilde_expand_filename(options.identity_files[i], original_real_uid); |
690 | for (i = 0; i < options.num_identity_files2; i++) | 680 | options.identity_files_type[i] = guess_identity_file_type(options.identity_files[i]); |
691 | options.identity_files2[i] = | 681 | debug("identity file %s type %d", options.identity_files[i], |
692 | tilde_expand_filename(options.identity_files2[i], original_real_uid); | 682 | options.identity_files_type[i]); |
693 | /* Expand ~ in known host file names. */ | 683 | } |
694 | options.system_hostfile = tilde_expand_filename(options.system_hostfile, | 684 | options.system_hostfile = |
695 | original_real_uid); | 685 | tilde_expand_filename(options.system_hostfile, original_real_uid); |
696 | options.user_hostfile = tilde_expand_filename(options.user_hostfile, | 686 | options.user_hostfile = |
697 | original_real_uid); | 687 | tilde_expand_filename(options.user_hostfile, original_real_uid); |
698 | options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, | 688 | options.system_hostfile2 = |
699 | original_real_uid); | 689 | tilde_expand_filename(options.system_hostfile2, original_real_uid); |
700 | options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, | 690 | options.user_hostfile2 = |
701 | original_real_uid); | 691 | tilde_expand_filename(options.user_hostfile2, original_real_uid); |
702 | 692 | ||
703 | /* Log into the remote system. This never returns if the login fails. */ | 693 | /* Log into the remote system. This never returns if the login fails. */ |
704 | ssh_login(host_private_key_loaded, host_private_key, | 694 | ssh_login(host_private_key_loaded, host_private_key, |
@@ -752,16 +742,57 @@ x11_get_proto(char *proto, int proto_len, char *data, int data_len) | |||
752 | } | 742 | } |
753 | } | 743 | } |
754 | 744 | ||
745 | void | ||
746 | ssh_init_forwarding(void) | ||
747 | { | ||
748 | int i; | ||
749 | /* Initiate local TCP/IP port forwardings. */ | ||
750 | for (i = 0; i < options.num_local_forwards; i++) { | ||
751 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | ||
752 | options.local_forwards[i].port, | ||
753 | options.local_forwards[i].host, | ||
754 | options.local_forwards[i].host_port); | ||
755 | channel_request_local_forwarding( | ||
756 | options.local_forwards[i].port, | ||
757 | options.local_forwards[i].host, | ||
758 | options.local_forwards[i].host_port, | ||
759 | options.gateway_ports); | ||
760 | } | ||
761 | |||
762 | /* Initiate remote TCP/IP port forwardings. */ | ||
763 | for (i = 0; i < options.num_remote_forwards; i++) { | ||
764 | debug("Connections to remote port %d forwarded to local address %.200s:%d", | ||
765 | options.remote_forwards[i].port, | ||
766 | options.remote_forwards[i].host, | ||
767 | options.remote_forwards[i].host_port); | ||
768 | channel_request_remote_forwarding( | ||
769 | options.remote_forwards[i].port, | ||
770 | options.remote_forwards[i].host, | ||
771 | options.remote_forwards[i].host_port); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | void | ||
776 | check_agent_present(void) | ||
777 | { | ||
778 | if (options.forward_agent) { | ||
779 | /* Clear agent forwarding if we don\'t have an agent. */ | ||
780 | int authfd = ssh_get_authentication_socket(); | ||
781 | if (authfd < 0) | ||
782 | options.forward_agent = 0; | ||
783 | else | ||
784 | ssh_close_authentication_socket(authfd); | ||
785 | } | ||
786 | } | ||
787 | |||
755 | int | 788 | int |
756 | ssh_session(void) | 789 | ssh_session(void) |
757 | { | 790 | { |
758 | int type; | 791 | int type; |
759 | int i; | ||
760 | int plen; | 792 | int plen; |
761 | int interactive = 0; | 793 | int interactive = 0; |
762 | int have_tty = 0; | 794 | int have_tty = 0; |
763 | struct winsize ws; | 795 | struct winsize ws; |
764 | int authfd; | ||
765 | char *cp; | 796 | char *cp; |
766 | 797 | ||
767 | /* Enable compression if requested. */ | 798 | /* Enable compression if requested. */ |
@@ -845,14 +876,10 @@ ssh_session(void) | |||
845 | /* Tell the packet module whether this is an interactive session. */ | 876 | /* Tell the packet module whether this is an interactive session. */ |
846 | packet_set_interactive(interactive, options.keepalives); | 877 | packet_set_interactive(interactive, options.keepalives); |
847 | 878 | ||
848 | /* Clear agent forwarding if we don\'t have an agent. */ | ||
849 | authfd = ssh_get_authentication_socket(); | ||
850 | if (authfd < 0) | ||
851 | options.forward_agent = 0; | ||
852 | else | ||
853 | ssh_close_authentication_socket(authfd); | ||
854 | 879 | ||
855 | /* Request authentication agent forwarding if appropriate. */ | 880 | /* Request authentication agent forwarding if appropriate. */ |
881 | check_agent_present(); | ||
882 | |||
856 | if (options.forward_agent) { | 883 | if (options.forward_agent) { |
857 | debug("Requesting authentication agent forwarding."); | 884 | debug("Requesting authentication agent forwarding."); |
858 | auth_request_forwarding(); | 885 | auth_request_forwarding(); |
@@ -863,28 +890,9 @@ ssh_session(void) | |||
863 | if (type != SSH_SMSG_SUCCESS) | 890 | if (type != SSH_SMSG_SUCCESS) |
864 | log("Warning: Remote host denied authentication agent forwarding."); | 891 | log("Warning: Remote host denied authentication agent forwarding."); |
865 | } | 892 | } |
866 | /* Initiate local TCP/IP port forwardings. */ | ||
867 | for (i = 0; i < options.num_local_forwards; i++) { | ||
868 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | ||
869 | options.local_forwards[i].port, | ||
870 | options.local_forwards[i].host, | ||
871 | options.local_forwards[i].host_port); | ||
872 | channel_request_local_forwarding(options.local_forwards[i].port, | ||
873 | options.local_forwards[i].host, | ||
874 | options.local_forwards[i].host_port, | ||
875 | options.gateway_ports); | ||
876 | } | ||
877 | 893 | ||
878 | /* Initiate remote TCP/IP port forwardings. */ | 894 | /* Initiate port forwardings. */ |
879 | for (i = 0; i < options.num_remote_forwards; i++) { | 895 | ssh_init_forwarding(); |
880 | debug("Connections to remote port %d forwarded to local address %.200s:%d", | ||
881 | options.remote_forwards[i].port, | ||
882 | options.remote_forwards[i].host, | ||
883 | options.remote_forwards[i].host_port); | ||
884 | channel_request_remote_forwarding(options.remote_forwards[i].port, | ||
885 | options.remote_forwards[i].host, | ||
886 | options.remote_forwards[i].host_port); | ||
887 | } | ||
888 | 896 | ||
889 | /* If requested, let ssh continue in the background. */ | 897 | /* If requested, let ssh continue in the background. */ |
890 | if (fork_after_authentication_flag) | 898 | if (fork_after_authentication_flag) |
@@ -915,27 +923,10 @@ ssh_session(void) | |||
915 | return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); | 923 | return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); |
916 | } | 924 | } |
917 | 925 | ||
918 | void | ||
919 | init_local_fwd(void) | ||
920 | { | ||
921 | int i; | ||
922 | /* Initiate local TCP/IP port forwardings. */ | ||
923 | for (i = 0; i < options.num_local_forwards; i++) { | ||
924 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | ||
925 | options.local_forwards[i].port, | ||
926 | options.local_forwards[i].host, | ||
927 | options.local_forwards[i].host_port); | ||
928 | channel_request_local_forwarding(options.local_forwards[i].port, | ||
929 | options.local_forwards[i].host, | ||
930 | options.local_forwards[i].host_port, | ||
931 | options.gateway_ports); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | extern void client_set_session_ident(int id); | 926 | extern void client_set_session_ident(int id); |
936 | 927 | ||
937 | void | 928 | void |
938 | client_init(int id, void *arg) | 929 | ssh_session2_callback(int id, void *arg) |
939 | { | 930 | { |
940 | int len; | 931 | int len; |
941 | debug("client_init id %d arg %d", id, (int)arg); | 932 | debug("client_init id %d arg %d", id, (int)arg); |
@@ -974,6 +965,13 @@ client_init(int id, void *arg) | |||
974 | /* XXX wait for reply */ | 965 | /* XXX wait for reply */ |
975 | } | 966 | } |
976 | 967 | ||
968 | check_agent_present(); | ||
969 | if (options.forward_agent) { | ||
970 | debug("Requesting authentication agent forwarding."); | ||
971 | channel_request_start(id, "auth-agent-req@openssh.com", 0); | ||
972 | packet_send(); | ||
973 | } | ||
974 | |||
977 | len = buffer_len(&command); | 975 | len = buffer_len(&command); |
978 | if (len > 0) { | 976 | if (len > 0) { |
979 | if (len > 900) | 977 | if (len > 900) |
@@ -1016,8 +1014,8 @@ ssh_session2(void) | |||
1016 | if (!isatty(err)) | 1014 | if (!isatty(err)) |
1017 | set_nonblock(err); | 1015 | set_nonblock(err); |
1018 | 1016 | ||
1019 | /* should be pre-session */ | 1017 | /* XXX should be pre-session */ |
1020 | init_local_fwd(); | 1018 | ssh_init_forwarding(); |
1021 | 1019 | ||
1022 | /* If requested, let ssh continue in the background. */ | 1020 | /* If requested, let ssh continue in the background. */ |
1023 | if (fork_after_authentication_flag) | 1021 | if (fork_after_authentication_flag) |
@@ -1036,7 +1034,28 @@ ssh_session2(void) | |||
1036 | xstrdup("client-session"), /*nonblock*/0); | 1034 | xstrdup("client-session"), /*nonblock*/0); |
1037 | 1035 | ||
1038 | channel_open(id); | 1036 | channel_open(id); |
1039 | channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); | 1037 | channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, |
1038 | ssh_session2_callback, (void *)0); | ||
1040 | 1039 | ||
1041 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); | 1040 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); |
1042 | } | 1041 | } |
1042 | |||
1043 | int | ||
1044 | guess_identity_file_type(const char *filename) | ||
1045 | { | ||
1046 | struct stat st; | ||
1047 | Key *public; | ||
1048 | int type = KEY_RSA1; /* default */ | ||
1049 | |||
1050 | if (stat(filename, &st) < 0) { | ||
1051 | perror(filename); | ||
1052 | return KEY_UNSPEC; | ||
1053 | } | ||
1054 | public = key_new(type); | ||
1055 | if (!load_public_key(filename, public, NULL)) { | ||
1056 | /* ok, so we will assume this is 'some' key */ | ||
1057 | type = KEY_UNSPEC; | ||
1058 | } | ||
1059 | key_free(public); | ||
1060 | return type; | ||
1061 | } | ||