示例#1
0
void
auth_log(Authctxt *authctxt, int authenticated, int partial,
    const char *method, const char *submethod)
{
	void (*authlog) (const char *fmt,...) = verbose;
	char *authmsg;

	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
		return;

	/* Raise logging level */
	if (authenticated == 1 ||
	    !authctxt->valid ||
	    authctxt->failures >= options.max_authtries / 2 ||
	    strcmp(method, "password") == 0)
		authlog = logit;

	if (authctxt->postponed)
		authmsg = "Postponed";
	else if (partial)
		authmsg = "Partial";
	else {
		authmsg = authenticated ? "Accepted" : "Failed";
		BLACKLIST_NOTIFY(authenticated ?
		    BLACKLIST_AUTH_OK : BLACKLIST_AUTH_FAIL);
	}

	authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s",
	    authmsg,
	    method,
	    submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
	    authctxt->valid ? "" : "invalid user ",
	    authctxt->user,
	    get_remote_ipaddr(),
	    get_remote_port(),
	    compat20 ? "ssh2" : "ssh1",
	    authctxt->info != NULL ? ": " : "",
	    authctxt->info != NULL ? authctxt->info : "");
	free(authctxt->info);
	authctxt->info = NULL;

#ifdef CUSTOM_FAILED_LOGIN
	if (authenticated == 0 && !authctxt->postponed &&
	    (strcmp(method, "password") == 0 ||
	    strncmp(method, "keyboard-interactive", 20) == 0 ||
	    strcmp(method, "challenge-response") == 0))
		record_failed_login(authctxt->user,
		    get_canonical_hostname(options.use_dns), "ssh");
# ifdef WITH_AIXAUTHENTICATE
	if (authenticated)
		sys_auth_record_login(authctxt->user,
		    get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
# endif
#endif
#ifdef SSH_AUDIT_EVENTS
	if (authenticated == 0 && !authctxt->postponed)
		audit_event(audit_classify_auth(method));
#endif
}
示例#2
0
文件: auth.c 项目: OPSF/uClinux
void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
	void (*authlog) (const char *fmt,...) = verbose;
	char *authmsg;

	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
		return;

	/* Raise logging level */
	if (authenticated == 1 ||
	    !authctxt->valid ||
	    authctxt->failures >= options.max_authtries / 2 ||
	    strcmp(method, "password") == 0)
		authlog = logit;

	if (authctxt->postponed)
		authmsg = "Postponed";
	else
		authmsg = authenticated ? "Accepted" : "Failed";

	authlog("%s %s for %s%.100s from %.200s port %d%s",
	    authmsg,
	    method,
	    authctxt->valid ? "" : "invalid user ",
	    authctxt->user,
	    get_remote_ipaddr(),
	    get_remote_port(),
	    info);

#ifdef CUSTOM_FAILED_LOGIN
	if (authenticated == 0 && !authctxt->postponed &&
	    (strcmp(method, "password") == 0 ||
	    strncmp(method, "keyboard-interactive", 20) == 0 ||
	    strcmp(method, "challenge-response") == 0))
		record_failed_login(authctxt->user,
		    get_canonical_hostname(options.use_dns), "ssh");
# ifdef WITH_AIXAUTHENTICATE
	if (authenticated)
		sys_auth_record_login(authctxt->user,
		    get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
# endif
#endif
#ifdef SSH_AUDIT_EVENTS
	if (authenticated == 0 && !authctxt->postponed)
		audit_event(audit_classify_auth(method));
#endif
#ifdef SECURITY_COUNTS
	if (strcmp(method, "password") == 0)
		access__attempted(!authenticated, authctxt->user);
#endif
}
示例#3
0
struct passwd *
getpwnamallow(const char *user)
{
#ifdef HAVE_LOGIN_CAP
	extern login_cap_t *lc;
#ifdef BSD_AUTH
	auth_session_t *as;
#endif
#endif
	struct passwd *pw;

	parse_server_match_config(&options, user,
	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());

	pw = getpwnam(user);
	if (pw == NULL) {
		logit("Invalid user %.100s from %.100s",
		    user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN
		record_failed_login(user,
		    get_canonical_hostname(options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
		audit_event(SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
		return (NULL);
	}
	if (!allowed_user(pw))
		return (NULL);
#ifdef HAVE_LOGIN_CAP
	if ((lc = login_getclass(pw->pw_class)) == NULL) {
		debug("unable to get login class: %s", user);
		return (NULL);
	}
#ifdef BSD_AUTH
	if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
	    auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
		debug("Approval failure for %s", user);
		pw = NULL;
	}
	if (as != NULL)
		auth_close(as);
#endif
#endif
	if (pw != NULL)
		return (pwcopy(pw));
	return (NULL);
}
示例#4
0
void
session_setup_sia(struct passwd *pw, char *tty)
{
	SIAENTITY *ent = NULL;
	const char *host;

	host = get_canonical_hostname(options.use_dns);

	if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name,
	    tty, 0, NULL) != SIASUCCESS)
		fatal("sia_ses_init failed");

	if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) {
		sia_ses_release(&ent);
		fatal("sia_make_entity_pwd failed");
	}

	ent->authtype = SIA_A_NONE;
	if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS)
		fatal("Couldn't establish session for %s from %s",
		    pw->pw_name, host);

	if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS)
		fatal("Couldn't launch session for %s from %s",
		    pw->pw_name, host);

	sia_ses_release(&ent);

	setuid(0);
	permanently_set_uid(pw);
}
示例#5
0
void
session_setup_sia(struct passwd *pw, char *tty)
{
	SIAENTITY *ent = NULL;
	const char *host;

	host = get_canonical_hostname(options.verify_reverse_mapping);

	if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, tty,
	    0, NULL) != SIASUCCESS)
		fatal("sia_ses_init failed");

	if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) {
		sia_ses_release(&ent);
		fatal("sia_make_entity_pwd failed");
	}

	ent->authtype = SIA_A_NONE;
	if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS)
		fatal("Couldn't establish session for %s from %s",
		    pw->pw_name, host);

	if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS)
		fatal("Couldn't launch session for %s from %s", pw->pw_name,
		    host);
	
	sia_ses_release(&ent);

	if (setreuid(geteuid(), geteuid()) < 0)
		fatal("setreuid: %s", strerror(errno));
}
示例#6
0
void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
	void (*authlog) (const char *fmt,...) = verbose;
	char *authmsg;

	/* Raise logging level */
	if (authenticated == 1 ||
	    !authctxt->valid ||
	    authctxt->failures >= AUTH_FAIL_LOG ||
	    strcmp(method, "password") == 0)
		authlog = log;

	if (authctxt->postponed)
		authmsg = "Postponed";
	else
		authmsg = authenticated ? "Accepted" : "Failed";

	authlog("%s %s for %s%.100s from %.200s port %d%s",
	    authmsg,
	    method,
	    authctxt->valid ? "" : "illegal user ",
	    authctxt->user,
	    get_remote_ipaddr(),
	    get_remote_port(),
	    info);

#ifdef WITH_AIXAUTHENTICATE
	if (authenticated == 0 && strcmp(method, "password") == 0)
	    loginfailed(authctxt->user,
		get_canonical_hostname(options.verify_reverse_mapping),
		"ssh");
#endif /* WITH_AIXAUTHENTICATE */

}
示例#7
0
int
auth_sia_password(Authctxt *authctxt, char *pass)
{
	int ret;
	SIAENTITY *ent = NULL;
	const char *host;

	host = get_canonical_hostname(options.verify_reverse_mapping);

	if (!authctxt->user || !pass || pass[0] == '\0')
		return(0);

	if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user,
	    NULL, 0, NULL) != SIASUCCESS)
		return(0);

	if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) {
		error("Couldn't authenticate %s from %s", authctxt->user,
		    host);
		if (ret & SIASTOP)
			sia_ses_release(&ent);
		return(0);
	}

	sia_ses_release(&ent);

	return(1);
}
示例#8
0
int
auth_rhosts(struct passwd *pw, const char *client_user)
{
	const char *hostname, *ipaddr;

	hostname = get_canonical_hostname(options.use_dns);
	ipaddr = get_remote_ipaddr();
	return auth_rhosts2(pw, client_user, hostname, ipaddr);
}
示例#9
0
const char *
get_remote_name_or_ip(u_int utmp_len, int use_dns)
{
	static const char *remote = "";
	if (utmp_len > 0)
		remote = get_canonical_hostname(use_dns);
	if (utmp_len == 0 || strlen(remote) > utmp_len)
		remote = get_remote_ipaddr();
	return remote;
}
示例#10
0
int
auth_rhosts(struct passwd *pw, const char *client_user)
{
	struct ssh *ssh = active_state;	/* XXX */
	const char *hostname, *ipaddr;

	hostname = get_canonical_hostname(options.use_dns);
	ipaddr = ssh_remote_ipaddr(ssh);
	return auth_rhosts2(pw, client_user, hostname, ipaddr);
}
示例#11
0
const char *
get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping)
{
	static const char *remote = "";
	if (utmp_len > 0)
		remote = get_canonical_hostname(verify_reverse_mapping);
	if (utmp_len == 0 || strlen(remote) > utmp_len)
		remote = get_remote_ipaddr();
	return remote;
}
示例#12
0
/*
 * record_failed_login: generic "login failed" interface function
 */
