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

Collapse All | Expand All

(-)Makefile.in (-1 / +1 lines)
Lines 82-88 SSHDOBJS=sshd.o auth-rhosts.o auth-passw Link Here
82
	auth.o auth1.o auth2.o auth-options.o session.o \
82
	auth.o auth1.o auth2.o auth-options.o session.o \
83
	auth-chall.o auth2-chall.o groupaccess.o \
83
	auth-chall.o auth2-chall.o groupaccess.o \
84
	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
84
	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
85
	auth2-none.o auth2-passwd.o auth2-pubkey.o \
85
	auth2-none.o auth2-passwd.o auth2-pubkey.o cfgmatch.o \
86
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
86
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
87
	auth-krb5.o \
87
	auth-krb5.o \
88
	auth2-gss.o gss-serv.o gss-serv-krb5.o \
88
	auth2-gss.o gss-serv.o gss-serv-krb5.o \
(-)auth.c (+3 lines)
Lines 499-504 getpwnamallow(const char *user) Link Here
499
#endif
499
#endif
500
	struct passwd *pw;
500
	struct passwd *pw;
501
501
502
	parse_server_match_config(&options, user,
503
	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());
504
502
	pw = getpwnam(user);
505
	pw = getpwnam(user);
503
	if (pw == NULL) {
506
	if (pw == NULL) {
504
		logit("Invalid user %.100s from %.100s",
507
		logit("Invalid user %.100s from %.100s",
(-)cfgmatch.c (+140 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2006 Darren Tucker.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
#include "includes.h"
26
27
#include "match.h"
28
#include "log.h"
29
#include "misc.h"
30
#include "canohost.h"
31
#include "servconf.h"
32
#include "groupaccess.h"
33
#include "xmalloc.h"
34
35
static int
36
match_cfg_line_group(const char *grps, int line, const char *user)
37
{
38
	int result = 0;
39
	u_int ngrps = 0;
40
	char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
41
	struct passwd *pw;
42
43
	arg = cp = xstrdup(grps);
44
	while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
45
		if (ngrps >= MAX_MATCH_GROUPS) {
46
			error("line %d: too many groups in Match Group", line);
47
			result = -1;
48
			goto out;
49
		}
50
		grplist[ngrps++] = p;
51
	}
52
53
	if (user == NULL)
54
		goto out;
55
56
	if ((pw = getpwnam(user)) == NULL) {
57
		debug("Can't match group at line %d because "
58
		    "user %.100s does not exist", line, user);
59
	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
60
		debug("Can't Match group because user %.100s "
61
		    "not in any group at line %d", user, line);
62
	} else if (ga_match(grplist, ngrps) != 1) {
63
		debug("user %.100s does not match group "
64
		    "%.100s at line %d", user, arg, line);
65
	} else {
66
		debug("user %.100s matched group %.100s at "
67
		    "line %d", user, arg, line);
68
		result = 1;
69
	}
70
out:
71
	xfree(arg);
72
	return result;
73
}
74
75
76
int
77
match_cfg_line(char **condition, int line, const char *user, const char *host,
78
    const char *address)
79
{
80
	int r, result = 1;
81
	char *arg, *attrib, *cp = *condition;
82
	size_t len;
83
84
	if (user == NULL)
85
		debug3("checking syntax for 'Match %s'", cp);
86
	else
87
		debug3("checking match for '%s'", cp);
88
89
	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
90
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
91
			error("Missing Match criteria for %s", attrib);
92
			return -1;
93
		}
94
		len = strlen(arg);
95
		if (strcasecmp(attrib, "user") == 0) {
96
			if (!user) {
97
				result = 0;
98
				continue;
99
			}
100
			if (match_pattern_list(user, arg, len, 0) != 1)
101
				/* XXX what about negative match? */
102
				result = 0;
103
			else
104
				debug("user %.100s matched 'User %.100s' at "
105
				    "line %d", user, arg, line);
106
		} else if (strcasecmp(attrib, "group") == 0) {
107
			if ((r = match_cfg_line_group(arg, line, user)) < 0)
108
				return -1;
109
			if (r == 0)
110
				result = 0;
111
		} else if (strcasecmp(attrib, "host") == 0) {
112
			if (!host) {
113
				result = 0;
114
				continue;
115
			}
116
			if (match_hostname(host, arg, len) != 1)
117
				result = 0;
118
			else
119
				debug("connection from %.100s matched 'Host "
120
				    "%.100s' at line %d", host, arg, line);
121
		} else if (strcasecmp(attrib, "address") == 0) {
122
			if (!address) {
123
				result = 0;
124
				continue;
125
			}
126
			if (match_hostname(address, arg, len) != 1)
127
				result = 0;
128
			else
129
				debug("connection from %.100s matched 'Address "
130
				    "%.100s' at line %d", address, arg, line);
131
		} else {
132
			error("Unsupported Match attribute %s", attrib);
133
			return -1;
134
		}
135
	}
136
	if (user != NULL)
137
		debug3("match %sfound", result ? "" : "not ");
138
	*condition = cp;
139
	return result;
140
}
(-)groupaccess.c (-1 / +12 lines)
Lines 32-37 Link Here
32
32
33
static int ngroups;
33
static int ngroups;
34
static char **groups_byname;
34
static char **groups_byname;
35
static char *saved_user;
36
static gid_t saved_gid;
35
37
36
/*
38
/*
37
 * Initialize group access list for user with primary (base) and
39
 * Initialize group access list for user with primary (base) and
Lines 44-57 ga_init(const char *user, gid_t base) Link Here
44
	int i, j;
46
	int i, j;
45
	struct group *gr;
47
	struct group *gr;
46
48
47
	if (ngroups > 0)
49
	if (saved_user != NULL && strcmp(saved_user, user) == 0 &&
50
	    saved_gid == base)
51
		return ngroups;
52
53
	if (ngroups > 0) {
48
		ga_free();
54
		ga_free();
55
		xfree(saved_user);
56
		saved_user = NULL;
57
	}
49
58
50
	ngroups = NGROUPS_MAX;
59
	ngroups = NGROUPS_MAX;
51
#if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
60
#if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
52
	ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX));
61
	ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX));
53
#endif
62
#endif
54
63
64
	saved_user = xstrdup(user);
65
	saved_gid = base;
55
	groups_bygid = xmalloc(ngroups * sizeof(*groups_bygid));
66
	groups_bygid = xmalloc(ngroups * sizeof(*groups_bygid));
56
	groups_byname = xmalloc(ngroups * sizeof(*groups_byname));
67
	groups_byname = xmalloc(ngroups * sizeof(*groups_byname));
57
68
(-)match.h (+1 lines)
Lines 20-24 int match_hostname(const char *, const Link Here
20
int	 match_host_and_ip(const char *, const char *, const char *);
20
int	 match_host_and_ip(const char *, const char *, const char *);
21
int	 match_user(const char *, const char *, const char *, const char *);
21
int	 match_user(const char *, const char *, const char *, const char *);
22
char	*match_list(const char *, const char *, u_int *);
22
char	*match_list(const char *, const char *, u_int *);
23
int	 match_cfg_line(char **, int, const char *, const char *, const char *);
23
24
24
#endif
25
#endif
(-)monitor.c (+6 lines)
Lines 628-633 mm_answer_pwnamallow(int sock, Buffer *m Link Here
628
#endif
628
#endif
629
	buffer_put_cstring(m, pwent->pw_dir);
629
	buffer_put_cstring(m, pwent->pw_dir);
630
	buffer_put_cstring(m, pwent->pw_shell);
630
	buffer_put_cstring(m, pwent->pw_shell);
631
	buffer_put_string(m, &options, sizeof(options));
632
	if (options.banner != NULL) {
633
		buffer_put_int(m, 1);
634
		buffer_put_cstring(m, options.banner);
635
	} else
636
		buffer_put_int(m, 0);
631
637
632
 out:
638
 out:
633
	debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
639
	debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
(-)monitor_wrap.c (-3 / +31 lines)
Lines 196-202 mm_getpwnamallow(const char *username) Link Here
196
{
196
{
197
	Buffer m;
197
	Buffer m;
198
	struct passwd *pw;
198
	struct passwd *pw;
199
	u_int pwlen;
199
	u_int len;
200
	void *p;
201
	ServerOptions newopts;
200
202
201
	debug3("%s entering", __func__);
203
	debug3("%s entering", __func__);
202
204
Lines 212-219 mm_getpwnamallow(const char *username) Link Here
212
		buffer_free(&m);
214
		buffer_free(&m);
213
		return (NULL);
215
		return (NULL);
214
	}
216
	}
215
	pw = buffer_get_string(&m, &pwlen);
217
	pw = buffer_get_string(&m, &len);
216
	if (pwlen != sizeof(struct passwd))
218
	if (len != sizeof(struct passwd))
217
		fatal("%s: struct passwd size mismatch", __func__);
219
		fatal("%s: struct passwd size mismatch", __func__);
218
	pw->pw_name = buffer_get_string(&m, NULL);
220
	pw->pw_name = buffer_get_string(&m, NULL);
219
	pw->pw_passwd = buffer_get_string(&m, NULL);
221
	pw->pw_passwd = buffer_get_string(&m, NULL);
Lines 223-228 mm_getpwnamallow(const char *username) Link Here
223
#endif
225
#endif
224
	pw->pw_dir = buffer_get_string(&m, NULL);
226
	pw->pw_dir = buffer_get_string(&m, NULL);
225
	pw->pw_shell = buffer_get_string(&m, NULL);
227
	pw->pw_shell = buffer_get_string(&m, NULL);
228
229
	/* copy options block as a Match directive may have changed some */
230
	p = buffer_get_string(&m, &len);
231
	if (len != sizeof(newopts))
232
		fatal("%s: option block size mismatch", __func__);
233
	memcpy(&newopts, p, sizeof(newopts));
234
	newopts.banner = NULL;
235
	if (buffer_get_int(&m) == 1)
236
		newopts.banner =  buffer_get_string(&m, NULL);
237
	/* unset the string/array options not used in the slave */
238
	newopts.num_ports = 0;
239
	newopts.ports_from_cmdline = 0;
240
	newopts.pid_file = NULL;
241
	newopts.xauth_location = NULL;
242
	newopts.ciphers = NULL;
243
	newopts.num_allow_users = 0;
244
	newopts.num_deny_users = 0;
245
	newopts.num_allow_groups = 0;
246
	newopts.num_deny_groups = 0;
247
	newopts.macs = NULL;
248
	newopts.num_subsystems = 0;
249
	newopts.authorized_keys_file = NULL;
250
	newopts.authorized_keys_file2 = NULL;
251
	newopts.num_accept_env = 0;
252
	copy_set_server_options(&options, &newopts);
253
226
	buffer_free(&m);
254
	buffer_free(&m);
227
255
228
	return (pw);
256
	return (pw);
(-)servconf.c (-96 / +301 lines)
Lines 22-33 Link Here
22
#include "cipher.h"
22
#include "cipher.h"
23
#include "kex.h"
23
#include "kex.h"
24
#include "mac.h"
24
#include "mac.h"
25
#include "match.h"
25
26
26
static void add_listen_addr(ServerOptions *, char *, u_short);
27
static void add_listen_addr(ServerOptions *, char *, u_short);
27
static void add_one_listen_addr(ServerOptions *, char *, u_short);
28
static void add_one_listen_addr(ServerOptions *, char *, u_short);
28
29
29
/* Use of privilege separation or not */
30
/* Use of privilege separation or not */
30
extern int use_privsep;
31
extern int use_privsep;
32
extern Buffer cfg;
31
33
32
/* Initializes the server options to their default values. */
34
/* Initializes the server options to their default values. */
33
35
Lines 102-110 initialize_server_options(ServerOptions Link Here
102
	options->authorized_keys_file2 = NULL;
104
	options->authorized_keys_file2 = NULL;
103
	options->num_accept_env = 0;
105
	options->num_accept_env = 0;
104
	options->permit_tun = -1;
106
	options->permit_tun = -1;
105
106
	/* Needs to be accessable in many places */
107
	use_privsep = -1;
108
}
107
}
109
108
110
void
109
void
Lines 274-383 typedef enum { Link Here
274
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
273
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
275
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
274
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
276
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
275
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
276
	sMatch,
277
	sUsePrivilegeSeparation,
277
	sUsePrivilegeSeparation,
278
	sDeprecated, sUnsupported
278
	sDeprecated, sUnsupported
279
} ServerOpCodes;
279
} ServerOpCodes;
280
280
281
#define SSHCFG_GLOBAL	0x01
282
#define SSHCFG_MATCH	0x02
283
#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
284
281
/* Textual representation of the tokens. */
285
/* Textual representation of the tokens. */
282
static struct {
286
static struct {
283
	const char *name;
287
	const char *name;
284
	ServerOpCodes opcode;
288
	ServerOpCodes opcode;
289
	u_int flags;
285
} keywords[] = {
290
} keywords[] = {
286
	/* Portable-specific options */
291
	/* Portable-specific options */
287
#ifdef USE_PAM
292
#ifdef USE_PAM
288
	{ "usepam", sUsePAM },
293
	{ "usepam", sUsePAM, SSHCFG_ALL },
289
#else
294
#else
290
	{ "usepam", sUnsupported },
295
	{ "usepam", sUnsupported, SSHCFG_ALL },
291
#endif
296
#endif
292
	{ "pamauthenticationviakbdint", sDeprecated },
297
	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
293
	/* Standard Options */
298
	/* Standard Options */
294
	{ "port", sPort },
299
	{ "port", sPort, SSHCFG_GLOBAL },
295
	{ "hostkey", sHostKeyFile },
300
	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
296
	{ "hostdsakey", sHostKeyFile },					/* alias */
301
	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
297
	{ "pidfile", sPidFile },
302
	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
298
	{ "serverkeybits", sServerKeyBits },
303
	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
299
	{ "logingracetime", sLoginGraceTime },
304
	{ "logingracetime", sLoginGraceTime, SSHCFG_ALL },
300
	{ "keyregenerationinterval", sKeyRegenerationTime },
305
	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
301
	{ "permitrootlogin", sPermitRootLogin },
306
	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
302
	{ "syslogfacility", sLogFacility },
307
	{ "syslogfacility", sLogFacility, SSHCFG_ALL },
303
	{ "loglevel", sLogLevel },
308
	{ "loglevel", sLogLevel, SSHCFG_ALL },
304
	{ "rhostsauthentication", sDeprecated },
309
	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
305
	{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
310
	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
306
	{ "hostbasedauthentication", sHostbasedAuthentication },
311
	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
307
	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
312
	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
308
	{ "rsaauthentication", sRSAAuthentication },
313
	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
309
	{ "pubkeyauthentication", sPubkeyAuthentication },
314
	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
310
	{ "dsaauthentication", sPubkeyAuthentication },			/* alias */
315
	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_ALL }, /* alias */
311
#ifdef KRB5
316
#ifdef KRB5
312
	{ "kerberosauthentication", sKerberosAuthentication },
317
	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
313
	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
318
	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_ALL },
314
	{ "kerberosticketcleanup", sKerberosTicketCleanup },
319
	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_ALL },
