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

Collapse All | Expand All

(-)a/readconf.c (-1 / +8 lines)
Lines 156-162 typedef enum { Link Here
156
	oPubkeyAuthentication,
156
	oPubkeyAuthentication,
157
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
157
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
158
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
158
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
159
	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
159
	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, oBindDevice,
160
	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
160
	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
161
	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
161
	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
162
	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
162
	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
Lines 305-310 static struct { Link Here
305
	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
305
	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
306
	{ "ignoreunknown", oIgnoreUnknown },
306
	{ "ignoreunknown", oIgnoreUnknown },
307
	{ "proxyjump", oProxyJump },
307
	{ "proxyjump", oProxyJump },
308
	{ "binddevice", oBindDevice },
308
309
309
	{ NULL, oBadOption }
310
	{ NULL, oBadOption }
310
};
311
};
Lines 1669-1674 parse_keytypes: Link Here
1669
		charptr = &options->identity_agent;
1670
		charptr = &options->identity_agent;
1670
		goto parse_string;
1671
		goto parse_string;
1671
1672
1673
	case oBindDevice:
1674
		charptr = &options->bind_device;
1675
		goto parse_string;
1676
1672
	case oDeprecated:
1677
	case oDeprecated:
1673
		debug("%s line %d: Deprecated option \"%s\"",
1678
		debug("%s line %d: Deprecated option \"%s\"",
1674
		    filename, linenum, keyword);
1679
		    filename, linenum, keyword);
Lines 1869-1874 initialize_options(Options * options) Link Here
1869
	options->update_hostkeys = -1;
1874
	options->update_hostkeys = -1;
1870
	options->hostbased_key_types = NULL;
1875
	options->hostbased_key_types = NULL;
1871
	options->pubkey_key_types = NULL;
1876
	options->pubkey_key_types = NULL;
1877
	options->bind_device = NULL;
1872
}
1878
}
1873
1879
1874
/*
1880
/*
Lines 2544-2549 dump_client_config(Options *o, const char *host) Link Here
2544
	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2550
	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2545
	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2551
	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2546
	dump_cfg_string(oXAuthLocation, o->xauth_location);
2552
	dump_cfg_string(oXAuthLocation, o->xauth_location);
2553
	dump_cfg_string(oBindDevice, o->bind_device);
2547
2554
2548
	/* Forwards */
2555
	/* Forwards */
2549
	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2556
	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
(-)a/readconf.h (+2 lines)
Lines 163-168 typedef struct { Link Here
163
	int	jump_port;
163
	int	jump_port;
164
	char   *jump_extra;
164
	char   *jump_extra;
165
165
166
	char   *bind_device;	/* network device to bind to */
167
166
	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
168
	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
167
}       Options;
169
}       Options;
168
170
(-)a/servconf.c (-43 / +84 lines)
Lines 58-65 Link Here
58
#include "myproposal.h"
58
#include "myproposal.h"
59
#include "digest.h"
59
#include "digest.h"
60
60
61
static void add_listen_addr(ServerOptions *, char *, int);
61
static void add_listen_addr(ServerOptions *, char *, int, char *);
62
static void add_one_listen_addr(ServerOptions *, char *, int);
62
static void add_one_listen_addr(ServerOptions *, char *, int, char *);
63
63
64
/* Use of privilege separation or not */
64
/* Use of privilege separation or not */
65
extern int use_privsep;
65
extern int use_privsep;
Lines 79-86 initialize_server_options(ServerOptions *options) Link Here
79
	options->num_ports = 0;
79
	options->num_ports = 0;
80
	options->ports_from_cmdline = 0;
80
	options->ports_from_cmdline = 0;
81
	options->queued_listen_addrs = NULL;
81
	options->queued_listen_addrs = NULL;
82
	options->queued_listen_domains = NULL;
82
	options->num_queued_listens = 0;
83
	options->num_queued_listens = 0;
83
	options->listen_addrs = NULL;
84
	options->listen_addrs = NULL;
85
	options->num_listen_addrs = 0;
84
	options->address_family = -1;
86
	options->address_family = -1;
85
	options->num_host_key_files = 0;
87
	options->num_host_key_files = 0;
86
	options->num_host_cert_files = 0;
88
	options->num_host_cert_files = 0;
Lines 165-170 initialize_server_options(ServerOptions *options) Link Here
165
	options->fingerprint_hash = -1;
167
	options->fingerprint_hash = -1;
166
	options->disable_forwarding = -1;
168
	options->disable_forwarding = -1;
167
	options->expose_userauth_info = -1;
169
	options->expose_userauth_info = -1;
