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

📄 monitor.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
	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->valid) {		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;		}	}	if (key != NULL)		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);	buffer_put_int(m, forced_command != NULL);	mm_append_debug(m);	mm_request_send(sock, 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;	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) {		logit("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, char *cuser,    char *chost){	Buffer b;	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) {		logit("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 sock, 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);	auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";	monitor_reset_key_state();	buffer_clear(m);	buffer_put_int(m, verified);	mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);	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));	fromlen = sizeof(from);	if (packet_connection_is_on_socket()) {		if (getpeername(packet_get_connection_in(),			(struct sockaddr *) & from, &fromlen) < 0) {			debug("getpeername: %.100s", strerror(errno));			cleanup_exit(255);		}	}	/* 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.use_dns),	    (struct sockaddr *)&from, fromlen);}static voidmm_session_close(Session *s){	debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);	if (s->ttyfd != -1) {		debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);		session_pty_cleanup2(s);	}	s->used = 0;}intmm_answer_pty(int sock, Buffer *m){	extern struct monitor *pmonitor;	Session *s;	int res, fd0;	debug3("%s entering", __func__);	buffer_clear(m);	s = session_new();	if (s == NULL)		goto error;	s->authctxt = authctxt;	s->pw = authctxt->pw;	s->pid = pmonitor->m_pid;	res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));	if (res == 0)		goto error;	pty_setowner(authctxt->pw, s->tty);	buffer_put_int(m, 1);	buffer_put_cstring(m, s->tty);	/* We need to trick ttyslot */	if (dup2(s->ttyfd, 0) == -1)		fatal("%s: dup2", __func__);	mm_record_login(s, authctxt->pw);	/* Now we can close the file descriptor again */	close(0);	/* send messages generated by record_login */	buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg));	buffer_clear(&loginmsg);	mm_request_send(sock, MONITOR_ANS_PTY, m);	mm_send_fd(sock, s->ptyfd);	mm_send_fd(sock, s->ttyfd);	/* make sure nothing uses fd 0 */	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)		fatal("%s: open(/dev/null): %s", __func__, strerror(errno));	if (fd0 != 0)		error("%s: fd0 %d != 0", __func__, fd0);	/* slave is not needed */	close(s->ttyfd);	s->ttyfd = s->ptyfd;	/* no need to dup() because nobody closes ptyfd */	s->ptymaster = s->ptyfd;	debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ttyfd);	return (0); error:	if (s != NULL)		mm_session_close(s);	buffer_put_int(m, 0);	mm_request_send(sock, MONITOR_ANS_PTY, m);	return (0);}intmm_answer_pty_cleanup(int sock, Buffer *m){	Session *s;	char *tty;	debug3("%s entering", __func__);	tty = buffer_get_string(m, NULL);	if ((s = session_by_tty(tty)) != NULL)		mm_session_close(s);	buffer_clear(m);	xfree(tty);	return (0);}intmm_answer_sesskey(int sock, Buffer *m){	BIGNUM *p;	int rsafail;	/* Turn off permissions */	monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0);	if ((p = BN_new()) == NULL)		fatal("%s: BN_new", __func__);	buffer_get_bignum2(m, p);	rsafail = ssh1_session_key(p);	buffer_clear(m);	buffer_put_int(m, rsafail);	buffer_put_bignum2(m, p);	BN_clear_free(p);	mm_request_send(sock, MONITOR_ANS_SESSKEY, m);	/* Turn on permissions for sessid passing */	monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);	return (0);}intmm_answer_sessid(int sock, Buffer *m){	int i;	debug3("%s entering", __func__);	if (buffer_len(m) != 16)		fatal("%s: bad ssh1 session id", __func__);	for (i = 0; i < 16; i++)		session_id[i] = buffer_get_char(m);	/* Turn on permissions for getpwnam */	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);	return (0);}intmm_answer_rsa_keyallowed(int sock, Buffer *m){	BIGNUM *client_n;	Key *key = NULL;	u_char *blob = NULL;	u_int blen = 0;	int allowed = 0;	debug3("%s entering", __func__);	if (options.rsa_authentication && authctxt->valid) {		if ((client_n = BN_new()) == NULL)			fatal("%s: BN_new", __func__);		buffer_get_bignum2(m, client_n);		allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);		BN_clear_free(client_n);	}	buffer_clear(m);	buffer_put_int(m, allowed);	buffer_put_int(m, forced_command != NULL);	/* clear temporarily storage (used by generate challenge) */	monitor_reset_key_state();	if (allowed && key != NULL) {		key->type = KEY_RSA;	/* cheat for key_to_blob */		if (key_to_blob(key, &blob, &blen) == 0)			fatal("%s: key_to_blob failed", __func__);		buffer_put_string(m, blob, blen);		/* Save temporarily for comparison in verify */		key_blob = blob;		key_bloblen = blen;		key_blobtype = MM_RSAUSERKEY;	}	if (key != NULL)		key_free(key);	mm_append_debug(m);	mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m);	monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0);	return (0);}intmm_answer_rsa_challenge(int sock, Buffer *m){	Key *key = NULL;	u_char *blob;	u_int blen;	debug3("%s entering", __func__);	if (!authctxt->valid)		fatal("%s: authctxt not valid", __func__);	blob = buffer_get_string(m, &blen);	if (!monitor_allowed_key(blob, blen))		fatal("%s: bad key, not previously allowed", __func__);	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)		fatal("%s: key type mismatch", __func__);	if ((key = key_from_blob(blob, blen)) == NULL)		fatal("%s: received bad key", __func__);	if (ssh1_challenge)		BN_clear_free(ssh1_challenge);	ssh1_challenge = auth_rsa_generate_challenge(key);	buffer_clear(m);	buffer_put_bignum2(m, ssh1_challenge);	debug3("%s sending reply", __func__);

⌨️ 快捷键说明

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