315
#ifdef USE_AFS
320
#ifdef USE_AFS
316
	{ "kerberosgetafstoken", sKerberosGetAFSToken },
321
	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_ALL },
317
#else
322
#else
318
	{ "kerberosgetafstoken", sUnsupported },
323
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_ALL },
319
#endif
324
#endif
320
#else
325
#else
321
	{ "kerberosauthentication", sUnsupported },
326
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
322
	{ "kerberosorlocalpasswd", sUnsupported },
327
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_ALL },
323
	{ "kerberosticketcleanup", sUnsupported },
328
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_ALL },
324
	{ "kerberosgetafstoken", sUnsupported },
329
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_ALL },
325
#endif
330
#endif
326
	{ "kerberostgtpassing", sUnsupported },
331
	{ "kerberostgtpassing", sUnsupported, SSHCFG_ALL },
327
	{ "afstokenpassing", sUnsupported },
332
	{ "afstokenpassing", sUnsupported, SSHCFG_ALL },
328
#ifdef GSSAPI
333
#ifdef GSSAPI
329
	{ "gssapiauthentication", sGssAuthentication },
334
	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
330
	{ "gssapicleanupcredentials", sGssCleanupCreds },
335
	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_ALL },
331
#else
336
#else
332
	{ "gssapiauthentication", sUnsupported },
