View | Details | Raw Unified | Return to bug 1338
Collapse All | Expand All

(-)openssh-4.6p1-orig/clientloop.c (-9 / +2 lines)
Lines 482-488 Link Here
482
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
482
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
483
    int *maxfdp, u_int *nallocp, int rekeying)
483
    int *maxfdp, u_int *nallocp, int rekeying)
484
{
484
{
485
	struct timeval tv, *tvp;
486
	int ret;
485
	int ret;
487
486
488
	/* Add any selections by the channel mechanism. */
487
	/* Add any selections by the channel mechanism. */
Lines 532-545 Link Here
532
	 * event pending.
531
	 * event pending.
533
	 */
532
	 */
534
533
535
	if (options.server_alive_interval == 0 || !compat20)
534
	ret = packet_select((*maxfdp)+1, *readsetp, *writesetp, NULL,
536
		tvp = NULL;
535
			compat20 ? options.server_alive_interval : 0);
537
	else {
538
		tv.tv_sec = options.server_alive_interval;
539
		tv.tv_usec = 0;
540
		tvp = &tv;
541
	}
542
	ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
543
	if (ret < 0) {
536
	if (ret < 0) {
544
		char buf[100];
537
		char buf[100];
545
538
(-)openssh-4.6p1-orig/packet.c (-14 / +107 lines)
Lines 161-166 Link Here
161
};
161
};
162
TAILQ_HEAD(, packet) outgoing;
162
TAILQ_HEAD(, packet) outgoing;
163
163
164
/* Idle timeout variables */
165
static time_t idletime_last=0;
166
static int idletimeout=0;
167
168
169
void
170
packet_set_idletimeout(int max_idle_seconds) 
171
{
172
	idletimeout=max_idle_seconds;
173
	if (max_idle_seconds>0) {
174
		/* Initialize */
175
		time(&idletime_last);
176
	}
177
}
178
179
/* Called by whenever packets are sent or received.
180
 * This function decides on which packets idletimeout should
181
 * be reset */
182
void 
183
idletimeout_check(int type) 
184
{
185
        /* No-op, if idletimeouts are not configured */
186
        if (idletimeout==0) return;
187
188
	/* The following packets reset idletimeout on input or output.
189
	 * Note that only actual data resets idletimeout, control packets 
190
	 * do not. */
191
	if (compat20) {
192
	        switch(type) {
193
		case SSH2_MSG_CHANNEL_DATA:
194
		case SSH2_MSG_CHANNEL_EXTENDED_DATA:
195
		        time(&idletime_last);
196
		}
197
	} else {
198
		switch(type) {
199
		case SSH_MSG_CHANNEL_DATA:
200
		case SSH_CMSG_STDIN_DATA:
201
		case SSH_SMSG_STDOUT_DATA:
202
		case SSH_SMSG_STDERR_DATA:	
203
		        time(&idletime_last);
204
		} 
205
	}
206
}
207
208
int     
209
packet_select(int maxfds,
210
	      fd_set *readset, fd_set *writeset, fd_set *exceptset,
211
	      int max_time_milliseconds)
212
{
213
        struct timeval tv, *tvp=NULL;
214
	int ret;
215
216
	if (idletimeout>0) {
217
	        /* Count the time to idletimeout */
218
	        time_t diff=time(NULL)-idletime_last;
219
		if (diff>=idletimeout)
220
		        tv.tv_sec=1;
221
		else
222
    		        tv.tv_sec=idletimeout-diff+1;
223
		tv.tv_usec=0;
224
		tvp = &tv;
225
		debug("idletimeout after %ld seconds",tv.tv_sec);
226
	}
227
	/* If a timeout value was given and the timeout happens before
228
	 * idletimeout, use it */
229
	if (max_time_milliseconds>0 &&
230
	    (tvp==NULL || max_time_milliseconds/1000<tv.tv_sec)) {
231
	        tv.tv_sec = max_time_milliseconds / 1000;
232
		tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
233
		tvp = &tv;
234
	        debug("timeout after %d milliseconds",max_time_milliseconds);
235
	}
236
	if (tvp==NULL) debug("no timeout");
237
238
	ret = select( maxfds, readset, writeset, exceptset, tvp );
239
	if (ret<0 && errno!=EAGAIN && errno!=EINTR) {
240
	        error("select: %.100s", strerror(errno));
241
	}
242
243
	/* Disconnect on idletimeout */
244
	if (idletimeout>0 && ret==0 && 
245
	    time(NULL)-idletime_last>idletimeout) {
246
	        packet_disconnect("Idletimeout.");
247
		idletimeout=0;
248
	}
249
	return ret;
250
}
164
/*
251
/*
165
 * Sets the descriptors used for communication.  Disables encryption until
252
 * Sets the descriptors used for communication.  Disables encryption until
166
 * packet_set_encryption_key is called.
253
 * packet_set_encryption_key is called.
Lines 472-477 Link Here
472
	int len;
559
	int len;
473
560
474
	DBG(debug("packet_start[%d]", type));
561
	DBG(debug("packet_start[%d]", type));
562
563
	idletimeout_check(type);
564
475
	len = compat20 ? 6 : 9;
565
	len = compat20 ? 6 : 9;
476
	memset(buf, 0, len - 1);
566
	memset(buf, 0, len - 1);
477
	buf[len - 1] = type;
567
	buf[len - 1] = type;
Lines 833-838 Link Here
833
	cp = buffer_ptr(&outgoing_packet);
923
	cp = buffer_ptr(&outgoing_packet);
834
	type = cp[5];
924
	type = cp[5];
835
925
926
	idletimeout_check(type);
927
836
	/* during rekeying we can only send key exchange messages */
928
	/* during rekeying we can only send key exchange messages */
837
	if (rekeying) {
929
	if (rekeying) {
838
		if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
930
		if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
Lines 912-931 Link Here
912
		/* If we got a packet, return it. */
1004
		/* If we got a packet, return it. */
913
		if (type != SSH_MSG_NONE) {
1005
		if (type != SSH_MSG_NONE) {
914
			xfree(setp);
1006
			xfree(setp);
1007
			idletimeout_check(type);
915
			return type;
1008
			return type;
916
		}
1009
		}
917
		/*
1010
		/*
918
		 * Otherwise, wait for some data to arrive, add it to the
1011
		 * Otherwise, wait for some data to arrive, add it to the
919
		 * buffer, and try again.
1012
		 * buffer, and try again.
920
		 */
1013
		 */
921
		memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
1014
		do {
922
		    sizeof(fd_mask));
1015
   		        memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
923
		FD_SET(connection_in, setp);
1016
			       sizeof(fd_mask));
924
1017
		        FD_SET(connection_in, setp);
925
		/* Wait for some data to arrive. */
1018
			
926
		while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 &&
1019
			/* Wait for some data to arrive. */
927
		    (errno == EAGAIN || errno == EINTR))
1020
		} while (packet_select(connection_in + 1,
928
			;
1021
				       setp, NULL, NULL, 0) == -1);
929
1022
930
		/* Read data from the socket. */
1023
		/* Read data from the socket. */
931
		len = read(connection_in, buf, sizeof(buf));
1024
		len = read(connection_in, buf, sizeof(buf));
Lines 1446-1457 Link Here
1446
	    sizeof(fd_mask));