170
	options->bind_device = NULL;
168
}
171
}
169
172
170
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
173
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
Lines 217-223 fill_default_server_options(ServerOptions *options) Link Here
217
	if (options->address_family == -1)
220
	if (options->address_family == -1)
218
		options->address_family = AF_UNSPEC;
221
		options->address_family = AF_UNSPEC;
219
	if (options->listen_addrs == NULL)
222
	if (options->listen_addrs == NULL)
220
		add_listen_addr(options, NULL, 0);
223
		add_listen_addr(options, NULL, 0, NULL);
221
	if (options->pid_file == NULL)
224
	if (options->pid_file == NULL)
222
		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
225
		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
223
	if (options->login_grace_time == -1)
226
	if (options->login_grace_time == -1)
Lines 396-402 typedef enum { Link Here
396
	sKerberosGetAFSToken,
399
	sKerberosGetAFSToken,
397
	sKerberosTgtPassing, sChallengeResponseAuthentication,
400
	sKerberosTgtPassing, sChallengeResponseAuthentication,
398
	sPasswordAuthentication, sKbdInteractiveAuthentication,
401
	sPasswordAuthentication, sKbdInteractiveAuthentication,
399
	sListenAddress, sAddressFamily,
402
	sListenAddress, sAddressFamily, sBindDevice,
400
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
403
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
401
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
404
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
402
	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
405
	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
Lines 566-571 static struct { Link Here
566
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
569
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
567
	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
570
	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
568
	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
571
	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
572
	{ "binddevice", sBindDevice },
569
	{ NULL, sBadOption, 0 }
573
	{ NULL, sBadOption, 0 }
570
};
574
};
571
575
Lines 619-639 derelativise_path(const char *path) Link Here
619
}
623
}
620
624
621
static void
625
static void
622
add_listen_addr(ServerOptions *options, char *addr, int port)
626
add_listen_addr(ServerOptions *options, char *addr, int port, char *domain)
623
{
627
{
624
	u_int i;
628
	u_int i;
625
629
626
	if (port == 0)
630
	if (port == 0)
627
		for (i = 0; i < options->num_ports; i++)
631
		for (i = 0; i < options->num_ports; i++)
628
			add_one_listen_addr(options, addr, options->ports[i]);
632
			add_one_listen_addr(options, addr, options->ports[i],
633
			    domain);
629
	else
634
	else
630
		add_one_listen_addr(options, addr, port);
635
		add_one_listen_addr(options, addr, port, domain);
631
}
636
}
632
637
633
static void
638
static void
634
add_one_listen_addr(ServerOptions *options, char *addr, int port)
639
add_one_listen_addr(ServerOptions *options, char *addr, int port, char *domain)
635
{
640
{
636
	struct addrinfo hints, *ai, *aitop;
641
	struct addrinfo hints, *aitop;
637
	char strport[NI_MAXSERV];
642
	char strport[NI_MAXSERV];
638
	int gaierr;
643
	int gaierr;
639
644
Lines 646-655 add_one_listen_addr(ServerOptions *options, char *addr, int port) Link Here
646
		fatal("bad addr or host: %s (%s)",
651
		fatal("bad addr or host: %s (%s)",
647
		    addr ? addr : "<NULL>",
652
		    addr ? addr : "<NULL>",
648
		    ssh_gai_strerror(gaierr));
653
		    ssh_gai_strerror(gaierr));
649
	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
654
650
		;
655
	options->listen_addrs = xreallocarray(
651
	ai->ai_next = options->listen_addrs;
656
	    options->listen_addrs, options->num_listen_addrs + 1,
652
	options->listen_addrs = aitop;
657
	    sizeof(struct listen_address));
658
	options->listen_addrs[options->num_listen_addrs].addrs = aitop;
659
	options->listen_addrs[options->num_listen_addrs].domain =
660
	    domain ? xstrdup(domain) : NULL;
661
	options->num_listen_addrs++;
653
}
662
}
654
663
655
/*
664
/*
Lines 657-663 add_one_listen_addr(ServerOptions *options, char *addr, int port) Link Here
657
 * and AddressFamily options.
666
 * and AddressFamily options.
658
 */
667
 */
