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