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