=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/Attic/sshconnect1.c,v retrieving revision 1.3 retrieving revision 1.3.2.4 diff -u -r1.3 -r1.3.2.4 --- src/usr.bin/ssh/Attic/sshconnect1.c 2000/05/08 17:12:16 1.3 +++ src/usr.bin/ssh/Attic/sshconnect1.c 2001/03/21 18:53:15 1.3.2.4 @@ -2,37 +2,51 @@ * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved - * Created: Sat Mar 18 22:15:47 1995 ylo * Code to connect to a remote host, and to perform the client side of the * login (authentication) dialog. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.3.2.4 2001/03/21 18:53:15 jason Exp $"); #include -#include -#include #include +#ifdef KRB4 +#include +#endif +#ifdef AFS +#include +#include "radix.h" +#endif + +#include "ssh.h" +#include "ssh1.h" #include "xmalloc.h" #include "rsa.h" -#include "ssh.h" #include "buffer.h" #include "packet.h" -#include "authfd.h" -#include "cipher.h" #include "mpaux.h" #include "uidswap.h" +#include "log.h" #include "readconf.h" #include "key.h" +#include "authfd.h" #include "sshconnect.h" #include "authfile.h" +#include "readpass.h" +#include "cipher.h" +#include "canohost.h" /* Session id for the current session. */ -unsigned char session_id[16]; -unsigned int supported_authentications = 0; +u_char session_id[16]; +u_int supported_authentications = 0; extern Options options; extern char *__progname; @@ -42,29 +56,28 @@ * authenticate using the agent. */ int -try_agent_authentication() +try_agent_authentication(void) { - int status, type; + int type; char *comment; AuthenticationConnection *auth; - unsigned char response[16]; - unsigned int i; - BIGNUM *e, *n, *challenge; + u_char response[16]; + u_int i; + int plen, clen; + Key *key; + BIGNUM *challenge; /* Get connection to the agent. */ auth = ssh_get_authentication_connection(); if (!auth) return 0; - e = BN_new(); - n = BN_new(); challenge = BN_new(); /* Loop through identities served by the agent. */ - for (status = ssh_get_first_identity(auth, e, n, &comment); - status; - status = ssh_get_next_identity(auth, e, n, &comment)) { - int plen, clen; + for (key = ssh_get_first_identity(auth, &comment, 1); + key != NULL; + key = ssh_get_next_identity(auth, &comment, 1)) { /* Try this identity. */ debug("Trying RSA authentication via agent with '%.100s'", comment); @@ -72,7 +85,7 @@ /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); - packet_put_bignum(n); + packet_put_bignum(key->rsa->n); packet_send(); packet_write_wait(); @@ -83,6 +96,7 @@ does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); + key_free(key); continue; } /* Otherwise it should have sent a challenge. */ @@ -97,13 +111,16 @@ debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ - if (!ssh_decrypt_challenge(auth, e, n, challenge, - session_id, 1, response)) { - /* The agent failed to authenticate this identifier although it - advertised it supports this. Just return a wrong value. */ + if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) { + /* + * The agent failed to authenticate this identifier + * although it advertised it supports this. Just + * return a wrong value. + */ log("Authentication agent failed to decrypt challenge."); memset(response, 0, sizeof(response)); } + key_free(key); debug("Sending response to RSA challenge."); /* Send the decrypted challenge back to the server. */ @@ -118,10 +135,9 @@ /* The server returns success if it accepted the authentication. */ if (type == SSH_SMSG_SUCCESS) { - debug("RSA authentication accepted by server."); - BN_clear_free(e); - BN_clear_free(n); + ssh_close_authentication_connection(auth); BN_clear_free(challenge); + debug("RSA authentication accepted by server."); return 1; } /* Otherwise it should return failure. */ @@ -129,11 +145,8 @@ packet_disconnect("Protocol error waiting RSA auth response: %d", type); } - - BN_clear_free(e); - BN_clear_free(n); + ssh_close_authentication_connection(auth); BN_clear_free(challenge); - debug("RSA authentication using agent refused."); return 0; } @@ -145,19 +158,22 @@ void respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) { - unsigned char buf[32], response[16]; + u_char buf[32], response[16]; MD5_CTX md; int i, len; /* Decrypt the challenge using the private key. */ - rsa_private_decrypt(challenge, challenge, prv); + /* XXX think about Bleichenbacher, too */ + if (rsa_private_decrypt(challenge, challenge, prv) <= 0) + packet_disconnect( + "respond_to_rsa_challenge: rsa_private_decrypt failed"); /* Compute the response. */ /* The response is MD5 of decrypted challenge plus session id. */ len = BN_num_bytes(challenge); if (len <= 0 || len > sizeof(buf)) - packet_disconnect("respond_to_rsa_challenge: bad challenge length %d", - len); + packet_disconnect( + "respond_to_rsa_challenge: bad challenge length %d", len); memset(buf, 0, sizeof(buf)); BN_bn2bin(challenge, buf + sizeof(buf) - len); @@ -195,7 +211,7 @@ int plen, clen; /* Try to load identification for the authentication key. */ - public = key_new(KEY_RSA); + public = key_new(KEY_RSA1); if (!load_public_key(authfile, public, &comment)) { key_free(public); /* Could not load it. Fail. */ @@ -236,7 +252,7 @@ debug("Received RSA challenge from server."); - private = key_new(KEY_RSA); + private = key_new(KEY_RSA1); /* * Load the private key. Try first with empty passphrase; if it * fails, ask for a passphrase. @@ -269,6 +285,8 @@ /* Expect the server to reject it... */ packet_read_expect(&plen, SSH_SMSG_FAILURE); xfree(comment); + key_free(private); + BN_clear_free(challenge); return 0; } /* Destroy the passphrase. */ @@ -362,7 +380,7 @@ #ifdef KRB4 int -try_kerberos_authentication() +try_kerberos_authentication(void) { KTEXT_ST auth; /* Kerberos data */ char *reply; @@ -381,11 +399,11 @@ if (stat(tkt_string(), &st) < 0) return 0; - strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); + strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ); - realm = (char *) krb_realmofhost(get_canonical_hostname()); + realm = (char *) krb_realmofhost(get_canonical_hostname(1)); if (!realm) { - debug("Kerberos V4: no realm for %s", get_canonical_hostname()); + debug("Kerberos V4: no realm for %s", get_canonical_hostname(1)); return 0; } /* This can really be anything. */ @@ -440,7 +458,7 @@ debug("Kerberos V4 authentication accepted."); /* Get server's response. */ - reply = packet_get_string((unsigned int *) &auth.length); + reply = packet_get_string((u_int *) &auth.length); memcpy(auth.dat, reply, auth.length); xfree(reply); @@ -479,7 +497,7 @@ #ifdef AFS int -send_kerberos_tgt() +send_kerberos_tgt(void) { CREDENTIALS *creds; char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; @@ -505,7 +523,7 @@ debug("Kerberos V4 ticket expired: %s", TKT_FILE); return 0; } - creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer); + creds_to_radix(creds, (u_char *)buffer, sizeof buffer); xfree(creds); packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); @@ -544,10 +562,10 @@ p = buf; /* Get secret token. */ - memcpy(&creds.ticket_st.length, p, sizeof(unsigned int)); + memcpy(&creds.ticket_st.length, p, sizeof(u_int)); if (creds.ticket_st.length > MAX_KTXT_LEN) break; - p += sizeof(unsigned int); + p += sizeof(u_int); memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); p += creds.ticket_st.length; @@ -573,7 +591,7 @@ creds.pinst[0] = '\0'; /* Encode token, ship it off. */ - if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0) + if (creds_to_radix(&creds, (u_char *) buffer, sizeof buffer) <= 0) break; packet_start(SSH_CMSG_HAVE_AFS_TOKEN); packet_put_string(buffer, strlen(buffer)); @@ -598,44 +616,49 @@ * Note that the client code is not tied to s/key or TIS. */ int -try_skey_authentication() +try_challenge_reponse_authentication(void) { int type, i; int payload_len; - unsigned int clen; + u_int clen; + char prompt[1024]; char *challenge, *response; - debug("Doing skey authentication."); + debug("Doing challenge reponse authentication."); - /* request a challenge */ - packet_start(SSH_CMSG_AUTH_TIS); - packet_send(); - packet_write_wait(); - - type = packet_read(&payload_len); - if (type != SSH_SMSG_FAILURE && - type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - packet_disconnect("Protocol error: got %d in response " - "to skey-auth", type); - } - if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - debug("No challenge for skey authentication."); - return 0; - } - challenge = packet_get_string(&clen); - packet_integrity_check(payload_len, (4 + clen), type); - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! " - "Reponse will be transmitted in clear text."); - fprintf(stderr, "%s\n", challenge); - xfree(challenge); - fflush(stderr); for (i = 0; i < options.number_of_password_prompts; i++) { + /* request a challenge */ + packet_start(SSH_CMSG_AUTH_TIS); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type != SSH_SMSG_FAILURE && + type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + packet_disconnect("Protocol error: got %d in response " + "to SSH_CMSG_AUTH_TIS", type); + } + if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + debug("No challenge."); + return 0; + } + challenge = packet_get_string(&clen); + packet_integrity_check(payload_len, (4 + clen), type); + snprintf(prompt, sizeof prompt, "%s%s", challenge, + strchr(challenge, '\n') ? "" : "\nResponse: "); + xfree(challenge); if (i != 0) error("Permission denied, please try again."); - response = read_passphrase("Response: ", 0); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! " + "Reponse will be transmitted in clear text."); + response = read_passphrase(prompt, 0); + if (strcmp(response, "") == 0) { + xfree(response); + break; + } packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); - packet_put_string(response, strlen(response)); + ssh_put_password(response); memset(response, 0, strlen(response)); xfree(response); packet_send(); @@ -645,7 +668,7 @@ return 1; if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error: got %d in response " - "to skey-auth-reponse", type); + "to SSH_CMSG_AUTH_TIS_RESPONSE", type); } /* failure */ return 0; @@ -668,7 +691,7 @@ error("Permission denied, please try again."); password = read_passphrase(prompt, 0); packet_start(SSH_CMSG_AUTH_PASSWORD); - packet_put_string(password, strlen(password)); + ssh_put_password(password); memset(password, 0, strlen(password)); xfree(password); packet_send(); @@ -697,10 +720,10 @@ Key k; int bits, rbits; int ssh_cipher_default = SSH_CIPHER_3DES; - unsigned char session_key[SSH_SESSION_KEY_LENGTH]; - unsigned char cookie[8]; - unsigned int supported_ciphers; - unsigned int server_flags, client_flags; + 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; @@ -759,7 +782,7 @@ packet_integrity_check(payload_len, 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, SSH_SMSG_PUBLIC_KEY); - k.type = KEY_RSA; + k.type = KEY_RSA1; k.rsa = host_key; check_host_key(host, hostaddr, &k, options.user_hostfile, options.system_hostfile); @@ -832,19 +855,14 @@ RSA_free(public_key); RSA_free(host_key); - if (options.cipher == SSH_CIPHER_ILLEGAL) { - log("No valid SSH1 cipher, using %.100s instead.", - cipher_name(SSH_FALLBACK_CIPHER)); - options.cipher = SSH_FALLBACK_CIPHER; - } else if (options.cipher == SSH_CIPHER_NOT_SET) { - if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) + if (options.cipher == SSH_CIPHER_NOT_SET) { + if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) options.cipher = ssh_cipher_default; - else { - debug("Cipher %s not supported, using %.100s instead.", - cipher_name(ssh_cipher_default), - cipher_name(SSH_FALLBACK_CIPHER)); - options.cipher = SSH_FALLBACK_CIPHER; - } + } else if (options.cipher == SSH_CIPHER_ILLEGAL || + !(cipher_mask_ssh1(1) & (1 << options.cipher))) { + log("No valid SSH1 cipher, using %.100s instead.", + cipher_name(ssh_cipher_default)); + options.cipher = ssh_cipher_default; } /* Check that the selected cipher is supported. */ if (!(supported_ciphers & (1 << options.cipher))) @@ -894,8 +912,8 @@ */ void ssh_userauth( - const char* local_user, - const char* server_user, + const char *local_user, + const char *server_user, char *host, int host_key_valid, RSA *own_host_key) { @@ -999,13 +1017,15 @@ /* Try RSA authentication for each identity. */ for (i = 0; i < options.num_identity_files; i++) - if (try_rsa_authentication(options.identity_files[i])) + if (options.identity_keys[i] != NULL && + options.identity_keys[i]->type == KEY_RSA1 && + try_rsa_authentication(options.identity_files[i])) return; } - /* Try skey authentication if the server supports it. */ + /* Try challenge response authentication if the server supports it. */ if ((supported_authentications & (1 << SSH_AUTH_TIS)) && - options.skey_authentication && !options.batch_mode) { - if (try_skey_authentication()) + options.challenge_reponse_authentication && !options.batch_mode) { + if (try_challenge_reponse_authentication()) return; } /* Try password authentication if the server supports it. */ @@ -1013,7 +1033,7 @@ options.password_authentication && !options.batch_mode) { char prompt[80]; - snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", server_user, host); if (try_password_authentication(prompt)) return;