void
record_failed_login(const char *user, const char *ttyname)
{
	char *hostname = get_canonical_hostname(options.use_dns);

	if (geteuid() != 0)
		return;

	aix_setauthdb(user);
#  ifdef AIX_LOGINFAILED_4ARG
	loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH);
#  else
	loginfailed((char *)user, hostname, (char *)ttyname);
#  endif
}
示例#13
0
struct passwd *
getpwnamallow(const char *user)
{
#ifdef HAVE_LOGIN_CAP
	extern login_cap_t *lc;
#ifdef BSD_AUTH
	auth_session_t *as;
#endif
#endif
	struct passwd *pw;

	pw = getpwnam(user);
	if (pw == NULL) {
		debug("Unknown user %.100s from %.100s",
		    user, get_remote_ipaddr());

 /*
  * Note, was ifdef CUSTOM_FAILED_LOGIN, but this is not an error for
  * us, as it may just be a mapped user name.  This is also why the
  * above message is a debug() instead of a logit().
  */
#if 0 && defined(CUSTOM_FAILED_LOGIN)
		record_failed_login(user,
		    get_canonical_hostname(options.use_dns), "ssh");
#endif
		return (NULL);
	}
	if (!allowed_user(pw))
		return (NULL);
#ifdef HAVE_LOGIN_CAP
	if ((lc = login_getclass(pw->pw_class)) == NULL) {
		debug("unable to get login class: %s", user);
		return (NULL);
	}
#ifdef BSD_AUTH
	if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
	    auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
		debug("Approval failure for %s", user);
		pw = NULL;
	}
	if (as != NULL)
		auth_close(as);
#endif
#endif
	if (pw != NULL)
		return (pwcopy(pw));
	return (NULL);
}
/* return 1 if given hostkey is allowed */
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
    Key *key)
{
	const char *resolvedname, *ipaddr, *lookup;
	HostStatus host_status;
	int len;

	resolvedname = get_canonical_hostname(options.use_dns);
	ipaddr = get_remote_ipaddr();

	debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
	    chost, resolvedname, ipaddr);

	if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
		debug2("stripping trailing dot from chost %s", chost);
		chost[len - 1] = '\0';
	}

	if (options.hostbased_uses_name_from_packet_only) {
		if (auth_rhosts2(pw, cuser, chost, chost) == 0)
			return 0;
		lookup = chost;
	} else {
		if (strcasecmp(resolvedname, chost) != 0)
			logit("userauth_hostbased mismatch: "
			    "client sends %s, but we resolve %s to %s",
			    chost, ipaddr, resolvedname);
		if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
			return 0;
		lookup = resolvedname;
	}
	debug2("userauth_hostbased: access allowed by auth_rhosts2");

	host_status = check_key_in_hostfiles(pw, key, lookup,
	    _PATH_SSH_SYSTEM_HOSTFILE,
	    options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);

	/* backward compat if no key has been found. */
	if (host_status == HOST_NEW)
		host_status = check_key_in_hostfiles(pw, key, lookup,
		    _PATH_SSH_SYSTEM_HOSTFILE2,
		    options.ignore_user_known_hosts ? NULL :
		    _PATH_SSH_USER_HOSTFILE2);

	return (host_status == HOST_OK);
}
示例#15
0
void
session_setup_sia(char *user, char *tty)
{
	struct passwd *pw;
	SIAENTITY *ent = NULL;
	const char *host;

	host = get_canonical_hostname (options.verify_reverse_mapping);

	if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, tty, 0,
	    NULL) != SIASUCCESS) {
		fatal("sia_ses_init failed");
	}

	if ((pw = getpwnam(user)) == NULL) {
		sia_ses_release(&ent);
		fatal("getpwnam: no user: %s", user);
	}
	if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) {
		sia_ses_release(&ent);
		fatal("sia_make_entity_pwd failed");
	}

	ent->authtype = SIA_A_NONE;
	if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS) {
		fatal("Couldn't establish session for %s from %s", user,
		    host);
	}

	if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
		sia_ses_release(&ent);
		fatal("setpriority: %s", strerror (errno));
	}

	if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) {
		fatal("Couldn't launch session for %s from %s", user, host);
	}
	
	sia_ses_release(&ent);

	if (setreuid(geteuid(), geteuid()) < 0) {
		fatal("setreuid: %s", strerror(errno));
	}
}
示例#16
0
/*
 * Tries to authenticate the user using the .rhosts file and the host using
 * its host key.  Returns true if authentication succeeds.
 */
int
auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
{
	char *chost;
	struct passwd *pw = authctxt->pw;

	debug("Trying rhosts with RSA host authentication for client user %.100s",
	    cuser);

	if (!authctxt->valid || client_host_key == NULL ||
	    client_host_key->rsa == NULL)
		return 0;

	chost = (char *)get_canonical_hostname(options.use_dns);
	debug("Rhosts RSA authentication: canonical host %.900s", chost);

	if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) {
		debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
		packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
		return 0;
	}
	/* A matching host key was found and is known. */

	/* Perform the challenge-response dialog with the client for the host key. */
	if (!auth_rsa_challenge_dialog(client_host_key)) {
		logit("Client on %.800s failed to respond correctly to host authentication.",
		    chost);
		return 0;
	}
	/*
	 * We have authenticated the user using .rhosts or /etc/hosts.equiv,
	 * and the host using RSA. We accept the authentication.
	 */

	verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
	    pw->pw_name, cuser, chost);
	packet_send_debug("Rhosts with RSA host authentication accepted.");
	return 1;
}
示例#17
0
void
cray_login_failure(char *username, int errcode)
{
	struct udb *ueptr;		/* UDB pointer for username */
	ia_failure_t fsent;		/* ia_failure structure */
	ia_failure_ret_t fret;		/* ia_failure return stuff */
	struct jtab jtab;		/* job table structure */
	int jid = 0;			/* job id */

	if ((jid = getjtab(&jtab)) < 0)
		debug("cray_login_failure(): getjtab error");

	getsysudb();
	if ((ueptr = getudbnam(username)) == UDB_NULL)
		debug("cray_login_failure(): getudbname() returned NULL");
	endudb();

	memset(&fsent, '\0', sizeof(fsent));
	fsent.revision = 0;
	fsent.uname = username;
	fsent.host = (char *)get_canonical_hostname(options.use_dns);
	fsent.ttyn = "sshd";
	fsent.caller = IA_SSHD;
	fsent.flags = IA_INTERACTIVE;
	fsent.ueptr = ueptr;
	fsent.jid = jid;
	fsent.errcode = errcode;
	fsent.pwdp = NULL;
	fsent.exitcode = 0;	/* dont exit in ia_failure() */

	fret.revision = 0;
	fret.normal = 0;

	/*
	 * Call ia_failure because of an login failure.
	 */
	ia_failure(&fsent, &fret);
}
示例#18
0
/*
 * Check if the user is allowed to log in via ssh. If user is listed
 * in DenyUsers or one of user's groups is listed in DenyGroups, false
 * will be returned. If AllowUsers isn't empty and user isn't listed
 * there, or if AllowGroups isn't empty and one of user's groups isn't
 * listed there, false will be returned.
 * If the user's shell is not executable, false will be returned.
 * Otherwise true is returned.
 */
int
allowed_user(struct passwd * pw)
{
	struct stat st;
	const char *hostname = NULL, *ipaddr = NULL;
	char *shell;
	int i;
#ifdef WITH_AIXAUTHENTICATE
	char *loginmsg;
#endif /* WITH_AIXAUTHENTICATE */
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
	!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
	struct spwd *spw;

	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
	if (!pw || !pw->pw_name)
		return 0;

#define	DAY		(24L * 60 * 60) /* 1 day in seconds */
	spw = getspnam(pw->pw_name);
	if (spw != NULL) {
		time_t today = time(NULL) / DAY;
		debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
		    " sp_max %d", (int)today, (int)spw->sp_expire,
		    (int)spw->sp_lstchg, (int)spw->sp_max);

		/*
		 * We assume account and password expiration occurs the
		 * day after the day specified.
		 */
		if (spw->sp_expire != -1 && today > spw->sp_expire) {
			log("Account %.100s has expired", pw->pw_name);
			return 0;
		}

		if (spw->sp_lstchg == 0) {
			log("User %.100s password has expired (root forced)",
			    pw->pw_name);
			return 0;
		}

		if (spw->sp_max != -1 &&
		    today > spw->sp_lstchg + spw->sp_max) {
			log("User %.100s password has expired (password aged)",
			    pw->pw_name);
			return 0;
		}
	}
#else
	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
	if (!pw || !pw->pw_name)
		return 0;