659
static void
668
static void
660
queue_listen_addr(ServerOptions *options, char *addr, int port)
669
queue_listen_addr(ServerOptions *options, char *addr, int port, char *domain)
661
{
670
{
662
	options->queued_listen_addrs = xreallocarray(
671
	options->queued_listen_addrs = xreallocarray(
663
	    options->queued_listen_addrs, options->num_queued_listens + 1,
672
	    options->queued_listen_addrs, options->num_queued_listens + 1,
Lines 665-673 queue_listen_addr(ServerOptions *options, char *addr, int port) Link Here
665
	options->queued_listen_ports = xreallocarray(
674
	options->queued_listen_ports = xreallocarray(
666
	    options->queued_listen_ports, options->num_queued_listens + 1,
675
	    options->queued_listen_ports, options->num_queued_listens + 1,
667
	    sizeof(port));
676
	    sizeof(port));
677
	options->queued_listen_domains = xreallocarray(
678
	    options->queued_listen_domains, options->num_queued_listens + 1,
679
	    sizeof(domain));
668
	options->queued_listen_addrs[options->num_queued_listens] =
680
	options->queued_listen_addrs[options->num_queued_listens] =
669
	    xstrdup(addr);
681
	    xstrdup(addr);
670
	options->queued_listen_ports[options->num_queued_listens] = port;
682
	options->queued_listen_ports[options->num_queued_listens] = port;
683
	options->queued_listen_domains[options->num_queued_listens] =
684
	    domain ? xstrdup(domain) : NULL;
671
	options->num_queued_listens++;
685
	options->num_queued_listens++;
672
}
686
}
673
687
Lines 686-699 process_queued_listen_addrs(ServerOptions *options) Link Here
686
700
687
	for (i = 0; i < options->num_queued_listens; i++) {
701
	for (i = 0; i < options->num_queued_listens; i++) {
688
		add_listen_addr(options, options->queued_listen_addrs[i],
702
		add_listen_addr(options, options->queued_listen_addrs[i],
689
		    options->queued_listen_ports[i]);
703
		    options->queued_listen_ports[i],
704
		    options->queued_listen_domains[i]);
690
		free(options->queued_listen_addrs[i]);
705
		free(options->queued_listen_addrs[i]);
691
		options->queued_listen_addrs[i] = NULL;
706
		options->queued_listen_addrs[i] = NULL;
707
		free(options->queued_listen_domains[i]);
708
		options->queued_listen_domains[i] = NULL;
692
	}
709
	}
693
	free(options->queued_listen_addrs);
710
	free(options->queued_listen_addrs);
694
	options->queued_listen_addrs = NULL;
711
	options->queued_listen_addrs = NULL;
695
	free(options->queued_listen_ports);
712
	free(options->queued_listen_ports);
696
	options->queued_listen_ports = NULL;
713
	options->queued_listen_ports = NULL;
714
	free(options->queued_listen_domains);
715
	options->queued_listen_domains = NULL;
697
	options->num_queued_listens = 0;
716
	options->num_queued_listens = 0;
698
}
717
}
699
718
Lines 992-998 process_server_config_line(ServerOptions *options, char *line, Link Here
992
    const char *filename, int linenum, int *activep,
1011
    const char *filename, int linenum, int *activep,
993
    struct connection_info *connectinfo)
1012
    struct connection_info *connectinfo)
