Пример #1
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 */

	/* 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);
}
Пример #2
0
/* 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");
}
Пример #3
0
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);
}
Пример #4
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);
}
Пример #6
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);
}
Пример #7
0
/*
 * 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);
}
Пример #8
0
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);
}
Пример #9
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;
}