X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/54a5250fa7562cae30dc022b8722bfc8da752a80..69538b0c680486cc60423b48f419583a9e5b4650:/sshconnect2.c diff --git a/sshconnect2.c b/sshconnect2.c index cfc7b60d..1ee92ab0 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,26 +23,18 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.91 2001/12/28 14:50:54 markus Exp $"); - -#include -#include -#include -#include +RCSID("$OpenBSD: sshconnect2.c,v 1.99 2002/03/26 15:58:46 markus Exp $"); #include "ssh.h" #include "ssh2.h" #include "xmalloc.h" -#include "rsa.h" #include "buffer.h" #include "packet.h" -#include "uidswap.h" #include "compat.h" #include "bufaux.h" #include "cipher.h" #include "kex.h" #include "myproposal.h" -#include "key.h" #include "sshconnect.h" #include "authfile.h" #include "dh.h" @@ -146,7 +138,7 @@ typedef struct Authmethod Authmethod; typedef int sign_cb_fn( Authctxt *authctxt, Key *key, - u_char **sigp, int *lenp, u_char *data, int datalen); + u_char **sigp, u_int *lenp, u_char *data, u_int datalen); struct Authctxt { const char *server_user; @@ -174,12 +166,13 @@ struct Authmethod { int *batch_flag; /* flag in option struct that disables method */ }; -void input_userauth_success(int, int, u_int32_t, void *); -void input_userauth_failure(int, int, u_int32_t, void *); -void input_userauth_banner(int, int, u_int32_t, void *); -void input_userauth_error(int, int, u_int32_t, void *); -void input_userauth_info_req(int, int, u_int32_t, void *); -void input_userauth_pk_ok(int, int, u_int32_t, void *); +void input_userauth_success(int, u_int32_t, void *); +void input_userauth_failure(int, u_int32_t, void *); +void input_userauth_banner(int, u_int32_t, void *); +void input_userauth_error(int, u_int32_t, void *); +void input_userauth_info_req(int, u_int32_t, void *); +void input_userauth_pk_ok(int, u_int32_t, void *); +void input_userauth_passwd_changereq(int, u_int32_t, void *); int userauth_none(Authctxt *); int userauth_pubkey(Authctxt *); @@ -307,13 +300,13 @@ userauth(Authctxt *authctxt, char *authlist) } } void -input_userauth_error(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_error(int type, u_int32_t seq, void *ctxt) { fatal("input_userauth_error: bad message during authentication: " "type %d", type); } void -input_userauth_banner(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_banner(int type, u_int32_t seq, void *ctxt) { char *msg, *lang; debug3("input_userauth_banner"); @@ -324,7 +317,7 @@ input_userauth_banner(int type, int plen, u_int32_t seq, void *ctxt) xfree(lang); } void -input_userauth_success(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_success(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; if (authctxt == NULL) @@ -335,7 +328,7 @@ input_userauth_success(int type, int plen, u_int32_t seq, void *ctxt) authctxt->success = 1; /* break out */ } void -input_userauth_failure(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_failure(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; char *authlist = NULL; @@ -356,13 +349,15 @@ input_userauth_failure(int type, int plen, u_int32_t seq, void *ctxt) userauth(authctxt, authlist); } void -input_userauth_pk_ok(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; Key *key = NULL; Buffer b; - int alen, blen, sent = 0; - char *pkalg, *pkblob, *fp; + int pktype, sent = 0; + u_int alen, blen; + char *pkalg, *fp; + u_char *pkblob; if (authctxt == NULL) fatal("input_userauth_pk_ok: no authentication context"); @@ -389,7 +384,7 @@ input_userauth_pk_ok(int type, int plen, u_int32_t seq, void *ctxt) debug("no last key or no sign cb"); break; } - if (key_type_from_name(pkalg) == KEY_UNSPEC) { + if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { debug("unknown pkalg %s", pkalg); break; } @@ -397,6 +392,12 @@ input_userauth_pk_ok(int type, int plen, u_int32_t seq, void *ctxt) debug("no key from blob. pkalg %s", pkalg); break; } + if (key->type != pktype) { + error("input_userauth_pk_ok: type mismatch " + "for decoded key (received %d, expected %d)", + key->type, pktype); + break; + } fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); debug2("input_userauth_pk_ok: fp %s", fp); xfree(fp); @@ -439,7 +440,7 @@ int userauth_passwd(Authctxt *authctxt) { static int attempt = 0; - char prompt[80]; + char prompt[150]; char *password; if (attempt++ >= options.number_of_password_prompts) @@ -461,13 +462,85 @@ userauth_passwd(Authctxt *authctxt) xfree(password); packet_add_padding(64); packet_send(); + + dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, + &input_userauth_passwd_changereq); + return 1; } +/* + * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST + */ +void +input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) +{ + Authctxt *authctxt = ctxt; + char *info, *lang, *password = NULL, *retype = NULL; + char prompt[150]; + + debug2("input_userauth_passwd_changereq"); + + if (authctxt == NULL) + fatal("input_userauth_passwd_changereq: " + "no authentication context"); + + info = packet_get_string(NULL); + lang = packet_get_string(NULL); + if (strlen(info) > 0) + log("%s", info); + xfree(info); + xfree(lang); + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_char(1); /* additional info */ + snprintf(prompt, sizeof(prompt), + "Enter %.30s@%.128s's old password: ", + authctxt->server_user, authctxt->host); + password = read_passphrase(prompt, 0); + packet_put_cstring(password); + memset(password, 0, strlen(password)); + xfree(password); + password = NULL; + while (password == NULL) { + snprintf(prompt, sizeof(prompt), + "Enter %.30s@%.128s's new password: ", + authctxt->server_user, authctxt->host); + password = read_passphrase(prompt, RP_ALLOW_EOF); + if (password == NULL) { + /* bail out */ + return; + } + snprintf(prompt, sizeof(prompt), + "Retype %.30s@%.128s's new password: ", + authctxt->server_user, authctxt->host); + retype = read_passphrase(prompt, 0); + if (strcmp(password, retype) != 0) { + memset(password, 0, strlen(password)); + xfree(password); + log("Mismatch; try again, EOF to quit."); + password = NULL; + } + memset(retype, 0, strlen(retype)); + xfree(retype); + } + packet_put_cstring(password); + memset(password, 0, strlen(password)); + xfree(password); + packet_add_padding(64); + packet_send(); + + dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, + &input_userauth_passwd_changereq); +} static void clear_auth_state(Authctxt *authctxt) { /* XXX clear authentication state */ + dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL); + if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) { debug3("clear_auth_state: key_free %p", authctxt->last_key); key_free(authctxt->last_key); @@ -482,7 +555,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) { Buffer b; u_char *blob, *signature; - int bloblen, slen; + u_int bloblen, slen; int skip = 0; int ret = -1; int have_sig = 1; @@ -567,7 +640,7 @@ send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, int hint) { u_char *blob; - int bloblen, have_sig = 0; + u_int bloblen, have_sig = 0; debug3("send_pubkey_test"); @@ -634,8 +707,8 @@ load_identity_file(char *filename) } static int -identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, - u_char *data, int datalen) +identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) { Key *private; int idx, ret; @@ -657,15 +730,15 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, } static int -agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, - u_char *data, int datalen) +agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) { return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen); } static int -key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, - u_char *data, int datalen) +key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) { return key_sign(key, sigp, lenp, data, datalen); } @@ -767,7 +840,7 @@ userauth_kbdint(Authctxt *authctxt) * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */ void -input_userauth_info_req(int type, int plen, u_int32_t seq, void *ctxt) +input_userauth_info_req(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; char *name, *inst, *lang, *prompt, *response; @@ -956,7 +1029,7 @@ authmethod_get(char *authlist) { char *name = NULL; - int next; + u_int next; /* Use a suitable default if we're passed a nil list. */ if (authlist == NULL || strlen(authlist) == 0) @@ -991,22 +1064,23 @@ authmethod_get(char *authlist) } } - -#define DELIM "," - static char * authmethods_get(void) { Authmethod *method = NULL; - char buf[1024]; + Buffer b; + char *list; - buf[0] = '\0'; + buffer_init(&b); for (method = authmethods; method->name != NULL; method++) { if (authmethod_is_enabled(method)) { - if (buf[0] != '\0') - strlcat(buf, DELIM, sizeof buf); - strlcat(buf, method->name, sizeof buf); + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + buffer_append(&b, method->name, strlen(method->name)); } } - return xstrdup(buf); + buffer_append(&b, "\0", 1); + list = xstrdup(buffer_ptr(&b)); + buffer_free(&b); + return list; }