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

📄 monitor.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	s->used = 0;}intmm_answer_pty(int socket, 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;	fatal_add_cleanup(session_pty_cleanup2, (void *)s);	pty_setowner(authctxt->pw, s->tty);	buffer_put_int(m, 1);	buffer_put_cstring(m, s->tty);	mm_request_send(socket, MONITOR_ANS_PTY, m);	mm_send_fd(socket, s->ptyfd);	mm_send_fd(socket, s->ttyfd);	/* 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);	/* 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(socket, MONITOR_ANS_PTY, m);	return (0);}intmm_answer_pty_cleanup(int socket, 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 socket, Buffer *m){	BIGNUM *p;	int rsafail;	/* Turn off permissions */	monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);	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(socket, MONITOR_ANS_SESSKEY, m);	/* Turn on permissions for sessid passing */	monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);	return (0);}intmm_answer_sessid(int socket, 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 socket, 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);	/* 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;		key_free(key);	}	mm_append_debug(m);	mm_request_send(socket, 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 socket, 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__);	mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);	return (0);}intmm_answer_rsa_response(int socket, 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);	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(socket, MONITOR_ANS_RSARESPONSE, m);	return (success);}intmm_answer_term(int socket, 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);}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->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;	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 */	packet_set_seqnr(MODE_OUT, buffer_get_int(&m));	packet_set_seqnr(MODE_IN, buffer_get_int(&m)); 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){	void *address;	address = mm_malloc(mm, size * ncount);	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));	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];}

⌨️ 快捷键说明

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