mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	merge of abac2150ee4f4031a98016241fbd136d24fed127
and ffa047425729e478a5b49b1ab0f8ec71c08a1421 --HG-- extra : convert_revision : e9b7d4eda64d70aff736f48cc8dea680b153139b
This commit is contained in:
		
						commit
						09b50641ff
					
				| @ -450,8 +450,8 @@ void recv_msg_kexinit() { | ||||
| 	/* the rest of ses.kexhashbuf will be done after DH exchange */ | ||||
| 
 | ||||
| 	ses.kexstate.recvkexinit = 1; | ||||
| //	ses.expecting = SSH_MSG_KEXDH_INIT;
 | ||||
| 	ses.expecting = 0; | ||||
| 	ses.requirenext = SSH_MSG_KEXDH_INIT; | ||||
| //	ses.expecting = 0; // client matt
 | ||||
| 
 | ||||
| 	TRACE(("leave recv_msg_kexinit")); | ||||
| } | ||||
|  | ||||
| @ -402,21 +402,6 @@ static buffer* buf_decompress(buffer* buf, unsigned int len) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* This must be called directly after receiving the unimplemented packet.
 | ||||
|  * Isn't the most clean implementation, it relies on packet processing | ||||
|  * occurring directly after decryption. This is reasonably valid, since | ||||
|  * there is only a single decryption buffer */ | ||||
| void recv_unimplemented() { | ||||
| 
 | ||||
| 	CHECKCLEARTOWRITE(); | ||||
| 
 | ||||
| 	buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED); | ||||
| 	/* the decryption routine increments the sequence number, we must
 | ||||
| 	 * decrement */ | ||||
| 	buf_putint(ses.writepayload, ses.recvseq - 1); | ||||
| 
 | ||||
| 	encrypt_packet(); | ||||
| } | ||||
| 	 | ||||
| /* encrypt the writepayload, putting into writebuf, ready for write_packet()
 | ||||
|  * to put on the wire */ | ||||
|  | ||||
| @ -76,7 +76,7 @@ void common_session_init(int sock, runopts *opts) { | ||||
| 	ses.payload = NULL; | ||||
| 	ses.recvseq = 0; | ||||
| 
 | ||||
| 	ses.expecting = SSH_MSG_KEXINIT; | ||||
| 	ses.requirenext = SSH_MSG_KEXINIT; | ||||
| 	ses.dataallowed = 0; /* don't send data yet, we'll wait until after kex */ | ||||
| 	ses.ignorenext = 0; | ||||
| 
 | ||||
| @ -106,8 +106,12 @@ void common_session_init(int sock, runopts *opts) { | ||||
| 	ses.dh_K = NULL; | ||||
| 	ses.remoteident = NULL; | ||||
| 
 | ||||
| 	ses.authdone = 0; | ||||
| 
 | ||||
| 	ses.chantypes = NULL; | ||||
| 
 | ||||
| 	ses.allowprivport = 0; | ||||
| 
 | ||||
| 
 | ||||
| 	TRACE(("leave session_init")); | ||||
| } | ||||
|  | ||||
							
								
								
									
										2
									
								
								debug.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								debug.h
									
									
									
									
									
								
							| @ -36,7 +36,7 @@ | ||||
| /* Define this to print trace statements - very verbose */ | ||||
| /* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
 | ||||
|  * since the printing does not sanitise strings etc */ | ||||
| /*#define DEBUG_TRACE*/ | ||||
| #define DEBUG_TRACE | ||||
| 
 | ||||
| /* All functions writing to the cleartext payload buffer call
 | ||||
|  * CHECKCLEARTOWRITE() before writing. This is only really useful if you're | ||||
|  | ||||
							
								
								
									
										8
									
								
								packet.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								packet.h
									
									
									
									
									
								
							| @ -32,9 +32,13 @@ void write_packet(); | ||||
| void read_packet(); | ||||
| void decrypt_packet(); | ||||
| void encrypt_packet(); | ||||
| void recv_unimplemented(); | ||||
| 
 | ||||
| void svr_process_packet(); | ||||
| void process_packet(); | ||||
| 
 | ||||
| typedef struct PacketType { | ||||
| 	unsigned char type; /* SSH_MSG_FOO */ | ||||
| 	void (*handler)(); | ||||
| } packettype; | ||||
| 
 | ||||
| #define PACKET_PADDING_OFF 4 | ||||
| #define PACKET_PAYLOAD_OFF 5 | ||||
|  | ||||
							
								
								
									
										161
									
								
								process-packet.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								process-packet.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | ||||
