From: damien Date: Tue, 16 Nov 1999 02:37:16 +0000 (+0000) Subject: - Merged OpenBSD CVS changes: X-Git-Tag: V_1_2_PRE13~19 X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/commitdiff_plain/4d19544715ea43252fa1dc6ddfbfd8979506968f - Merged OpenBSD CVS changes: - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] the keysize of rsa-parameter 'n' is passed implizit, a few more checks and warnings about 'pretended' keysizes. - [cipher.c cipher.h packet.c packet.h sshd.c] remove support for cipher RC4 - [ssh.c] a note for legay systems about secuity issues with permanently_set_uid(), the private hostkey and ptrace() - [sshconnect.c] more detailed messages about adding and checking hostkeys --- diff --git a/ChangeLog b/ChangeLog index 88cf9b38..9d6d07a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +19991116 + - Fix some Linux libc5 problems reported by Miles Wilson + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] + [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] + the keysize of rsa-parameter 'n' is passed implizit, + a few more checks and warnings about 'pretended' keysizes. + - [cipher.c cipher.h packet.c packet.h sshd.c] + remove support for cipher RC4 + - [ssh.c] + a note for legay systems about secuity issues with permanently_set_uid(), + the private hostkey and ptrace() + - [sshconnect.c] + more detailed messages about adding and checking hostkeys + 19991115 - Merged OpenBSD CVS changes: - [ssh-add.c] change passphrase loop logic and remove ref to diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index 345a7b66..cb03b839 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c @@ -27,7 +27,6 @@ RCSID("$Id$"); its host key. Returns true if authentication succeeds. */ int auth_rhosts_rsa(struct passwd *pw, const char *client_user, - unsigned int client_host_key_bits, BIGNUM *client_host_key_e, BIGNUM *client_host_key_n) { extern ServerOptions options; @@ -51,8 +50,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user, ke = BN_new(); kn = BN_new(); host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, - client_host_key_bits, client_host_key_e, - client_host_key_n, ke, kn); + client_host_key_e, client_host_key_n, ke, kn); /* Check user host file unless ignored. */ 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, /* XXX race between stat and the following open() */ temporarily_use_uid(pw->pw_uid); host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, - client_host_key_bits, client_host_key_e, - client_host_key_n, ke, kn); + client_host_key_e, client_host_key_n, ke, kn); restore_uid(); } xfree(user_hostfile); @@ -89,8 +86,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user, /* A matching host key was found and is known. */ /* Perform the challenge-response dialog with the client for the host key. */ - if (!auth_rsa_challenge_dialog(client_host_key_bits, - client_host_key_e, client_host_key_n)) + if (!auth_rsa_challenge_dialog(client_host_key_e, client_host_key_n)) { log("Client on %.800s failed to respond correctly to host authentication.", canonical_hostname); diff --git a/auth-rsa.c b/auth-rsa.c index 86aa72de..c4e52fbb 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -61,7 +61,7 @@ extern unsigned char session_id[16]; our challenge; returns zero if the client gives a wrong answer. */ int -auth_rsa_challenge_dialog(unsigned int bits, BIGNUM *e, BIGNUM *n) +auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) { BIGNUM *challenge, *encrypted_challenge, *aux; RSA *pk; @@ -138,7 +138,7 @@ int auth_rsa(struct passwd *pw, BIGNUM *client_n) { extern ServerOptions options; - char line[8192]; + char line[8192], file[1024]; int authenticated; unsigned int bits; FILE *f; @@ -150,11 +150,11 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) temporarily_use_uid(pw->pw_uid); /* The authorized keys. */ - snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, SSH_USER_PERMITTED_KEYS); /* Fail quietly if file does not exist */ - if (stat(line, &st) < 0) + if (stat(file, &st) < 0) { /* Restore the privileged uid. */ restore_uid(); @@ -162,12 +162,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) } /* Open the file containing the authorized keys. */ - f = fopen(line, "r"); + f = fopen(file, "r"); if (!f) { /* Restore the privileged uid. */ restore_uid(); - packet_send_debug("Could not open %.900s for reading.", line); + packet_send_debug("Could not open %.900s for reading.", file); packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); return 0; } @@ -180,7 +180,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) (st.st_uid != 0 && st.st_uid != pw->pw_uid) || (st.st_mode & 022) != 0) { snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " - "bad ownership or modes for '%s'.", pw->pw_name, line); + "bad ownership or modes for '%s'.", pw->pw_name, file); fail=1; }else{ /* Check path to SSH_USER_PERMITTED_KEYS */ @@ -263,6 +263,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) } /* cp now points to the comment part. */ + /* check the real bits */ + if (bits != BN_num_bits(n)) + error("Warning: error in %s, line %d: keysize mismatch: " + "actual size %d vs. announced %d.", + file, linenum, BN_num_bits(n), bits); + /* Check if the we have found the desired key (identified by its modulus). */ if (BN_cmp(n, client_n) != 0) @@ -271,7 +277,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) /* We have found the desired key. */ /* Perform the challenge-response dialog for this key. */ - if (!auth_rsa_challenge_dialog(bits, e, n)) + if (!auth_rsa_challenge_dialog(e, n)) { /* Wrong response. */ log("Wrong response to RSA authentication challenge."); diff --git a/authfd.c b/authfd.c index 5317b330..e7bd61cc 100644 --- a/authfd.c +++ b/authfd.c @@ -117,7 +117,7 @@ void ssh_close_authentication_connection(AuthenticationConnection *ac) int ssh_get_first_identity(AuthenticationConnection *auth, - int *bitsp, BIGNUM *e, BIGNUM *n, char **comment) + BIGNUM *e, BIGNUM *n, char **comment) { unsigned char msg[8192]; int len, l; @@ -179,7 +179,7 @@ ssh_get_first_identity(AuthenticationConnection *auth, fatal("Too many identities in authentication reply: %d\n", auth->howmany); /* Return the first entry (if any). */ - return ssh_get_next_identity(auth, bitsp, e, n, comment); + return ssh_get_next_identity(auth, e, n, comment); } /* Returns the next authentication identity for the agent. Other functions @@ -189,19 +189,25 @@ ssh_get_first_identity(AuthenticationConnection *auth, int ssh_get_next_identity(AuthenticationConnection *auth, - int *bitsp, BIGNUM *e, BIGNUM *n, char **comment) + BIGNUM *e, BIGNUM *n, char **comment) { + unsigned int bits; + /* Return failure if no more entries. */ if (auth->howmany <= 0) return 0; /* Get the next entry from the packet. These will abort with a fatal error if the packet is too short or contains corrupt data. */ - *bitsp = buffer_get_int(&auth->identities); + bits = buffer_get_int(&auth->identities); buffer_get_bignum(&auth->identities, e); buffer_get_bignum(&auth->identities, n); *comment = buffer_get_string(&auth->identities, NULL); + if (bits != BN_num_bits(n)) + error("Warning: keysize mismatch: actual %d, announced %s", + BN_num_bits(n), bits); + /* Decrement the number of remaining entries. */ auth->howmany--; @@ -216,7 +222,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, int ssh_decrypt_challenge(AuthenticationConnection *auth, - int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge, + BIGNUM *e, BIGNUM *n, BIGNUM *challenge, unsigned char session_id[16], unsigned int response_type, unsigned char response[16]) @@ -233,7 +239,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth, buf[0] = SSH_AGENTC_RSA_CHALLENGE; buffer_init(&buffer); buffer_append(&buffer, (char *)buf, 1); - buffer_put_int(&buffer, bits); + buffer_put_int(&buffer, BN_num_bits(n)); buffer_put_bignum(&buffer, e); buffer_put_bignum(&buffer, n); buffer_put_bignum(&buffer, challenge); diff --git a/authfd.h b/authfd.h index 459a2020..7b54d639 100644 --- a/authfd.h +++ b/authfd.h @@ -62,19 +62,19 @@ void ssh_close_authentication_connection(AuthenticationConnection *ac); The caller must initialize the integers before the call, and free the comment after a successful call (before calling ssh_get_next_identity). */ int ssh_get_first_identity(AuthenticationConnection *connection, - int *bitsp, BIGNUM *e, BIGNUM *n, char **comment); + BIGNUM *e, BIGNUM *n, char **comment); /* Returns the next authentication identity for the agent. Other functions can be called between this and ssh_get_first_identity or two calls of this function. This returns 0 if there are no more identities. The caller must free comment after a successful return. */ int ssh_get_next_identity(AuthenticationConnection *connection, - int *bitsp, BIGNUM *e, BIGNUM *n, char **comment); + BIGNUM *e, BIGNUM *n, char **comment); /* Requests the agent to decrypt the given challenge. Returns true if the agent claims it was able to decrypt it. */ int ssh_decrypt_challenge(AuthenticationConnection *auth, - int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge, + BIGNUM *e, BIGNUM *n, BIGNUM *challenge, unsigned char session_id[16], unsigned int response_type, unsigned char response[16]); diff --git a/cipher.c b/cipher.c index b55a4ac5..f0da856e 100644 --- a/cipher.c +++ b/cipher.c @@ -235,7 +235,7 @@ void cipher_set_key(CipherContext *context, int cipher, break; default: - fatal("cipher_set_key: unknown cipher: %d", cipher); + fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); } memset(padded, 0, sizeof(padded)); } diff --git a/cipher.h b/cipher.h index d04855a4..90b02c11 100644 --- a/cipher.h +++ b/cipher.h @@ -13,11 +13,11 @@ Created: Wed Apr 19 16:50:42 1995 ylo /* RCSID("$Id$"); */ -#include "config.h" - #ifndef CIPHER_H #define CIPHER_H +#include "config.h" + #ifdef HAVE_OPENSSL #include #include @@ -34,8 +34,8 @@ Created: Wed Apr 19 16:50:42 1995 ylo #define SSH_CIPHER_IDEA 1 /* IDEA CFB */ #define SSH_CIPHER_DES 2 /* DES CBC */ #define SSH_CIPHER_3DES 3 /* 3DES CBC */ -#define SSH_CIPHER_TSS 4 /* TRI's Simple Stream encryption CBC */ -#define SSH_CIPHER_RC4 5 /* Alleged RC4 */ +#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ #define SSH_CIPHER_BLOWFISH 6 typedef struct { diff --git a/hostfile.c b/hostfile.c index 2bf077e9..04e9a355 100644 --- a/hostfile.c +++ b/hostfile.c @@ -166,29 +166,20 @@ match_hostname(const char *host, const char *pattern, unsigned int len) but used to have a different host key. */ HostStatus -check_host_in_hostfile(const char *filename, - const char *host, unsigned int bits, - BIGNUM *e, BIGNUM *n, - BIGNUM *ke, BIGNUM *kn) +check_host_in_hostfile(const char *filename, const char *host, + BIGNUM *e, BIGNUM *n, BIGNUM *ke, BIGNUM *kn) { FILE *f; char line[8192]; - unsigned int kbits, hostlen; + int linenum = 0; + unsigned int bits, kbits, hostlen; char *cp, *cp2; HostStatus end_return; - struct stat st; /* Open the file containing the list of known hosts. */ f = fopen(filename, "r"); if (!f) - { - if (stat(filename, &st) >= 0) - { - packet_send_debug("Could not open %.900s for reading.", filename); - packet_send_debug("If your home directory is on an NFS volume, it may need to be world-readable."); - } - return HOST_NEW; - } + return HOST_NEW; /* Cache the length of the host name. */ hostlen = strlen(host); @@ -198,10 +189,14 @@ check_host_in_hostfile(const char *filename, one. */ end_return = HOST_NEW; + /* size of modulus 'n' */ + bits = BN_num_bits(n); + /* Go trough the file. */ while (fgets(line, sizeof(line), f)) { cp = line; + linenum++; /* Skip any leading whitespace. */ for (; *cp == ' ' || *cp == '\t'; cp++) @@ -227,7 +222,15 @@ check_host_in_hostfile(const char *filename, if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) continue; - /* Check if the current key is the same as the previous one. */ + if (kbits != BN_num_bits(kn)) { + error("Warning: error in %s, line %d: keysize mismatch for host %s: " + "actual size %d vs. announced %d.", + filename, linenum, host, BN_num_bits(kn), kbits); + error("Warning: replace %d with %d in %s, line %d.", + kbits, BN_num_bits(kn), filename, linenum); + } + + /* Check if the current key is the same as the given key. */ if (kbits == bits && BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) { /* Ok, they match. */ @@ -252,21 +255,25 @@ check_host_in_hostfile(const char *filename, int add_host_to_hostfile(const char *filename, const char *host, - unsigned int bits, BIGNUM *e, BIGNUM *n) + BIGNUM *e, BIGNUM *n) { FILE *f; char *buf; + unsigned int bits; /* Open the file for appending. */ f = fopen(filename, "a"); if (!f) return 0; + /* size of modulus 'n' */ + bits = BN_num_bits(n); + /* Print the host name and key to the file. */ fprintf(f, "%s %u ", host, bits); buf = BN_bn2dec(e); if (buf == NULL) { - error("add_host_to_hostfile: BN_bn2dec #1 failed"); + error("add_host_to_hostfile: BN_bn2dec(e) failed"); fclose(f); return 0; } @@ -274,7 +281,7 @@ add_host_to_hostfile(const char *filename, const char *host, free (buf); buf = BN_bn2dec(n); if (buf == NULL) { - error("add_host_to_hostfile: BN_bn2dec #2 failed"); + error("add_host_to_hostfile: BN_bn2dec(n) failed"); fclose(f); return 0; } diff --git a/mpaux.c b/mpaux.c index d6e79455..fbc986cf 100644 --- a/mpaux.c +++ b/mpaux.c @@ -33,15 +33,15 @@ RCSID("$Id$"); void compute_session_id(unsigned char session_id[16], unsigned char cookie[8], - unsigned int host_key_bits, BIGNUM *host_key_n, - unsigned int session_key_bits, BIGNUM *session_key_n) { + unsigned int host_key_bits = BN_num_bits(host_key_n); + unsigned int session_key_bits = BN_num_bits(session_key_n); unsigned int bytes = (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8 + 8; unsigned char *buf = xmalloc(bytes); MD5_CTX md; - + BN_bn2bin(host_key_n, buf); BN_bn2bin(session_key_n, buf + (host_key_bits + 7 ) / 8); memcpy(buf + (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8, diff --git a/mpaux.h b/mpaux.h index 240d6f7f..4d50688b 100644 --- a/mpaux.h +++ b/mpaux.h @@ -24,9 +24,7 @@ precision integers. first representations of host_key_n, session_key_n, and the cookie. */ void compute_session_id(unsigned char session_id[16], unsigned char cookie[8], - unsigned int host_key_bits, BIGNUM *host_key_n, - unsigned int session_key_bits, BIGNUM *session_key_n); #endif /* MPAUX_H */ diff --git a/packet.c b/packet.c index 7a56c88f..18692082 100644 --- a/packet.c +++ b/packet.c @@ -236,30 +236,11 @@ packet_decrypt(CipherContext *cc, void *dest, void *src, void packet_set_encryption_key(const unsigned char *key, unsigned int keylen, - int cipher, int is_client) + int cipher) { - cipher_type = cipher; - if (cipher == SSH_CIPHER_RC4) - { - if (is_client) - { /* In client: use first half for receiving, second for sending. */ - cipher_set_key(&receive_context, cipher, key, keylen / 2, 0); - cipher_set_key(&send_context, cipher, key + keylen / 2, - keylen / 2, 1); - } - else - { /* In server: use first half for sending, second for receiving. */ - cipher_set_key(&receive_context, cipher, key + keylen / 2, - keylen / 2, 0); - cipher_set_key(&send_context, cipher, key, keylen / 2, 1); - } - } - else - { - /* All other ciphers use the same key in both directions for now. */ - cipher_set_key(&receive_context, cipher, key, keylen, 0); - cipher_set_key(&send_context, cipher, key, keylen, 1); - } + /* All other ciphers use the same key in both directions for now. */ + cipher_set_key(&receive_context, cipher, key, keylen, 0); + cipher_set_key(&send_context, cipher, key, keylen, 1); } /* Starts constructing a packet to send. */ diff --git a/packet.h b/packet.h index 9746fcca..f317f4a1 100644 --- a/packet.h +++ b/packet.h @@ -51,7 +51,7 @@ void packet_close(void); are encrypted independently of each other. Cipher types are defined in ssh.h. */ void packet_set_encryption_key(const unsigned char *key, unsigned int keylen, - int cipher_type, int is_client); + int cipher_type); /* Sets remote side protocol flags for the current connection. This can be called at any time. */ diff --git a/ssh-add.c b/ssh-add.c index 30c67cd0..58224415 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -133,33 +133,32 @@ void list_identities(AuthenticationConnection *ac) { BIGNUM *e, *n; - int bits, status; + int status; char *comment; int had_identities; e = BN_new(); n = BN_new(); had_identities = 0; - for (status = ssh_get_first_identity(ac, &bits, e, n, &comment); + for (status = ssh_get_first_identity(ac, e, n, &comment); status; - status = ssh_get_next_identity(ac, &bits, e, n, &comment)) + status = ssh_get_next_identity(ac, e, n, &comment)) { - char *buf; + char *ebuf, *nbuf; had_identities = 1; - printf("%d ", bits); - buf = BN_bn2dec(e); - if (buf != NULL) { - printf("%s ", buf); - free (buf); - } else { - error("list_identities: BN_bn2dec #1 failed."); - } - buf = BN_bn2dec(n); - if (buf != NULL) { - printf("%s %s\n", buf, comment); - free (buf); - } else { - error("list_identities: BN_bn2dec #2 failed."); + ebuf = BN_bn2dec(e); + if (ebuf == NULL) { + error("list_identities: BN_bn2dec(e) failed."); + }else{ + nbuf = BN_bn2dec(n); + if (nbuf == NULL) { + error("list_identities: BN_bn2dec(n) failed."); + }else{ + unsigned int bits = BN_num_bits(n); + printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); + free(nbuf); + } + free(ebuf); } xfree(comment); } diff --git a/ssh-agent.c b/ssh-agent.c index 27e064d6..743cdb20 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.16 1999/10/28 20:41:23 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.18 1999/11/15 20:53:24 markus Exp $ */ /* @@ -16,7 +16,7 @@ The authentication agent program. */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.17 1999/11/02 19:42:36 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.18 1999/11/15 20:53:24 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -195,6 +195,10 @@ process_remove_identity(SocketEntry *e) bits = buffer_get_int(&e->input); buffer_get_bignum(&e->input, dummy); buffer_get_bignum(&e->input, n); + + if (bits != BN_num_bits(n)) + error("Warning: keysize mismatch: actual %d, announced %s", + BN_num_bits(n), bits); /* Check if we have the key. */ for (i = 0; i < num_identities; i++) diff --git a/ssh.c b/ssh.c index 7e66b52f..28fa3290 100644 --- a/ssh.c +++ b/ssh.c @@ -555,6 +555,13 @@ main(int ac, char **av) them. Also, extra privileges could make it very hard to read identity files and other non-world-readable files from the user's home directory if it happens to be on a NFS volume where root is mapped to nobody. */ + + /* Note that some legacy systems need to postpone the following call to + permanently_set_uid() until the private hostkey is destroyed with + RSA_free(). Otherwise the calling user could ptrace() the process, + read the private hostkey and impersonate the host. OpenBSD does not + allow ptracing of setuid processes. */ + permanently_set_uid(original_real_uid); /* Now that we are back to our own permissions, create ~/.ssh directory diff --git a/ssh.h b/ssh.h index 653dfc2b..78332471 100644 --- a/ssh.h +++ b/ssh.h @@ -273,8 +273,7 @@ int auth_rhosts(struct passwd *pw, const char *client_user); /* Tries to authenticate the user using the .rhosts file and the host using its host key. Returns true if authentication succeeds. */ int auth_rhosts_rsa(struct passwd *pw, const char *client_user, - unsigned int bits, BIGNUM *client_host_key_e, - BIGNUM *client_host_key_n); + BIGNUM *client_host_key_e, BIGNUM *client_host_key_n); /* Tries to authenticate the user using password. Returns true if authentication succeeds. */ @@ -319,20 +318,18 @@ int match_hostname(const char *host, const char *pattern, unsigned int len); HOST_NEW if the host is not known, and HOST_CHANGED if the host is known but used to have a different host key. The host must be in all lowercase. */ typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED } HostStatus; -HostStatus check_host_in_hostfile(const char *filename, - const char *host, unsigned int bits, - BIGNUM *e, BIGNUM *n, - BIGNUM *ke, BIGNUM *kn); +HostStatus check_host_in_hostfile(const char *filename, const char *host, + BIGNUM *e, BIGNUM *n, BIGNUM *ke, BIGNUM *kn); /* Appends an entry to the host file. Returns false if the entry could not be appended. */ int add_host_to_hostfile(const char *filename, const char *host, - unsigned int bits, BIGNUM *e, BIGNUM *n); + BIGNUM *e, BIGNUM *n); /* Performs the RSA authentication challenge-response dialog with the client, and returns true (non-zero) if the client gave the correct answer to our challenge; returns zero if the client gives a wrong answer. */ -int auth_rsa_challenge_dialog(unsigned int bits, BIGNUM *e, BIGNUM *n); +int auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n); /* Reads a passphrase from /dev/tty with echo turned off. Returns the passphrase (allocated with xmalloc). Exits if EOF is encountered. diff --git a/sshconnect.c b/sshconnect.c index 4b5a6660..5ff24aca 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -339,7 +339,7 @@ int ssh_connect(const char *host, struct sockaddr_in *hostaddr, int try_agent_authentication() { - int status, type, bits; + int status, type; char *comment; AuthenticationConnection *auth; unsigned char response[16]; @@ -356,9 +356,9 @@ try_agent_authentication() challenge = BN_new(); /* Loop through identities served by the agent. */ - for (status = ssh_get_first_identity(auth, &bits, e, n, &comment); + for (status = ssh_get_first_identity(auth, e, n, &comment); status; - status = ssh_get_next_identity(auth, &bits, e, n, &comment)) + status = ssh_get_next_identity(auth, e, n, &comment)) { int plen, clen; @@ -395,7 +395,7 @@ try_agent_authentication() debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ - if (!ssh_decrypt_challenge(auth, bits, e, n, challenge, + if (!ssh_decrypt_challenge(auth, e, n, challenge, session_id, 1, response)) { /* The agent failed to authenticate this identifier although it @@ -1128,19 +1128,15 @@ void ssh_login(int host_key_valid, SSH_SMSG_PUBLIC_KEY); /* Compute the session id. */ - compute_session_id(session_id, check_bytes, - BN_num_bits(host_key->n), host_key->n, - BN_num_bits(public_key->n), public_key->n); + compute_session_id(session_id, check_bytes, host_key->n, public_key->n); /* Check if the host key is present in the user\'s list of known hosts or in the systemwide list. */ - host_status = check_host_in_hostfile(options.user_hostfile, - host, BN_num_bits(host_key->n), + host_status = check_host_in_hostfile(options.user_hostfile, host, host_key->e, host_key->n, file_key->e, file_key->n); if (host_status == HOST_NEW) host_status = check_host_in_hostfile(options.system_hostfile, host, - BN_num_bits(host_key->n), host_key->e, host_key->n, file_key->e, file_key->n); /* Force accepting of the host key for localhost and 127.0.0.1. @@ -1161,13 +1157,11 @@ void ssh_login(int host_key_valid, ip_key->n = BN_new(); ip_key->e = BN_new(); ip_status = check_host_in_hostfile(options.user_hostfile, ip, - BN_num_bits(host_key->n), host_key->e, host_key->n, ip_key->e, ip_key->n); if (ip_status == HOST_NEW) ip_status = check_host_in_hostfile(options.system_hostfile, ip, - BN_num_bits(host_key->n), host_key->e, host_key->n, ip_key->e, ip_key->n); if (host_status == HOST_CHANGED && @@ -1188,14 +1182,15 @@ void ssh_login(int host_key_valid, if (options.check_host_ip) { if (ip_status == HOST_NEW) { if (!add_host_to_hostfile(options.user_hostfile, ip, - BN_num_bits(host_key->n), host_key->e, host_key->n)) - log("Failed to add the host ip to the list of known hosts (%.30s).", - options.user_hostfile); + log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", + ip, options.user_hostfile); else - log("Warning: Permanently added host ip '%.30s' to the list of known hosts.", ip); + log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", + ip); } else if (ip_status != HOST_OK) - log("Warning: the host key differ from the key of the ip address '%.30s' differs", ip); + log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'", + host, ip); } break; @@ -1226,7 +1221,6 @@ void ssh_login(int host_key_valid, /* If not in strict mode, add the key automatically to the local known_hosts file. */ if (!add_host_to_hostfile(options.user_hostfile, hostp, - BN_num_bits(host_key->n), host_key->e, host_key->n)) log("Failed to add the host to the list of known hosts (%.500s).", options.user_hostfile); @@ -1238,13 +1232,20 @@ void ssh_login(int host_key_valid, case HOST_CHANGED: if (options.check_host_ip) { if (host_ip_differ) { + char *msg; + if (ip_status == HOST_NEW) + msg = "is unknown"; + else if (ip_status == HOST_OK) + msg = "is unchanged"; + else + msg = "has a different value"; error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The host key for %s has changed,", host); - error("but the key for the according IP address %s has", ip); - error("a different status. This could either mean that DNS"); - error("SPOOFING is happening or the IP address for the host"); + error("and the key for the according IP address %s", ip); + error("%s. This could either mean that", msg); + error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time"); } } @@ -1391,8 +1392,7 @@ void ssh_login(int host_key_valid, debug("Sent encrypted session key."); /* Set the encryption key. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, - options.cipher, 1); + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); /* We will no longer need the session key here. Destroy any extra copies. */ memset(session_key, 0, sizeof(session_key)); diff --git a/sshd.c b/sshd.c index 7a641cf4..91d594c7 100644 --- a/sshd.c +++ b/sshd.c @@ -1036,9 +1036,7 @@ do_connection() /* Compute session id for this session. */ compute_session_id(session_id, check_bytes, - BN_num_bits(sensitive_data.host_key->n), sensitive_data.host_key->n, - BN_num_bits(sensitive_data.private_key->n), sensitive_data.private_key->n); /* Extract session key from the decrypted integer. The key is in the @@ -1061,8 +1059,7 @@ do_connection() /* Set the session key. From this on all communications will be encrypted. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, - cipher_type, 0); + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); /* Destroy our copy of the session key. It is no longer needed. */ memset(session_key, 0, sizeof(session_key)); @@ -1270,7 +1267,7 @@ void do_authloop(struct passwd *pw) { int authentication_failures = 0; - unsigned int client_host_key_bits; + unsigned int bits; BIGNUM *client_host_key_e, *client_host_key_n; BIGNUM *n; char *client_user = NULL, *password = NULL; @@ -1398,13 +1395,17 @@ do_authloop(struct passwd *pw) /* Get the client host key. */ client_host_key_e = BN_new(); client_host_key_n = BN_new(); - client_host_key_bits = packet_get_int(); + bits = packet_get_int(); packet_get_bignum(client_host_key_e, &elen); packet_get_bignum(client_host_key_n, &nlen); + + if (bits != BN_num_bits(client_host_key_n)) + error("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %s", BN_num_bits(client_host_key_n), bits); packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); - authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_bits, + authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_e, client_host_key_n); log("Rhosts authentication %s for %.100s, remote %.100s.", authenticated ? "accepted" : "failed",