Annotation of src/usr.bin/ssh/auth-options.c, Revision 1.3
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: * 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: *
! 16: * Copyright (c) 2000 Markus Friedl. All rights reserved.
! 17: *
! 18: * Redistribution and use in source and binary forms, with or without
! 19: * modification, are permitted provided that the following conditions
! 20: * are met:
! 21: * 1. Redistributions of source code must retain the above copyright
! 22: * notice, this list of conditions and the following disclaimer.
! 23: * 2. Redistributions in binary form must reproduce the above copyright
! 24: * notice, this list of conditions and the following disclaimer in the
! 25: * documentation and/or other materials provided with the distribution.
! 26: *
! 27: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 28: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 29: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 30: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 31: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 32: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 33: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 34: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 35: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 36: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 37: */
! 38:
1.1 markus 39: #include "includes.h"
1.3 ! deraadt 40: RCSID("$OpenBSD: auth-options.c,v 1.2 2000/06/20 01:39:38 markus Exp $");
1.1 markus 41:
42: #include "ssh.h"
43: #include "packet.h"
44: #include "xmalloc.h"
45: #include "match.h"
46:
47: /* Flags set authorized_keys flags */
48: int no_port_forwarding_flag = 0;
49: int no_agent_forwarding_flag = 0;
50: int no_x11_forwarding_flag = 0;
51: int no_pty_flag = 0;
52:
53: /* "command=" option. */
54: char *forced_command = NULL;
55:
56: /* "environment=" options. */
57: struct envstring *custom_environment = NULL;
58:
59: /* return 1 if access is granted, 0 if not. side effect: sets key option flags */
60: int
61: auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
62: {
63: const char *cp;
64: if (!options)
65: return 1;
66: while (*options && *options != ' ' && *options != '\t') {
67: cp = "no-port-forwarding";
68: if (strncmp(options, cp, strlen(cp)) == 0) {
69: 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";
75: if (strncmp(options, cp, strlen(cp)) == 0) {
76: 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";
82: if (strncmp(options, cp, strlen(cp)) == 0) {
83: 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";
89: if (strncmp(options, cp, strlen(cp)) == 0) {
90: packet_send_debug("Pty allocation disabled.");
91: no_pty_flag = 1;
92: options += strlen(cp);
93: goto next_option;
94: }
95: cp = "command=\"";
96: if (strncmp(options, cp, strlen(cp)) == 0) {
97: 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",
113: SSH_USER_PERMITTED_KEYS, linenum);
114: packet_send_debug("%.100s, line %lu: missing end quote",
115: SSH_USER_PERMITTED_KEYS, linenum);
116: 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=\"";
124: if (strncmp(options, cp, strlen(cp)) == 0) {
125: 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",
143: SSH_USER_PERMITTED_KEYS, linenum);
144: packet_send_debug("%.100s, line %lu: missing end quote",
145: SSH_USER_PERMITTED_KEYS, linenum);
146: 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=\"";
159: if (strncmp(options, cp, strlen(cp)) == 0) {
160: 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());
201: /* key invalid for this host, reset flags */
202: no_agent_forwarding_flag = 0;
203: no_port_forwarding_flag = 0;
204: no_pty_flag = 0;
205: no_x11_forwarding_flag = 0;
206: while (custom_environment) {
207: struct envstring *ce = custom_environment;
208: custom_environment = ce->next;
209: xfree(ce->s);
210: xfree(ce);
211: }
212: if (forced_command) {
213: xfree(forced_command);
214: forced_command = NULL;
215: }
216: /* deny access */
217: return 0;
218: }
219: /* Host name matches. */
220: goto next_option;
221: }
222: next_option:
223: /*
224: * Skip the comma, and move to the next option
225: * (or break out if there are no more).
226: */
227: if (!*options)
228: fatal("Bugs in auth-options.c option processing.");
229: if (*options == ' ' || *options == '\t')
230: break; /* End of options. */
231: if (*options != ',')
232: goto bad_option;
233: options++;
234: /* Process the next option. */
235: }
236: /* grant access */
237: return 1;
238:
239: bad_option:
240: log("Bad options in %.100s file, line %lu: %.50s",
241: SSH_USER_PERMITTED_KEYS, linenum, options);
242: packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
243: SSH_USER_PERMITTED_KEYS, linenum, options);
244: /* deny access */
245: return 0;
246: }