示例#1
0
/*ARGSUSED*/
static int
input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
{
	Authctxt *authctxt = ssh->authctxt;
	Authmethod *m = NULL;
	char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
	int r, authenticated = 0;

	if (authctxt == NULL)
		fatal("input_userauth_request: no authctxt");

	if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 ||
	    (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
	    (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
		goto out;
	debug("userauth-request for user %s service %s method %s", user, service, method);
	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);

	if ((style = strchr(user, ':')) != NULL)
		*style++ = 0;

	if (authctxt->attempt++ == 0) {
		/* setup auth context */
		authctxt->pw = PRIVSEP(getpwnamallow(user));
		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
			authctxt->valid = 1;
			debug2("input_userauth_request: setting up authctxt for %s", user);
		} else {
			logit("input_userauth_request: invalid user %s", user);
			authctxt->pw = fakepw();
		}
		setproctitle("%s%s", authctxt->valid ? user : "******",
		    use_privsep ? " [net]" : "");
		authctxt->user = xstrdup(user);
		authctxt->service = xstrdup(service);
		authctxt->style = style ? xstrdup(style) : NULL;
		if (use_privsep)
			mm_inform_authserv(service, style);
		userauth_banner(ssh);
		if (auth2_setup_methods_lists(authctxt) != 0)
			ssh_packet_disconnect(ssh,
			    "no authentication methods enabled");
	} else if (strcmp(user, authctxt->user) != 0 ||
	    strcmp(service, authctxt->service) != 0) {
		ssh_packet_disconnect(ssh, "Change of username or service not allowed: "
		    "(%s,%s) -> (%s,%s)",
		    authctxt->user, authctxt->service, user, service);
	}
	/* reset state */
	auth2_challenge_stop(ssh);
#ifdef JPAKE
	auth2_jpake_stop(ssh);
#endif

#ifdef GSSAPI
	/* XXX move to auth2_gssapi_stop() */
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
#endif

	authctxt->postponed = 0;
	authctxt->server_caused_failure = 0;

	/* try to authenticate user */
	m = authmethod_lookup(authctxt, method);
	if (m != NULL && authctxt->failures < options.max_authtries) {
		debug2("input_userauth_request: try method %s", method);
		authenticated =	m->userauth(ssh);
	}
	userauth_finish(ssh, authenticated, method, NULL);
	r = 0;
 out:
	xfree(service);
	xfree(user);
	xfree(method);
	return r;
}
示例#2
0
/*ARGSUSED*/
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Authmethod *m = NULL;
	char *user, *service, *method, *style = NULL;
	int authenticated = 0;

	if (authctxt == NULL)
		fatal("input_userauth_request: no authctxt");

	user = packet_get_cstring(NULL);
	service = packet_get_cstring(NULL);
	method = packet_get_cstring(NULL);
	debug("userauth-request for user %s service %s method %s", user, service, method);
	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);

	if ((style = strchr(user, ':')) != NULL)
		*style++ = 0;

	if (authctxt->attempt++ == 0) {
		/* setup auth context */
		authctxt->pw = PRIVSEP(getpwnamallow(user));
		authctxt->user = xstrdup(user);
		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
			authctxt->valid = 1;
			debug2("input_userauth_request: setting up authctxt for %s", user);
		} else {
			logit("input_userauth_request: invalid user %s", user);
			authctxt->pw = fakepw();
#ifdef SSH_AUDIT_EVENTS
			PRIVSEP(audit_event(SSH_INVALID_USER));
#endif
		}
#ifdef USE_PAM
		if (options.use_pam)
			PRIVSEP(start_pam(authctxt));
#endif
		setproctitle("%s%s", authctxt->valid ? user : "******",
		    use_privsep ? " [net]" : "");
		authctxt->service = xstrdup(service);
		authctxt->style = style ? xstrdup(style) : NULL;
		if (use_privsep)
			mm_inform_authserv(service, style);
		userauth_banner();
	} else if (strcmp(user, authctxt->user) != 0 ||
	    strcmp(service, authctxt->service) != 0) {
		packet_disconnect("Change of username or service not allowed: "
		    "(%s,%s) -> (%s,%s)",
		    authctxt->user, authctxt->service, user, service);
	}
	/* reset state */
	auth2_challenge_stop(authctxt);
#ifdef JPAKE
	auth2_jpake_stop(authctxt);
#endif