1539
	    sizeof(fd_mask));
1447
	packet_write_poll();
1540
	packet_write_poll();
1448
	while (packet_have_data_to_write()) {
1541
	while (packet_have_data_to_write()) {
1449
		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1542
	        do {
1450
		    sizeof(fd_mask));
1543
		        memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1451
		FD_SET(connection_out, setp);
1544
			       sizeof(fd_mask));
1452
		while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
1545
			FD_SET(connection_out, setp);
1453
		    (errno == EAGAIN || errno == EINTR))
1546
		} while (packet_select(connection_out + 1, 
1454
			;
1547
				       NULL, setp, NULL, 0) == -1);
1455
		packet_write_poll();
1548
		packet_write_poll();
1456
	}
1549
	}
1457
	xfree(setp);
1550
	xfree(setp);
(-)openssh-4.6p1-orig/packet.h (+16 lines)
Lines 103-106 Link Here
103
int	 packet_need_rekeying(void);
103
int	 packet_need_rekeying(void);
104
void	 packet_set_rekey_limit(u_int32_t);
104
void	 packet_set_rekey_limit(u_int32_t);
105
105
106
/* This sets the maximum idle time before packet_select() automatically
107
 * disconnects with packet_disconnect("Idletimeout"). 
108
 * Never autodisconnects if set to zero. zero is the default */
