Authctxt * do_authentication2(void) { Authctxt *authctxt = authctxt_new(); x_authctxt = authctxt; /*XXX*/ #ifdef HAVE_BSM fatal_add_cleanup(audit_failed_login_cleanup, authctxt); #endif /* HAVE_BSM */ /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; if (options.pam_authentication_via_kbd_int) options.kbd_interactive_authentication = 1; if (use_privsep) options.pam_authentication_via_kbd_int = 0; dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); return (authctxt); }
/* As user */ void ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { (*gssapi_client.mech->storecreds)(&gssapi_client); if (options.gss_cleanup_creds) fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); }
static int krb4_init(void *context) { static int cleanup_registered = 0; Authctxt *authctxt = (Authctxt *)context; const char *tkt_root = TKT_ROOT; struct stat st; int fd; if (!authctxt->krb4_ticket_file) { /* Set unique ticket string manually since we're still root. */ authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN); #ifdef AFS if (lstat("/ticket", &st) != -1) tkt_root = "/ticket/"; #endif /* AFS */ snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld", tkt_root, authctxt->pw->pw_uid, (long)getpid()); krb_set_tkt_string(authctxt->krb4_ticket_file); } /* Register ticket cleanup in case of fatal error. */ if (!cleanup_registered) { fatal_add_cleanup(krb4_cleanup_proc, authctxt); cleanup_registered = 1; } /* Try to create our ticket file. */ if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) { close(fd); return (1); } /* Ticket file exists - make sure user owns it (just passed ticket). */ if (lstat(authctxt->krb4_ticket_file, &st) != -1) { if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && st.st_uid == authctxt->pw->pw_uid) return (1); } /* Failure - cancel cleanup function, leaving ticket for inspection. */ log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file); fatal_remove_cleanup(krb4_cleanup_proc, authctxt); cleanup_registered = 0; xfree(authctxt->krb4_ticket_file); authctxt->krb4_ticket_file = NULL; return (0); }
Authctxt * do_authentication2(void) { Authctxt *authctxt = authctxt_new(); x_authctxt = authctxt; /*XXX*/ #ifdef HAVE_BSM fatal_add_cleanup(audit_failed_login_cleanup, authctxt); #endif /* HAVE_BSM */ dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); return (authctxt); }
static int krb5_init(void *context) { Authctxt *authctxt = (Authctxt *)context; krb5_error_code problem; static int cleanup_registered = 0; if (authctxt->krb5_ctx == NULL) { problem = krb5_init_context(&authctxt->krb5_ctx); if (problem) return (problem); krb5_init_ets(authctxt->krb5_ctx); } if (!cleanup_registered) { fatal_add_cleanup(krb5_cleanup_proc, authctxt); cleanup_registered = 1; } return (0); }
static void * pam_init_ctx(Authctxt *authctxt) { struct pam_ctxt *ctxt; int socks[2]; int i; ctxt = xmalloc(sizeof *ctxt); ctxt->pam_user = xstrdup(authctxt->user); ctxt->pam_done = 0; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { error("%s: failed create sockets: %s", __func__, strerror(errno)); xfree(ctxt); return (NULL); } if ((ctxt->pam_pid = fork()) == -1) { error("%s: failed to fork auth-pam child: %s", __func__, strerror(errno)); close(socks[0]); close(socks[1]); xfree(ctxt); return (NULL); } if (ctxt->pam_pid == 0) { /* close everything except our end of the pipe */ ctxt->pam_sock = socks[1]; for (i = 3; i < getdtablesize(); ++i) if (i != ctxt->pam_sock) close(i); pam_child(ctxt); /* not reached */ exit(1); } ctxt->pam_sock = socks[0]; close(socks[1]); fatal_add_cleanup(pam_cleanup, ctxt); return (ctxt); }
/* * Performs authentication of an incoming connection. Session key has already * been exchanged and encryption is enabled. */ Authctxt * do_authentication(void) { Authctxt *authctxt; u_int ulen; char *user, *style = NULL; /* Get the name of the user that we wish to log in as. */ packet_read_expect(SSH_CMSG_USER); /* Get the user name. */ user = packet_get_string(&ulen); packet_check_eom(); if ((style = strchr(user, ':')) != NULL) *style++ = '\0'; #ifdef KRB5 /* XXX - SSH.com Kerberos v5 braindeath. */ if ((datafellows & SSH_BUG_K5USER) && options.kerberos_authentication) { char *p; if ((p = strchr(user, '@')) != NULL) *p = '\0'; } #endif authctxt = authctxt_new(); authctxt->user = user; authctxt->style = style; #ifdef HAVE_BSM fatal_add_cleanup(audit_failed_login_cleanup, authctxt); #endif /* HAVE_BSM */ /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) { authctxt->valid = 1; } else { authctxt->valid = 0; debug("do_authentication: illegal user %s", user); } setproctitle("%s%s", authctxt->pw ? user : "******", use_privsep ? " [net]" : ""); #if 0 #ifdef USE_PAM PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user)); #endif #endif /* * If we are not running as root, the user must have the same uid as * the server. (Unless you are running Windows) */ #ifndef HAVE_CYGWIN if (!use_privsep && getuid() != 0 && authctxt->pw && authctxt->pw->pw_uid != getuid()) packet_disconnect("Cannot change user when server not running as root."); #endif /* * Loop until the user has been authenticated or the connection is * closed, do_authloop() returns only if authentication is successful */ do_authloop(authctxt); /* The user has been authenticated and accepted. */ packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); return (authctxt); }
int mm_answer_pty(int socket, Buffer *m) { extern struct monitor *pmonitor; Session *s; int res, fd0; debug3("%s entering", __func__); buffer_clear(m); s = session_new(); if (s == NULL) goto error; s->authctxt = authctxt; s->pw = authctxt->pw; s->pid = pmonitor->m_pid; res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; fatal_add_cleanup(session_pty_cleanup2, (void *)s); pty_setowner(authctxt->pw, s->tty); buffer_put_int(m, 1); buffer_put_cstring(m, s->tty); mm_request_send(socket, MONITOR_ANS_PTY, m); mm_send_fd(socket, s->ptyfd); mm_send_fd(socket, s->ttyfd); /* We need to trick ttyslot */ if (dup2(s->ttyfd, 0) == -1) fatal("%s: dup2", __func__); mm_record_login(s, authctxt->pw); /* Now we can close the file descriptor again */ close(0); /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); if (fd0 != 0) error("%s: fd0 %d != 0", __func__, fd0); /* slave is not needed */ close(s->ttyfd); s->ttyfd = s->ptyfd; /* no need to dup() because nobody closes ptyfd */ s->ptymaster = s->ptyfd; debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); return (0); error: if (s != NULL) mm_session_close(s); buffer_put_int(m, 0); mm_request_send(socket, MONITOR_ANS_PTY, m); return (0); }
void new_start_pam(Authctxt *authctxt, struct pam_conv *conv) { int retval; pam_handle_t *pamh; const char *rhost, *svc; char *user = NULL; pam_stuff *pam; if (authctxt == NULL) fatal("Internal error during userauth"); if (compat20 && authctxt->method == NULL) fatal("Userauth method unknown while starting PAM"); /* PAM service selected here */ svc = derive_pam_svc_name(authctxt->method); debug2("Starting PAM service %s for method %s", svc, get_method_name(authctxt)); if (authctxt->user != NULL) user = authctxt->user; /* Cleanup previous PAM state */ if (authctxt->pam != NULL) { fatal_remove_cleanup(&do_pam_cleanup_proc, authctxt->pam); do_pam_cleanup_proc(authctxt->pam); } pam = xmalloc(sizeof(pam_stuff)); (void) memset(pam, 0, sizeof(pam_stuff)); /* * pam->last_pam_retval has to be and is considered * along with pam->state. * * pam->state = 0; -> no PAM auth, account, etc, work * done yet. (Set by memset() above.) * * pam->last_pam_retval = PAM_SUCCESS; -> meaningless at * this point. * * See finish_userauth_do_pam() below. */ pam->authctxt = authctxt; pam->last_pam_retval = PAM_SUCCESS; authctxt->pam = pam; /* Free any previously stored text/error PAM prompts */ if (__pam_msg) { xfree(__pam_msg); __pam_msg = NULL; } if ((retval = pam_start(svc, user, conv, &pamh)) != PAM_SUCCESS) { fatal("PAM initialization failed during %s userauth", get_method_name(authctxt)); } fatal_add_cleanup((void (*)(void *)) &do_pam_cleanup_proc, (void *) authctxt->pam); rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping); if ((retval = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) { (void) pam_end(pamh, retval); fatal("Could not set PAM_RHOST item during %s userauth", get_method_name(authctxt)); } if ((retval = pam_set_item(pamh, PAM_TTY, "sshd")) != PAM_SUCCESS) { (void) pam_end(pamh, retval); fatal("Could not set PAM_TTY item during %s userauth", get_method_name(authctxt)); } authctxt->pam->h = pamh; }