xref: /freebsd/crypto/openssh/auth-options.c (revision 5b9b2fafd4d6d82af10bf630cbfc9393b8ed1d0a)
1b66f2d16SKris Kennaway /*
2b66f2d16SKris Kennaway  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3b66f2d16SKris Kennaway  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4b66f2d16SKris Kennaway  *                    All rights reserved
5b66f2d16SKris Kennaway  * RSA-based authentication.  This code determines whether to admit a login
6b66f2d16SKris Kennaway  * based on RSA authentication.  This file also contains functions to check
7b66f2d16SKris Kennaway  * validity of the host key.
8b66f2d16SKris Kennaway  *
9b66f2d16SKris Kennaway  * As far as I am concerned, the code I have written for this software
10b66f2d16SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
11b66f2d16SKris Kennaway  * software must be clearly marked as such, and if the derived work is
12b66f2d16SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
13b66f2d16SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
14b66f2d16SKris Kennaway  */
15b66f2d16SKris Kennaway 
16b66f2d16SKris Kennaway #include "includes.h"
175b9b2fafSBrian Feldman RCSID("$OpenBSD: auth-options.c,v 1.5 2000/10/09 21:32:34 markus Exp $");
18b66f2d16SKris Kennaway 
19b66f2d16SKris Kennaway #include "ssh.h"
20b66f2d16SKris Kennaway #include "packet.h"
21b66f2d16SKris Kennaway #include "xmalloc.h"
22b66f2d16SKris Kennaway #include "match.h"
23b66f2d16SKris Kennaway 
24b66f2d16SKris Kennaway /* Flags set authorized_keys flags */
25b66f2d16SKris Kennaway int no_port_forwarding_flag = 0;
26b66f2d16SKris Kennaway int no_agent_forwarding_flag = 0;
27b66f2d16SKris Kennaway int no_x11_forwarding_flag = 0;
28b66f2d16SKris Kennaway int no_pty_flag = 0;
29b66f2d16SKris Kennaway 
30b66f2d16SKris Kennaway /* "command=" option. */
31b66f2d16SKris Kennaway char *forced_command = NULL;
32b66f2d16SKris Kennaway 
33b66f2d16SKris Kennaway /* "environment=" options. */
34b66f2d16SKris Kennaway struct envstring *custom_environment = NULL;
35b66f2d16SKris Kennaway 
365b9b2fafSBrian Feldman void
375b9b2fafSBrian Feldman auth_clear_options(void)
385b9b2fafSBrian Feldman {
395b9b2fafSBrian Feldman 	no_agent_forwarding_flag = 0;
405b9b2fafSBrian Feldman 	no_port_forwarding_flag = 0;
415b9b2fafSBrian Feldman 	no_pty_flag = 0;
425b9b2fafSBrian Feldman 	no_x11_forwarding_flag = 0;
435b9b2fafSBrian Feldman 	while (custom_environment) {
445b9b2fafSBrian Feldman 		struct envstring *ce = custom_environment;
455b9b2fafSBrian Feldman 		custom_environment = ce->next;
465b9b2fafSBrian Feldman 		xfree(ce->s);
475b9b2fafSBrian Feldman 		xfree(ce);
485b9b2fafSBrian Feldman 	}
495b9b2fafSBrian Feldman 	if (forced_command) {
505b9b2fafSBrian Feldman 		xfree(forced_command);
515b9b2fafSBrian Feldman 		forced_command = NULL;
525b9b2fafSBrian Feldman 	}
535b9b2fafSBrian Feldman }
545b9b2fafSBrian Feldman 
55b66f2d16SKris Kennaway /* return 1 if access is granted, 0 if not. side effect: sets key option flags */
56b66f2d16SKris Kennaway int
57b66f2d16SKris Kennaway auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
58b66f2d16SKris Kennaway {
59b66f2d16SKris Kennaway 	const char *cp;
60b66f2d16SKris Kennaway 	if (!options)
61b66f2d16SKris Kennaway 		return 1;
625b9b2fafSBrian Feldman 
635b9b2fafSBrian Feldman 	/* reset options */
645b9b2fafSBrian Feldman 	auth_clear_options();
655b9b2fafSBrian Feldman 
66b66f2d16SKris Kennaway 	while (*options && *options != ' ' && *options != '\t') {
67b66f2d16SKris Kennaway 		cp = "no-port-forwarding";
68b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
69b66f2d16SKris Kennaway 			packet_send_debug("Port forwarding disabled.");
70b66f2d16SKris Kennaway 			no_port_forwarding_flag = 1;
71b66f2d16SKris Kennaway 			options += strlen(cp);
72b66f2d16SKris Kennaway 			goto next_option;
73b66f2d16SKris Kennaway 		}
74b66f2d16SKris Kennaway 		cp = "no-agent-forwarding";
75b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
76b66f2d16SKris Kennaway 			packet_send_debug("Agent forwarding disabled.");
77b66f2d16SKris Kennaway 			no_agent_forwarding_flag = 1;
78b66f2d16SKris Kennaway 			options += strlen(cp);
79b66f2d16SKris Kennaway 			goto next_option;
80b66f2d16SKris Kennaway 		}
81b66f2d16SKris Kennaway 		cp = "no-X11-forwarding";
82b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
83b66f2d16SKris Kennaway 			packet_send_debug("X11 forwarding disabled.");
84b66f2d16SKris Kennaway 			no_x11_forwarding_flag = 1;
85b66f2d16SKris Kennaway 			options += strlen(cp);
86b66f2d16SKris Kennaway 			goto next_option;
87b66f2d16SKris Kennaway 		}
88b66f2d16SKris Kennaway 		cp = "no-pty";
89b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
90b66f2d16SKris Kennaway 			packet_send_debug("Pty allocation disabled.");
91b66f2d16SKris Kennaway 			no_pty_flag = 1;
92b66f2d16SKris Kennaway 			options += strlen(cp);
93b66f2d16SKris Kennaway 			goto next_option;
94b66f2d16SKris Kennaway 		}
95b66f2d16SKris Kennaway 		cp = "command=\"";
96b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
97b66f2d16SKris Kennaway 			int i;
98b66f2d16SKris Kennaway 			options += strlen(cp);
99b66f2d16SKris Kennaway 			forced_command = xmalloc(strlen(options) + 1);
100b66f2d16SKris Kennaway 			i = 0;
101b66f2d16SKris Kennaway 			while (*options) {
102b66f2d16SKris Kennaway 				if (*options == '"')
103b66f2d16SKris Kennaway 					break;
104b66f2d16SKris Kennaway 				if (*options == '\\' && options[1] == '"') {
105b66f2d16SKris Kennaway 					options += 2;
106b66f2d16SKris Kennaway 					forced_command[i++] = '"';
107b66f2d16SKris Kennaway 					continue;
108b66f2d16SKris Kennaway 				}
109b66f2d16SKris Kennaway 				forced_command[i++] = *options++;
110b66f2d16SKris Kennaway 			}
111b66f2d16SKris Kennaway 			if (!*options) {
112b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
113b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
114b66f2d16SKris Kennaway 				packet_send_debug("%.100s, line %lu: missing end quote",
115b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
116b66f2d16SKris Kennaway 				continue;
117b66f2d16SKris Kennaway 			}
118b66f2d16SKris Kennaway 			forced_command[i] = 0;
119b66f2d16SKris Kennaway 			packet_send_debug("Forced command: %.900s", forced_command);
120b66f2d16SKris Kennaway 			options++;
121b66f2d16SKris Kennaway 			goto next_option;
122b66f2d16SKris Kennaway 		}
123b66f2d16SKris Kennaway 		cp = "environment=\"";
124b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
125b66f2d16SKris Kennaway 			int i;
126b66f2d16SKris Kennaway 			char *s;
127b66f2d16SKris Kennaway 			struct envstring *new_envstring;
128b66f2d16SKris Kennaway 			options += strlen(cp);
129b66f2d16SKris Kennaway 			s = xmalloc(strlen(options) + 1);
130b66f2d16SKris Kennaway 			i = 0;
131b66f2d16SKris Kennaway 			while (*options) {
132b66f2d16SKris Kennaway 				if (*options == '"')
133b66f2d16SKris Kennaway 					break;
134b66f2d16SKris Kennaway 				if (*options == '\\' && options[1] == '"') {
135b66f2d16SKris Kennaway 					options += 2;
136b66f2d16SKris Kennaway 					s[i++] = '"';
137b66f2d16SKris Kennaway 					continue;
138b66f2d16SKris Kennaway 				}
139b66f2d16SKris Kennaway 				s[i++] = *options++;
140b66f2d16SKris Kennaway 			}
141b66f2d16SKris Kennaway 			if (!*options) {
142b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
143b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
144b66f2d16SKris Kennaway 				packet_send_debug("%.100s, line %lu: missing end quote",
145b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
146b66f2d16SKris Kennaway 				continue;
147b66f2d16SKris Kennaway 			}
148b66f2d16SKris Kennaway 			s[i] = 0;
149b66f2d16SKris Kennaway 			packet_send_debug("Adding to environment: %.900s", s);
150b66f2d16SKris Kennaway 			debug("Adding to environment: %.900s", s);
151b66f2d16SKris Kennaway 			options++;
152b66f2d16SKris Kennaway 			new_envstring = xmalloc(sizeof(struct envstring));
153b66f2d16SKris Kennaway 			new_envstring->s = s;
154b66f2d16SKris Kennaway 			new_envstring->next = custom_environment;
155b66f2d16SKris Kennaway 			custom_environment = new_envstring;
156b66f2d16SKris Kennaway 			goto next_option;
157b66f2d16SKris Kennaway 		}
158b66f2d16SKris Kennaway 		cp = "from=\"";
159b66f2d16SKris Kennaway 		if (strncmp(options, cp, strlen(cp)) == 0) {
160b66f2d16SKris Kennaway 			int mname, mip;
161b66f2d16SKris Kennaway 			char *patterns = xmalloc(strlen(options) + 1);
162b66f2d16SKris Kennaway 			int i;
163b66f2d16SKris Kennaway 			options += strlen(cp);
164b66f2d16SKris Kennaway 			i = 0;
165b66f2d16SKris Kennaway 			while (*options) {
166b66f2d16SKris Kennaway 				if (*options == '"')
167b66f2d16SKris Kennaway 					break;
168b66f2d16SKris Kennaway 				if (*options == '\\' && options[1] == '"') {
169b66f2d16SKris Kennaway 					options += 2;
170b66f2d16SKris Kennaway 					patterns[i++] = '"';
171b66f2d16SKris Kennaway 					continue;
172b66f2d16SKris Kennaway 				}
173b66f2d16SKris Kennaway 				patterns[i++] = *options++;
174b66f2d16SKris Kennaway 			}
175b66f2d16SKris Kennaway 			if (!*options) {
176b66f2d16SKris Kennaway 				debug("%.100s, line %lu: missing end quote",
177b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
178b66f2d16SKris Kennaway 				packet_send_debug("%.100s, line %lu: missing end quote",
179b66f2d16SKris Kennaway 				    SSH_USER_PERMITTED_KEYS, linenum);
180b66f2d16SKris Kennaway 				continue;
181b66f2d16SKris Kennaway 			}
182b66f2d16SKris Kennaway 			patterns[i] = 0;
183b66f2d16SKris Kennaway 			options++;
184b66f2d16SKris Kennaway 			/*
185b66f2d16SKris Kennaway 			 * Deny access if we get a negative
186b66f2d16SKris Kennaway 			 * match for the hostname or the ip
187b66f2d16SKris Kennaway 			 * or if we get not match at all
188b66f2d16SKris Kennaway 			 */
189b66f2d16SKris Kennaway 			mname = match_hostname(get_canonical_hostname(),
190b66f2d16SKris Kennaway 			    patterns, strlen(patterns));
191b66f2d16SKris Kennaway 			mip = match_hostname(get_remote_ipaddr(),
192b66f2d16SKris Kennaway 			    patterns, strlen(patterns));
193b66f2d16SKris Kennaway 			xfree(patterns);
194b66f2d16SKris Kennaway 			if (mname == -1 || mip == -1 ||
195b66f2d16SKris Kennaway 			    (mname != 1 && mip != 1)) {
196b66f2d16SKris Kennaway 				log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
197b66f2d16SKris Kennaway 				    pw->pw_name, get_canonical_hostname(),
198b66f2d16SKris Kennaway 				    get_remote_ipaddr());
199b66f2d16SKris Kennaway 				packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
200b66f2d16SKris Kennaway 				get_canonical_hostname());
201b66f2d16SKris Kennaway 				/* deny access */
202b66f2d16SKris Kennaway 				return 0;
203b66f2d16SKris Kennaway 			}
204b66f2d16SKris Kennaway 			/* Host name matches. */
205b66f2d16SKris Kennaway 			goto next_option;
206b66f2d16SKris Kennaway 		}
207b66f2d16SKris Kennaway next_option:
208b66f2d16SKris Kennaway 		/*
209b66f2d16SKris Kennaway 		 * Skip the comma, and move to the next option
210b66f2d16SKris Kennaway 		 * (or break out if there are no more).
211b66f2d16SKris Kennaway 		 */
212b66f2d16SKris Kennaway 		if (!*options)
213b66f2d16SKris Kennaway 			fatal("Bugs in auth-options.c option processing.");
214b66f2d16SKris Kennaway 		if (*options == ' ' || *options == '\t')
215b66f2d16SKris Kennaway 			break;		/* End of options. */
216b66f2d16SKris Kennaway 		if (*options != ',')
217b66f2d16SKris Kennaway 			goto bad_option;
218b66f2d16SKris Kennaway 		options++;
219b66f2d16SKris Kennaway 		/* Process the next option. */
220b66f2d16SKris Kennaway 	}
221b66f2d16SKris Kennaway 	/* grant access */
222b66f2d16SKris Kennaway 	return 1;
223b66f2d16SKris Kennaway 
224b66f2d16SKris Kennaway bad_option:
225b66f2d16SKris Kennaway 	log("Bad options in %.100s file, line %lu: %.50s",
226b66f2d16SKris Kennaway 	    SSH_USER_PERMITTED_KEYS, linenum, options);
227b66f2d16SKris Kennaway 	packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
228b66f2d16SKris Kennaway 	    SSH_USER_PERMITTED_KEYS, linenum, options);
229b66f2d16SKris Kennaway 	/* deny access */
230b66f2d16SKris Kennaway 	return 0;
231b66f2d16SKris Kennaway }
232