source: trunk/third/openssh/auth-options.c @ 18759

Revision 18759, 7.5 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
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"
13RCSID("$OpenBSD: auth-options.c,v 1.26 2002/07/30 17:03:55 markus Exp $");
14
15#include "xmalloc.h"
16#include "match.h"
17#include "log.h"
18#include "canohost.h"
19#include "channels.h"
20#include "auth-options.h"
21#include "servconf.h"
22#include "misc.h"
23#include "monitor_wrap.h"
24#include "auth.h"
25
26/* Flags set authorized_keys flags */
27int no_port_forwarding_flag = 0;
28int no_agent_forwarding_flag = 0;
29int no_x11_forwarding_flag = 0;
30int no_pty_flag = 0;
31
32/* "command=" option. */
33char *forced_command = NULL;
34
35/* "environment=" options. */
36struct envstring *custom_environment = NULL;
37
38extern ServerOptions options;
39
40void
41auth_clear_options(void)
42{
43        no_agent_forwarding_flag = 0;
44        no_port_forwarding_flag = 0;
45        no_pty_flag = 0;
46        no_x11_forwarding_flag = 0;
47        while (custom_environment) {
48                struct envstring *ce = custom_environment;
49                custom_environment = ce->next;
50                xfree(ce->s);
51                xfree(ce);
52        }
53        if (forced_command) {
54                xfree(forced_command);
55                forced_command = NULL;
56        }
57        channel_clear_permitted_opens();
58        auth_debug_reset();
59}
60
61/*
62 * return 1 if access is granted, 0 if not.
63 * side effect: sets key option flags
64 */
65int
66auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
67{
68        const char *cp;
69        int i;
70
71        /* reset options */
72        auth_clear_options();
73
74        if (!opts)
75                return 1;
76
77        while (*opts && *opts != ' ' && *opts != '\t') {
78                cp = "no-port-forwarding";
79                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
80                        auth_debug_add("Port forwarding disabled.");
81                        no_port_forwarding_flag = 1;
82                        opts += strlen(cp);
83                        goto next_option;
84                }
85                cp = "no-agent-forwarding";
86                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
87                        auth_debug_add("Agent forwarding disabled.");
88                        no_agent_forwarding_flag = 1;
89                        opts += strlen(cp);
90                        goto next_option;
91                }
92                cp = "no-X11-forwarding";
93                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
94                        auth_debug_add("X11 forwarding disabled.");
95                        no_x11_forwarding_flag = 1;
96                        opts += strlen(cp);
97                        goto next_option;
98                }
99                cp = "no-pty";
100                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
101                        auth_debug_add("Pty allocation disabled.");
102                        no_pty_flag = 1;
103                        opts += strlen(cp);
104                        goto next_option;
105                }
106                cp = "command=\"";
107                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
108                        opts += strlen(cp);
109                        forced_command = xmalloc(strlen(opts) + 1);
110                        i = 0;
111                        while (*opts) {
112                                if (*opts == '"')
113                                        break;
114                                if (*opts == '\\' && opts[1] == '"') {
115                                        opts += 2;
116                                        forced_command[i++] = '"';
117                                        continue;
118                                }
119                                forced_command[i++] = *opts++;
120                        }
121                        if (!*opts) {
122                                debug("%.100s, line %lu: missing end quote",
123                                    file, linenum);
124                                auth_debug_add("%.100s, line %lu: missing end quote",
125                                    file, linenum);
126                                xfree(forced_command);
127                                forced_command = NULL;
128                                goto bad_option;
129                        }
130                        forced_command[i] = 0;
131                        auth_debug_add("Forced command: %.900s", forced_command);
132                        opts++;
133                        goto next_option;
134                }
135                cp = "environment=\"";
136                if (options.permit_user_env &&
137                    strncasecmp(opts, cp, strlen(cp)) == 0) {
138                        char *s;
139                        struct envstring *new_envstring;
140
141                        opts += strlen(cp);
142                        s = xmalloc(strlen(opts) + 1);
143                        i = 0;
144                        while (*opts) {
145                                if (*opts == '"')
146                                        break;
147                                if (*opts == '\\' && opts[1] == '"') {
148                                        opts += 2;
149                                        s[i++] = '"';
150                                        continue;
151                                }
152                                s[i++] = *opts++;
153                        }
154                        if (!*opts) {
155                                debug("%.100s, line %lu: missing end quote",
156                                    file, linenum);
157                                auth_debug_add("%.100s, line %lu: missing end quote",
158                                    file, linenum);
159                                xfree(s);
160                                goto bad_option;
161                        }
162                        s[i] = 0;
163                        auth_debug_add("Adding to environment: %.900s", s);
164                        debug("Adding to environment: %.900s", s);
165                        opts++;
166                        new_envstring = xmalloc(sizeof(struct envstring));
167                        new_envstring->s = s;
168                        new_envstring->next = custom_environment;
169                        custom_environment = new_envstring;
170                        goto next_option;
171                }
172                cp = "from=\"";
173                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
174                        const char *remote_ip = get_remote_ipaddr();
175                        const char *remote_host = get_canonical_hostname(
176                            options.verify_reverse_mapping);
177                        char *patterns = xmalloc(strlen(opts) + 1);
178
179                        opts += strlen(cp);
180                        i = 0;
181                        while (*opts) {
182                                if (*opts == '"')
183                                        break;
184                                if (*opts == '\\' && opts[1] == '"') {
185                                        opts += 2;
186                                        patterns[i++] = '"';
187                                        continue;
188                                }
189                                patterns[i++] = *opts++;
190                        }
191                        if (!*opts) {
192                                debug("%.100s, line %lu: missing end quote",
193                                    file, linenum);
194                                auth_debug_add("%.100s, line %lu: missing end quote",
195                                    file, linenum);
196                                xfree(patterns);
197                                goto bad_option;
198                        }
199                        patterns[i] = 0;
200                        opts++;
201                        if (match_host_and_ip(remote_host, remote_ip,
202                            patterns) != 1) {
203                                xfree(patterns);
204                                log("Authentication tried for %.100s with "
205                                    "correct key but not from a permitted "
206                                    "host (host=%.200s, ip=%.200s).",
207                                    pw->pw_name, remote_host, remote_ip);
208                                auth_debug_add("Your host '%.200s' is not "
209                                    "permitted to use this key for login.",
210                                    remote_host);
211                                /* deny access */
212                                return 0;
213                        }
214                        xfree(patterns);
215                        /* Host name matches. */
216                        goto next_option;
217                }
218                cp = "permitopen=\"";
219                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
220                        char host[256], sport[6];
221                        u_short port;
222                        char *patterns = xmalloc(strlen(opts) + 1);
223
224                        opts += strlen(cp);
225                        i = 0;
226                        while (*opts) {
227                                if (*opts == '"')
228                                        break;
229                                if (*opts == '\\' && opts[1] == '"') {
230                                        opts += 2;
231                                        patterns[i++] = '"';
232                                        continue;
233                                }
234                                patterns[i++] = *opts++;
235                        }
236                        if (!*opts) {
237                                debug("%.100s, line %lu: missing end quote",
238                                    file, linenum);
239                                auth_debug_add("%.100s, line %lu: missing end quote",
240                                    file, linenum);
241                                xfree(patterns);
242                                goto bad_option;
243                        }
244                        patterns[i] = 0;
245                        opts++;
246                        if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 &&
247                            sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
248                                debug("%.100s, line %lu: Bad permitopen specification "
249                                    "<%.100s>", file, linenum, patterns);
250                                auth_debug_add("%.100s, line %lu: "
251                                    "Bad permitopen specification", file, linenum);
252                                xfree(patterns);
253                                goto bad_option;
254                        }
255                        if ((port = a2port(sport)) == 0) {
256                                debug("%.100s, line %lu: Bad permitopen port <%.100s>",
257                                    file, linenum, sport);
258                                auth_debug_add("%.100s, line %lu: "
259                                    "Bad permitopen port", file, linenum);
260                                xfree(patterns);
261                                goto bad_option;
262                        }
263                        if (options.allow_tcp_forwarding)
264                                channel_add_permitted_opens(host, port);
265                        xfree(patterns);
266                        goto next_option;
267                }
268next_option:
269                /*
270                 * Skip the comma, and move to the next option
271                 * (or break out if there are no more).
272                 */
273                if (!*opts)
274                        fatal("Bugs in auth-options.c option processing.");
275                if (*opts == ' ' || *opts == '\t')
276                        break;          /* End of options. */
277                if (*opts != ',')
278                        goto bad_option;
279                opts++;
280                /* Process the next option. */
281        }
282
283        if (!use_privsep)
284                auth_debug_send();
285
286        /* grant access */
287        return 1;
288
289bad_option:
290        log("Bad options in %.100s file, line %lu: %.50s",
291            file, linenum, opts);
292        auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
293            file, linenum, opts);
294
295        if (!use_privsep)
296                auth_debug_send();
297
298        /* deny access */
299        return 0;
300}
Note: See TracBrowser for help on using the repository browser.