Annotation of src/usr.bin/ssh/auth-options.c, Revision 1.14
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.14 ! markus 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.11 markus 18: #include "log.h"
19: #include "canohost.h"
20: #include "auth-options.h"
1.12 markus 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.12 markus 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.10 markus 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.12 markus 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();
1.13 markus 67:
68: if (!opts)
69: return 1;
1.5 markus 70:
1.12 markus 71: while (*opts && *opts != ' ' && *opts != '\t') {
1.1 markus 72: cp = "no-port-forwarding";
1.12 markus 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.12 markus 76: opts += strlen(cp);
1.1 markus 77: goto next_option;
78: }
79: cp = "no-agent-forwarding";
1.12 markus 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.12 markus 83: opts += strlen(cp);
1.1 markus 84: goto next_option;
85: }
86: cp = "no-X11-forwarding";
1.12 markus 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.12 markus 90: opts += strlen(cp);
1.1 markus 91: goto next_option;
92: }
93: cp = "no-pty";
1.12 markus 94: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1 markus 95: packet_send_debug("Pty allocation disabled.");
96: no_pty_flag = 1;
1.12 markus 97: opts += strlen(cp);
1.1 markus 98: goto next_option;
99: }
100: cp = "command=\"";
1.12 markus 101: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1 markus 102: int i;
1.12 markus 103: opts += strlen(cp);
104: forced_command = xmalloc(strlen(opts) + 1);
1.1 markus 105: i = 0;
1.12 markus 106: while (*opts) {
107: if (*opts == '"')
1.1 markus 108: break;
1.12 markus 109: if (*opts == '\\' && opts[1] == '"') {
110: opts += 2;
1.1 markus 111: forced_command[i++] = '"';
112: continue;
113: }
1.12 markus 114: forced_command[i++] = *opts++;
1.1 markus 115: }
1.12 markus 116: if (!*opts) {
1.1 markus 117: debug("%.100s, line %lu: missing end quote",
1.10 markus 118: file, linenum);
1.1 markus 119: packet_send_debug("%.100s, line %lu: missing end quote",
1.10 markus 120: file, linenum);
1.14 ! markus 121: xfree(forced_command);
! 122: forced_command = NULL;
! 123: goto bad_option;
1.1 markus 124: }
125: forced_command[i] = 0;
126: packet_send_debug("Forced command: %.900s", forced_command);
1.12 markus 127: opts++;
1.1 markus 128: goto next_option;
129: }
130: cp = "environment=\"";
1.12 markus 131: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1 markus 132: int i;
133: char *s;
134: struct envstring *new_envstring;
1.12 markus 135: opts += strlen(cp);
136: s = xmalloc(strlen(opts) + 1);
1.1 markus 137: i = 0;
1.12 markus 138: while (*opts) {
139: if (*opts == '"')
1.1 markus 140: break;
1.12 markus 141: if (*opts == '\\' && opts[1] == '"') {
142: opts += 2;
1.1 markus 143: s[i++] = '"';
144: continue;
145: }
1.12 markus 146: s[i++] = *opts++;
1.1 markus 147: }
1.12 markus 148: if (!*opts) {
1.1 markus 149: debug("%.100s, line %lu: missing end quote",
1.10 markus 150: file, linenum);
1.1 markus 151: packet_send_debug("%.100s, line %lu: missing end quote",
1.10 markus 152: file, linenum);
1.14 ! markus 153: xfree(s);
! 154: goto bad_option;
1.1 markus 155: }
156: s[i] = 0;
157: packet_send_debug("Adding to environment: %.900s", s);
158: debug("Adding to environment: %.900s", s);
1.12 markus 159: opts++;
1.1 markus 160: new_envstring = xmalloc(sizeof(struct envstring));
161: new_envstring->s = s;
162: new_envstring->next = custom_environment;
163: custom_environment = new_envstring;
164: goto next_option;
165: }
166: cp = "from=\"";
1.12 markus 167: if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1 markus 168: int mname, mip;
1.12 markus 169: const char *remote_ip = get_remote_ipaddr();
170: const char *remote_host = get_canonical_hostname(
171: options.reverse_mapping_check);
172: char *patterns = xmalloc(strlen(opts) + 1);
1.1 markus 173: int i;
1.12 markus 174: opts += strlen(cp);
1.1 markus 175: i = 0;
1.12 markus 176: while (*opts) {
177: if (*opts == '"')
1.1 markus 178: break;
1.12 markus 179: if (*opts == '\\' && opts[1] == '"') {
180: opts += 2;
1.1 markus 181: patterns[i++] = '"';
182: continue;
183: }
1.12 markus 184: patterns[i++] = *opts++;
1.1 markus 185: }
1.12 markus 186: if (!*opts) {
1.1 markus 187: debug("%.100s, line %lu: missing end quote",
1.10 markus 188: file, linenum);
1.1 markus 189: packet_send_debug("%.100s, line %lu: missing end quote",
1.10 markus 190: file, linenum);
1.14 ! markus 191: xfree(patterns);
! 192: goto bad_option;
1.1 markus 193: }
194: patterns[i] = 0;
1.12 markus 195: opts++;
1.1 markus 196: /*
197: * Deny access if we get a negative
198: * match for the hostname or the ip
199: * or if we get not match at all
200: */
1.12 markus 201: mname = match_hostname(remote_host, patterns,
202: strlen(patterns));
203: mip = match_hostname(remote_ip, patterns,
204: strlen(patterns));
1.1 markus 205: xfree(patterns);
206: if (mname == -1 || mip == -1 ||
207: (mname != 1 && mip != 1)) {
1.12 markus 208: log("Authentication tried for %.100s with "
209: "correct key but not from a permitted "
210: "host (host=%.200s, ip=%.200s).",
211: pw->pw_name, remote_host, remote_ip);
212: packet_send_debug("Your host '%.200s' is not "
213: "permitted to use this key for login.",
214: remote_host);
1.1 markus 215: /* deny access */
216: return 0;
217: }
218: /* Host name matches. */
219: goto next_option;
220: }
221: next_option:
222: /*
223: * Skip the comma, and move to the next option
224: * (or break out if there are no more).
225: */
1.12 markus 226: if (!*opts)
1.1 markus 227: fatal("Bugs in auth-options.c option processing.");
1.12 markus 228: if (*opts == ' ' || *opts == '\t')
1.1 markus 229: break; /* End of options. */
1.12 markus 230: if (*opts != ',')
1.1 markus 231: goto bad_option;
1.12 markus 232: opts++;
1.1 markus 233: /* Process the next option. */
234: }
235: /* grant access */
236: return 1;
237:
238: bad_option:
239: log("Bad options in %.100s file, line %lu: %.50s",
1.12 markus 240: file, linenum, opts);
1.1 markus 241: packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
1.12 markus 242: file, linenum, opts);
1.1 markus 243: /* deny access */
244: return 0;
245: }