#endif

	/*
	 * Get the shell from the password data.  An empty shell field is
	 * legal, and means /bin/sh.
	 */
	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;

	/* deny if shell does not exists or is not executable */
	if (stat(shell, &st) != 0) {
		log("User %.100s not allowed because shell %.100s does not exist",
		    pw->pw_name, shell);
		return 0;
	}
	if (S_ISREG(st.st_mode) == 0 ||
	    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
		log("User %.100s not allowed because shell %.100s is not executable",
		    pw->pw_name, shell);
		return 0;
	}

	if (options.num_deny_users > 0 || options.num_allow_users > 0) {
		hostname = get_canonical_hostname(options.verify_reverse_mapping);
		ipaddr = get_remote_ipaddr();
	}

	/* Return false if user is listed in DenyUsers */
	if (options.num_deny_users > 0) {
		for (i = 0; i < options.num_deny_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.deny_users[i])) {
				log("User %.100s not allowed because listed in DenyUsers",
				    pw->pw_name);
				return 0;
			}
	}
	/* Return false if AllowUsers isn't empty and user isn't listed there */
	if (options.num_allow_users > 0) {
		for (i = 0; i < options.num_allow_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.allow_users[i]))
				break;
		/* i < options.num_allow_users iff we break for loop */
		if (i >= options.num_allow_users) {
			log("User %.100s not allowed because not listed in AllowUsers",
			    pw->pw_name);
			return 0;
		}
	}
	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
		/* Get the user's group access list (primary and supplementary) */
		if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
			log("User %.100s not allowed because not in any group",
			    pw->pw_name);
			return 0;
		}

		/* Return false if one of user's groups is listed in DenyGroups */
		if (options.num_deny_groups > 0)
			if (ga_match(options.deny_groups,
			    options.num_deny_groups)) {
				ga_free();
				log("User %.100s not allowed because a group is listed in DenyGroups",
				    pw->pw_name);
				return 0;
			}
		/*
		 * Return false if AllowGroups isn't empty and one of user's groups
		 * isn't listed there
		 */
		if (options.num_allow_groups > 0)
			if (!ga_match(options.allow_groups,
			    options.num_allow_groups)) {
				ga_free();
				log("User %.100s not allowed because none of user's groups are listed in AllowGroups",
				    pw->pw_name);
				return 0;
			}
		ga_free();
	}

#ifdef WITH_AIXAUTHENTICATE
	if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
		if (loginmsg && *loginmsg) {
			/* Remove embedded newlines (if any) */
			char *p;
			for (p = loginmsg; *p; p++) {
				if (*p == '\n')
					*p = ' ';
			}
			/* Remove trailing newline */
			*--p = '\0';
			log("Login restricted for %s: %.100s", pw->pw_name, loginmsg);
		}
		return 0;
	}
#endif /* WITH_AIXAUTHENTICATE */

	/* We found no reason not to let this user try to log on... */
	return 1;
}
示例#19
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);
	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);
}
示例#20
0
/*
 * Tries to authenticate the user using password.  Returns true if
 * authentication succeeds.
 */
int
auth_password(Authctxt *authctxt, const char *password)
{
#if defined(USE_PAM)
	if (*password == '\0' && options.permit_empty_passwd == 0)
		return 0;
	return auth_pam_password(authctxt, password);
#elif defined(HAVE_OSF_SIA)
	if (*password == '\0' && options.permit_empty_passwd == 0)
		return 0;
	return auth_sia_password(authctxt, password);
#else
	struct passwd * pw = authctxt->pw;
	char *encrypted_password;
	char *pw_password;
	char *salt;
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
	struct spwd *spw;
#endif
#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
	struct passwd_adjunct *spw;
#endif
#ifdef WITH_AIXAUTHENTICATE
	char *authmsg;
	int authsuccess;
	int reenter = 1;
#endif

	/* deny if no user. */
	if (pw == NULL)
		return 0;
#ifndef HAVE_CYGWIN
       if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
		return 0;
#endif
	if (*password == '\0' && options.permit_empty_passwd == 0)
		return 0;
#ifdef KRB5
	if (options.kerberos_authentication == 1) {
		int ret = auth_krb5_password(authctxt, password);
		if (ret == 1 || ret == 0)
			return ret;
		/* Fall back to ordinary passwd authentication. */
	}
#endif
#ifdef HAVE_CYGWIN
	if (is_winnt) {
		HANDLE hToken = cygwin_logon_user(pw, password);

		if (hToken == INVALID_HANDLE_VALUE)
			return 0;
		cygwin_set_impersonation_token(hToken);
		return 1;
	}
#endif
#ifdef WITH_AIXAUTHENTICATE
	authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);

	if (authsuccess)
	        /* We don't have a pty yet, so just label the line as "ssh" */
	        if (loginsuccess(authctxt->user,
			get_canonical_hostname(options.verify_reverse_mapping),
			"ssh", &aixloginmsg) < 0)
				aixloginmsg = NULL;

	return(authsuccess);
#endif
#ifdef KRB4
	if (options.kerberos_authentication == 1) {
		int ret = auth_krb4_password(authctxt, password);
		if (ret == 1 || ret == 0)
			return ret;
		/* Fall back to ordinary passwd authentication. */
	}
#endif
#ifdef BSD_AUTH
	if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
	    (char *)password) == 0)
		return 0;
	else
		return 1;
#endif
	pw_password = pw->pw_passwd;

	/*
	 * Various interfaces to shadow or protected password data
	 */
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
	spw = getspnam(pw->pw_name);
	if (spw != NULL)
		pw_password = spw->sp_pwdp;
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */

#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
	if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
		pw_password = spw->pwa_passwd;
#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */

	/* Check for users with no password. */
	if ((password[0] == '\0') && (pw_password[0] == '\0'))
		return 1;

	if (pw_password[0] != '\0')
		salt = pw_password;
	else
		salt = "xx";

#ifdef HAVE_MD5_PASSWORDS
	if (is_md5_salt(salt))
		encrypted_password = md5_crypt(password, salt);
	else
		encrypted_password = crypt(password, salt);
#else /* HAVE_MD5_PASSWORDS */
	encrypted_password = crypt(password, salt);
#endif /* HAVE_MD5_PASSWORDS */

	/* Authentication is accepted if the encrypted passwords are identical. */
	return (strcmp(encrypted_password, pw_password) == 0);
#endif /* !USE_PAM && !HAVE_OSF_SIA */
}
示例#21
0
apr_status_t
serf__kerb_init_sec_context(serf__kerb_context_t *ctx,
                            const char *service,
                            const char *hostname,
                            serf__kerb_buffer_t *input_buf,
                            serf__kerb_buffer_t *output_buf,
                            apr_pool_t *scratch_pool,
                            apr_pool_t *result_pool
                            )
{
    SECURITY_STATUS status;
    ULONG actual_attr;
    SecBuffer sspi_in_buffer;
    SecBufferDesc sspi_in_buffer_desc;
    SecBuffer sspi_out_buffer;
    SecBufferDesc sspi_out_buffer_desc;
    char *target_name;
    apr_status_t apr_status;
    const char *canonname;

    apr_status = get_canonical_hostname(&canonname, hostname, scratch_pool);
    if (apr_status) {
        return apr_status;
    }
    target_name = apr_pstrcat(scratch_pool, service, "/", canonname, NULL);

    /* Prepare input buffer description. */
    sspi_in_buffer.BufferType = SECBUFFER_TOKEN;
    sspi_in_buffer.pvBuffer = input_buf->value;
    sspi_in_buffer.cbBuffer = input_buf->length; 

    sspi_in_buffer_desc.cBuffers = 1;
    sspi_in_buffer_desc.pBuffers = &sspi_in_buffer;
    sspi_in_buffer_desc.ulVersion = SECBUFFER_VERSION;

    /* Output buffers. Output buffer will be allocated by system. */
    sspi_out_buffer.BufferType = SECBUFFER_TOKEN;
    sspi_out_buffer.pvBuffer = NULL; 
    sspi_out_buffer.cbBuffer = 0;

    sspi_out_buffer_desc.cBuffers = 1;
    sspi_out_buffer_desc.pBuffers = &sspi_out_buffer;
    sspi_out_buffer_desc.ulVersion = SECBUFFER_VERSION;

    status = InitializeSecurityContext(
        &ctx->sspi_credentials,
        ctx->initalized ? &ctx->sspi_context : NULL,
        target_name,
        ISC_REQ_ALLOCATE_MEMORY
        | ISC_REQ_MUTUAL_AUTH
        | ISC_REQ_CONFIDENTIALITY,
        0,                          /* Reserved1 */
        SECURITY_NETWORK_DREP,
        &sspi_in_buffer_desc,
        0,                          /* Reserved2 */
        &ctx->sspi_context,
        &sspi_out_buffer_desc,
        &actual_attr,
        NULL);

    if (sspi_out_buffer.cbBuffer > 0) {
        apr_pool_cleanup_register(result_pool, sspi_out_buffer.pvBuffer,
                                  cleanup_sec_buffer,
                                  apr_pool_cleanup_null);
    }

    ctx->initalized = TRUE;

    /* Finish authentication if SSPI requires so. */
    if (status == SEC_I_COMPLETE_NEEDED
        || status == SEC_I_COMPLETE_AND_CONTINUE)
    {
        CompleteAuthToken(&ctx->sspi_context, &sspi_out_buffer_desc);
    }

    output_buf->value = sspi_out_buffer.pvBuffer;
    output_buf->length = sspi_out_buffer.cbBuffer;

    switch(status) {
    case SEC_I_COMPLETE_AND_CONTINUE:
    case SEC_I_CONTINUE_NEEDED:
        return APR_EAGAIN;

    case SEC_I_COMPLETE_NEEDED:
    case SEC_E_OK:
        return APR_SUCCESS;

    default:
        return map_sspi_status(status);
    }
}
示例#22
0
/*
 * Check if the user is allowed to log in via ssh. If user is listed
 * in DenyUsers or one of user's groups is listed in DenyGroups, false
 * will be returned. If AllowUsers isn't empty and user isn't listed
 * there, or if AllowGroups isn't empty and one of user's groups isn't
 * listed there, false will be returned.
 * If the user's shell is not executable, false will be returned.
 * Otherwise true is returned.
 */
