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

📄 clientloop.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* 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 voidclient_input_agent_open(int type, u_int32_t seq, void *ctxt){	Channel *c = NULL;	int remote_id, sock;	/* Read the remote channel number from the message. */	remote_id = packet_get_int();	packet_check_eom();	/*	 * Get a connection to the local authentication agent (this may again	 * get forwarded).	 */	sock = ssh_get_authentication_socket();	/*	 * If we could not connect the agent, send an error message back to	 * the server. This should never happen unless the agent dies,	 * because authentication forwarding is only enabled if we have an	 * agent.	 */	if (sock >= 0) {		c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,		    -1, 0, 0, 0, "authentication agent connection", 1);		c->remote_id = remote_id;		c->force_drain = 1;	}	if (c == NULL) {		packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);		packet_put_int(remote_id);	} else {		/* Send a confirmation to the remote host. */		debug("Forwarding authentication connection.");		packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);		packet_put_int(remote_id);		packet_put_int(c->self);	}	packet_send();}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,	    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, "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,	    "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;	int rchan;	u_int rmaxpack, rwindow, len;	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 exitval, 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 (id == -1) {		error("client_input_channel_req: request for channel -1");	} else if ((c = channel_lookup(id)) == NULL) {		error("client_input_channel_req: channel %d: unknown channel", id);	} else if (strcmp(rtype, "exit-status") == 0) {		exitval = packet_get_int();		if (id == session_ident) {			success = 1;			exit_status = exitval;		} else if (c->ctl_fd == -1) {			error("client_input_channel_req: unexpected channel %d",			    session_ident);		} else {			atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval));			success = 1;		}		packet_check_eom();	}	if (reply) {		packet_start(success ?		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);		packet_put_int(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);}voidclient_session2_setup(int id, int want_tty, int want_subsystem,    const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env,    dispatch_fn *subsys_repl){	int len;	Channel *c = NULL;	debug2("%s: id %d", __func__, id);	if ((c = channel_lookup(id)) == NULL)		fatal("client_session2_setup: channel %d: unknown channel", id);	if (want_tty) {		struct winsize ws;		struct termios tio;		/* Store window size in the packet. */		if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)			memset(&ws, 0, sizeof(ws));		channel_request_start(id, "pty-req", 0);		packet_put_cstring(term != NULL ? term : "");		packet_put_int(ws.ws_col);		packet_put_int(ws.ws_row);		packet_put_int(ws.ws_xpixel);		packet_put_int(ws.ws_ypixel);		tio = get_saved_tio();		tty_make_modes(-1, tiop != NULL ? tiop : &tio);		packet_send();		/* XXX wait for reply */		c->client_tty = 1;	}	/* Transfer any environment variables from client to server */	if (options.num_send_env != 0 && env != NULL) {		int i, j, matched;		char *name, *val;		debug("Sending environment.");		for (i = 0; env[i] != NULL; i++) {			/* Split */			name = xstrdup(env[i]);			if ((val = strchr(name, '=')) == NULL) {				free(name);				continue;			}			*val++ = '\0';			matched = 0;			for (j = 0; j < options.num_send_env; j++) {				if (match_pattern(name, options.send_env[j])) {					matched = 1;					break;				}			}			if (!matched) {				debug3("Ignored env %s", name);				free(name);				continue;			}			debug("Sending env %s = %s", name, val);			channel_request_start(id, "env", 0);			packet_put_cstring(name);			packet_put_cstring(val);			packet_send();			free(name);		}	}	len = buffer_len(cmd);	if (len > 0) {		if (len > 900)			len = 900;		if (want_subsystem) {			debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd));			channel_request_start(id, "subsystem", subsys_repl != NULL);			if (subsys_repl != NULL) {				/* register callback for reply */				/* XXX we assume that client_loop has already been called */				dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl);				dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl);			}		} else {			debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd));			channel_request_start(id, "exec", 0);		}		packet_put_string(buffer_ptr(cmd), buffer_len(cmd));		packet_send();	} else {		channel_request_start(id, "shell", 0);		packet_send();	}}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 ?	    &client_input_agent_open : &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();}/* client specific fatal cleanup */voidcleanup_exit(int i){	leave_raw_mode();	leave_non_blocking();	if (options.control_path != NULL && control_fd != -1)		unlink(options.control_path);	_exit(i);}

⌨️ 快捷键说明

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