994
{
1013
{
995
	char *cp, **charptr, *arg, *arg2, *p;
1014
	char *cp, **charptr, *arg, *arg2, *p, *domain;
996
	int cmdline = 0, *intptr, value, value2, n, port;
1015
	int cmdline = 0, *intptr, value, value2, n, port;
997
	SyslogFacility *log_facility_ptr;
1016
	SyslogFacility *log_facility_ptr;
998
	LogLevel *log_level_ptr;
1017
	LogLevel *log_level_ptr;
Lines 1088-1095 process_server_config_line(ServerOptions *options, char *line, Link Here
1088
		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1107
		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1089
		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1108
		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1090
		    && strchr(p+1, ':') != NULL) {
1109
		    && strchr(p+1, ':') != NULL) {
1091
			queue_listen_addr(options, arg, 0);
1110
			port = 0;
1092
			break;
1111
			p = arg;
1112
			goto parse_domain;
1093
		}
1113
		}
1094
		p = hpdelim(&arg);
1114
		p = hpdelim(&arg);
1095
		if (p == NULL)
1115
		if (p == NULL)
Lines 1101-1107 process_server_config_line(ServerOptions *options, char *line, Link Here
1101
		else if ((port = a2port(arg)) <= 0)
1121
		else if ((port = a2port(arg)) <= 0)
1102
			fatal("%s line %d: bad port number", filename, linenum);
1122
			fatal("%s line %d: bad port number", filename, linenum);
1103
1123
1104
		queue_listen_addr(options, p, port);
1124
 parse_domain:
1125
		domain = NULL;
1126
		arg = strdelim(&cp);
1127
		if (arg && !strcmp(arg, "domain")) {
1128
			arg = strdelim(&cp);
1129
			if (arg != NULL && *arg != '\0')
1130
				domain = arg;
1131
		}
1132
1133
		queue_listen_addr(options, p, port, domain);
1105
1134
1106
		break;
1135
		break;
1107
1136
Lines 1879-1884 process_server_config_line(ServerOptions *options, char *line, Link Here
1879
			options->fingerprint_hash = value;
1908
			options->fingerprint_hash = value;
1880
		break;
1909
		break;
1881
1910
1911
	case sBindDevice:
1912
		arg = strdelim(&cp);
1913
		if (!arg || *arg == '\0')
1914
			fatal("%s line %d: Missing argument.", filename, linenum);
1915
		if (options->bind_device == NULL)
1916
			options->bind_device = xstrdup(arg);
1917
		break;
1918
1882
	case sExposeAuthInfo:
1919
	case sExposeAuthInfo:
1883
		intptr = &options->expose_userauth_info;
1920
		intptr = &options->expose_userauth_info;
1884
		goto parse_flag;
1921
		goto parse_flag;
Lines 2238-2275 dump_config(ServerOptions *o) Link Here
2238
	int ret;
2275
	int ret;
2239
	struct addrinfo *ai;
2276
	struct addrinfo *ai;
2240
	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
2277
	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
2241
	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2278
	char *laddr = xstrdup("");
2242
2279
2243
	/* these are usually at the top of the config */
2280
	/* these are usually at the top of the config */
2244
	for (i = 0; i < o->num_ports; i++)
2281
	for (i = 0; i < o->num_ports; i++)
2245
		printf("port %d\n", o->ports[i]);
2282
		printf("port %d\n", o->ports[i]);
2246
	dump_cfg_fmtint(sAddressFamily, o->address_family);
2283
	dump_cfg_fmtint(sAddressFamily, o->address_family);
2247
2284
2248
	/*
2285
	/* ListenAddress must be after Port. */
2249
	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2286
	for (i = 0; i < o->num_listen_addrs; i++) {
2250
	 * addresses onto a stack, so to maintain ordering we need to
2287
		for (ai = o->listen_addrs[i].addrs; ai; ai = ai->ai_next) {
2251
	 * print these in reverse order.
2288
			if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2252
	 */
2289
			    sizeof(addr), port, sizeof(port),
2253
	for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
2290
			    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2254
		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2291
				error("getnameinfo failed: %.100s",
2255
		    sizeof(addr), port, sizeof(port),
2292
				    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
2256
		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2293
				    strerror(errno));
2257
			error("getnameinfo failed: %.100s",
2294
			} else {
2258
			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
2295
				if (ai->ai_family == AF_INET6)
2259
			    strerror(errno));
2296
					xasprintf(&laddr,
2260
		} else {
2297
					    "%slistenaddress [%s]:%s", laddr,
2261
			laddr2 = laddr1;
2298
					    addr, port);
2262
			if (ai->ai_family == AF_INET6)
2299
				else
2263
				xasprintf(&laddr1, "listenaddress [%s]:%s\n%s",
2300
					xasprintf(&laddr,
2264
				    addr, port, laddr2);
2301
					    "%slistenaddress %s:%s", laddr,
2265
			else
2302
					    addr, port);
2266
				xasprintf(&laddr1, "listenaddress %s:%s\n%s",
2303
				if (o->listen_addrs[i].domain)
2267
				    addr, port, laddr2);
2304
					xasprintf(&laddr, "%s domain %s\n",
2268
			free(laddr2);
2305
					    laddr, o->listen_addrs[i].domain);
2306
				else
2307
					xasprintf(&laddr, "%s\n", laddr);
2308
			}
2269
		}
2309
		}
2270
	}
2310
	}
2271
	printf("%s", laddr1);
2311
	printf("%s", laddr);
2272
	free(laddr1);
2312
	free(laddr);
2273
2313
2274
	/* integer arguments */
2314
	/* integer arguments */
2275
#ifdef USE_PAM
2315
#ifdef USE_PAM
Lines 2358-2363 dump_config(ServerOptions *o) Link Here
2358
	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2398
	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2359
	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2399
	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2360
	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2400
	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2401
	dump_cfg_string(sBindDevice, o->bind_device);
2361
2402
2362
	/* string arguments requiring a lookup */
2403
	/* string arguments requiring a lookup */