337
	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
333
	{ "gssapicleanupcredentials", sUnsupported },
338
	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_ALL },
334
#endif
339
#endif
335
	{ "passwordauthentication", sPasswordAuthentication },
340
	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
336
	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
341
	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
337
	{ "challengeresponseauthentication", sChallengeResponseAuthentication },
342
	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_ALL },
338
	{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
343
	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_ALL }, /* alias */
339
	{ "checkmail", sDeprecated },
344
	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
340
	{ "listenaddress", sListenAddress },
345
	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
341
	{ "addressfamily", sAddressFamily },
346
	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
342
	{ "printmotd", sPrintMotd },
347
	{ "printmotd", sPrintMotd, SSHCFG_ALL },
343
	{ "printlastlog", sPrintLastLog },
348
	{ "printlastlog", sPrintLastLog, SSHCFG_ALL },
344
	{ "ignorerhosts", sIgnoreRhosts },
349
	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
345
	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
350
	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_ALL },
346
	{ "x11forwarding", sX11Forwarding },
351
	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
347
	{ "x11displayoffset", sX11DisplayOffset },
352
	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
348
	{ "x11uselocalhost", sX11UseLocalhost },
353
	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
349
	{ "xauthlocation", sXAuthLocation },
354
	{ "xauthlocation", sXAuthLocation, SSHCFG_ALL },
