⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auth.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2000 Markus Friedl.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "includes.h"RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $");#ifdef HAVE_LOGIN_H#include <login.h>#endif#ifdef USE_SHADOW#include <shadow.h>#endif#ifdef HAVE_LIBGEN_H#include <libgen.h>#endif#include "xmalloc.h"#include "match.h"#include "groupaccess.h"#include "log.h"#include "servconf.h"#include "auth.h"#include "auth-options.h"#include "canohost.h"#include "buffer.h"#include "bufaux.h"#include "uidswap.h"#include "misc.h"#include "bufaux.h"#include "packet.h"#include "loginrec.h"#include "monitor_wrap.h"/* import */extern ServerOptions options;extern Buffer loginmsg;/* Debugging messages */Buffer auth_debug;int auth_debug_init;/* * 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. */intallowed_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 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;}voidauth_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}/* * Check whether root logins are disallowed. */intauth_root_allowed(char *method){	switch (options.permit_root_login) {	case PERMIT_YES:		return 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -