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