1295367Sdes/* $OpenBSD: auth1.c,v 1.82 2014/07/15 15:54:14 millert 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 15295367Sdes#ifdef WITH_SSH1 16295367Sdes 17162856Sdes#include <sys/types.h> 18162856Sdes 19162856Sdes#include <stdarg.h> 20162856Sdes#include <stdio.h> 21162856Sdes#include <string.h> 22162856Sdes#include <unistd.h> 23162856Sdes#include <pwd.h> 24162856Sdes 25181111Sdes#include "openbsd-compat/sys-queue.h" 2660573Skris#include "xmalloc.h" 2760573Skris#include "rsa.h" 2876262Sgreen#include "ssh1.h" 2960573Skris#include "packet.h" 3060573Skris#include "buffer.h" 3176262Sgreen#include "log.h" 32295367Sdes#include "misc.h" 3360573Skris#include "servconf.h" 3460573Skris#include "compat.h" 35162856Sdes#include "key.h" 36162856Sdes#include "hostfile.h" 3760573Skris#include "auth.h" 3892559Sdes#include "channels.h" 3960573Skris#include "session.h" 4092559Sdes#include "uidswap.h" 41162856Sdes#ifdef GSSAPI 42162856Sdes#include "ssh-gss.h" 43162856Sdes#endif 4498684Sdes#include "monitor_wrap.h" 45147005Sdes#include "buffer.h" 4692559Sdes 4760573Skris/* import */ 4860573Skrisextern ServerOptions options; 49147005Sdesextern Buffer loginmsg; 5060573Skris 51255767Sdesstatic int auth1_process_password(Authctxt *); 52255767Sdesstatic int auth1_process_rsa(Authctxt *); 53255767Sdesstatic int auth1_process_rhosts_rsa(Authctxt *); 54255767Sdesstatic int auth1_process_tis_challenge(Authctxt *); 55255767Sdesstatic int auth1_process_tis_response(Authctxt *); 56149753Sdes 57149753Sdesstatic char *client_user = NULL; /* Used to fill in remote user for PAM */ 58149753Sdes 59149753Sdesstruct AuthMethod1 { 60149753Sdes int type; 61149753Sdes char *name; 62149753Sdes int *enabled; 63255767Sdes int (*method)(Authctxt *); 64149753Sdes}; 65149753Sdes 66149753Sdesconst struct AuthMethod1 auth1_methods[] = { 67149753Sdes { 68149753Sdes SSH_CMSG_AUTH_PASSWORD, "password", 69149753Sdes &options.password_authentication, auth1_process_password 70149753Sdes }, 71149753Sdes { 72149753Sdes SSH_CMSG_AUTH_RSA, "rsa", 73149753Sdes &options.rsa_authentication, auth1_process_rsa 74149753Sdes }, 75149753Sdes { 76149753Sdes SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa", 77149753Sdes &options.rhosts_rsa_authentication, auth1_process_rhosts_rsa 78149753Sdes }, 79149753Sdes { 80149753Sdes SSH_CMSG_AUTH_TIS, "challenge-response", 81149753Sdes &options.challenge_response_authentication, 82149753Sdes auth1_process_tis_challenge 83149753Sdes }, 84149753Sdes { 85149753Sdes SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response", 86149753Sdes &options.challenge_response_authentication, 87149753Sdes auth1_process_tis_response 88149753Sdes }, 89149753Sdes { -1, NULL, NULL, NULL} 90149753Sdes}; 91149753Sdes 92149753Sdesstatic const struct AuthMethod1 93149753Sdes*lookup_authmethod1(int type) 94149753Sdes{ 95149753Sdes int i; 96149753Sdes 97162856Sdes for (i = 0; auth1_methods[i].name != NULL; i++) 98149753Sdes if (auth1_methods[i].type == type) 99149753Sdes return (&(auth1_methods[i])); 100149753Sdes 101149753Sdes return (NULL); 102149753Sdes} 103149753Sdes 10492559Sdesstatic char * 10560573Skrisget_authname(int type) 10660573Skris{ 107149753Sdes const struct AuthMethod1 *a; 108149753Sdes static char buf[64]; 109149753Sdes 110149753Sdes if ((a = lookup_authmethod1(type)) != NULL) 111149753Sdes return (a->name); 112149753Sdes snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type); 113149753Sdes return (buf); 114149753Sdes} 115149753Sdes 116162856Sdes/*ARGSUSED*/ 117149753Sdesstatic int 118255767Sdesauth1_process_password(Authctxt *authctxt) 119149753Sdes{ 120149753Sdes int authenticated = 0; 121149753Sdes char *password; 122149753Sdes u_int dlen; 123149753Sdes 124149753Sdes /* 125149753Sdes * Read user password. It is in plain text, but was 126149753Sdes * transmitted over the encrypted channel so it is 127149753Sdes * not visible to an outside observer. 128149753Sdes */ 129149753Sdes password = packet_get_string(&dlen); 130149753Sdes packet_check_eom(); 131149753Sdes 132149753Sdes /* Try authentication with the password. */ 133149753Sdes authenticated = PRIVSEP(auth_password(authctxt, password)); 134149753Sdes 135264377Sdes explicit_bzero(password, dlen); 136255767Sdes free(password); 137149753Sdes 138149753Sdes return (authenticated); 139149753Sdes} 140149753Sdes 141162856Sdes/*ARGSUSED*/ 142149753Sdesstatic int 143255767Sdesauth1_process_rsa(Authctxt *authctxt) 144149753Sdes{ 145149753Sdes int authenticated = 0; 146149753Sdes BIGNUM *n; 147149753Sdes 148149753Sdes /* RSA authentication requested. */ 149149753Sdes if ((n = BN_new()) == NULL) 150149753Sdes fatal("do_authloop: BN_new failed"); 151149753Sdes packet_get_bignum(n); 152149753Sdes packet_check_eom(); 153149753Sdes authenticated = auth_rsa(authctxt, n); 154149753Sdes BN_clear_free(n); 155149753Sdes 156149753Sdes return (authenticated); 157149753Sdes} 158149753Sdes 159162856Sdes/*ARGSUSED*/ 160149753Sdesstatic int 161255767Sdesauth1_process_rhosts_rsa(Authctxt *authctxt) 162149753Sdes{ 163149753Sdes int keybits, authenticated = 0; 164149753Sdes u_int bits; 165149753Sdes Key *client_host_key; 166149753Sdes u_int ulen; 167149753Sdes 168149753Sdes /* 169149753Sdes * Get client user name. Note that we just have to 170149753Sdes * trust the client; root on the client machine can 171149753Sdes * claim to be any user. 172149753Sdes */ 173221420Sdes client_user = packet_get_cstring(&ulen); 174149753Sdes 175149753Sdes /* Get the client host key. */ 176149753Sdes client_host_key = key_new(KEY_RSA1); 177149753Sdes bits = packet_get_int(); 178149753Sdes packet_get_bignum(client_host_key->rsa->e); 179149753Sdes packet_get_bignum(client_host_key->rsa->n); 180149753Sdes 181149753Sdes keybits = BN_num_bits(client_host_key->rsa->n); 182149753Sdes if (keybits < 0 || bits != (u_int)keybits) { 183149753Sdes verbose("Warning: keysize mismatch for client_host_key: " 184149753Sdes "actual %d, announced %d", 185149753Sdes BN_num_bits(client_host_key->rsa->n), bits); 18660573Skris } 187149753Sdes packet_check_eom(); 188149753Sdes 189149753Sdes authenticated = auth_rhosts_rsa(authctxt, client_user, 190149753Sdes client_host_key); 191149753Sdes key_free(client_host_key); 192149753Sdes 193255767Sdes auth_info(authctxt, "ruser %.100s", client_user); 194149753Sdes 195149753Sdes return (authenticated); 19660573Skris} 19760573Skris 198162856Sdes/*ARGSUSED*/ 199149753Sdesstatic int 200255767Sdesauth1_process_tis_challenge(Authctxt *authctxt) 201149753Sdes{ 202149753Sdes char *challenge; 203149753Sdes 204149753Sdes if ((challenge = get_challenge(authctxt)) == NULL) 205149753Sdes return (0); 206149753Sdes 207149753Sdes debug("sending challenge '%s'", challenge); 208149753Sdes packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 209149753Sdes packet_put_cstring(challenge); 210255767Sdes free(challenge); 211149753Sdes packet_send(); 212149753Sdes packet_write_wait(); 213149753Sdes 214149753Sdes return (-1); 215149753Sdes} 216149753Sdes 217162856Sdes/*ARGSUSED*/ 218149753Sdesstatic int 219255767Sdesauth1_process_tis_response(Authctxt *authctxt) 220149753Sdes{ 221149753Sdes int authenticated = 0; 222149753Sdes char *response; 223149753Sdes u_int dlen; 224149753Sdes 225149753Sdes response = packet_get_string(&dlen); 226149753Sdes packet_check_eom(); 227149753Sdes authenticated = verify_response(authctxt, response); 228264377Sdes explicit_bzero(response, dlen); 229255767Sdes free(response); 230149753Sdes 231149753Sdes return (authenticated); 232149753Sdes} 233149753Sdes 23460573Skris/* 23576262Sgreen * read packets, try to authenticate the user and 23676262Sgreen * return only if authentication is successful 23760573Skris */ 23892559Sdesstatic void 23976262Sgreendo_authloop(Authctxt *authctxt) 24060573Skris{ 24169591Sgreen int authenticated = 0; 242149753Sdes int prev = 0, type = 0; 243149753Sdes const struct AuthMethod1 *meth; 24460573Skris 24576262Sgreen debug("Attempting authentication for %s%.100s.", 246137019Sdes authctxt->valid ? "" : "invalid user ", authctxt->user); 24776262Sgreen 24876262Sgreen /* If the user has no password, accept authentication immediately. */ 249215116Sdes if (options.permit_empty_passwd && options.password_authentication && 250124211Sdes#ifdef KRB5 25192559Sdes (!options.kerberos_authentication || options.kerberos_or_local_passwd) && 25276262Sgreen#endif 25398684Sdes PRIVSEP(auth_password(authctxt, ""))) { 254137019Sdes#ifdef USE_PAM 255137019Sdes if (options.use_pam && (PRIVSEP(do_pam_account()))) 256137019Sdes#endif 257137019Sdes { 258248619Sdes auth_log(authctxt, 1, 0, "without authentication", 259255767Sdes NULL); 260137019Sdes return; 261137019Sdes } 26276262Sgreen } 26376262Sgreen 26460573Skris /* Indicate that authentication is needed. */ 26560573Skris packet_start(SSH_SMSG_FAILURE); 26660573Skris packet_send(); 26760573Skris packet_write_wait(); 26860573Skris 26976262Sgreen for (;;) { 27069591Sgreen /* default to fail */ 27169591Sgreen authenticated = 0; 27269591Sgreen 27360573Skris 27460573Skris /* Get a packet from the client. */ 275112870Sdes prev = type; 27692559Sdes type = packet_read(); 27760573Skris 278112870Sdes /* 279112870Sdes * If we started challenge-response authentication but the 280112870Sdes * next packet is not a response to our challenge, release 281112870Sdes * the resources allocated by get_challenge() (which would 282112870Sdes * normally have been released by verify_response() had we 283112870Sdes * received such a response) 284112870Sdes */ 285112870Sdes if (prev == SSH_CMSG_AUTH_TIS && 286112870Sdes type != SSH_CMSG_AUTH_TIS_RESPONSE) 287112870Sdes abandon_challenge_response(authctxt); 288112870Sdes 289181111Sdes if (authctxt->failures >= options.max_authtries) 290181111Sdes goto skip; 291149753Sdes if ((meth = lookup_authmethod1(type)) == NULL) { 292149753Sdes logit("Unknown message during authentication: " 293149753Sdes "type %d", type); 294149753Sdes goto skip; 295149753Sdes } 29660573Skris 297149753Sdes if (!*(meth->enabled)) { 298149753Sdes verbose("%s authentication disabled.", meth->name); 299149753Sdes goto skip; 300149753Sdes } 30160573Skris 302255767Sdes authenticated = meth->method(authctxt); 303149753Sdes if (authenticated == -1) 304149753Sdes continue; /* "postponed" */ 30560573Skris 30676262Sgreen#ifdef BSD_AUTH 30776262Sgreen if (authctxt->as) { 30876262Sgreen auth_close(authctxt->as); 30976262Sgreen authctxt->as = NULL; 31076262Sgreen } 31176262Sgreen#endif 31276262Sgreen if (!authctxt->valid && authenticated) 31376262Sgreen fatal("INTERNAL ERROR: authenticated invalid user %s", 31476262Sgreen authctxt->user); 31560576Skris 316106130Sdes#ifdef _UNICOS 317106130Sdes if (authenticated && cray_access_denied(authctxt->user)) { 318106130Sdes authenticated = 0; 319106130Sdes fatal("Access denied for user %s.",authctxt->user); 320106130Sdes } 321106130Sdes#endif /* _UNICOS */ 322106130Sdes 323197679Sdes#ifndef HAVE_CYGWIN 32476262Sgreen /* Special handling for root */ 325113911Sdes if (authenticated && authctxt->pw->pw_uid == 0 && 326149753Sdes !auth_root_allowed(meth->name)) { 327149753Sdes authenticated = 0; 328147005Sdes# ifdef SSH_AUDIT_EVENTS 329147005Sdes PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 330147005Sdes# endif 331147005Sdes } 33298941Sdes#endif 333124211Sdes 33498941Sdes#ifdef USE_PAM 335126277Sdes if (options.use_pam && authenticated && 336147005Sdes !PRIVSEP(do_pam_account())) { 337147005Sdes char *msg; 338147005Sdes size_t len; 339147005Sdes 340147005Sdes error("Access denied for user %s by PAM account " 341149753Sdes "configuration", authctxt->user); 342147005Sdes len = buffer_len(&loginmsg); 343147005Sdes buffer_append(&loginmsg, "\0", 1); 344147005Sdes msg = buffer_ptr(&loginmsg); 345147005Sdes /* strip trailing newlines */ 346147005Sdes if (len > 0) 347147005Sdes while (len > 0 && msg[--len] == '\n') 348147005Sdes msg[len] = '\0'; 349147005Sdes else 350147005Sdes msg = "Access denied."; 351181111Sdes packet_disconnect("%s", msg); 352147005Sdes } 35398941Sdes#endif 35476262Sgreen 355149753Sdes skip: 35676262Sgreen /* Log before sending the reply */ 357255767Sdes auth_log(authctxt, authenticated, 0, get_authname(type), NULL); 35860573Skris 359255767Sdes free(client_user); 360255767Sdes client_user = NULL; 36169591Sgreen 36276262Sgreen if (authenticated) 36376262Sgreen return; 36460573Skris 365181111Sdes if (++authctxt->failures >= options.max_authtries) { 366147005Sdes#ifdef SSH_AUDIT_EVENTS 367147005Sdes PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 368147005Sdes#endif 369295367Sdes auth_maxtries_exceeded(authctxt); 370147005Sdes } 37176262Sgreen 37260573Skris packet_start(SSH_SMSG_FAILURE); 37360573Skris packet_send(); 37460573Skris packet_write_wait(); 37560573Skris } 37660573Skris} 37760573Skris 37860573Skris/* 37960573Skris * Performs authentication of an incoming connection. Session key has already 38060573Skris * been exchanged and encryption is enabled. 38160573Skris */ 382126277Sdesvoid 383126277Sdesdo_authentication(Authctxt *authctxt) 38460573Skris{ 38576262Sgreen u_int ulen; 38698684Sdes char *user, *style = NULL; 38760573Skris 38860573Skris /* Get the name of the user that we wish to log in as. */ 38992559Sdes packet_read_expect(SSH_CMSG_USER); 39060573Skris 39160573Skris /* Get the user name. */ 392221420Sdes user = packet_get_cstring(&ulen); 39392559Sdes packet_check_eom(); 39460573Skris 39576262Sgreen if ((style = strchr(user, ':')) != NULL) 39692559Sdes *style++ = '\0'; 39760573Skris 39876262Sgreen authctxt->user = user; 39976262Sgreen authctxt->style = style; 40060573Skris 40160573Skris /* Verify that the user is a valid user. */ 40298684Sdes if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 40376262Sgreen authctxt->valid = 1; 404124211Sdes else { 405137019Sdes debug("do_authentication: invalid user %s", user); 406124211Sdes authctxt->pw = fakepw(); 407124211Sdes } 40860573Skris 409248619Sdes /* Configuration may have changed as a result of Match */ 410248619Sdes if (options.num_auth_methods != 0) 411248619Sdes fatal("AuthenticationMethods is not supported with SSH " 412248619Sdes "protocol 1"); 413248619Sdes 414137019Sdes setproctitle("%s%s", authctxt->valid ? user : "unknown", 41598684Sdes use_privsep ? " [net]" : ""); 41676262Sgreen 41798941Sdes#ifdef USE_PAM 418124211Sdes if (options.use_pam) 419128460Sdes PRIVSEP(start_pam(authctxt)); 42098941Sdes#endif 42198941Sdes 42260573Skris /* 42360573Skris * If we are not running as root, the user must have the same uid as 424149753Sdes * the server. 42560573Skris */ 42698941Sdes#ifndef HAVE_CYGWIN 42798684Sdes if (!use_privsep && getuid() != 0 && authctxt->pw && 42898684Sdes authctxt->pw->pw_uid != getuid()) 42960573Skris packet_disconnect("Cannot change user when server not running as root."); 43098941Sdes#endif 43160573Skris 43276262Sgreen /* 43376262Sgreen * Loop until the user has been authenticated or the connection is 43476262Sgreen * closed, do_authloop() returns only if authentication is successful 43576262Sgreen */ 43676262Sgreen do_authloop(authctxt); 43760573Skris 43860573Skris /* The user has been authenticated and accepted. */ 43960573Skris packet_start(SSH_SMSG_SUCCESS); 44060573Skris packet_send(); 44160573Skris packet_write_wait(); 44260573Skris} 443295367Sdes 444295367Sdes#endif /* WITH_SSH1 */ 445