2363
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2404
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)a/servconf.h (-1 / +14 lines)
Lines 68-74 typedef struct { Link Here
68
	u_int	num_queued_listens;
68
	u_int	num_queued_listens;
69
	char   **queued_listen_addrs;
69
	char   **queued_listen_addrs;
70
	int    *queued_listen_ports;
70
	int    *queued_listen_ports;
71
	struct addrinfo *listen_addrs;	/* Addresses on which the server listens. */
71
	char   **queued_listen_domains;
72
	struct listen_address *listen_addrs; /* Addresses on which the server listens. */
73
	u_int	num_listen_addrs;
72
	int     address_family;		/* Address family used by the server. */
74
	int     address_family;		/* Address family used by the server. */
73
	char   *host_key_files[MAX_HOSTKEYS];	/* Files containing host keys. */
75
	char   *host_key_files[MAX_HOSTKEYS];	/* Files containing host keys. */
74
	int     num_host_key_files;     /* Number of files for host keys. */
76
	int     num_host_key_files;     /* Number of files for host keys. */
Lines 198-203 typedef struct { Link Here
198
200
199
	int	fingerprint_hash;
201
	int	fingerprint_hash;
200
	int	expose_userauth_info;
202
	int	expose_userauth_info;
203
204
	char   *bind_device;	/* network device to bind to */
201
}       ServerOptions;
205
}       ServerOptions;
202
206
203
/* Information about the incoming connection as used by Match */
207
/* Information about the incoming connection as used by Match */
Lines 209-214 struct connection_info { Link Here
209
	int lport;		/* local port */
213
	int lport;		/* local port */
210
};
214
};
211
215
216
/*
217
 * Each hostname might have multiple addresses, but they are all tied to
218
 * the same domain (VRF). This struct helps keeping them associated.
219
 */
220
struct listen_address {
221
	struct addrinfo *addrs;
222
	char *domain;
223
};
224
212
225
213
/*
226
/*
214
 * These are string config options that must be copied between the
227
 * These are string config options that must be copied between the
(-)a/ssh.1 (+8 lines)
Lines 45-50 Link Here
45
.Bk -words
45
.Bk -words
46
.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
46
.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
47
.Op Fl b Ar bind_address
47
.Op Fl b Ar bind_address
48
.Op Fl B Ar bind_device
48
.Op Fl c Ar cipher_spec
49
.Op Fl c Ar cipher_spec
49
.Op Fl D Oo Ar bind_address : Oc Ns Ar port
50
.Op Fl D Oo Ar bind_address : Oc Ns Ar port
50
.Op Fl E Ar log_file
51
.Op Fl E Ar log_file
Lines 128-133 on the local machine as the source address Link Here
128
of the connection.
129
of the connection.
129
Only useful on systems with more than one address.
130
Only useful on systems with more than one address.
130
.Pp
131
.Pp
132
.It Fl B Ar bind_device
133
Bind the connecting socket to
134
.Ar bind_device
135
on the local machine.
136
Useful on systems that use
137
.Cm VRF .
138
.Pp
131
.It Fl C
139
.It Fl C
132
Requests compression of all data (including stdin, stdout, stderr, and
140
Requests compression of all data (including stdin, stdout, stderr, and
133
data for forwarded X11, TCP and
141
data for forwarded X11, TCP and
(-)a/ssh.c (-2 / +5 lines)
Lines 197-203 static void Link Here
197
usage(void)
197
usage(void)
198
{
198
{
199
	fprintf(stderr,
199
	fprintf(stderr,
200
"usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
200
"usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-B bind_device] [-c cipher_spec]\n"
201
"           [-D [bind_address:]port] [-E log_file] [-e escape_char]\n"
201
"           [-D [bind_address:]port] [-E log_file] [-e escape_char]\n"
202
"           [-F configfile] [-I pkcs11] [-i identity_file]\n"
202
"           [-F configfile] [-I pkcs11] [-i identity_file]\n"
203
"           [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n"
203
"           [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n"
Lines 612-618 main(int ac, char **av) Link Here
612
612
613
 again:
613
 again:
614
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
614
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
615
	    "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
615
	    "AB:CD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
616
		switch (opt) {
616
		switch (opt) {
617
		case '1':
617
		case '1':
618
			fatal("SSH protocol v.1 is no longer supported");
618
			fatal("SSH protocol v.1 is no longer supported");
Lines 918-923 main(int ac, char **av) Link Here
918
		case 'b':
918
		case 'b':
919
			options.bind_address = optarg;
919
			options.bind_address = optarg;
920
			break;
920
			break;
921
		case 'B':
922
			options.bind_device = optarg;
923
			break;
921
		case 'F':
924
		case 'F':
922
			config = optarg;
925
			config = optarg;
923
			break;
926
			break;
(-)a/ssh_config.5 (+4 lines)
Lines 262-267 Note that this option does not work if Link Here
262
.Cm UsePrivilegedPort
262
.Cm UsePrivilegedPort
263
is set to
263
is set to
264
.Cm yes .
264
.Cm yes .
265
.It Cm BindDevice
266
Bind the connecting socket to the specified device on the local machine.
267
Useful on systems that use
268
.Cm VRF .
265
.It Cm CanonicalDomains
269
.It Cm CanonicalDomains
266
When
270
When
267
.Cm CanonicalizeHostname
271
.Cm CanonicalizeHostname
(-)a/sshconnect.c (+20 lines)
Lines 286-291 ssh_create_socket(int privileged, struct addrinfo *ai) Link Here
286
	}
286
	}
287
	fcntl(sock, F_SETFD, FD_CLOEXEC);
287
	fcntl(sock, F_SETFD, FD_CLOEXEC);
288
288
289
	if (options.bind_device != NULL) {
290
#ifdef SO_BINDTODEVICE
291
		r = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
292
		    options.bind_device, strlen(options.bind_device));
293
		if (r != 0) {
294
			error("Bind to: %s failed %s", options.bind_device,
295
			    strerror(errno));
296
			close(sock);
297
			return -1;
298
		}
299
		debug("Bound to device: %s", options.bind_device);
300
#else
301
		error("No SO_BINDTODEVICE, unable to bind to: %s",
302
		    options.bind_device);
303
		close(sock);
304
		return -1;
305
#endif
306
	}
307
308
289
	/* Bind the socket to an alternative local IP address */