int
allowed_user(struct passwd * pw)
{
	struct stat st;
	const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
	char *shell;
	int i;
#ifdef USE_SHADOW
	struct spwd *spw = NULL;
#endif

	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
	if (!pw || !pw->pw_name)
		return 0;

#ifdef USE_SHADOW
	if (!options.use_pam)
		spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
	if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
		return 0;
#endif /* HAS_SHADOW_EXPIRE */
#endif /* USE_SHADOW */

	/* grab passwd field for locked account check */
#ifdef USE_SHADOW
	if (spw != NULL)
		passwd = spw->sp_pwdp;
#else
	passwd = pw->pw_passwd;
#endif

	/* check for locked account */
	if (!options.use_pam && passwd && *passwd) {
		int locked = 0;

#ifdef LOCKED_PASSWD_STRING
		if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
			 locked = 1;
#endif
#ifdef LOCKED_PASSWD_PREFIX
		if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
		    strlen(LOCKED_PASSWD_PREFIX)) == 0)
			 locked = 1;
#endif
#ifdef LOCKED_PASSWD_SUBSTR
		if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
			locked = 1;
#endif
		if (locked) {
			logit("User %.100s not allowed because account is locked",
			    pw->pw_name);
			return 0;
		}
	}

	/*
	 * Get the shell from the password data.  An empty shell field is
	 * legal, and means /bin/sh.
	 */
	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;

	/* deny if shell does not exists or is not executable */
	if (stat(shell, &st) != 0) {
		logit("User %.100s not allowed because shell %.100s does not exist",
		    pw->pw_name, shell);
		return 0;
	}
	if (S_ISREG(st.st_mode) == 0 ||
	    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
		logit("User %.100s not allowed because shell %.100s is not executable",
		    pw->pw_name, shell);
		return 0;
	}

	if (options.num_deny_users > 0 || options.num_allow_users > 0) {
		hostname = get_canonical_hostname(options.use_dns);
		ipaddr = get_remote_ipaddr();
	}

	/* Return false if user is listed in DenyUsers */
	if (options.num_deny_users > 0) {
		for (i = 0; i < options.num_deny_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.deny_users[i])) {
				logit("User %.100s not allowed because listed in DenyUsers",
				    pw->pw_name);
				return 0;
			}
	}
	/* Return false if AllowUsers isn't empty and user isn't listed there */
	if (options.num_allow_users > 0) {
		for (i = 0; i < options.num_allow_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.allow_users[i]))
				break;
		/* i < options.num_allow_users iff we break for loop */
		if (i >= options.num_allow_users) {
			logit("User %.100s not allowed because not listed in AllowUsers",
			    pw->pw_name);
			return 0;
		}
	}
	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
		/* Get the user's group access list (primary and supplementary) */
		if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
			logit("User %.100s not allowed because not in any group",
			    pw->pw_name);
			return 0;
		}

		/* Return false if one of user's groups is listed in DenyGroups */
		if (options.num_deny_groups > 0)
			if (ga_match(options.deny_groups,
			    options.num_deny_groups)) {
				ga_free();
				logit("User %.100s not allowed because a group is listed in DenyGroups",
				    pw->pw_name);
				return 0;
			}
		/*
		 * Return false if AllowGroups isn't empty and one of user's groups
		 * isn't listed there
		 */
		if (options.num_allow_groups > 0)
			if (!ga_match(options.allow_groups,
			    options.num_allow_groups)) {
				ga_free();
				logit("User %.100s not allowed because none of user's groups are listed in AllowGroups",
				    pw->pw_name);
				return 0;
			}
		ga_free();
	}

#ifdef WITH_AIXAUTHENTICATE
	/*
	 * Don't check loginrestrictions() for root account (use
	 * PermitRootLogin to control logins via ssh), or if running as
	 * non-root user (since loginrestrictions will always fail).
	 */
	if ((pw->pw_uid != 0) && (geteuid() == 0)) {
		char *msg;

		if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
			int loginrestrict_errno = errno;

			if (msg && *msg) {
				buffer_append(&loginmsg, msg, strlen(msg));
				aix_remove_embedded_newlines(msg);
				logit("Login restricted for %s: %.100s",
				    pw->pw_name, msg);
			}
			/* Don't fail if /etc/nologin  set */
			if (!(loginrestrict_errno == EPERM &&
			    stat(_PATH_NOLOGIN, &st) == 0))
				return 0;
		}
	}
#endif /* WITH_AIXAUTHENTICATE */

	/* We found no reason not to let this user try to log on... */
	return 1;
}
示例#23
0
void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
	void (*authlog) (const char *fmt,...) = verbose;
	void (*final_authlog) (const char *fmt,...) = logit_notice;
	char *authmsg;
        char *gecos = NULL;
        int is_none_first_failure = 0;

	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
		return;

        /*
         * Avoid unhelpful messages about "Failed none", which happen
         * because the infrastructure always first tries to see if
         * logging in with an empty password will work.
         */
        if (authenticated == 0 && !(authctxt->postponed) && 
            authctxt->failures == 0 && strcmp(method, "none") == 0) {
            is_none_first_failure = 1;
            authlog = debug;
            final_authlog = debug;
        }

	/* Raise logging level */
	else if (authenticated == 1 ||
	    !authctxt->valid ||
	    authctxt->failures >= AUTH_FAIL_LOG ||
	    strcmp(method, "password") == 0)
		authlog = logit;

	if (authctxt->postponed)
		authmsg = "Postponed";
	else
		authmsg = authenticated ? "Accepted" : "Failed";

        if (authctxt->valid || aaa_log_unknown_usernames_flag) {
            (*authlog)("%s %s for %s%.100s from %.200s port %d%s",
                       authmsg,
                       method,
                       authctxt->valid ? "" : "unknown user ",
                       authctxt->user,
                       get_remote_ipaddr(),
                       get_remote_port(),
                       info);
        }
        else {
            debug("%s %s for %s%.100s from %.200s port %d%s",
                  authmsg,
                  method,
                  authctxt->valid ? "" : "unknown user ",
                  authctxt->user,
                  get_remote_ipaddr(),
                  get_remote_port(),
                  info);
            (*authlog)("%s %s for unknown user from %.200s port %d%s",
                       authmsg,
                       method,
                       get_remote_ipaddr(),
                       get_remote_port(),
                       info);
        }
        if (!(authctxt->postponed)) {
            gecos = get_gecos(authctxt->user);
            if (authenticated) {
                (*final_authlog)("%s %s%s logged in via%s from %s",
                             authctxt->valid ? "User" : "Unknown user",
                             authctxt->user, gecos ? gecos : "",
                             info, get_remote_ipaddr());
            }
            else {
                if (authctxt->valid || aaa_log_unknown_usernames_flag) {
                    (*final_authlog)("%s %s%s failed to login via%s from %s",
                                     authctxt->valid ? "User" : "Unknown user",
                                     authctxt->user, gecos ? gecos : "",
                                     info, get_remote_ipaddr());
                }
                else {
                    debug("%s %s%s failed to login via%s from %s",
                          authctxt->valid ? "User" : "Unknown user",
                          authctxt->user, gecos ? gecos : "",
                          info, get_remote_ipaddr());
                    (*final_authlog)("Unknown user failed to login via%s from %s",
                                     info, get_remote_ipaddr());
                }
            }
            if (gecos) {
                free(gecos);
            }
        }

#ifdef CUSTOM_FAILED_LOGIN
	if (authenticated == 0 && !authctxt->postponed &&
            !is_none_first_failure &&
            (strcmp(method, "password") == 0 ||
            strncmp(method, "keyboard-interactive", 20) == 0 ||
            strcmp(method, "challenge-response") == 0))
		record_failed_login(authctxt->user,
                    get_canonical_hostname(options.use_dns), "ssh");
#endif
}
示例#24
0
/*
 * return 1 if access is granted, 0 if not.
 * side effect: sets key option flags
 */