109
void    packet_set_idletimeout(int max_idle_seconds);
110
111
/* This is an quite normal select, except that it implements idletimeouts
112
 * set with packet_set_idletimeout().
113
 * It also returns exits, if select() returns any other error than AGAIN
114
 * or EINTR. So if packet_select returns -1, you can safely reinit fd_sets
115
 * and call packet_select again, without checking errno.
116
 */
117
int     packet_select(int maxfds,
118
		      fd_set *readset, fd_set *writeset, fd_set *exceptset,
119
		      int max_time_milliseconds);
120
121
106
#endif				/* PACKET_H */
122
#endif				/* PACKET_H */
(-)openssh-4.6p1-orig/readconf.c (-1 / +27 lines)
Lines 130-136 Link Here
130
	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
130
	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
131
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
131
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
132
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
132
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
133
	oDeprecated, oUnsupported
133
	oIdleTimeout, oDeprecated, oUnsupported
134
} OpCodes;
134
} OpCodes;
135
135
136
/* Textual representations of the tokens. */
136
/* Textual representations of the tokens. */
Lines 226-231 Link Here
226
	{ "tunneldevice", oTunnelDevice },
226
	{ "tunneldevice", oTunnelDevice },
227
	{ "localcommand", oLocalCommand },
227
	{ "localcommand", oLocalCommand },
228
	{ "permitlocalcommand", oPermitLocalCommand },
228
	{ "permitlocalcommand", oPermitLocalCommand },
229
	{ "idletimeout", oIdleTimeout },
229
	{ NULL, oBadOption }
230
	{ NULL, oBadOption }
230
};
231
};
231
232
Lines 915-920 Link Here
915
		intptr = &options->permit_local_command;
916
		intptr = &options->permit_local_command;
916
		goto parse_flag;
917
		goto parse_flag;
917
918
919
	case oIdleTimeout:
920
		arg = strdelim(&s);
921
		if (!arg || *arg == '\0')
922
			fatal("%s line %d: Missing IdleTimeout argument",
923
					filename,linenum);
924
		options->idletimeout=atoi(arg);
925
		switch(arg[strlen(arg)-1]) {
926
			case 'w': options->idletimeout*=7;
927
			case 'd': options->idletimeout*=24;
928
			case 'h': options->idletimeout*=60;
929
			case 'm': options->idletimeout*=60;
930
			case 's': 
931
			case '0': case '1': case '2': case '3': 
932
			case '4': case '5': case '6': case '7': 
933
			case '8': case '9':
934
				  break;
935
			default:
936
				  fatal("%s line %d: Invalid IdleTimeout argument",
937
						  filename,linenum);
938
		}
939
		break;
940
918
	case oDeprecated:
941
	case oDeprecated:
919
		debug("%s line %d: Deprecated option \"%s\"",
942
		debug("%s line %d: Deprecated option \"%s\"",
920
		    filename, linenum, keyword);
943
		    filename, linenum, keyword);
Lines 1065-1070 Link Here
1065
	options->tun_remote = -1;
1088
	options->tun_remote = -1;
1066
	options->local_command = NULL;
1089
	options->local_command = NULL;
1067
	options->permit_local_command = -1;
1090
	options->permit_local_command = -1;
1091
	options->idletimeout = -1;
1068
}
1092
}
1069
1093
1070
/*
1094
/*
Lines 1199-1204 Link Here
1199
		options->tun_remote = SSH_TUNID_ANY;
1223
		options->tun_remote = SSH_TUNID_ANY;
1200
	if (options->permit_local_command == -1)
1224
	if (options->permit_local_command == -1)
1201
		options->permit_local_command = 0;
1225
		options->permit_local_command = 0;
1226
	if (options->idletimeout == -1)
1227
		options->idletimeout = 0;
1202
	/* options->local_command should not be set by default */
