=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/Attic/auth1.c,v retrieving revision 1.59 retrieving revision 1.59.4.1 diff -u -r1.59 -r1.59.4.1 --- src/usr.bin/ssh/Attic/auth1.c 2004/07/28 09:40:29 1.59 +++ src/usr.bin/ssh/Attic/auth1.c 2005/09/04 18:39:56 1.59.4.1 @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/28 09:40:29 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.59.4.1 2005/09/04 18:39:56 brad Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -29,30 +29,184 @@ /* import */ extern ServerOptions options; -/* - * convert ssh auth msg type into description - */ +static int auth1_process_password(Authctxt *, char *, size_t); +static int auth1_process_rsa(Authctxt *, char *, size_t); +static int auth1_process_rhosts_rsa(Authctxt *, char *, size_t); +static int auth1_process_tis_challenge(Authctxt *, char *, size_t); +static int auth1_process_tis_response(Authctxt *, char *, size_t); + +struct AuthMethod1 { + int type; + char *name; + int *enabled; + int (*method)(Authctxt *, char *, size_t); +}; + +const struct AuthMethod1 auth1_methods[] = { + { + SSH_CMSG_AUTH_PASSWORD, "password", + &options.password_authentication, auth1_process_password + }, + { + SSH_CMSG_AUTH_RSA, "rsa", + &options.rsa_authentication, auth1_process_rsa + }, + { + SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa", + &options.rhosts_rsa_authentication, auth1_process_rhosts_rsa + }, + { + SSH_CMSG_AUTH_TIS, "challenge-response", + &options.challenge_response_authentication, + auth1_process_tis_challenge + }, + { + SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response", + &options.challenge_response_authentication, + auth1_process_tis_response + }, + { -1, NULL, NULL, NULL} +}; + +static const struct AuthMethod1 +*lookup_authmethod1(int type) +{ + int i; + + for(i = 0; auth1_methods[i].name != NULL; i++) + if (auth1_methods[i].type == type) + return (&(auth1_methods[i])); + + return (NULL); +} + static char * get_authname(int type) { - static char buf[1024]; - switch (type) { - case SSH_CMSG_AUTH_PASSWORD: - return "password"; - case SSH_CMSG_AUTH_RSA: - return "rsa"; - case SSH_CMSG_AUTH_RHOSTS_RSA: - return "rhosts-rsa"; - case SSH_CMSG_AUTH_RHOSTS: - return "rhosts"; - case SSH_CMSG_AUTH_TIS: - case SSH_CMSG_AUTH_TIS_RESPONSE: - return "challenge-response"; + const struct AuthMethod1 *a; + static char buf[64]; + + if ((a = lookup_authmethod1(type)) != NULL) + return (a->name); + snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type); + return (buf); +} + +static int +auth1_process_password(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + char *password; + u_int dlen; + + /* + * Read user password. It is in plain text, but was + * transmitted over the encrypted channel so it is + * not visible to an outside observer. + */ + password = packet_get_string(&dlen); + packet_check_eom(); + + /* Try authentication with the password. */ + authenticated = PRIVSEP(auth_password(authctxt, password)); + + memset(password, 0, dlen); + xfree(password); + + return (authenticated); +} + +static int +auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + BIGNUM *n; + + /* RSA authentication requested. */ + if ((n = BN_new()) == NULL) + fatal("do_authloop: BN_new failed"); + packet_get_bignum(n); + packet_check_eom(); + authenticated = auth_rsa(authctxt, n); + BN_clear_free(n); + + return (authenticated); +} + +static int +auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen) +{ + int keybits, authenticated = 0; + u_int bits; + char *client_user; + Key *client_host_key; + u_int ulen; + + /* + * Get client user name. Note that we just have to + * trust the client; root on the client machine can + * claim to be any user. + */ + client_user = packet_get_string(&ulen); + + /* Get the client host key. */ + client_host_key = key_new(KEY_RSA1); + bits = packet_get_int(); + packet_get_bignum(client_host_key->rsa->e); + packet_get_bignum(client_host_key->rsa->n); + + keybits = BN_num_bits(client_host_key->rsa->n); + if (keybits < 0 || bits != (u_int)keybits) { + verbose("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", + BN_num_bits(client_host_key->rsa->n), bits); } - snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); - return buf; + packet_check_eom(); + + authenticated = auth_rhosts_rsa(authctxt, client_user, + client_host_key); + key_free(client_host_key); + + snprintf(info, infolen, " ruser %.100s", client_user); + xfree(client_user); + + return (authenticated); } +static int +auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen) +{ + char *challenge; + + if ((challenge = get_challenge(authctxt)) == NULL) + return (0); + + debug("sending challenge '%s'", challenge); + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_cstring(challenge); + xfree(challenge); + packet_send(); + packet_write_wait(); + + return (-1); +} + +static int +auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + char *response; + u_int dlen; + + response = packet_get_string(&dlen); + packet_check_eom(); + authenticated = verify_response(authctxt, response); + memset(response, 'r', dlen); + xfree(response); + + return (authenticated); +} + /* * read packets, try to authenticate the user and * return only if authentication is successful @@ -61,14 +215,9 @@ do_authloop(Authctxt *authctxt) { int authenticated = 0; - u_int bits; - Key *client_host_key; - BIGNUM *n; - char *client_user, *password; char info[1024]; - u_int dlen; - u_int ulen; int type = 0; + const struct AuthMethod1 *meth; debug("Attempting authentication for %s%.100s.", authctxt->valid ? "" : "invalid user ", authctxt->user); @@ -96,109 +245,21 @@ /* Get a packet from the client. */ type = packet_read(); + if ((meth = lookup_authmethod1(type)) == NULL) { + logit("Unknown message during authentication: " + "type %d", type); + goto skip; + } - /* Process the packet. */ - switch (type) { - case SSH_CMSG_AUTH_RHOSTS_RSA: - if (!options.rhosts_rsa_authentication) { - verbose("Rhosts with RSA authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; root on the client machine can - * claim to be any user. - */ - client_user = packet_get_string(&ulen); + if (!*(meth->enabled)) { + verbose("%s authentication disabled.", meth->name); + goto skip; + } - /* Get the client host key. */ - client_host_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(client_host_key->rsa->e); - packet_get_bignum(client_host_key->rsa->n); + authenticated = meth->method(authctxt, info, sizeof(info)); + if (authenticated == -1) + continue; /* "postponed" */ - if (bits != BN_num_bits(client_host_key->rsa->n)) - verbose("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", - BN_num_bits(client_host_key->rsa->n), bits); - packet_check_eom(); - - authenticated = auth_rhosts_rsa(authctxt, client_user, - client_host_key); - key_free(client_host_key); - - snprintf(info, sizeof info, " ruser %.100s", client_user); - xfree(client_user); - break; - - case SSH_CMSG_AUTH_RSA: - if (!options.rsa_authentication) { - verbose("RSA authentication disabled."); - break; - } - /* RSA authentication requested. */ - if ((n = BN_new()) == NULL) - fatal("do_authloop: BN_new failed"); - packet_get_bignum(n); - packet_check_eom(); - authenticated = auth_rsa(authctxt, n); - BN_clear_free(n); - break; - - case SSH_CMSG_AUTH_PASSWORD: - if (!options.password_authentication) { - verbose("Password authentication disabled."); - break; - } - /* - * Read user password. It is in plain text, but was - * transmitted over the encrypted channel so it is - * not visible to an outside observer. - */ - password = packet_get_string(&dlen); - packet_check_eom(); - - /* Try authentication with the password. */ - authenticated = PRIVSEP(auth_password(authctxt, password)); - - memset(password, 0, strlen(password)); - xfree(password); - break; - - case SSH_CMSG_AUTH_TIS: - debug("rcvd SSH_CMSG_AUTH_TIS"); - if (options.challenge_response_authentication == 1) { - char *challenge = get_challenge(authctxt); - if (challenge != NULL) { - debug("sending challenge '%s'", challenge); - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_cstring(challenge); - xfree(challenge); - packet_send(); - packet_write_wait(); - continue; - } - } - break; - case SSH_CMSG_AUTH_TIS_RESPONSE: - debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); - if (options.challenge_response_authentication == 1) { - char *response = packet_get_string(&dlen); - packet_check_eom(); - authenticated = verify_response(authctxt, response); - memset(response, 'r', dlen); - xfree(response); - } - break; - - default: - /* - * Any unknown messages will be ignored (and failure - * returned) during authentication. - */ - logit("Unknown message during authentication: type %d", type); - break; - } #ifdef BSD_AUTH if (authctxt->as) { auth_close(authctxt->as); @@ -211,9 +272,10 @@ /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && - !auth_root_allowed(get_authname(type))) + !auth_root_allowed(meth->name)) authenticated = 0; + skip: /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info);