summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--auth-krb4.c113
-rw-r--r--auth-passwd.c133
-rw-r--r--auth-rsa.c14
-rw-r--r--auth-skey.c33
-rw-r--r--channels.c24
-rw-r--r--hostfile.c8
-rw-r--r--nchan.c20
-rw-r--r--packet.c11
-rw-r--r--readconf.c19
-rw-r--r--readconf.h16
-rw-r--r--serverloop.c2
-rw-r--r--ssh-add.17
-rw-r--r--ssh-add.c10
-rw-r--r--ssh.15
-rw-r--r--ssh.c16
-rw-r--r--ssh.h21
-rw-r--r--sshconnect.c185
18 files changed, 383 insertions, 278 deletions
diff --git a/ChangeLog b/ChangeLog
index 69b5688d3..dc16db037 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
119991204 119991204
2 - Small cleanup of PAM code in sshd.c 2 - Small cleanup of PAM code in sshd.c
3 - Merged OpenBSD CVS changes:
4 - [auth-krb4.c auth-passwd.c auth-skey.c ssh.h]
5 move skey-auth from auth-passwd.c to auth-skey.c, same for krb4
6 - [auth-rsa.c]
7 warn only about mismatch if key is _used_
8 warn about keysize-mismatch with log() not error()
9 channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c
10 ports are u_short
11 - [hostfile.c]
12 indent, shorter warning
13 - [nchan.c]
14 use error() for internal errors
15 - [packet.c]
16 set loglevel for SSH_MSG_DISCONNECT to log(), not fatal()
17 serverloop.c
18 indent
19 - [ssh-add.1 ssh-add.c ssh.h]
20 document $SSH_ASKPASS, reasonable default
21 - [ssh.1]
22 CheckHostIP is not available for connects via proxy command
23 - [sshconnect.c]
24 typo
25 easier to read client code for passwd and skey auth
26 turn of checkhostip for proxy connects, since we don't know the remote ip
3 27
419991126 2819991126
5 - Add definition for __P() 29 - Add definition for __P()
diff --git a/auth-krb4.c b/auth-krb4.c
index 9f99533b1..fb0e20ce2 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -7,10 +7,123 @@
7#include "packet.h" 7#include "packet.h"
8#include "xmalloc.h" 8#include "xmalloc.h"
9#include "ssh.h" 9#include "ssh.h"
10#include "servconf.h"
10 11
11#ifdef KRB4 12#ifdef KRB4
12char *ticket = NULL; 13char *ticket = NULL;
13 14
15extern ServerOptions options;
16
17/*
18 * try krb4 authentication,
19 * return 1 on success, 0 on failure, -1 if krb4 is not available
20 */
21
22int
23auth_krb4_password(struct passwd * pw, const char *password)
24{
25 AUTH_DAT adata;
26 KTEXT_ST tkt;
27 struct hostent *hp;
28 unsigned long faddr;
29 char localhost[MAXHOSTNAMELEN];
30 char phost[INST_SZ];
31 char realm[REALM_SZ];
32 int r;
33
34 /*
35 * Try Kerberos password authentication only for non-root
36 * users and only if Kerberos is installed.
37 */
38 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
39
40 /* Set up our ticket file. */
41 if (!krb4_init(pw->pw_uid)) {
42 log("Couldn't initialize Kerberos ticket file for %s!",
43 pw->pw_name);
44 goto kerberos_auth_failure;
45 }
46 /* Try to get TGT using our password. */
47 r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
48 realm, "krbtgt", realm,
49 DEFAULT_TKT_LIFE, (char *) password);
50 if (r != INTK_OK) {
51 packet_send_debug("Kerberos V4 password "
52 "authentication for %s failed: %s",
53 pw->pw_name, krb_err_txt[r]);
54 goto kerberos_auth_failure;
55 }
56 /* Successful authentication. */
57 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
58
59 /*
60 * Now that we have a TGT, try to get a local
61 * "rcmd" ticket to ensure that we are not talking
62 * to a bogus Kerberos server.
63 */
64 (void) gethostname(localhost, sizeof(localhost));
65 (void) strlcpy(phost, (char *) krb_get_phost(localhost),
66 INST_SZ);
67 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
68
69 if (r == KSUCCESS) {
70 if (!(hp = gethostbyname(localhost))) {
71 log("Couldn't get local host address!");
72 goto kerberos_auth_failure;
73 }
74 memmove((void *) &faddr, (void *) hp->h_addr,
75 sizeof(faddr));
76
77 /* Verify our "rcmd" ticket. */
78 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
79 faddr, &adata, "");
80 if (r == RD_AP_UNDEC) {
81 /*
82 * Probably didn't have a srvtab on
83 * localhost. Allow login.
84 */
85 log("Kerberos V4 TGT for %s unverifiable, "
86 "no srvtab installed? krb_rd_req: %s",
87 pw->pw_name, krb_err_txt[r]);
88 } else if (r != KSUCCESS) {
89 log("Kerberos V4 %s ticket unverifiable: %s",
90 KRB4_SERVICE_NAME, krb_err_txt[r]);
91 goto kerberos_auth_failure;
92 }
93 } else if (r == KDC_PR_UNKNOWN) {
94 /*
95 * Allow login if no rcmd service exists, but
96 * log the error.
97 */
98 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
99 "not registered, or srvtab is wrong?", pw->pw_name,
100 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
101 } else {
102 /*
103 * TGT is bad, forget it. Possibly spoofed!
104 */
105 packet_send_debug("WARNING: Kerberos V4 TGT "
106 "possibly spoofed for %s: %s",
107 pw->pw_name, krb_err_txt[r]);
108 goto kerberos_auth_failure;
109 }
110
111 /* Authentication succeeded. */
112 return 1;
113
114kerberos_auth_failure:
115 krb4_cleanup_proc(NULL);
116
117 if (!options.kerberos_or_local_passwd)
118 return 0;
119 } else {
120 /* Logging in as root or no local Kerberos realm. */
121 packet_send_debug("Unable to authenticate to Kerberos.");
122 }
123 /* Fall back to ordinary passwd authentication. */
124 return -1;
125}
126
14void 127void
15krb4_cleanup_proc(void *ignore) 128krb4_cleanup_proc(void *ignore)
16{ 129{
diff --git a/auth-passwd.c b/auth-passwd.c
index e5574ffbe..efae0fd2b 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -11,7 +11,7 @@
11 11
12#ifndef HAVE_PAM 12#ifndef HAVE_PAM
13 13
14RCSID("$Id: auth-passwd.c,v 1.7 1999/11/25 00:54:57 damien Exp $"); 14RCSID("$Id: auth-passwd.c,v 1.8 1999/12/06 00:47:28 damien Exp $");
15 15
16#include "packet.h" 16#include "packet.h"
17#include "ssh.h" 17#include "ssh.h"
@@ -49,133 +49,20 @@ auth_password(struct passwd * pw, const char *password)
49 49
50#ifdef SKEY 50#ifdef SKEY
51 if (options.skey_authentication == 1) { 51 if (options.skey_authentication == 1) {
52 if (strncasecmp(password, "s/key", 5) == 0) { 52 int ret = auth_skey_password(pw, password);
53 char *skeyinfo = skey_keyinfo(pw->pw_name); 53 if (ret == 1 || ret == 0)
54 if (skeyinfo == NULL) { 54 return ret;
55 debug("generating fake skeyinfo for %.100s.",
56 pw->pw_name);
57 skeyinfo = skey_fake_keyinfo(pw->pw_name);
58 }
59 if (skeyinfo != NULL)
60 packet_send_debug(skeyinfo);
61 /* Try again. */
62 return 0;
63 } else if (skey_haskey(pw->pw_name) == 0 &&
64 skey_passcheck(pw->pw_name, (char *) password) != -1) {
65 /* Authentication succeeded. */
66 return 1;
67 }
68 /* Fall back to ordinary passwd authentication. */ 55 /* Fall back to ordinary passwd authentication. */
69 } 56 }
70#endif 57#endif
71 58#ifdef KRB4
72#if defined(KRB4) 59 if (options.kerberos_authentication == 1) {
73 /* 60 int ret = auth_krb4_password(pw, password);
74 * Support for Kerberos v4 authentication 61 if (ret == 1 || ret == 0)
75 * - Dug Song <dugsong@UMICH.EDU> 62 return ret;
76 */
77 if (options.kerberos_authentication) {
78 AUTH_DAT adata;
79 KTEXT_ST tkt;
80 struct hostent *hp;
81 unsigned long faddr;
82 char localhost[MAXHOSTNAMELEN];
83 char phost[INST_SZ];
84 char realm[REALM_SZ];
85 int r;
86
87 /*
88 * Try Kerberos password authentication only for non-root
89 * users and only if Kerberos is installed.
90 */
91 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
92
93 /* Set up our ticket file. */
94 if (!krb4_init(pw->pw_uid)) {
95 log("Couldn't initialize Kerberos ticket file for %s!",
96 pw->pw_name);
97 goto kerberos_auth_failure;
98 }
99 /* Try to get TGT using our password. */
100 r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
101 realm, "krbtgt", realm,
102 DEFAULT_TKT_LIFE, (char *) password);
103 if (r != INTK_OK) {
104 packet_send_debug("Kerberos V4 password "
105 "authentication for %s failed: %s",
106 pw->pw_name, krb_err_txt[r]);
107 goto kerberos_auth_failure;
108 }
109 /* Successful authentication. */
110 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
111
112 /*
113 * Now that we have a TGT, try to get a local
114 * "rcmd" ticket to ensure that we are not talking
115 * to a bogus Kerberos server.
116 */
117 (void) gethostname(localhost, sizeof(localhost));
118 (void) strlcpy(phost, (char *) krb_get_phost(localhost),
119 INST_SZ);
120 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
121
122 if (r == KSUCCESS) {
123 if (!(hp = gethostbyname(localhost))) {
124 log("Couldn't get local host address!");
125 goto kerberos_auth_failure;
126 }
127 memmove((void *) &faddr, (void *) hp->h_addr,
128 sizeof(faddr));
129
130 /* Verify our "rcmd" ticket. */
131 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
132 faddr, &adata, "");
133 if (r == RD_AP_UNDEC) {
134 /*
135 * Probably didn't have a srvtab on
136 * localhost. Allow login.
137 */
138 log("Kerberos V4 TGT for %s unverifiable, "
139 "no srvtab installed? krb_rd_req: %s",
140 pw->pw_name, krb_err_txt[r]);
141 } else if (r != KSUCCESS) {
142 log("Kerberos V4 %s ticket unverifiable: %s",
143 KRB4_SERVICE_NAME, krb_err_txt[r]);
144 goto kerberos_auth_failure;
145 }
146 } else if (r == KDC_PR_UNKNOWN) {
147 /*
148 * Allow login if no rcmd service exists, but
149 * log the error.
150 */
151 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
152 "not registered, or srvtab is wrong?", pw->pw_name,
153 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
154 } else {
155 /*
156 * TGT is bad, forget it. Possibly spoofed!
157 */
158 packet_send_debug("WARNING: Kerberos V4 TGT "
159 "possibly spoofed for %s: %s",
160 pw->pw_name, krb_err_txt[r]);
161 goto kerberos_auth_failure;
162 }
163
164 /* Authentication succeeded. */
165 return 1;
166
167 kerberos_auth_failure:
168 krb4_cleanup_proc(NULL);
169
170 if (!options.kerberos_or_local_passwd)
171 return 0;
172 } else {
173 /* Logging in as root or no local Kerberos realm. */
174 packet_send_debug("Unable to authenticate to Kerberos.");
175 }
176 /* Fall back to ordinary passwd authentication. */ 63 /* Fall back to ordinary passwd authentication. */
177 } 64 }
178#endif /* KRB4 */ 65#endif
179 66
180 /* Check for users with no password. */ 67 /* Check for users with no password. */
181 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) 68 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
diff --git a/auth-rsa.c b/auth-rsa.c
index 88dc2e76c..bc53b049b 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rsa.c,v 1.10 1999/11/25 00:54:57 damien Exp $"); 19RCSID("$Id: auth-rsa.c,v 1.11 1999/12/06 00:47:28 damien Exp $");
20 20
21#include "rsa.h" 21#include "rsa.h"
22#include "packet.h" 22#include "packet.h"
@@ -259,16 +259,16 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
259 } 259 }
260 /* cp now points to the comment part. */ 260 /* cp now points to the comment part. */
261 261
262 /* check the real bits */
263 if (bits != BN_num_bits(n))
264 error("Warning: error in %s, line %ld: keysize mismatch: "
265 "actual size %d vs. announced %d.",
266 file, linenum, BN_num_bits(n), bits);
267
268 /* Check if the we have found the desired key (identified by its modulus). */ 262 /* Check if the we have found the desired key (identified by its modulus). */
269 if (BN_cmp(n, client_n) != 0) 263 if (BN_cmp(n, client_n) != 0)
270 continue; 264 continue;
271 265
266 /* check the real bits */
267 if (bits != BN_num_bits(n))
268 log("Warning: %s, line %ld: keysize mismatch: "
269 "actual %d vs. announced %d.",
270 file, linenum, BN_num_bits(n), bits);
271
272 /* We have found the desired key. */ 272 /* We have found the desired key. */
273 273
274 /* Perform the challenge-response dialog for this key. */ 274 /* Perform the challenge-response dialog for this key. */
diff --git a/auth-skey.c b/auth-skey.c
index a0d786cb2..cc5f45101 100644
--- a/auth-skey.c
+++ b/auth-skey.c
@@ -1,9 +1,11 @@
1#include "includes.h" 1#include "includes.h"
2 2
3#ifdef SKEY 3#ifdef SKEY
4RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $"); 4RCSID("$Id: auth-skey.c,v 1.4 1999/12/01 16:54:35 markus Exp $");
5 5
6#include "ssh.h" 6#include "ssh.h"
7#include "packet.h"
8
7#ifdef HAVE_OPENSSL 9#ifdef HAVE_OPENSSL
8#include <openssl/sha1.h> 10#include <openssl/sha1.h>
9#endif 11#endif
@@ -13,6 +15,35 @@ RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $");
13 15
14/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ 16/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
15 17
18/*
19 * try skey authentication,
20 * return 1 on success, 0 on failure, -1 if skey is not available
21 */
22
23int
24auth_skey_password(struct passwd * pw, const char *password)
25{
26 if (strncasecmp(password, "s/key", 5) == 0) {
27 char *skeyinfo = skey_keyinfo(pw->pw_name);
28 if (skeyinfo == NULL) {
29 debug("generating fake skeyinfo for %.100s.",
30 pw->pw_name);
31 skeyinfo = skey_fake_keyinfo(pw->pw_name);
32 }
33 if (skeyinfo != NULL)
34 packet_send_debug(skeyinfo);
35 /* Try again. */
36 return 0;
37 } else if (skey_haskey(pw->pw_name) == 0 &&
38 skey_passcheck(pw->pw_name, (char *) password) != -1) {
39 /* Authentication succeeded. */
40 return 1;
41 }
42 /* Fall back to ordinary passwd authentication. */
43 return -1;
44}
45
46+ /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
16 47
17#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ 48#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
18 ((x)[3])) 49 ((x)[3]))
diff --git a/channels.c b/channels.c
index 61ba76dec..013823659 100644
--- a/channels.c
+++ b/channels.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: channels.c,v 1.8 1999/11/25 00:54:58 damien Exp $"); 19RCSID("$Id: channels.c,v 1.9 1999/12/06 00:47:29 damien Exp $");
20 20
21#include "ssh.h" 21#include "ssh.h"
22#include "packet.h" 22#include "packet.h"
@@ -82,7 +82,7 @@ unsigned int x11_fake_data_len;
82 */ 82 */
83typedef struct { 83typedef struct {
84 char *host; /* Host name. */ 84 char *host; /* Host name. */
85 int port; /* Port number. */ 85 u_short port; /* Port number. */
86} ForwardPermission; 86} ForwardPermission;
87 87
88/* List of all permitted host/port pairs to connect. */ 88/* List of all permitted host/port pairs to connect. */
@@ -876,8 +876,8 @@ channel_open_message()
876 */ 876 */
877 877
878void 878void
879channel_request_local_forwarding(int port, const char *host, 879channel_request_local_forwarding(u_short port, const char *host,
880 int host_port) 880 u_short host_port)
881{ 881{
882 int ch, sock, on = 1; 882 int ch, sock, on = 1;
883 struct sockaddr_in sin; 883 struct sockaddr_in sin;
@@ -932,8 +932,8 @@ channel_request_local_forwarding(int port, const char *host,
932 */ 932 */
933 933
934void 934void
935channel_request_remote_forwarding(int port, const char *host, 935channel_request_remote_forwarding(u_short port, const char *host,
936 int remote_port) 936 u_short remote_port)
937{ 937{
938 int payload_len; 938 int payload_len;
939 /* Record locally that connection to this host/port is permitted. */ 939 /* Record locally that connection to this host/port is permitted. */
@@ -968,7 +968,7 @@ channel_request_remote_forwarding(int port, const char *host,
968void 968void
969channel_input_port_forward_request(int is_root) 969channel_input_port_forward_request(int is_root)
970{ 970{
971 int port, host_port; 971 u_short port, host_port;
972 char *hostname; 972 char *hostname;
973 973
974 /* Get arguments from the packet. */ 974 /* Get arguments from the packet. */
@@ -976,10 +976,6 @@ channel_input_port_forward_request(int is_root)
976 hostname = packet_get_string(NULL); 976 hostname = packet_get_string(NULL);
977 host_port = packet_get_int(); 977 host_port = packet_get_int();
978 978
979 /* Port numbers are 16 bit quantities. */
980 if ((port & 0xffff) != port)
981 packet_disconnect("Requested forwarding of nonexistent port %d.", port);
982
983 /* 979 /*
984 * Check that an unprivileged user is not trying to forward a 980 * Check that an unprivileged user is not trying to forward a
985 * privileged port. 981 * privileged port.
@@ -1004,7 +1000,8 @@ channel_input_port_forward_request(int is_root)
1004void 1000void
1005channel_input_port_open(int payload_len) 1001channel_input_port_open(int payload_len)
1006{ 1002{
1007 int remote_channel, sock, newch, host_port, i; 1003 int remote_channel, sock, newch, i;
1004 u_short host_port;
1008 struct sockaddr_in sin; 1005 struct sockaddr_in sin;
1009 char *host, *originator_string; 1006 char *host, *originator_string;
1010 struct hostent *hp; 1007 struct hostent *hp;
@@ -1122,7 +1119,8 @@ char *
1122x11_create_display_inet(int screen_number) 1119x11_create_display_inet(int screen_number)
1123{ 1120{
1124 extern ServerOptions options; 1121 extern ServerOptions options;
1125 int display_number, port, sock; 1122 int display_number, sock;
1123 u_short port;
1126 struct sockaddr_in sin; 1124 struct sockaddr_in sin;
1127 char buf[512]; 1125 char buf[512];
1128 char hostname[MAXHOSTNAMELEN]; 1126 char hostname[MAXHOSTNAMELEN];
diff --git a/hostfile.c b/hostfile.c
index cdfb48f3e..7060a899e 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: hostfile.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); 17RCSID("$OpenBSD: hostfile.c,v 1.10 1999/12/02 20:18:59 markus Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -231,9 +231,9 @@ check_host_in_hostfile(const char *filename, const char *host,
231 continue; 231 continue;
232 232
233 if (kbits != BN_num_bits(kn)) { 233 if (kbits != BN_num_bits(kn)) {
234 error("Warning: error in %s, line %d: keysize mismatch for host %s: " 234 error("Warning: %s, line %d: keysize mismatch for host %s: "
235 "actual size %d vs. announced %d.", 235 "actual %d vs. announced %d.",
236 filename, linenum, host, BN_num_bits(kn), kbits); 236 filename, linenum, host, BN_num_bits(kn), kbits);
237 error("Warning: replace %d with %d in %s, line %d.", 237 error("Warning: replace %d with %d in %s, line %d.",
238 kbits, BN_num_bits(kn), filename, linenum); 238 kbits, BN_num_bits(kn), filename, linenum);
239 } 239 }
diff --git a/nchan.c b/nchan.c
index 065b69baf..23d180c4d 100644
--- a/nchan.c
+++ b/nchan.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: nchan.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); 31RCSID("$Id: nchan.c,v 1.4 1999/12/06 00:47:29 damien Exp $");
32 32
33#include "ssh.h" 33#include "ssh.h"
34 34
@@ -65,7 +65,7 @@ chan_rcvd_oclose(Channel *c)
65 chan_delele_if_full_closed(c); 65 chan_delele_if_full_closed(c);
66 break; 66 break;
67 default: 67 default:
68 debug("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate); 68 error("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate);
69 break; 69 break;
70 } 70 }
71} 71}
@@ -79,7 +79,7 @@ chan_read_failed(Channel *c)
79 c->istate = CHAN_INPUT_WAIT_DRAIN; 79 c->istate = CHAN_INPUT_WAIT_DRAIN;
80 break; 80 break;
81 default: 81 default:
82 debug("internal error: we do not read, but chan_read_failed %d for istate %d", 82 error("internal error: we do not read, but chan_read_failed %d for istate %d",
83 c->self, c->istate); 83 c->self, c->istate);
84 break; 84 break;
85 } 85 }
@@ -88,7 +88,7 @@ void
88chan_ibuf_empty(Channel *c) 88chan_ibuf_empty(Channel *c)
89{ 89{
90 if (buffer_len(&c->input)) { 90 if (buffer_len(&c->input)) {
91 debug("internal error: chan_ibuf_empty %d for non empty buffer", c->self); 91 error("internal error: chan_ibuf_empty %d for non empty buffer", c->self);
92 return; 92 return;
93 } 93 }
94 switch (c->istate) { 94 switch (c->istate) {
@@ -98,7 +98,7 @@ chan_ibuf_empty(Channel *c)
98 c->istate = CHAN_INPUT_WAIT_OCLOSE; 98 c->istate = CHAN_INPUT_WAIT_OCLOSE;
99 break; 99 break;
100 default: 100 default:
101 debug("internal error: chan_ibuf_empty %d for istate %d", c->self, c->istate); 101 error("internal error: chan_ibuf_empty %d for istate %d", c->self, c->istate);
102 break; 102 break;
103 } 103 }
104} 104}
@@ -118,7 +118,7 @@ chan_rcvd_ieof(Channel *c)
118 chan_delele_if_full_closed(c); 118 chan_delele_if_full_closed(c);
119 break; 119 break;
120 default: 120 default:
121 debug("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate); 121 error("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate);
122 break; 122 break;
123 } 123 }
124} 124}
@@ -138,7 +138,7 @@ chan_write_failed(Channel *c)
138 chan_delele_if_full_closed(c); 138 chan_delele_if_full_closed(c);
139 break; 139 break;
140 default: 140 default:
141 debug("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate); 141 error("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate);
142 break; 142 break;
143 } 143 }
144} 144}
@@ -157,7 +157,7 @@ chan_obuf_empty(Channel *c)
157 chan_delele_if_full_closed(c); 157 chan_delele_if_full_closed(c);
158 break; 158 break;
159 default: 159 default:
160 debug("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate); 160 error("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate);
161 break; 161 break;
162 } 162 }
163} 163}
@@ -176,7 +176,7 @@ chan_send_ieof(Channel *c)
176 packet_send(); 176 packet_send();
177 break; 177 break;
178 default: 178 default:
179 debug("internal error: channel %d: cannot send IEOF for istate %d", c->self, c->istate); 179 error("internal error: channel %d: cannot send IEOF for istate %d", c->self, c->istate);
180 break; 180 break;
181 } 181 }
182} 182}
@@ -193,7 +193,7 @@ chan_send_oclose(Channel *c)
193 packet_send(); 193 packet_send();
194 break; 194 break;
195 default: 195 default:
196 debug("internal error: channel %d: cannot send OCLOSE for ostate %d", c->self, c->istate); 196 error("internal error: channel %d: cannot send OCLOSE for ostate %d", c->self, c->istate);
197 break; 197 break;
198 } 198 }
199} 199}
diff --git a/packet.c b/packet.c
index f4b44f5e0..9e8cf2e31 100644
--- a/packet.c
+++ b/packet.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: packet.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); 18RCSID("$Id: packet.c,v 1.7 1999/12/06 00:47:29 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "buffer.h" 21#include "buffer.h"
@@ -530,8 +530,10 @@ restart:
530 *payload_len_ptr = buffer_len(&incoming_packet); 530 *payload_len_ptr = buffer_len(&incoming_packet);
531 531
532 /* Handle disconnect message. */ 532 /* Handle disconnect message. */
533 if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT) 533 if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT) {
534 fatal("Received disconnect: %.900s", packet_get_string(NULL)); 534 log("Received disconnect: %.900s", packet_get_string(NULL));
535 fatal_cleanup();
536 }
535 537
536 /* Ignore ignore messages. */ 538 /* Ignore ignore messages. */
537 if ((unsigned char) buf[0] == SSH_MSG_IGNORE) 539 if ((unsigned char) buf[0] == SSH_MSG_IGNORE)
@@ -662,7 +664,8 @@ packet_disconnect(const char *fmt,...)
662 packet_close(); 664 packet_close();
663 665
664 /* Display the error locally and exit. */ 666 /* Display the error locally and exit. */
665 fatal("Disconnecting: %.100s", buf); 667 log("Disconnecting: %.100s", buf);
668 fatal_cleanup();
666} 669}
667 670
668/* Checks if there is any buffered output, and tries to write some of the output. */ 671/* Checks if there is any buffered output, and tries to write some of the output. */
diff --git a/readconf.c b/readconf.c
index 2c2705067..0ba78639e 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.7 1999/12/06 00:47:29 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -164,13 +164,11 @@ static struct {
164 */ 164 */
165 165
166void 166void
167add_local_forward(Options *options, int port, const char *host, 167add_local_forward(Options *options, u_short port, const char *host,
168 int host_port) 168 u_short host_port)
169{ 169{
170 Forward *fwd; 170 Forward *fwd;
171 extern uid_t original_real_uid; 171 extern uid_t original_real_uid;
172 if ((port & 0xffff) != port)
173 fatal("Requested forwarding of nonexistent port %d.", port);
174 if (port < IPPORT_RESERVED && original_real_uid != 0) 172 if (port < IPPORT_RESERVED && original_real_uid != 0)
175 fatal("Privileged ports can only be forwarded by root.\n"); 173 fatal("Privileged ports can only be forwarded by root.\n");
176 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 174 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
@@ -187,8 +185,8 @@ add_local_forward(Options *options, int port, const char *host,
187 */ 185 */
188 186
189void 187void
190add_remote_forward(Options *options, int port, const char *host, 188add_remote_forward(Options *options, u_short port, const char *host,
191 int host_port) 189 u_short host_port)
192{ 190{
193 Forward *fwd; 191 Forward *fwd;
194 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 192 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
@@ -230,7 +228,8 @@ process_config_line(Options *options, const char *host,
230 int *activep) 228 int *activep)
231{ 229{
232 char buf[256], *cp, *string, **charptr, *cp2; 230 char buf[256], *cp, *string, **charptr, *cp2;
233 int opcode, *intptr, value, fwd_port, fwd_host_port; 231 int opcode, *intptr, value;
232 u_short fwd_port, fwd_host_port;
234 233
235 /* Skip leading whitespace. */ 234 /* Skip leading whitespace. */
236 cp = line + strspn(line, WHITESPACE); 235 cp = line + strspn(line, WHITESPACE);
@@ -467,7 +466,7 @@ parse_int:
467 if (!cp) 466 if (!cp)
468 fatal("%.200s line %d: Missing second argument.", 467 fatal("%.200s line %d: Missing second argument.",
469 filename, linenum); 468 filename, linenum);
470 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) 469 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
471 fatal("%.200s line %d: Badly formatted host:port.", 470 fatal("%.200s line %d: Badly formatted host:port.",
472 filename, linenum); 471 filename, linenum);
473 if (*activep) 472 if (*activep)
@@ -486,7 +485,7 @@ parse_int:
486 if (!cp) 485 if (!cp)
487 fatal("%.200s line %d: Missing second argument.", 486 fatal("%.200s line %d: Missing second argument.",
488 filename, linenum); 487 filename, linenum);
489 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) 488 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
490 fatal("%.200s line %d: Badly formatted host:port.", 489 fatal("%.200s line %d: Badly formatted host:port.",
491 filename, linenum); 490 filename, linenum);
492 if (*activep) 491 if (*activep)
diff --git a/readconf.h b/readconf.h
index d594a46d7..09f051401 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: readconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */ 16/* RCSID("$Id: readconf.h,v 1.6 1999/12/06 00:47:29 damien Exp $"); */
17 17
18#ifndef READCONF_H 18#ifndef READCONF_H
19#define READCONF_H 19#define READCONF_H
@@ -21,9 +21,9 @@
21/* Data structure for representing a forwarding request. */ 21/* Data structure for representing a forwarding request. */
22 22
23typedef struct { 23typedef struct {
24 int port; /* Port to forward. */ 24 u_short port; /* Port to forward. */
25 char *host; /* Host to connect. */ 25 char *host; /* Host to connect. */
26 int host_port; /* Port to connect on host. */ 26 u_short host_port; /* Port to connect on host. */
27} Forward; 27} Forward;
28/* Data structure for representing option data. */ 28/* Data structure for representing option data. */
29 29
@@ -123,15 +123,15 @@ read_config_file(const char *filename, const char *host,
123 * error. 123 * error.
124 */ 124 */
125void 125void
126add_local_forward(Options * options, int port, const char *host, 126add_local_forward(Options * options, u_short port, const char *host,
127 int host_port); 127 u_short host_port);
128 128
129/* 129/*
130 * Adds a remote TCP/IP port forward to options. Never returns if there is 130 * Adds a remote TCP/IP port forward to options. Never returns if there is
131 * an error. 131 * an error.
132 */ 132 */
133void 133void
134add_remote_forward(Options * options, int port, const char *host, 134add_remote_forward(Options * options, u_short port, const char *host,
135 int host_port); 135 u_short host_port);
136 136
137#endif /* READCONF_H */ 137#endif /* READCONF_H */
diff --git a/serverloop.c b/serverloop.c
index 683598ef8..94c211571 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -609,7 +609,7 @@ quit:
609 /* Check if it matches the process we forked. */ 609 /* Check if it matches the process we forked. */
610 if (wait_pid != pid) 610 if (wait_pid != pid)
611 error("Strange, wait returned pid %d, expected %d", 611 error("Strange, wait returned pid %d, expected %d",
612 wait_pid, pid); 612 wait_pid, pid);
613 } 613 }
614 614
615 /* We no longer want our SIGCHLD handler to be called. */ 615 /* We no longer want our SIGCHLD handler to be called. */
diff --git a/ssh-add.1 b/ssh-add.1
index 67e09b467..444af9416 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 23:55:14 1995 ylo 10.\" Created: Sat Apr 22 23:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh-add.1,v 1.5 1999/11/25 00:54:59 damien Exp $ 12.\" $Id: ssh-add.1,v 1.6 1999/12/06 00:47:29 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-ADD 1 15.Dt SSH-ADD 1
@@ -51,7 +51,7 @@ Deletes all identities from the agent.
51.El 51.El
52.Sh FILES 52.Sh FILES
53.Bl -tag -width Ds 53.Bl -tag -width Ds
54.Pa $HOME/.ssh/identity 54.It Pa $HOME/.ssh/identity
55Contains the RSA authentication identity of the user. This file 55Contains the RSA authentication identity of the user. This file
56should not be readable by anyone but the user. 56should not be readable by anyone but the user.
57Note that 57Note that
@@ -64,6 +64,9 @@ default file added by
64.Nm 64.Nm
65when no other files have been specified. 65when no other files have been specified.
66.Pp 66.Pp
67.Sh ENVIRONMENT
68.Bl -tag -width Ds
69.It Ev "DISPLAY" and "SSH_ASKPASS"
67If 70If
68.Nm 71.Nm
69needs a passphrase, it will read the passphrase from the current 72needs a passphrase, it will read the passphrase from the current
diff --git a/ssh-add.c b/ssh-add.c
index 2d0dad400..f01cca5c8 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: ssh-add.c,v 1.15 1999/11/25 01:31:26 damien Exp $"); 10RCSID("$Id: ssh-add.c,v 1.16 1999/12/06 00:47:29 damien Exp $");
11 11
12#include "rsa.h" 12#include "rsa.h"
13#include "ssh.h" 13#include "ssh.h"
@@ -106,8 +106,12 @@ add_file(AuthenticationConnection *ac, const char *filename)
106 } 106 }
107 RSA_free(public_key); 107 RSA_free(public_key);
108 108
109 if (!interactive && getenv("DISPLAY")) 109 if (!interactive && getenv("DISPLAY")) {
110 askpass = getenv("SSH_ASKPASS"); 110 if (getenv(SSH_ASKPASS_ENV))
111 askpass = getenv(SSH_ASKPASS_ENV);
112 else
113 askpass = SSH_ASKPASS_DEFAULT;
114 }
111 115
112 /* At first, try empty passphrase */ 116 /* At first, try empty passphrase */
113 success = load_private_key(filename, "", key, &comment); 117 success = load_private_key(filename, "", key, &comment);
diff --git a/ssh.1 b/ssh.1
index 537a6e08f..fb5044482 100644
--- a/ssh.1
+++ b/ssh.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh.1,v 1.10 1999/11/25 00:54:59 damien Exp $ 12.\" $Id: ssh.1,v 1.11 1999/12/06 00:47:29 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -627,6 +627,9 @@ server running on some machine, or execute
627somewhere. Host key management will be done using the 627somewhere. Host key management will be done using the
628HostName of the host being connected (defaulting to the name typed by 628HostName of the host being connected (defaulting to the name typed by
629the user). 629the user).
630Note that
631.Cm CheckHostIP
632is not available for connects with a proxy command.
630.Pp 633.Pp
631.It Cm RemoteForward 634.It Cm RemoteForward
632Specifies that a TCP/IP port on the remote machine be forwarded over 635Specifies that a TCP/IP port on the remote machine be forwarded over
diff --git a/ssh.c b/ssh.c
index 21147f7e8..c0d61f820 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: ssh.c,v 1.12 1999/11/25 00:54:59 damien Exp $"); 14RCSID("$Id: ssh.c,v 1.13 1999/12/06 00:47:29 damien Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "ssh.h" 17#include "ssh.h"
@@ -162,8 +162,8 @@ rsh_connect(char *host, char *user, Buffer * command)
162int 162int
163main(int ac, char **av) 163main(int ac, char **av)
164{ 164{
165 int i, opt, optind, type, exit_status, ok, fwd_port, fwd_host_port, 165 int i, opt, optind, type, exit_status, ok, authfd;
166 authfd; 166 u_short fwd_port, fwd_host_port;
167 char *optarg, *cp, buf[256]; 167 char *optarg, *cp, buf[256];
168 Buffer command; 168 Buffer command;
169 struct winsize ws; 169 struct winsize ws;
@@ -340,10 +340,6 @@ main(int ac, char **av)
340 340
341 case 'p': 341 case 'p':
342 options.port = atoi(optarg); 342 options.port = atoi(optarg);
343 if (options.port < 1 || options.port > 65535) {
344 fprintf(stderr, "Bad port %s.\n", optarg);
345 exit(1);
346 }
347 break; 343 break;
348 344
349 case 'l': 345 case 'l':
@@ -351,7 +347,7 @@ main(int ac, char **av)
351 break; 347 break;
352 348
353 case 'R': 349 case 'R':
354 if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf, 350 if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf,
355 &fwd_host_port) != 3) { 351 &fwd_host_port) != 3) {
356 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); 352 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
357 usage(); 353 usage();
@@ -361,7 +357,7 @@ main(int ac, char **av)
361 break; 357 break;
362 358
363 case 'L': 359 case 'L':
364 if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf, 360 if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf,
365 &fwd_host_port) != 3) { 361 &fwd_host_port) != 3) {
366 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); 362 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
367 usage(); 363 usage();
@@ -561,7 +557,7 @@ main(int ac, char **av)
561 /* Check if the connection failed, and try "rsh" if appropriate. */ 557 /* Check if the connection failed, and try "rsh" if appropriate. */
562 if (!ok) { 558 if (!ok) {
563 if (options.port != 0) 559 if (options.port != 0)
564 log("Secure connection to %.100s on port %d refused%.100s.", 560 log("Secure connection to %.100s on port %hu refused%.100s.",
565 host, options.port, 561 host, options.port,
566 options.fallback_to_rsh ? "; reverting to insecure method" : ""); 562 options.fallback_to_rsh ? "; reverting to insecure method" : "");
567 else 563 else
diff --git a/ssh.h b/ssh.h
index e3fed053e..961c82a25 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: ssh.h,v 1.16 1999/11/25 00:54:59 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.17 1999/12/06 00:47:29 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
@@ -170,6 +170,13 @@
170#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" 170#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID"
171 171
172/* 172/*
173 * Default path to ssh-askpass used by ssh-add,
174 * environment variable for overwriting the default location
175 */
176#define SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass"
177#define SSH_ASKPASS_ENV "SSH_ASKPASS"
178
179/*
173 * Force host key length and server key length to differ by at least this 180 * Force host key length and server key length to differ by at least this
174 * many bits. This is to make double encryption with rsaref work. 181 * many bits. This is to make double encryption with rsaref work.
175 */ 182 */
@@ -294,7 +301,7 @@ void record_logout(int pid, const char *ttyname);
294 */ 301 */
295int 302int
296ssh_connect(const char *host, struct sockaddr_in * hostaddr, 303ssh_connect(const char *host, struct sockaddr_in * hostaddr,
297 int port, int connection_attempts, 304 u_short port, int connection_attempts,
298 int anonymous, uid_t original_real_uid, 305 int anonymous, uid_t original_real_uid,
299 const char *proxy_command); 306 const char *proxy_command);
300 307
@@ -579,8 +586,8 @@ char *channel_open_message(void);
579 * error. 586 * error.
580 */ 587 */
581void 588void
582channel_request_local_forwarding(int port, const char *host, 589channel_request_local_forwarding(u_short port, const char *host,
583 int remote_port); 590 u_short remote_port);
584 591
585/* 592/*
586 * Initiate forwarding of connections to port "port" on remote host through 593 * Initiate forwarding of connections to port "port" on remote host through
@@ -589,8 +596,8 @@ channel_request_local_forwarding(int port, const char *host,
589 * permitted. 596 * permitted.
590 */ 597 */
591void 598void
592channel_request_remote_forwarding(int port, const char *host, 599channel_request_remote_forwarding(u_short port, const char *host,
593 int remote_port); 600 u_short remote_port);
594 601
595/* 602/*
596 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually 603 * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
@@ -704,6 +711,7 @@ struct envstring {
704int auth_krb4(const char *server_user, KTEXT auth, char **client); 711int auth_krb4(const char *server_user, KTEXT auth, char **client);
705int krb4_init(uid_t uid); 712int krb4_init(uid_t uid);
706void krb4_cleanup_proc(void *ignore); 713void krb4_cleanup_proc(void *ignore);
714int auth_krb4_password(struct passwd * pw, const char *password);
707 715
708#ifdef AFS 716#ifdef AFS
709#include <kafs.h> 717#include <kafs.h>
@@ -721,6 +729,7 @@ int radix_to_creds(const char *buf, CREDENTIALS * creds);
721#ifdef SKEY 729#ifdef SKEY
722#include <skey.h> 730#include <skey.h>
723char *skey_fake_keyinfo(char *username); 731char *skey_fake_keyinfo(char *username);
732int auth_skey_password(struct passwd * pw, const char *password);
724#endif /* SKEY */ 733#endif /* SKEY */
725 734
726#endif /* SSH_H */ 735#endif /* SSH_H */
diff --git a/sshconnect.c b/sshconnect.c
index 0b1c0901f..593eade03 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $"); 11RCSID("$Id: sshconnect.c,v 1.16 1999/12/06 00:47:29 damien Exp $");
12 12
13#ifdef HAVE_OPENSSL 13#ifdef HAVE_OPENSSL
14#include <openssl/bn.h> 14#include <openssl/bn.h>
@@ -34,11 +34,13 @@ RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $");
34/* Session id for the current session. */ 34/* Session id for the current session. */
35unsigned char session_id[16]; 35unsigned char session_id[16];
36 36
37extern Options options;
38
37/* 39/*
38 * Connect to the given ssh server using a proxy command. 40 * Connect to the given ssh server using a proxy command.
39 */ 41 */
40int 42int
41ssh_proxy_connect(const char *host, int port, uid_t original_real_uid, 43ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid,
42 const char *proxy_command) 44 const char *proxy_command)
43{ 45{
44 Buffer command; 46 Buffer command;
@@ -49,7 +51,7 @@ ssh_proxy_connect(const char *host, int port, uid_t original_real_uid,
49 char portstring[100]; 51 char portstring[100];
50 52
51 /* Convert the port number into a string. */ 53 /* Convert the port number into a string. */
52 snprintf(portstring, sizeof portstring, "%d", port); 54 snprintf(portstring, sizeof portstring, "%hu", port);
53 55
54 /* Build the final command string in the buffer by making the 56 /* Build the final command string in the buffer by making the
55 appropriate substitutions to the given proxy command. */ 57 appropriate substitutions to the given proxy command. */
@@ -177,7 +179,7 @@ ssh_create_socket(uid_t original_real_uid, int privileged)
177 */ 179 */
178int 180int
179ssh_connect(const char *host, struct sockaddr_in * hostaddr, 181ssh_connect(const char *host, struct sockaddr_in * hostaddr,
180 int port, int connection_attempts, 182 u_short port, int connection_attempts,
181 int anonymous, uid_t original_real_uid, 183 int anonymous, uid_t original_real_uid,
182 const char *proxy_command) 184 const char *proxy_command)
183{ 185{
@@ -476,9 +478,8 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
476 * the user using it. 478 * the user using it.
477 */ 479 */
478int 480int
479try_rsa_authentication(struct passwd * pw, const char *authfile) 481try_rsa_authentication(const char *authfile)
480{ 482{
481 extern Options options;
482 BIGNUM *challenge; 483 BIGNUM *challenge;
483 RSA *private_key; 484 RSA *private_key;
484 RSA *public_key; 485 RSA *public_key;
@@ -490,7 +491,8 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
490 public_key = RSA_new(); 491 public_key = RSA_new();
491 if (!load_public_key(authfile, public_key, &comment)) { 492 if (!load_public_key(authfile, public_key, &comment)) {
492 RSA_free(public_key); 493 RSA_free(public_key);
493 return 0; /* Could not load it. Fail. */ 494 /* Could not load it. Fail. */
495 return 0;
494 } 496 }
495 debug("Trying RSA authentication with key '%.100s'", comment); 497 debug("Trying RSA authentication with key '%.100s'", comment);
496 498
@@ -513,8 +515,7 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
513 if (type == SSH_SMSG_FAILURE) { 515 if (type == SSH_SMSG_FAILURE) {
514 debug("Server refused our key."); 516 debug("Server refused our key.");
515 xfree(comment); 517 xfree(comment);
516 return 0; /* Server refuses to authenticate with 518 return 0;
517 this key. */
518 } 519 }
519 /* Otherwise, the server should respond with a challenge. */ 520 /* Otherwise, the server should respond with a challenge. */
520 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) 521 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
@@ -885,6 +886,93 @@ send_afs_tokens(void)
885#endif /* AFS */ 886#endif /* AFS */
886 887
887/* 888/*
889 * Tries to authenticate with any string-based challenge/response system.
890 * Note that the client code is not tied to s/key or TIS.
891 */
892int
893try_skey_authentication()
894{
895 int type, i, payload_len;
896 char *challenge, *response;
897
898 debug("Doing skey authentication.");
899
900 /* request a challenge */
901 packet_start(SSH_CMSG_AUTH_TIS);
902 packet_send();
903 packet_write_wait();
904
905 type = packet_read(&payload_len);
906 if (type != SSH_SMSG_FAILURE &&
907 type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
908 packet_disconnect("Protocol error: got %d in response "
909 "to skey-auth", type);
910 }
911 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
912 debug("No challenge for skey authentication.");
913 return 0;
914 }
915 challenge = packet_get_string(&payload_len);
916 if (options.cipher == SSH_CIPHER_NONE)
917 log("WARNING: Encryption is disabled! "
918 "Reponse will be transmitted in clear text.");
919 fprintf(stderr, "%s\n", challenge);
920 fflush(stderr);
921 for (i = 0; i < options.number_of_password_prompts; i++) {
922 if (i != 0)
923 error("Permission denied, please try again.");
924 response = read_passphrase("Response: ", 0);
925 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
926 packet_put_string(response, strlen(response));
927 memset(response, 0, strlen(response));
928 xfree(response);
929 packet_send();
930 packet_write_wait();
931 type = packet_read(&payload_len);
932 if (type == SSH_SMSG_SUCCESS)
933 return 1;
934 if (type != SSH_SMSG_FAILURE)
935 packet_disconnect("Protocol error: got %d in response "
936 "to skey-auth-reponse", type);
937 }
938 /* failure */
939 return 0;
940}
941
942/*
943 * Tries to authenticate with plain passwd authentication.
944 */
945int
946try_password_authentication(char *prompt)
947{
948 int type, i, payload_len;
949 char *password;
950
951 debug("Doing password authentication.");
952 if (options.cipher == SSH_CIPHER_NONE)
953 log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
954 for (i = 0; i < options.number_of_password_prompts; i++) {
955 if (i != 0)
956 error("Permission denied, please try again.");
957 password = read_passphrase(prompt, 0);
958 packet_start(SSH_CMSG_AUTH_PASSWORD);
959 packet_put_string(password, strlen(password));
960 memset(password, 0, strlen(password));
961 xfree(password);
962 packet_send();
963 packet_write_wait();
964
965 type = packet_read(&payload_len);
966 if (type == SSH_SMSG_SUCCESS)
967 return 1;
968 if (type != SSH_SMSG_FAILURE)
969 packet_disconnect("Protocol error: got %d in response to passwd auth", type);
970 }
971 /* failure */
972 return 0;
973}
974
975/*
888 * Waits for the server identification string, and sends our own 976 * Waits for the server identification string, and sends our own
889 * identification string. 977 * identification string.
890 */ 978 */
@@ -895,7 +983,6 @@ ssh_exchange_identification()
895 int remote_major, remote_minor, i; 983 int remote_major, remote_minor, i;
896 int connection_in = packet_get_connection_in(); 984 int connection_in = packet_get_connection_in();
897 int connection_out = packet_get_connection_out(); 985 int connection_out = packet_get_connection_out();
898 extern Options options;
899 986
900 /* Read other side\'s version identification. */ 987 /* Read other side\'s version identification. */
901 for (i = 0; i < sizeof(buf) - 1; i++) { 988 for (i = 0; i < sizeof(buf) - 1; i++) {
@@ -1015,9 +1102,7 @@ ssh_login(int host_key_valid,
1015 struct sockaddr_in *hostaddr, 1102 struct sockaddr_in *hostaddr,
1016 uid_t original_real_uid) 1103 uid_t original_real_uid)
1017{ 1104{
1018 extern Options options;
1019 int i, type; 1105 int i, type;
1020 char *password;
1021 struct passwd *pw; 1106 struct passwd *pw;
1022 BIGNUM *key; 1107 BIGNUM *key;
1023 RSA *host_key, *file_key; 1108 RSA *host_key, *file_key;
@@ -1036,6 +1121,13 @@ ssh_login(int host_key_valid,
1036 int payload_len, clen, sum_len = 0; 1121 int payload_len, clen, sum_len = 0;
1037 u_int32_t rand = 0; 1122 u_int32_t rand = 0;
1038 1123
1124 /*
1125 * Turn off check_host_ip for proxy connects, since
1126 * we don't have the remote ip-address
1127 */
1128 if (options.proxy_command != NULL && options.check_host_ip)
1129 options.check_host_ip = 0;
1130
1039 if (options.check_host_ip) 1131 if (options.check_host_ip)
1040 ip = xstrdup(inet_ntoa(hostaddr->sin_addr)); 1132 ip = xstrdup(inet_ntoa(hostaddr->sin_addr));
1041 1133
@@ -1494,80 +1586,23 @@ ssh_login(int host_key_valid,
1494 1586
1495 /* Try RSA authentication for each identity. */ 1587 /* Try RSA authentication for each identity. */
1496 for (i = 0; i < options.num_identity_files; i++) 1588 for (i = 0; i < options.num_identity_files; i++)
1497 if (try_rsa_authentication(pw, options.identity_files[i])) 1589 if (try_rsa_authentication(options.identity_files[i]))
1498 return; 1590 return;
1499 } 1591 }
1500 /* Try skey authentication if the server supports it. */ 1592 /* Try skey authentication if the server supports it. */
1501 if ((supported_authentications & (1 << SSH_AUTH_TIS)) && 1593 if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1502 options.skey_authentication && !options.batch_mode) { 1594 options.skey_authentication && !options.batch_mode) {
1503 debug("Doing skey authentication."); 1595 if (try_skey_authentication())
1504 1596 return;
1505 /* request a challenge */
1506 packet_start(SSH_CMSG_AUTH_TIS);
1507 packet_send();
1508 packet_write_wait();
1509
1510 type = packet_read(&payload_len);
1511 if (type != SSH_SMSG_FAILURE &&
1512 type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
1513 packet_disconnect("Protocol error: got %d in response "
1514 "to skey auth", type);
1515 }
1516 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
1517 debug("No challenge for skey authentication.");
1518 } else {
1519 char *challenge, *response;
1520 challenge = packet_get_string(&payload_len);
1521 if (options.cipher == SSH_CIPHER_NONE)
1522 log("WARNING: Encryption is disabled! "
1523 "Reponse will be transmitted in clear text.");
1524 fprintf(stderr, "%s\n", challenge);
1525 fflush(stderr);
1526 for (i = 0; i < options.number_of_password_prompts; i++) {
1527 if (i != 0)
1528 error("Permission denied, please try again.");
1529 response = read_passphrase("Response: ", 0);
1530 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
1531 packet_put_string(response, strlen(response));
1532 memset(response, 0, strlen(response));
1533 xfree(response);
1534 packet_send();
1535 packet_write_wait();
1536 type = packet_read(&payload_len);
1537 if (type == SSH_SMSG_SUCCESS)
1538 return;
1539 if (type != SSH_SMSG_FAILURE)
1540 packet_disconnect("Protocol error: got %d in response "
1541 "to skey auth", type);
1542 }
1543 }
1544 } 1597 }
1545 /* Try password authentication if the server supports it. */ 1598 /* Try password authentication if the server supports it. */
1546 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && 1599 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1547 options.password_authentication && !options.batch_mode) { 1600 options.password_authentication && !options.batch_mode) {
1548 char prompt[80]; 1601 char prompt[80];
1549 snprintf(prompt, sizeof(prompt), "%.30s@%.30s's password: ", 1602 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
1550 server_user, host); 1603 server_user, host);
1551 debug("Doing password authentication."); 1604 if (try_password_authentication(prompt))
1552 if (options.cipher == SSH_CIPHER_NONE) 1605 return;
1553 log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
1554 for (i = 0; i < options.number_of_password_prompts; i++) {
1555 if (i != 0)
1556 error("Permission denied, please try again.");
1557 password = read_passphrase(prompt, 0);
1558 packet_start(SSH_CMSG_AUTH_PASSWORD);
1559 packet_put_string(password, strlen(password));
1560 memset(password, 0, strlen(password));
1561 xfree(password);
1562 packet_send();
1563 packet_write_wait();
1564
1565 type = packet_read(&payload_len);
1566 if (type == SSH_SMSG_SUCCESS)
1567 return;
1568 if (type != SSH_SMSG_FAILURE)
1569 packet_disconnect("Protocol error: got %d in response to passwd auth", type);
1570 }
1571 } 1606 }
1572 /* All authentication methods have failed. Exit with an error message. */ 1607 /* All authentication methods have failed. Exit with an error message. */
1573 fatal("Permission denied."); 1608 fatal("Permission denied.");