#ifdef GSSAPI
	/* XXX move to auth2_gssapi_stop() */
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
#endif

	authctxt->postponed = 0;
	authctxt->server_caused_failure = 0;

	/* try to authenticate user */
	m = authmethod_lookup(method);
	if (m != NULL && authctxt->failures < options.max_authtries) {
		debug2("input_userauth_request: try method %s", method);
		authenticated =	m->userauth(authctxt);
	}
	userauth_finish(authctxt, authenticated, method);

	xfree(service);
	xfree(user);
	xfree(method);
}
示例#3
0
static void
input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	KbdintAuthctxt *kbdintctxt;
	int authenticated = 0, res, len;
	u_int i, nresp;
	char **response = NULL, *method;

	if (authctxt == NULL)
		fatal("input_userauth_info_response: no authctxt");
	kbdintctxt = authctxt->kbdintctxt;
	if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
		fatal("input_userauth_info_response: no kbdintctxt");
	if (kbdintctxt->device == NULL)
		fatal("input_userauth_info_response: no device");

	authctxt->postponed = 0;	/* reset */
	nresp = packet_get_int();
	if (nresp != kbdintctxt->nreq)
		fatal("input_userauth_info_response: wrong number of replies");
	if (nresp > 100)
		fatal("input_userauth_info_response: too many replies");
	if (nresp > 0) {
		response = xcalloc(nresp, sizeof(char *));
		for (i = 0; i < nresp; i++)
			response[i] = packet_get_string(NULL);
	}
	packet_check_eom();

	res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);

	for (i = 0; i < nresp; i++) {
		memset(response[i], 'r', strlen(response[i]));
		xfree(response[i]);
	}
	if (response)
		xfree(response);

	switch (res) {
	case 0:
		/* Success! */
		authenticated = authctxt->valid ? 1 : 0;
		break;
	case 1:
		/* Authentication needs further interaction */
		if (send_userauth_info_request(authctxt) == 1)
			authctxt->postponed = 1;
		break;
	default:
		/* Failure! */
		break;
	}

	len = strlen("keyboard-interactive") + 2 +
		strlen(kbdintctxt->device->name);
	method = xmalloc(len);
	snprintf(method, len, "keyboard-interactive/%s",
	    kbdintctxt->device->name);

	if (!authctxt->postponed) {
		if (authenticated) {
			auth2_challenge_stop(authctxt);
		} else {
			/* start next device */
			/* may set authctxt->postponed */
			auth2_challenge_start(authctxt);
		}
	}
	userauth_finish(authctxt, authenticated, method);
	xfree(method);
}
示例#4
0
/*ARGSUSED*/
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Authmethod *m = NULL;
	char *user, *service, *method, *style = NULL;
	int authenticated = 0;
#ifdef HAVE_LOGIN_CAP
	login_cap_t *lc;
	const char *from_host, *from_ip;

        from_host = get_canonical_hostname(options.use_dns);
        from_ip = get_remote_ipaddr();
#endif

	if (authctxt == NULL)
		fatal("input_userauth_request: no authctxt");

	user = packet_get_cstring(NULL);
	service = packet_get_cstring(NULL);
	method = packet_get_cstring(NULL);
	debug("userauth-request for user %s service %s method %s", user, service, method);
	if (!log_flag) {
		logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s",
		      get_remote_ipaddr(), get_remote_port(), user);
		log_flag = 1;
	}
	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);

	if ((style = strchr(user, ':')) != NULL)
		*style++ = 0;

	if (authctxt->attempt++ == 0) {
		/* setup auth context */
		authctxt->pw = PRIVSEP(getpwnamallow(user));
		authctxt->user = xstrdup(user);
		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
			authctxt->valid = 1;
			debug2("input_userauth_request: setting up authctxt for %s", user);
		} else {
			logit("input_userauth_request: invalid user %s", user);
			authctxt->pw = fakepw();
#ifdef SSH_AUDIT_EVENTS
			PRIVSEP(audit_event(SSH_INVALID_USER));
#endif
		}
#ifdef USE_PAM
		if (options.use_pam)
			PRIVSEP(start_pam(authctxt));
#endif
		setproctitle("%s%s", authctxt->valid ? user : "******",
		    use_privsep ? " [net]" : "");
		authctxt->service = xstrdup(service);
		authctxt->style = style ? xstrdup(style) : NULL;
		if (use_privsep)
			mm_inform_authserv(service, style);
		userauth_banner();
		if (auth2_setup_methods_lists(authctxt) != 0)
			packet_disconnect("no authentication methods enabled");
	} else if (strcmp(user, authctxt->user) != 0 ||
	    strcmp(service, authctxt->service) != 0) {
		packet_disconnect("Change of username or service not allowed: "
		    "(%s,%s) -> (%s,%s)",
		    authctxt->user, authctxt->service, user, service);
	}

#ifdef HAVE_LOGIN_CAP
        if (authctxt->pw != NULL) {
                lc = login_getpwclass(authctxt->pw);
                if (lc == NULL)
                        lc = login_getclassbyname(NULL, authctxt->pw);
                if (!auth_hostok(lc, from_host, from_ip)) {
                        logit("Denied connection for %.200s from %.200s [%.200s].",
                            authctxt->pw->pw_name, from_host, from_ip);
                        packet_disconnect("Sorry, you are not allowed to connect.");
                }
                if (!auth_timeok(lc, time(NULL))) {
                        logit("LOGIN %.200s REFUSED (TIME) FROM %.200s",
                            authctxt->pw->pw_name, from_host);
                        packet_disconnect("Logins not available right now.");
                }
                login_close(lc);
                lc = NULL;
        }
#endif  /* HAVE_LOGIN_CAP */

	/* reset state */
	auth2_challenge_stop(authctxt);

#ifdef GSSAPI
	/* XXX move to auth2_gssapi_stop() */
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
#endif

	authctxt->postponed = 0;
	authctxt->server_caused_failure = 0;

	/* try to authenticate user */
	m = authmethod_lookup(authctxt, method);
	if (m != NULL && authctxt->failures < options.max_authtries) {
		debug2("input_userauth_request: try method %s", method);
		authenticated =	m->userauth(authctxt);
	}
	userauth_finish(authctxt, authenticated, method, NULL);

	free(service);
	free(user);
	free(method);
}