int
auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
{
	const char *cp;
	int i;

	/* reset options */
	auth_clear_options();

	if (!opts)
		return 1;

	while (*opts && *opts != ' ' && *opts != '\t') {
		cp = "no-port-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Port forwarding disabled.");
			no_port_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-agent-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Agent forwarding disabled.");
			no_agent_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-X11-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("X11 forwarding disabled.");
			no_x11_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-pty";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Pty allocation disabled.");
			no_pty_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "command=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			opts += strlen(cp);
			forced_command = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					forced_command[i++] = '"';
					continue;
				}
				forced_command[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(forced_command);
				forced_command = NULL;
				goto bad_option;
			}
			forced_command[i] = 0;
			auth_debug_add("Forced command: %.900s", forced_command);
			opts++;
			goto next_option;
		}
		cp = "environment=\"";
		if (options.permit_user_env &&
		    strncasecmp(opts, cp, strlen(cp)) == 0) {
			char *s;
			struct envstring *new_envstring;

			opts += strlen(cp);
			s = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					s[i++] = '"';
					continue;
				}
				s[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(s);
				goto bad_option;
			}
			s[i] = 0;
			auth_debug_add("Adding to environment: %.900s", s);
			debug("Adding to environment: %.900s", s);
			opts++;
			new_envstring = xmalloc(sizeof(struct envstring));
			new_envstring->s = s;
			new_envstring->next = custom_environment;
			custom_environment = new_envstring;
			goto next_option;
		}
		cp = "from=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			const char *remote_ip = get_remote_ipaddr();
			const char *remote_host = get_canonical_hostname(
			    options.verify_reverse_mapping);
			char *patterns = xmalloc(strlen(opts) + 1);

			opts += strlen(cp);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					patterns[i++] = '"';
					continue;
				}
				patterns[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			patterns[i] = 0;
			opts++;
			if (match_host_and_ip(remote_host, remote_ip,
			    patterns) != 1) {
				xfree(patterns);
				log("Authentication tried for %.100s with "
				    "correct key but not from a permitted "
				    "host (host=%.200s, ip=%.200s).",
				    pw->pw_name, remote_host, remote_ip);
				auth_debug_add("Your host '%.200s' is not "
				    "permitted to use this key for login.",
				    remote_host);
				/* deny access */
				return 0;
			}
			xfree(patterns);
			/* Host name matches. */
			goto next_option;
		}
		cp = "permitopen=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			char host[256], sport[6];
			u_short port;
			char *patterns = xmalloc(strlen(opts) + 1);

			opts += strlen(cp);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					patterns[i++] = '"';
					continue;
				}
				patterns[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			patterns[i] = 0;
			opts++;
			if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 &&
			    sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
				debug("%.100s, line %lu: Bad permitopen specification "
				    "<%.100s>", file, linenum, patterns);
				auth_debug_add("%.100s, line %lu: "
				    "Bad permitopen specification", file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			if ((port = a2port(sport)) == 0) {
				debug("%.100s, line %lu: Bad permitopen port <%.100s>",
				    file, linenum, sport);
				auth_debug_add("%.100s, line %lu: "
				    "Bad permitopen port", file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			if (options.allow_tcp_forwarding)
				channel_add_permitted_opens(host, port);
			xfree(patterns);
			goto next_option;
		}
next_option:
		/*
		 * Skip the comma, and move to the next option
		 * (or break out if there are no more).
		 */
		if (!*opts)
			fatal("Bugs in auth-options.c option processing.");
		if (*opts == ' ' || *opts == '\t')
			break;		/* End of options. */
		if (*opts != ',')
			goto bad_option;
		opts++;
		/* Process the next option. */
	}

	if (!use_privsep)
		auth_debug_send();

	/* grant access */
	return 1;

bad_option:
	log("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, opts);
	auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, opts);

	if (!use_privsep)
		auth_debug_send();

	/* deny access */
	return 0;
}
示例#25
0
/*
 * return 1 if access is granted, 0 if not.
 * side effect: sets key option flags
 */
int
auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
{
	const char *cp;
	int i;

	/* reset options */
	auth_clear_options();

	if (!opts)
		return 1;

	while (*opts && *opts != ' ' && *opts != '\t') {
		cp = "cert-authority";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			key_is_cert_authority = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-port-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Port forwarding disabled.");
			no_port_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-agent-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Agent forwarding disabled.");
			no_agent_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-X11-forwarding";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("X11 forwarding disabled.");
			no_x11_forwarding_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-pty";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("Pty allocation disabled.");
			no_pty_flag = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "no-user-rc";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			auth_debug_add("User rc file execution disabled.");
			no_user_rc = 1;
			opts += strlen(cp);
			goto next_option;
		}
		cp = "command=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			opts += strlen(cp);
			if (forced_command != NULL)
				xfree(forced_command);
			forced_command = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					forced_command[i++] = '"';
					continue;
				}
				forced_command[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(forced_command);
				forced_command = NULL;
				goto bad_option;
			}
			forced_command[i] = '\0';
			auth_debug_add("Forced command.");
			opts++;
			goto next_option;
		}
		cp = "principals=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			opts += strlen(cp);
			if (authorized_principals != NULL)
				xfree(authorized_principals);
			authorized_principals = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					authorized_principals[i++] = '"';
					continue;
				}
				authorized_principals[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(authorized_principals);
				authorized_principals = NULL;
				goto bad_option;
			}
			authorized_principals[i] = '\0';
			auth_debug_add("principals: %.900s",
			    authorized_principals);
			opts++;
			goto next_option;
		}
		cp = "environment=\"";
		if (options.permit_user_env &&
		    strncasecmp(opts, cp, strlen(cp)) == 0) {
			char *s;
			struct envstring *new_envstring;

			opts += strlen(cp);
			s = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					s[i++] = '"';
					continue;
				}
				s[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(s);
				goto bad_option;
			}
			s[i] = '\0';
			auth_debug_add("Adding to environment: %.900s", s);
			debug("Adding to environment: %.900s", s);
			opts++;
			new_envstring = xmalloc(sizeof(struct envstring));
			new_envstring->s = s;
			new_envstring->next = custom_environment;
			custom_environment = new_envstring;
			goto next_option;
		}
		cp = "from=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			const char *remote_ip = get_remote_ipaddr();
			const char *remote_host = get_canonical_hostname(
			    options.use_dns);
			char *patterns = xmalloc(strlen(opts) + 1);

			opts += strlen(cp);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					patterns[i++] = '"';
					continue;
				}
				patterns[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			patterns[i] = '\0';
			opts++;
			switch (match_host_and_ip(remote_host, remote_ip,
			    patterns)) {
			case 1:
				xfree(patterns);
				/* Host name matches. */
				goto next_option;
			case -1:
				debug("%.100s, line %lu: invalid criteria",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: "
				    "invalid criteria", file, linenum);
				/* FALLTHROUGH */
			case 0:
				xfree(patterns);
				logit("Authentication tried for %.100s with "
				    "correct key but not from a permitted "
				    "host (host=%.200s, ip=%.200s).",
				    pw->pw_name, remote_host, remote_ip);
				auth_debug_add("Your host '%.200s' is not "
				    "permitted to use this key for login.",
				    remote_host);
				break;
			}
			/* deny access */
			return 0;
		}
		cp = "permitopen=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			char *host, *p;
			int port;
			char *patterns = xmalloc(strlen(opts) + 1);

			opts += strlen(cp);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				if (*opts == '\\' && opts[1] == '"') {
					opts += 2;
					patterns[i++] = '"';
					continue;
				}
				patterns[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing "
				    "end quote", file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			patterns[i] = '\0';
			opts++;
			p = patterns;
			host = hpdelim(&p);
			if (host == NULL || strlen(host) >= NI_MAXHOST) {
				debug("%.100s, line %lu: Bad permitopen "
				    "specification <%.100s>", file, linenum,
				    patterns);
				auth_debug_add("%.100s, line %lu: "
				    "Bad permitopen specification", file,
				    linenum);
				xfree(patterns);
				goto bad_option;
			}
			host = cleanhostname(host);
			if (p == NULL || (port = a2port(p)) <= 0) {
				debug("%.100s, line %lu: Bad permitopen port "
				    "<%.100s>", file, linenum, p ? p : "");
				auth_debug_add("%.100s, line %lu: "
				    "Bad permitopen port", file, linenum);
				xfree(patterns);
				goto bad_option;
			}
			if (options.allow_tcp_forwarding)
				channel_add_permitted_opens(host, port);
			xfree(patterns);
			goto next_option;
		}
		cp = "tunnel=\"";
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
			char *tun = NULL;
			opts += strlen(cp);
			tun = xmalloc(strlen(opts) + 1);
			i = 0;
			while (*opts) {
				if (*opts == '"')
					break;
				tun[i++] = *opts++;
			}
			if (!*opts) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: missing end quote",
				    file, linenum);
				xfree(tun);
				forced_tun_device = -1;
				goto bad_option;
			}
			tun[i] = '\0';
			forced_tun_device = a2tun(tun, NULL);
			xfree(tun);
			if (forced_tun_device == SSH_TUNID_ERR) {
				debug("%.100s, line %lu: invalid tun device",
				    file, linenum);
				auth_debug_add("%.100s, line %lu: invalid tun device",
				    file, linenum);
				forced_tun_device = -1;
				goto bad_option;
			}
			auth_debug_add("Forced tun device: %d", forced_tun_device);
			opts++;
			goto next_option;
		}