1228
	/* options->local_command should not be set by default */
1203
	/* options->proxy_command should not be set by default */
1229
	/* options->proxy_command should not be set by default */
1204
	/* options->user will be set in the main program if appropriate */
1230
	/* options->user will be set in the main program if appropriate */
(-)openssh-4.6p1-orig/readconf.h (+6 lines)
Lines 121-126 Link Here
121
	char	*local_command;
121
	char	*local_command;
122
	int	permit_local_command;
122
	int	permit_local_command;
123
123
124
	int	idletimeout;	/*
125
				 * If nonzero, the number of seconds
126
				 * after which idle connections
127
				 * will be terminated
128
				 */
129
124
}       Options;
130
}       Options;
125
131
126
#define SSHCTL_MASTER_NO	0
132
#define SSHCTL_MASTER_NO	0
(-)openssh-4.6p1-orig/servconf.c (-1 / +27 lines)
Lines 122-127 Link Here
122
	options->permit_tun = -1;
122
	options->permit_tun = -1;
123
	options->num_permitted_opens = -1;
123
	options->num_permitted_opens = -1;
124
	options->adm_forced_command = NULL;
124
	options->adm_forced_command = NULL;
125
	options->idletimeout = -1;
125
}
126
}
126
127
127
void
128
void
Lines 262-267 Link Here
262
		options->compression = 0;
263
		options->compression = 0;
263
	}
264
	}
264
#endif
265
#endif
266
	if (options->idletimeout == -1)
267
		options->idletimeout=0;
265
268
266
}
269
}
267
270
Lines 293-299 Link Here
293
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
296
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
294
	sMatch, sPermitOpen, sForceCommand,
297
	sMatch, sPermitOpen, sForceCommand,
295
	sUsePrivilegeSeparation,
298
	sUsePrivilegeSeparation,
296
	sDeprecated, sUnsupported
299
	sIdleTimeout, sDeprecated, sUnsupported
297
} ServerOpCodes;
300
} ServerOpCodes;
298
301
299
#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
302
#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
Lines 403-408 Link Here
403
 	{ "match", sMatch, SSHCFG_ALL },
406
 	{ "match", sMatch, SSHCFG_ALL },
404
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
407
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
405
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
408
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
409
	{ "idletimeout", sIdleTimeout, SSHCFG_ALL },
406
	{ NULL, sBadOption, 0 }
410
	{ NULL, sBadOption, 0 }
407
};
411
};
408
412
Lines 1268-1273 Link Here
1268
		    arg = strdelim(&cp);
1272
		    arg = strdelim(&cp);
1269
		break;
1273
		break;
1270
1274
1275
	case sIdleTimeout:
1276
		arg = strdelim(&cp);
1277
		if (!arg || *arg == '\0')
1278
			fatal("%s line %d: Missing IdleTimeout argument",
1279
					filename,linenum);
1280
		options->idletimeout=atoi(arg);
1281
		switch(arg[strlen(arg)-1]) {
1282
			case 'w': options->idletimeout*=7;
1283
			case 'd': options->idletimeout*=24;
1284
			case 'h': options->idletimeout*=60;
1285
			case 'm': options->idletimeout*=60;
1286
			case 's': 
1287
			case '0': case '1': case '2': case '3': 
1288
			case '4': case '5': case '6': case '7': 
1289
			case '8': case '9':
1290
				  break;
1291
			default:
1292
				  fatal("%s line %d: Invalid IdleTimeout argument",
1293
						  filename,linenum);
1294
		}
1295
		break;
1296
1271
	default:
1297
	default:
1272
		fatal("%s line %d: Missing handler for opcode %s (%d)",
1298
		fatal("%s line %d: Missing handler for opcode %s (%d)",
1273
		    filename, linenum, arg, opcode);
1299
		    filename, linenum, arg, opcode);