| /*
 | ||||
|  * Dropbear - a SSH2 server | ||||
|  *  | ||||
|  * Copyright (c) 2002-2004 Matt Johnston | ||||
|  * All rights reserved. | ||||
|  *  | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  *  | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  *  | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. */ | ||||
| 
 | ||||
| #include "includes.h" | ||||
| #include "packet.h" | ||||
| #include "session.h" | ||||
| #include "dbutil.h" | ||||
| #include "ssh.h" | ||||
| #include "algo.h" | ||||
| #include "buffer.h" | ||||
| #include "kex.h" | ||||
| #include "random.h" | ||||
| #include "service.h" | ||||
| #include "auth.h" | ||||
| #include "channel.h" | ||||
| 
 | ||||
| #define MAX_UNAUTH_PACKET_TYPE SSH_MSG_USERAUTH_PK_OK | ||||
| 
 | ||||
| static void recv_unimplemented(); | ||||
| 
 | ||||
| /* process a decrypted packet, call the appropriate handler */ | ||||
| void process_packet() { | ||||
| 
 | ||||
| 	unsigned char type; | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	TRACE(("enter process_packet")); | ||||
| 
 | ||||
| 	type = buf_getbyte(ses.payload); | ||||
| 	TRACE(("process_packet: packet type = %d", type)); | ||||
| 
 | ||||
| 	/* These packets we can receive at any time */ | ||||
| 	switch(type) { | ||||
| 
 | ||||
| 		case SSH_MSG_IGNORE: | ||||
| 		case SSH_MSG_DEBUG: | ||||
| 			TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG")); | ||||
| 			goto out; | ||||
| 
 | ||||
| 		case SSH_MSG_UNIMPLEMENTED: | ||||
| 			/* debugging XXX */ | ||||
| 			TRACE(("SSH_MSG_UNIMPLEMENTED")); | ||||
| 			dropbear_exit("received SSH_MSG_UNIMPLEMENTED"); | ||||
| 			 | ||||
| 		case SSH_MSG_DISCONNECT: | ||||
| 			/* TODO cleanup? */ | ||||
| 			dropbear_close("Disconnect received"); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	/* This applies for KEX, where the spec says the next packet MUST be
 | ||||
| 	 * NEWKEYS */ | ||||
| 	if (ses.requirenext != 0) { | ||||
| 		if (ses.requirenext != type) { | ||||
| 			/* TODO send disconnect? */ | ||||
| 			dropbear_exit("unexpected packet type %d, expected %d", type, | ||||
| 					ses.requirenext); | ||||
| 		} else { | ||||
| 			/* Got what we expected */ | ||||
| 			ses.requirenext = 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Check if we should ignore this packet. Used currently only for
 | ||||
| 	 * KEX code, with first_kex_packet_follows */ | ||||
| 	if (ses.ignorenext) { | ||||
| 		TRACE(("Ignoring packet, type = %d", type)); | ||||
| 		ses.ignorenext = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* XXX This code somewhere else perhaps? */ | ||||
| #ifdef DROPBEAR_CLIENT | ||||
| 	if (IS_DROPBEAR_CLIENT) { | ||||
| 
 | ||||
| 		/* XXX - needs changing */ | ||||
| 		/* In client mode, we REUSE ses.expecting to proceed to the 
 | ||||
| 		 *  next phase when a packet was received. | ||||
| 		 * If the "expecting" flag is set to a non-null value, it will  | ||||
| 		 *  be reset when a packet of that type is received. | ||||
| 		 * This is different from the server-mode behaviour, when  | ||||
| 		 *  a packet type mismatch would have caused sudden death. | ||||
| 		 */ | ||||
| 		  | ||||
| 		/* check that we aren't expecting a particular packet */ | ||||
| 		if (cli_ses.expecting && cli_ses.expecting == type) { | ||||
| 			cli_ses.expecting = 0; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	/* Kindly the protocol authors gave all the preauth packets type values
 | ||||
| 	 * less-than-or-equal-to 60 ( == MAX_UNAUTH_PACKET_TYPE ). | ||||
| 	 * NOTE: if the protocol changes and new types are added, revisit this  | ||||
| 	 * assumption */ | ||||
| 	if ( !ses.authdone && type > MAX_UNAUTH_PACKET_TYPE ) { | ||||
| 		dropbear_exit("received message %d before userauth", type); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; ; i++) { | ||||
| 		if (ses.packettypes[i].type == 0) { | ||||
| 			/* end of list */ | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (ses.packettypes[i].type == type) { | ||||
| 			ses.packettypes[i].handler(); | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	/* TODO do something more here? */ | ||||
| 	TRACE(("preauth unknown packet")); | ||||
| 	recv_unimplemented(); | ||||
| 
 | ||||
| out: | ||||
| 	buf_free(ses.payload); | ||||
| 	ses.payload = NULL; | ||||
| 
 | ||||
| 	TRACE(("leave process_packet")); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* This must be called directly after receiving the unimplemented packet.
 | ||||
|  * Isn't the most clean implementation, it relies on packet processing | ||||
|  * occurring directly after decryption (direct use of ses.recvseq). | ||||
|  * This is reasonably valid, since there is only a single decryption buffer */ | ||||
| static void recv_unimplemented() { | ||||
| 
 | ||||
| 	CHECKCLEARTOWRITE(); | ||||
| 
 | ||||
| 	buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED); | ||||
| 	/* the decryption routine increments the sequence number, we must
 | ||||
| 	 * decrement */ | ||||
| 	buf_putint(ses.writepayload, ses.recvseq - 1); | ||||
| 
 | ||||
| 	encrypt_packet(); | ||||
| } | ||||
							
								
								
									
										17
									
								
								session.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								session.h
									
									
									
									
									
								
							| @ -34,6 +34,7 @@ | ||||
| #include "queue.h" | ||||
| #include "runopts.h" | ||||
| #include "listener.h" | ||||
| #include "packet.h" | ||||
| 
 | ||||
| extern int sessinitdone; /* Is set to 0 somewhere */ | ||||
| extern int exitflag; | ||||
| @ -106,10 +107,13 @@ struct sshsession { | ||||
| 	unsigned int transseq, recvseq; /* Sequence IDs */ | ||||
| 
 | ||||
| 	/* Packet-handling flags */ | ||||
| 	const packettype * packettypes; /* Packet handler mappings for this
 | ||||
| 										session, see process-packet.c */ | ||||
| 
 | ||||
| 	unsigned dataallowed : 1; /* whether we can send data packets or we are in
 | ||||
| 								 the middle of a KEX or something */ | ||||
| 
 | ||||
| 	unsigned char expecting; /* byte indicating what packet we expect next, 
 | ||||
| 	unsigned char requirenext; /* byte indicating what packet we require next, 
 | ||||
| 								or 0x00 for any */ | ||||
| 
 | ||||
| 	unsigned char ignorenext; /* whether to ignore the next packet,
 | ||||
| @ -130,6 +134,12 @@ struct sshsession { | ||||
| 							 can add it to the hash when generating keys */ | ||||
| 
 | ||||
| 
 | ||||
| 	unsigned char authdone;	/* Indicates when authentication has been
 | ||||
| 							   completed. This applies to both client and | ||||
| 							   server - in the server it gets set to 1 when | ||||
| 							   authentication is successful, in the client it | ||||
| 							   is set when the server has told us that auth | ||||
| 							   succeeded */ | ||||
| 
 | ||||
| 	/* Channel related */ | ||||
| 	struct Channel ** channels; /* these pointers may be null */ | ||||
| @ -138,10 +148,13 @@ struct sshsession { | ||||
| 
 | ||||
| 	 | ||||
| 	/* TCP forwarding - where manage listeners */ | ||||
| #ifndef DISABLE_REMOTETCPFWD | ||||
| #ifdef USING_LISTENERS | ||||
| 	struct Listener ** listeners; | ||||
| 	unsigned int listensize; | ||||
| 	/* Whether to allow binding to privileged ports (<1024). This doesn't
 | ||||
| 	 * really belong here, but nowhere else fits nicely */ | ||||
| #endif | ||||
| 	int allowprivport; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										3
									
								
								ssh.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ssh.h
									
									
									
									
									
								
							| @ -44,6 +44,9 @@ | ||||
| #define SSH_MSG_USERAUTH_BANNER             53 | ||||
| #define SSH_MSG_USERAUTH_PK_OK				60 | ||||
| 
 | ||||
| /* If adding numbers here, check MAX_UNAUTH_PACKET_TYPE in process-packet.c
 | ||||
|  * is still valid */ | ||||
| 
 | ||||
| /* connect message numbers */ | ||||
| #define SSH_MSG_GLOBAL_REQUEST                  80 | ||||
| #define SSH_MSG_REQUEST_SUCCESS                 81 | ||||
|  | ||||
							
								
								
									
										10
									
								
								svr-auth.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								svr-auth.c
									
									
									
									
									
								
							| @ -52,7 +52,7 @@ void authinitialise() { | ||||
|  * on initialisation */ | ||||
| static void authclear() { | ||||
| 	 | ||||
| 	svr_ses.authstate.authdone = 0; | ||||
| 	ses.authdone = 0; | ||||
| 	svr_ses.authstate.pw = NULL; | ||||
| 	svr_ses.authstate.username = NULL; | ||||
| 	svr_ses.authstate.printableuser = NULL; | ||||
| @ -102,7 +102,7 @@ void recv_msg_userauth_request() { | ||||
| 	TRACE(("enter recv_msg_userauth_request")); | ||||
| 
 | ||||
| 	/* ignore packets if auth is already done */ | ||||
| 	if (svr_ses.authstate.authdone == 1) { | ||||
| 	if (ses.authdone == 1) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| @ -339,7 +339,11 @@ void send_msg_userauth_success() { | ||||
| 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS); | ||||
| 	encrypt_packet(); | ||||
| 
 | ||||
| 	svr_ses.authstate.authdone = 1; | ||||
| 	ses.authdone = 1; | ||||
| 
 | ||||
| 	if (svr_ses.authstate.pw->pw_uid == 0) { | ||||
| 		ses.allowprivport = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Remove from the list of pre-auth sockets. Should be m_close(), since if
 | ||||
| 	 * we fail, we might end up leaking connection slots, and disallow new | ||||
|  | ||||
| @ -57,7 +57,7 @@ void recv_msg_kexdh_init() { | ||||
| 	mp_clear(&dh_e); | ||||
| 
 | ||||
| 	send_msg_newkeys(); | ||||
| 	ses.expecting = SSH_MSG_NEWKEYS; | ||||
| 	ses.requirenext = SSH_MSG_NEWKEYS; | ||||
| 	TRACE(("leave recv_msg_kexdh_init")); | ||||
| } | ||||
| 	 | ||||
|  | ||||
							
								
								
									
										196
									
								
								svr-packet.c
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								svr-packet.c
									
									
									
									
									
								
							| @ -1,196 +0,0 @@ | ||||
| /*
 | ||||
|  * Dropbear - a SSH2 server | ||||
|  *  | ||||
|  * Copyright (c) 2002,2003 Matt Johnston | ||||
|  * All rights reserved. | ||||
|  *  | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  *  | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  *  | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. */ | ||||
| 
 | ||||
| #include "includes.h" | ||||
| #include "packet.h" | ||||
| #include "session.h" | ||||
| #include "dbutil.h" | ||||
| #include "ssh.h" | ||||
| #include "algo.h" | ||||
| #include "buffer.h" | ||||
| #include "kex.h" | ||||
| #include "random.h" | ||||
| #include "service.h" | ||||
| #include "auth.h" | ||||
| #include "channel.h" | ||||
| 
 | ||||
| static void svr_process_postauth_packet(unsigned int type); | ||||
| 
 | ||||
| /* process a decrypted packet, call the appropriate handler */ | ||||
| void svr_process_packet() { | ||||
| 
 | ||||
| 	unsigned char type; | ||||
| 
 | ||||
| 	TRACE(("enter process_packet")); | ||||
| 
 | ||||
| 	type = buf_getbyte(ses.payload); | ||||
| 	TRACE(("process_packet: packet type = %d", type)); | ||||
| 
 | ||||
| 	/* these packets we can receive at any time, regardless of expecting
 | ||||
| 	 * other packets: */ | ||||
| 	switch(type) { | ||||
| 
 | ||||
| 		case SSH_MSG_IGNORE: | ||||
| 		case SSH_MSG_DEBUG: | ||||
| 			TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG")); | ||||
| 			goto out; | ||||
| 
 | ||||
| 		case SSH_MSG_UNIMPLEMENTED: | ||||
| 			/* debugging XXX */ | ||||
| 			TRACE(("SSH_MSG_UNIMPLEMENTED")); | ||||
| 			dropbear_exit("received SSH_MSG_UNIMPLEMENTED"); | ||||
| 			 | ||||
| 		case SSH_MSG_DISCONNECT: | ||||
| 			/* TODO cleanup? */ | ||||
| 			dropbear_close("Disconnect received"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Check if we should ignore this packet. Used currently only for
 | ||||
| 	 * KEX code, with first_kex_packet_follows */ | ||||
| 	if (ses.ignorenext) { | ||||
| 		TRACE(("Ignoring packet, type = %d", type)); | ||||
| 		ses.ignorenext = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* check that we aren't expecting a particular packet */ | ||||
| 	if (ses.expecting && ses.expecting != type) { | ||||
| 		/* TODO send disconnect? */ | ||||
| 		dropbear_exit("unexpected packet type %d, expected %d", type, | ||||
| 				ses.expecting); | ||||
| 	} | ||||
| 
 | ||||
| 	/* handle the packet depending on type */ | ||||
| 	ses.expecting = 0; | ||||
| 
 | ||||
| 	switch (type) { | ||||
| 
 | ||||
| 		case SSH_MSG_SERVICE_REQUEST: | ||||
| 			recv_msg_service_request(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_USERAUTH_REQUEST: | ||||
| 			recv_msg_userauth_request(); | ||||
| 			break; | ||||
| 			 | ||||
| 		case SSH_MSG_KEXINIT: | ||||
| 			recv_msg_kexinit(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_KEXDH_INIT: | ||||
| 			recv_msg_kexdh_init(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_NEWKEYS: | ||||
| 			recv_msg_newkeys(); | ||||
| 			break; | ||||
| 
 | ||||
| 		/* this is ugly, need to make a cleaner way to do it */ | ||||
| 		case SSH_MSG_CHANNEL_DATA: | ||||
| 		case SSH_MSG_CHANNEL_WINDOW_ADJUST: | ||||
| 		case SSH_MSG_CHANNEL_REQUEST: | ||||
| 		case SSH_MSG_CHANNEL_OPEN: | ||||
| 		case SSH_MSG_CHANNEL_EOF: | ||||
| 		case SSH_MSG_CHANNEL_CLOSE: | ||||
| 		case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: | ||||
| 		case SSH_MSG_CHANNEL_OPEN_FAILURE: | ||||
| 		case SSH_MSG_GLOBAL_REQUEST: | ||||
| 			/* these should be checked for authdone below */ | ||||
| 			svr_process_postauth_packet(type); | ||||
| 			break; | ||||
| 	 | ||||
| 		default: | ||||
| 			/* TODO this possibly should be handled */ | ||||
| 			TRACE(("preauth unknown packet")); | ||||
| 			recv_unimplemented(); | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	buf_free(ses.payload); | ||||
| 	ses.payload = NULL; | ||||
| 
 | ||||
| 	TRACE(("leave process_packet")); | ||||
| } | ||||
| 
 | ||||
| /* process a packet, and also check that auth has been done */ | ||||
| static void svr_process_postauth_packet(unsigned int type) { | ||||
| 
 | ||||
| 	/* messages following here require userauth before use */ | ||||
| 
 | ||||
| 	/* IF YOU ADD MORE PACKET TYPES, MAKE SURE THEY'RE ALSO ADDED TO THE LIST
 | ||||
| 	 * IN process_packet() XXX XXX XXX */ | ||||
| 	if (!svr_ses.authstate.authdone) { | ||||
| 		dropbear_exit("received message %d before userauth", type); | ||||
| 	} | ||||
| 
 | ||||
| 	switch (type) { | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_DATA: | ||||
| 			recv_msg_channel_data(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_WINDOW_ADJUST: | ||||
| 			recv_msg_channel_window_adjust(); | ||||
| 			break; | ||||
| 
 | ||||
| #ifndef DISABLE_REMOTETCPFWD | ||||
| 		case SSH_MSG_GLOBAL_REQUEST: | ||||
| 			/* currently only used for remote tcp, so we cheat a little */ | ||||
| 			recv_msg_global_request_remotetcp(); | ||||
| 			break; | ||||
| #endif | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_REQUEST: | ||||
| 			recv_msg_channel_request(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_OPEN: | ||||
| 			recv_msg_channel_open(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_EOF: | ||||
| 			recv_msg_channel_eof(); | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSH_MSG_CHANNEL_CLOSE: | ||||
| 			recv_msg_channel_close(); | ||||
| 			break; | ||||
| 
 | ||||
| #ifdef USING_LISTENERS /* for x11, tcp fwd etc */ | ||||
| 		case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: | ||||
| 			recv_msg_channel_open_confirmation(); | ||||
| 			break; | ||||
| 			 | ||||
| 		case SSH_MSG_CHANNEL_OPEN_FAILURE: | ||||
| 			recv_msg_channel_open_failure(); | ||||
| 			break; | ||||
| #endif | ||||
| 			 | ||||
| 		default: | ||||
| 			TRACE(("unknown packet()")); | ||||
| 			recv_unimplemented(); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| @ -56,7 +56,7 @@ void recv_msg_service_request() { | ||||
| 	/* ssh-connection */ | ||||
| 	if (len == SSH_SERVICE_CONNECTION_LEN && | ||||
| 			(strncmp(SSH_SERVICE_CONNECTION, name, len) == 0)) { | ||||
| 		if (svr_ses.authstate.authdone != 1) { | ||||
| 		if (ses.authdone != 1) { | ||||
| 			dropbear_exit("request for connection before auth"); | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -36,18 +36,39 @@ | ||||
| #include "chansession.h" | ||||
| #include "atomicio.h" | ||||
| #include "tcpfwd-direct.h" | ||||
| #include "service.h" | ||||
| #include "auth.h" | ||||
| #include "tcpfwd-remote.h" | ||||
| 
 | ||||
| static void svr_remoteclosed(); | ||||
| 
 | ||||
| struct serversession svr_ses; | ||||
| 
 | ||||
| const struct ChanType *chantypes[] = { | ||||
| static const packettype svr_packettypes[] = { | ||||
| 	/* TYPE, AUTHREQUIRED, FUNCTION */ | ||||
| 	{SSH_MSG_SERVICE_REQUEST, recv_msg_service_request}, // server
 | ||||
| 	{SSH_MSG_USERAUTH_REQUEST, recv_msg_userauth_request}, //server
 | ||||
| 	{SSH_MSG_KEXINIT, recv_msg_kexinit}, | ||||
| 	{SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init}, | ||||
| 	{SSH_MSG_NEWKEYS, recv_msg_newkeys}, | ||||
| 	{SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, | ||||
| 	{SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, | ||||
| 	{SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp}, | ||||
| 	{SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request}, | ||||
| 	{SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open}, | ||||
| 	{SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof}, | ||||
| 	{SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close}, | ||||
| 	{SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, | ||||
| 	{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, | ||||
| 	{0, 0} /* End */ | ||||
| }; | ||||
| 
 | ||||
| static const struct ChanType *svr_chantypes[] = { | ||||
| 	&svrchansess, | ||||
| 	&chan_tcpdirect, | ||||
| 	NULL /* Null termination is mandatory. */ | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| void svr_session(int sock, runopts *opts, int childpipe,  | ||||
| 		struct sockaddr* remoteaddr) { | ||||
| 
 | ||||
| @ -64,7 +85,7 @@ void svr_session(int sock, runopts *opts, int childpipe, | ||||
| 	/* Initialise server specific parts of the session */ | ||||
| 	svr_ses.childpipe = childpipe; | ||||
| 	authinitialise(); | ||||
| 	chaninitialise(chantypes); | ||||
| 	chaninitialise(svr_chantypes); | ||||
| 	svr_chansessinitialise(); | ||||
| 
 | ||||
| 	if (gettimeofday(&timeout, 0) < 0) { | ||||
| @ -76,6 +97,9 @@ void svr_session(int sock, runopts *opts, int childpipe, | ||||
| 	/* set up messages etc */ | ||||
| 	session_remoteclosed = svr_remoteclosed; | ||||
| 
 | ||||
| 	/* packet handlers */ | ||||
| 	ses.packettypes = svr_packettypes; | ||||
| 
 | ||||
| 	/* We're ready to go now */ | ||||
| 	sessinitdone = 1; | ||||
| 
 | ||||
| @ -145,7 +169,7 @@ void svr_session(int sock, runopts *opts, int childpipe, | ||||
| 			/* Process the decrypted packet. After this, the read buffer
 | ||||
| 			 * will be ready for a new packet */ | ||||
| 			if (ses.payload != NULL) { | ||||
| 				svr_process_packet(); | ||||
| 				process_packet(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -208,13 +208,10 @@ static int remotetcpreq() { | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* XXX matt - server change
 | ||||
| 	if (ses.authstate.pw->pw_uid != 0 | ||||
| 			&& port < IPPORT_RESERVED) { | ||||
| 	if (!ses.allowprivport && port < IPPORT_RESERVED) { | ||||
| 		TRACE(("can't assign port < 1024 for non-root")); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	*/ | ||||
| 
 | ||||
| 	ret = listen_tcpfwd(bindaddr, port); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user