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

📄 serverloop.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
	int status;	/* block SIGCHLD while we check for dead children */	sigemptyset(&nset);	sigaddset(&nset, SIGCHLD);	sigprocmask(SIG_BLOCK, &nset, &oset);	if (child_terminated) {		while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||		    (pid < 0 && errno == EINTR))			if (pid > 0)				session_close_by_pid(pid, status);		child_terminated = 0;	}	sigprocmask(SIG_SETMASK, &oset, NULL);}voidserver_loop2(Authctxt *authctxt){	fd_set *readset = NULL, *writeset = NULL;	int rekeying = 0, max_fd, nalloc = 0;	debug("Entering interactive session for SSH2.");	mysignal(SIGCHLD, sigchld_handler);	child_terminated = 0;	connection_in = packet_get_connection_in();	connection_out = packet_get_connection_out();	notify_setup();	max_fd = MAX(connection_in, connection_out);	max_fd = MAX(max_fd, notify_pipe[0]);	xxx_authctxt = authctxt;	server_init_dispatch();	for (;;) {		process_buffered_input_packets();		rekeying = (xxx_kex != NULL && !xxx_kex->done);		if (!rekeying && packet_not_very_much_data_to_write())			channel_output_poll();		wait_until_can_do_something(&readset, &writeset, &max_fd,		    &nalloc, 0);		collect_children();		if (!rekeying)			channel_after_select(readset, writeset);		process_input(readset);		if (connection_closed)			break;		process_output(writeset);	}	collect_children();	if (readset)		xfree(readset);	if (writeset)		xfree(writeset);	/* free all channels, no more reads and writes */	channel_free_all();	/* free remaining sessions, e.g. remove wtmp entries */	session_destroy_all(NULL);}static voidserver_input_channel_failure(int type, u_int32_t seq, void *ctxt){	debug("Got CHANNEL_FAILURE for keepalive");	/*	 * reset timeout, since we got a sane answer from the client.	 * even if this was generated by something other than	 * the bogus CHANNEL_REQUEST we send for keepalives.	 */	client_alive_timeouts = 0;}static voidserver_input_stdin_data(int type, u_int32_t seq, void *ctxt){	char *data;	u_int data_len;	/* Stdin data from the client.  Append it to the buffer. */	/* Ignore any data if the client has closed stdin. */	if (fdin == -1)		return;	data = packet_get_string(&data_len);	packet_check_eom();	buffer_append(&stdin_buffer, data, data_len);	memset(data, 0, data_len);	xfree(data);}static voidserver_input_eof(int type, u_int32_t seq, void *ctxt){	/*	 * Eof from the client.  The stdin descriptor to the	 * program will be closed when all buffered data has	 * drained.	 */	debug("EOF received for stdin.");	packet_check_eom();	stdin_eof = 1;}static voidserver_input_window_size(int type, u_int32_t seq, void *ctxt){	int row = packet_get_int();	int col = packet_get_int();	int xpixel = packet_get_int();	int ypixel = packet_get_int();	debug("Window change received.");	packet_check_eom();	if (fdin != -1)		pty_change_window_size(fdin, row, col, xpixel, ypixel);}static Channel *server_request_direct_tcpip(char *ctype){	Channel *c;	int sock;	char *target, *originator;	int target_port, originator_port;	target = packet_get_string(NULL);	target_port = packet_get_int();	originator = packet_get_string(NULL);	originator_port = packet_get_int();	packet_check_eom();	debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",	   originator, originator_port, target, target_port);	/* XXX check permission */	sock = channel_connect_to(target, target_port);	xfree(target);	xfree(originator);	if (sock < 0)		return NULL;	c = channel_new(ctype, SSH_CHANNEL_CONNECTING,	    sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,	    CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);	return c;}static Channel *server_request_session(char *ctype){	Channel *c;	debug("input_session_request");	packet_check_eom();	/*	 * A server session has no fd to read or write until a	 * CHANNEL_REQUEST for a shell is made, so we set the type to	 * SSH_CHANNEL_LARVAL.  Additionally, a callback for handling all	 * CHANNEL_REQUEST messages is registered.	 */	c = channel_new(ctype, SSH_CHANNEL_LARVAL,	    -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,	    0, xstrdup("server-session"), 1);	if (session_open(xxx_authctxt, c->self) != 1) {		debug("session open failed, free channel %d", c->self);		channel_free(c);		return NULL;	}	channel_register_cleanup(c->self, session_close_by_channel);	return c;}static voidserver_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("server_input_channel_open: ctype %s rchan %d win %d max %d",	    ctype, rchan, rwindow, rmaxpack);	if (strcmp(ctype, "session") == 0) {		c = server_request_session(ctype);	} else if (strcmp(ctype, "direct-tcpip") == 0) {		c = server_request_direct_tcpip(ctype);	}	if (c != NULL) {		debug("server_input_channel_open: 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("server_input_channel_open: 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 voidserver_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("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);	/* -R style forwarding */	if (strcmp(rtype, "tcpip-forward") == 0) {		struct passwd *pw;		char *listen_address;		u_short listen_port;		pw = auth_get_user();		if (pw == NULL)			fatal("server_input_global_request: no user");		listen_address = packet_get_string(NULL); /* XXX currently ignored */		listen_port = (u_short)packet_get_int();		debug("server_input_global_request: tcpip-forward listen %s port %d",		    listen_address, listen_port);		/* check permissions */		if (!options.allow_tcp_forwarding ||		    no_port_forwarding_flag ||		    (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)) {			success = 0;			packet_send_debug("Server has disabled port forwarding.");		} else {			/* Start listening on the port */			success = channel_setup_remote_fwd_listener(			    listen_address, listen_port, options.gateway_ports);		}		xfree(listen_address);	}	if (want_reply) {		packet_start(success ?		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);		packet_send();		packet_write_wait();	}	xfree(rtype);}static voidserver_input_channel_req(int type, u_int32_t seq, void *ctxt){	Channel *c;	int id, reply, success = 0;	char *rtype;	id = packet_get_int();	rtype = packet_get_string(NULL);	reply = packet_get_char();	debug("server_input_channel_req: channel %d request %s reply %d",	    id, rtype, reply);	if ((c = channel_lookup(id)) == NULL)		packet_disconnect("server_input_channel_req: "		    "unknown channel %d", id);	if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN)		success = session_input_channel_req(c, rtype);	if (reply) {		packet_start(success ?		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);		packet_put_int(c->remote_id);		packet_send();	}	xfree(rtype);}static voidserver_init_dispatch_20(void){	debug("server_init_dispatch_20");	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, &server_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, &server_input_channel_req);	dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);	dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);	/* client_alive */	dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_channel_failure);	/* rekeying */	dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);}static voidserver_init_dispatch_13(void){	debug("server_init_dispatch_13");	dispatch_init(NULL);	dispatch_set(SSH_CMSG_EOF, &server_input_eof);	dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data);	dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size);	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);}static voidserver_init_dispatch_15(void){	server_init_dispatch_13();	debug("server_init_dispatch_15");	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);}static voidserver_init_dispatch(void){	if (compat20)		server_init_dispatch_20();	else if (compat13)		server_init_dispatch_13();	else		server_init_dispatch_15();}

⌨️ 快捷键说明

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