summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--auth-rh-rsa.c12
-rw-r--r--auth-rsa.c24
-rw-r--r--authfd.c20
-rw-r--r--authfd.h8
-rw-r--r--cipher.c4
-rw-r--r--cipher.h10
-rw-r--r--hostfile.c45
-rw-r--r--mpaux.c8
-rw-r--r--mpaux.h4
-rw-r--r--packet.c29
-rw-r--r--packet.h4
-rw-r--r--ssh-add.c37
-rw-r--r--ssh-agent.c8
-rw-r--r--ssh.c9
-rw-r--r--ssh.h15
-rw-r--r--sshconnect.c48
-rw-r--r--sshd.c17
18 files changed, 167 insertions, 150 deletions
diff --git a/ChangeLog b/ChangeLog
index 88cf9b387..9d6d07a1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
119991116
2 - Fix some Linux libc5 problems reported by Miles Wilson <mw@mctitle.com>
3 - Merged OpenBSD CVS changes:
4 - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c]
5 [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c]
6 the keysize of rsa-parameter 'n' is passed implizit,
7 a few more checks and warnings about 'pretended' keysizes.
8 - [cipher.c cipher.h packet.c packet.h sshd.c]
9 remove support for cipher RC4
10 - [ssh.c]
11 a note for legay systems about secuity issues with permanently_set_uid(),
12 the private hostkey and ptrace()
13 - [sshconnect.c]
14 more detailed messages about adding and checking hostkeys
15
119991115 1619991115
2 - Merged OpenBSD CVS changes: 17 - Merged OpenBSD CVS changes:
3 - [ssh-add.c] change passphrase loop logic and remove ref to 18 - [ssh-add.c] change passphrase loop logic and remove ref to
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index fa855a1a8..68e0b829e 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -15,7 +15,7 @@ authentication.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: auth-rh-rsa.c,v 1.4 1999/11/12 04:19:27 damien Exp $"); 18RCSID("$Id: auth-rh-rsa.c,v 1.5 1999/11/16 02:37:16 damien Exp $");
19 19
20#include "packet.h" 20#include "packet.h"
21#include "ssh.h" 21#include "ssh.h"
@@ -27,7 +27,6 @@ RCSID("$Id: auth-rh-rsa.c,v 1.4 1999/11/12 04:19:27 damien Exp $");
27 its host key. Returns true if authentication succeeds. */ 27 its host key. Returns true if authentication succeeds. */
28 28
29int auth_rhosts_rsa(struct passwd *pw, const char *client_user, 29int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
30 unsigned int client_host_key_bits,
31 BIGNUM *client_host_key_e, BIGNUM *client_host_key_n) 30 BIGNUM *client_host_key_e, BIGNUM *client_host_key_n)
32{ 31{
33 extern ServerOptions options; 32 extern ServerOptions options;
@@ -51,8 +50,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
51 ke = BN_new(); 50 ke = BN_new();
52 kn = BN_new(); 51 kn = BN_new();
53 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, 52 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
54 client_host_key_bits, client_host_key_e, 53 client_host_key_e, client_host_key_n, ke, kn);
55 client_host_key_n, ke, kn);
56 54
57 /* Check user host file unless ignored. */ 55 /* Check user host file unless ignored. */
58 if (host_status != HOST_OK && !options.ignore_user_known_hosts) { 56 if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
@@ -70,8 +68,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
70 /* XXX race between stat and the following open() */ 68 /* XXX race between stat and the following open() */
71 temporarily_use_uid(pw->pw_uid); 69 temporarily_use_uid(pw->pw_uid);
72 host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, 70 host_status = check_host_in_hostfile(user_hostfile, canonical_hostname,
73 client_host_key_bits, client_host_key_e, 71 client_host_key_e, client_host_key_n, ke, kn);
74 client_host_key_n, ke, kn);
75 restore_uid(); 72 restore_uid();
76 } 73 }
77 xfree(user_hostfile); 74 xfree(user_hostfile);
@@ -89,8 +86,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
89 /* A matching host key was found and is known. */ 86 /* A matching host key was found and is known. */
90 87
91 /* Perform the challenge-response dialog with the client for the host key. */ 88 /* Perform the challenge-response dialog with the client for the host key. */
92 if (!auth_rsa_challenge_dialog(client_host_key_bits, 89 if (!auth_rsa_challenge_dialog(client_host_key_e, client_host_key_n))
93 client_host_key_e, client_host_key_n))
94 { 90 {
95 log("Client on %.800s failed to respond correctly to host authentication.", 91 log("Client on %.800s failed to respond correctly to host authentication.",
96 canonical_hostname); 92 canonical_hostname);
diff --git a/auth-rsa.c b/auth-rsa.c
index cc76bf07e..6041a3211 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@ validity of the host key.
16*/ 16*/
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rsa.c,v 1.6 1999/11/12 23:51:58 damien Exp $"); 19RCSID("$Id: auth-rsa.c,v 1.7 1999/11/16 02:37:16 damien Exp $");
20 20
21#include "rsa.h" 21#include "rsa.h"
22#include "packet.h" 22#include "packet.h"
@@ -61,7 +61,7 @@ extern unsigned char session_id[16];
61 our challenge; returns zero if the client gives a wrong answer. */ 61 our challenge; returns zero if the client gives a wrong answer. */
62 62
63int 63int
64auth_rsa_challenge_dialog(unsigned int bits, BIGNUM *e, BIGNUM *n) 64auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n)
65{ 65{
66 BIGNUM *challenge, *encrypted_challenge, *aux; 66 BIGNUM *challenge, *encrypted_challenge, *aux;
67 RSA *pk; 67 RSA *pk;
@@ -138,7 +138,7 @@ int
138auth_rsa(struct passwd *pw, BIGNUM *client_n) 138auth_rsa(struct passwd *pw, BIGNUM *client_n)
139{ 139{
140 extern ServerOptions options; 140 extern ServerOptions options;
141 char line[8192]; 141 char line[8192], file[1024];
142 int authenticated; 142 int authenticated;
143 unsigned int bits; 143 unsigned int bits;
144 FILE *f; 144 FILE *f;
@@ -150,11 +150,11 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
150 temporarily_use_uid(pw->pw_uid); 150 temporarily_use_uid(pw->pw_uid);
151 151
152 /* The authorized keys. */ 152 /* The authorized keys. */
153 snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, 153 snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
154 SSH_USER_PERMITTED_KEYS); 154 SSH_USER_PERMITTED_KEYS);
155 155
156 /* Fail quietly if file does not exist */ 156 /* Fail quietly if file does not exist */
157 if (stat(line, &st) < 0) 157 if (stat(file, &st) < 0)
158 { 158 {
159 /* Restore the privileged uid. */ 159 /* Restore the privileged uid. */
160 restore_uid(); 160 restore_uid();
@@ -162,12 +162,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
162 } 162 }
163 163
164 /* Open the file containing the authorized keys. */ 164 /* Open the file containing the authorized keys. */
165 f = fopen(line, "r"); 165 f = fopen(file, "r");
166 if (!f) 166 if (!f)
167 { 167 {
168 /* Restore the privileged uid. */ 168 /* Restore the privileged uid. */
169 restore_uid(); 169 restore_uid();
170 packet_send_debug("Could not open %.900s for reading.", line); 170 packet_send_debug("Could not open %.900s for reading.", file);
171 packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); 171 packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
172 return 0; 172 return 0;
173 } 173 }
@@ -180,7 +180,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
180 (st.st_uid != 0 && st.st_uid != pw->pw_uid) || 180 (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
181 (st.st_mode & 022) != 0) { 181 (st.st_mode & 022) != 0) {
182 snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " 182 snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: "
183 "bad ownership or modes for '%s'.", pw->pw_name, line); 183 "bad ownership or modes for '%s'.", pw->pw_name, file);
184 fail=1; 184 fail=1;
185 }else{ 185 }else{
186 /* Check path to SSH_USER_PERMITTED_KEYS */ 186 /* Check path to SSH_USER_PERMITTED_KEYS */
@@ -263,6 +263,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
263 } 263 }
264 /* cp now points to the comment part. */ 264 /* cp now points to the comment part. */
265 265
266 /* check the real bits */
267 if (bits != BN_num_bits(n))
268 error("Warning: error in %s, line %d: keysize mismatch: "
269 "actual size %d vs. announced %d.",
270 file, linenum, BN_num_bits(n), bits);
271
266 /* Check if the we have found the desired key (identified by its 272 /* Check if the we have found the desired key (identified by its
267 modulus). */ 273 modulus). */
268 if (BN_cmp(n, client_n) != 0) 274 if (BN_cmp(n, client_n) != 0)
@@ -271,7 +277,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
271 /* We have found the desired key. */ 277 /* We have found the desired key. */
272 278
273 /* Perform the challenge-response dialog for this key. */ 279 /* Perform the challenge-response dialog for this key. */
274 if (!auth_rsa_challenge_dialog(bits, e, n)) 280 if (!auth_rsa_challenge_dialog(e, n))
275 { 281 {
276 /* Wrong response. */ 282 /* Wrong response. */
277 log("Wrong response to RSA authentication challenge."); 283 log("Wrong response to RSA authentication challenge.");
diff --git a/authfd.c b/authfd.c
index ac2c19601..84a5fc742 100644
--- a/authfd.c
+++ b/authfd.c
@@ -14,7 +14,7 @@ Functions for connecting the local authentication agent.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: authfd.c,v 1.3 1999/11/12 23:51:58 damien Exp $"); 17RCSID("$Id: authfd.c,v 1.4 1999/11/16 02:37:16 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "rsa.h" 20#include "rsa.h"
@@ -117,7 +117,7 @@ void ssh_close_authentication_connection(AuthenticationConnection *ac)
117 117
118int 118int
119ssh_get_first_identity(AuthenticationConnection *auth, 119ssh_get_first_identity(AuthenticationConnection *auth,
120 int *bitsp, BIGNUM *e, BIGNUM *n, char **comment) 120 BIGNUM *e, BIGNUM *n, char **comment)
121{ 121{
122 unsigned char msg[8192]; 122 unsigned char msg[8192];
123 int len, l; 123 int len, l;
@@ -179,7 +179,7 @@ ssh_get_first_identity(AuthenticationConnection *auth,
179 fatal("Too many identities in authentication reply: %d\n", auth->howmany); 179 fatal("Too many identities in authentication reply: %d\n", auth->howmany);
180 180
181 /* Return the first entry (if any). */ 181 /* Return the first entry (if any). */
182 return ssh_get_next_identity(auth, bitsp, e, n, comment); 182 return ssh_get_next_identity(auth, e, n, comment);
183} 183}
184 184
185/* Returns the next authentication identity for the agent. Other functions 185/* Returns the next authentication identity for the agent. Other functions
@@ -189,19 +189,25 @@ ssh_get_first_identity(AuthenticationConnection *auth,
189 189
190int 190int
191ssh_get_next_identity(AuthenticationConnection *auth, 191ssh_get_next_identity(AuthenticationConnection *auth,
192 int *bitsp, BIGNUM *e, BIGNUM *n, char **comment) 192 BIGNUM *e, BIGNUM *n, char **comment)
193{ 193{
194 unsigned int bits;
195
194 /* Return failure if no more entries. */ 196 /* Return failure if no more entries. */
195 if (auth->howmany <= 0) 197 if (auth->howmany <= 0)
196 return 0; 198 return 0;
197 199
198 /* Get the next entry from the packet. These will abort with a fatal 200 /* Get the next entry from the packet. These will abort with a fatal
199 error if the packet is too short or contains corrupt data. */ 201 error if the packet is too short or contains corrupt data. */
200 *bitsp = buffer_get_int(&auth->identities); 202 bits = buffer_get_int(&auth->identities);
201 buffer_get_bignum(&auth->identities, e); 203 buffer_get_bignum(&auth->identities, e);
202 buffer_get_bignum(&auth->identities, n); 204 buffer_get_bignum(&auth->identities, n);
203 *comment = buffer_get_string(&auth->identities, NULL); 205 *comment = buffer_get_string(&auth->identities, NULL);
204 206
207 if (bits != BN_num_bits(n))
208 error("Warning: keysize mismatch: actual %d, announced %s",
209 BN_num_bits(n), bits);
210
205 /* Decrement the number of remaining entries. */ 211 /* Decrement the number of remaining entries. */
206 auth->howmany--; 212 auth->howmany--;
207 213
@@ -216,7 +222,7 @@ ssh_get_next_identity(AuthenticationConnection *auth,
216 222
217int 223int
218ssh_decrypt_challenge(AuthenticationConnection *auth, 224ssh_decrypt_challenge(AuthenticationConnection *auth,
219 int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge, 225 BIGNUM *e, BIGNUM *n, BIGNUM *challenge,
220 unsigned char session_id[16], 226 unsigned char session_id[16],
221 unsigned int response_type, 227 unsigned int response_type,
222 unsigned char response[16]) 228 unsigned char response[16])
@@ -233,7 +239,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
233 buf[0] = SSH_AGENTC_RSA_CHALLENGE; 239 buf[0] = SSH_AGENTC_RSA_CHALLENGE;
234 buffer_init(&buffer); 240 buffer_init(&buffer);
235 buffer_append(&buffer, (char *)buf, 1); 241 buffer_append(&buffer, (char *)buf, 1);
236 buffer_put_int(&buffer, bits); 242 buffer_put_int(&buffer, BN_num_bits(n));
237 buffer_put_bignum(&buffer, e); 243 buffer_put_bignum(&buffer, e);
238 buffer_put_bignum(&buffer, n); 244 buffer_put_bignum(&buffer, n);
239 buffer_put_bignum(&buffer, challenge); 245 buffer_put_bignum(&buffer, challenge);
diff --git a/authfd.h b/authfd.h
index 1def920e3..df589b1c4 100644
--- a/authfd.h
+++ b/authfd.h
@@ -13,7 +13,7 @@ Functions to interface with the SSH_AUTHENTICATION_FD socket.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: authfd.h,v 1.1 1999/10/27 03:42:43 damien Exp $"); */ 16/* RCSID("$Id: authfd.h,v 1.2 1999/11/16 02:37:16 damien Exp $"); */
17 17
18#ifndef AUTHFD_H 18#ifndef AUTHFD_H
19#define AUTHFD_H 19#define AUTHFD_H
@@ -62,19 +62,19 @@ void ssh_close_authentication_connection(AuthenticationConnection *ac);
62 The caller must initialize the integers before the call, and free the 62 The caller must initialize the integers before the call, and free the
63 comment after a successful call (before calling ssh_get_next_identity). */ 63 comment after a successful call (before calling ssh_get_next_identity). */
64int ssh_get_first_identity(AuthenticationConnection *connection, 64int ssh_get_first_identity(AuthenticationConnection *connection,
65 int *bitsp, BIGNUM *e, BIGNUM *n, char **comment); 65 BIGNUM *e, BIGNUM *n, char **comment);
66 66
67/* Returns the next authentication identity for the agent. Other functions 67/* Returns the next authentication identity for the agent. Other functions
68 can be called between this and ssh_get_first_identity or two calls of this 68 can be called between this and ssh_get_first_identity or two calls of this
69 function. This returns 0 if there are no more identities. The caller 69 function. This returns 0 if there are no more identities. The caller
70 must free comment after a successful return. */ 70 must free comment after a successful return. */
71int ssh_get_next_identity(AuthenticationConnection *connection, 71int ssh_get_next_identity(AuthenticationConnection *connection,
72 int *bitsp, BIGNUM *e, BIGNUM *n, char **comment); 72 BIGNUM *e, BIGNUM *n, char **comment);
73 73
74/* Requests the agent to decrypt the given challenge. Returns true if 74/* Requests the agent to decrypt the given challenge. Returns true if
75 the agent claims it was able to decrypt it. */ 75 the agent claims it was able to decrypt it. */
76int ssh_decrypt_challenge(AuthenticationConnection *auth, 76int ssh_decrypt_challenge(AuthenticationConnection *auth,
77 int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge, 77 BIGNUM *e, BIGNUM *n, BIGNUM *challenge,
78 unsigned char session_id[16], 78 unsigned char session_id[16],
79 unsigned int response_type, 79 unsigned int response_type,
80 unsigned char response[16]); 80 unsigned char response[16]);
diff --git a/cipher.c b/cipher.c
index 32b5ecb63..a33188e46 100644
--- a/cipher.c
+++ b/cipher.c
@@ -12,7 +12,7 @@ Created: Wed Apr 19 17:41:39 1995 ylo
12*/ 12*/
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.5 1999/11/12 23:51:58 damien Exp $"); 15RCSID("$Id: cipher.c,v 1.6 1999/11/16 02:37:16 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "cipher.h" 18#include "cipher.h"
@@ -235,7 +235,7 @@ void cipher_set_key(CipherContext *context, int cipher,
235 break; 235 break;
236 236
237 default: 237 default:
238 fatal("cipher_set_key: unknown cipher: %d", cipher); 238 fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
239 } 239 }
240 memset(padded, 0, sizeof(padded)); 240 memset(padded, 0, sizeof(padded));
241} 241}
diff --git a/cipher.h b/cipher.h
index 9c2a0b52c..5bfb74241 100644
--- a/cipher.h
+++ b/cipher.h
@@ -11,13 +11,13 @@ Created: Wed Apr 19 16:50:42 1995 ylo
11 11
12*/ 12*/
13 13
14/* RCSID("$Id: cipher.h,v 1.2 1999/10/28 03:25:17 damien Exp $"); */ 14/* RCSID("$Id: cipher.h,v 1.3 1999/11/16 02:37:16 damien Exp $"); */
15
16#include "config.h"
17 15
18#ifndef CIPHER_H 16#ifndef CIPHER_H
19#define CIPHER_H 17#define CIPHER_H
20 18
19#include "config.h"
20
21#ifdef HAVE_OPENSSL 21#ifdef HAVE_OPENSSL
22#include <openssl/des.h> 22#include <openssl/des.h>
23#include <openssl/blowfish.h> 23#include <openssl/blowfish.h>
@@ -34,8 +34,8 @@ Created: Wed Apr 19 16:50:42 1995 ylo
34#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ 34#define SSH_CIPHER_IDEA 1 /* IDEA CFB */
35#define SSH_CIPHER_DES 2 /* DES CBC */ 35#define SSH_CIPHER_DES 2 /* DES CBC */
36#define SSH_CIPHER_3DES 3 /* 3DES CBC */ 36#define SSH_CIPHER_3DES 3 /* 3DES CBC */
37#define SSH_CIPHER_TSS 4 /* TRI's Simple Stream encryption CBC */ 37#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */
38#define SSH_CIPHER_RC4 5 /* Alleged RC4 */ 38#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
39#define SSH_CIPHER_BLOWFISH 6 39#define SSH_CIPHER_BLOWFISH 6
40 40
41typedef struct { 41typedef struct {
diff --git a/hostfile.c b/hostfile.c
index 0e65bfe5f..79ff7f988 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,7 +14,7 @@ Functions for manipulating the known hosts files.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: hostfile.c,v 1.2 1999/11/08 05:15:55 damien Exp $"); 17RCSID("$Id: hostfile.c,v 1.3 1999/11/16 02:37:16 damien Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -166,29 +166,20 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
166 but used to have a different host key. */ 166 but used to have a different host key. */
167 167
168HostStatus 168HostStatus
169check_host_in_hostfile(const char *filename, 169check_host_in_hostfile(const char *filename, const char *host,
170 const char *host, unsigned int bits, 170 BIGNUM *e, BIGNUM *n, BIGNUM *ke, BIGNUM *kn)
171 BIGNUM *e, BIGNUM *n,
172 BIGNUM *ke, BIGNUM *kn)
173{ 171{
174 FILE *f; 172 FILE *f;
175 char line[8192]; 173 char line[8192];
176 unsigned int kbits, hostlen; 174 int linenum = 0;
175 unsigned int bits, kbits, hostlen;
177 char *cp, *cp2; 176 char *cp, *cp2;
178 HostStatus end_return; 177 HostStatus end_return;
179 struct stat st;
180 178
181 /* Open the file containing the list of known hosts. */ 179 /* Open the file containing the list of known hosts. */
182 f = fopen(filename, "r"); 180 f = fopen(filename, "r");
183 if (!f) 181 if (!f)
184 { 182 return HOST_NEW;
185 if (stat(filename, &st) >= 0)
186 {
187 packet_send_debug("Could not open %.900s for reading.", filename);
188 packet_send_debug("If your home directory is on an NFS volume, it may need to be world-readable.");
189 }
190 return HOST_NEW;
191 }
192 183
193 /* Cache the length of the host name. */ 184 /* Cache the length of the host name. */
194 hostlen = strlen(host); 185 hostlen = strlen(host);
@@ -198,10 +189,14 @@ check_host_in_hostfile(const char *filename,
198 one. */ 189 one. */
199 end_return = HOST_NEW; 190 end_return = HOST_NEW;
200 191
192 /* size of modulus 'n' */
193 bits = BN_num_bits(n);
194
201 /* Go trough the file. */ 195 /* Go trough the file. */
202 while (fgets(line, sizeof(line), f)) 196 while (fgets(line, sizeof(line), f))
203 { 197 {
204 cp = line; 198 cp = line;
199 linenum++;
205 200
206 /* Skip any leading whitespace. */ 201 /* Skip any leading whitespace. */
207 for (; *cp == ' ' || *cp == '\t'; cp++) 202 for (; *cp == ' ' || *cp == '\t'; cp++)
@@ -227,7 +222,15 @@ check_host_in_hostfile(const char *filename,
227 if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) 222 if (!auth_rsa_read_key(&cp, &kbits, ke, kn))
228 continue; 223 continue;
229 224
230 /* Check if the current key is the same as the previous one. */ 225 if (kbits != BN_num_bits(kn)) {
226 error("Warning: error in %s, line %d: keysize mismatch for host %s: "
227 "actual size %d vs. announced %d.",
228 filename, linenum, host, BN_num_bits(kn), kbits);
229 error("Warning: replace %d with %d in %s, line %d.",
230 kbits, BN_num_bits(kn), filename, linenum);
231 }
232
233 /* Check if the current key is the same as the given key. */
231 if (kbits == bits && BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) 234 if (kbits == bits && BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0)
232 { 235 {
233 /* Ok, they match. */ 236 /* Ok, they match. */
@@ -252,21 +255,25 @@ check_host_in_hostfile(const char *filename,
252 255
253int 256int
254add_host_to_hostfile(const char *filename, const char *host, 257add_host_to_hostfile(const char *filename, const char *host,
255 unsigned int bits, BIGNUM *e, BIGNUM *n) 258 BIGNUM *e, BIGNUM *n)
256{ 259{
257 FILE *f; 260 FILE *f;
258 char *buf; 261 char *buf;
262 unsigned int bits;
259 263
260 /* Open the file for appending. */ 264 /* Open the file for appending. */
261 f = fopen(filename, "a"); 265 f = fopen(filename, "a");
262 if (!f) 266 if (!f)
263 return 0; 267 return 0;
264 268
269 /* size of modulus 'n' */
270 bits = BN_num_bits(n);
271
265 /* Print the host name and key to the file. */ 272 /* Print the host name and key to the file. */
266 fprintf(f, "%s %u ", host, bits); 273 fprintf(f, "%s %u ", host, bits);
267 buf = BN_bn2dec(e); 274 buf = BN_bn2dec(e);
268 if (buf == NULL) { 275 if (buf == NULL) {
269 error("add_host_to_hostfile: BN_bn2dec #1 failed"); 276 error("add_host_to_hostfile: BN_bn2dec(e) failed");
270 fclose(f); 277 fclose(f);
271 return 0; 278 return 0;
272 } 279 }
@@ -274,7 +281,7 @@ add_host_to_hostfile(const char *filename, const char *host,
274 free (buf); 281 free (buf);
275 buf = BN_bn2dec(n); 282 buf = BN_bn2dec(n);
276 if (buf == NULL) { 283 if (buf == NULL) {
277 error("add_host_to_hostfile: BN_bn2dec #2 failed"); 284 error("add_host_to_hostfile: BN_bn2dec(n) failed");
278 fclose(f); 285 fclose(f);
279 return 0; 286 return 0;
280 } 287 }
diff --git a/mpaux.c b/mpaux.c
index 311b1ed9d..378fd90da 100644
--- a/mpaux.c
+++ b/mpaux.c
@@ -15,7 +15,7 @@ precision integers.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: mpaux.c,v 1.5 1999/11/12 23:51:58 damien Exp $"); 18RCSID("$Id: mpaux.c,v 1.6 1999/11/16 02:37:16 damien Exp $");
19 19
20#ifdef HAVE_OPENSSL 20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h> 21#include <openssl/bn.h>
@@ -33,15 +33,15 @@ RCSID("$Id: mpaux.c,v 1.5 1999/11/12 23:51:58 damien Exp $");
33void 33void
34compute_session_id(unsigned char session_id[16], 34compute_session_id(unsigned char session_id[16],
35 unsigned char cookie[8], 35 unsigned char cookie[8],
36 unsigned int host_key_bits,
37 BIGNUM *host_key_n, 36 BIGNUM *host_key_n,
38 unsigned int session_key_bits,
39 BIGNUM *session_key_n) 37 BIGNUM *session_key_n)
40{ 38{
39 unsigned int host_key_bits = BN_num_bits(host_key_n);
40 unsigned int session_key_bits = BN_num_bits(session_key_n);
41 unsigned int bytes = (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8 + 8; 41 unsigned int bytes = (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8 + 8;
42 unsigned char *buf = xmalloc(bytes); 42 unsigned char *buf = xmalloc(bytes);
43 MD5_CTX md; 43 MD5_CTX md;
44 44
45 BN_bn2bin(host_key_n, buf); 45 BN_bn2bin(host_key_n, buf);
46 BN_bn2bin(session_key_n, buf + (host_key_bits + 7 ) / 8); 46 BN_bn2bin(session_key_n, buf + (host_key_bits + 7 ) / 8);
47 memcpy(buf + (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8, 47 memcpy(buf + (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8,
diff --git a/mpaux.h b/mpaux.h
index 3ad06813b..85e2fa2bf 100644
--- a/mpaux.h
+++ b/mpaux.h
@@ -14,7 +14,7 @@ precision integers.
14 14
15*/ 15*/
16 16
17/* RCSID("$Id: mpaux.h,v 1.1 1999/10/27 03:42:44 damien Exp $"); */ 17/* RCSID("$Id: mpaux.h,v 1.2 1999/11/16 02:37:16 damien Exp $"); */
18 18
19#ifndef MPAUX_H 19#ifndef MPAUX_H
20#define MPAUX_H 20#define MPAUX_H
@@ -24,9 +24,7 @@ precision integers.
24 first representations of host_key_n, session_key_n, and the cookie. */ 24 first representations of host_key_n, session_key_n, and the cookie. */
25void compute_session_id(unsigned char session_id[16], 25void compute_session_id(unsigned char session_id[16],
26 unsigned char cookie[8], 26 unsigned char cookie[8],
27 unsigned int host_key_bits,
28 BIGNUM *host_key_n, 27 BIGNUM *host_key_n,
29 unsigned int session_key_bits,
30 BIGNUM *session_key_n); 28 BIGNUM *session_key_n);
31 29
32#endif /* MPAUX_H */ 30#endif /* MPAUX_H */
diff --git a/packet.c b/packet.c
index 6dfd492a1..9c2a4f86e 100644
--- a/packet.c
+++ b/packet.c
@@ -15,7 +15,7 @@ with the other side. This same code is used both on client and server side.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: packet.c,v 1.2 1999/11/08 05:15:55 damien Exp $"); 18RCSID("$Id: packet.c,v 1.3 1999/11/16 02:37:16 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "buffer.h" 21#include "buffer.h"
@@ -236,30 +236,11 @@ packet_decrypt(CipherContext *cc, void *dest, void *src,
236 236
237void 237void
238packet_set_encryption_key(const unsigned char *key, unsigned int keylen, 238packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
239 int cipher, int is_client) 239 int cipher)
240{ 240{
241 cipher_type = cipher; 241 /* All other ciphers use the same key in both directions for now. */
242 if (cipher == SSH_CIPHER_RC4) 242 cipher_set_key(&receive_context, cipher, key, keylen, 0);
243 { 243 cipher_set_key(&send_context, cipher, key, keylen, 1);
244 if (is_client)
245 { /* In client: use first half for receiving, second for sending. */
246 cipher_set_key(&receive_context, cipher, key, keylen / 2, 0);
247 cipher_set_key(&send_context, cipher, key + keylen / 2,
248 keylen / 2, 1);
249 }
250 else
251 { /* In server: use first half for sending, second for receiving. */
252 cipher_set_key(&receive_context, cipher, key + keylen / 2,
253 keylen / 2, 0);
254 cipher_set_key(&send_context, cipher, key, keylen / 2, 1);
255 }
256 }
257 else
258 {
259 /* All other ciphers use the same key in both directions for now. */
260 cipher_set_key(&receive_context, cipher, key, keylen, 0);
261 cipher_set_key(&send_context, cipher, key, keylen, 1);
262 }
263} 244}
264 245
265/* Starts constructing a packet to send. */ 246/* Starts constructing a packet to send. */
diff --git a/packet.h b/packet.h
index 0a4df7993..5aa4fd928 100644
--- a/packet.h
+++ b/packet.h
@@ -13,7 +13,7 @@ Interface for the packet protocol functions.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: packet.h,v 1.3 1999/11/15 04:40:55 damien Exp $"); */ 16/* RCSID("$Id: packet.h,v 1.4 1999/11/16 02:37:16 damien Exp $"); */
17 17
18#ifndef PACKET_H 18#ifndef PACKET_H
19#define PACKET_H 19#define PACKET_H
@@ -51,7 +51,7 @@ void packet_close(void);
51 are encrypted independently of each other. Cipher types are 51 are encrypted independently of each other. Cipher types are
52 defined in ssh.h. */ 52 defined in ssh.h. */
53void packet_set_encryption_key(const unsigned char *key, unsigned int keylen, 53void packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
54 int cipher_type, int is_client); 54 int cipher_type);
55 55
56/* Sets remote side protocol flags for the current connection. This can 56/* Sets remote side protocol flags for the current connection. This can
57 be called at any time. */ 57 be called at any time. */
diff --git a/ssh-add.c b/ssh-add.c
index 0f01d5dfd..2a0f0de98 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -14,7 +14,7 @@ Adds an identity to the authentication server, or removes an identity.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: ssh-add.c,v 1.8 1999/11/15 06:10:57 damien Exp $"); 17RCSID("$Id: ssh-add.c,v 1.9 1999/11/16 02:37:16 damien Exp $");
18 18
19#include "rsa.h" 19#include "rsa.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -133,33 +133,32 @@ void
133list_identities(AuthenticationConnection *ac) 133list_identities(AuthenticationConnection *ac)
134{ 134{
135 BIGNUM *e, *n; 135 BIGNUM *e, *n;
136 int bits, status; 136 int status;
137 char *comment; 137 char *comment;
138 int had_identities; 138 int had_identities;
139 139
140 e = BN_new(); 140 e = BN_new();
141 n = BN_new(); 141 n = BN_new();
142 had_identities = 0; 142 had_identities = 0;
143 for (status = ssh_get_first_identity(ac, &bits, e, n, &comment); 143 for (status = ssh_get_first_identity(ac, e, n, &comment);
144 status; 144 status;
145 status = ssh_get_next_identity(ac, &bits, e, n, &comment)) 145 status = ssh_get_next_identity(ac, e, n, &comment))
146 { 146 {
147 char *buf; 147 char *ebuf, *nbuf;
148 had_identities = 1; 148 had_identities = 1;
149 printf("%d ", bits); 149 ebuf = BN_bn2dec(e);
150 buf = BN_bn2dec(e); 150 if (ebuf == NULL) {
151 if (buf != NULL) { 151 error("list_identities: BN_bn2dec(e) failed.");
152 printf("%s ", buf); 152 }else{
153 free (buf); 153 nbuf = BN_bn2dec(n);
154 } else { 154 if (nbuf == NULL) {
155 error("list_identities: BN_bn2dec #1 failed."); 155 error("list_identities: BN_bn2dec(n) failed.");
156 } 156 }else{
157 buf = BN_bn2dec(n); 157 unsigned int bits = BN_num_bits(n);
158 if (buf != NULL) { 158 printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
159 printf("%s %s\n", buf, comment); 159 free(nbuf);
160 free (buf); 160 }
161 } else { 161 free(ebuf);
162 error("list_identities: BN_bn2dec #2 failed.");
163 } 162 }
164 xfree(comment); 163 xfree(comment);
165 } 164 }
diff --git a/ssh-agent.c b/ssh-agent.c
index 27e064d64..743cdb20d 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.16 1999/10/28 20:41:23 markus Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.18 1999/11/15 20:53:24 markus Exp $ */
2 2
3/* 3/*
4 4
@@ -16,7 +16,7 @@ The authentication agent program.
16*/ 16*/
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$OpenBSD: ssh-agent.c,v 1.17 1999/11/02 19:42:36 markus Exp $"); 19RCSID("$OpenBSD: ssh-agent.c,v 1.18 1999/11/15 20:53:24 markus Exp $");
20 20
21#include "ssh.h" 21#include "ssh.h"
22#include "rsa.h" 22#include "rsa.h"
@@ -195,6 +195,10 @@ process_remove_identity(SocketEntry *e)
195 bits = buffer_get_int(&e->input); 195 bits = buffer_get_int(&e->input);
196 buffer_get_bignum(&e->input, dummy); 196 buffer_get_bignum(&e->input, dummy);
197 buffer_get_bignum(&e->input, n); 197 buffer_get_bignum(&e->input, n);
198
199 if (bits != BN_num_bits(n))
200 error("Warning: keysize mismatch: actual %d, announced %s",
201 BN_num_bits(n), bits);
198 202
199 /* Check if we have the key. */ 203 /* Check if we have the key. */
200 for (i = 0; i < num_identities; i++) 204 for (i = 0; i < num_identities; i++)
diff --git a/ssh.c b/ssh.c
index 43950f7c5..08a32cc19 100644
--- a/ssh.c
+++ b/ssh.c
@@ -18,7 +18,7 @@ Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: ssh.c,v 1.9 1999/11/15 06:10:57 damien Exp $"); 21RCSID("$Id: ssh.c,v 1.10 1999/11/16 02:37:16 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "ssh.h" 24#include "ssh.h"
@@ -555,6 +555,13 @@ main(int ac, char **av)
555 them. Also, extra privileges could make it very hard to read identity 555 them. Also, extra privileges could make it very hard to read identity
556 files and other non-world-readable files from the user's home directory 556 files and other non-world-readable files from the user's home directory
557 if it happens to be on a NFS volume where root is mapped to nobody. */ 557 if it happens to be on a NFS volume where root is mapped to nobody. */
558
559 /* Note that some legacy systems need to postpone the following call to
560 permanently_set_uid() until the private hostkey is destroyed with
561 RSA_free(). Otherwise the calling user could ptrace() the process,
562 read the private hostkey and impersonate the host. OpenBSD does not
563 allow ptracing of setuid processes. */
564
558 permanently_set_uid(original_real_uid); 565 permanently_set_uid(original_real_uid);
559 566
560 /* Now that we are back to our own permissions, create ~/.ssh directory 567 /* Now that we are back to our own permissions, create ~/.ssh directory
diff --git a/ssh.h b/ssh.h
index ac98d1814..72685e648 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@ Generic header file for ssh.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: ssh.h,v 1.12 1999/11/12 04:19:27 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.13 1999/11/16 02:37:17 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
@@ -273,8 +273,7 @@ int auth_rhosts(struct passwd *pw, const char *client_user);
273/* Tries to authenticate the user using the .rhosts file and the host using 273/* Tries to authenticate the user using the .rhosts file and the host using
274 its host key. Returns true if authentication succeeds. */ 274 its host key. Returns true if authentication succeeds. */
275int auth_rhosts_rsa(struct passwd *pw, const char *client_user, 275int auth_rhosts_rsa(struct passwd *pw, const char *client_user,
276 unsigned int bits, BIGNUM *client_host_key_e, 276 BIGNUM *client_host_key_e, BIGNUM *client_host_key_n);
277 BIGNUM *client_host_key_n);
278 277
279/* Tries to authenticate the user using password. Returns true if 278/* Tries to authenticate the user using password. Returns true if
280 authentication succeeds. */ 279 authentication succeeds. */
@@ -319,20 +318,18 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
319 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known 318 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known
320 but used to have a different host key. The host must be in all lowercase. */ 319 but used to have a different host key. The host must be in all lowercase. */
321typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED } HostStatus; 320typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED } HostStatus;
322HostStatus check_host_in_hostfile(const char *filename, 321HostStatus check_host_in_hostfile(const char *filename, const char *host,
323 const char *host, unsigned int bits, 322 BIGNUM *e, BIGNUM *n, BIGNUM *ke, BIGNUM *kn);
324 BIGNUM *e, BIGNUM *n,
325 BIGNUM *ke, BIGNUM *kn);
326 323
327/* Appends an entry to the host file. Returns false if the entry 324/* Appends an entry to the host file. Returns false if the entry
328 could not be appended. */ 325 could not be appended. */
329int add_host_to_hostfile(const char *filename, const char *host, 326int add_host_to_hostfile(const char *filename, const char *host,
330 unsigned int bits, BIGNUM *e, BIGNUM *n); 327 BIGNUM *e, BIGNUM *n);
331 328
332/* Performs the RSA authentication challenge-response dialog with the client, 329/* Performs the RSA authentication challenge-response dialog with the client,
333 and returns true (non-zero) if the client gave the correct answer to 330 and returns true (non-zero) if the client gave the correct answer to
334 our challenge; returns zero if the client gives a wrong answer. */ 331 our challenge; returns zero if the client gives a wrong answer. */
335int auth_rsa_challenge_dialog(unsigned int bits, BIGNUM *e, BIGNUM *n); 332int auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n);
336 333
337/* Reads a passphrase from /dev/tty with echo turned off. Returns the 334/* Reads a passphrase from /dev/tty with echo turned off. Returns the
338 passphrase (allocated with xmalloc). Exits if EOF is encountered. 335 passphrase (allocated with xmalloc). Exits if EOF is encountered.
diff --git a/sshconnect.c b/sshconnect.c
index f984bcaa0..17c660979 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -15,7 +15,7 @@ login (authentication) dialog.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: sshconnect.c,v 1.8 1999/11/15 04:25:10 damien Exp $"); 18RCSID("$Id: sshconnect.c,v 1.9 1999/11/16 02:37:17 damien Exp $");
19 19
20#ifdef HAVE_OPENSSL 20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h> 21#include <openssl/bn.h>
@@ -339,7 +339,7 @@ int ssh_connect(const char *host, struct sockaddr_in *hostaddr,
339int 339int
340try_agent_authentication() 340try_agent_authentication()
341{ 341{
342 int status, type, bits; 342 int status, type;
343 char *comment; 343 char *comment;
344 AuthenticationConnection *auth; 344 AuthenticationConnection *auth;
345 unsigned char response[16]; 345 unsigned char response[16];
@@ -356,9 +356,9 @@ try_agent_authentication()
356 challenge = BN_new(); 356 challenge = BN_new();
357 357
358 /* Loop through identities served by the agent. */ 358 /* Loop through identities served by the agent. */
359 for (status = ssh_get_first_identity(auth, &bits, e, n, &comment); 359 for (status = ssh_get_first_identity(auth, e, n, &comment);
360 status; 360 status;
361 status = ssh_get_next_identity(auth, &bits, e, n, &comment)) 361 status = ssh_get_next_identity(auth, e, n, &comment))
362 { 362 {
363 int plen, clen; 363 int plen, clen;
364 364
@@ -395,7 +395,7 @@ try_agent_authentication()
395 debug("Received RSA challenge from server."); 395 debug("Received RSA challenge from server.");
396 396
397 /* Ask the agent to decrypt the challenge. */ 397 /* Ask the agent to decrypt the challenge. */
398 if (!ssh_decrypt_challenge(auth, bits, e, n, challenge, 398 if (!ssh_decrypt_challenge(auth, e, n, challenge,
399 session_id, 1, response)) 399 session_id, 1, response))
400 { 400 {
401 /* The agent failed to authenticate this identifier although it 401 /* The agent failed to authenticate this identifier although it
@@ -1128,19 +1128,15 @@ void ssh_login(int host_key_valid,
1128 SSH_SMSG_PUBLIC_KEY); 1128 SSH_SMSG_PUBLIC_KEY);
1129 1129
1130 /* Compute the session id. */ 1130 /* Compute the session id. */
1131 compute_session_id(session_id, check_bytes, 1131 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
1132 BN_num_bits(host_key->n), host_key->n,
1133 BN_num_bits(public_key->n), public_key->n);
1134 1132
1135 /* Check if the host key is present in the user\'s list of known hosts 1133 /* Check if the host key is present in the user\'s list of known hosts
1136 or in the systemwide list. */ 1134 or in the systemwide list. */
1137 host_status = check_host_in_hostfile(options.user_hostfile, 1135 host_status = check_host_in_hostfile(options.user_hostfile, host,
1138 host, BN_num_bits(host_key->n),
1139 host_key->e, host_key->n, 1136 host_key->e, host_key->n,
1140 file_key->e, file_key->n); 1137 file_key->e, file_key->n);
1141 if (host_status == HOST_NEW) 1138 if (host_status == HOST_NEW)
1142 host_status = check_host_in_hostfile(options.system_hostfile, host, 1139 host_status = check_host_in_hostfile(options.system_hostfile, host,
1143 BN_num_bits(host_key->n),
1144 host_key->e, host_key->n, 1140 host_key->e, host_key->n,
1145 file_key->e, file_key->n); 1141 file_key->e, file_key->n);
1146 /* Force accepting of the host key for localhost and 127.0.0.1. 1142 /* Force accepting of the host key for localhost and 127.0.0.1.
@@ -1161,13 +1157,11 @@ void ssh_login(int host_key_valid,
1161 ip_key->n = BN_new(); 1157 ip_key->n = BN_new();
1162 ip_key->e = BN_new(); 1158 ip_key->e = BN_new();
1163 ip_status = check_host_in_hostfile(options.user_hostfile, ip, 1159 ip_status = check_host_in_hostfile(options.user_hostfile, ip,
1164 BN_num_bits(host_key->n),
1165 host_key->e, host_key->n, 1160 host_key->e, host_key->n,
1166 ip_key->e, ip_key->n); 1161 ip_key->e, ip_key->n);
1167 1162
1168 if (ip_status == HOST_NEW) 1163 if (ip_status == HOST_NEW)
1169 ip_status = check_host_in_hostfile(options.system_hostfile, ip, 1164 ip_status = check_host_in_hostfile(options.system_hostfile, ip,
1170 BN_num_bits(host_key->n),
1171 host_key->e, host_key->n, 1165 host_key->e, host_key->n,
1172 ip_key->e, ip_key->n); 1166 ip_key->e, ip_key->n);
1173 if (host_status == HOST_CHANGED && 1167 if (host_status == HOST_CHANGED &&
@@ -1188,14 +1182,15 @@ void ssh_login(int host_key_valid,
1188 if (options.check_host_ip) { 1182 if (options.check_host_ip) {
1189 if (ip_status == HOST_NEW) { 1183 if (ip_status == HOST_NEW) {
1190 if (!add_host_to_hostfile(options.user_hostfile, ip, 1184 if (!add_host_to_hostfile(options.user_hostfile, ip,
1191 BN_num_bits(host_key->n),
1192 host_key->e, host_key->n)) 1185 host_key->e, host_key->n))
1193 log("Failed to add the host ip to the list of known hosts (%.30s).", 1186 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
1194 options.user_hostfile); 1187 ip, options.user_hostfile);
1195 else 1188 else
1196 log("Warning: Permanently added host ip '%.30s' to the list of known hosts.", ip); 1189 log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
1190 ip);
1197 } else if (ip_status != HOST_OK) 1191 } else if (ip_status != HOST_OK)
1198 log("Warning: the host key differ from the key of the ip address '%.30s' differs", ip); 1192 log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'",
1193 host, ip);
1199 } 1194 }
1200 1195
1201 break; 1196 break;
@@ -1226,7 +1221,6 @@ void ssh_login(int host_key_valid,
1226 /* If not in strict mode, add the key automatically to the local 1221 /* If not in strict mode, add the key automatically to the local
1227 known_hosts file. */ 1222 known_hosts file. */
1228 if (!add_host_to_hostfile(options.user_hostfile, hostp, 1223 if (!add_host_to_hostfile(options.user_hostfile, hostp,
1229 BN_num_bits(host_key->n),
1230 host_key->e, host_key->n)) 1224 host_key->e, host_key->n))
1231 log("Failed to add the host to the list of known hosts (%.500s).", 1225 log("Failed to add the host to the list of known hosts (%.500s).",
1232 options.user_hostfile); 1226 options.user_hostfile);
@@ -1238,13 +1232,20 @@ void ssh_login(int host_key_valid,
1238 case HOST_CHANGED: 1232 case HOST_CHANGED:
1239 if (options.check_host_ip) { 1233 if (options.check_host_ip) {
1240 if (host_ip_differ) { 1234 if (host_ip_differ) {
1235 char *msg;
1236 if (ip_status == HOST_NEW)
1237 msg = "is unknown";
1238 else if (ip_status == HOST_OK)
1239 msg = "is unchanged";
1240 else
1241 msg = "has a different value";
1241 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1242 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1242 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); 1243 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
1243 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1244 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1244 error("The host key for %s has changed,", host); 1245 error("The host key for %s has changed,", host);
1245 error("but the key for the according IP address %s has", ip); 1246 error("and the key for the according IP address %s", ip);
1246 error("a different status. This could either mean that DNS"); 1247 error("%s. This could either mean that", msg);
1247 error("SPOOFING is happening or the IP address for the host"); 1248 error("DNS SPOOFING is happening or the IP address for the host");
1248 error("and its host key have changed at the same time"); 1249 error("and its host key have changed at the same time");
1249 } 1250 }
1250 } 1251 }
@@ -1391,8 +1392,7 @@ void ssh_login(int host_key_valid,
1391 debug("Sent encrypted session key."); 1392 debug("Sent encrypted session key.");
1392 1393
1393 /* Set the encryption key. */ 1394 /* Set the encryption key. */
1394 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, 1395 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
1395 options.cipher, 1);
1396 1396
1397 /* We will no longer need the session key here. Destroy any extra copies. */ 1397 /* We will no longer need the session key here. Destroy any extra copies. */
1398 memset(session_key, 0, sizeof(session_key)); 1398 memset(session_key, 0, sizeof(session_key));
diff --git a/sshd.c b/sshd.c
index 2bf8193b7..a08252844 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: sshd.c,v 1.20 1999/11/15 06:10:57 damien Exp $"); 21RCSID("$Id: sshd.c,v 1.21 1999/11/16 02:37:17 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "rsa.h" 24#include "rsa.h"
@@ -1036,9 +1036,7 @@ do_connection()
1036 1036
1037 /* Compute session id for this session. */ 1037 /* Compute session id for this session. */
1038 compute_session_id(session_id, check_bytes, 1038 compute_session_id(session_id, check_bytes,
1039 BN_num_bits(sensitive_data.host_key->n),
1040 sensitive_data.host_key->n, 1039 sensitive_data.host_key->n,
1041 BN_num_bits(sensitive_data.private_key->n),
1042 sensitive_data.private_key->n); 1040 sensitive_data.private_key->n);
1043 1041
1044 /* Extract session key from the decrypted integer. The key is in the 1042 /* Extract session key from the decrypted integer. The key is in the
@@ -1061,8 +1059,7 @@ do_connection()
1061 1059
1062 /* Set the session key. From this on all communications will be 1060 /* Set the session key. From this on all communications will be
1063 encrypted. */ 1061 encrypted. */
1064 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, 1062 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);
1065 cipher_type, 0);
1066 1063
1067 /* Destroy our copy of the session key. It is no longer needed. */ 1064 /* Destroy our copy of the session key. It is no longer needed. */
1068 memset(session_key, 0, sizeof(session_key)); 1065 memset(session_key, 0, sizeof(session_key));
@@ -1270,7 +1267,7 @@ void
1270do_authloop(struct passwd *pw) 1267do_authloop(struct passwd *pw)
1271{ 1268{
1272 int authentication_failures = 0; 1269 int authentication_failures = 0;
1273 unsigned int client_host_key_bits; 1270 unsigned int bits;
1274 BIGNUM *client_host_key_e, *client_host_key_n; 1271 BIGNUM *client_host_key_e, *client_host_key_n;
1275 BIGNUM *n; 1272 BIGNUM *n;
1276 char *client_user = NULL, *password = NULL; 1273 char *client_user = NULL, *password = NULL;
@@ -1398,13 +1395,17 @@ do_authloop(struct passwd *pw)
1398 /* Get the client host key. */ 1395 /* Get the client host key. */
1399 client_host_key_e = BN_new(); 1396 client_host_key_e = BN_new();
1400 client_host_key_n = BN_new(); 1397 client_host_key_n = BN_new();
1401 client_host_key_bits = packet_get_int(); 1398 bits = packet_get_int();
1402 packet_get_bignum(client_host_key_e, &elen); 1399 packet_get_bignum(client_host_key_e, &elen);
1403 packet_get_bignum(client_host_key_n, &nlen); 1400 packet_get_bignum(client_host_key_n, &nlen);
1401
1402 if (bits != BN_num_bits(client_host_key_n))
1403 error("Warning: keysize mismatch for client_host_key: "
1404 "actual %d, announced %s", BN_num_bits(client_host_key_n), bits);
1404 1405
1405 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); 1406 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
1406 1407
1407 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_bits, 1408 authenticated = auth_rhosts_rsa(pw, client_user,
1408 client_host_key_e, client_host_key_n); 1409 client_host_key_e, client_host_key_n);
1409 log("Rhosts authentication %s for %.100s, remote %.100s.", 1410 log("Rhosts authentication %s for %.100s, remote %.100s.",
1410 authenticated ? "accepted" : "failed", 1411 authenticated ? "accepted" : "failed",