Annotation of src/usr.bin/ssh/auth-options.c, Revision 1.9
1.3 deraadt 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:
1.1 markus 12: #include "includes.h"
1.9 ! markus 13: RCSID("$OpenBSD: auth-options.c,v 1.8 2001/01/13 18:38:00 markus Exp $");
1.1 markus 14:
15: #include "ssh.h"
16: #include "packet.h"
17: #include "xmalloc.h"
18: #include "match.h"
1.9 ! markus 19: #include "pathnames.h"
1.1 markus 20:
21: /* Flags set authorized_keys flags */
22: int no_port_forwarding_flag = 0;
23: int no_agent_forwarding_flag = 0;
24: int no_x11_forwarding_flag = 0;
25: int no_pty_flag = 0;
26:
27: /* "command=" option. */
28: char *forced_command = NULL;
29:
30: /* "environment=" options. */
31: struct envstring *custom_environment = NULL;
32:
1.5 markus 33: void
34: auth_clear_options(void)
35: {
36: no_agent_forwarding_flag = 0;
37: no_port_forwarding_flag = 0;
38: no_pty_flag = 0;
39: no_x11_forwarding_flag = 0;
40: while (custom_environment) {
41: struct envstring *ce = custom_environment;
42: custom_environment = ce->next;
43: xfree(ce->s);
44: xfree(ce);
45: }
46: if (forced_command) {
47: xfree(forced_command);
48: forced_command = NULL;
49: }
50: }
51:
1.1 markus 52: /* return 1 if access is granted, 0 if not. side effect: sets key option flags */
53: int
1.7 markus 54: auth_parse_options(struct passwd *pw, char *options, u_long linenum)
1.1 markus 55: {
56: const char *cp;
57: if (!options)
58: return 1;
1.5 markus 59:
60: /* reset options */
61: auth_clear_options();
62:
1.1 markus 63: while (*options && *options != ' ' && *options != '\t') {
64: cp = "no-port-forwarding";
1.6 markus 65: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 66: packet_send_debug("Port forwarding disabled.");
67: no_port_forwarding_flag = 1;
68: options += strlen(cp);
69: goto next_option;
70: }
71: cp = "no-agent-forwarding";
1.6 markus 72: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 73: packet_send_debug("Agent forwarding disabled.");
74: no_agent_forwarding_flag = 1;
75: options += strlen(cp);
76: goto next_option;
77: }
78: cp = "no-X11-forwarding";
1.6 markus 79: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 80: packet_send_debug("X11 forwarding disabled.");
81: no_x11_forwarding_flag = 1;
82: options += strlen(cp);
83: goto next_option;
84: }
85: cp = "no-pty";
1.6 markus 86: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 87: packet_send_debug("Pty allocation disabled.");
88: no_pty_flag = 1;
89: options += strlen(cp);
90: goto next_option;
91: }
92: cp = "command=\"";
1.6 markus 93: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 94: int i;
95: options += strlen(cp);
96: forced_command = xmalloc(strlen(options) + 1);
97: i = 0;
98: while (*options) {
99: if (*options == '"')
100: break;
101: if (*options == '\\' && options[1] == '"') {
102: options += 2;
103: forced_command[i++] = '"';
104: continue;
105: }
106: forced_command[i++] = *options++;
107: }
108: if (!*options) {
109: debug("%.100s, line %lu: missing end quote",
1.9 ! markus 110: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 111: packet_send_debug("%.100s, line %lu: missing end quote",
1.9 ! markus 112: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 113: continue;
114: }
115: forced_command[i] = 0;
116: packet_send_debug("Forced command: %.900s", forced_command);
117: options++;
118: goto next_option;
119: }
120: cp = "environment=\"";
1.6 markus 121: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 122: int i;
123: char *s;
124: struct envstring *new_envstring;
125: options += strlen(cp);
126: s = xmalloc(strlen(options) + 1);
127: i = 0;
128: while (*options) {
129: if (*options == '"')
130: break;
131: if (*options == '\\' && options[1] == '"') {
132: options += 2;
133: s[i++] = '"';
134: continue;
135: }
136: s[i++] = *options++;
137: }
138: if (!*options) {
139: debug("%.100s, line %lu: missing end quote",
1.9 ! markus 140: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 141: packet_send_debug("%.100s, line %lu: missing end quote",
1.9 ! markus 142: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 143: continue;
144: }
145: s[i] = 0;
146: packet_send_debug("Adding to environment: %.900s", s);
147: debug("Adding to environment: %.900s", s);
148: options++;
149: new_envstring = xmalloc(sizeof(struct envstring));
150: new_envstring->s = s;
151: new_envstring->next = custom_environment;
152: custom_environment = new_envstring;
153: goto next_option;
154: }
155: cp = "from=\"";
1.6 markus 156: if (strncasecmp(options, cp, strlen(cp)) == 0) {
1.1 markus 157: int mname, mip;
158: char *patterns = xmalloc(strlen(options) + 1);
159: int i;
160: options += strlen(cp);
161: i = 0;
162: while (*options) {
163: if (*options == '"')
164: break;
165: if (*options == '\\' && options[1] == '"') {
166: options += 2;
167: patterns[i++] = '"';
168: continue;
169: }
170: patterns[i++] = *options++;
171: }
172: if (!*options) {
173: debug("%.100s, line %lu: missing end quote",
1.9 ! markus 174: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 175: packet_send_debug("%.100s, line %lu: missing end quote",
1.9 ! markus 176: _PATH_SSH_USER_PERMITTED_KEYS, linenum);
1.1 markus 177: continue;
178: }
179: patterns[i] = 0;
180: options++;
181: /*
182: * Deny access if we get a negative
183: * match for the hostname or the ip
184: * or if we get not match at all
185: */
186: mname = match_hostname(get_canonical_hostname(),
187: patterns, strlen(patterns));
188: mip = match_hostname(get_remote_ipaddr(),
189: patterns, strlen(patterns));
190: xfree(patterns);
191: if (mname == -1 || mip == -1 ||
192: (mname != 1 && mip != 1)) {
193: log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
194: pw->pw_name, get_canonical_hostname(),
195: get_remote_ipaddr());
196: packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
197: get_canonical_hostname());
198: /* deny access */
199: return 0;
200: }
201: /* Host name matches. */
202: goto next_option;
203: }
204: next_option:
205: /*
206: * Skip the comma, and move to the next option
207: * (or break out if there are no more).
208: */
209: if (!*options)
210: fatal("Bugs in auth-options.c option processing.");
211: if (*options == ' ' || *options == '\t')
212: break; /* End of options. */
213: if (*options != ',')
214: goto bad_option;
215: options++;
216: /* Process the next option. */
217: }
218: /* grant access */
219: return 1;
220:
221: bad_option:
222: log("Bad options in %.100s file, line %lu: %.50s",
1.9 ! markus 223: _PATH_SSH_USER_PERMITTED_KEYS, linenum, options);
1.1 markus 224: packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
1.9 ! markus 225: _PATH_SSH_USER_PERMITTED_KEYS, linenum, options);
1.1 markus 226: /* deny access */
227: return 0;
228: }