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

📄 clientloop.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (compat20 && session_closed && !channel_still_open())			break;		rekeying = (xxx_kex != NULL && !xxx_kex->done);		if (rekeying) {			debug("rekeying in progress");		} else {			/*			 * Make packets of buffered stdin data, and buffer			 * them for sending to the server.			 */			if (!compat20)				client_make_packets_from_stdin_data();			/*			 * Make packets from buffered channel data, and			 * enqueue them for sending to the server.			 */			if (packet_not_very_much_data_to_write())				channel_output_poll();			/*			 * Check if the window size has changed, and buffer a			 * message about it to the server if so.			 */			client_check_window_change();			if (quit_pending)				break;		}		/*		 * Wait until we have something to do (something becomes		 * available on one of the descriptors).		 */		max_fd2 = max_fd;		client_wait_until_can_do_something(&readset, &writeset,		    &max_fd2, &nalloc, rekeying);		if (quit_pending)			break;		/* Do channel operations unless rekeying in progress. */		if (!rekeying) {			channel_after_select(readset, writeset);			if (need_rekeying) {				debug("user requests rekeying");				xxx_kex->done = 0;				kex_send_kexinit(xxx_kex);				need_rekeying = 0;			}		}		/* Buffer input from the connection.  */		client_process_net_input(readset);		if (quit_pending)			break;		if (!compat20) {			/* Buffer data from stdin */			client_process_input(readset);			/*			 * Process output to stdout and stderr.  Output to			 * the connection is processed elsewhere (above).			 */			client_process_output(writeset);		}		/* Send as much buffered packet data as possible to the sender. */		if (FD_ISSET(connection_out, writeset))			packet_write_poll();	}	if (readset)		xfree(readset);	if (writeset)		xfree(writeset);	/* Terminate the session. */	/* Stop watching for window change. */	if (have_pty)		signal(SIGWINCH, SIG_DFL);	channel_free_all();	if (have_pty)		leave_raw_mode();	/* restore blocking io */	if (!isatty(fileno(stdin)))		unset_nonblock(fileno(stdin));	if (!isatty(fileno(stdout)))		unset_nonblock(fileno(stdout));	if (!isatty(fileno(stderr)))		unset_nonblock(fileno(stderr));	if (received_signal) {		if (in_non_blocking_mode)	/* XXX */			leave_non_blocking();		fatal("Killed by signal %d.", (int) received_signal);	}	/*	 * In interactive mode (with pseudo tty) display a message indicating	 * that the connection has been closed.	 */	if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {		snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);		buffer_append(&stderr_buffer, buf, strlen(buf));	}	/* Output any buffered data for stdout. */	while (buffer_len(&stdout_buffer) > 0) {		len = write(fileno(stdout), buffer_ptr(&stdout_buffer),		    buffer_len(&stdout_buffer));		if (len <= 0) {			error("Write failed flushing stdout buffer.");			break;		}		buffer_consume(&stdout_buffer, len);		stdout_bytes += len;	}	/* Output any buffered data for stderr. */	while (buffer_len(&stderr_buffer) > 0) {		len = write(fileno(stderr), buffer_ptr(&stderr_buffer),		    buffer_len(&stderr_buffer));		if (len <= 0) {			error("Write failed flushing stderr buffer.");			break;		}		buffer_consume(&stderr_buffer, len);		stderr_bytes += len;	}	/* Clear and free any buffers. */	memset(buf, 0, sizeof(buf));	buffer_free(&stdin_buffer);	buffer_free(&stdout_buffer);	buffer_free(&stderr_buffer);	/* Report bytes transferred, and transfer rates. */	total_time = get_current_time() - start_time;	debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds",	    stdin_bytes, stdout_bytes, stderr_bytes, total_time);	if (total_time > 0)		debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f",		    stdin_bytes / total_time, stdout_bytes / total_time,		    stderr_bytes / total_time);	/* Return the exit status of the program. */	debug("Exit status %d", exit_status);	return exit_status;}/*********/static voidclient_input_stdout_data(int type, u_int32_t seq, void *ctxt){	u_int data_len;	char *data = packet_get_string(&data_len);	packet_check_eom();	buffer_append(&stdout_buffer, data, data_len);	memset(data, 0, data_len);	xfree(data);}static voidclient_input_stderr_data(int type, u_int32_t seq, void *ctxt){	u_int data_len;	char *data = packet_get_string(&data_len);	packet_check_eom();	buffer_append(&stderr_buffer, data, data_len);	memset(data, 0, data_len);	xfree(data);}static voidclient_input_exit_status(int type, u_int32_t seq, void *ctxt){	exit_status = packet_get_int();	packet_check_eom();	/* Acknowledge the exit. */	packet_start(SSH_CMSG_EXIT_CONFIRMATION);	packet_send();	/*	 * Must wait for packet to be sent since we are	 * exiting the loop.	 */	packet_write_wait();	/* Flag that we want to exit. */	quit_pending = 1;}static Channel *client_request_forwarded_tcpip(const char *request_type, int rchan){	Channel* c = NULL;	char *listen_address, *originator_address;	int listen_port, originator_port;	int sock;	/* Get rest of the packet */	listen_address = packet_get_string(NULL);	listen_port = packet_get_int();	originator_address = packet_get_string(NULL);	originator_port = packet_get_int();	packet_check_eom();	debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",	    listen_address, listen_port, originator_address, originator_port);	sock = channel_connect_by_listen_address(listen_port);	if (sock < 0) {		xfree(originator_address);		xfree(listen_address);		return NULL;	}	c = channel_new("forwarded-tcpip",	    SSH_CHANNEL_CONNECTING, sock, sock, -1,	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,	    xstrdup(originator_address), 1);	xfree(originator_address);	xfree(listen_address);	return c;}static Channel*client_request_x11(const char *request_type, int rchan){	Channel *c = NULL;	char *originator;	int originator_port;	int sock;	if (!options.forward_x11) {		error("Warning: ssh server tried X11 forwarding.");		error("Warning: this is probably a break in attempt by a malicious server.");		return NULL;	}	originator = packet_get_string(NULL);	if (datafellows & SSH_BUG_X11FWD) {		debug2("buggy server: x11 request w/o originator_port");		originator_port = 0;	} else {		originator_port = packet_get_int();	}	packet_check_eom();	/* XXX check permission */	debug("client_request_x11: request from %s %d", originator,	    originator_port);	xfree(originator);	sock = x11_connect_display();	if (sock < 0)		return NULL;	c = channel_new("x11",	    SSH_CHANNEL_X11_OPEN, sock, sock, -1,	    CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,	    xstrdup("x11"), 1);	c->force_drain = 1;	return c;}static Channel*client_request_agent(const char *request_type, int rchan){	Channel *c = NULL;	int sock;	if (!options.forward_agent) {		error("Warning: ssh server tried agent forwarding.");		error("Warning: this is probably a break in attempt by a malicious server.");		return NULL;	}	sock =  ssh_get_authentication_socket();	if (sock < 0)		return NULL;	c = channel_new("authentication agent connection",	    SSH_CHANNEL_OPEN, sock, sock, -1,	    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,	    xstrdup("authentication agent connection"), 1);	c->force_drain = 1;	return c;}/* XXXX move to generic input handler */static voidclient_input_channel_open(int type, u_int32_t seq, void *ctxt){	Channel *c = NULL;	char *ctype;	u_int len;	int rchan;	int rmaxpack;	int rwindow;	ctype = packet_get_string(&len);	rchan = packet_get_int();	rwindow = packet_get_int();	rmaxpack = packet_get_int();	debug("client_input_channel_open: ctype %s rchan %d win %d max %d",	    ctype, rchan, rwindow, rmaxpack);	if (strcmp(ctype, "forwarded-tcpip") == 0) {		c = client_request_forwarded_tcpip(ctype, rchan);	} else if (strcmp(ctype, "x11") == 0) {		c = client_request_x11(ctype, rchan);	} else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {		c = client_request_agent(ctype, rchan);	}/* XXX duplicate : */	if (c != NULL) {		debug("confirm %s", ctype);		c->remote_id = rchan;		c->remote_window = rwindow;		c->remote_maxpacket = rmaxpack;		if (c->type != SSH_CHANNEL_CONNECTING) {			packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);			packet_put_int(c->remote_id);			packet_put_int(c->self);			packet_put_int(c->local_window);			packet_put_int(c->local_maxpacket);			packet_send();		}	} else {		debug("failure %s", ctype);		packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);		packet_put_int(rchan);		packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);		if (!(datafellows & SSH_BUG_OPENFAILURE)) {			packet_put_cstring("open failed");			packet_put_cstring("");		}		packet_send();	}	xfree(ctype);}static voidclient_input_channel_req(int type, u_int32_t seq, void *ctxt){	Channel *c = NULL;	int id, reply, success = 0;	char *rtype;	id = packet_get_int();	rtype = packet_get_string(NULL);	reply = packet_get_char();	debug("client_input_channel_req: channel %d rtype %s reply %d",	    id, rtype, reply);	if (session_ident == -1) {		error("client_input_channel_req: no channel %d", session_ident);	} else if (id != session_ident) {		error("client_input_channel_req: channel %d: wrong channel: %d",		    session_ident, id);	}	c = channel_lookup(id);	if (c == NULL) {		error("client_input_channel_req: channel %d: unknown channel", id);	} else if (strcmp(rtype, "exit-status") == 0) {		success = 1;		exit_status = packet_get_int();		packet_check_eom();	}	if (reply) {		packet_start(success ?		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);		packet_put_int(c->remote_id);		packet_send();	}	xfree(rtype);}static voidclient_input_global_request(int type, u_int32_t seq, void *ctxt){	char *rtype;	int want_reply;	int success = 0;	rtype = packet_get_string(NULL);	want_reply = packet_get_char();	debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply);	if (want_reply) {		packet_start(success ?		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);		packet_send();		packet_write_wait();	}	xfree(rtype);}static voidclient_init_dispatch_20(void){	dispatch_init(&dispatch_protocol_error);	dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);	dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);	dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);	dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);	dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);	dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);	dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);	dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);	dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);	dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);	/* rekeying */	dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);	/* global request reply messages */	dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);	dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);}static voidclient_init_dispatch_13(void){	dispatch_init(NULL);	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);	dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);	dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);	dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);	dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);	dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);	dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);	dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?	    &auth_input_open_request : &deny_input_open);	dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?	    &x11_input_open : &deny_input_open);}static voidclient_init_dispatch_15(void){	client_init_dispatch_13();	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);}static voidclient_init_dispatch(void){	if (compat20)		client_init_dispatch_20();	else if (compat13)		client_init_dispatch_13();	else		client_init_dispatch_15();}

⌨️ 快捷键说明

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