next_option:
		/*
		 * Skip the comma, and move to the next option
		 * (or break out if there are no more).
		 */
		if (!*opts)
			fatal("Bugs in auth-options.c option processing.");
		if (*opts == ' ' || *opts == '\t')
			break;		/* End of options. */
		if (*opts != ',')
			goto bad_option;
		opts++;
		/* Process the next option. */
	}

	/* grant access */
	return 1;

bad_option:
	logit("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, opts);
	auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, opts);

	/* deny access */
	return 0;
}
示例#26
0
/* return 1 if given hostkey is allowed */
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
    Key *key)
{
	const char *resolvedname, *ipaddr, *lookup, *reason;
	HostStatus host_status;
	int len;
	char *fp;

	if (auth_key_is_revoked(key))
		return 0;

	resolvedname = get_canonical_hostname(options.use_dns);
	ipaddr = get_remote_ipaddr();

	debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
	    chost, resolvedname, ipaddr);

	if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
		debug2("stripping trailing dot from chost %s", chost);
		chost[len - 1] = '\0';
	}

	if (options.hostbased_uses_name_from_packet_only) {
		if (auth_rhosts2(pw, cuser, chost, chost) == 0)
			return 0;
		lookup = chost;
	} else {
		if (strcasecmp(resolvedname, chost) != 0)
			logit("userauth_hostbased mismatch: "
			    "client sends %s, but we resolve %s to %s",
			    chost, ipaddr, resolvedname);
		if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
			return 0;
		lookup = resolvedname;
	}
	debug2("userauth_hostbased: access allowed by auth_rhosts2");

	if (key_is_cert(key) && 
	    key_cert_check_authority(key, 1, 0, lookup, &reason)) {
		error("%s", reason);
		auth_debug_add("%s", reason);
		return 0;
	}

	host_status = check_key_in_hostfiles(pw, key, lookup,
	    _PATH_SSH_SYSTEM_HOSTFILE,
	    options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);

	/* backward compat if no key has been found. */
	if (host_status == HOST_NEW) {
		host_status = check_key_in_hostfiles(pw, key, lookup,
		    _PATH_SSH_SYSTEM_HOSTFILE2,
		    options.ignore_user_known_hosts ? NULL :
		    _PATH_SSH_USER_HOSTFILE2);
	}

	if (host_status == HOST_OK) {
		if (key_is_cert(key)) {
			fp = key_fingerprint(key->cert->signature_key,
			    SSH_FP_MD5, SSH_FP_HEX);
			verbose("Accepted certificate ID \"%s\" signed by "
			    "%s CA %s from %s@%s", key->cert->key_id,
			    key_type(key->cert->signature_key), fp,
			    cuser, lookup);
		} else {
			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Accepted %s public key %s from %s@%s",
			    key_type(key), fp, cuser, lookup);
		}
		xfree(fp);
	}

	return (host_status == HOST_OK);
}
示例#27
0
/*
 * Check if the user is allowed to log in via ssh. If user is listed
 * in DenyUsers or one of user's groups is listed in DenyGroups, false
 * will be returned. If AllowUsers isn't empty and user isn't listed
 * there, or if AllowGroups isn't empty and one of user's groups isn't
 * listed there, false will be returned.
 * If the user's shell is not executable, false will be returned.
 * Otherwise true is returned.
 */
int
allowed_user(struct passwd * pw)
{
	struct stat st;
	const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
	u_int i;
#ifdef USE_SHADOW
	struct spwd *spw = NULL;
#endif

	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
	if (!pw || !pw->pw_name)
		return 0;

#ifdef USE_SHADOW
	if (!options.use_pam)
		spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
	if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
		return 0;
#endif /* HAS_SHADOW_EXPIRE */
#endif /* USE_SHADOW */

	/* grab passwd field for locked account check */
	passwd = pw->pw_passwd;
#ifdef USE_SHADOW
	if (spw != NULL)
#ifdef USE_LIBIAF
		passwd = get_iaf_password(pw);
#else
		passwd = spw->sp_pwdp;
#endif /* USE_LIBIAF */
#endif

	/* check for locked account */
	if (!options.use_pam && passwd && *passwd) {
		int locked = 0;

#ifdef LOCKED_PASSWD_STRING
		if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
			 locked = 1;
#endif
#ifdef LOCKED_PASSWD_PREFIX
		if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
		    strlen(LOCKED_PASSWD_PREFIX)) == 0)
			 locked = 1;
#endif
#ifdef LOCKED_PASSWD_SUBSTR
		if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
			locked = 1;
#endif
#ifdef USE_LIBIAF
		free((void *) passwd);
#endif /* USE_LIBIAF */
		if (locked) {
			logit("User %.100s not allowed because account is locked",
			    pw->pw_name);
			return 0;
		}
	}

	/*
	 * Deny if shell does not exist or is not executable unless we
	 * are chrooting.
	 */
	if (options.chroot_directory == NULL ||
	    strcasecmp(options.chroot_directory, "none") == 0) {
		char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
		    _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */

		if (stat(shell, &st) != 0) {
			logit("User %.100s not allowed because shell %.100s "
			    "does not exist", pw->pw_name, shell);
			xfree(shell);
			return 0;
		}
		if (S_ISREG(st.st_mode) == 0 ||
		    (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
			logit("User %.100s not allowed because shell %.100s "
			    "is not executable", pw->pw_name, shell);
			xfree(shell);
			return 0;
		}
		xfree(shell);
	}

	if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
	    options.num_deny_groups > 0 || options.num_allow_groups > 0) {
		hostname = get_canonical_hostname(options.use_dns);
		ipaddr = get_remote_ipaddr();
	}

	/* Return false if user is listed in DenyUsers */
	if (options.num_deny_users > 0) {
		for (i = 0; i < options.num_deny_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.deny_users[i])) {
				logit("User %.100s from %.100s not allowed "
				    "because listed in DenyUsers",
				    pw->pw_name, hostname);
				return 0;
			}
	}
	/* Return false if AllowUsers isn't empty and user isn't listed there */
	if (options.num_allow_users > 0) {
		for (i = 0; i < options.num_allow_users; i++)
			if (match_user(pw->pw_name, hostname, ipaddr,
			    options.allow_users[i]))
				break;
		/* i < options.num_allow_users iff we break for loop */
		if (i >= options.num_allow_users) {
			logit("User %.100s from %.100s not allowed because "
			    "not listed in AllowUsers", pw->pw_name, hostname);
			return 0;
		}
	}
	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
		/* Get the user's group access list (primary and supplementary) */
		if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
			logit("User %.100s from %.100s not allowed because "
			    "not in any group", pw->pw_name, hostname);
			return 0;
		}

		/* Return false if one of user's groups is listed in DenyGroups */
		if (options.num_deny_groups > 0)
			if (ga_match(options.deny_groups,
			    options.num_deny_groups)) {
				ga_free();
				logit("User %.100s from %.100s not allowed "
				    "because a group is listed in DenyGroups",
				    pw->pw_name, hostname);
				return 0;
			}
		/*
		 * Return false if AllowGroups isn't empty and one of user's groups
		 * isn't listed there
		 */
		if (options.num_allow_groups > 0)
			if (!ga_match(options.allow_groups,
			    options.num_allow_groups)) {
				ga_free();
				logit("User %.100s from %.100s not allowed "
				    "because none of user's groups are listed "
				    "in AllowGroups", pw->pw_name, hostname);
				return 0;
			}
		ga_free();
	}

#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
	if (!sys_auth_allowed_user(pw, &loginmsg))
		return 0;
#endif

	/* We found no reason not to let this user try to log on... */
	return 1;
}
示例#28
0
struct passwd *
getpwnamallow(const char *user)
{
#ifdef HAVE_LOGIN_CAP
	extern login_cap_t *lc;
#ifdef BSD_AUTH
	auth_session_t *as;
#endif
#endif
	struct passwd *pw;

	parse_server_match_config(&options, user,
	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());

#if defined(_AIX) && defined(HAVE_SETAUTHDB)
	aix_setauthdb(user);
#endif

	pw = getpwnam(user);

#if defined(_AIX) && defined(HAVE_SETAUTHDB)
	aix_restoreauthdb();
#endif
#ifdef HAVE_CYGWIN
	/*
	 * Windows usernames are case-insensitive.  To avoid later problems
	 * when trying to match the username, the user is only allowed to
	 * login if the username is given in the same case as stored in the
	 * user database.
	 */
	if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
		logit("Login name %.100s does not match stored username %.100s",
		    user, pw->pw_name);
		pw = NULL;
	}
