10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 30Sstevel@tonic-gate * All rights reserved 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * As far as I am concerned, the code I have written for this software 60Sstevel@tonic-gate * can be used freely for any purpose. Any derived versions of this 70Sstevel@tonic-gate * software must be clearly marked as such, and if the derived work is 80Sstevel@tonic-gate * incompatible with the protocol description in the RFC file, it must be 90Sstevel@tonic-gate * called by a name other than "ssh" or "Secure Shell". 100Sstevel@tonic-gate */ 110Sstevel@tonic-gate /* 12*5562Sjp161948 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 130Sstevel@tonic-gate * Use is subject to license terms. 140Sstevel@tonic-gate */ 150Sstevel@tonic-gate 160Sstevel@tonic-gate #include "includes.h" 170Sstevel@tonic-gate RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $"); 180Sstevel@tonic-gate 190Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 200Sstevel@tonic-gate 210Sstevel@tonic-gate #include "xmalloc.h" 220Sstevel@tonic-gate #include "rsa.h" 230Sstevel@tonic-gate #include "ssh1.h" 240Sstevel@tonic-gate #include "packet.h" 250Sstevel@tonic-gate #include "buffer.h" 260Sstevel@tonic-gate #include "mpaux.h" 270Sstevel@tonic-gate #include "log.h" 280Sstevel@tonic-gate #include "servconf.h" 290Sstevel@tonic-gate #include "compat.h" 300Sstevel@tonic-gate #include "auth.h" 310Sstevel@tonic-gate #include "channels.h" 320Sstevel@tonic-gate #include "session.h" 330Sstevel@tonic-gate #include "uidswap.h" 340Sstevel@tonic-gate 350Sstevel@tonic-gate #ifdef HAVE_BSM 360Sstevel@tonic-gate #include "bsmaudit.h" 370Sstevel@tonic-gate extern adt_session_data_t *ah; 380Sstevel@tonic-gate #endif /* HAVE_BSM */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate /* import */ 410Sstevel@tonic-gate extern ServerOptions options; 420Sstevel@tonic-gate 430Sstevel@tonic-gate /* 440Sstevel@tonic-gate * convert ssh auth msg type into description 450Sstevel@tonic-gate */ 460Sstevel@tonic-gate static char * 470Sstevel@tonic-gate get_authname(int type) 480Sstevel@tonic-gate { 490Sstevel@tonic-gate static char buf[1024]; 500Sstevel@tonic-gate switch (type) { 510Sstevel@tonic-gate case SSH_CMSG_AUTH_PASSWORD: 520Sstevel@tonic-gate return "password"; 530Sstevel@tonic-gate case SSH_CMSG_AUTH_RSA: 540Sstevel@tonic-gate return "rsa"; 550Sstevel@tonic-gate case SSH_CMSG_AUTH_RHOSTS_RSA: 560Sstevel@tonic-gate return "rhosts-rsa"; 570Sstevel@tonic-gate case SSH_CMSG_AUTH_RHOSTS: 580Sstevel@tonic-gate return "rhosts"; 590Sstevel@tonic-gate case SSH_CMSG_AUTH_TIS: 600Sstevel@tonic-gate case SSH_CMSG_AUTH_TIS_RESPONSE: 610Sstevel@tonic-gate return "challenge-response"; 620Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 630Sstevel@tonic-gate case SSH_CMSG_AUTH_KERBEROS: 640Sstevel@tonic-gate return "kerberos"; 650Sstevel@tonic-gate #endif 660Sstevel@tonic-gate } 670Sstevel@tonic-gate snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); 680Sstevel@tonic-gate return buf; 690Sstevel@tonic-gate } 700Sstevel@tonic-gate 710Sstevel@tonic-gate /* 720Sstevel@tonic-gate * read packets, try to authenticate the user and 730Sstevel@tonic-gate * return only if authentication is successful 740Sstevel@tonic-gate */ 750Sstevel@tonic-gate static void 760Sstevel@tonic-gate do_authloop(Authctxt *authctxt) 770Sstevel@tonic-gate { 780Sstevel@tonic-gate int authenticated = 0; 790Sstevel@tonic-gate u_int bits; 800Sstevel@tonic-gate Key *client_host_key; 810Sstevel@tonic-gate BIGNUM *n; 820Sstevel@tonic-gate char *client_user, *password; 830Sstevel@tonic-gate char info[1024]; 840Sstevel@tonic-gate u_int dlen; 850Sstevel@tonic-gate u_int ulen; 860Sstevel@tonic-gate int type = 0; 870Sstevel@tonic-gate struct passwd *pw = authctxt->pw; 880Sstevel@tonic-gate 890Sstevel@tonic-gate debug("Attempting authentication for %s%.100s.", 900Sstevel@tonic-gate authctxt->valid ? "" : "illegal user ", authctxt->user); 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* If the user has no password, accept authentication immediately. */ 930Sstevel@tonic-gate if (options.password_authentication && 940Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 950Sstevel@tonic-gate (!options.kerberos_authentication || options.kerberos_or_local_passwd) && 960Sstevel@tonic-gate #endif 97*5562Sjp161948 auth_password(authctxt, "")) { 980Sstevel@tonic-gate auth_log(authctxt, 1, "without authentication", ""); 990Sstevel@tonic-gate return; 1000Sstevel@tonic-gate } 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate /* Indicate that authentication is needed. */ 1030Sstevel@tonic-gate packet_start(SSH_SMSG_FAILURE); 1040Sstevel@tonic-gate packet_send(); 1050Sstevel@tonic-gate packet_write_wait(); 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate client_user = NULL; 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate for ( ;; ) { 1100Sstevel@tonic-gate /* default to fail */ 1110Sstevel@tonic-gate authenticated = 0; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate info[0] = '\0'; 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate /* Get a packet from the client. */ 1160Sstevel@tonic-gate authctxt->v1_auth_type = type = packet_read(); 1170Sstevel@tonic-gate authctxt->v1_auth_name = get_authname(type); 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate authctxt->attempt++; 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate /* Process the packet. */ 1220Sstevel@tonic-gate switch (type) { 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 1250Sstevel@tonic-gate case SSH_CMSG_AUTH_KERBEROS: 1260Sstevel@tonic-gate if (!options.kerberos_authentication) { 1270Sstevel@tonic-gate verbose("Kerberos authentication disabled."); 1280Sstevel@tonic-gate } else { 1290Sstevel@tonic-gate char *kdata = packet_get_string(&dlen); 1300Sstevel@tonic-gate packet_check_eom(); 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate if (kdata[0] == 4) { /* KRB_PROT_VERSION */ 1330Sstevel@tonic-gate #ifdef KRB4 1340Sstevel@tonic-gate KTEXT_ST tkt, reply; 1350Sstevel@tonic-gate tkt.length = dlen; 1360Sstevel@tonic-gate if (tkt.length < MAX_KTXT_LEN) 1370Sstevel@tonic-gate memcpy(tkt.dat, kdata, tkt.length); 1380Sstevel@tonic-gate 139*5562Sjp161948 if (auth_krb4(authctxt, &tkt, 140*5562Sjp161948 &client_user, &reply)) { 1410Sstevel@tonic-gate authenticated = 1; 1420Sstevel@tonic-gate snprintf(info, sizeof(info), 1430Sstevel@tonic-gate " tktuser %.100s", 1440Sstevel@tonic-gate client_user); 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate packet_start( 1470Sstevel@tonic-gate SSH_SMSG_AUTH_KERBEROS_RESPONSE); 1480Sstevel@tonic-gate packet_put_string((char *) 1490Sstevel@tonic-gate reply.dat, reply.length); 1500Sstevel@tonic-gate packet_send(); 1510Sstevel@tonic-gate packet_write_wait(); 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate #endif /* KRB4 */ 1540Sstevel@tonic-gate } else { 1550Sstevel@tonic-gate #ifdef KRB5 1560Sstevel@tonic-gate krb5_data tkt, reply; 1570Sstevel@tonic-gate tkt.length = dlen; 1580Sstevel@tonic-gate tkt.data = kdata; 1590Sstevel@tonic-gate 160*5562Sjp161948 if (auth_krb5(authctxt, &tkt, 161*5562Sjp161948 &client_user, &reply)) { 1620Sstevel@tonic-gate authenticated = 1; 1630Sstevel@tonic-gate snprintf(info, sizeof(info), 1640Sstevel@tonic-gate " tktuser %.100s", 1650Sstevel@tonic-gate client_user); 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate /* Send response to client */ 1680Sstevel@tonic-gate packet_start( 1690Sstevel@tonic-gate SSH_SMSG_AUTH_KERBEROS_RESPONSE); 1700Sstevel@tonic-gate packet_put_string((char *) 1710Sstevel@tonic-gate reply.data, reply.length); 1720Sstevel@tonic-gate packet_send(); 1730Sstevel@tonic-gate packet_write_wait(); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate if (reply.length) 1760Sstevel@tonic-gate xfree(reply.data); 1770Sstevel@tonic-gate } 1780Sstevel@tonic-gate #endif /* KRB5 */ 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate xfree(kdata); 1810Sstevel@tonic-gate } 1820Sstevel@tonic-gate break; 1830Sstevel@tonic-gate #endif /* KRB4 || KRB5 */ 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 1860Sstevel@tonic-gate /* XXX - punt on backward compatibility here. */ 1870Sstevel@tonic-gate case SSH_CMSG_HAVE_KERBEROS_TGT: 1880Sstevel@tonic-gate packet_send_debug("Kerberos TGT passing disabled before authentication."); 1890Sstevel@tonic-gate break; 1900Sstevel@tonic-gate #ifdef AFS 1910Sstevel@tonic-gate case SSH_CMSG_HAVE_AFS_TOKEN: 1920Sstevel@tonic-gate packet_send_debug("AFS token passing disabled before authentication."); 1930Sstevel@tonic-gate break; 1940Sstevel@tonic-gate #endif /* AFS */ 1950Sstevel@tonic-gate #endif /* AFS || KRB5 */ 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate case SSH_CMSG_AUTH_RHOSTS: 1980Sstevel@tonic-gate if (!options.rhosts_authentication) { 1990Sstevel@tonic-gate verbose("Rhosts authentication disabled."); 2000Sstevel@tonic-gate break; 2010Sstevel@tonic-gate } 2020Sstevel@tonic-gate /* 2030Sstevel@tonic-gate * Get client user name. Note that we just have to 2040Sstevel@tonic-gate * trust the client; this is one reason why rhosts 2050Sstevel@tonic-gate * authentication is insecure. (Another is 2060Sstevel@tonic-gate * IP-spoofing on a local network.) 2070Sstevel@tonic-gate */ 2080Sstevel@tonic-gate client_user = packet_get_string(&ulen); 2090Sstevel@tonic-gate packet_check_eom(); 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ 2120Sstevel@tonic-gate authenticated = auth_rhosts(pw, client_user); 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate snprintf(info, sizeof info, " ruser %.100s", client_user); 2150Sstevel@tonic-gate break; 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate case SSH_CMSG_AUTH_RHOSTS_RSA: 2180Sstevel@tonic-gate if (!options.rhosts_rsa_authentication) { 2190Sstevel@tonic-gate verbose("Rhosts with RSA authentication disabled."); 2200Sstevel@tonic-gate break; 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate /* 2230Sstevel@tonic-gate * Get client user name. Note that we just have to 2240Sstevel@tonic-gate * trust the client; root on the client machine can 2250Sstevel@tonic-gate * claim to be any user. 2260Sstevel@tonic-gate */ 2270Sstevel@tonic-gate client_user = packet_get_string(&ulen); 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* Get the client host key. */ 2300Sstevel@tonic-gate client_host_key = key_new(KEY_RSA1); 2310Sstevel@tonic-gate bits = packet_get_int(); 2320Sstevel@tonic-gate packet_get_bignum(client_host_key->rsa->e); 2330Sstevel@tonic-gate packet_get_bignum(client_host_key->rsa->n); 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if (bits != BN_num_bits(client_host_key->rsa->n)) 2360Sstevel@tonic-gate verbose("Warning: keysize mismatch for client_host_key: " 2370Sstevel@tonic-gate "actual %d, announced %d", 2380Sstevel@tonic-gate BN_num_bits(client_host_key->rsa->n), bits); 2390Sstevel@tonic-gate packet_check_eom(); 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate authenticated = auth_rhosts_rsa(pw, client_user, 2420Sstevel@tonic-gate client_host_key); 2430Sstevel@tonic-gate key_free(client_host_key); 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate snprintf(info, sizeof info, " ruser %.100s", client_user); 2460Sstevel@tonic-gate break; 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate case SSH_CMSG_AUTH_RSA: 2490Sstevel@tonic-gate if (!options.rsa_authentication) { 2500Sstevel@tonic-gate verbose("RSA authentication disabled."); 2510Sstevel@tonic-gate break; 2520Sstevel@tonic-gate } 2530Sstevel@tonic-gate /* RSA authentication requested. */ 2540Sstevel@tonic-gate if ((n = BN_new()) == NULL) 2550Sstevel@tonic-gate fatal("do_authloop: BN_new failed"); 2560Sstevel@tonic-gate packet_get_bignum(n); 2570Sstevel@tonic-gate packet_check_eom(); 2580Sstevel@tonic-gate authenticated = auth_rsa(pw, n); 2590Sstevel@tonic-gate BN_clear_free(n); 2600Sstevel@tonic-gate break; 2610Sstevel@tonic-gate 2620Sstevel@tonic-gate case SSH_CMSG_AUTH_PASSWORD: 2630Sstevel@tonic-gate authctxt->init_attempt++; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate if (!options.password_authentication) { 2660Sstevel@tonic-gate verbose("Password authentication disabled."); 2670Sstevel@tonic-gate break; 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate /* 2700Sstevel@tonic-gate * Read user password. It is in plain text, but was 2710Sstevel@tonic-gate * transmitted over the encrypted channel so it is 2720Sstevel@tonic-gate * not visible to an outside observer. 2730Sstevel@tonic-gate */ 2740Sstevel@tonic-gate password = packet_get_string(&dlen); 2750Sstevel@tonic-gate packet_check_eom(); 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate /* Try authentication with the password. */ 2780Sstevel@tonic-gate if (authctxt->init_failures < 2790Sstevel@tonic-gate options.max_init_auth_tries) 2800Sstevel@tonic-gate authenticated = 281*5562Sjp161948 auth_password(authctxt, password); 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate memset(password, 0, strlen(password)); 2840Sstevel@tonic-gate xfree(password); 2850Sstevel@tonic-gate break; 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate case SSH_CMSG_AUTH_TIS: 2880Sstevel@tonic-gate debug("rcvd SSH_CMSG_AUTH_TIS"); 2890Sstevel@tonic-gate if (options.challenge_response_authentication == 1) { 2900Sstevel@tonic-gate char *challenge = get_challenge(authctxt); 2910Sstevel@tonic-gate if (challenge != NULL) { 2920Sstevel@tonic-gate debug("sending challenge '%s'", challenge); 2930Sstevel@tonic-gate packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); 2940Sstevel@tonic-gate packet_put_cstring(challenge); 2950Sstevel@tonic-gate xfree(challenge); 2960Sstevel@tonic-gate packet_send(); 2970Sstevel@tonic-gate packet_write_wait(); 2980Sstevel@tonic-gate continue; 2990Sstevel@tonic-gate } 3000Sstevel@tonic-gate } 3010Sstevel@tonic-gate break; 3020Sstevel@tonic-gate case SSH_CMSG_AUTH_TIS_RESPONSE: 3030Sstevel@tonic-gate debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); 3040Sstevel@tonic-gate if (options.challenge_response_authentication == 1) { 3050Sstevel@tonic-gate char *response = packet_get_string(&dlen); 3060Sstevel@tonic-gate debug("got response '%s'", response); 3070Sstevel@tonic-gate packet_check_eom(); 3080Sstevel@tonic-gate authenticated = verify_response(authctxt, response); 3090Sstevel@tonic-gate memset(response, 'r', dlen); 3100Sstevel@tonic-gate xfree(response); 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate break; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate default: 3150Sstevel@tonic-gate /* 3160Sstevel@tonic-gate * Any unknown messages will be ignored (and failure 3170Sstevel@tonic-gate * returned) during authentication. 3180Sstevel@tonic-gate */ 3190Sstevel@tonic-gate log("Unknown message during authentication: type %d", type); 3200Sstevel@tonic-gate break; 3210Sstevel@tonic-gate } 3220Sstevel@tonic-gate #ifdef BSD_AUTH 3230Sstevel@tonic-gate if (authctxt->as) { 3240Sstevel@tonic-gate auth_close(authctxt->as); 3250Sstevel@tonic-gate authctxt->as = NULL; 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate #endif 3280Sstevel@tonic-gate if (!authctxt->valid && authenticated) { 3290Sstevel@tonic-gate authenticated = 0; 3300Sstevel@tonic-gate log("Ignoring authenticated invalid user %s", 3310Sstevel@tonic-gate authctxt->user); 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate #ifdef _UNICOS 3350Sstevel@tonic-gate if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated) 3360Sstevel@tonic-gate cray_login_failure(authctxt->user, IA_UDBERR); 3370Sstevel@tonic-gate if (authenticated && cray_access_denied(authctxt->user)) { 3380Sstevel@tonic-gate authenticated = 0; 3390Sstevel@tonic-gate fatal("Access denied for user %s.",authctxt->user); 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate #endif /* _UNICOS */ 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate #ifdef HAVE_CYGWIN 3440Sstevel@tonic-gate if (authenticated && 3450Sstevel@tonic-gate !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) { 3460Sstevel@tonic-gate packet_disconnect("Authentication rejected for uid %d.", 3470Sstevel@tonic-gate pw == NULL ? -1 : pw->pw_uid); 3480Sstevel@tonic-gate authenticated = 0; 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate #else 3510Sstevel@tonic-gate /* Special handling for root */ 352*5562Sjp161948 if (authenticated && authctxt->pw->pw_uid == 0 && 3530Sstevel@tonic-gate !auth_root_allowed(get_authname(type))) 3540Sstevel@tonic-gate authenticated = 0; 3550Sstevel@tonic-gate #endif 3560Sstevel@tonic-gate #ifdef USE_PAM 3570Sstevel@tonic-gate if (authenticated && type != SSH_CMSG_AUTH_PASSWORD) 3580Sstevel@tonic-gate authenticated = do_pam_non_initial_userauth(authctxt); 3590Sstevel@tonic-gate else if (authenticated && !AUTHPAM_DONE(authctxt)) 3600Sstevel@tonic-gate authenticated = 0; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate if (!authenticated) 3630Sstevel@tonic-gate authctxt->pam_retval = AUTHPAM_ERROR(authctxt, 3640Sstevel@tonic-gate PAM_PERM_DENIED); 3650Sstevel@tonic-gate #endif /* USE_PAM */ 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate /* Log before sending the reply */ 3680Sstevel@tonic-gate auth_log(authctxt, authenticated, get_authname(type), info); 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate if (client_user != NULL) { 3710Sstevel@tonic-gate xfree(client_user); 3720Sstevel@tonic-gate client_user = NULL; 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate if (authenticated) 3760Sstevel@tonic-gate return; 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate if (type == SSH_CMSG_AUTH_PASSWORD) 3790Sstevel@tonic-gate authctxt->init_failures++; 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate if (authctxt->failures++ > options.max_auth_tries) { 3820Sstevel@tonic-gate #ifdef HAVE_BSM 3830Sstevel@tonic-gate fatal_remove_cleanup(audit_failed_login_cleanup, 3840Sstevel@tonic-gate authctxt); 3850Sstevel@tonic-gate audit_sshd_login_failure(&ah, PAM_MAXTRIES); 3860Sstevel@tonic-gate #endif /* HAVE_BSM */ 3870Sstevel@tonic-gate packet_disconnect(AUTH_FAIL_MSG, authctxt->user); 3880Sstevel@tonic-gate } 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate packet_start(SSH_SMSG_FAILURE); 3910Sstevel@tonic-gate packet_send(); 3920Sstevel@tonic-gate packet_write_wait(); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate /* 3970Sstevel@tonic-gate * Performs authentication of an incoming connection. Session key has already 3980Sstevel@tonic-gate * been exchanged and encryption is enabled. 3990Sstevel@tonic-gate */ 4000Sstevel@tonic-gate Authctxt * 4010Sstevel@tonic-gate do_authentication(void) 4020Sstevel@tonic-gate { 4030Sstevel@tonic-gate Authctxt *authctxt; 4040Sstevel@tonic-gate u_int ulen; 4050Sstevel@tonic-gate char *user, *style = NULL; 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* Get the name of the user that we wish to log in as. */ 4080Sstevel@tonic-gate packet_read_expect(SSH_CMSG_USER); 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate /* Get the user name. */ 4110Sstevel@tonic-gate user = packet_get_string(&ulen); 4120Sstevel@tonic-gate packet_check_eom(); 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate if ((style = strchr(user, ':')) != NULL) 4150Sstevel@tonic-gate *style++ = '\0'; 4160Sstevel@tonic-gate 4170Sstevel@tonic-gate #ifdef KRB5 4180Sstevel@tonic-gate /* XXX - SSH.com Kerberos v5 braindeath. */ 4190Sstevel@tonic-gate if ((datafellows & SSH_BUG_K5USER) && 4200Sstevel@tonic-gate options.kerberos_authentication) { 4210Sstevel@tonic-gate char *p; 4220Sstevel@tonic-gate if ((p = strchr(user, '@')) != NULL) 4230Sstevel@tonic-gate *p = '\0'; 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate #endif 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate authctxt = authctxt_new(); 4280Sstevel@tonic-gate authctxt->user = user; 4290Sstevel@tonic-gate authctxt->style = style; 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate #ifdef HAVE_BSM 4320Sstevel@tonic-gate fatal_add_cleanup(audit_failed_login_cleanup, authctxt); 4330Sstevel@tonic-gate #endif /* HAVE_BSM */ 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate /* Verify that the user is a valid user. */ 436*5562Sjp161948 if ((authctxt->pw = getpwnamallow(user)) != NULL) { 4370Sstevel@tonic-gate authctxt->valid = 1; 4380Sstevel@tonic-gate } else { 4390Sstevel@tonic-gate authctxt->valid = 0; 4400Sstevel@tonic-gate debug("do_authentication: illegal user %s", user); 4410Sstevel@tonic-gate } 4420Sstevel@tonic-gate 443*5562Sjp161948 setproctitle("%s", authctxt->pw ? user : "unknown"); 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate /* 4460Sstevel@tonic-gate * If we are not running as root, the user must have the same uid as 4470Sstevel@tonic-gate * the server. (Unless you are running Windows) 4480Sstevel@tonic-gate */ 4490Sstevel@tonic-gate #ifndef HAVE_CYGWIN 450*5562Sjp161948 if (getuid() != 0 && authctxt->pw && 4510Sstevel@tonic-gate authctxt->pw->pw_uid != getuid()) 4520Sstevel@tonic-gate packet_disconnect("Cannot change user when server not running as root."); 4530Sstevel@tonic-gate #endif 4540Sstevel@tonic-gate 4550Sstevel@tonic-gate /* 4560Sstevel@tonic-gate * Loop until the user has been authenticated or the connection is 4570Sstevel@tonic-gate * closed, do_authloop() returns only if authentication is successful 4580Sstevel@tonic-gate */ 4590Sstevel@tonic-gate do_authloop(authctxt); 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate /* The user has been authenticated and accepted. */ 4620Sstevel@tonic-gate packet_start(SSH_SMSG_SUCCESS); 4630Sstevel@tonic-gate packet_send(); 4640Sstevel@tonic-gate packet_write_wait(); 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate return (authctxt); 4670Sstevel@tonic-gate } 468