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