blob: 181bf73215e7db96a494d4a7b5b861297ac3ded9 [file] [log] [blame]
Damien Millere4340be2000-09-16 13:29:08 +11001/*
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 * RSA-based authentication. This code determines whether to admit a login
6 * based on RSA authentication. This file also contains functions to check
7 * validity of the host key.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 */
15
Damien Millerf6d9e222000-06-18 14:50:44 +100016#include "includes.h"
Ben Lindstrom14920292000-11-21 21:24:55 +000017RCSID("$OpenBSD: auth-options.c,v 1.6 2000/11/15 22:31:36 markus Exp $");
Damien Millerf6d9e222000-06-18 14:50:44 +100018
19#include "ssh.h"
20#include "packet.h"
21#include "xmalloc.h"
22#include "match.h"
23
24/* Flags set authorized_keys flags */
25int no_port_forwarding_flag = 0;
26int no_agent_forwarding_flag = 0;
27int no_x11_forwarding_flag = 0;
28int no_pty_flag = 0;
29
30/* "command=" option. */
31char *forced_command = NULL;
32
33/* "environment=" options. */
34struct envstring *custom_environment = NULL;
35
Damien Miller874d77b2000-10-14 16:23:11 +110036void
37auth_clear_options(void)
38{
39 no_agent_forwarding_flag = 0;
40 no_port_forwarding_flag = 0;
41 no_pty_flag = 0;
42 no_x11_forwarding_flag = 0;
43 while (custom_environment) {
44 struct envstring *ce = custom_environment;
45 custom_environment = ce->next;
46 xfree(ce->s);
47 xfree(ce);
48 }
49 if (forced_command) {
50 xfree(forced_command);
51 forced_command = NULL;
52 }
53}
54
Damien Millerf6d9e222000-06-18 14:50:44 +100055/* return 1 if access is granted, 0 if not. side effect: sets key option flags */
56int
57auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
58{
59 const char *cp;
60 if (!options)
61 return 1;
Damien Miller874d77b2000-10-14 16:23:11 +110062
63 /* reset options */
64 auth_clear_options();
65
Damien Millerf6d9e222000-06-18 14:50:44 +100066 while (*options && *options != ' ' && *options != '\t') {
67 cp = "no-port-forwarding";
Ben Lindstrom14920292000-11-21 21:24:55 +000068 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +100069 packet_send_debug("Port forwarding disabled.");
70 no_port_forwarding_flag = 1;
71 options += strlen(cp);
72 goto next_option;
73 }
74 cp = "no-agent-forwarding";
Ben Lindstrom14920292000-11-21 21:24:55 +000075 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +100076 packet_send_debug("Agent forwarding disabled.");
77 no_agent_forwarding_flag = 1;
78 options += strlen(cp);
79 goto next_option;
80 }
81 cp = "no-X11-forwarding";
Ben Lindstrom14920292000-11-21 21:24:55 +000082 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +100083 packet_send_debug("X11 forwarding disabled.");
84 no_x11_forwarding_flag = 1;
85 options += strlen(cp);
86 goto next_option;
87 }
88 cp = "no-pty";
Ben Lindstrom14920292000-11-21 21:24:55 +000089 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +100090 packet_send_debug("Pty allocation disabled.");
91 no_pty_flag = 1;
92 options += strlen(cp);
93 goto next_option;
94 }
95 cp = "command=\"";
Ben Lindstrom14920292000-11-21 21:24:55 +000096 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +100097 int i;
98 options += strlen(cp);
99 forced_command = xmalloc(strlen(options) + 1);
100 i = 0;
101 while (*options) {
102 if (*options == '"')
103 break;
104 if (*options == '\\' && options[1] == '"') {
105 options += 2;
106 forced_command[i++] = '"';
107 continue;
108 }
109 forced_command[i++] = *options++;
110 }
111 if (!*options) {
112 debug("%.100s, line %lu: missing end quote",
Damien Miller874d77b2000-10-14 16:23:11 +1100113 SSH_USER_PERMITTED_KEYS, linenum);
Damien Millerf6d9e222000-06-18 14:50:44 +1000114 packet_send_debug("%.100s, line %lu: missing end quote",
Damien Miller874d77b2000-10-14 16:23:11 +1100115 SSH_USER_PERMITTED_KEYS, linenum);
Damien Millerf6d9e222000-06-18 14:50:44 +1000116 continue;
117 }
118 forced_command[i] = 0;
119 packet_send_debug("Forced command: %.900s", forced_command);
120 options++;
121 goto next_option;
122 }
123 cp = "environment=\"";
Ben Lindstrom14920292000-11-21 21:24:55 +0000124 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +1000125 int i;
126 char *s;
127 struct envstring *new_envstring;
128 options += strlen(cp);
129 s = xmalloc(strlen(options) + 1);
130 i = 0;
131 while (*options) {
132 if (*options == '"')
133 break;
134 if (*options == '\\' && options[1] == '"') {
135 options += 2;
136 s[i++] = '"';
137 continue;
138 }
139 s[i++] = *options++;
140 }
141 if (!*options) {
142 debug("%.100s, line %lu: missing end quote",
Damien Miller874d77b2000-10-14 16:23:11 +1100143 SSH_USER_PERMITTED_KEYS, linenum);
Damien Millerf6d9e222000-06-18 14:50:44 +1000144 packet_send_debug("%.100s, line %lu: missing end quote",
Damien Miller874d77b2000-10-14 16:23:11 +1100145 SSH_USER_PERMITTED_KEYS, linenum);
Damien Millerf6d9e222000-06-18 14:50:44 +1000146 continue;
147 }
148 s[i] = 0;
149 packet_send_debug("Adding to environment: %.900s", s);
150 debug("Adding to environment: %.900s", s);
151 options++;
152 new_envstring = xmalloc(sizeof(struct envstring));
153 new_envstring->s = s;
154 new_envstring->next = custom_environment;
155 custom_environment = new_envstring;
156 goto next_option;
157 }
158 cp = "from=\"";
Ben Lindstrom14920292000-11-21 21:24:55 +0000159 if (strncasecmp(options, cp, strlen(cp)) == 0) {
Damien Millerf6d9e222000-06-18 14:50:44 +1000160 int mname, mip;
161 char *patterns = xmalloc(strlen(options) + 1);
162 int i;
163 options += strlen(cp);
164 i = 0;
165 while (*options) {
166 if (*options == '"')
167 break;
168 if (*options == '\\' && options[1] == '"') {
169 options += 2;
170 patterns[i++] = '"';
171 continue;
172 }
173 patterns[i++] = *options++;
174 }
175 if (!*options) {
176 debug("%.100s, line %lu: missing end quote",
177 SSH_USER_PERMITTED_KEYS, linenum);
178 packet_send_debug("%.100s, line %lu: missing end quote",
179 SSH_USER_PERMITTED_KEYS, linenum);
180 continue;
181 }
182 patterns[i] = 0;
183 options++;
184 /*
185 * Deny access if we get a negative
186 * match for the hostname or the ip
187 * or if we get not match at all
188 */
189 mname = match_hostname(get_canonical_hostname(),
190 patterns, strlen(patterns));
191 mip = match_hostname(get_remote_ipaddr(),
192 patterns, strlen(patterns));
193 xfree(patterns);
194 if (mname == -1 || mip == -1 ||
195 (mname != 1 && mip != 1)) {
196 log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
197 pw->pw_name, get_canonical_hostname(),
198 get_remote_ipaddr());
199 packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
200 get_canonical_hostname());
Damien Millerf6d9e222000-06-18 14:50:44 +1000201 /* deny access */
202 return 0;
203 }
204 /* Host name matches. */
205 goto next_option;
206 }
207next_option:
208 /*
209 * Skip the comma, and move to the next option
210 * (or break out if there are no more).
211 */
212 if (!*options)
213 fatal("Bugs in auth-options.c option processing.");
214 if (*options == ' ' || *options == '\t')
215 break; /* End of options. */
216 if (*options != ',')
217 goto bad_option;
218 options++;
219 /* Process the next option. */
220 }
221 /* grant access */
222 return 1;
223
224bad_option:
225 log("Bad options in %.100s file, line %lu: %.50s",
226 SSH_USER_PERMITTED_KEYS, linenum, options);
227 packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
228 SSH_USER_PERMITTED_KEYS, linenum, options);
229 /* deny access */
230 return 0;
231}