xref: /freebsd/crypto/openssh/auth-options.c (revision d4af9e693f15f5155095f38c7650b24fe74ae351)
1d4af9e69SDag-Erling Smørgrav /* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */
2b66f2d16SKris Kennaway /*
3b66f2d16SKris Kennaway  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4b66f2d16SKris Kennaway  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5b66f2d16SKris Kennaway  *                    All rights reserved
6b66f2d16SKris Kennaway  * As far as I am concerned, the code I have written for this software
7b66f2d16SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
8b66f2d16SKris Kennaway  * software must be clearly marked as such, and if the derived work is
9b66f2d16SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
10b66f2d16SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
11b66f2d16SKris Kennaway  */
12b66f2d16SKris Kennaway 
13b66f2d16SKris Kennaway #include "includes.h"
14761efaa7SDag-Erling Smørgrav 
15761efaa7SDag-Erling Smørgrav #include <sys/types.h>
16761efaa7SDag-Erling Smørgrav 
17761efaa7SDag-Erling Smørgrav #include <netdb.h>
18761efaa7SDag-Erling Smørgrav #include <pwd.h>
19761efaa7SDag-Erling Smørgrav #include <string.h>
20761efaa7SDag-Erling Smørgrav #include <stdio.h>
21761efaa7SDag-Erling Smørgrav #include <stdarg.h>
22b66f2d16SKris Kennaway 
23d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h"
24b66f2d16SKris Kennaway #include "xmalloc.h"
25b66f2d16SKris Kennaway #include "match.h"
261e8db6e2SBrian Feldman #include "log.h"
271e8db6e2SBrian Feldman #include "canohost.h"
28761efaa7SDag-Erling Smørgrav #include "buffer.h"
291e8db6e2SBrian Feldman #include "channels.h"
301e8db6e2SBrian Feldman #include "auth-options.h"
311e8db6e2SBrian Feldman #include "servconf.h"
32ae1f160dSDag-Erling Smørgrav #include "misc.h"
33761efaa7SDag-Erling Smørgrav #include "key.h"
34761efaa7SDag-Erling Smørgrav #include "hostfile.h"
35545d5ecaSDag-Erling Smørgrav #include "auth.h"
36761efaa7SDag-Erling Smørgrav #ifdef GSSAPI
37761efaa7SDag-Erling Smørgrav #include "ssh-gss.h"
38761efaa7SDag-Erling Smørgrav #endif
39761efaa7SDag-Erling Smørgrav #include "monitor_wrap.h"
40b66f2d16SKris Kennaway 
41b66f2d16SKris Kennaway /* Flags set authorized_keys flags */
42b66f2d16SKris Kennaway int no_port_forwarding_flag = 0;
43b66f2d16SKris Kennaway int no_agent_forwarding_flag = 0;
44b66f2d16SKris Kennaway int no_x11_forwarding_flag = 0;
45b66f2d16SKris Kennaway int no_pty_flag = 0;
46d4af9e69SDag-Erling Smørgrav int no_user_rc = 0;
47b66f2d16SKris Kennaway 
48b66f2d16SKris Kennaway /* "command=" option. */
49b66f2d16SKris Kennaway char *forced_command = NULL;
50b66f2d16SKris Kennaway 
51b66f2d16SKris Kennaway /* "environment=" options. */
52b66f2d16SKris Kennaway struct envstring *custom_environment = NULL;
53b66f2d16SKris Kennaway 
54021d409fSDag-Erling Smørgrav /* "tunnel=" option. */
55021d409fSDag-Erling Smørgrav int forced_tun_device = -1;
56021d409fSDag-Erling Smørgrav 
571e8db6e2SBrian Feldman extern ServerOptions options;
581e8db6e2SBrian Feldman 
595b9b2fafSBrian Feldman void
605b9b2fafSBrian Feldman auth_clear_options(void)
615b9b2fafSBrian Feldman {
625b9b2fafSBrian Feldman 	no_agent_forwarding_flag = 0;
635b9b2fafSBrian Feldman 	no_port_forwarding_flag = 0;
645b9b2fafSBrian Feldman 	no_pty_flag = 0;
655b9b2fafSBrian Feldman 	no_x11_forwarding_flag = 0;
66d4af9e69SDag-Erling Smørgrav 	no_user_rc = 0;
675b9b2fafSBrian Feldman 	while (custom_environment) {
685b9b2fafSBrian Feldman 		struct envstring *ce = custom_environment;
695b9b2fafSBrian Feldman 		custom_environment = ce->next;
705b9b2fafSBrian Feldman 		xfree(ce->s);
715b9b2fafSBrian Feldman 		xfree(ce);
725b9b2fafSBrian Feldman 	}
735b9b2fafSBrian Feldman 	if (forced_command) {
745b9b2fafSBrian Feldman 		xfree(forced_command);
755b9b2fafSBrian Feldman 		forced_command = NULL;
765b9b2fafSBrian Feldman 	}
77021d409fSDag-Erling Smørgrav 	forced_tun_device = -1;
781e8db6e2SBrian Feldman 	channel_clear_permitted_opens();
79545d5ecaSDag-Erling Smørgrav 	auth_debug_reset();
805b9b2fafSBrian Feldman }
815b9b2fafSBrian Feldman 
821e8db6e2SBrian Feldman /*
831e8db6e2SBrian Feldman  * return 1 if access is granted, 0 if not.
841e8db6e2SBrian Feldman  * side effect: sets key option flags
851e8db6e2SBrian Feldman  */
86b66f2d16SKris Kennaway int
871e8db6e2SBrian Feldman auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
88b66f2d16SKris Kennaway {
89b66f2d16SKris Kennaway 	const char *cp;
901e8db6e2SBrian Feldman 	int i;
915b9b2fafSBrian Feldman 
925b9b2fafSBrian Feldman 	/* reset options */
935b9b2fafSBrian Feldman 	auth_clear_options();
945b9b2fafSBrian Feldman 
951e8db6e2SBrian Feldman 	if (!opts)
961e8db6e2SBrian Feldman 		return 1;
971e8db6e2SBrian Feldman 
981e8db6e2SBrian Feldman 	while (*opts && *opts != ' ' && *opts != '\t') {
99b66f2d16SKris Kennaway 		cp = "no-port-forwarding";
1001e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
101545d5ecaSDag-Erling Smørgrav 			auth_debug_add("Port forwarding disabled.");
102b66f2d16SKris Kennaway 			no_port_forwarding_flag = 1;
1031e8db6e2SBrian Feldman 			opts += strlen(cp);
104b66f2d16SKris Kennaway 			goto next_option;
105b66f2d16SKris Kennaway 		}
106b66f2d16SKris Kennaway 		cp = "no-agent-forwarding";
1071e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
108545d5ecaSDag-Erling Smørgrav 			auth_debug_add("Agent forwarding disabled.");
109b66f2d16SKris Kennaway 			no_agent_forwarding_flag = 1;
1101e8db6e2SBrian Feldman 			opts += strlen(cp);
111b66f2d16SKris Kennaway 			goto next_option;
112b66f2d16SKris Kennaway 		}
113b66f2d16SKris Kennaway 		cp = "no-X11-forwarding";
1141e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
115545d5ecaSDag-Erling Smørgrav 			auth_debug_add("X11 forwarding disabled.");
116b66f2d16SKris Kennaway 			no_x11_forwarding_flag = 1;
1171e8db6e2SBrian Feldman 			opts += strlen(cp);
118b66f2d16SKris Kennaway 			goto next_option;
119b66f2d16SKris Kennaway 		}
120b66f2d16SKris Kennaway 		cp = "no-pty";
1211e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
122545d5ecaSDag-Erling Smørgrav 			auth_debug_add("Pty allocation disabled.");
123b66f2d16SKris Kennaway 			no_pty_flag = 1;
1241e8db6e2SBrian Feldman 			opts += strlen(cp);
125b66f2d16SKris Kennaway 			goto next_option;
126b66f2d16SKris Kennaway 		}
127d4af9e69SDag-Erling Smørgrav 		cp = "no-user-rc";
128d4af9e69SDag-Erling Smørgrav 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
129d4af9e69SDag-Erling Smørgrav 			auth_debug_add("User rc file execution disabled.");
130d4af9e69SDag-Erling Smørgrav 			no_user_rc = 1;
131d4af9e69SDag-Erling Smørgrav 			opts += strlen(cp);
132d4af9e69SDag-Erling Smørgrav 			goto next_option;
133d4af9e69SDag-Erling Smørgrav 		}
134b66f2d16SKris Kennaway 		cp = "command=\"";
1351e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1361e8db6e2SBrian Feldman 			opts += strlen(cp);
1371e8db6e2SBrian Feldman 			forced_command = xmalloc(strlen(opts) + 1);
138b66f2d16SKris Kennaway 			i = 0;
1391e8db6e2SBrian Feldman 			while (*opts) {
1401e8db6e2SBrian Feldman 				if (*opts == '"')
141b66f2d16SKris Kennaway 					break;
1421e8db6e2SBrian Feldman 				if (*opts == '\\' && opts[1] == '"') {
1431e8db6e2SBrian Feldman 					opts += 2;
144b66f2d16SKris Kennaway 					forced_command[i++] = '"';
145b66f2d16SKris Kennaway 					continue;
146b66f2d16SKris Kennaway 				}
1471e8db6e2SBrian Feldman 				forced_command[i++] = *opts++;
148b66f2d16SKris Kennaway 			}
1491e8db6e2SBrian Feldman 			if (!*opts) {
150b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
1511e8db6e2SBrian Feldman 				    file, linenum);
152545d5ecaSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: missing end quote",
1531e8db6e2SBrian Feldman 				    file, linenum);
1541e8db6e2SBrian Feldman 				xfree(forced_command);
1551e8db6e2SBrian Feldman 				forced_command = NULL;
1561e8db6e2SBrian Feldman 				goto bad_option;
157b66f2d16SKris Kennaway 			}
158761efaa7SDag-Erling Smørgrav 			forced_command[i] = '\0';
159545d5ecaSDag-Erling Smørgrav 			auth_debug_add("Forced command: %.900s", forced_command);
1601e8db6e2SBrian Feldman 			opts++;
161b66f2d16SKris Kennaway 			goto next_option;
162b66f2d16SKris Kennaway 		}
163b66f2d16SKris Kennaway 		cp = "environment=\"";
1644b17dab0SDag-Erling Smørgrav 		if (options.permit_user_env &&
1654b17dab0SDag-Erling Smørgrav 		    strncasecmp(opts, cp, strlen(cp)) == 0) {
166b66f2d16SKris Kennaway 			char *s;
167b66f2d16SKris Kennaway 			struct envstring *new_envstring;
1681e8db6e2SBrian Feldman 
1691e8db6e2SBrian Feldman 			opts += strlen(cp);
1701e8db6e2SBrian Feldman 			s = xmalloc(strlen(opts) + 1);
171b66f2d16SKris Kennaway 			i = 0;
1721e8db6e2SBrian Feldman 			while (*opts) {
1731e8db6e2SBrian Feldman 				if (*opts == '"')
174b66f2d16SKris Kennaway 					break;
1751e8db6e2SBrian Feldman 				if (*opts == '\\' && opts[1] == '"') {
1761e8db6e2SBrian Feldman 					opts += 2;
177b66f2d16SKris Kennaway 					s[i++] = '"';
178b66f2d16SKris Kennaway 					continue;
179b66f2d16SKris Kennaway 				}
1801e8db6e2SBrian Feldman 				s[i++] = *opts++;
181b66f2d16SKris Kennaway 			}
1821e8db6e2SBrian Feldman 			if (!*opts) {
183b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
1841e8db6e2SBrian Feldman 				    file, linenum);
185545d5ecaSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: missing end quote",
1861e8db6e2SBrian Feldman 				    file, linenum);
1871e8db6e2SBrian Feldman 				xfree(s);
1881e8db6e2SBrian Feldman 				goto bad_option;
189b66f2d16SKris Kennaway 			}
190761efaa7SDag-Erling Smørgrav 			s[i] = '\0';
191545d5ecaSDag-Erling Smørgrav 			auth_debug_add("Adding to environment: %.900s", s);
192b66f2d16SKris Kennaway 			debug("Adding to environment: %.900s", s);
1931e8db6e2SBrian Feldman 			opts++;
194b66f2d16SKris Kennaway 			new_envstring = xmalloc(sizeof(struct envstring));
195b66f2d16SKris Kennaway 			new_envstring->s = s;
196b66f2d16SKris Kennaway 			new_envstring->next = custom_environment;
197b66f2d16SKris Kennaway 			custom_environment = new_envstring;
198b66f2d16SKris Kennaway 			goto next_option;
199b66f2d16SKris Kennaway 		}
200b66f2d16SKris Kennaway 		cp = "from=\"";
2011e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
2021e8db6e2SBrian Feldman 			const char *remote_ip = get_remote_ipaddr();
2031e8db6e2SBrian Feldman 			const char *remote_host = get_canonical_hostname(
204d95e11bfSDag-Erling Smørgrav 			    options.use_dns);
2051e8db6e2SBrian Feldman 			char *patterns = xmalloc(strlen(opts) + 1);
2061e8db6e2SBrian Feldman 
2071e8db6e2SBrian Feldman 			opts += strlen(cp);
208b66f2d16SKris Kennaway 			i = 0;
2091e8db6e2SBrian Feldman 			while (*opts) {
2101e8db6e2SBrian Feldman 				if (*opts == '"')
211b66f2d16SKris Kennaway 					break;
2121e8db6e2SBrian Feldman 				if (*opts == '\\' && opts[1] == '"') {
2131e8db6e2SBrian Feldman 					opts += 2;
214b66f2d16SKris Kennaway 					patterns[i++] = '"';
215b66f2d16SKris Kennaway 					continue;
216b66f2d16SKris Kennaway 				}
2171e8db6e2SBrian Feldman 				patterns[i++] = *opts++;
218b66f2d16SKris Kennaway 			}
2191e8db6e2SBrian Feldman 			if (!*opts) {
220b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
2211e8db6e2SBrian Feldman 				    file, linenum);
222545d5ecaSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: missing end quote",
2231e8db6e2SBrian Feldman 				    file, linenum);
2241e8db6e2SBrian Feldman 				xfree(patterns);
2251e8db6e2SBrian Feldman 				goto bad_option;
226b66f2d16SKris Kennaway 			}
227761efaa7SDag-Erling Smørgrav 			patterns[i] = '\0';
2281e8db6e2SBrian Feldman 			opts++;
229d4af9e69SDag-Erling Smørgrav 			switch (match_host_and_ip(remote_host, remote_ip,
230d4af9e69SDag-Erling Smørgrav 			    patterns)) {
231d4af9e69SDag-Erling Smørgrav 			case 1:
232d4af9e69SDag-Erling Smørgrav 				xfree(patterns);
233d4af9e69SDag-Erling Smørgrav 				/* Host name matches. */
234d4af9e69SDag-Erling Smørgrav 				goto next_option;
235d4af9e69SDag-Erling Smørgrav 			case -1:
236d4af9e69SDag-Erling Smørgrav 				debug("%.100s, line %lu: invalid criteria",
237d4af9e69SDag-Erling Smørgrav 				    file, linenum);
238d4af9e69SDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: "
239d4af9e69SDag-Erling Smørgrav 				    "invalid criteria", file, linenum);
240d4af9e69SDag-Erling Smørgrav 				/* FALLTHROUGH */
241d4af9e69SDag-Erling Smørgrav 			case 0:
242b66f2d16SKris Kennaway 				xfree(patterns);
243d95e11bfSDag-Erling Smørgrav 				logit("Authentication tried for %.100s with "
2441e8db6e2SBrian Feldman 				    "correct key but not from a permitted "
2451e8db6e2SBrian Feldman 				    "host (host=%.200s, ip=%.200s).",
2461e8db6e2SBrian Feldman 				    pw->pw_name, remote_host, remote_ip);
247545d5ecaSDag-Erling Smørgrav 				auth_debug_add("Your host '%.200s' is not "
2481e8db6e2SBrian Feldman 				    "permitted to use this key for login.",
2491e8db6e2SBrian Feldman 				    remote_host);
250d4af9e69SDag-Erling Smørgrav 				break;
251d4af9e69SDag-Erling Smørgrav 			}
252b66f2d16SKris Kennaway 			/* deny access */
253b66f2d16SKris Kennaway 			return 0;
254b66f2d16SKris Kennaway 		}
2551e8db6e2SBrian Feldman 		cp = "permitopen=\"";
2561e8db6e2SBrian Feldman 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
2575e8dbd04SDag-Erling Smørgrav 			char *host, *p;
2581e8db6e2SBrian Feldman 			u_short port;
2591e8db6e2SBrian Feldman 			char *patterns = xmalloc(strlen(opts) + 1);
2601e8db6e2SBrian Feldman 
2611e8db6e2SBrian Feldman 			opts += strlen(cp);
2621e8db6e2SBrian Feldman 			i = 0;
2631e8db6e2SBrian Feldman 			while (*opts) {
2641e8db6e2SBrian Feldman 				if (*opts == '"')
2651e8db6e2SBrian Feldman 					break;
2661e8db6e2SBrian Feldman 				if (*opts == '\\' && opts[1] == '"') {
2671e8db6e2SBrian Feldman 					opts += 2;
2681e8db6e2SBrian Feldman 					patterns[i++] = '"';
2691e8db6e2SBrian Feldman 					continue;
2701e8db6e2SBrian Feldman 				}
2711e8db6e2SBrian Feldman 				patterns[i++] = *opts++;
2721e8db6e2SBrian Feldman 			}
2731e8db6e2SBrian Feldman 			if (!*opts) {
2741e8db6e2SBrian Feldman 				debug("%.100s, line %lu: missing end quote",
2751e8db6e2SBrian Feldman 				    file, linenum);
2765e8dbd04SDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: missing "
2775e8dbd04SDag-Erling Smørgrav 				    "end quote", file, linenum);
2781e8db6e2SBrian Feldman 				xfree(patterns);
2791e8db6e2SBrian Feldman 				goto bad_option;
2801e8db6e2SBrian Feldman 			}
281761efaa7SDag-Erling Smørgrav 			patterns[i] = '\0';
2821e8db6e2SBrian Feldman 			opts++;
2835e8dbd04SDag-Erling Smørgrav 			p = patterns;
2845e8dbd04SDag-Erling Smørgrav 			host = hpdelim(&p);
2855e8dbd04SDag-Erling Smørgrav 			if (host == NULL || strlen(host) >= NI_MAXHOST) {
2865e8dbd04SDag-Erling Smørgrav 				debug("%.100s, line %lu: Bad permitopen "
2875e8dbd04SDag-Erling Smørgrav 				    "specification <%.100s>", file, linenum,
2885e8dbd04SDag-Erling Smørgrav 				    patterns);
289545d5ecaSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: "
2905e8dbd04SDag-Erling Smørgrav 				    "Bad permitopen specification", file,
2915e8dbd04SDag-Erling Smørgrav 				    linenum);
2921e8db6e2SBrian Feldman 				xfree(patterns);
2931e8db6e2SBrian Feldman 				goto bad_option;
2941e8db6e2SBrian Feldman 			}
2955e8dbd04SDag-Erling Smørgrav 			host = cleanhostname(host);
2965e8dbd04SDag-Erling Smørgrav 			if (p == NULL || (port = a2port(p)) == 0) {
2975e8dbd04SDag-Erling Smørgrav 				debug("%.100s, line %lu: Bad permitopen port "
2985e8dbd04SDag-Erling Smørgrav 				    "<%.100s>", file, linenum, p ? p : "");
299545d5ecaSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: "
300ae1f160dSDag-Erling Smørgrav 				    "Bad permitopen port", file, linenum);
3011e8db6e2SBrian Feldman 				xfree(patterns);
3021e8db6e2SBrian Feldman 				goto bad_option;
3031e8db6e2SBrian Feldman 			}
3041e8db6e2SBrian Feldman 			if (options.allow_tcp_forwarding)
305ae1f160dSDag-Erling Smørgrav 				channel_add_permitted_opens(host, port);
3061e8db6e2SBrian Feldman 			xfree(patterns);
3071e8db6e2SBrian Feldman 			goto next_option;
3081e8db6e2SBrian Feldman 		}
309021d409fSDag-Erling Smørgrav 		cp = "tunnel=\"";
310021d409fSDag-Erling Smørgrav 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
311021d409fSDag-Erling Smørgrav 			char *tun = NULL;
312021d409fSDag-Erling Smørgrav 			opts += strlen(cp);
313021d409fSDag-Erling Smørgrav 			tun = xmalloc(strlen(opts) + 1);
314021d409fSDag-Erling Smørgrav 			i = 0;
315021d409fSDag-Erling Smørgrav 			while (*opts) {
316021d409fSDag-Erling Smørgrav 				if (*opts == '"')
317021d409fSDag-Erling Smørgrav 					break;
318021d409fSDag-Erling Smørgrav 				tun[i++] = *opts++;
319021d409fSDag-Erling Smørgrav 			}
320021d409fSDag-Erling Smørgrav 			if (!*opts) {
321021d409fSDag-Erling Smørgrav 				debug("%.100s, line %lu: missing end quote",
322021d409fSDag-Erling Smørgrav 				    file, linenum);
323021d409fSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: missing end quote",
324021d409fSDag-Erling Smørgrav 				    file, linenum);
325021d409fSDag-Erling Smørgrav 				xfree(tun);
326021d409fSDag-Erling Smørgrav 				forced_tun_device = -1;
327021d409fSDag-Erling Smørgrav 				goto bad_option;
328021d409fSDag-Erling Smørgrav 			}
329761efaa7SDag-Erling Smørgrav 			tun[i] = '\0';
330021d409fSDag-Erling Smørgrav 			forced_tun_device = a2tun(tun, NULL);
331021d409fSDag-Erling Smørgrav 			xfree(tun);
332021d409fSDag-Erling Smørgrav 			if (forced_tun_device == SSH_TUNID_ERR) {
333021d409fSDag-Erling Smørgrav 				debug("%.100s, line %lu: invalid tun device",
334021d409fSDag-Erling Smørgrav 				    file, linenum);
335021d409fSDag-Erling Smørgrav 				auth_debug_add("%.100s, line %lu: invalid tun device",
336021d409fSDag-Erling Smørgrav 				    file, linenum);
337021d409fSDag-Erling Smørgrav 				forced_tun_device = -1;
338021d409fSDag-Erling Smørgrav 				goto bad_option;
339021d409fSDag-Erling Smørgrav 			}
340021d409fSDag-Erling Smørgrav 			auth_debug_add("Forced tun device: %d", forced_tun_device);
341021d409fSDag-Erling Smørgrav 			opts++;
342021d409fSDag-Erling Smørgrav 			goto next_option;
343021d409fSDag-Erling Smørgrav 		}
344b66f2d16SKris Kennaway next_option:
345b66f2d16SKris Kennaway 		/*
346b66f2d16SKris Kennaway 		 * Skip the comma, and move to the next option
347b66f2d16SKris Kennaway 		 * (or break out if there are no more).
348b66f2d16SKris Kennaway 		 */
3491e8db6e2SBrian Feldman 		if (!*opts)
350b66f2d16SKris Kennaway 			fatal("Bugs in auth-options.c option processing.");
3511e8db6e2SBrian Feldman 		if (*opts == ' ' || *opts == '\t')
352b66f2d16SKris Kennaway 			break;		/* End of options. */
3531e8db6e2SBrian Feldman 		if (*opts != ',')
354b66f2d16SKris Kennaway 			goto bad_option;
3551e8db6e2SBrian Feldman 		opts++;
356b66f2d16SKris Kennaway 		/* Process the next option. */
357b66f2d16SKris Kennaway 	}
358545d5ecaSDag-Erling Smørgrav 
359545d5ecaSDag-Erling Smørgrav 	if (!use_privsep)
360545d5ecaSDag-Erling Smørgrav 		auth_debug_send();
361545d5ecaSDag-Erling Smørgrav 
362b66f2d16SKris Kennaway 	/* grant access */
363b66f2d16SKris Kennaway 	return 1;
364b66f2d16SKris Kennaway 
365b66f2d16SKris Kennaway bad_option:
366d95e11bfSDag-Erling Smørgrav 	logit("Bad options in %.100s file, line %lu: %.50s",
3671e8db6e2SBrian Feldman 	    file, linenum, opts);
368545d5ecaSDag-Erling Smørgrav 	auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
3691e8db6e2SBrian Feldman 	    file, linenum, opts);
370545d5ecaSDag-Erling Smørgrav 
371545d5ecaSDag-Erling Smørgrav 	if (!use_privsep)
372545d5ecaSDag-Erling Smørgrav 		auth_debug_send();
373545d5ecaSDag-Erling Smørgrav 
374b66f2d16SKris Kennaway 	/* deny access */
375b66f2d16SKris Kennaway 	return 0;
376b66f2d16SKris Kennaway }
377