mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	Idle timeout patch from Farrell Aultman. Needs testing, unsure if server
code works --HG-- extra : convert_revision : ff66e05ae040561110af70114bf83f11ed528f05
This commit is contained in:
		
							parent
							
								
									e80f8e8c09
								
							
						
					
					
						commit
						adc4d0194f
					
				
							
								
								
									
										2
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								CHANGES
									
									
									
									
									
								
							| @ -16,7 +16,7 @@ | ||||
|   to end up at host3 via the other two, using SSH TCP forwarding. It's a bit | ||||
|   like onion-routing. All connections are established from the local machine. | ||||
|   The comma-separated syntax can also be used for scp/rsync, eg | ||||
| 	  scp -S dbclient matt@martello,root@wrt,canyons:/tmp/dump . | ||||
| 	  rsync -a -e dbclient m@gateway,m2@host,martello:/home/matt/ ~/backup/ | ||||
|   to bounce through a few hosts. | ||||
| 
 | ||||
| - Allow restrictions on authorized_keys logins such as restricting commands | ||||
|  | ||||
| @ -75,6 +75,7 @@ static void printhelp() { | ||||
| #endif | ||||
| 					"-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n" | ||||
| 					"-K <keepalive>  (0 is never, default %d)\n" | ||||
| 					"-I <idle_timeout>  (0 is never, default %d)\n" | ||||
| #ifdef ENABLE_CLI_NETCAT | ||||
| 					"-B <endhost:endport> Netcat-alike forwarding\n" | ||||
| #endif				 | ||||
| @ -85,7 +86,7 @@ static void printhelp() { | ||||
| 					"-v    verbose (compiled with DEBUG_TRACE)\n" | ||||
| #endif | ||||
| 					,DROPBEAR_VERSION, cli_opts.progname, | ||||
| 					DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE); | ||||
| 					DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT); | ||||
| 					 | ||||
| } | ||||
| 
 | ||||
