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

📄 monitor.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (pwent == NULL) {		buffer_put_char(m, 0);		goto out;	}	allowed = 1;	authctxt->pw = pwent;	authctxt->valid = 1;	buffer_put_char(m, 1);	buffer_put_string(m, pwent, sizeof(struct passwd));	buffer_put_cstring(m, pwent->pw_name);	buffer_put_cstring(m, "*");	buffer_put_cstring(m, pwent->pw_gecos);#ifdef HAVE_PW_CLASS_IN_PASSWD	buffer_put_cstring(m, pwent->pw_class);#endif	buffer_put_cstring(m, pwent->pw_dir);	buffer_put_cstring(m, pwent->pw_shell); out:	debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);	mm_request_send(socket, MONITOR_ANS_PWNAM, m);	/* For SSHv1 allow authentication now */	if (!compat20)		monitor_permit_authentications(1);	else {		/* Allow service/style information on the auth context */		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);	}#ifdef USE_PAM	monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);#endif	return (0);}int mm_answer_auth2_read_banner(int socket, Buffer *m){	char *banner;	buffer_clear(m);	banner = auth2_read_banner();	buffer_put_cstring(m, banner != NULL ? banner : "");	mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m);	if (banner != NULL)		free(banner);	return (0);}intmm_answer_authserv(int socket, Buffer *m){	monitor_permit_authentications(1);	authctxt->service = buffer_get_string(m, NULL);	authctxt->style = buffer_get_string(m, NULL);	debug3("%s: service=%s, style=%s",	    __func__, authctxt->service, authctxt->style);	if (strlen(authctxt->style) == 0) {		xfree(authctxt->style);		authctxt->style = NULL;	}	return (0);}intmm_answer_authpassword(int socket, Buffer *m){	static int call_count;	char *passwd;	int authenticated, plen;	passwd = buffer_get_string(m, &plen);	/* Only authenticate if the context is valid */	authenticated = options.password_authentication &&	    authctxt->valid && auth_password(authctxt, passwd);	memset(passwd, 0, strlen(passwd));	xfree(passwd);	buffer_clear(m);	buffer_put_int(m, authenticated);	debug3("%s: sending result %d", __func__, authenticated);	mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);	call_count++;	if (plen == 0 && call_count == 1)		auth_method = "none";	else		auth_method = "password";	/* Causes monitor loop to terminate if authenticated */	return (authenticated);}#ifdef BSD_AUTHintmm_answer_bsdauthquery(int socket, Buffer *m){	char *name, *infotxt;	u_int numprompts;	u_int *echo_on;	char **prompts;	int res;	res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,	    &prompts, &echo_on);	buffer_clear(m);	buffer_put_int(m, res);	if (res != -1)		buffer_put_cstring(m, prompts[0]);	debug3("%s: sending challenge res: %d", __func__, res);	mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);	if (res != -1) {		xfree(name);		xfree(infotxt);		xfree(prompts);		xfree(echo_on);	}	return (0);}intmm_answer_bsdauthrespond(int socket, Buffer *m){	char *response;	int authok;	if (authctxt->as == 0)		fatal("%s: no bsd auth session", __func__);	response = buffer_get_string(m, NULL);	authok = options.challenge_response_authentication &&	    auth_userresponse(authctxt->as, response, 0);	authctxt->as = NULL;	debug3("%s: <%s> = <%d>", __func__, response, authok);	xfree(response);	buffer_clear(m);	buffer_put_int(m, authok);	debug3("%s: sending authenticated: %d", __func__, authok);	mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);	auth_method = "bsdauth";	return (authok != 0);}#endif#ifdef SKEYintmm_answer_skeyquery(int socket, Buffer *m){	struct skey skey;	char challenge[1024];	int res;	res = skeychallenge(&skey, authctxt->user, challenge);	buffer_clear(m);	buffer_put_int(m, res);	if (res != -1)		buffer_put_cstring(m, challenge);	debug3("%s: sending challenge res: %d", __func__, res);	mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);	return (0);}intmm_answer_skeyrespond(int socket, Buffer *m){	char *response;	int authok;	response = buffer_get_string(m, NULL);	authok = (options.challenge_response_authentication &&	    authctxt->valid &&	    skey_haskey(authctxt->pw->pw_name) == 0 &&	    skey_passcheck(authctxt->pw->pw_name, response) != -1);	xfree(response);	buffer_clear(m);	buffer_put_int(m, authok);	debug3("%s: sending authenticated: %d", __func__, authok);	mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);	auth_method = "skey";	return (authok != 0);}#endif#ifdef USE_PAMintmm_answer_pam_start(int socket, Buffer *m){	char *user;		user = buffer_get_string(m, NULL);	start_pam(user);	xfree(user);	return (0);}#endifstatic voidmm_append_debug(Buffer *m){	if (auth_debug_init && buffer_len(&auth_debug)) {		debug3("%s: Appending debug messages for child", __func__);		buffer_append(m, buffer_ptr(&auth_debug),		    buffer_len(&auth_debug));		buffer_clear(&auth_debug);	}}intmm_answer_keyallowed(int socket, Buffer *m){	Key *key;	u_char *cuser, *chost, *blob;	u_int bloblen;	enum mm_keytype type = 0;	int allowed = 0;	debug3("%s entering", __func__);	type = buffer_get_int(m);	cuser = buffer_get_string(m, NULL);	chost = buffer_get_string(m, NULL);	blob = buffer_get_string(m, &bloblen);	key = key_from_blob(blob, bloblen);	if ((compat20 && type == MM_RSAHOSTKEY) ||	    (!compat20 && type != MM_RSAHOSTKEY))		fatal("%s: key type and protocol mismatch", __func__);	debug3("%s: key_from_blob: %p", __func__, key);	if (key != NULL && authctxt->pw != NULL) {		switch(type) {		case MM_USERKEY:			allowed = options.pubkey_authentication &&			    user_key_allowed(authctxt->pw, key);			break;		case MM_HOSTKEY:			allowed = options.hostbased_authentication &&			    hostbased_key_allowed(authctxt->pw,			    cuser, chost, key);			break;		case MM_RSAHOSTKEY:			key->type = KEY_RSA1; /* XXX */			allowed = options.rhosts_rsa_authentication &&			    auth_rhosts_rsa_key_allowed(authctxt->pw,			    cuser, chost, key);			break;		default:			fatal("%s: unknown key type %d", __func__, type);			break;		}		key_free(key);	}	/* clear temporarily storage (used by verify) */	monitor_reset_key_state();	if (allowed) {		/* Save temporarily for comparison in verify */		key_blob = blob;		key_bloblen = bloblen;		key_blobtype = type;		hostbased_cuser = cuser;		hostbased_chost = chost;	}	debug3("%s: key %p is %s",	    __func__, key, allowed ? "allowed" : "disallowed");	buffer_clear(m);	buffer_put_int(m, allowed);	mm_append_debug(m);	mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m);	if (type == MM_RSAHOSTKEY)		monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);	return (0);}static intmonitor_valid_userblob(u_char *data, u_int datalen){	Buffer b;	u_char *p;	u_int len;	int fail = 0;	buffer_init(&b);	buffer_append(&b, data, datalen);	if (datafellows & SSH_OLD_SESSIONID) {		p = buffer_ptr(&b);		len = buffer_len(&b);		if ((session_id2 == NULL) ||		    (len < session_id2_len) ||		    (memcmp(p, session_id2, session_id2_len) != 0))			fail++;		buffer_consume(&b, session_id2_len);	} else {		p = buffer_get_string(&b, &len);		if ((session_id2 == NULL) ||		    (len != session_id2_len) ||		    (memcmp(p, session_id2, session_id2_len) != 0))			fail++;		xfree(p);	}	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)		fail++;	p = buffer_get_string(&b, NULL);	if (strcmp(authctxt->user, p) != 0) {		log("wrong user name passed to monitor: expected %s != %.100s",		    authctxt->user, p);		fail++;	}	xfree(p);	buffer_skip_string(&b);	if (datafellows & SSH_BUG_PKAUTH) {		if (!buffer_get_char(&b))			fail++;	} else {		p = buffer_get_string(&b, NULL);		if (strcmp("publickey", p) != 0)			fail++;		xfree(p);		if (!buffer_get_char(&b))			fail++;		buffer_skip_string(&b);	}	buffer_skip_string(&b);	if (buffer_len(&b) != 0)		fail++;	buffer_free(&b);	return (fail == 0);}static intmonitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser,    u_char *chost){	Buffer b;	u_char *p;	u_int len;	int fail = 0;	buffer_init(&b);	buffer_append(&b, data, datalen);	p = buffer_get_string(&b, &len);	if ((session_id2 == NULL) ||	    (len != session_id2_len) ||	    (memcmp(p, session_id2, session_id2_len) != 0))		fail++;	xfree(p);	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)		fail++;	p = buffer_get_string(&b, NULL);	if (strcmp(authctxt->user, p) != 0) {		log("wrong user name passed to monitor: expected %s != %.100s",		    authctxt->user, p);		fail++;	}	xfree(p);	buffer_skip_string(&b);	/* service */	p = buffer_get_string(&b, NULL);	if (strcmp(p, "hostbased") != 0)		fail++;	xfree(p);	buffer_skip_string(&b);	/* pkalg */	buffer_skip_string(&b);	/* pkblob */	/* verify client host, strip trailing dot if necessary */	p = buffer_get_string(&b, NULL);	if (((len = strlen(p)) > 0) && p[len - 1] == '.')		p[len - 1] = '\0';	if (strcmp(p, chost) != 0)		fail++;	xfree(p);	/* verify client user */	p = buffer_get_string(&b, NULL);	if (strcmp(p, cuser) != 0)		fail++;	xfree(p);	if (buffer_len(&b) != 0)		fail++;	buffer_free(&b);	return (fail == 0);}intmm_answer_keyverify(int socket, Buffer *m){	Key *key;	u_char *signature, *data, *blob;	u_int signaturelen, datalen, bloblen;	int verified = 0;	int valid_data = 0;	blob = buffer_get_string(m, &bloblen);	signature = buffer_get_string(m, &signaturelen);	data = buffer_get_string(m, &datalen);	if (hostbased_cuser == NULL || hostbased_chost == NULL ||	  !monitor_allowed_key(blob, bloblen))		fatal("%s: bad key, not previously allowed", __func__);	key = key_from_blob(blob, bloblen);	if (key == NULL)		fatal("%s: bad public key blob", __func__);	switch (key_blobtype) {	case MM_USERKEY:		valid_data = monitor_valid_userblob(data, datalen);		break;	case MM_HOSTKEY:		valid_data = monitor_valid_hostbasedblob(data, datalen,		    hostbased_cuser, hostbased_chost);		break;	default:		valid_data = 0;		break;	}	if (!valid_data)		fatal("%s: bad signature data blob", __func__);	verified = key_verify(key, signature, signaturelen, data, datalen);	debug3("%s: key %p signature %s",	    __func__, key, verified ? "verified" : "unverified");	key_free(key);	xfree(blob);	xfree(signature);	xfree(data);	monitor_reset_key_state();	buffer_clear(m);	buffer_put_int(m, verified);	mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);	auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";	return (verified);}static voidmm_record_login(Session *s, struct passwd *pw){	socklen_t fromlen;	struct sockaddr_storage from;	/*	 * Get IP address of client. If the connection is not a socket, let	 * the address be 0.0.0.0.	 */	memset(&from, 0, sizeof(from));	if (packet_connection_is_on_socket()) {		fromlen = sizeof(from);		if (getpeername(packet_get_connection_in(),			(struct sockaddr *) & from, &fromlen) < 0) {			debug("getpeername: %.100s", strerror(errno));			fatal_cleanup();		}	}	/* Record that there was a login on that tty from the remote host. */	record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,	    get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),	    (struct sockaddr *)&from);}static voidmm_session_close(Session *s){	debug3("%s: session %d pid %d", __func__, s->self, s->pid);	if (s->ttyfd != -1) {		debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);		fatal_remove_cleanup(session_pty_cleanup2, (void *)s);		session_pty_cleanup2(s);

⌨️ 快捷键说明

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