350
	{ "strictmodes", sStrictModes },
355
	{ "strictmodes", sStrictModes, SSHCFG_ALL },
351
	{ "permitemptypasswords", sEmptyPasswd },
356
	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
352
	{ "permituserenvironment", sPermitUserEnvironment },
357
	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_ALL },
353
	{ "uselogin", sUseLogin },
358
	{ "uselogin", sUseLogin, SSHCFG_ALL },
354
	{ "compression", sCompression },
359
	{ "compression", sCompression, SSHCFG_GLOBAL },
355
	{ "tcpkeepalive", sTCPKeepAlive },
360
	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
356
	{ "keepalive", sTCPKeepAlive },				/* obsolete alias */
361
	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
357
	{ "allowtcpforwarding", sAllowTcpForwarding },
362
	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
358
	{ "allowusers", sAllowUsers },
363
	{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
359
	{ "denyusers", sDenyUsers },
364
	{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
360
	{ "allowgroups", sAllowGroups },
365
	{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
361
	{ "denygroups", sDenyGroups },
366
	{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
362
	{ "ciphers", sCiphers },
367
	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
363
	{ "macs", sMacs },
368
	{ "macs", sMacs, SSHCFG_GLOBAL },
364
	{ "protocol", sProtocol },
369
	{ "protocol", sProtocol, SSHCFG_GLOBAL },
365
	{ "gatewayports", sGatewayPorts },
370
	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
366
	{ "subsystem", sSubsystem },
371
	{ "subsystem", sSubsystem, SSHCFG_ALL },
367
	{ "maxstartups", sMaxStartups },
372
	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
368
	{ "maxauthtries", sMaxAuthTries },
373
	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
369
	{ "banner", sBanner },
374
	{ "banner", sBanner, SSHCFG_ALL },
370
	{ "usedns", sUseDNS },
375
	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
371
	{ "verifyreversemapping", sDeprecated },
376
	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
372
	{ "reversemappingcheck", sDeprecated },
377
	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
373
	{ "clientaliveinterval", sClientAliveInterval },
378
	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
374
	{ "clientalivecountmax", sClientAliveCountMax },
379
	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
375
	{ "authorizedkeysfile", sAuthorizedKeysFile },
380
	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
376
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
381
	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL },
377
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
382
	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
378
	{ "acceptenv", sAcceptEnv },
383
	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
379
	{ "permittunnel", sPermitTunnel },
384
	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
380
	{ NULL, sBadOption }
385
	{ "match", sMatch, SSHCFG_ALL },
386
	{ NULL, sBadOption, 0 }
381
};
387
};
382
388
383
/*
389
/*
Lines 386-398 static struct { Link Here
386
392
387
static ServerOpCodes
393
static ServerOpCodes
388
parse_token(const char *cp, const char *filename,
394
parse_token(const char *cp, const char *filename,
389
	    int linenum)
395
	    int linenum, u_int *flags)
390
{
396
{
391
	u_int i;
397
	u_int i;
392
398
393
	for (i = 0; keywords[i].name; i++)
399
	for (i = 0; keywords[i].name; i++)
394
		if (strcasecmp(cp, keywords[i].name) == 0)
400
		if (strcasecmp(cp, keywords[i].name) == 0) {
401
			*flags = keywords[i].flags;
395
			return keywords[i].opcode;
402
			return keywords[i].opcode;
403
		}
396
404
397
	error("%s: line %d: Bad configuration option: %s",
405
	error("%s: line %d: Bad configuration option: %s",
398
	    filename, linenum, cp);
406
	    filename, linenum, cp);
Lines 437-451 add_one_listen_addr(ServerOptions *optio Link Here
437
	options->listen_addrs = aitop;
445
	options->listen_addrs = aitop;
438
}
446
}
439
447
448
/*
449
 * The strategy for the Match blocks is that the config file is parsed twice.
450
 *
451
 * The first time is at startup.  activep is initialized to 1 and the
452
 * directives in the global context are processed and acted on.  Hitting a
453
 * Match directive unsets activep and the directives inside the block are
454
 * checked for syntax only.
455
 *
456
 * The second time is after a connection has been established but before
457
 * authentication.  activep is initialized to 2 and global config directives
458
 * are ignored since they have already been processed.  If the criteria in a
459
 * Match block is met, activep is set and the subsequent directives
460
 * processed and actioned until EOF or another Match block unsets it.  Any
461
 * options set are copied into the main server config.
462
 *
463
 * Potential additions/improvements:
464
 *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
465
 *
466
 *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
467
 *	Match Address 192.168.0.*
468
 *		Tag trusted
469
 *	Match Group wheel
470
 *		Tag trusted
471
 *	Match Tag trusted
472
 *		AllowTcpForwarding yes
473
 *		GatewayPorts clientspecified
474
 *		[...]
475
 *
476
 *  - Add a PermittedChannelRequests directive
477
 *	Match Group shell
478
 *		PermittedChannelRequests session,forwarded-tcpip
479
 */
480
440
int
481
int
441
process_server_config_line(ServerOptions *options, char *line,
482
process_server_config_line(ServerOptions *options, char *line,
442
    const char *filename, int linenum)
483
    const char *filename, int linenum, int *activep, const char *user,
484
    const char *host, const char *address)
443
{
485
{
444
	char *cp, **charptr, *arg, *p;
486
	char *cp, **charptr, *arg, *p;
445
	int *intptr, value, n;
487
	int cmdline = 0, *intptr, value, n;
446
	ServerOpCodes opcode;
488
	ServerOpCodes opcode;
447
	u_short port;
489
	u_short port;
448
	u_int i;
490
	u_int i, flags = 0;
449
491
450
	cp = line;
492
	cp = line;
451
	if ((arg = strdelim(&cp)) == NULL)
493
	if ((arg = strdelim(&cp)) == NULL)
Lines 457-463 process_server_config_line(ServerOptions Link Here
457
		return 0;
499
		return 0;
458
	intptr = NULL;
500
	intptr = NULL;
459
	charptr = NULL;
501
	charptr = NULL;
460
	opcode = parse_token(arg, filename, linenum);
502
	opcode = parse_token(arg, filename, linenum, &flags);
503
504
	if (activep == NULL) { /* We are processing a command line directive */
505
		cmdline = 1;
506
		activep = &cmdline;
507
	}
508
	if (*activep && opcode != sMatch)
509
		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
510
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
511
		if (user == NULL) {
512
			fatal("%s line %d: Directive '%s' is not allowed "
513
			    "within a Match block", filename, linenum, arg);
514
		} else { /* this is a directive we have already processed */
515
			while (arg)
516
				arg = strdelim(&cp);
517
			return 0;
518
		}
519
	}
520
461
	switch (opcode) {
521
	switch (opcode) {
462
	/* Portable-specific options */
522
	/* Portable-specific options */
463
	case sUsePAM:
523
	case sUsePAM:
Lines 495-501 parse_int: Link Here
495
			fatal("%s line %d: missing integer value.",
555
			fatal("%s line %d: missing integer value.",
496
			    filename, linenum);
556
			    filename, linenum);
497
		value = atoi(arg);
557
		value = atoi(arg);
498
		if (*intptr == -1)
558
		if (*activep && *intptr == -1)
499
			*intptr = value;
559
			*intptr = value;
500
		break;
560
		break;
501
561
Lines 575-581 parse_filename: Link Here
575
		if (!arg || *arg == '\0')
635
		if (!arg || *arg == '\0')
576
			fatal("%s line %d: missing file name.",
636
			fatal("%s line %d: missing file name.",
577
			    filename, linenum);
637
			    filename, linenum);
578
		if (*charptr == NULL) {
638
		if (*activep && *charptr == NULL) {
579
			*charptr = tilde_expand_filename(arg, getuid());
639
			*charptr = tilde_expand_filename(arg, getuid());
580
			/* increase optional counter */
640
			/* increase optional counter */
581
			if (intptr != NULL)
641
			if (intptr != NULL)
Lines 626-632 parse_flag: Link Here
626
		else
686
		else
627
			fatal("%s line %d: Bad yes/no argument: %s",
687
			fatal("%s line %d: Bad yes/no argument: %s",
628
				filename, linenum, arg);
688
				filename, linenum, arg);
629
		if (*intptr == -1)
689
		if (*activep && *intptr == -1)
630
			*intptr = value;
690
			*intptr = value;
631
		break;
691
		break;
632
692
Lines 891-896 parse_flag: Link Here
891
		if (!arg || *arg == '\0')
951
		if (!arg || *arg == '\0')
892
			fatal("%s line %d: Missing subsystem name.",
952
			fatal("%s line %d: Missing subsystem name.",
893
			    filename, linenum);
953
			    filename, linenum);
954
		if (!*activep) {
955
			arg = strdelim(&cp);
956
			break;
957
		}
894
		for (i = 0; i < options->num_subsystems; i++)
958
		for (i = 0; i < options->num_subsystems; i++)
895
			if (strcmp(arg, options->subsystem_name[i]) == 0)
959
			if (strcmp(arg, options->subsystem_name[i]) == 0)
896
				fatal("%s line %d: Subsystem '%s' already defined.",
960
				fatal("%s line %d: Subsystem '%s' already defined.",
Lines 962-967 parse_flag: Link Here
962
			if (options->num_accept_env >= MAX_ACCEPT_ENV)
1026
			if (options->num_accept_env >= MAX_ACCEPT_ENV)
963
				fatal("%s line %d: too many allow env.",
1027
				fatal("%s line %d: too many allow env.",
964
				    filename, linenum);
1028
				    filename, linenum);
1029
			if (!*activep)
1030
				break;
965
			options->accept_env[options->num_accept_env++] =
1031
			options->accept_env[options->num_accept_env++] =
966
			    xstrdup(arg);
1032
			    xstrdup(arg);
967
		}
1033
		}
Lines 989-994 parse_flag: Link Here
989
			*intptr = value;
1055
			*intptr = value;
990
		break;
1056
		break;
991
1057
1058
	case sMatch:
1059
		if (cmdline)
1060
			fatal("Match directive not supported as a command-line "
1061
			   "option");
1062
		value = match_cfg_line(&cp, linenum, user, host, address);
1063
		if (value < 0)
1064
			fatal("%s line %d: Bad Match condition", filename,
1065
			    linenum);
1066
		*activep = value;
1067
		break;
1068
992
	case sDeprecated:
1069
	case sDeprecated:
993
		logit("%s line %d: Deprecated option %s",
1070
		logit("%s line %d: Deprecated option %s",
994
		    filename, linenum, arg);
1071
		    filename, linenum, arg);
Lines 1045-1062 load_server_config(const char *filename, Link Here
1045
}
1122
}
1046
1123
1047
void
1124
void
1048
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
1125
parse_server_match_config(ServerOptions *options, const char *user,
1126
    const char *host, const char *address)
1127
{
1128
	ServerOptions mo;
1129
1130
	initialize_server_options(&mo);
1131
	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1132
	copy_set_server_options(options, &mo);
1133
}
1134
1135
/* Copy any (supported) values that are set */
1136
void
1137
copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1138
{
1139
	u_int i;
1140
1141
	if (src->use_pam != -1)
1142
		dst->use_pam = src->use_pam;
1143
	if (src->num_accept_env > 0) {
1144
		for (i = 0; i < dst->num_accept_env; i++)
1145
			xfree(dst->accept_env[i]);
1146
		dst->num_accept_env = 0;
1147
		for (i = 0; i < src->num_accept_env; i++) {
1148
			if (dst->num_accept_env >= MAX_ACCEPT_ENV)
1149
				fatal("Too many allow env in Match block.");
1150
			dst->accept_env[dst->num_accept_env++] =
1151
			    src->accept_env[i];
1152
		}
1153
	}
1154
	if (src->allow_tcp_forwarding != -1)
1155
		dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1156
	if (src->authorized_keys_file != NULL) {
1157
		if (dst->authorized_keys_file != NULL)
1158
			xfree(dst->authorized_keys_file);
1159
		dst->authorized_keys_file = src->authorized_keys_file;
1160
	}
1161
	if (src->authorized_keys_file2 != NULL) {
1162
		if (dst->authorized_keys_file2 != NULL)
1163
			xfree(dst->authorized_keys_file2);
1164
		dst->authorized_keys_file2 = src->authorized_keys_file2;
1165
	}
1166
	if (src->banner != NULL) {
1167
		if (dst->banner != NULL)
1168
			xfree(dst->banner);
1169
		dst->banner = src->banner;
1170
	}
1171
	if (src->password_authentication != -1)
1172
		dst->password_authentication = src->password_authentication;
1173
	if (src->challenge_response_authentication != -1)
1174
		dst->challenge_response_authentication =
1175
		    src->challenge_response_authentication;
1176
	if (src->client_alive_count_max != -1)
1177
		dst->client_alive_count_max = src->client_alive_count_max;
1178
	if (src->client_alive_interval != -1)
1179
		dst->client_alive_interval = src->client_alive_interval;
1180
	if (src->gateway_ports != -1)
1181
		dst->gateway_ports = src->gateway_ports;
1182
	if (src->gss_authentication != -1)
1183
		dst->gss_authentication = src->gss_authentication;
1184
	if (src->hostbased_authentication != -1)
1185
		dst->hostbased_authentication = src->hostbased_authentication;
1186
	if (src->hostbased_uses_name_from_packet_only != -1)
1187
		dst->hostbased_uses_name_from_packet_only =
1188
		    src->hostbased_uses_name_from_packet_only;
1189
	if (src->kerberos_authentication != -1)
1190
		dst->kerberos_authentication = src->kerberos_authentication;
1191
	if (src->kerberos_or_local_passwd != -1)
1192
		dst->kerberos_or_local_passwd = src->kerberos_or_local_passwd;
1193
	if (src->kerberos_ticket_cleanup != -1)
1194
		dst->kerberos_ticket_cleanup = src->kerberos_ticket_cleanup;
1195
	if (src->kerberos_get_afs_token != -1)
1196
		dst->kerberos_get_afs_token = src->kerberos_get_afs_token;
1197
	if (src->login_grace_time != -1)
1198
		dst->login_grace_time = src->login_grace_time;
1199
	if (src->log_facility != -1)
1200
		dst->log_facility = src->log_facility;
1201
	if (src->log_level != -1)
1202
		dst->log_level = src->log_level;
1203
	if (src->permit_root_login != -1)
1204
		dst->permit_root_login = src->permit_root_login;
1205
	if (src->max_authtries != -1)
1206
		dst->max_authtries = src->max_authtries;
1207
	if (src->permit_empty_passwd != -1)
1208
		dst->permit_empty_passwd = src->permit_empty_passwd;
1209
	if (src->permit_tun != -1)
1210
		dst->permit_tun = src->permit_tun;
1211
	if (src->permit_user_env != -1)
1212
		dst->permit_user_env = src->permit_user_env;
1213
	if (src->print_motd != -1)
1214
		dst->print_motd = src->print_motd;
1215
	if (src->pubkey_authentication != -1)
1216
		dst->pubkey_authentication = src->pubkey_authentication;
1217
	if (src->rsa_authentication != -1)
1218
		dst->rsa_authentication = src->rsa_authentication;
1219
	if (src->strict_modes != -1)
1220
		dst->strict_modes = src->strict_modes;
1221
	if (src->num_subsystems != 0) {  /* Not currently used */
1222
		for (i = 0; i < dst->num_subsystems; i++) {
1223
			xfree(dst->subsystem_name[i]);
1224
			xfree(dst->subsystem_command[i]);
1225
		}
1226
		dst->num_subsystems = 0;
1227
		for (i = 0; i < src->num_subsystems; i++) {
1228
			dst->subsystem_name[dst->num_subsystems] =
1229
			    src->subsystem_name[i];
1230
			dst->subsystem_command[dst->num_subsystems] =
1231
			    src->subsystem_command[i];
1232
			dst->num_subsystems++;
1233
		}
1234
	}
1235
	if (src->use_login != -1)
1236
		dst->use_login = src->use_login;
1237
	if (src->xauth_location != NULL) {
1238
		if (dst->xauth_location != NULL)
1239
			xfree(dst->xauth_location);
1240
		dst->xauth_location = src->xauth_location;
1241
	}
1242
	if (src->x11_display_offset != -1)
1243
		dst->x11_display_offset = src->x11_display_offset;
1244
	if (src->x11_forwarding != -1)
1245
		dst->x11_forwarding = src->x11_forwarding;
1246
	if (src->x11_use_localhost != -1)
1247
		dst->x11_use_localhost = src->x11_use_localhost;
1248
}
1249
1250
void
1251
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1252
    const char *user, const char *host, const char *address)
1049
{
1253
{
1050
	int linenum, bad_options = 0;
1254
	int active, linenum, bad_options = 0;
1051
	char *cp, *obuf, *cbuf;
1255
	char *cp, *obuf, *cbuf;
1052
1256
1053
	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1257
	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1054
1258
1055
	obuf = cbuf = xstrdup(buffer_ptr(conf));
1259
	obuf = cbuf = xstrdup(buffer_ptr(conf));
1260
	active = user ? 0 : 1;
1056
	linenum = 1;
1261
	linenum = 1;
1057
	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1262
	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1058
		if (process_server_config_line(options, cp, filename,
1263
		if (process_server_config_line(options, cp, filename,
1059
		    linenum++) != 0)
1264
		    linenum++, &active, user, host, address) != 0)
1060
			bad_options++;
1265
			bad_options++;
1061
	}
1266
	}
1062
	xfree(obuf);
1267
	xfree(obuf);
(-)servconf.h (-2 / +8 lines)
Lines 27-32 Link Here
27
#define MAX_SUBSYSTEMS		256	/* Max # subsystems. */
27
#define MAX_SUBSYSTEMS		256	/* Max # subsystems. */
28
#define MAX_HOSTKEYS		256	/* Max # hostkeys. */
28
#define MAX_HOSTKEYS		256	/* Max # hostkeys. */
29
#define MAX_ACCEPT_ENV		256	/* Max # of env vars. */
29
#define MAX_ACCEPT_ENV		256	/* Max # of env vars. */
30
#define MAX_MATCH_GROUPS	256	/* Max # of groups for Match Group */
30
31
31
/* permit_root_login */
32
/* permit_root_login */
32
#define	PERMIT_NOT_SET		-1
33
#define	PERMIT_NOT_SET		-1
Lines 141-148 typedef struct { Link Here
141
142
142
void	 initialize_server_options(ServerOptions *);
143
void	 initialize_server_options(ServerOptions *);
143
void	 fill_default_server_options(ServerOptions *);
144
void	 fill_default_server_options(ServerOptions *);
144
int	 process_server_config_line(ServerOptions *, char *, const char *, int);
145
int	 process_server_config_line(ServerOptions *, char *, const char *, int,
146
	     int *, const char *, const char *, const char *);
145
void	 load_server_config(const char *, Buffer *);
147
void	 load_server_config(const char *, Buffer *);
146
void	 parse_server_config(ServerOptions *, const char *, Buffer *);
148
void	 parse_server_config(ServerOptions *, const char *, Buffer *,
149
	     const char *, const char *, const char *);
150
void	 parse_server_match_config(ServerOptions *, const char *, const char *,
151
	     const char *);
152
void	 copy_set_server_options(ServerOptions *, ServerOptions *);
147
153
148
#endif				/* SERVCONF_H */
154
#endif				/* SERVCONF_H */
(-)sshd.c (-8 / +7 lines)
Lines 213-224 int *startup_pipes = NULL; Link Here
213
int startup_pipe;		/* in child */
213
int startup_pipe;		/* in child */
214
214
215
/* variables used for privilege separation */
215
/* variables used for privilege separation */
216
int use_privsep;
216
int use_privsep = -1;		/* Needs to be accessable in many places */
217
struct monitor *pmonitor = NULL;
217
struct monitor *pmonitor = NULL;
218
218
219
/* global authentication context */
219
/* global authentication context */
220
Authctxt *the_authctxt = NULL;
220
Authctxt *the_authctxt = NULL;
221
221
222
/* sshd_config buffer */
223
Buffer cfg;
224
222
/* message to be displayed after login */
225
/* message to be displayed after login */
223
Buffer loginmsg;
226
Buffer loginmsg;
224
227
Lines 910-916 main(int ac, char **av) Link Here
910
	Key *key;
913
	Key *key;
911
	Authctxt *authctxt;
914
	Authctxt *authctxt;
912
	int ret, key_used = 0;
915
	int ret, key_used = 0;
913
	Buffer cfg;
914
916
915
#ifdef HAVE_SECUREWARE
917
#ifdef HAVE_SECUREWARE
916
	(void)set_auth_parameters(ac, av);
918
	(void)set_auth_parameters(ac, av);
Lines 1030-1036 main(int ac, char **av) Link Here
1030
		case 'o':
1032
		case 'o':
1031
			line = xstrdup(optarg);
1033
			line = xstrdup(optarg);
1032
			if (process_server_config_line(&options, line,
1034
			if (process_server_config_line(&options, line,
1033
			    "command-line", 0) != 0)
1035
			    "command-line", 0, NULL, NULL, NULL, NULL) != 0)
1034
				exit(1);
1036
				exit(1);
1035
			xfree(line);
1037
			xfree(line);
1036
			break;
1038
			break;
Lines 1088-1098 main(int ac, char **av) Link Here
1088
	else
1090
	else
1089
		load_server_config(config_file_name, &cfg);
1091
		load_server_config(config_file_name, &cfg);
1090
1092
1091
	parse_server_config(&options,
1093
	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
1092
	    rexeced_flag ? "rexec" : config_file_name, &cfg);
1094
	    &cfg, NULL, NULL, NULL);
1093
1094
	if (!rexec_flag)
1095
		buffer_free(&cfg);
1096
1095
1097
	seed_rng();
1096
	seed_rng();
1098
1097
(-)sshd_config.5 (+75 lines)
Lines 463-468 for data integrity protection. Link Here
463
Multiple algorithms must be comma-separated.
463
Multiple algorithms must be comma-separated.
464
The default is:
464
The default is:
465
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
465
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
466
.It Cm Match
467
Introduces a conditional block.  Keywords on lines following a
468
.Cm Match
469
block are only applied if the criteria on the
470
.Cm Match
471
are satisfied.
472
The the arguments to
473
.Cm Match
474
block are one or more criteria-pattern pairs.
475
The available criteria are
476
.Cm User ,
477
.Cm Group ,
478
.Cm Host ,
479
and
480
.Cm Address .
481
Only a subset of keywords may be used on the lines following a
482
.Cm Match
483
keyword.
484
Available keywords are
485
.Cm AcceptEnv ,
486
.Cm AllowTcpForwarding ,
487
.Cm AuthorizedKeysFile ,
488
.Cm AuthorizedKeysFile2 ,
489
.Cm Banner ,
490
.Cm ChallengeResponseAuthentication ,
491
.Cm ChallengeResponseAuthentication ,
492
.Cm ClientAliveCountMax ,
493
.Cm ClientAliveInterval ,
494
.Cm GatewayPorts ,
495
.Cm GssAuthentication ,
496
.Cm GssCleanupCreds ,
497
.Cm HostbasedAuthentication ,
498
.Cm HostbasedUsesNameFromPacketOnly ,
499
.Cm IgnoreRhosts ,
500
.Cm IgnoreUserKnownHosts ,
501
.Cm KbdInteractiveAuthentication ,
502
.Cm KerberosAuthentication ,
503
.Cm KerberosGetAFSToken ,
504
.Cm KerberosOrLocalPasswd ,
505
.Cm KerberosTicketCleanup ,
506
.Cm LogFacility ,
507
.Cm LogLevel ,
508
.Cm LoginGraceTime ,
509
.Cm MaxAuthTries ,
510
.Cm PasswordAuthentication ,
511
.Cm PermitEmptyPasswd ,
512
.Cm PermitRootLogin ,
513
.Cm PermitTunnel ,
514
.Cm PermitUserEnvironment ,
515
.Cm PrintLastLog ,
516
.Cm PrintMotd ,
517
.Cm PubkeyAuthentication ,
518
.Cm PubkeyAuthentication ,
519
.Cm RSAAuthentication ,
520
.Cm RhostsRSAAuthentication ,
521
.Cm StrictModes ,
522
.Cm Subsystem ,
523
.Cm UseLogin ,
524
.Cm UsePAM ,
525
.Cm X11DisplayOffset ,
526
.Cm X11Forwarding ,
527
.Cm X11UseLocalhost ,
528
and
529
.Cm XAuthLocation .
466
.It Cm MaxAuthTries
530
.It Cm MaxAuthTries
467
Specifies the maximum number of authentication attempts permitted per
531
Specifies the maximum number of authentication attempts permitted per
468
connection.
532
connection.
Lines 855-860 Contains configuration data for Link Here
855
This file should be writable by root only, but it is recommended
919
This file should be writable by root only, but it is recommended
856
(though not necessary) that it be world-readable.
920
(though not necessary) that it be world-readable.
857
.El
921
.El
922
.Sh EXAMPLES
923
To allow
924
.Cm PasswordAuthentication
925
only from the local private network:
926
.Bd -literal -offset indent
927
PasswordAuthentication no
928
Match Address 192.168.0.*
929
	PasswordAuthentication yes
930
.Ed
931
.Bl -tag -width Ds
932
.Bl -tag -width Ds
858
.Sh SEE ALSO
933
.Sh SEE ALSO
859
.Xr sshd 8
934
.Xr sshd 8
860
.Sh AUTHORS
935
.Sh AUTHORS

Return to bug 1180