From 0ca2bdc2f755d323cf97966ca69c4d32b283070a Mon Sep 17 00:00:00 2001 From: kris Date: Sun, 10 Sep 2000 08:31:17 +0000 Subject: Initial import of OpenSSH post-2.2.0 snapshot dated 2000-09-09 --- crypto/openssh/sshconnect2.c | 160 +++++++++++++++++++++++++++++++------------ 1 file changed, 117 insertions(+), 43 deletions(-) (limited to 'crypto/openssh/sshconnect2.c') diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 0abcf89..d225359 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $"); #include #include @@ -54,6 +49,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); #include "dsa.h" #include "sshconnect.h" #include "authfile.h" +#include "authfd.h" /* import */ extern char *client_version_string; @@ -71,7 +67,6 @@ void ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, Buffer *client_kexinit, Buffer *server_kexinit) { - int i; int plen, dlen; unsigned int klen, kout; char *signature = NULL; @@ -265,9 +260,12 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) char prompt[80]; char *password; - if (attempt++ > options.number_of_password_prompts) + if (attempt++ >= options.number_of_password_prompts) return 0; + if(attempt != 1) + error("Permission denied, please try again."); + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", server_user, host); password = read_passphrase(prompt, 0); @@ -284,42 +282,32 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) return 1; } +typedef int sign_fn( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen); + int -ssh2_try_pubkey(char *filename, +ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, const char *server_user, const char *host, const char *service) { Buffer b; - Key *k; unsigned char *blob, *signature; int bloblen, slen; - struct stat st; - - if (stat(filename, &st) != 0) { - debug("key does not exist: %s", filename); - return 0; - } - debug("try pubkey: %s", filename); + int skip = 0; + int ret = -1; - k = key_new(KEY_DSA); - if (!load_private_key(filename, "", k, NULL)) { - int success = 0; - char *passphrase; - char prompt[300]; - snprintf(prompt, sizeof prompt, - "Enter passphrase for DSA key '%.100s': ", - filename); - passphrase = read_passphrase(prompt, 0); - success = load_private_key(filename, passphrase, k, NULL); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - if (!success) - return 0; - } dsa_make_key_blob(k, &blob, &bloblen); /* data to be signed */ buffer_init(&b); - buffer_append(&b, session_id2, session_id2_len); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + skip = buffer_len(&b); + } else { + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + } buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, server_user); buffer_put_cstring(&b, @@ -332,13 +320,16 @@ ssh2_try_pubkey(char *filename, buffer_put_string(&b, blob, bloblen); /* generate signature */ - dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); - key_free(k); + ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + if (ret == -1) { + xfree(blob); + buffer_free(&b); + return 0; + } #ifdef DEBUG_DSS buffer_dump(&b); #endif if (datafellows & SSH_BUG_PUBKEYAUTH) { - /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */ buffer_clear(&b); buffer_append(&b, session_id2, session_id2_len); buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -355,9 +346,9 @@ ssh2_try_pubkey(char *filename, xfree(signature); /* skip session id and packet type */ - if (buffer_len(&b) < session_id2_len + 1) + if (buffer_len(&b) < skip + 1) fatal("ssh2_try_pubkey: internal error"); - buffer_consume(&b, session_id2_len + 1); + buffer_consume(&b, skip + 1); /* put remaining data from buffer into packet */ packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -367,12 +358,88 @@ ssh2_try_pubkey(char *filename, /* send */ packet_send(); packet_write_wait(); + return 1; } +int +ssh2_try_pubkey(char *filename, + const char *server_user, const char *host, const char *service) +{ + Key *k; + int ret = 0; + struct stat st; + + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } + debug("try pubkey: %s", filename); + + k = key_new(KEY_DSA); + if (!load_private_key(filename, "", k, NULL)) { + int success = 0; + char *passphrase; + char prompt[300]; + snprintf(prompt, sizeof prompt, + "Enter passphrase for DSA key '%.100s': ", + filename); + passphrase = read_passphrase(prompt, 0); + success = load_private_key(filename, passphrase, k, NULL); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (!success) { + key_free(k); + return 0; + } + } + ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service); + key_free(k); + return ret; +} + +int agent_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen) +{ + int ret = -1; + AuthenticationConnection *ac = ssh_get_authentication_connection(); + if (ac != NULL) { + ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen); + ssh_close_authentication_connection(ac); + } + return ret; +} + +int +ssh2_try_agent(AuthenticationConnection *ac, + const char *server_user, const char *host, const char *service) +{ + static int called = 0; + char *comment; + Key *k; + int ret; + + if (called == 0) { + k = ssh_get_first_identity(ac, &comment, 2); + called ++; + } else { + k = ssh_get_next_identity(ac, &comment, 2); + } + if (k == NULL) + return 0; + debug("trying DSA agent key %s", comment); + xfree(comment); + ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service); + key_free(k); + return ret; +} + void ssh_userauth2(const char *server_user, char *host) { + AuthenticationConnection *ac = ssh_get_authentication_connection(); int type; int plen; int sent; @@ -427,12 +494,17 @@ ssh_userauth2(const char *server_user, char *host) debug("partial success"); if (options.dsa_authentication && strstr(auths, "publickey") != NULL) { - while (i < options.num_identity_files2) { - sent = ssh2_try_pubkey( - options.identity_files2[i++], + if (ac != NULL) + sent = ssh2_try_agent(ac, server_user, host, service); - if (sent) - break; + if (!sent) { + while (i < options.num_identity_files2) { + sent = ssh2_try_pubkey( + options.identity_files2[i++], + server_user, host, service); + if (sent) + break; + } } } if (!sent) { @@ -446,6 +518,8 @@ ssh_userauth2(const char *server_user, char *host) fatal("Permission denied (%s).", auths); xfree(auths); } + if (ac != NULL) + ssh_close_authentication_connection(ac); packet_done(); debug("ssh-userauth2 successfull"); } -- cgit v1.1