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

📄 monitor.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
	mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m);	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);	xfree(blob);	key_free(key);	return (0);}intmm_answer_rsa_response(int sock, Buffer *m){	Key *key = NULL;	u_char *blob, *response;	u_int blen, len;	int success;	debug3("%s entering", __func__);	if (!authctxt->valid)		fatal("%s: authctxt not valid", __func__);	if (ssh1_challenge == NULL)		fatal("%s: no ssh1_challenge", __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: %d", __func__, key_blobtype);	if ((key = key_from_blob(blob, blen)) == NULL)		fatal("%s: received bad key", __func__);	response = buffer_get_string(m, &len);	if (len != 16)		fatal("%s: received bad response to challenge", __func__);	success = auth_rsa_verify_response(key, ssh1_challenge, response);	xfree(blob);	key_free(key);	xfree(response);	auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";	/* reset state */	BN_clear_free(ssh1_challenge);	ssh1_challenge = NULL;	monitor_reset_key_state();	buffer_clear(m);	buffer_put_int(m, success);	mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m);	return (success);}intmm_answer_term(int sock, Buffer *req){	extern struct monitor *pmonitor;	int res, status;	debug3("%s: tearing down sessions", __func__);	/* The child is terminating */	session_destroy_all(&mm_session_close);	while (waitpid(pmonitor->m_pid, &status, 0) == -1)		if (errno != EINTR)			exit(1);	res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;	/* Terminate process */	exit(res);}#ifdef SSH_AUDIT_EVENTS/* Report that an audit event occurred */intmm_answer_audit_event(int socket, Buffer *m){	ssh_audit_event_t event;	debug3("%s entering", __func__);	event = buffer_get_int(m);	buffer_free(m);	switch(event) {	case SSH_AUTH_FAIL_PUBKEY:	case SSH_AUTH_FAIL_HOSTBASED:	case SSH_AUTH_FAIL_GSSAPI:	case SSH_LOGIN_EXCEED_MAXTRIES:	case SSH_LOGIN_ROOT_DENIED:	case SSH_CONNECTION_CLOSE:	case SSH_INVALID_USER:		audit_event(event);		break;	default:		fatal("Audit event type %d not permitted", event);	}	return (0);}intmm_answer_audit_command(int socket, Buffer *m){	u_int len;	char *cmd;	debug3("%s entering", __func__);	cmd = buffer_get_string(m, &len);	/* sanity check command, if so how? */	audit_run_command(cmd);	xfree(cmd);	buffer_free(m);	return (0);}#endif /* SSH_AUDIT_EVENTS */voidmonitor_apply_keystate(struct monitor *pmonitor){	if (compat20) {		set_newkeys(MODE_IN);		set_newkeys(MODE_OUT);	} else {		packet_set_protocol_flags(child_state.ssh1protoflags);		packet_set_encryption_key(child_state.ssh1key,		    child_state.ssh1keylen, child_state.ssh1cipher);		xfree(child_state.ssh1key);	}	/* for rc4 and other stateful ciphers */	packet_set_keycontext(MODE_OUT, child_state.keyout);	xfree(child_state.keyout);	packet_set_keycontext(MODE_IN, child_state.keyin);	xfree(child_state.keyin);	if (!compat20) {		packet_set_iv(MODE_OUT, child_state.ivout);		xfree(child_state.ivout);		packet_set_iv(MODE_IN, child_state.ivin);		xfree(child_state.ivin);	}	memcpy(&incoming_stream, &child_state.incoming,	    sizeof(incoming_stream));	memcpy(&outgoing_stream, &child_state.outgoing,	    sizeof(outgoing_stream));	/* Update with new address */	if (options.compression)		mm_init_compression(pmonitor->m_zlib);	/* Network I/O buffers */	/* XXX inefficient for large buffers, need: buffer_init_from_string */	buffer_clear(&input);	buffer_append(&input, child_state.input, child_state.ilen);	memset(child_state.input, 0, child_state.ilen);	xfree(child_state.input);	buffer_clear(&output);	buffer_append(&output, child_state.output, child_state.olen);	memset(child_state.output, 0, child_state.olen);	xfree(child_state.output);}static Kex *mm_get_kex(Buffer *m){	Kex *kex;	void *blob;	u_int bloblen;	kex = xmalloc(sizeof(*kex));	memset(kex, 0, sizeof(*kex));	kex->session_id = buffer_get_string(m, &kex->session_id_len);	if ((session_id2 == NULL) ||	    (kex->session_id_len != session_id2_len) ||	    (memcmp(kex->session_id, session_id2, session_id2_len) != 0))		fatal("mm_get_get: internal error: bad session id");	kex->we_need = buffer_get_int(m);	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;	kex->server = 1;	kex->hostkey_type = buffer_get_int(m);	kex->kex_type = buffer_get_int(m);	blob = buffer_get_string(m, &bloblen);	buffer_init(&kex->my);	buffer_append(&kex->my, blob, bloblen);	xfree(blob);	blob = buffer_get_string(m, &bloblen);	buffer_init(&kex->peer);	buffer_append(&kex->peer, blob, bloblen);	xfree(blob);	kex->done = 1;	kex->flags = buffer_get_int(m);	kex->client_version_string = buffer_get_string(m, NULL);	kex->server_version_string = buffer_get_string(m, NULL);	kex->load_host_key=&get_hostkey_by_type;	kex->host_key_index=&get_hostkey_index;	return (kex);}/* This function requries careful sanity checking */voidmm_get_keystate(struct monitor *pmonitor){	Buffer m;	u_char *blob, *p;	u_int bloblen, plen;	u_int32_t seqnr, packets;	u_int64_t blocks;	debug3("%s: Waiting for new keys", __func__);	buffer_init(&m);	mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);	if (!compat20) {		child_state.ssh1protoflags = buffer_get_int(&m);		child_state.ssh1cipher = buffer_get_int(&m);		child_state.ssh1key = buffer_get_string(&m,		    &child_state.ssh1keylen);		child_state.ivout = buffer_get_string(&m,		    &child_state.ivoutlen);		child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);		goto skip;	} else {		/* Get the Kex for rekeying */		*pmonitor->m_pkex = mm_get_kex(&m);	}	blob = buffer_get_string(&m, &bloblen);	current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);	xfree(blob);	debug3("%s: Waiting for second key", __func__);	blob = buffer_get_string(&m, &bloblen);	current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);	xfree(blob);	/* Now get sequence numbers for the packets */	seqnr = buffer_get_int(&m);	blocks = buffer_get_int64(&m);	packets = buffer_get_int(&m);	packet_set_state(MODE_OUT, seqnr, blocks, packets);	seqnr = buffer_get_int(&m);	blocks = buffer_get_int64(&m);	packets = buffer_get_int(&m);	packet_set_state(MODE_IN, seqnr, blocks, packets); skip:	/* Get the key context */	child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);	child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);	debug3("%s: Getting compression state", __func__);	/* Get compression state */	p = buffer_get_string(&m, &plen);	if (plen != sizeof(child_state.outgoing))		fatal("%s: bad request size", __func__);	memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));	xfree(p);	p = buffer_get_string(&m, &plen);	if (plen != sizeof(child_state.incoming))		fatal("%s: bad request size", __func__);	memcpy(&child_state.incoming, p, sizeof(child_state.incoming));	xfree(p);	/* Network I/O buffers */	debug3("%s: Getting Network I/O buffers", __func__);	child_state.input = buffer_get_string(&m, &child_state.ilen);	child_state.output = buffer_get_string(&m, &child_state.olen);	buffer_free(&m);}/* Allocation functions for zlib */void *mm_zalloc(struct mm_master *mm, u_int ncount, u_int size){	size_t len = (size_t) size * ncount;	void *address;	if (len == 0 || ncount > SIZE_T_MAX / size)		fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);	address = mm_malloc(mm, len);	return (address);}voidmm_zfree(struct mm_master *mm, void *address){	mm_free(mm, address);}voidmm_init_compression(struct mm_master *mm){	outgoing_stream.zalloc = (alloc_func)mm_zalloc;	outgoing_stream.zfree = (free_func)mm_zfree;	outgoing_stream.opaque = mm;	incoming_stream.zalloc = (alloc_func)mm_zalloc;	incoming_stream.zfree = (free_func)mm_zfree;	incoming_stream.opaque = mm;}/* XXX */#define FD_CLOSEONEXEC(x) do { \	if (fcntl(x, F_SETFD, 1) == -1) \		fatal("fcntl(%d, F_SETFD)", x); \} while (0)static voidmonitor_socketpair(int *pair){#ifdef HAVE_SOCKETPAIR	if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)		fatal("%s: socketpair", __func__);#else	fatal("%s: UsePrivilegeSeparation=yes not supported",	    __func__);#endif	FD_CLOSEONEXEC(pair[0]);	FD_CLOSEONEXEC(pair[1]);}#define MM_MEMSIZE	65536struct monitor *monitor_init(void){	struct monitor *mon;	int pair[2];	mon = xmalloc(sizeof(*mon));	mon->m_pid = 0;	monitor_socketpair(pair);	mon->m_recvfd = pair[0];	mon->m_sendfd = pair[1];	/* Used to share zlib space across processes */	if (options.compression) {		mon->m_zback = mm_create(NULL, MM_MEMSIZE);		mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);		/* Compression needs to share state across borders */		mm_init_compression(mon->m_zlib);	}	return mon;}voidmonitor_reinit(struct monitor *mon){	int pair[2];	monitor_socketpair(pair);	mon->m_recvfd = pair[0];	mon->m_sendfd = pair[1];}#ifdef GSSAPIintmm_answer_gss_setup_ctx(int sock, Buffer *m){	gss_OID_desc goid;	OM_uint32 major;	u_int len;	goid.elements = buffer_get_string(m, &len);	goid.length = len;	major = ssh_gssapi_server_ctx(&gsscontext, &goid);	xfree(goid.elements);	buffer_clear(m);	buffer_put_int(m, major);	mm_request_send(sock,MONITOR_ANS_GSSSETUP, m);	/* Now we have a context, enable the step */	monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);	return (0);}intmm_answer_gss_accept_ctx(int sock, Buffer *m){	gss_buffer_desc in;	gss_buffer_desc out = GSS_C_EMPTY_BUFFER;	OM_uint32 major,minor;	OM_uint32 flags = 0; /* GSI needs this */	u_int len;	in.value = buffer_get_string(m, &len);	in.length = len;	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);	xfree(in.value);	buffer_clear(m);	buffer_put_int(m, major);	buffer_put_string(m, out.value, out.length);	buffer_put_int(m, flags);	mm_request_send(sock, MONITOR_ANS_GSSSTEP, m);	gss_release_buffer(&minor, &out);	if (major==GSS_S_COMPLETE) {		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);	}	return (0);}intmm_answer_gss_checkmic(int sock, Buffer *m){	gss_buffer_desc gssbuf, mic;	OM_uint32 ret;	u_int len;	gssbuf.value = buffer_get_string(m, &len);	gssbuf.length = len;	mic.value = buffer_get_string(m, &len);	mic.length = len;	ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);	xfree(gssbuf.value);	xfree(mic.value);	buffer_clear(m);	buffer_put_int(m, ret);	mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m);	if (!GSS_ERROR(ret))		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);	return (0);}intmm_answer_gss_userok(int sock, Buffer *m){	int authenticated;	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);	buffer_clear(m);	buffer_put_int(m, authenticated);	debug3("%s: sending result %d", __func__, authenticated);	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);	auth_method="gssapi-with-mic";	/* Monitor loop will terminate if authenticated */	return (authenticated);}#endif /* GSSAPI */

⌨️ 快捷键说明

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