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