Annotation of src/usr.bin/ssh/auth-options.c, Revision 1.5.2.1
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: }