Annotation of src/crypto/external/bsd/openssh/dist/auth-options.c, Revision 1.1.1.1
1.1 christos 1: /* $NetBSD$ */
2: /* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
3: /*
4: * Author: Tatu Ylonen <ylo@cs.hut.fi>
5: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6: * All rights reserved
7: * As far as I am concerned, the code I have written for this software
8: * can be used freely for any purpose. Any derived versions of this
9: * software must be clearly marked as such, and if the derived work is
10: * incompatible with the protocol description in the RFC file, it must be
11: * called by a name other than "ssh" or "Secure Shell".
12: */
13:
14: #include <sys/types.h>
15: #include <sys/queue.h>
16:
17: #include <netdb.h>
18: #include <pwd.h>
19: #include <string.h>
20: #include <stdio.h>
21: #include <stdarg.h>
22:
23: #include "xmalloc.h"
24: #include "match.h"
25: #include "log.h"
26: #include "canohost.h"
27: #include "buffer.h"
28: #include "channels.h"
29: #include "auth-options.h"
30: #include "servconf.h"
31: #include "misc.h"
32: #include "key.h"
33: #include "hostfile.h"
34: #include "auth.h"
35: #ifdef GSSAPI
36: #include "ssh-gss.h"
37: #endif
38: #include "monitor_wrap.h"
39:
40: /* Flags set authorized_keys flags */
41: int no_port_forwarding_flag = 0;
42: int no_agent_forwarding_flag = 0;
43: int no_x11_forwarding_flag = 0;
44: int no_pty_flag = 0;
45: int no_user_rc = 0;
46:
47: /* "command=" option. */
48: char *forced_command = NULL;
49:
50: /* "environment=" options. */
51: struct envstring *custom_environment = NULL;
52:
53: /* "tunnel=" option. */
54: int forced_tun_device = -1;
55:
56: extern ServerOptions options;
57:
58: void
59: auth_clear_options(void)
60: {
61: no_agent_forwarding_flag = 0;
62: no_port_forwarding_flag = 0;
63: no_pty_flag = 0;
64: no_x11_forwarding_flag = 0;
65: no_user_rc = 0;
66: while (custom_environment) {
67: struct envstring *ce = custom_environment;
68: custom_environment = ce->next;
69: xfree(ce->s);
70: xfree(ce);
71: }
72: if (forced_command) {
73: xfree(forced_command);
74: forced_command = NULL;
75: }
76: forced_tun_device = -1;
77: channel_clear_permitted_opens();
78: auth_debug_reset();
79: }
80:
81: /*
82: * return 1 if access is granted, 0 if not.
83: * side effect: sets key option flags
84: */
85: int
86: auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
87: {
88: const char *cp;
89: int i;
90:
91: /* reset options */
92: auth_clear_options();
93:
94: if (!opts)
95: return 1;
96:
97: while (*opts && *opts != ' ' && *opts != '\t') {
98: cp = "no-port-forwarding";
99: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
100: auth_debug_add("Port forwarding disabled.");
101: no_port_forwarding_flag = 1;
102: opts += strlen(cp);
103: goto next_option;
104: }
105: cp = "no-agent-forwarding";
106: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
107: auth_debug_add("Agent forwarding disabled.");
108: no_agent_forwarding_flag = 1;
109: opts += strlen(cp);
110: goto next_option;
111: }
112: cp = "no-X11-forwarding";
113: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
114: auth_debug_add("X11 forwarding disabled.");
115: no_x11_forwarding_flag = 1;
116: opts += strlen(cp);
117: goto next_option;
118: }
119: cp = "no-pty";
120: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
121: auth_debug_add("Pty allocation disabled.");
122: no_pty_flag = 1;
123: opts += strlen(cp);
124: goto next_option;
125: }
126: cp = "no-user-rc";
127: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
128: auth_debug_add("User rc file execution disabled.");
129: no_user_rc = 1;
130: opts += strlen(cp);
131: goto next_option;
132: }
133: cp = "command=\"";
134: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
135: opts += strlen(cp);
136: forced_command = xmalloc(strlen(opts) + 1);
137: i = 0;
138: while (*opts) {
139: if (*opts == '"')
140: break;
141: if (*opts == '\\' && opts[1] == '"') {
142: opts += 2;
143: forced_command[i++] = '"';
144: continue;
145: }
146: forced_command[i++] = *opts++;
147: }
148: if (!*opts) {
149: debug("%.100s, line %lu: missing end quote",
150: file, linenum);
151: auth_debug_add("%.100s, line %lu: missing end quote",
152: file, linenum);
153: xfree(forced_command);
154: forced_command = NULL;
155: goto bad_option;
156: }
157: forced_command[i] = '\0';
158: auth_debug_add("Forced command: %.900s", forced_command);
159: opts++;
160: goto next_option;
161: }
162: cp = "environment=\"";
163: if (options.permit_user_env &&
164: strncasecmp(opts, cp, strlen(cp)) == 0) {
165: char *s;
166: struct envstring *new_envstring;
167:
168: opts += strlen(cp);
169: s = xmalloc(strlen(opts) + 1);
170: i = 0;
171: while (*opts) {
172: if (*opts == '"')
173: break;
174: if (*opts == '\\' && opts[1] == '"') {
175: opts += 2;
176: s[i++] = '"';
177: continue;
178: }
179: s[i++] = *opts++;
180: }
181: if (!*opts) {
182: debug("%.100s, line %lu: missing end quote",
183: file, linenum);
184: auth_debug_add("%.100s, line %lu: missing end quote",
185: file, linenum);
186: xfree(s);
187: goto bad_option;
188: }
189: s[i] = '\0';
190: auth_debug_add("Adding to environment: %.900s", s);
191: debug("Adding to environment: %.900s", s);
192: opts++;
193: new_envstring = xmalloc(sizeof(struct envstring));
194: new_envstring->s = s;
195: new_envstring->next = custom_environment;
196: custom_environment = new_envstring;
197: goto next_option;
198: }
199: cp = "from=\"";
200: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
201: const char *remote_ip = get_remote_ipaddr();
202: const char *remote_host = get_canonical_hostname(
203: options.use_dns);
204: char *patterns = xmalloc(strlen(opts) + 1);
205:
206: opts += strlen(cp);
207: i = 0;
208: while (*opts) {
209: if (*opts == '"')
210: break;
211: if (*opts == '\\' && opts[1] == '"') {
212: opts += 2;
213: patterns[i++] = '"';
214: continue;
215: }
216: patterns[i++] = *opts++;
217: }
218: if (!*opts) {
219: debug("%.100s, line %lu: missing end quote",
220: file, linenum);
221: auth_debug_add("%.100s, line %lu: missing end quote",
222: file, linenum);
223: xfree(patterns);
224: goto bad_option;
225: }
226: patterns[i] = '\0';
227: opts++;
228: switch (match_host_and_ip(remote_host, remote_ip,
229: patterns)) {
230: case 1:
231: xfree(patterns);
232: /* Host name matches. */
233: goto next_option;
234: case -1:
235: debug("%.100s, line %lu: invalid criteria",
236: file, linenum);
237: auth_debug_add("%.100s, line %lu: "
238: "invalid criteria", file, linenum);
239: /* FALLTHROUGH */
240: case 0:
241: xfree(patterns);
242: logit("Authentication tried for %.100s with "
243: "correct key but not from a permitted "
244: "host (host=%.200s, ip=%.200s).",
245: pw->pw_name, remote_host, remote_ip);
246: auth_debug_add("Your host '%.200s' is not "
247: "permitted to use this key for login.",
248: remote_host);
249: break;
250: }
251: /* deny access */
252: return 0;
253: }
254: cp = "permitopen=\"";
255: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
256: char *host, *p;
257: int port;
258: char *patterns = xmalloc(strlen(opts) + 1);
259:
260: opts += strlen(cp);
261: i = 0;
262: while (*opts) {
263: if (*opts == '"')
264: break;
265: if (*opts == '\\' && opts[1] == '"') {
266: opts += 2;
267: patterns[i++] = '"';
268: continue;
269: }
270: patterns[i++] = *opts++;
271: }
272: if (!*opts) {
273: debug("%.100s, line %lu: missing end quote",
274: file, linenum);
275: auth_debug_add("%.100s, line %lu: missing "
276: "end quote", file, linenum);
277: xfree(patterns);
278: goto bad_option;
279: }
280: patterns[i] = '\0';
281: opts++;
282: p = patterns;
283: host = hpdelim(&p);
284: if (host == NULL || strlen(host) >= NI_MAXHOST) {
285: debug("%.100s, line %lu: Bad permitopen "
286: "specification <%.100s>", file, linenum,
287: patterns);
288: auth_debug_add("%.100s, line %lu: "
289: "Bad permitopen specification", file,
290: linenum);
291: xfree(patterns);
292: goto bad_option;
293: }
294: host = cleanhostname(host);
295: if (p == NULL || (port = a2port(p)) <= 0) {
296: debug("%.100s, line %lu: Bad permitopen port "
297: "<%.100s>", file, linenum, p ? p : "");
298: auth_debug_add("%.100s, line %lu: "
299: "Bad permitopen port", file, linenum);
300: xfree(patterns);
301: goto bad_option;
302: }
303: if (options.allow_tcp_forwarding)
304: channel_add_permitted_opens(host, port);
305: xfree(patterns);
306: goto next_option;
307: }
308: cp = "tunnel=\"";
309: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
310: char *tun = NULL;
311: opts += strlen(cp);
312: tun = xmalloc(strlen(opts) + 1);
313: i = 0;
314: while (*opts) {
315: if (*opts == '"')
316: break;
317: tun[i++] = *opts++;
318: }
319: if (!*opts) {
320: debug("%.100s, line %lu: missing end quote",
321: file, linenum);
322: auth_debug_add("%.100s, line %lu: missing end quote",
323: file, linenum);
324: xfree(tun);
325: forced_tun_device = -1;
326: goto bad_option;
327: }
328: tun[i] = '\0';
329: forced_tun_device = a2tun(tun, NULL);
330: xfree(tun);
331: if (forced_tun_device == SSH_TUNID_ERR) {
332: debug("%.100s, line %lu: invalid tun device",
333: file, linenum);
334: auth_debug_add("%.100s, line %lu: invalid tun device",
335: file, linenum);
336: forced_tun_device = -1;
337: goto bad_option;
338: }
339: auth_debug_add("Forced tun device: %d", forced_tun_device);
340: opts++;
341: goto next_option;
342: }
343: next_option:
344: /*
345: * Skip the comma, and move to the next option
346: * (or break out if there are no more).
347: */
348: if (!*opts)
349: fatal("Bugs in auth-options.c option processing.");
350: if (*opts == ' ' || *opts == '\t')
351: break; /* End of options. */
352: if (*opts != ',')
353: goto bad_option;
354: opts++;
355: /* Process the next option. */
356: }
357:
358: if (!use_privsep)
359: auth_debug_send();
360:
361: /* grant access */
362: return 1;
363:
364: bad_option:
365: logit("Bad options in %.100s file, line %lu: %.50s",
366: file, linenum, opts);
367: auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
368: file, linenum, opts);
369:
370: if (!use_privsep)
371: auth_debug_send();
372:
373: /* deny access */
374: return 0;
375: }
CVSweb <webmaster@jp.NetBSD.org>