309
	/* Bind the socket to an alternative local IP address */
290
	if (options.bind_address == NULL && !privileged)
310
	if (options.bind_address == NULL && !privileged)
291
		return sock;
311
		return sock;
(-)a/sshd.8 (+11 lines)
Lines 44-49 Link Here
44
.Nm sshd
44
.Nm sshd
45
.Bk -words
45
.Bk -words
46
.Op Fl 46DdeiqTt
46
.Op Fl 46DdeiqTt
47
.Op Fl B Ar bind_device
47
.Op Fl C Ar connection_spec
48
.Op Fl C Ar connection_spec
48
.Op Fl c Ar host_certificate_file
49
.Op Fl c Ar host_certificate_file
49
.Op Fl E Ar log_file
50
.Op Fl E Ar log_file
Lines 94-99 to use IPv4 addresses only. Link Here
94
Forces
95
Forces
95
.Nm
96
.Nm
96
to use IPv6 addresses only.
97
to use IPv6 addresses only.
98
.It Fl B Ar bind_device
99
Bind the listening sockets to
100
.Ar bind_device
101
on the local machine.
102
Useful on systems that use
103
.Cm VRF .
104
.Pp
105
Note that a domain specified on the
106
.Cm ListenAddress
107
line will have the priority.
97
.It Fl C Ar connection_spec
108
.It Fl C Ar connection_spec
98
Specify the connection parameters to use for the
109
Specify the connection parameters to use for the
99
.Fl T
110
.Fl T
(-)a/sshd.c (-59 / +108 lines)
Lines 908-914 usage(void) Link Here
908
#endif
908
#endif
909
	);
909
	);
910
	fprintf(stderr,
910
	fprintf(stderr,
911
"usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n"
911
"usage: sshd [-46DdeiqTt] [-B bind_device] [-C connection_spec] [-c host_cert_file]\n"
912
"            [-E log_file] [-f config_file] [-g login_grace_time]\n"
912
"            [-E log_file] [-f config_file] [-g login_grace_time]\n"
913
"            [-h host_key_file] [-o option] [-p port] [-u len]\n"
913
"            [-h host_key_file] [-o option] [-p port] [-u len]\n"
914
	);
914
	);
