auth-options.c revision 65668
190075Sobrien/* 290075Sobrien * Author: Tatu Ylonen <ylo@cs.hut.fi> 390075Sobrien * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 490075Sobrien * All rights reserved 590075Sobrien * RSA-based authentication. This code determines whether to admit a login 690075Sobrien * based on RSA authentication. This file also contains functions to check 790075Sobrien * validity of the host key. 890075Sobrien * 990075Sobrien * As far as I am concerned, the code I have written for this software 1090075Sobrien * can be used freely for any purpose. Any derived versions of this 1190075Sobrien * software must be clearly marked as such, and if the derived work is 1290075Sobrien * incompatible with the protocol description in the RFC file, it must be 1390075Sobrien * called by a name other than "ssh" or "Secure Shell". 1490075Sobrien */ 1590075Sobrien 1690075Sobrien#include "includes.h" 1790075SobrienRCSID("$OpenBSD: auth-options.c,v 1.4 2000/09/07 21:13:36 markus Exp $"); 1890075Sobrien 1990075Sobrien#include "ssh.h" 2090075Sobrien#include "packet.h" 2190075Sobrien#include "xmalloc.h" 2290075Sobrien#include "match.h" 2390075Sobrien 2490075Sobrien/* Flags set authorized_keys flags */ 2590075Sobrienint no_port_forwarding_flag = 0; 26117395Skanint no_agent_forwarding_flag = 0; 2790075Sobrienint no_x11_forwarding_flag = 0; 2890075Sobrienint no_pty_flag = 0; 2990075Sobrien 3090075Sobrien/* "command=" option. */ 31117395Skanchar *forced_command = NULL; 3290075Sobrien 3390075Sobrien/* "environment=" options. */ 3490075Sobrienstruct envstring *custom_environment = NULL; 35117395Skan 3690075Sobrien/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ 3790075Sobrienint 3890075Sobrienauth_parse_options(struct passwd *pw, char *options, unsigned long linenum) 39117395Skan{ 4090075Sobrien const char *cp; 4190075Sobrien if (!options) 4290075Sobrien return 1; 43117395Skan while (*options && *options != ' ' && *options != '\t') { 4490075Sobrien cp = "no-port-forwarding"; 4590075Sobrien if (strncmp(options, cp, strlen(cp)) == 0) { 4690075Sobrien packet_send_debug("Port forwarding disabled."); 47117395Skan no_port_forwarding_flag = 1; 4890075Sobrien options += strlen(cp); 4990075Sobrien goto next_option; 5090075Sobrien } 51117395Skan cp = "no-agent-forwarding"; 5290075Sobrien if (strncmp(options, cp, strlen(cp)) == 0) { 5390075Sobrien packet_send_debug("Agent forwarding disabled."); 5490075Sobrien no_agent_forwarding_flag = 1; 55117395Skan options += strlen(cp); 5690075Sobrien goto next_option; 5790075Sobrien } 5890075Sobrien cp = "no-X11-forwarding"; 59117395Skan if (strncmp(options, cp, strlen(cp)) == 0) { 6090075Sobrien packet_send_debug("X11 forwarding disabled."); 6190075Sobrien no_x11_forwarding_flag = 1; 6290075Sobrien options += strlen(cp); 63117395Skan goto next_option; 6490075Sobrien } 6590075Sobrien cp = "no-pty"; 6690075Sobrien if (strncmp(options, cp, strlen(cp)) == 0) { 67117395Skan packet_send_debug("Pty allocation disabled."); 6890075Sobrien no_pty_flag = 1; 6990075Sobrien options += strlen(cp); 7090075Sobrien goto next_option; 71117395Skan } 7290075Sobrien cp = "command=\""; 7390075Sobrien if (strncmp(options, cp, strlen(cp)) == 0) { 7490075Sobrien int i; 7590075Sobrien options += strlen(cp); 7690075Sobrien forced_command = xmalloc(strlen(options) + 1); 7790075Sobrien i = 0; 7890075Sobrien 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 } 199next_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 216bad_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