View | Details | Raw Unified | Return to bug 223 | Differences between
and this patch

Collapse All | Expand All

(-)ssh.c (+78 lines)
Lines 149-154 Link Here
149
/* # of replies received for global requests */
149
/* # of replies received for global requests */
150
static int client_global_request_id = 0;
150
static int client_global_request_id = 0;
151
151
152
/* pid of proxycommand child process */
153
pid_t proxy_command_pid = 0;
154
155
/* last signal sent to proxycommand child process */
156
int proxy_command_signal_level = 0;
157
152
/* Prints a help message to the user.  This function never returns. */
158
/* Prints a help message to the user.  This function never returns. */
153
159
154
static void
160
static void
Lines 244-249 Link Here
244
static int ssh_session(void);
250
static int ssh_session(void);
245
static int ssh_session2(void);
251
static int ssh_session2(void);
246
static void load_public_identity_files(void);
252
static void load_public_identity_files(void);
253
static void terminate_proxy_command(pid_t);
254
static void inc_proxy_command_signal(int);
247
255
248
/*
256
/*
249
 * Main program for the ssh client.
257
 * Main program for the ssh client.
Lines 786-791 Link Here
786
794
787
	exit_status = compat20 ? ssh_session2() : ssh_session();
795
	exit_status = compat20 ? ssh_session2() : ssh_session();
788
	packet_close();
796
	packet_close();
797
798
	/* Terminate proxy command if used */
799
	if (proxy_command_pid)
800
		terminate_proxy_command(proxy_command_pid);
801
789
	return exit_status;
802
	return exit_status;
790
}
803
}
791
804
Lines 1246-1249 Link Here
1246
		options.identity_files[i] = filename;
1259
		options.identity_files[i] = filename;
1247
		options.identity_keys[i] = public;
1260
		options.identity_keys[i] = public;
1248
	}
1261
	}
1262
}
1263
1264
static void
1265
terminate_proxy_command(pid_t pid)
1266
{
1267
	debug("Terminating ProxyCommand child process pid:%d", (int)pid);
1268
1269
	/* Try to kill proxycommand child process.
1270
	   Loop will terminate if process is killed (proxy_command_pid = 0) or
1271
	   it runs out of signals to try (proxy_command_signal_level = -1).
1272
	   The latter should never happen as it means SIGKILL didn't work.
1273
1274
	   The waitpid() will be interrupted by either the child terminating
1275
	   or SIGALRM.
1276
	 */
1277
	proxy_command_signal_level = SIGHUP;	/* try sighup first */
1278
	while (proxy_command_pid > 0 && proxy_command_signal_level > 0) {
1279
		kill(pid, proxy_command_signal_level);
1280
		debug2("Sent signal %d to ProxyCommand child process",
1281
			proxy_command_signal_level);
1282
1283
		signal(SIGALRM, inc_proxy_command_signal);
1284
		alarm(2); /* Give time to exit */
1285
		if (waitpid(pid, NULL, 0) > 0) {
1286
			debug("ProxyCommand terminated with signal %d",
1287
				proxy_command_signal_level);
1288
			proxy_command_pid = 0;
1289
		}
1290
	}
1291
1292
	if (proxy_command_signal_level == -1) {
1293
		debug("Couldn't terminate ProxyCommand pid:%d (shouldn't happen!)", (int)pid);
1294
	}
1295
}
1296
1297
static void
1298
inc_proxy_command_signal(int sigreceived)
1299
{
1300
	/* This handler increases the nastiness of the signal
1301
	   to be sent to the ProxyCommand child.
1302
	   HUP -> INT -> QUIT -> TERM -> KILL
1303
	 */
1304
	switch(proxy_command_signal_level) {
1305
	case SIGHUP:
1306
		proxy_command_signal_level = SIGINT;
1307
		break;
1308
	case SIGINT:
1309
		proxy_command_signal_level = SIGQUIT;
1310
		break;
1311
	case SIGQUIT:
1312
		proxy_command_signal_level = SIGTERM;
1313
		break;
1314
	case SIGTERM:
1315
		proxy_command_signal_level = SIGKILL;
1316
		break;
1317
	case SIGKILL:
1318
		proxy_command_signal_level = -1; /* no more to try */
1319
		break;
1320
	default:
1321
		debug("inc_proxy_command_signal: unknown signal level (%d)!",
1322
			proxy_command_signal_level);
1323
	}
1324
1325
	debug2("inc_proxy_command_signal called, signal set to %d",
1326
		proxy_command_signal_level);
1249
}
1327
}
(-)sshconnect.c (+8 lines)
Lines 38-43 Link Here
38
38
39
extern Options options;
39
extern Options options;
40
extern char *__progname;
40
extern char *__progname;
41
extern pid_t proxy_command_pid;
41
42
42
#ifndef INET6_ADDRSTRLEN		/* for non IPv6 machines */
43
#ifndef INET6_ADDRSTRLEN		/* for non IPv6 machines */
43
#define INET6_ADDRSTRLEN 46
44
#define INET6_ADDRSTRLEN 46
Lines 84-89 Link Here
84
	/* Build the final command string in the buffer by making the
85
	/* Build the final command string in the buffer by making the
85
	   appropriate substitutions to the given proxy command. */
86
	   appropriate substitutions to the given proxy command. */
86
	buffer_init(&command);
87
	buffer_init(&command);
88
89
	/* have shell exec proxy command to prevent extra sh -c processes
90
	   on some platforms (eg Solaris) */
91
	buffer_append(&command, "exec ", 5);
92
87
	for (cp = proxy_command; *cp; cp++) {
93
	for (cp = proxy_command; *cp; cp++) {
88
		if (cp[0] == '%' && cp[1] == '%') {
94
		if (cp[0] == '%' && cp[1] == '%') {
89
			buffer_append(&command, "%", 1);
95
			buffer_append(&command, "%", 1);
Lines 150-155 Link Here
150
	/* Parent. */
156
	/* Parent. */
151
	if (pid < 0)
157
	if (pid < 0)
152
		fatal("fork failed: %.100s", strerror(errno));
158
		fatal("fork failed: %.100s", strerror(errno));
159
	else
160
		proxy_command_pid = pid; /* save pid to clean up later */
153
161
154
	/* Close child side of the descriptors. */
162
	/* Close child side of the descriptors. */
155
	close(pin[0]);
163
	close(pin[0]);

Return to bug 223