1*462c32cbSDag-Erling Smørgrav /* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 djm Exp $ */ 2a04a10f8SKris Kennaway /* 3a04a10f8SKris Kennaway * Copyright (c) 2000 Markus Friedl. All rights reserved. 4a04a10f8SKris Kennaway * 5a04a10f8SKris Kennaway * Redistribution and use in source and binary forms, with or without 6a04a10f8SKris Kennaway * modification, are permitted provided that the following conditions 7a04a10f8SKris Kennaway * are met: 8a04a10f8SKris Kennaway * 1. Redistributions of source code must retain the above copyright 9a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer. 10a04a10f8SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 11a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer in the 12a04a10f8SKris Kennaway * documentation and/or other materials provided with the distribution. 13a04a10f8SKris Kennaway * 14a04a10f8SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15a04a10f8SKris Kennaway * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16a04a10f8SKris Kennaway * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17a04a10f8SKris Kennaway * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18a04a10f8SKris Kennaway * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19a04a10f8SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20a04a10f8SKris Kennaway * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21a04a10f8SKris Kennaway * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22a04a10f8SKris Kennaway * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23a04a10f8SKris Kennaway * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24a04a10f8SKris Kennaway */ 25c2d3a559SKris Kennaway 26a04a10f8SKris Kennaway #include "includes.h" 27333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 28a04a10f8SKris Kennaway 29333ee039SDag-Erling Smørgrav #include <sys/types.h> 30d4af9e69SDag-Erling Smørgrav #include <sys/stat.h> 31d4af9e69SDag-Erling Smørgrav #include <sys/uio.h> 32333ee039SDag-Erling Smørgrav 33d4af9e69SDag-Erling Smørgrav #include <fcntl.h> 34333ee039SDag-Erling Smørgrav #include <pwd.h> 35333ee039SDag-Erling Smørgrav #include <stdarg.h> 36333ee039SDag-Erling Smørgrav #include <string.h> 37d4af9e69SDag-Erling Smørgrav #include <unistd.h> 38333ee039SDag-Erling Smørgrav 39d4af9e69SDag-Erling Smørgrav #include "atomicio.h" 407aee6ffeSDag-Erling Smørgrav #include "xmalloc.h" 41333ee039SDag-Erling Smørgrav #include "ssh2.h" 42a04a10f8SKris Kennaway #include "packet.h" 43ca3176e7SBrian Feldman #include "log.h" 44333ee039SDag-Erling Smørgrav #include "buffer.h" 45a04a10f8SKris Kennaway #include "servconf.h" 46a04a10f8SKris Kennaway #include "compat.h" 47333ee039SDag-Erling Smørgrav #include "key.h" 48333ee039SDag-Erling Smørgrav #include "hostfile.h" 49a04a10f8SKris Kennaway #include "auth.h" 50a04a10f8SKris Kennaway #include "dispatch.h" 51ca3176e7SBrian Feldman #include "pathnames.h" 52aa49c926SDag-Erling Smørgrav #include "buffer.h" 53333ee039SDag-Erling Smørgrav #include "canohost.h" 54a04a10f8SKris Kennaway 55cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 56cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h" 57cf2b5f3bSDag-Erling Smørgrav #endif 58333ee039SDag-Erling Smørgrav #include "monitor_wrap.h" 59cf2b5f3bSDag-Erling Smørgrav 60a04a10f8SKris Kennaway /* import */ 61a04a10f8SKris Kennaway extern ServerOptions options; 62ca3176e7SBrian Feldman extern u_char *session_id2; 63cf2b5f3bSDag-Erling Smørgrav extern u_int session_id2_len; 64aa49c926SDag-Erling Smørgrav extern Buffer loginmsg; 65a04a10f8SKris Kennaway 6680628bacSDag-Erling Smørgrav /* methods */ 6780628bacSDag-Erling Smørgrav 6880628bacSDag-Erling Smørgrav extern Authmethod method_none; 6980628bacSDag-Erling Smørgrav extern Authmethod method_pubkey; 7080628bacSDag-Erling Smørgrav extern Authmethod method_passwd; 7180628bacSDag-Erling Smørgrav extern Authmethod method_kbdint; 7280628bacSDag-Erling Smørgrav extern Authmethod method_hostbased; 73cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 74cf2b5f3bSDag-Erling Smørgrav extern Authmethod method_gssapi; 75cf2b5f3bSDag-Erling Smørgrav #endif 76cce7d346SDag-Erling Smørgrav #ifdef JPAKE 77cce7d346SDag-Erling Smørgrav extern Authmethod method_jpake; 78cce7d346SDag-Erling Smørgrav #endif 7980628bacSDag-Erling Smørgrav 8080628bacSDag-Erling Smørgrav Authmethod *authmethods[] = { 8180628bacSDag-Erling Smørgrav &method_none, 8280628bacSDag-Erling Smørgrav &method_pubkey, 83cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 84cf2b5f3bSDag-Erling Smørgrav &method_gssapi, 85cf2b5f3bSDag-Erling Smørgrav #endif 86cce7d346SDag-Erling Smørgrav #ifdef JPAKE 87cce7d346SDag-Erling Smørgrav &method_jpake, 88cce7d346SDag-Erling Smørgrav #endif 8980628bacSDag-Erling Smørgrav &method_passwd, 9080628bacSDag-Erling Smørgrav &method_kbdint, 9180628bacSDag-Erling Smørgrav &method_hostbased, 9280628bacSDag-Erling Smørgrav NULL 9309958426SBrian Feldman }; 9409958426SBrian Feldman 95a04a10f8SKris Kennaway /* protocol */ 96a04a10f8SKris Kennaway 97af12a3e7SDag-Erling Smørgrav static void input_service_request(int, u_int32_t, void *); 98af12a3e7SDag-Erling Smørgrav static void input_userauth_request(int, u_int32_t, void *); 99a04a10f8SKris Kennaway 100a04a10f8SKris Kennaway /* helper */ 101af12a3e7SDag-Erling Smørgrav static Authmethod *authmethod_lookup(const char *); 102af12a3e7SDag-Erling Smørgrav static char *authmethods_get(void); 103d4af9e69SDag-Erling Smørgrav 104d4af9e69SDag-Erling Smørgrav char * 105d4af9e69SDag-Erling Smørgrav auth2_read_banner(void) 106d4af9e69SDag-Erling Smørgrav { 107d4af9e69SDag-Erling Smørgrav struct stat st; 108d4af9e69SDag-Erling Smørgrav char *banner = NULL; 109d4af9e69SDag-Erling Smørgrav size_t len, n; 110d4af9e69SDag-Erling Smørgrav int fd; 111d4af9e69SDag-Erling Smørgrav 112d4af9e69SDag-Erling Smørgrav if ((fd = open(options.banner, O_RDONLY)) == -1) 113d4af9e69SDag-Erling Smørgrav return (NULL); 114d4af9e69SDag-Erling Smørgrav if (fstat(fd, &st) == -1) { 115d4af9e69SDag-Erling Smørgrav close(fd); 116d4af9e69SDag-Erling Smørgrav return (NULL); 117d4af9e69SDag-Erling Smørgrav } 118*462c32cbSDag-Erling Smørgrav if (st.st_size <= 0 || st.st_size > 1*1024*1024) { 119d4af9e69SDag-Erling Smørgrav close(fd); 120d4af9e69SDag-Erling Smørgrav return (NULL); 121d4af9e69SDag-Erling Smørgrav } 122d4af9e69SDag-Erling Smørgrav 123d4af9e69SDag-Erling Smørgrav len = (size_t)st.st_size; /* truncate */ 124d4af9e69SDag-Erling Smørgrav banner = xmalloc(len + 1); 125d4af9e69SDag-Erling Smørgrav n = atomicio(read, fd, banner, len); 126d4af9e69SDag-Erling Smørgrav close(fd); 127d4af9e69SDag-Erling Smørgrav 128d4af9e69SDag-Erling Smørgrav if (n != len) { 129d4af9e69SDag-Erling Smørgrav xfree(banner); 130d4af9e69SDag-Erling Smørgrav return (NULL); 131d4af9e69SDag-Erling Smørgrav } 132d4af9e69SDag-Erling Smørgrav banner[n] = '\0'; 133d4af9e69SDag-Erling Smørgrav 134d4af9e69SDag-Erling Smørgrav return (banner); 135d4af9e69SDag-Erling Smørgrav } 136d4af9e69SDag-Erling Smørgrav 137d4af9e69SDag-Erling Smørgrav void 138d4af9e69SDag-Erling Smørgrav userauth_send_banner(const char *msg) 139d4af9e69SDag-Erling Smørgrav { 140d4af9e69SDag-Erling Smørgrav if (datafellows & SSH_BUG_BANNER) 141d4af9e69SDag-Erling Smørgrav return; 142d4af9e69SDag-Erling Smørgrav 143d4af9e69SDag-Erling Smørgrav packet_start(SSH2_MSG_USERAUTH_BANNER); 144d4af9e69SDag-Erling Smørgrav packet_put_cstring(msg); 145d4af9e69SDag-Erling Smørgrav packet_put_cstring(""); /* language, unused */ 146d4af9e69SDag-Erling Smørgrav packet_send(); 147d4af9e69SDag-Erling Smørgrav debug("%s: sent", __func__); 148d4af9e69SDag-Erling Smørgrav } 149d4af9e69SDag-Erling Smørgrav 150d4af9e69SDag-Erling Smørgrav static void 151d4af9e69SDag-Erling Smørgrav userauth_banner(void) 152d4af9e69SDag-Erling Smørgrav { 153d4af9e69SDag-Erling Smørgrav char *banner = NULL; 154d4af9e69SDag-Erling Smørgrav 155d4af9e69SDag-Erling Smørgrav if (options.banner == NULL || 156d4af9e69SDag-Erling Smørgrav strcasecmp(options.banner, "none") == 0 || 157d4af9e69SDag-Erling Smørgrav (datafellows & SSH_BUG_BANNER) != 0) 158d4af9e69SDag-Erling Smørgrav return; 159d4af9e69SDag-Erling Smørgrav 160d4af9e69SDag-Erling Smørgrav if ((banner = PRIVSEP(auth2_read_banner())) == NULL) 161d4af9e69SDag-Erling Smørgrav goto done; 162d4af9e69SDag-Erling Smørgrav userauth_send_banner(banner); 163d4af9e69SDag-Erling Smørgrav 164d4af9e69SDag-Erling Smørgrav done: 165d4af9e69SDag-Erling Smørgrav if (banner) 166d4af9e69SDag-Erling Smørgrav xfree(banner); 167d4af9e69SDag-Erling Smørgrav } 168a04a10f8SKris Kennaway 169a04a10f8SKris Kennaway /* 17009958426SBrian Feldman * loop until authctxt->success == TRUE 171a04a10f8SKris Kennaway */ 1721ec0d754SDag-Erling Smørgrav void 1731ec0d754SDag-Erling Smørgrav do_authentication2(Authctxt *authctxt) 174a04a10f8SKris Kennaway { 175af12a3e7SDag-Erling Smørgrav dispatch_init(&dispatch_protocol_error); 176a04a10f8SKris Kennaway dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 17709958426SBrian Feldman dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 178a04a10f8SKris Kennaway } 179a04a10f8SKris Kennaway 180333ee039SDag-Erling Smørgrav /*ARGSUSED*/ 181af12a3e7SDag-Erling Smørgrav static void 182af12a3e7SDag-Erling Smørgrav input_service_request(int type, u_int32_t seq, void *ctxt) 183a04a10f8SKris Kennaway { 18409958426SBrian Feldman Authctxt *authctxt = ctxt; 185ca3176e7SBrian Feldman u_int len; 186f388f5efSDag-Erling Smørgrav int acceptit = 0; 1874a421b63SDag-Erling Smørgrav char *service = packet_get_cstring(&len); 188af12a3e7SDag-Erling Smørgrav packet_check_eom(); 189a04a10f8SKris Kennaway 19009958426SBrian Feldman if (authctxt == NULL) 19109958426SBrian Feldman fatal("input_service_request: no authctxt"); 19209958426SBrian Feldman 193a04a10f8SKris Kennaway if (strcmp(service, "ssh-userauth") == 0) { 19409958426SBrian Feldman if (!authctxt->success) { 195f388f5efSDag-Erling Smørgrav acceptit = 1; 196a04a10f8SKris Kennaway /* now we can handle user-auth requests */ 197a04a10f8SKris Kennaway dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); 198a04a10f8SKris Kennaway } 199a04a10f8SKris Kennaway } 200a04a10f8SKris Kennaway /* XXX all other service requests are denied */ 201a04a10f8SKris Kennaway 202f388f5efSDag-Erling Smørgrav if (acceptit) { 203a04a10f8SKris Kennaway packet_start(SSH2_MSG_SERVICE_ACCEPT); 204a04a10f8SKris Kennaway packet_put_cstring(service); 205a04a10f8SKris Kennaway packet_send(); 206a04a10f8SKris Kennaway packet_write_wait(); 207a04a10f8SKris Kennaway } else { 208a04a10f8SKris Kennaway debug("bad service request %s", service); 209a04a10f8SKris Kennaway packet_disconnect("bad service request %s", service); 210a04a10f8SKris Kennaway } 211a04a10f8SKris Kennaway xfree(service); 212a04a10f8SKris Kennaway } 213a04a10f8SKris Kennaway 214333ee039SDag-Erling Smørgrav /*ARGSUSED*/ 215af12a3e7SDag-Erling Smørgrav static void 216af12a3e7SDag-Erling Smørgrav input_userauth_request(int type, u_int32_t seq, void *ctxt) 217a04a10f8SKris Kennaway { 21809958426SBrian Feldman Authctxt *authctxt = ctxt; 21909958426SBrian Feldman Authmethod *m = NULL; 220ca3176e7SBrian Feldman char *user, *service, *method, *style = NULL; 221a04a10f8SKris Kennaway int authenticated = 0; 2225b400a39SDag-Erling Smørgrav #ifdef HAVE_LOGIN_CAP 2235b400a39SDag-Erling Smørgrav login_cap_t *lc; 2245b400a39SDag-Erling Smørgrav const char *from_host, *from_ip; 2255b400a39SDag-Erling Smørgrav 226cf2b5f3bSDag-Erling Smørgrav from_host = get_canonical_hostname(options.use_dns); 2275b400a39SDag-Erling Smørgrav from_ip = get_remote_ipaddr(); 2285b400a39SDag-Erling Smørgrav #endif 229a04a10f8SKris Kennaway 23009958426SBrian Feldman if (authctxt == NULL) 23109958426SBrian Feldman fatal("input_userauth_request: no authctxt"); 232a04a10f8SKris Kennaway 2334a421b63SDag-Erling Smørgrav user = packet_get_cstring(NULL); 2344a421b63SDag-Erling Smørgrav service = packet_get_cstring(NULL); 2354a421b63SDag-Erling Smørgrav method = packet_get_cstring(NULL); 236a04a10f8SKris Kennaway debug("userauth-request for user %s service %s method %s", user, service, method); 237ca3176e7SBrian Feldman debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 238a04a10f8SKris Kennaway 239ca3176e7SBrian Feldman if ((style = strchr(user, ':')) != NULL) 240ca3176e7SBrian Feldman *style++ = 0; 241ca3176e7SBrian Feldman 242ca3176e7SBrian Feldman if (authctxt->attempt++ == 0) { 24309958426SBrian Feldman /* setup auth context */ 24480628bacSDag-Erling Smørgrav authctxt->pw = PRIVSEP(getpwnamallow(user)); 2455962c0e9SDag-Erling Smørgrav authctxt->user = xstrdup(user); 24680628bacSDag-Erling Smørgrav if (authctxt->pw && strcmp(service, "ssh-connection")==0) { 24709958426SBrian Feldman authctxt->valid = 1; 24809958426SBrian Feldman debug2("input_userauth_request: setting up authctxt for %s", user); 24909958426SBrian Feldman } else { 25021e764dfSDag-Erling Smørgrav logit("input_userauth_request: invalid user %s", user); 251cf2b5f3bSDag-Erling Smørgrav authctxt->pw = fakepw(); 252aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 253aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_INVALID_USER)); 254aa49c926SDag-Erling Smørgrav #endif 255a04a10f8SKris Kennaway } 256b74df5b2SDag-Erling Smørgrav #ifdef USE_PAM 257b74df5b2SDag-Erling Smørgrav if (options.use_pam) 258b74df5b2SDag-Erling Smørgrav PRIVSEP(start_pam(authctxt)); 259b74df5b2SDag-Erling Smørgrav #endif 26021e764dfSDag-Erling Smørgrav setproctitle("%s%s", authctxt->valid ? user : "unknown", 26180628bacSDag-Erling Smørgrav use_privsep ? " [net]" : ""); 26209958426SBrian Feldman authctxt->service = xstrdup(service); 263af12a3e7SDag-Erling Smørgrav authctxt->style = style ? xstrdup(style) : NULL; 26480628bacSDag-Erling Smørgrav if (use_privsep) 26580628bacSDag-Erling Smørgrav mm_inform_authserv(service, style); 266d4af9e69SDag-Erling Smørgrav userauth_banner(); 267af12a3e7SDag-Erling Smørgrav } else if (strcmp(user, authctxt->user) != 0 || 26809958426SBrian Feldman strcmp(service, authctxt->service) != 0) { 269af12a3e7SDag-Erling Smørgrav packet_disconnect("Change of username or service not allowed: " 270af12a3e7SDag-Erling Smørgrav "(%s,%s) -> (%s,%s)", 271af12a3e7SDag-Erling Smørgrav authctxt->user, authctxt->service, user, service); 272a04a10f8SKris Kennaway } 2735b400a39SDag-Erling Smørgrav 2745b400a39SDag-Erling Smørgrav #ifdef HAVE_LOGIN_CAP 2755b400a39SDag-Erling Smørgrav if (authctxt->pw != NULL) { 2765b400a39SDag-Erling Smørgrav lc = login_getpwclass(authctxt->pw); 2775b400a39SDag-Erling Smørgrav if (lc == NULL) 2785b400a39SDag-Erling Smørgrav lc = login_getclassbyname(NULL, authctxt->pw); 2795b400a39SDag-Erling Smørgrav if (!auth_hostok(lc, from_host, from_ip)) { 280cf2b5f3bSDag-Erling Smørgrav logit("Denied connection for %.200s from %.200s [%.200s].", 2815b400a39SDag-Erling Smørgrav authctxt->pw->pw_name, from_host, from_ip); 2825b400a39SDag-Erling Smørgrav packet_disconnect("Sorry, you are not allowed to connect."); 2835b400a39SDag-Erling Smørgrav } 2845b400a39SDag-Erling Smørgrav if (!auth_timeok(lc, time(NULL))) { 285cf2b5f3bSDag-Erling Smørgrav logit("LOGIN %.200s REFUSED (TIME) FROM %.200s", 2865b400a39SDag-Erling Smørgrav authctxt->pw->pw_name, from_host); 2875b400a39SDag-Erling Smørgrav packet_disconnect("Logins not available right now."); 2885b400a39SDag-Erling Smørgrav } 2895b400a39SDag-Erling Smørgrav login_close(lc); 2905b400a39SDag-Erling Smørgrav lc = NULL; 2915b400a39SDag-Erling Smørgrav } 2925b400a39SDag-Erling Smørgrav #endif /* HAVE_LOGIN_CAP */ 2935b400a39SDag-Erling Smørgrav 294ca3176e7SBrian Feldman /* reset state */ 295af12a3e7SDag-Erling Smørgrav auth2_challenge_stop(authctxt); 296cce7d346SDag-Erling Smørgrav #ifdef JPAKE 297cce7d346SDag-Erling Smørgrav auth2_jpake_stop(authctxt); 298cce7d346SDag-Erling Smørgrav #endif 299cf2b5f3bSDag-Erling Smørgrav 300cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 301cce7d346SDag-Erling Smørgrav /* XXX move to auth2_gssapi_stop() */ 302cf2b5f3bSDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 303cf2b5f3bSDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 304cf2b5f3bSDag-Erling Smørgrav #endif 305cf2b5f3bSDag-Erling Smørgrav 306ca3176e7SBrian Feldman authctxt->postponed = 0; 307e146993eSDag-Erling Smørgrav authctxt->server_caused_failure = 0; 30803e72be8SBrian Feldman 309ca3176e7SBrian Feldman /* try to authenticate user */ 31009958426SBrian Feldman m = authmethod_lookup(method); 311d4af9e69SDag-Erling Smørgrav if (m != NULL && authctxt->failures < options.max_authtries) { 31209958426SBrian Feldman debug2("input_userauth_request: try method %s", method); 31309958426SBrian Feldman authenticated = m->userauth(authctxt); 31409958426SBrian Feldman } 315ca3176e7SBrian Feldman userauth_finish(authctxt, authenticated, method); 31609958426SBrian Feldman 31709958426SBrian Feldman xfree(service); 31809958426SBrian Feldman xfree(user); 31909958426SBrian Feldman xfree(method); 32009958426SBrian Feldman } 32109958426SBrian Feldman 322ca3176e7SBrian Feldman void 323ca3176e7SBrian Feldman userauth_finish(Authctxt *authctxt, int authenticated, char *method) 324ca3176e7SBrian Feldman { 325af12a3e7SDag-Erling Smørgrav char *methods; 326af12a3e7SDag-Erling Smørgrav 327ca3176e7SBrian Feldman if (!authctxt->valid && authenticated) 328ca3176e7SBrian Feldman fatal("INTERNAL ERROR: authenticated invalid user %s", 329ca3176e7SBrian Feldman authctxt->user); 330ca3176e7SBrian Feldman 331ca3176e7SBrian Feldman /* Special handling for root */ 332e73e9afaSDag-Erling Smørgrav if (authenticated && authctxt->pw->pw_uid == 0 && 333aa49c926SDag-Erling Smørgrav !auth_root_allowed(method)) { 334ca3176e7SBrian Feldman authenticated = 0; 335aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 336aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 337aa49c926SDag-Erling Smørgrav #endif 338aa49c926SDag-Erling Smørgrav } 339ca3176e7SBrian Feldman 340989dd127SDag-Erling Smørgrav #ifdef USE_PAM 341aa49c926SDag-Erling Smørgrav if (options.use_pam && authenticated) { 342aa49c926SDag-Erling Smørgrav if (!PRIVSEP(do_pam_account())) { 343aa49c926SDag-Erling Smørgrav /* if PAM returned a message, send it to the user */ 344aa49c926SDag-Erling Smørgrav if (buffer_len(&loginmsg) > 0) { 345aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, "\0", 1); 346aa49c926SDag-Erling Smørgrav userauth_send_banner(buffer_ptr(&loginmsg)); 347aa49c926SDag-Erling Smørgrav packet_write_wait(); 348aa49c926SDag-Erling Smørgrav } 349aa49c926SDag-Erling Smørgrav fatal("Access denied for user %s by PAM account " 350aa49c926SDag-Erling Smørgrav "configuration", authctxt->user); 351aa49c926SDag-Erling Smørgrav } 352aa49c926SDag-Erling Smørgrav } 353cf2b5f3bSDag-Erling Smørgrav #endif 354989dd127SDag-Erling Smørgrav 355f388f5efSDag-Erling Smørgrav #ifdef _UNICOS 356f388f5efSDag-Erling Smørgrav if (authenticated && cray_access_denied(authctxt->user)) { 357f388f5efSDag-Erling Smørgrav authenticated = 0; 358f388f5efSDag-Erling Smørgrav fatal("Access denied for user %s.",authctxt->user); 359f388f5efSDag-Erling Smørgrav } 360f388f5efSDag-Erling Smørgrav #endif /* _UNICOS */ 361f388f5efSDag-Erling Smørgrav 362ca3176e7SBrian Feldman /* Log before sending the reply */ 363ca3176e7SBrian Feldman auth_log(authctxt, authenticated, method, " ssh2"); 364ca3176e7SBrian Feldman 365af12a3e7SDag-Erling Smørgrav if (authctxt->postponed) 366af12a3e7SDag-Erling Smørgrav return; 367af12a3e7SDag-Erling Smørgrav 368af12a3e7SDag-Erling Smørgrav /* XXX todo: check if multiple auth methods are needed */ 369af12a3e7SDag-Erling Smørgrav if (authenticated == 1) { 370af12a3e7SDag-Erling Smørgrav /* turn off userauth */ 371af12a3e7SDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); 372af12a3e7SDag-Erling Smørgrav packet_start(SSH2_MSG_USERAUTH_SUCCESS); 373af12a3e7SDag-Erling Smørgrav packet_send(); 374af12a3e7SDag-Erling Smørgrav packet_write_wait(); 375af12a3e7SDag-Erling Smørgrav /* now we can break out */ 376af12a3e7SDag-Erling Smørgrav authctxt->success = 1; 377af12a3e7SDag-Erling Smørgrav } else { 378d4af9e69SDag-Erling Smørgrav 379d4af9e69SDag-Erling Smørgrav /* Allow initial try of "none" auth without failure penalty */ 380e146993eSDag-Erling Smørgrav if (!authctxt->server_caused_failure && 381e146993eSDag-Erling Smørgrav (authctxt->attempt > 1 || strcmp(method, "none") != 0)) 382d4af9e69SDag-Erling Smørgrav authctxt->failures++; 383d4af9e69SDag-Erling Smørgrav if (authctxt->failures >= options.max_authtries) { 384aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 385aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 386aa49c926SDag-Erling Smørgrav #endif 387af12a3e7SDag-Erling Smørgrav packet_disconnect(AUTH_FAIL_MSG, authctxt->user); 388aa49c926SDag-Erling Smørgrav } 389af12a3e7SDag-Erling Smørgrav methods = authmethods_get(); 390af12a3e7SDag-Erling Smørgrav packet_start(SSH2_MSG_USERAUTH_FAILURE); 391af12a3e7SDag-Erling Smørgrav packet_put_cstring(methods); 392af12a3e7SDag-Erling Smørgrav packet_put_char(0); /* XXX partial success, unused */ 393af12a3e7SDag-Erling Smørgrav packet_send(); 394af12a3e7SDag-Erling Smørgrav packet_write_wait(); 395af12a3e7SDag-Erling Smørgrav xfree(methods); 396af12a3e7SDag-Erling Smørgrav } 397ca3176e7SBrian Feldman } 39809958426SBrian Feldman 399af12a3e7SDag-Erling Smørgrav static char * 40009958426SBrian Feldman authmethods_get(void) 401a04a10f8SKris Kennaway { 402af12a3e7SDag-Erling Smørgrav Buffer b; 40309958426SBrian Feldman char *list; 40480628bacSDag-Erling Smørgrav int i; 405a04a10f8SKris Kennaway 406af12a3e7SDag-Erling Smørgrav buffer_init(&b); 40780628bacSDag-Erling Smørgrav for (i = 0; authmethods[i] != NULL; i++) { 40880628bacSDag-Erling Smørgrav if (strcmp(authmethods[i]->name, "none") == 0) 40909958426SBrian Feldman continue; 41080628bacSDag-Erling Smørgrav if (authmethods[i]->enabled != NULL && 41180628bacSDag-Erling Smørgrav *(authmethods[i]->enabled) != 0) { 412af12a3e7SDag-Erling Smørgrav if (buffer_len(&b) > 0) 413af12a3e7SDag-Erling Smørgrav buffer_append(&b, ",", 1); 41480628bacSDag-Erling Smørgrav buffer_append(&b, authmethods[i]->name, 41580628bacSDag-Erling Smørgrav strlen(authmethods[i]->name)); 41609958426SBrian Feldman } 41709958426SBrian Feldman } 418af12a3e7SDag-Erling Smørgrav buffer_append(&b, "\0", 1); 419af12a3e7SDag-Erling Smørgrav list = xstrdup(buffer_ptr(&b)); 420af12a3e7SDag-Erling Smørgrav buffer_free(&b); 42109958426SBrian Feldman return list; 42209958426SBrian Feldman } 42309958426SBrian Feldman 424af12a3e7SDag-Erling Smørgrav static Authmethod * 42509958426SBrian Feldman authmethod_lookup(const char *name) 42609958426SBrian Feldman { 42780628bacSDag-Erling Smørgrav int i; 42880628bacSDag-Erling Smørgrav 42909958426SBrian Feldman if (name != NULL) 43080628bacSDag-Erling Smørgrav for (i = 0; authmethods[i] != NULL; i++) 43180628bacSDag-Erling Smørgrav if (authmethods[i]->enabled != NULL && 43280628bacSDag-Erling Smørgrav *(authmethods[i]->enabled) != 0 && 43380628bacSDag-Erling Smørgrav strcmp(name, authmethods[i]->name) == 0) 43480628bacSDag-Erling Smørgrav return authmethods[i]; 43580628bacSDag-Erling Smørgrav debug2("Unrecognized authentication method name: %s", 43680628bacSDag-Erling Smørgrav name ? name : "NULL"); 437a04a10f8SKris Kennaway return NULL; 438a04a10f8SKris Kennaway } 439d4af9e69SDag-Erling Smørgrav 440