1264377Sdes/* $OpenBSD: auth1.c,v 1.80 2014/02/02 03:44:31 djm Exp $ */ 260573Skris/* 360573Skris * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 460573Skris * All rights reserved 560576Skris * 665674Skris * As far as I am concerned, the code I have written for this software 765674Skris * can be used freely for any purpose. Any derived versions of this 865674Skris * software must be clearly marked as such, and if the derived work is 965674Skris * incompatible with the protocol description in the RFC file, it must be 1065674Skris * called by a name other than "ssh" or "Secure Shell". 1160573Skris */ 1260573Skris 1360573Skris#include "includes.h" 1460573Skris 15162856Sdes#include <sys/types.h> 16162856Sdes 17162856Sdes#include <stdarg.h> 18162856Sdes#include <stdio.h> 19162856Sdes#include <string.h> 20162856Sdes#include <unistd.h> 21162856Sdes#include <pwd.h> 22162856Sdes 23181111Sdes#include "openbsd-compat/sys-queue.h" 2460573Skris#include "xmalloc.h" 2560573Skris#include "rsa.h" 2676262Sgreen#include "ssh1.h" 2760573Skris#include "packet.h" 2860573Skris#include "buffer.h" 2976262Sgreen#include "log.h" 3060573Skris#include "servconf.h" 3160573Skris#include "compat.h" 32162856Sdes#include "key.h" 33162856Sdes#include "hostfile.h" 3460573Skris#include "auth.h" 3592559Sdes#include "channels.h" 3660573Skris#include "session.h" 3792559Sdes#include "uidswap.h" 38162856Sdes#ifdef GSSAPI 39162856Sdes#include "ssh-gss.h" 40162856Sdes#endif 4198684Sdes#include "monitor_wrap.h" 42147005Sdes#include "buffer.h" 4392559Sdes 4460573Skris/* import */ 4560573Skrisextern ServerOptions options; 46147005Sdesextern Buffer loginmsg; 4760573Skris 48255767Sdesstatic int auth1_process_password(Authctxt *); 49255767Sdesstatic int auth1_process_rsa(Authctxt *); 50255767Sdesstatic int auth1_process_rhosts_rsa(Authctxt *); 51255767Sdesstatic int auth1_process_tis_challenge(Authctxt *); 52255767Sdesstatic int auth1_process_tis_response(Authctxt *); 53149753Sdes 54149753Sdesstatic char *client_user = NULL; /* Used to fill in remote user for PAM */ 55149753Sdes 56149753Sdesstruct AuthMethod1 { 57149753Sdes int type; 58149753Sdes char *name; 59149753Sdes int *enabled; 60255767Sdes int (*method)(Authctxt *); 61149753Sdes}; 62149753Sdes 63149753Sdesconst struct AuthMethod1 auth1_methods[] = { 64149753Sdes { 65149753Sdes SSH_CMSG_AUTH_PASSWORD, "password", 66149753Sdes &options.password_authentication, auth1_process_password 67149753Sdes }, 68149753Sdes { 69149753Sdes SSH_CMSG_AUTH_RSA, "rsa", 70149753Sdes &options.rsa_authentication, auth1_process_rsa 71149753Sdes }, 72149753Sdes { 73149753Sdes SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa", 74149753Sdes &options.rhosts_rsa_authentication, auth1_process_rhosts_rsa 75149753Sdes }, 76149753Sdes { 77149753Sdes SSH_CMSG_AUTH_TIS, "challenge-response", 78149753Sdes &options.challenge_response_authentication, 79149753Sdes auth1_process_tis_challenge 80149753Sdes }, 81149753Sdes { 82149753Sdes SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response", 83149753Sdes &options.challenge_response_authentication, 84149753Sdes auth1_process_tis_response 85149753Sdes }, 86149753Sdes { -1, NULL, NULL, NULL} 87149753Sdes}; 88149753Sdes 89149753Sdesstatic const struct AuthMethod1 90149753Sdes*lookup_authmethod1(int type) 91149753Sdes{ 92149753Sdes int i; 93149753Sdes 94162856Sdes for (i = 0; auth1_methods[i].name != NULL; i++) 95149753Sdes if (auth1_methods[i].type == type) 96149753Sdes return (&(auth1_methods[i])); 97149753Sdes 98149753Sdes return (NULL); 99149753Sdes} 100149753Sdes 10192559Sdesstatic char * 10260573Skrisget_authname(int type) 10360573Skris{ 104149753Sdes const struct AuthMethod1 *a; 105149753Sdes static char buf[64]; 106149753Sdes 107149753Sdes if ((a = lookup_authmethod1(type)) != NULL) 108149753Sdes return (a->name); 109149753Sdes snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type); 110149753Sdes return (buf); 111149753Sdes} 112149753Sdes 113162856Sdes/*ARGSUSED*/ 114149753Sdesstatic int 115255767Sdesauth1_process_password(Authctxt *authctxt) 116149753Sdes{ 117149753Sdes int authenticated = 0; 118149753Sdes char *password; 119149753Sdes u_int dlen; 120149753Sdes 121149753Sdes /* 122149753Sdes * Read user password. It is in plain text, but was 123149753Sdes * transmitted over the encrypted channel so it is 124149753Sdes * not visible to an outside observer. 125149753Sdes */ 126149753Sdes password = packet_get_string(&dlen); 127149753Sdes packet_check_eom(); 128149753Sdes 129149753Sdes /* Try authentication with the password. */ 130149753Sdes authenticated = PRIVSEP(auth_password(authctxt, password)); 131149753Sdes 132264377Sdes explicit_bzero(password, dlen); 133255767Sdes free(password); 134149753Sdes 135149753Sdes return (authenticated); 136149753Sdes} 137149753Sdes 138162856Sdes/*ARGSUSED*/ 139149753Sdesstatic int 140255767Sdesauth1_process_rsa(Authctxt *authctxt) 141149753Sdes{ 142149753Sdes int authenticated = 0; 143149753Sdes BIGNUM *n; 144149753Sdes 145149753Sdes /* RSA authentication requested. */ 146149753Sdes if ((n = BN_new()) == NULL) 147149753Sdes fatal("do_authloop: BN_new failed"); 148149753Sdes packet_get_bignum(n); 149149753Sdes packet_check_eom(); 150149753Sdes authenticated = auth_rsa(authctxt, n); 151149753Sdes BN_clear_free(n); 152149753Sdes 153149753Sdes return (authenticated); 154149753Sdes} 155149753Sdes 156162856Sdes/*ARGSUSED*/ 157149753Sdesstatic int 158255767Sdesauth1_process_rhosts_rsa(Authctxt *authctxt) 159149753Sdes{ 160149753Sdes int keybits, authenticated = 0; 161149753Sdes u_int bits; 162149753Sdes Key *client_host_key; 163149753Sdes u_int ulen; 164149753Sdes 165149753Sdes /* 166149753Sdes * Get client user name. Note that we just have to 167149753Sdes * trust the client; root on the client machine can 168149753Sdes * claim to be any user. 169149753Sdes */ 170221420Sdes client_user = packet_get_cstring(&ulen); 171149753Sdes 172149753Sdes /* Get the client host key. */ 173149753Sdes client_host_key = key_new(KEY_RSA1); 174149753Sdes bits = packet_get_int(); 175149753Sdes packet_get_bignum(client_host_key->rsa->e); 176149753Sdes packet_get_bignum(client_host_key->rsa->n); 177149753Sdes 178149753Sdes keybits = BN_num_bits(client_host_key->rsa->n); 179149753Sdes if (keybits < 0 || bits != (u_int)keybits) { 180149753Sdes verbose("Warning: keysize mismatch for client_host_key: " 181149753Sdes "actual %d, announced %d", 182149753Sdes BN_num_bits(client_host_key->rsa->n), bits); 18360573Skris } 184149753Sdes packet_check_eom(); 185149753Sdes 186149753Sdes authenticated = auth_rhosts_rsa(authctxt, client_user, 187149753Sdes client_host_key); 188149753Sdes key_free(client_host_key); 189149753Sdes 190255767Sdes auth_info(authctxt, "ruser %.100s", client_user); 191149753Sdes 192149753Sdes return (authenticated); 19360573Skris} 19460573Skris 195162856Sdes/*ARGSUSED*/ 196149753Sdesstatic int 197255767Sdesauth1_process_tis_challenge(Authctxt *authctxt) 198149753Sdes{ 199149753Sdes char *challenge; 200149753Sdes 201149753Sdes if ((challenge = get_challenge(authctxt)) == NULL) 202149753Sdes return (0); 203149753Sdes 204149753Sdes debug("sending challenge '%s'", challenge); 205149753Sdes packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 206149753Sdes packet_put_cstring(challenge); 207255767Sdes free(challenge); 208149753Sdes packet_send(); 209149753Sdes packet_write_wait(); 210149753Sdes 211149753Sdes return (-1); 212149753Sdes} 213149753Sdes 214162856Sdes/*ARGSUSED*/ 215149753Sdesstatic int 216255767Sdesauth1_process_tis_response(Authctxt *authctxt) 217149753Sdes{ 218149753Sdes int authenticated = 0; 219149753Sdes char *response; 220149753Sdes u_int dlen; 221149753Sdes 222149753Sdes response = packet_get_string(&dlen); 223149753Sdes packet_check_eom(); 224149753Sdes authenticated = verify_response(authctxt, response); 225264377Sdes explicit_bzero(response, dlen); 226255767Sdes free(response); 227149753Sdes 228149753Sdes return (authenticated); 229149753Sdes} 230149753Sdes 23160573Skris/* 23276262Sgreen * read packets, try to authenticate the user and 23376262Sgreen * return only if authentication is successful 23460573Skris */ 23592559Sdesstatic void 23676262Sgreendo_authloop(Authctxt *authctxt) 23760573Skris{ 23869591Sgreen int authenticated = 0; 239149753Sdes int prev = 0, type = 0; 240149753Sdes const struct AuthMethod1 *meth; 24160573Skris 24276262Sgreen debug("Attempting authentication for %s%.100s.", 243137019Sdes authctxt->valid ? "" : "invalid user ", authctxt->user); 24476262Sgreen 24576262Sgreen /* If the user has no password, accept authentication immediately. */ 246215116Sdes if (options.permit_empty_passwd && options.password_authentication && 247124211Sdes#ifdef KRB5 24892559Sdes (!options.kerberos_authentication || options.kerberos_or_local_passwd) && 24976262Sgreen#endif 25098684Sdes PRIVSEP(auth_password(authctxt, ""))) { 251137019Sdes#ifdef USE_PAM 252137019Sdes if (options.use_pam && (PRIVSEP(do_pam_account()))) 253137019Sdes#endif 254137019Sdes { 255248619Sdes auth_log(authctxt, 1, 0, "without authentication", 256255767Sdes NULL); 257137019Sdes return; 258137019Sdes } 25976262Sgreen } 26076262Sgreen 26160573Skris /* Indicate that authentication is needed. */ 26260573Skris packet_start(SSH_SMSG_FAILURE); 26360573Skris packet_send(); 26460573Skris packet_write_wait(); 26560573Skris 26676262Sgreen for (;;) { 26769591Sgreen /* default to fail */ 26869591Sgreen authenticated = 0; 26969591Sgreen 27060573Skris 27160573Skris /* Get a packet from the client. */ 272112870Sdes prev = type; 27392559Sdes type = packet_read(); 27460573Skris 275112870Sdes /* 276112870Sdes * If we started challenge-response authentication but the 277112870Sdes * next packet is not a response to our challenge, release 278112870Sdes * the resources allocated by get_challenge() (which would 279112870Sdes * normally have been released by verify_response() had we 280112870Sdes * received such a response) 281112870Sdes */ 282112870Sdes if (prev == SSH_CMSG_AUTH_TIS && 283112870Sdes type != SSH_CMSG_AUTH_TIS_RESPONSE) 284112870Sdes abandon_challenge_response(authctxt); 285112870Sdes 286181111Sdes if (authctxt->failures >= options.max_authtries) 287181111Sdes goto skip; 288149753Sdes if ((meth = lookup_authmethod1(type)) == NULL) { 289149753Sdes logit("Unknown message during authentication: " 290149753Sdes "type %d", type); 291149753Sdes goto skip; 292149753Sdes } 29360573Skris 294149753Sdes if (!*(meth->enabled)) { 295149753Sdes verbose("%s authentication disabled.", meth->name); 296149753Sdes goto skip; 297149753Sdes } 29860573Skris 299255767Sdes authenticated = meth->method(authctxt); 300149753Sdes if (authenticated == -1) 301149753Sdes continue; /* "postponed" */ 30260573Skris 30376262Sgreen#ifdef BSD_AUTH 30476262Sgreen if (authctxt->as) { 30576262Sgreen auth_close(authctxt->as); 30676262Sgreen authctxt->as = NULL; 30776262Sgreen } 30876262Sgreen#endif 30976262Sgreen if (!authctxt->valid && authenticated) 31076262Sgreen fatal("INTERNAL ERROR: authenticated invalid user %s", 31176262Sgreen authctxt->user); 31260576Skris 313106130Sdes#ifdef _UNICOS 314106130Sdes if (authenticated && cray_access_denied(authctxt->user)) { 315106130Sdes authenticated = 0; 316106130Sdes fatal("Access denied for user %s.",authctxt->user); 317106130Sdes } 318106130Sdes#endif /* _UNICOS */ 319106130Sdes 320197679Sdes#ifndef HAVE_CYGWIN 32176262Sgreen /* Special handling for root */ 322113911Sdes if (authenticated && authctxt->pw->pw_uid == 0 && 323149753Sdes !auth_root_allowed(meth->name)) { 324149753Sdes authenticated = 0; 325147005Sdes# ifdef SSH_AUDIT_EVENTS 326147005Sdes PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 327147005Sdes# endif 328147005Sdes } 32998941Sdes#endif 330124211Sdes 33198941Sdes#ifdef USE_PAM 332126277Sdes if (options.use_pam && authenticated && 333147005Sdes !PRIVSEP(do_pam_account())) { 334147005Sdes char *msg; 335147005Sdes size_t len; 336147005Sdes 337147005Sdes error("Access denied for user %s by PAM account " 338149753Sdes "configuration", authctxt->user); 339147005Sdes len = buffer_len(&loginmsg); 340147005Sdes buffer_append(&loginmsg, "\0", 1); 341147005Sdes msg = buffer_ptr(&loginmsg); 342147005Sdes /* strip trailing newlines */ 343147005Sdes if (len > 0) 344147005Sdes while (len > 0 && msg[--len] == '\n') 345147005Sdes msg[len] = '\0'; 346147005Sdes else 347147005Sdes msg = "Access denied."; 348181111Sdes packet_disconnect("%s", msg); 349147005Sdes } 35098941Sdes#endif 35176262Sgreen 352149753Sdes skip: 35376262Sgreen /* Log before sending the reply */ 354255767Sdes auth_log(authctxt, authenticated, 0, get_authname(type), NULL); 35560573Skris 356255767Sdes free(client_user); 357255767Sdes client_user = NULL; 35869591Sgreen 35976262Sgreen if (authenticated) 36076262Sgreen return; 36160573Skris 362181111Sdes if (++authctxt->failures >= options.max_authtries) { 363147005Sdes#ifdef SSH_AUDIT_EVENTS 364147005Sdes PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 365147005Sdes#endif 36676262Sgreen packet_disconnect(AUTH_FAIL_MSG, authctxt->user); 367147005Sdes } 36876262Sgreen 36960573Skris packet_start(SSH_SMSG_FAILURE); 37060573Skris packet_send(); 37160573Skris packet_write_wait(); 37260573Skris } 37360573Skris} 37460573Skris 37560573Skris/* 37660573Skris * Performs authentication of an incoming connection. Session key has already 37760573Skris * been exchanged and encryption is enabled. 37860573Skris */ 379126277Sdesvoid 380126277Sdesdo_authentication(Authctxt *authctxt) 38160573Skris{ 38276262Sgreen u_int ulen; 38398684Sdes char *user, *style = NULL; 38460573Skris 38560573Skris /* Get the name of the user that we wish to log in as. */ 38692559Sdes packet_read_expect(SSH_CMSG_USER); 38760573Skris 38860573Skris /* Get the user name. */ 389221420Sdes user = packet_get_cstring(&ulen); 39092559Sdes packet_check_eom(); 39160573Skris 39276262Sgreen if ((style = strchr(user, ':')) != NULL) 39392559Sdes *style++ = '\0'; 39460573Skris 39576262Sgreen authctxt->user = user; 39676262Sgreen authctxt->style = style; 39760573Skris 39860573Skris /* Verify that the user is a valid user. */ 39998684Sdes if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 40076262Sgreen authctxt->valid = 1; 401124211Sdes else { 402137019Sdes debug("do_authentication: invalid user %s", user); 403124211Sdes authctxt->pw = fakepw(); 404124211Sdes } 40560573Skris 406248619Sdes /* Configuration may have changed as a result of Match */ 407248619Sdes if (options.num_auth_methods != 0) 408248619Sdes fatal("AuthenticationMethods is not supported with SSH " 409248619Sdes "protocol 1"); 410248619Sdes 411137019Sdes setproctitle("%s%s", authctxt->valid ? user : "unknown", 41298684Sdes use_privsep ? " [net]" : ""); 41376262Sgreen 41498941Sdes#ifdef USE_PAM 415124211Sdes if (options.use_pam) 416128460Sdes PRIVSEP(start_pam(authctxt)); 41798941Sdes#endif 41898941Sdes 41960573Skris /* 42060573Skris * If we are not running as root, the user must have the same uid as 421149753Sdes * the server. 42260573Skris */ 42398941Sdes#ifndef HAVE_CYGWIN 42498684Sdes if (!use_privsep && getuid() != 0 && authctxt->pw && 42598684Sdes authctxt->pw->pw_uid != getuid()) 42660573Skris packet_disconnect("Cannot change user when server not running as root."); 42798941Sdes#endif 42860573Skris 42976262Sgreen /* 43076262Sgreen * Loop until the user has been authenticated or the connection is 43176262Sgreen * closed, do_authloop() returns only if authentication is successful 43276262Sgreen */ 43376262Sgreen do_authloop(authctxt); 43460573Skris 43560573Skris /* The user has been authenticated and accepted. */ 43660573Skris packet_start(SSH_SMSG_SUCCESS); 43760573Skris packet_send(); 43860573Skris packet_write_wait(); 43960573Skris} 440