(-)openssh-4.6p1-orig/servconf.h (+5 lines)
Lines 141-146 Link Here
141
	int	permit_tun;
141
	int	permit_tun;
142
142
143
	int	num_permitted_opens;
143
	int	num_permitted_opens;
144
	int	idletimeout;		/*
145
					 * If nonzero, the number of second
146
					 * after which idle connections
147
					 * will be terminated
148
					 */
144
}       ServerOptions;
149
}       ServerOptions;
145
150
146
void	 initialize_server_options(ServerOptions *);
151
void	 initialize_server_options(ServerOptions *);
(-)openssh-4.6p1-orig/serverloop.c (-13 / +4 lines)
Lines 277-283 Link Here
277
wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
277
wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
278
    u_int *nallocp, u_int max_time_milliseconds)
278
    u_int *nallocp, u_int max_time_milliseconds)
279
{
279
{
280
	struct timeval tv, *tvp;
281
	int ret;
280
	int ret;
282
	int client_alive_scheduled = 0;
281
	int client_alive_scheduled = 0;
283
	int program_alive_scheduled = 0;
282
	int program_alive_scheduled = 0;
Lines 348-369 Link Here
348
		if (max_time_milliseconds == 0 || client_alive_scheduled)
347
		if (max_time_milliseconds == 0 || client_alive_scheduled)
349
			max_time_milliseconds = 100;
348
			max_time_milliseconds = 100;
350
349
351
	if (max_time_milliseconds == 0)
350
	/* Wait for something to happen, or the timeout to expire. 
352
		tvp = NULL;
351
	 * packet select also implements server idletimeouts for us. */
353
	else {
352
	ret = packet_select((*maxfdp)+1, *readsetp, *writesetp, NULL, 
354
		tv.tv_sec = max_time_milliseconds / 1000;
353
			    max_time_milliseconds);
355
		tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
356
		tvp = &tv;
357
	}
358
359
	/* Wait for something to happen, or the timeout to expire. */
360
	ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
361
354
362
	if (ret == -1) {
355
	if (ret == -1) {
363
		memset(*readsetp, 0, *nallocp);
356
		memset(*readsetp, 0, *nallocp);
364
		memset(*writesetp, 0, *nallocp);
357
		memset(*writesetp, 0, *nallocp);
365
		if (errno != EINTR)
366
			error("select: %.100s", strerror(errno));
367
	} else {
358
	} else {
368
		if (ret == 0 && client_alive_scheduled)
359
		if (ret == 0 && client_alive_scheduled)
369
			client_alive_check();
360
			client_alive_check();
(-)openssh-4.6p1-orig/session.c (+2 lines)
Lines 238-243 Link Here
238
	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
238
	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
239
		channel_permit_all_opens();
239
		channel_permit_all_opens();
240
240
241
	packet_set_idletimeout(options.idletimeout);
242
241
	if (compat20)
243
	if (compat20)
242
		do_authenticated2(authctxt);
244
		do_authenticated2(authctxt);
243
	else
245
	else
(-)openssh-4.6p1-orig/ssh.c (+3 lines)
Lines 975-980 Link Here
975
	/* Initiate port forwardings. */
975
	/* Initiate port forwardings. */
976
	ssh_init_forwarding();
976
	ssh_init_forwarding();
977
977
978
	/* Start idletimeout timers before we daemonize */
979
	packet_set_idletimeout(options.idletimeout);
980
978
	/* If requested, let ssh continue in the background. */
981
	/* If requested, let ssh continue in the background. */
979
	if (fork_after_authentication_flag)
982
	if (fork_after_authentication_flag)
980
		if (daemon(1, 1) < 0)
983
		if (daemon(1, 1) < 0)
(-)openssh-4.6p1-orig/sshconnect.c (+1 lines)
Lines 973-978 Link Here
973
		ssh_userauth1(local_user, server_user, host, sensitive);
973
		ssh_userauth1(local_user, server_user, host, sensitive);
974
	}
974
	}
975
	xfree(local_user);
975
	xfree(local_user);
976
	packet_set_idletimeout(options.idletimeout);
976
}
977
}
977
978
978
void
979
void

Return to bug 1338