Lines 1016-1086 server_accept_inetd(int *sock_in, int *sock_out) Link Here
1016
static void
1016
static void
1017
server_listen(void)
1017
server_listen(void)
1018
{
1018
{
1019
	u_int i;
1019
	int ret, listen_sock, on = 1;
1020
	int ret, listen_sock, on = 1;
1020
	struct addrinfo *ai;
1021
	struct addrinfo *ai;
1021
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1022
	char ntop[NI_MAXHOST], strport[NI_MAXSERV], *domain;
1022
1023
1023
	for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
1024
	for (i = 0; i < options.num_listen_addrs; i++) {
1024
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1025
		for (ai = options.listen_addrs[i].addrs; ai; ai = ai->ai_next) {
1025
			continue;
1026
			if (ai->ai_family != AF_INET &&
1026
		if (num_listen_socks >= MAX_LISTEN_SOCKS)
1027
			    ai->ai_family != AF_INET6)
1027
			fatal("Too many listen sockets. "
1028
				continue;
1028
			    "Enlarge MAX_LISTEN_SOCKS");
1029
			if (num_listen_socks >= MAX_LISTEN_SOCKS)
1029
		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
1030
				fatal("Too many listen sockets. "
1030
		    ntop, sizeof(ntop), strport, sizeof(strport),
1031
				    "Enlarge MAX_LISTEN_SOCKS");
1031
		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1032
			if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
1032
			error("getnameinfo failed: %.100s",
1033
			    ntop, sizeof(ntop), strport, sizeof(strport),
1033
			    ssh_gai_strerror(ret));
1034
			    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1034
			continue;
1035
				error("getnameinfo failed: %.100s",
1035
		}
1036
				    ssh_gai_strerror(ret));
1036
		/* Create socket for listening. */
1037
				continue;
1037
		listen_sock = socket(ai->ai_family, ai->ai_socktype,
1038
			}
1038
		    ai->ai_protocol);
1039
			/* Create socket for listening. */
1039
		if (listen_sock < 0) {
1040
			listen_sock = socket(ai->ai_family, ai->ai_socktype,
1040
			/* kernel may not support ipv6 */
1041
			    ai->ai_protocol);
1041
			verbose("socket: %.100s", strerror(errno));
1042
			if (listen_sock < 0) {
1042
			continue;
1043
				/* kernel may not support ipv6 */
1043
		}
1044
				verbose("socket: %.100s", strerror(errno));
1044
		if (set_nonblock(listen_sock) == -1) {
1045
				continue;
1045
			close(listen_sock);
1046
			}
1046
			continue;
1047
			if (set_nonblock(listen_sock) == -1) {
1047
		}
1048
				close(listen_sock);
1048
		if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) {
1049
				continue;
1049
			verbose("socket: CLOEXEC: %s", strerror(errno));
1050
			}
1050
			close(listen_sock);
1051
			if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) {
1051
			continue;
1052
				verbose("socket: CLOEXEC: %s",
1052
		}
1053
				    strerror(errno));
1053
		/*
1054
				close(listen_sock);
1054
		 * Set socket options.
1055
				continue;
1055
		 * Allow local port reuse in TIME_WAIT.
1056
			}
1056
		 */
1057
			/*
1057
		if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
1058
			 * Set socket options.
1058
		    &on, sizeof(on)) == -1)
1059
			 * Allow local port reuse in TIME_WAIT.
1059
			error("setsockopt SO_REUSEADDR: %s", strerror(errno));
1060
			 */
1061
			if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
1062
			    &on, sizeof(on)) == -1)
1063
				error("setsockopt SO_REUSEADDR: %s",
1064
				    strerror(errno));
1060
1065
1061
		/* Only communicate in IPv6 over AF_INET6 sockets. */
1066
			/* Only communicate in IPv6 over AF_INET6 sockets. */
1062
		if (ai->ai_family == AF_INET6)
1067
			if (ai->ai_family == AF_INET6)
1063
			sock_set_v6only(listen_sock);
1068
				sock_set_v6only(listen_sock);
1064
1069
1065
		debug("Bind to port %s on %s.", strport, ntop);
1070
			/* Fallback to global domain if available. */
1071
			if (options.listen_addrs[i].domain != NULL &&
1072
			    strlen(options.listen_addrs[i].domain) > 0)
1073
				domain = options.listen_addrs[i].domain;
1074
			else if (options.bind_device != NULL &&
1075
			    strlen(options.bind_device) > 0)
1076
				domain = options.bind_device;
1077
			else
1078
				domain = NULL;
1066
1079
1067
		/* Bind the socket to the desired port. */
1080
			if (domain) {
1068
		if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1081
#ifdef SO_BINDTODEVICE
1069
			error("Bind to port %s on %s failed: %.200s.",
1082
				ret = setsockopt(listen_sock, SOL_SOCKET,
1070
			    strport, ntop, strerror(errno));
1083
				    SO_BINDTODEVICE, domain, strlen(domain));
1071
			close(listen_sock);
1084
				if (ret != 0) {
1072
			continue;
1085
					error("Bind to: %s failed: %s",
1073
		}
1086
					    domain, strerror(errno));
1074
		listen_socks[num_listen_socks] = listen_sock;
1087
					close(listen_sock);
1075
		num_listen_socks++;
1088
					continue;
1089
				}
1090
				debug("Bind to device %s", domain);
1091
#else
1092
				error("No SO_BINDTODEVICE, unable to bind to: %s",
1093
				    domain);
1094
				close(listen_sock);
