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

📄 packet.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
		    need, block_size, need % block_size);	/*	 * check if the entire packet has been received and	 * decrypt into incoming_packet	 */	if (buffer_len(&input) < need + maclen)		return SSH_MSG_NONE;#ifdef PACKET_DEBUG	fprintf(stderr, "read_poll enc/full: ");	buffer_dump(&input);#endif	cp = buffer_append_space(&incoming_packet, need);	cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);	buffer_consume(&input, need);	/*	 * compute MAC over seqnr and packet,	 * increment sequence number for incoming packet	 */	if (mac && mac->enabled) {		macbuf = mac_compute(mac, read_seqnr,		    buffer_ptr(&incoming_packet),		    buffer_len(&incoming_packet));		if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)			packet_disconnect("Corrupted MAC on input.");		DBG(debug("MAC #%d ok", read_seqnr));		buffer_consume(&input, mac->mac_len);	}	if (seqnr_p != NULL)		*seqnr_p = read_seqnr;	if (++read_seqnr == 0)		log("incoming seqnr wraps around");	/* get padlen */	cp = buffer_ptr(&incoming_packet);	padlen = cp[4];	DBG(debug("input: padlen %d", padlen));	if (padlen < 4)		packet_disconnect("Corrupted padlen %d on input.", padlen);	/* skip packet size + padlen, discard padding */	buffer_consume(&incoming_packet, 4 + 1);	buffer_consume_end(&incoming_packet, padlen);	DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));	if (comp && comp->enabled) {		buffer_clear(&compression_buffer);		buffer_uncompress(&incoming_packet, &compression_buffer);		buffer_clear(&incoming_packet);		buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),		    buffer_len(&compression_buffer));		DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet)));	}	/*	 * get packet type, implies consume.	 * return length of payload (without type field)	 */	type = buffer_get_char(&incoming_packet);	if (type == SSH2_MSG_NEWKEYS)		set_newkeys(MODE_IN);#ifdef PACKET_DEBUG	fprintf(stderr, "read/plain[%d]:\r\n", type);	buffer_dump(&incoming_packet);#endif	/* reset for next packet */	packet_length = 0;	return type;}intpacket_read_poll_seqnr(u_int32_t *seqnr_p){	int reason, seqnr;	u_char type;	char *msg;	for (;;) {		if (compat20) {			type = packet_read_poll2(seqnr_p);			if (type)				DBG(debug("received packet type %d", type));			switch (type) {			case SSH2_MSG_IGNORE:				break;			case SSH2_MSG_DEBUG:				packet_get_char();				msg = packet_get_string(NULL);				debug("Remote: %.900s", msg);				xfree(msg);				msg = packet_get_string(NULL);				xfree(msg);				break;			case SSH2_MSG_DISCONNECT:				reason = packet_get_int();				msg = packet_get_string(NULL);				log("Received disconnect from %s: %d: %.400s", get_remote_ipaddr(),					reason, msg);				xfree(msg);				fatal_cleanup();				break;			case SSH2_MSG_UNIMPLEMENTED:				seqnr = packet_get_int();				debug("Received SSH2_MSG_UNIMPLEMENTED for %d", seqnr);				break;			default:				return type;				break;			}		} else {			type = packet_read_poll1();			switch (type) {			case SSH_MSG_IGNORE:				break;			case SSH_MSG_DEBUG:				msg = packet_get_string(NULL);				debug("Remote: %.900s", msg);				xfree(msg);				break;			case SSH_MSG_DISCONNECT:				msg = packet_get_string(NULL);				log("Received disconnect from %s: %.400s", get_remote_ipaddr(),					msg);				fatal_cleanup();				xfree(msg);				break;			default:				if (type)					DBG(debug("received packet type %d", type));				return type;				break;			}		}	}}intpacket_read_poll(void){	return packet_read_poll_seqnr(NULL);}/* * Buffers the given amount of input characters.  This is intended to be used * together with packet_read_poll. */voidpacket_process_incoming(const char *buf, u_int len){	buffer_append(&input, buf, len);}/* Returns a character from the packet. */u_intpacket_get_char(void){	char ch;	buffer_get(&incoming_packet, &ch, 1);	return (u_char) ch;}/* Returns an integer from the packet data. */u_intpacket_get_int(void){	return buffer_get_int(&incoming_packet);}/* * Returns an arbitrary precision integer from the packet data.  The integer * must have been initialized before this call. */voidpacket_get_bignum(BIGNUM * value){	buffer_get_bignum(&incoming_packet, value);}voidpacket_get_bignum2(BIGNUM * value){	buffer_get_bignum2(&incoming_packet, value);}void *packet_get_raw(int *length_ptr){	int bytes = buffer_len(&incoming_packet);	if (length_ptr != NULL)		*length_ptr = bytes;	return buffer_ptr(&incoming_packet);}intpacket_remaining(void){	return buffer_len(&incoming_packet);}/* * Returns a string from the packet data.  The string is allocated using * xmalloc; it is the responsibility of the calling program to free it when * no longer needed.  The length_ptr argument may be NULL, or point to an * integer into which the length of the string is stored. */void *packet_get_string(u_int *length_ptr){	return buffer_get_string(&incoming_packet, length_ptr);}/* * Sends a diagnostic message from the server to the client.  This message * can be sent at any time (but not while constructing another message). The * message is printed immediately, but only if the client is being executed * in verbose mode.  These messages are primarily intended to ease debugging * authentication problems.   The length of the formatted message must not * exceed 1024 bytes.  This will automatically call packet_write_wait. */voidpacket_send_debug(const char *fmt,...){	char buf[1024];	va_list args;	if (compat20 && (datafellows & SSH_BUG_DEBUG))		return;	va_start(args, fmt);	vsnprintf(buf, sizeof(buf), fmt, args);	va_end(args);	if (compat20) {		packet_start(SSH2_MSG_DEBUG);		packet_put_char(0);	/* bool: always display */		packet_put_cstring(buf);		packet_put_cstring("");	} else {		packet_start(SSH_MSG_DEBUG);		packet_put_cstring(buf);	}	packet_send();	packet_write_wait();}/* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits.  This function never returns. The error message * should not contain a newline.  The length of the formatted message must * not exceed 1024 bytes. */voidpacket_disconnect(const char *fmt,...){	char buf[1024];	va_list args;	static int disconnecting = 0;	if (disconnecting)	/* Guard against recursive invocations. */		fatal("packet_disconnect called recursively.");	disconnecting = 1;	/*	 * Format the message.  Note that the caller must make sure the	 * message is of limited size.	 */	va_start(args, fmt);	vsnprintf(buf, sizeof(buf), fmt, args);	va_end(args);	/* Send the disconnect message to the other side, and wait for it to get sent. */	if (compat20) {		packet_start(SSH2_MSG_DISCONNECT);		packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);		packet_put_cstring(buf);		packet_put_cstring("");	} else {		packet_start(SSH_MSG_DISCONNECT);		packet_put_cstring(buf);	}	packet_send();	packet_write_wait();	/* Stop listening for connections. */	channel_close_all();	/* Close the connection. */	packet_close();	/* Display the error locally and exit. */	log("Disconnecting: %.100s", buf);	fatal_cleanup();}/* Checks if there is any buffered output, and tries to write some of the output. */voidpacket_write_poll(void){	int len = buffer_len(&output);	if (len > 0) {		len = write(connection_out, buffer_ptr(&output), len);		if (len <= 0) {			if (errno == EAGAIN)				return;			else				fatal("Write failed: %.100s", strerror(errno));		}		buffer_consume(&output, len);	}}/* * Calls packet_write_poll repeatedly until all pending output data has been * written. */voidpacket_write_wait(void){	fd_set *setp;	setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) *	    sizeof(fd_mask));	packet_write_poll();	while (packet_have_data_to_write()) {		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *		    sizeof(fd_mask));		FD_SET(connection_out, setp);		while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&		    (errno == EAGAIN || errno == EINTR))			;		packet_write_poll();	}	xfree(setp);}/* Returns true if there is buffered data to write to the connection. */intpacket_have_data_to_write(void){	return buffer_len(&output) != 0;}/* Returns true if there is not too much data to write to the connection. */intpacket_not_very_much_data_to_write(void){	if (interactive_mode)		return buffer_len(&output) < 16384;	else		return buffer_len(&output) < 128 * 1024;}/* Informs that the current session is interactive.  Sets IP flags for that. */voidpacket_set_interactive(int interactive){	static int called = 0;#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)	int lowdelay = IPTOS_LOWDELAY;	int throughput = IPTOS_THROUGHPUT;#endif	if (called)		return;	called = 1;	/* Record that we are in interactive mode. */	interactive_mode = interactive;	/* Only set socket options if using a socket.  */	if (!packet_connection_is_on_socket())		return;	/*	 * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only	 */	if (interactive) {		/*		 * Set IP options for an interactive connection.  Use		 * IPTOS_LOWDELAY and TCP_NODELAY.		 */#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)		if (packet_connection_is_ipv4()) {			if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,			    &lowdelay, sizeof(lowdelay)) < 0)				error("setsockopt IPTOS_LOWDELAY: %.100s",				    strerror(errno));		}#endif		set_nodelay(connection_in);	} else if (packet_connection_is_ipv4()) {		/*		 * Set IP options for a non-interactive connection.  Use		 * IPTOS_THROUGHPUT.		 */#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)		if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput,		    sizeof(throughput)) < 0)			error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));#endif	}}/* Returns true if the current connection is interactive. */intpacket_is_interactive(void){	return interactive_mode;}intpacket_set_maxsize(int s){	static int called = 0;	if (called) {		log("packet_set_maxsize: called twice: old %d new %d",		    max_packet_size, s);		return -1;	}	if (s < 4 * 1024 || s > 1024 * 1024) {		log("packet_set_maxsize: bad size %d", s);		return -1;	}	called = 1;	debug("packet_set_maxsize: setting to %d", s);	max_packet_size = s;	return s;}/* roundup current message to pad bytes */voidpacket_add_padding(u_char pad){	extra_pad = pad;}/* * 9.2.  Ignored Data Message * *   byte      SSH_MSG_IGNORE *   string    data * * All implementations MUST understand (and ignore) this message at any * time (after receiving the protocol version). No implementation is * required to send them. This message can be used as an additional * protection measure against advanced traffic analysis techniques. */voidpacket_send_ignore(int nbytes){	u_int32_t rand = 0;	int i;	packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);	packet_put_int(nbytes);	for (i = 0; i < nbytes; i++) {		if (i % 4 == 0)			rand = arc4random();		packet_put_char(rand & 0xff);		rand >>= 8;	}}

⌨️ 快捷键说明

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