| @ -110,6 +111,7 @@ void cli_getopts(int argc, char ** argv) { | ||||
| 
 | ||||
| 	char* recv_window_arg = NULL; | ||||
| 	char* keepalive_arg = NULL; | ||||
| 	char* idle_timeout_arg = NULL; | ||||
| 
 | ||||
| 	/* see printhelp() for options */ | ||||
| 	cli_opts.progname = argv[0]; | ||||
| @ -261,6 +263,9 @@ void cli_getopts(int argc, char ** argv) { | ||||
| 				case 'K': | ||||
| 					next = &keepalive_arg; | ||||
| 					break; | ||||
| 				case 'I': | ||||
| 					next = &idle_timeout_arg; | ||||
| 					break; | ||||
| #ifdef DEBUG_TRACE | ||||
| 				case 'v': | ||||
| 					debug_trace = 1; | ||||
| @ -369,6 +374,12 @@ void cli_getopts(int argc, char ** argv) { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (idle_timeout_arg) { | ||||
| 		if (m_str_to_uint(idle_timeout_arg, &opts.idle_timeout_secs) == DROPBEAR_FAILURE) { | ||||
| 			dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| #ifdef ENABLE_CLI_NETCAT | ||||
| 	if (cli_opts.cmd && cli_opts.netcat_host) { | ||||
| 		dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd); | ||||
|  | ||||
| @ -691,7 +691,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, | ||||
| 		dropbear_exit("received data after eof"); | ||||
| 	} | ||||
| 
 | ||||
|  	if (fd < 0) { | ||||
| 	if (fd < 0) { | ||||
| 		/* If we have encountered failed write, the far side might still
 | ||||
| 		 * be sending data without having yet received our close notification. | ||||
| 		 * We just drop the data. */ | ||||
|  | ||||
| @ -63,6 +63,7 @@ void common_session_init(int sock_in, int sock_out, char* remotehost) { | ||||
| 	ses.maxfd = MAX(sock_in, sock_out); | ||||
| 
 | ||||
| 	ses.connect_time = 0; | ||||
| 	ses.last_trx_packet_time = 0; | ||||
| 	ses.last_packet_time = 0; | ||||
| 	 | ||||
| 	if (pipe(ses.signal_pipe) < 0) { | ||||
| @ -258,7 +259,7 @@ void session_identification() { | ||||
| 		ses.remoteclosed(); | ||||
| 	} | ||||
| 
 | ||||
|     /* If they send more than 50 lines, something is wrong */ | ||||
| 	/* If they send more than 50 lines, something is wrong */ | ||||
| 	for (i = 0; i < 50; i++) { | ||||
| 		len = ident_readln(ses.sock_in, linebuf, sizeof(linebuf)); | ||||
| 
 | ||||
| @ -283,11 +284,11 @@ void session_identification() { | ||||
| 		memcpy(ses.remoteident, linebuf, len); | ||||
| 	} | ||||
| 
 | ||||
|     /* Shall assume that 2.x will be backwards compatible. */ | ||||
|     if (strncmp(ses.remoteident, "SSH-2.", 6) != 0 | ||||
|             && strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) { | ||||
|         dropbear_exit("Incompatible remote version '%s'", ses.remoteident); | ||||
|     } | ||||
| 	/* Shall assume that 2.x will be backwards compatible. */ | ||||
| 	if (strncmp(ses.remoteident, "SSH-2.", 6) != 0 | ||||
| 			&& strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) { | ||||
| 		dropbear_exit("Incompatible remote version '%s'", ses.remoteident); | ||||
| 	} | ||||
| 
 | ||||
| 	TRACE(("remoteident: %s", ses.remoteident)) | ||||
| 
 | ||||
| @ -399,9 +400,14 @@ static void checktimeouts() { | ||||
| 	} | ||||
| 	 | ||||
| 	if (opts.keepalive_secs > 0  | ||||
| 		&& now - ses.last_packet_time >= opts.keepalive_secs) { | ||||
| 			&& now - ses.last_trx_packet_time >= opts.keepalive_secs) { | ||||
| 		send_msg_ignore(); | ||||
| 	} | ||||
| 
 | ||||
| 	if (opts.idle_timeout_secs > 0 && ses.last_packet_time > 0 | ||||
| 			&& now - ses.last_packet_time >= opts.idle_timeout_secs) { | ||||
| 		dropbear_close("Idle timeout"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static long select_timeout() { | ||||
| @ -414,6 +420,8 @@ static long select_timeout() { | ||||
| 		ret = MIN(AUTH_TIMEOUT, ret); | ||||
| 	if (opts.keepalive_secs > 0) | ||||
| 		ret = MIN(opts.keepalive_secs, ret); | ||||
|     if (opts.idle_timeout_secs > 0) | ||||
|         ret = MIN(opts.idle_timeout_secs, ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -149,9 +149,9 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ | ||||
|  * but there's an interface via a PAM module - don't bother using it otherwise. | ||||
|  * You can't enable both PASSWORD and PAM. */ | ||||
| 
 | ||||
| #define ENABLE_SVR_PASSWORD_AUTH | ||||
| /*#define ENABLE_SVR_PASSWORD_AUTH*/ | ||||
| /* PAM requires ./configure --enable-pam */ | ||||
| /*#define ENABLE_SVR_PAM_AUTH*/ | ||||
| #define ENABLE_SVR_PAM_AUTH | ||||
| #define ENABLE_SVR_PUBKEY_AUTH | ||||
| 
 | ||||
| /* Wether to ake public key options in authorized_keys file into account */ | ||||
| @ -258,6 +258,10 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ | ||||
| be overridden at runtime with -K. 0 disables keepalives */ | ||||
| #define DEFAULT_KEEPALIVE 0 | ||||
| 
 | ||||
| /* Ensure that data is received within IDLE_TIMEOUT seconds. This can
 | ||||
| be overridden at runtime with -I. 0 disables idle timeouts */ | ||||
| #define DEFAULT_IDLE_TIMEOUT 0 | ||||
| 
 | ||||
| /* The default path. This will often get replaced by the shell */ | ||||
| #define DEFAULT_PATH "/usr/bin:/bin" | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										1
									
								
								packet.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								packet.c
									
									
									
									
									
								
							| @ -72,6 +72,7 @@ void write_packet() { | ||||
| 		} | ||||
| 	}  | ||||
| 	 | ||||
| 	ses.last_trx_packet_time = time(NULL); | ||||
| 	ses.last_packet_time = time(NULL); | ||||
| 
 | ||||
| 	if (written == 0) { | ||||
|  | ||||
| @ -70,6 +70,7 @@ void process_packet() { | ||||
| 			dropbear_close("Disconnect received"); | ||||
| 	} | ||||
| 
 | ||||
|     ses.last_packet_time = time(NULL); | ||||
| 
 | ||||
| 	/* This applies for KEX, where the spec says the next packet MUST be
 | ||||
| 	 * NEWKEYS */ | ||||
|  | ||||
| @ -38,6 +38,7 @@ typedef struct runopts { | ||||
| #endif | ||||
| 	unsigned int recv_window; | ||||
| 	unsigned int keepalive_secs; | ||||
| 	unsigned int idle_timeout_secs; | ||||
| 
 | ||||
| } runopts; | ||||
| 
 | ||||
|  | ||||
| @ -148,12 +148,16 @@ struct sshsession { | ||||
| 
 | ||||
| 	unsigned char lastpacket; /* What the last received packet type was */ | ||||
| 	 | ||||
|     int signal_pipe[2]; /* stores endpoints of a self-pipe used for
 | ||||
| 	int signal_pipe[2]; /* stores endpoints of a self-pipe used for
 | ||||
| 						   race-free signal handling */ | ||||
| 						 | ||||
| 	time_t last_packet_time; /* time of the last packet transmission, for
 | ||||
| 	time_t last_trx_packet_time; /* time of the last packet transmission, for
 | ||||
| 							keepalive purposes */ | ||||
| 
 | ||||
| 	time_t last_packet_time; /* time of the last packet transmission or receive, for
 | ||||
| 								idle timeout purposes */ | ||||
| 
 | ||||
| 
 | ||||
| 	/* KEX/encryption related */ | ||||
| 	struct KEXState kexstate; | ||||
| 	struct key_context *keys; | ||||
|  | ||||
| @ -82,6 +82,7 @@ static void printhelp(const char * progname) { | ||||
| #endif | ||||
| 					"-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n" | ||||
| 					"-K <keepalive>  (0 is never, default %d)\n" | ||||
| 					"-I <idle_timeout>  (0 is never, default %d)\n" | ||||
| #ifdef DEBUG_TRACE | ||||
| 					"-v		verbose (compiled with DEBUG_TRACE)\n" | ||||
| #endif | ||||
| @ -93,7 +94,7 @@ static void printhelp(const char * progname) { | ||||
| 					RSA_PRIV_FILENAME, | ||||
| #endif | ||||
| 					DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT, DROPBEAR_PIDFILE, | ||||
| 					DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE); | ||||
| 					DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| void svr_getopts(int argc, char ** argv) { | ||||
| @ -103,6 +104,7 @@ void svr_getopts(int argc, char ** argv) { | ||||
| 	int nextisport = 0; | ||||
| 	char* recv_window_arg = NULL; | ||||
| 	char* keepalive_arg = NULL; | ||||
| 	char* idle_timeout_arg = NULL; | ||||
| 
 | ||||
| 	/* see printhelp() for options */ | ||||
| 	svr_opts.rsakeyfile = NULL; | ||||
| @ -134,7 +136,8 @@ void svr_getopts(int argc, char ** argv) { | ||||
| 	svr_opts.usingsyslog = 1; | ||||
| #endif | ||||
| 	opts.recv_window = DEFAULT_RECV_WINDOW; | ||||
| 	opts.keepalive_secs = DEFAULT_KEEPALIVE;	 | ||||
| 	opts.keepalive_secs = DEFAULT_KEEPALIVE; | ||||
| 	opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; | ||||
| 	 | ||||
| #ifdef ENABLE_SVR_REMOTETCPFWD | ||||
| 	opts.listen_fwd_all = 0; | ||||
| @ -218,6 +221,9 @@ void svr_getopts(int argc, char ** argv) { | ||||
| 				case 'K': | ||||
| 					next = &keepalive_arg; | ||||
| 					break; | ||||
| 				case 'I': | ||||
| 					next = &idle_timeout_arg; | ||||
| 					break; | ||||
| #if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) | ||||
| 				case 's': | ||||
| 					svr_opts.noauthpass = 1; | ||||
| @ -253,7 +259,7 @@ void svr_getopts(int argc, char ** argv) { | ||||
| 		svr_opts.addresses[0] = m_strdup(DROPBEAR_DEFADDRESS); | ||||
| 		svr_opts.portcount = 1; | ||||
| 	} | ||||
|          | ||||
| 
 | ||||
| 	if (svr_opts.dsskeyfile == NULL) { | ||||
| 		svr_opts.dsskeyfile = DSS_PRIV_FILENAME; | ||||
| 	} | ||||
| @ -294,6 +300,12 @@ void svr_getopts(int argc, char ** argv) { | ||||
| 			dropbear_exit("Bad keepalive '%s'", keepalive_arg); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (idle_timeout_arg) { | ||||
| 		if (m_str_to_uint(idle_timeout_arg, &opts.idle_timeout_secs) == DROPBEAR_FAILURE) { | ||||
| 			dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void addportandaddress(char* spec) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user