1095
				continue;
1096
#endif
1097
			}
1098
1099
			debug("Bind to port %s on %s.", strport, ntop);
1076
1100
1077
		/* Start listening on the port. */
1101
			/* Bind the socket to the desired port. */
1078
		if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1102
			if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1079
			fatal("listen on [%s]:%s: %.100s",
1103
				error("Bind to port %s on %s failed: %.200s.",
1080
			    ntop, strport, strerror(errno));
1104
				    strport, ntop, strerror(errno));
1081
		logit("Server listening on %s port %s.", ntop, strport);
1105
				close(listen_sock);
1106
				continue;
1107
			}
1108
			listen_socks[num_listen_socks] = listen_sock;
1109
			num_listen_socks++;
1110
1111
			/* Start listening on the port. */
1112
			if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1113
				fatal("listen on [%s]:%s: %.100s",
1114
				    ntop, strport, strerror(errno));
1115
			if (!domain) {
1116
				logit("Server listening on %s port %s.", ntop,
1117
				    strport);
1118
			} else {
1119
				logit("Server listening on %s port %s domain %s.",
1120
				    ntop, strport, domain);
1121
			}
1122
		}
1123
		freeaddrinfo(options.listen_addrs[i].addrs);
1124
		free(options.listen_addrs[i].domain);
1125
		options.listen_addrs[i].domain = NULL;
1082
	}
1126
	}
1083
	freeaddrinfo(options.listen_addrs);
1127
	free(options.listen_addrs);
1128
	options.listen_addrs = NULL;
1129
	options.num_listen_addrs = 0;
1084
1130
1085
	if (!num_listen_socks)
1131
	if (!num_listen_socks)
1086
		fatal("Cannot bind any address.");
1132
		fatal("Cannot bind any address.");
Lines 1404-1410 main(int ac, char **av) Link Here
1404
1450
1405
	/* Parse command-line arguments. */
1451
	/* Parse command-line arguments. */
1406
	while ((opt = getopt(ac, av,
1452
	while ((opt = getopt(ac, av,
1407
	    "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) {
1453
	    "C:E:b:c:B:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) {
1408
		switch (opt) {
1454
		switch (opt) {
1409
		case '4':
1455
		case '4':
1410
			options.address_family = AF_INET;
1456
			options.address_family = AF_INET;
Lines 1512-1517 main(int ac, char **av) Link Here
1512
				exit(1);
1558
				exit(1);
1513
			free(line);
1559
			free(line);
1514
			break;
1560
			break;
1561
		case 'B':
1562
			options.bind_device = optarg;
1563
			break;
1515
		case '?':
1564
		case '?':
1516
		default:
1565
		default:
1517
			usage();
1566
			usage();
(-)a/sshd_config.5 (-1 / +19 lines)
Lines 380-385 If the argument is Link Here
380
.Cm none
380
.Cm none
381
then no banner is displayed.
381
then no banner is displayed.
382
By default, no banner is displayed.
382
By default, no banner is displayed.
383
.It Cm BindDevice
384
Bind the listening sockets to the specified device on the local machine.
385
Useful on systems that use
386
.Cm VRF .
387
.Pp
388
Note that a domain specified on the
389
.Cm ListenAddress
390
line will have the priority.
383
.It Cm ChallengeResponseAuthentication
391
.It Cm ChallengeResponseAuthentication
384
Specifies whether challenge-response authentication is allowed (e.g. via
392
Specifies whether challenge-response authentication is allowed (e.g. via
385
PAM or through authentication styles supported in
393
PAM or through authentication styles supported in
Lines 921-926 The following forms may be used: Link Here
921
.Oo
929
.Oo
922
.Ar host | Ar IPv6_addr Oc : Ar port
930
.Ar host | Ar IPv6_addr Oc : Ar port
923
.Sm on
931
.Sm on
932
.It
933
.Cm ListenAddress
934
.Sm off
935
.Ar host | Ar IPv4_addr | Ar IPv6_addr
936
.Sm on
937
.Ar domain vrf-blue
924
.El
938
.El
925
.Pp
939
.Pp
926
If
940
If
Lines 929-934 is not specified, Link Here
929
sshd will listen on the address and all
943
sshd will listen on the address and all
930
.Cm Port
944
.Cm Port
931
options specified.
945
options specified.
946
If
947
.Ar domain
948
is not specified, sshd will use
949
.Cm BindDevice
950
if present.
932
The default is to listen on all local addresses.
951
The default is to listen on all local addresses.
933
Multiple
952
Multiple
934
.Cm ListenAddress
953
.Cm ListenAddress
935
- 

Return to bug 2784