=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/Attic/sshconnect1.c,v retrieving revision 1.41.2.4 retrieving revision 1.42 diff -u -r1.41.2.4 -r1.42 --- src/usr.bin/ssh/Attic/sshconnect1.c 2002/10/11 14:53:07 1.41.2.4 +++ src/usr.bin/ssh/Attic/sshconnect1.c 2001/12/19 07:18:56 1.42 @@ -13,10 +13,10 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.41.2.4 2002/10/11 14:53:07 miod Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.42 2001/12/19 07:18:56 deraadt Exp $"); #include -#include +#include #ifdef KRB4 #include @@ -67,6 +67,7 @@ AuthenticationConnection *auth; u_char response[16]; u_int i; + int plen, clen; Key *key; BIGNUM *challenge; @@ -75,8 +76,8 @@ if (!auth) return 0; - if ((challenge = BN_new()) == NULL) - fatal("try_agent_authentication: BN_new failed"); + challenge = BN_new(); + /* Loop through identities served by the agent. */ for (key = ssh_get_first_identity(auth, &comment, 1); key != NULL; @@ -93,7 +94,7 @@ packet_write_wait(); /* Wait for server's response. */ - type = packet_read(); + type = packet_read(&plen); /* The server sends failure if it doesn\'t like our key or does not support RSA authentication. */ @@ -107,9 +108,10 @@ packet_disconnect("Protocol error during RSA authentication: %d", type); - packet_get_bignum(challenge); - packet_check_eom(); + packet_get_bignum(challenge, &clen); + packet_integrity_check(plen, clen, type); + debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ @@ -133,7 +135,7 @@ packet_write_wait(); /* Wait for response from the server. */ - type = packet_read(); + type = packet_read(&plen); /* The server returns success if it accepted the authentication. */ if (type == SSH_SMSG_SUCCESS) { @@ -208,7 +210,7 @@ BIGNUM *challenge; Key *public, *private; char buf[300], *passphrase, *comment, *authfile; - int i, type, quit; + int i, type, quit, plen, clen; public = options.identity_keys[idx]; authfile = options.identity_files[idx]; @@ -223,7 +225,7 @@ packet_write_wait(); /* Wait for server's response. */ - type = packet_read(); + type = packet_read(&plen); /* * The server responds with failure if it doesn\'t like our key or @@ -239,11 +241,11 @@ packet_disconnect("Protocol error during RSA authentication: %d", type); /* Get the challenge from the packet. */ - if ((challenge = BN_new()) == NULL) - fatal("try_rsa_authentication: BN_new failed"); - packet_get_bignum(challenge); - packet_check_eom(); + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + packet_integrity_check(plen, clen, type); + debug("Received RSA challenge from server."); /* @@ -251,7 +253,7 @@ * load the private key. Try first with empty passphrase; if it * fails, ask for a passphrase. */ - if (public->flags & KEY_FLAG_EXT) + if (public->flags && KEY_FLAG_EXT) private = public; else private = key_load_private_type(KEY_RSA1, authfile, "", NULL); @@ -290,7 +292,7 @@ packet_write_wait(); /* Expect the server to reject it... */ - packet_read_expect(SSH_SMSG_FAILURE); + packet_read_expect(&plen, SSH_SMSG_FAILURE); BN_clear_free(challenge); return 0; } @@ -306,7 +308,7 @@ BN_clear_free(challenge); /* Wait for response from the server. */ - type = packet_read(); + type = packet_read(&plen); if (type == SSH_SMSG_SUCCESS) { debug("RSA authentication accepted by server."); return 1; @@ -326,6 +328,7 @@ { int type; BIGNUM *challenge; + int plen, clen; debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); @@ -339,7 +342,7 @@ packet_write_wait(); /* Wait for server's response. */ - type = packet_read(); + type = packet_read(&plen); /* The server responds with failure if it doesn't admit our .rhosts authentication or doesn't know our host key. */ @@ -352,11 +355,11 @@ packet_disconnect("Protocol error during RSA authentication: %d", type); /* Get the challenge from the packet. */ - if ((challenge = BN_new()) == NULL) - fatal("try_rhosts_rsa_authentication: BN_new failed"); - packet_get_bignum(challenge); - packet_check_eom(); + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + packet_integrity_check(plen, clen, type); + debug("Received RSA challenge for host key from server."); /* Compute a response to the challenge. */ @@ -366,7 +369,7 @@ BN_clear_free(challenge); /* Wait for response from the server. */ - type = packet_read(); + type = packet_read(&plen); if (type == SSH_SMSG_SUCCESS) { debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); return 1; @@ -386,7 +389,7 @@ char inst[INST_SZ]; char *realm; CREDENTIALS cred; - int r, type; + int r, type, plen; socklen_t slen; Key_schedule schedule; u_long checksum, cksum; @@ -445,7 +448,7 @@ fatal_cleanup(); } /* Get server reply. */ - type = packet_read(); + type = packet_read(&plen); switch (type) { case SSH_SMSG_FAILURE: /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ @@ -459,12 +462,10 @@ /* Get server's response. */ reply = packet_get_string((u_int *) &auth.length); - if (auth.length >= MAX_KTXT_LEN) - fatal("Kerberos v4: Malformed response from server"); memcpy(auth.dat, reply, auth.length); xfree(reply); - packet_check_eom(); + packet_integrity_check(plen, 4 + auth.length, type); /* * If his response isn't properly encrypted with the session @@ -509,7 +510,7 @@ krb5_ccache ccache = NULL; const char *remotehost; krb5_data ap; - int type; + int type, payload_len; krb5_ap_rep_enc_part *reply = NULL; int ret; @@ -559,7 +560,7 @@ xfree(ap.data); ap.length = 0; - type = packet_read(); + type = packet_read(&payload_len); switch (type) { case SSH_SMSG_FAILURE: /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ @@ -573,7 +574,8 @@ /* Get server's response. */ ap.data = packet_get_string((unsigned int *) &ap.length); - packet_check_eom(); + + packet_integrity_check(payload_len, 4 + ap.length, type); /* XXX je to dobre? */ problem = krb5_rd_rep(*context, *auth_context, &ap, &reply); @@ -605,7 +607,7 @@ static void send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) { - int fd, type; + int fd, type, payload_len; krb5_error_code problem; krb5_data outbuf; krb5_ccache ccache = NULL; @@ -655,7 +657,7 @@ packet_send(); packet_write_wait(); - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) { char *pname; @@ -690,7 +692,7 @@ CREDENTIALS *creds; struct stat st; char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - int problem, type; + int problem, type, len; /* Don't do anything if we don't have any tickets. */ if (stat(tkt_string(), &st) < 0) @@ -717,7 +719,7 @@ packet_send(); packet_write_wait(); - type = packet_read(); + type = packet_read(&len); if (type == SSH_SMSG_SUCCESS) debug("Kerberos v4 TGT forwarded (%s%s%s@%s).", @@ -795,7 +797,7 @@ /* Roger, Roger. Clearance, Clarence. What's your vector, Victor? */ - type = packet_read(); + type = packet_read(&len); if (type == SSH_SMSG_FAILURE) debug("AFS token for cell %s rejected.", server_cell); @@ -814,6 +816,7 @@ try_challenge_response_authentication(void) { int type, i; + int payload_len; u_int clen; char prompt[1024]; char *challenge, *response; @@ -826,7 +829,7 @@ packet_send(); packet_write_wait(); - type = packet_read(); + type = packet_read(&payload_len); if (type != SSH_SMSG_FAILURE && type != SSH_SMSG_AUTH_TIS_CHALLENGE) { packet_disconnect("Protocol error: got %d in response " @@ -837,7 +840,7 @@ return 0; } challenge = packet_get_string(&clen); - packet_check_eom(); + packet_integrity_check(payload_len, (4 + clen), type); snprintf(prompt, sizeof prompt, "%s%s", challenge, strchr(challenge, '\n') ? "" : "\nResponse: "); xfree(challenge); @@ -845,7 +848,7 @@ error("Permission denied, please try again."); if (options.cipher == SSH_CIPHER_NONE) log("WARNING: Encryption is disabled! " - "Response will be transmitted in clear text."); + "Reponse will be transmitted in clear text."); response = read_passphrase(prompt, 0); if (strcmp(response, "") == 0) { xfree(response); @@ -857,7 +860,7 @@ xfree(response); packet_send(); packet_write_wait(); - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) return 1; if (type != SSH_SMSG_FAILURE) @@ -874,7 +877,7 @@ static int try_password_authentication(char *prompt) { - int type, i; + int type, i, payload_len; char *password; debug("Doing password authentication."); @@ -891,7 +894,7 @@ packet_send(); packet_write_wait(); - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) return 1; if (type != SSH_SMSG_FAILURE) @@ -909,43 +912,54 @@ { int i; BIGNUM *key; - Key *host_key, *server_key; + RSA *host_key; + RSA *public_key; + Key k; int bits, rbits; int ssh_cipher_default = SSH_CIPHER_3DES; u_char session_key[SSH_SESSION_KEY_LENGTH]; u_char cookie[8]; u_int supported_ciphers; u_int server_flags, client_flags; + int payload_len, clen, sum_len = 0; u_int32_t rand = 0; debug("Waiting for server public key."); /* Wait for a public key packet from the server. */ - packet_read_expect(SSH_SMSG_PUBLIC_KEY); + packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); /* Get cookie from the packet. */ for (i = 0; i < 8; i++) cookie[i] = packet_get_char(); /* Get the public key. */ - server_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(server_key->rsa->e); - packet_get_bignum(server_key->rsa->n); + public_key = RSA_new(); + bits = packet_get_int();/* bits */ + public_key->e = BN_new(); + packet_get_bignum(public_key->e, &clen); + sum_len += clen; + public_key->n = BN_new(); + packet_get_bignum(public_key->n, &clen); + sum_len += clen; - rbits = BN_num_bits(server_key->rsa->n); + rbits = BN_num_bits(public_key->n); if (bits != rbits) { log("Warning: Server lies about size of server public key: " "actual size is %d bits vs. announced %d.", rbits, bits); log("Warning: This may be due to an old implementation of ssh."); } /* Get the host key. */ - host_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(host_key->rsa->e); - packet_get_bignum(host_key->rsa->n); + host_key = RSA_new(); + bits = packet_get_int();/* bits */ + host_key->e = BN_new(); + packet_get_bignum(host_key->e, &clen); + sum_len += clen; + host_key->n = BN_new(); + packet_get_bignum(host_key->n, &clen); + sum_len += clen; - rbits = BN_num_bits(host_key->rsa->n); + rbits = BN_num_bits(host_key->n); if (bits != rbits) { log("Warning: Server lies about size of server host key: " "actual size is %d bits vs. announced %d.", rbits, bits); @@ -958,17 +972,21 @@ supported_ciphers = packet_get_int(); supported_authentications = packet_get_int(); - packet_check_eom(); debug("Received server public key (%d bits) and host key (%d bits).", - BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); + BN_num_bits(public_key->n), BN_num_bits(host_key->n)); - if (verify_host_key(host, hostaddr, host_key) == -1) + packet_integrity_check(payload_len, + 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, + SSH_SMSG_PUBLIC_KEY); + k.type = KEY_RSA1; + k.rsa = host_key; + if (verify_host_key(host, hostaddr, &k) == -1) fatal("Host key verification failed."); client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n); + compute_session_id(session_id, cookie, host_key->n, public_key->n); /* Generate a session key. */ arc4random_stir(); @@ -990,8 +1008,7 @@ * is the highest byte of the integer. The session key is xored with * the first 16 bytes of the session id. */ - if ((key = BN_new()) == NULL) - fatal("respond_to_rsa_challenge: BN_new failed"); + key = BN_new(); BN_set_word(key, 0); for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { BN_lshift(key, key, 8); @@ -1005,35 +1022,35 @@ * Encrypt the integer using the public key and host key of the * server (key with smaller modulus first). */ - if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { + if (BN_cmp(public_key->n, host_key->n) < 0) { /* Public key has smaller modulus. */ - if (BN_num_bits(host_key->rsa->n) < - BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " + if (BN_num_bits(host_key->n) < + BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(host_key->rsa->n), - BN_num_bits(server_key->rsa->n), + BN_num_bits(host_key->n), + BN_num_bits(public_key->n), SSH_KEY_BITS_RESERVED); } - rsa_public_encrypt(key, key, server_key->rsa); - rsa_public_encrypt(key, key, host_key->rsa); + rsa_public_encrypt(key, key, public_key); + rsa_public_encrypt(key, key, host_key); } else { /* Host key has smaller modulus (or they are equal). */ - if (BN_num_bits(server_key->rsa->n) < - BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " + if (BN_num_bits(public_key->n) < + BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(server_key->rsa->n), - BN_num_bits(host_key->rsa->n), + BN_num_bits(public_key->n), + BN_num_bits(host_key->n), SSH_KEY_BITS_RESERVED); } - rsa_public_encrypt(key, key, host_key->rsa); - rsa_public_encrypt(key, key, server_key->rsa); + rsa_public_encrypt(key, key, host_key); + rsa_public_encrypt(key, key, public_key); } /* Destroy the public keys since we no longer need them. */ - key_free(server_key); - key_free(host_key); + RSA_free(public_key); + RSA_free(host_key); if (options.cipher == SSH_CIPHER_NOT_SET) { if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) @@ -1082,7 +1099,7 @@ * Expect a success message from the server. Note that this message * will be received in encrypted form. */ - packet_read_expect(SSH_SMSG_SUCCESS); + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); debug("Received encrypted confirmation."); } @@ -1092,13 +1109,14 @@ */ void ssh_userauth1(const char *local_user, const char *server_user, char *host, - Sensitive *sensitive) + Key **keys, int nkeys) { #ifdef KRB5 krb5_context context = NULL; krb5_auth_context auth_context = NULL; #endif int i, type; + int payload_len; if (supported_authentications == 0) fatal("ssh_userauth1: server supports no auth methods"); @@ -1114,7 +1132,7 @@ * needed (the user has no password). Otherwise the server responds * with failure. */ - type = packet_read(); + type = packet_read(&payload_len); /* check whether the connection was accepted without authentication. */ if (type == SSH_SMSG_SUCCESS) @@ -1128,7 +1146,7 @@ debug("Trying Kerberos v5 authentication."); if (try_krb5_authentication(&context, &auth_context)) { - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) goto success; if (type != SSH_SMSG_FAILURE) @@ -1143,7 +1161,7 @@ debug("Trying Kerberos v4 authentication."); if (try_krb4_authentication()) { - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) goto success; if (type != SSH_SMSG_FAILURE) @@ -1165,7 +1183,7 @@ packet_write_wait(); /* The server should respond with success or failure. */ - type = packet_read(); + type = packet_read(&payload_len); if (type == SSH_SMSG_SUCCESS) goto success; if (type != SSH_SMSG_FAILURE) @@ -1178,11 +1196,9 @@ */ if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && options.rhosts_rsa_authentication) { - for (i = 0; i < sensitive->nkeys; i++) { - if (sensitive->keys[i] != NULL && - sensitive->keys[i]->type == KEY_RSA1 && - try_rhosts_rsa_authentication(local_user, - sensitive->keys[i])) + for (i = 0; i < nkeys; i++) { + if (keys[i] != NULL && keys[i]->type == KEY_RSA1 && + try_rhosts_rsa_authentication(local_user, keys[i])) goto success; } }