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

📄 monitor.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> * 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: monitor.c,v 1.62 2005/01/30 11:18:08 dtucker Exp $");#include <openssl/dh.h>#ifdef SKEY#include <skey.h>#endif#include "ssh.h"#include "auth.h"#include "kex.h"#include "dh.h"#ifdef TARGET_OS_MAC	/* XXX Broken krb5 headers on Mac */#undef TARGET_OS_MAC#include "zlib.h"#define TARGET_OS_MAC 1#else#include "zlib.h"#endif#include "packet.h"#include "auth-options.h"#include "sshpty.h"#include "channels.h"#include "session.h"#include "sshlogin.h"#include "canohost.h"#include "log.h"#include "servconf.h"#include "monitor.h"#include "monitor_mm.h"#include "monitor_wrap.h"#include "monitor_fdpass.h"#include "xmalloc.h"#include "misc.h"#include "buffer.h"#include "bufaux.h"#include "compat.h"#include "ssh2.h"#ifdef GSSAPI#include "ssh-gss.h"static Gssctxt *gsscontext = NULL;#endif/* Imports */extern ServerOptions options;extern u_int utmp_len;extern Newkeys *current_keys[];extern z_stream incoming_stream;extern z_stream outgoing_stream;extern u_char session_id[];extern Buffer input, output;extern Buffer auth_debug;extern int auth_debug_init;extern Buffer loginmsg;/* State exported from the child */struct {	z_stream incoming;	z_stream outgoing;	u_char *keyin;	u_int keyinlen;	u_char *keyout;	u_int keyoutlen;	u_char *ivin;	u_int ivinlen;	u_char *ivout;	u_int ivoutlen;	u_char *ssh1key;	u_int ssh1keylen;	int ssh1cipher;	int ssh1protoflags;	u_char *input;	u_int ilen;	u_char *output;	u_int olen;} child_state;/* Functions on the monitor that answer unprivileged requests */int mm_answer_moduli(int, Buffer *);int mm_answer_sign(int, Buffer *);int mm_answer_pwnamallow(int, Buffer *);int mm_answer_auth2_read_banner(int, Buffer *);int mm_answer_authserv(int, Buffer *);int mm_answer_authpassword(int, Buffer *);int mm_answer_bsdauthquery(int, Buffer *);int mm_answer_bsdauthrespond(int, Buffer *);int mm_answer_skeyquery(int, Buffer *);int mm_answer_skeyrespond(int, Buffer *);int mm_answer_keyallowed(int, Buffer *);int mm_answer_keyverify(int, Buffer *);int mm_answer_pty(int, Buffer *);int mm_answer_pty_cleanup(int, Buffer *);int mm_answer_term(int, Buffer *);int mm_answer_rsa_keyallowed(int, Buffer *);int mm_answer_rsa_challenge(int, Buffer *);int mm_answer_rsa_response(int, Buffer *);int mm_answer_sesskey(int, Buffer *);int mm_answer_sessid(int, Buffer *);#ifdef USE_PAMint mm_answer_pam_start(int, Buffer *);int mm_answer_pam_account(int, Buffer *);int mm_answer_pam_init_ctx(int, Buffer *);int mm_answer_pam_query(int, Buffer *);int mm_answer_pam_respond(int, Buffer *);int mm_answer_pam_free_ctx(int, Buffer *);#endif#ifdef GSSAPIint mm_answer_gss_setup_ctx(int, Buffer *);int mm_answer_gss_accept_ctx(int, Buffer *);int mm_answer_gss_userok(int, Buffer *);int mm_answer_gss_checkmic(int, Buffer *);#endif#ifdef SSH_AUDIT_EVENTSint mm_answer_audit_event(int, Buffer *);int mm_answer_audit_command(int, Buffer *);#endifstatic Authctxt *authctxt;static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth *//* local state for key verify */static u_char *key_blob = NULL;static u_int key_bloblen = 0;static int key_blobtype = MM_NOKEY;static char *hostbased_cuser = NULL;static char *hostbased_chost = NULL;static char *auth_method = "unknown";static u_int session_id2_len = 0;static u_char *session_id2 = NULL;static pid_t monitor_child_pid;struct mon_table {	enum monitor_reqtype type;	int flags;	int (*f)(int, Buffer *);};#define MON_ISAUTH	0x0004	/* Required for Authentication */#define MON_AUTHDECIDE	0x0008	/* Decides Authentication */#define MON_ONCE	0x0010	/* Disable after calling */#define MON_AUTH	(MON_ISAUTH|MON_AUTHDECIDE)#define MON_PERMIT	0x1000	/* Request is permitted */struct mon_table mon_dispatch_proto20[] = {    {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},#ifdef USE_PAM    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},#endif#ifdef SSH_AUDIT_EVENTS    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},#endif#ifdef BSD_AUTH    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},#endif#ifdef SKEY    {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},    {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},#endif    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},    {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},#ifdef GSSAPI    {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},    {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},    {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},#endif    {0, 0, NULL}};struct mon_table mon_dispatch_postauth20[] = {    {MONITOR_REQ_MODULI, 0, mm_answer_moduli},    {MONITOR_REQ_SIGN, 0, mm_answer_sign},    {MONITOR_REQ_PTY, 0, mm_answer_pty},    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},    {MONITOR_REQ_TERM, 0, mm_answer_term},#ifdef SSH_AUDIT_EVENTS    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},#endif    {0, 0, NULL}};struct mon_table mon_dispatch_proto15[] = {    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},    {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},    {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},    {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},    {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},    {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},#ifdef BSD_AUTH    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},#endif#ifdef SKEY    {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},    {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},#endif#ifdef USE_PAM    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},#endif#ifdef SSH_AUDIT_EVENTS    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},#endif    {0, 0, NULL}};struct mon_table mon_dispatch_postauth15[] = {    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},    {MONITOR_REQ_TERM, 0, mm_answer_term},#ifdef SSH_AUDIT_EVENTS    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},    {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command},#endif    {0, 0, NULL}};struct mon_table *mon_dispatch;/* Specifies if a certain message is allowed at the moment */static voidmonitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit){	while (ent->f != NULL) {		if (ent->type == type) {			ent->flags &= ~MON_PERMIT;			ent->flags |= permit ? MON_PERMIT : 0;			return;		}		ent++;	}}static voidmonitor_permit_authentications(int permit){	struct mon_table *ent = mon_dispatch;	while (ent->f != NULL) {		if (ent->flags & MON_AUTH) {			ent->flags &= ~MON_PERMIT;			ent->flags |= permit ? MON_PERMIT : 0;		}		ent++;	}}voidmonitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor){	struct mon_table *ent;	int authenticated = 0;	debug3("preauth child monitor started");	authctxt = _authctxt;	memset(authctxt, 0, sizeof(*authctxt));	if (compat20) {		mon_dispatch = mon_dispatch_proto20;		/* Permit requests for moduli and signatures */		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);	} else {		mon_dispatch = mon_dispatch_proto15;		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);	}	/* The first few requests do not require asynchronous access */	while (!authenticated) {		authenticated = monitor_read(pmonitor, mon_dispatch, &ent);		if (authenticated) {			if (!(ent->flags & MON_AUTHDECIDE))				fatal("%s: unexpected authentication from %d",				    __func__, ent->type);			if (authctxt->pw->pw_uid == 0 &&			    !auth_root_allowed(auth_method))				authenticated = 0;#ifdef USE_PAM			/* PAM needs to perform account checks after auth */			if (options.use_pam && authenticated) {				Buffer m;				buffer_init(&m);				mm_request_receive_expect(pmonitor->m_sendfd,				    MONITOR_REQ_PAM_ACCOUNT, &m);				authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);				buffer_free(&m);			}#endif		}		if (ent->flags & MON_AUTHDECIDE) {			auth_log(authctxt, authenticated, auth_method,			    compat20 ? " ssh2" : "");			if (!authenticated)				authctxt->failures++;		}	}	if (!authctxt->valid)		fatal("%s: authenticated invalid user", __func__);	debug("%s: %s has been authenticated by privileged process",	    __func__, authctxt->user);	mm_get_keystate(pmonitor);}static voidmonitor_set_child_handler(pid_t pid){	monitor_child_pid = pid;}static voidmonitor_child_handler(int sig){	kill(monitor_child_pid, sig);}voidmonitor_child_postauth(struct monitor *pmonitor){	monitor_set_child_handler(pmonitor->m_pid);	signal(SIGHUP, &monitor_child_handler);	signal(SIGTERM, &monitor_child_handler);	if (compat20) {		mon_dispatch = mon_dispatch_postauth20;		/* Permit requests for moduli and signatures */		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);	} else {		mon_dispatch = mon_dispatch_postauth15;		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);	}	if (!no_pty_flag) {		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);	}	for (;;)		monitor_read(pmonitor, mon_dispatch, NULL);}voidmonitor_sync(struct monitor *pmonitor){	if (options.compression) {		/* The member allocation is not visible, so sync it */		mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);	}}intmonitor_read(struct monitor *pmonitor, struct mon_table *ent,    struct mon_table **pent){	Buffer m;	int ret;	u_char type;	buffer_init(&m);	mm_request_receive(pmonitor->m_sendfd, &m);	type = buffer_get_char(&m);	debug3("%s: checking request %d", __func__, type);	while (ent->f != NULL) {		if (ent->type == type)			break;		ent++;	}	if (ent->f != NULL) {		if (!(ent->flags & MON_PERMIT))			fatal("%s: unpermitted request %d", __func__,			    type);		ret = (*ent->f)(pmonitor->m_sendfd, &m);		buffer_free(&m);		/* The child may use this request only once, disable it */		if (ent->flags & MON_ONCE) {			debug2("%s: %d used once, disabling now", __func__,			    type);			ent->flags &= ~MON_PERMIT;		}		if (pent != NULL)			*pent = ent;		return ret;	}	fatal("%s: unsupported request: %d", __func__, type);	/* NOTREACHED */	return (-1);}/* allowed key state */static intmonitor_allowed_key(u_char *blob, u_int bloblen){	/* make sure key is allowed */	if (key_blob == NULL || key_bloblen != bloblen ||	    memcmp(key_blob, blob, key_bloblen))		return (0);	return (1);}static voidmonitor_reset_key_state(void){	/* reset state */	if (key_blob != NULL)		xfree(key_blob);	if (hostbased_cuser != NULL)		xfree(hostbased_cuser);	if (hostbased_chost != NULL)

⌨️ 快捷键说明

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