#endif
	if (pw == NULL) {
		logit("Invalid user %.100s from %.100s",
		    user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN
		record_failed_login(user,
		    get_canonical_hostname(options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
		audit_event(SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
		return (NULL);
	}
	if (!allowed_user(pw))
		return (NULL);
#ifdef HAVE_LOGIN_CAP
	if ((lc = login_getclass(pw->pw_class)) == NULL) {
		debug("unable to get login class: %s", user);
		return (NULL);
	}
#ifdef BSD_AUTH
	if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
	    auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
		debug("Approval failure for %s", user);
		pw = NULL;
	}
	if (as != NULL)
		auth_close(as);
#endif
#endif
	if (pw != NULL)
		return (pwcopy(pw));
	return (NULL);
}
示例#29
0
int
cray_setup (uid_t uid, char *username, const char *command)
{
	extern struct udb *getudb();
	extern char *setlimits();

	int err;                      /* error return */
	time_t		system_time;	/* current system clock */
	time_t		expiration_time; /* password expiration time */
	int		maxattempts;	/* maximum no. of failed login attempts */
	int		SecureSys;	/* unicos security flag */
	int		minslevel = 0;	/* system minimum security level */
	int		i, j;
	int		valid_acct = -1; /* flag for reading valid acct */
	char acct_name[MAXACID]  = { "" }; /* used to read acct name */
	struct		jtab jtab;	/* Job table struct */
	struct		udb ue;		/* udb entry for logging-in user */
	struct		udb *up;	/* pointer to UDB entry */
	struct		secstat secinfo; /* file  security attributes */
	struct          servprov init_info; /* used for sesscntl() call */
	int		jid;		/* job ID */
	int		pid;		/* process ID */
	char		*sr;            /* status return from setlimits() */
	char		*ttyn = NULL;	/* ttyname or command name*/
	char		hostname[MAXHOSTNAMELEN];
	passwd_t	pwdacm,
			pwddialup,
			pwdudb,
			pwdwal,
			pwddce;		/* passwd stuff for ia_user */
	ia_user_ret_t	uret;		/* stuff returned from ia_user */
	ia_user_t	usent;		/* ia_user main structure */
	int		ia_rcode;	/* ia_user return code */
	ia_failure_t	fsent;		/* ia_failure structure */
	ia_failure_ret_t fret;		/* ia_failure return stuff */
	ia_success_t	ssent;		/* ia_success structure */
	ia_success_ret_t sret;		/* ia_success return stuff */
	int		ia_mlsrcode;    /* ia_mlsuser return code */
	int		secstatrc;      /* [f]secstat return code */

	if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) {
		getsysv(&sysv, sizeof(struct sysv));
		minslevel = sysv.sy_minlvl;
		if (getusrv(&usrv) < 0) {
			debug("getusrv() failed, errno = %d",errno);
			exit(1);
		}
	}
	hostname[0] = '\0';
	strncpy(hostname,
	   (char *)get_canonical_hostname(options.verify_reverse_mapping),
	   MAXHOSTNAMELEN);
        /*
         *  Fetch user's UDB entry.
         */
        getsysudb();
        if ((up = getudbnam(username)) == UDB_NULL) {
                debug("cannot fetch user's UDB entry");
                exit(1);
        }

        /*
         *  Prevent any possible fudging so perform a data
         *  safety check and compare the supplied uid against
         *  the udb's uid.
         */
        if (up->ue_uid != uid) {
                debug("IA uid missmatch");
                exit(1);
        }
	endudb();

	if ((jid = getjtab (&jtab)) < 0) {
		debug("getjtab");
		return -1;
	}
	pid = getpid();
	ttyn = ttyname(0);
	if (SecureSys) {
		if (ttyn) {
			secstatrc = secstat(ttyn, &secinfo);
		} else {
			secstatrc = fsecstat(1, &secinfo);
		}
		if (secstatrc == 0) {
			debug("[f]secstat() successful");
		} else {
			debug("[f]secstat() error, rc = %d", secstatrc);
			exit(1);
		}
	}
	if ((ttyn == NULL) && ((char *)command != NULL))
		ttyn = (char *)command;
        /*
         *  Initialize all structures to call ia_user
         */
        usent.revision = 0;
        usent.uname    = username;
        usent.host     = hostname;
        usent.ttyn     = ttyn;
        usent.caller   = IA_SSHD; 
        usent.pswdlist = &pwdacm;
        usent.ueptr    = &ue;
        usent.flags    = IA_INTERACTIVE | IA_FFLAG;
        pwdacm.atype   = IA_SECURID;
        pwdacm.pwdp    = NULL;
        pwdacm.next    = &pwdudb;

        pwdudb.atype   = IA_UDB;
        pwdudb.pwdp    = NULL;
        pwdudb.next    = &pwddce;

        pwddce.atype   = IA_DCE;
        pwddce.pwdp    = NULL;
        pwddce.next    = &pwddialup;

        pwddialup.atype = IA_DIALUP;
        pwddialup.pwdp  = NULL;
        /* pwddialup.next  = &pwdwal; */
        pwddialup.next  = NULL;

        pwdwal.atype = IA_WAL;
        pwdwal.pwdp  = NULL;
        pwdwal.next  = NULL;

        uret.revision = 0;
        uret.pswd     = NULL;
        uret.normal   = 0;

        ia_rcode = ia_user(&usent, &uret);

        switch (ia_rcode) {
                /*
                 *  These are acceptable return codes from ia_user()
                 */
                case IA_UDBWEEK:        /* Password Expires in 1 week */
		     expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage;
		     printf ("WARNING - your current password will expire %s\n",
                     ctime((const time_t *)&expiration_time));
                     break;
                case IA_UDBEXPIRED:
		     if (ttyname(0) != NULL) {
		     /* Force a password change */
		         printf("Your password has expired; Choose a new one.\n");
		         execl("/bin/passwd", "passwd", username, 0);
		         exit(9);
		     }

		     break;
                case IA_NORMAL:         /* Normal Return Code */
                     break;
                case IA_BACKDOOR:
                     strcpy(ue.ue_name, "root");
                     strcpy(ue.ue_passwd, "");
                     strcpy(ue.ue_dir, "/");
                     strcpy(ue.ue_shell, "/bin/sh");
                     strcpy(ue.ue_age, "");
                     strcpy(ue.ue_comment, "");
                     strcpy(ue.ue_loghost, "");
                     strcpy(ue.ue_logline, "");
                     ue.ue_uid=-1;
                     ue.ue_nice[UDBRC_INTER]=0;
                     for (i=0;i<MAXVIDS;i++)
                         ue.ue_gids[i]=0;
                     ue.ue_logfails=0;
                     ue.ue_minlvl=minslevel; 
                     ue.ue_maxlvl=minslevel;
                     ue.ue_deflvl=minslevel;
                     ue.ue_defcomps=0;
                     ue.ue_comparts=0;
                     ue.ue_permits=0;
                     ue.ue_trap=0;
                     ue.ue_disabled=0;
                     ue.ue_logtime=0;
                     break;
                case IA_CONSOLE:        /* Superuser not from Console */
		case IA_TRUSTED:	/* Trusted user */
		     if (options.permit_root_login > PERMIT_NO)
                     	break;		/* Accept root login */
   	        default:
                /*
                 *  These are failed return codes from ia_user()
                 */
		     switch (ia_rcode) 
		       {
		       case IA_BADAUTH:
			 printf ("Bad authorization, access denied.\n");
			 break;
		       case IA_DIALUPERR:
			 break;
		       case IA_DISABLED:
			 printf ("Your login has been disabled. Contact the system ");
			 printf ("administrator for assistance.\n");
			 break;
		       case IA_GETSYSV:
			 printf ("getsysv() failed - errno = %d\n", errno);
			 break;
		       case IA_LOCALHOST:
			 break;
		       case IA_MAXLOGS:
			 printf ("Maximum number of failed login attempts exceeded.\n");
			 printf ("Access denied.\n");
			 break;
		       case IA_NOPASS:
			 break;
		       case IA_PUBLIC:
			 break;
		       case IA_SECURIDERR:
			 break;
		       case IA_CONSOLE:
			 break;
		       case IA_TRUSTED:
			 break;
		       case IA_UDBERR:
			 break;
		       case IA_UDBPWDNULL:
			 /* 
			  * NULL password not allowed on MLS systems
			  */
			 if (SecureSys) {
			   printf("NULL Password not allowed on MLS systems.\n");
			 }
			 break;
		       case IA_UNKNOWN:
			 break;
		       case IA_UNKNOWNYP:
			 break;
		       case IA_WALERR:
			 break;
		       default:
			 /* nothing special */
			 ;
		       }   /* 2. switch  (ia_rcode) */
		     /*
		      *  Authentication failed.
		      */
		     printf("sshd: Login incorrect, (0%o)\n",
			    ia_rcode-IA_ERRORCODE);
		     
		     /*
		      *  Initialize structure for ia_failure
		      *  which will exit.
		      */
		     fsent.revision = 0;
		     fsent.uname    = username;
		     fsent.host     = hostname;
		     fsent.ttyn     = ttyn;
		     fsent.caller   = IA_SSHD;
		     fsent.flags    = IA_INTERACTIVE;
		     fsent.ueptr    = &ue;
		     fsent.jid      = jid;
		     fsent.errcode  = ia_rcode;
		     fsent.pwdp     = uret.pswd;
		     fsent.exitcode = 1;
		     
		     fret.revision  = 0;
		     fret.normal    = 0;
		     
		     /*
		      *  Call ia_failure because of an IA failure.
		      *  There is no return because ia_failure exits.
		      */
	
		     ia_failure(&fsent,&fret);

		     exit(1); 
	}   /* 1. switch  (ia_rcode) */
	ia_mlsrcode = IA_NORMAL;
	if (SecureSys) {
		debug("calling ia_mlsuser()");
		ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0);
	}
	if (ia_mlsrcode != IA_NORMAL) {
		printf("sshd: Login incorrect, (0%o)\n",
		ia_mlsrcode-IA_ERRORCODE);
		/*
 		 *  Initialize structure for ia_failure
 		 *  which will exit.
		*/
		fsent.revision = 0;
		fsent.uname    = username;
		fsent.host     = hostname;
		fsent.ttyn     = ttyn;
		fsent.caller   = IA_SSHD;
		fsent.flags    = IA_INTERACTIVE;
		fsent.ueptr    = &ue;
		fsent.jid      = jid;
		fsent.errcode  = ia_mlsrcode;
		fsent.pwdp     = uret.pswd;
		fsent.exitcode = 1;
		fret.revision  = 0;
		fret.normal    = 0;

		/*
		*  Call ia_failure because of an IA failure.
		*  There is no return because ia_failure exits.
		*/
		ia_failure(&fsent,&fret);
		exit(1); 
	}

        /* Provide login status information */
        if (options.print_lastlog && ue.ue_logtime != 0) {
            printf("Last successful login was : %.*s ",
                    19, (char *)ctime(&ue.ue_logtime));
  
           if (*ue.ue_loghost != '\0')
                printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost);
 
            else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline);
 
            if ( SecureSys && (ue.ue_logfails != 0)) 
                printf("  followed by %d failed attempts\n", ue.ue_logfails);
        }

	
	/*
	 * Call ia_success to process successful I/A.
	 */
	ssent.revision = 0;
	ssent.uname = username;
	ssent.host = hostname;
	ssent.ttyn = ttyn;
	ssent.caller = IA_SSHD;
	ssent.flags = IA_INTERACTIVE;
	ssent.ueptr = &ue;
	ssent.jid = jid;
	ssent.errcode = ia_rcode;
	ssent.us = NULL;
	ssent.time = 1;      		 /* Set ue_logtime */

	sret.revision = 0;
	sret.normal = 0;

	ia_success(&ssent,&sret);

        /*
         * Query for account, iff > 1 valid acid & askacid permbit
         */
        if (((ue.ue_permbits & PERMBITS_ACCTID) ||
             (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) &&
            ue.ue_permbits & PERMBITS_ASKACID) {
		if (ttyname(0) != NULL) {
		  debug("cray_setup: ttyname true case, %.100s", ttyname);
                  while (valid_acct == -1) {
                        printf("Account (? for available accounts)"
                               " [%s]: ", acid2nam(ue.ue_acids[0]));
                        gets(acct_name);
                        switch (acct_name[0]) {
                        case EOF:
                                exit(0);
                                break;
                        case '\0':
                                valid_acct = ue.ue_acids[0];
                                strcpy(acct_name, acid2nam(valid_acct));
                                break;
                        case '?':
                                /* Print the list 3 wide */
                                for (i = 0, j = 0; i < MAXVIDS; i++) {
                                        if (ue.ue_acids[i] == -1) {
                                                printf("\n");
                                                break;
                                        }
                                        if (++j == 4) {
                                                j = 1;
                                                printf("\n");
                                        }
                                        printf(" %s",
                                               acid2nam(ue.ue_acids[i]));
                                }
                                if (ue.ue_permbits & PERMBITS_ACCTID)
                                        printf("\"acctid\" permbit also allows"
                                               " you to select any valid "
                                               "account name.\n");
                                printf("\n");
                                break;
                        default:
                                if ((valid_acct = nam2acid(acct_name)) == -1)                                        printf("Account id not found for"
                                               " account name \"%s\"\n\n",
                                               acct_name);
                                break;
                        }
                        /*
                         * If an account was given, search the user's
                         * acids array to verify they can use this account.
                         */
                        if ((valid_acct != -1) &&
                            !(ue.ue_permbits & PERMBITS_ACCTID)) {
                                for (i = 0; i < MAXVIDS; i++) {
                                        if (ue.ue_acids[i] == -1)
                                                break;
                                        if (valid_acct == ue.ue_acids[i])
                                                break;
                                }
                                if (i == MAXVIDS ||
                                    ue.ue_acids[i] == -1) {
                                        fprintf(stderr, "Cannot set"
                                                " account name to "
                                                "\"%s\", permission "
                                                "denied\n\n", acct_name);
                                        valid_acct = -1;
                                }
                        }
                  }
		} else {
			/*
			 * The client isn't connected to a terminal and can't
			 * respond to an acid prompt.  Use default acid.
			 */
			debug("cray_setup: ttyname false case, %.100s", ttyname);
			valid_acct = ue.ue_acids[0];
		}
        } else {
                /*
                 * The user doesn't have the askacid permbit set or
                 * only has one valid account to use.
                 */
                valid_acct = ue.ue_acids[0];
        }
        if (acctid(0, valid_acct) < 0) {
                printf ("Bad account id: %d\n", valid_acct);
                exit(1);
        }

/* set up shares and quotas */
/* Now set shares, quotas, limits, including CPU time for the (interactive) 
 * job and process, and set up permissions (for chown etc), etc.
 */
	if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) {
		printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct);
		exit(1);
        }

	sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
	if (sr != NULL) {
		debug("%.200s", sr);
		exit(1);
	}
	sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
	if (sr != NULL) {
		debug("%.200s", sr);
		exit(1);
	}
	/*
 	 * Place the service provider information into
	 * the session table (Unicos) or job table (Unicos/mk).
	 * There exist double defines for the job/session table in
	 * unicos/mk (jtab.h) so no need for a compile time switch.
	 */
	bzero((char *)&init_info, sizeof(struct servprov));
	init_info.s_sessinit.si_id  = URM_SPT_LOGIN;
	init_info.s_sessinit.si_pid = getpid();
	init_info.s_sessinit.si_sid = jid;
	init_info.s_routing.seqno = 0;
	init_info.s_routing.iadrs = 0;
	sesscntl(0, S_SETSERVPO, (int)&init_info);

	/*
	 * Set user and controlling tty security attributes.
	 */
	if (SecureSys) {
		if (setusrv(&usrv) == -1) {
			debug("setusrv() failed, errno = %d",errno);
			exit(1);
		}
	}

        return(0);
}
示例#30
0
void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
	void (*authlog) (const char *fmt,...) = verbose;
	char *authmsg;

	/* Raise logging level */
	if (authenticated == 1 ||
	    !authctxt->valid ||
	    authctxt->failures >= options.max_authtries / 2 ||
	    strcmp(method, "password") == 0)
		authlog = logit;

	if (authctxt->postponed)
		authmsg = "Postponed";
	else
		authmsg = authenticated ? "Accepted" : "Failed";

	authlog("%s %s for %s%.100s from %.200s port %d%s",
	    authmsg,
	    method,
	    authctxt->valid ? "" : "invalid user ",
	    authctxt->user,
	    get_remote_ipaddr(),
	    get_remote_port(),
	    info);

#ifdef CUSTOM_FAILED_LOGIN
	if (authenticated == 0 && !authctxt->postponed &&
	    (strcmp(method, "password") == 0 ||
	    strncmp(method, "keyboard-interactive", 20) == 0 ||
	    strcmp(method, "challenge-response") == 0))
		record_failed_login(authctxt->user,
		    get_canonical_hostname(options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
	if (authenticated == 0 && !authctxt->postponed) {
		ssh_audit_event_t event;

		debug3("audit failed auth attempt, method %s euid %d",
		    method, (int)geteuid());
		/*
		 * Because the auth loop is used in both monitor and slave,
		 * we must be careful to send each event only once and with
		 * enough privs to write the event.
		 */
		event = audit_classify_auth(method);
		switch(event) {
		case SSH_AUTH_FAIL_NONE:
		case SSH_AUTH_FAIL_PASSWD:
		case SSH_AUTH_FAIL_KBDINT:
			if (geteuid() == 0)
				audit_event(event);
			break;
		case SSH_AUTH_FAIL_PUBKEY:
		case SSH_AUTH_FAIL_HOSTBASED:
		case SSH_AUTH_FAIL_GSSAPI:
			/*
			 * This is required to handle the case where privsep
			 * is enabled but it's root logging in, since
			 * use_privsep won't be cleared until after a
			 * successful login.
			 */
			if (geteuid() == 0)
				audit_event(event);
			else
				PRIVSEP(audit_event(event));
			break;
		default:
			error("unknown authentication audit event %d", event);
		}
	}
#endif
}