00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "includes.h"
00013 RCSID("$OpenBSD: auth-options.c,v 1.33 2005/12/08 18:34:11 reyk Exp $");
00014
00015 #include "xmalloc.h"
00016 #include "match.h"
00017 #include "log.h"
00018 #include "canohost.h"
00019 #include "channels.h"
00020 #include "auth-options.h"
00021 #include "servconf.h"
00022 #include "misc.h"
00023 #include "monitor_wrap.h"
00024 #include "auth.h"
00025
00026
00027 int no_port_forwarding_flag = 0;
00028 int no_agent_forwarding_flag = 0;
00029 int no_x11_forwarding_flag = 0;
00030 int no_pty_flag = 0;
00031
00032
00033 char *forced_command = NULL;
00034
00035
00036 struct envstring *custom_environment = NULL;
00037
00038
00039 int forced_tun_device = -1;
00040
00041 extern ServerOptions options;
00042
00043 void
00044 auth_clear_options(void)
00045 {
00046 no_agent_forwarding_flag = 0;
00047 no_port_forwarding_flag = 0;
00048 no_pty_flag = 0;
00049 no_x11_forwarding_flag = 0;
00050 while (custom_environment) {
00051 struct envstring *ce = custom_environment;
00052 custom_environment = ce->next;
00053 xfree(ce->s);
00054 xfree(ce);
00055 }
00056 if (forced_command) {
00057 xfree(forced_command);
00058 forced_command = NULL;
00059 }
00060 forced_tun_device = -1;
00061 channel_clear_permitted_opens();
00062 auth_debug_reset();
00063 }
00064
00065
00066
00067
00068
00069 int
00070 auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
00071 {
00072 const char *cp;
00073 int i;
00074
00075
00076 auth_clear_options();
00077
00078 if (!opts)
00079 return 1;
00080
00081 while (*opts && *opts != ' ' && *opts != '\t') {
00082 cp = "no-port-forwarding";
00083 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00084 auth_debug_add("Port forwarding disabled.");
00085 no_port_forwarding_flag = 1;
00086 opts += strlen(cp);
00087 goto next_option;
00088 }
00089 cp = "no-agent-forwarding";
00090 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00091 auth_debug_add("Agent forwarding disabled.");
00092 no_agent_forwarding_flag = 1;
00093 opts += strlen(cp);
00094 goto next_option;
00095 }
00096 cp = "no-X11-forwarding";
00097 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00098 auth_debug_add("X11 forwarding disabled.");
00099 no_x11_forwarding_flag = 1;
00100 opts += strlen(cp);
00101 goto next_option;
00102 }
00103 cp = "no-pty";
00104 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00105 auth_debug_add("Pty allocation disabled.");
00106 no_pty_flag = 1;
00107 opts += strlen(cp);
00108 goto next_option;
00109 }
00110 cp = "command=\"";
00111 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00112 opts += strlen(cp);
00113 forced_command = xmalloc(strlen(opts) + 1);
00114 i = 0;
00115 while (*opts) {
00116 if (*opts == '"')
00117 break;
00118 if (*opts == '\\' && opts[1] == '"') {
00119 opts += 2;
00120 forced_command[i++] = '"';
00121 continue;
00122 }
00123 forced_command[i++] = *opts++;
00124 }
00125 if (!*opts) {
00126 debug("%.100s, line %lu: missing end quote",
00127 file, linenum);
00128 auth_debug_add("%.100s, line %lu: missing end quote",
00129 file, linenum);
00130 xfree(forced_command);
00131 forced_command = NULL;
00132 goto bad_option;
00133 }
00134 forced_command[i] = 0;
00135 auth_debug_add("Forced command: %.900s", forced_command);
00136 opts++;
00137 goto next_option;
00138 }
00139 cp = "environment=\"";
00140 if (options.permit_user_env &&
00141 strncasecmp(opts, cp, strlen(cp)) == 0) {
00142 char *s;
00143 struct envstring *new_envstring;
00144
00145 opts += strlen(cp);
00146 s = xmalloc(strlen(opts) + 1);
00147 i = 0;
00148 while (*opts) {
00149 if (*opts == '"')
00150 break;
00151 if (*opts == '\\' && opts[1] == '"') {
00152 opts += 2;
00153 s[i++] = '"';
00154 continue;
00155 }
00156 s[i++] = *opts++;
00157 }
00158 if (!*opts) {
00159 debug("%.100s, line %lu: missing end quote",
00160 file, linenum);
00161 auth_debug_add("%.100s, line %lu: missing end quote",
00162 file, linenum);
00163 xfree(s);
00164 goto bad_option;
00165 }
00166 s[i] = 0;
00167 auth_debug_add("Adding to environment: %.900s", s);
00168 debug("Adding to environment: %.900s", s);
00169 opts++;
00170 new_envstring = xmalloc(sizeof(struct envstring));
00171 new_envstring->s = s;
00172 new_envstring->next = custom_environment;
00173 custom_environment = new_envstring;
00174 goto next_option;
00175 }
00176 cp = "from=\"";
00177 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00178 const char *remote_ip = get_remote_ipaddr();
00179 const char *remote_host = get_canonical_hostname(
00180 options.use_dns);
00181 char *patterns = xmalloc(strlen(opts) + 1);
00182
00183 opts += strlen(cp);
00184 i = 0;
00185 while (*opts) {
00186 if (*opts == '"')
00187 break;
00188 if (*opts == '\\' && opts[1] == '"') {
00189 opts += 2;
00190 patterns[i++] = '"';
00191 continue;
00192 }
00193 patterns[i++] = *opts++;
00194 }
00195 if (!*opts) {
00196 debug("%.100s, line %lu: missing end quote",
00197 file, linenum);
00198 auth_debug_add("%.100s, line %lu: missing end quote",
00199 file, linenum);
00200 xfree(patterns);
00201 goto bad_option;
00202 }
00203 patterns[i] = 0;
00204 opts++;
00205 if (match_host_and_ip(remote_host, remote_ip,
00206 patterns) != 1) {
00207 xfree(patterns);
00208 logit("Authentication tried for %.100s with "
00209 "correct key but not from a permitted "
00210 "host (host=%.200s, ip=%.200s).",
00211 pw->pw_name, remote_host, remote_ip);
00212 auth_debug_add("Your host '%.200s' is not "
00213 "permitted to use this key for login.",
00214 remote_host);
00215
00216 return 0;
00217 }
00218 xfree(patterns);
00219
00220 goto next_option;
00221 }
00222 cp = "permitopen=\"";
00223 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00224 char *host, *p;
00225 u_short port;
00226 char *patterns = xmalloc(strlen(opts) + 1);
00227
00228 opts += strlen(cp);
00229 i = 0;
00230 while (*opts) {
00231 if (*opts == '"')
00232 break;
00233 if (*opts == '\\' && opts[1] == '"') {
00234 opts += 2;
00235 patterns[i++] = '"';
00236 continue;
00237 }
00238 patterns[i++] = *opts++;
00239 }
00240 if (!*opts) {
00241 debug("%.100s, line %lu: missing end quote",
00242 file, linenum);
00243 auth_debug_add("%.100s, line %lu: missing "
00244 "end quote", file, linenum);
00245 xfree(patterns);
00246 goto bad_option;
00247 }
00248 patterns[i] = 0;
00249 opts++;
00250 p = patterns;
00251 host = hpdelim(&p);
00252 if (host == NULL || strlen(host) >= NI_MAXHOST) {
00253 debug("%.100s, line %lu: Bad permitopen "
00254 "specification <%.100s>", file, linenum,
00255 patterns);
00256 auth_debug_add("%.100s, line %lu: "
00257 "Bad permitopen specification", file,
00258 linenum);
00259 xfree(patterns);
00260 goto bad_option;
00261 }
00262 host = cleanhostname(host);
00263 if (p == NULL || (port = a2port(p)) == 0) {
00264 debug("%.100s, line %lu: Bad permitopen port "
00265 "<%.100s>", file, linenum, p ? p : "");
00266 auth_debug_add("%.100s, line %lu: "
00267 "Bad permitopen port", file, linenum);
00268 xfree(patterns);
00269 goto bad_option;
00270 }
00271 if (options.allow_tcp_forwarding)
00272 channel_add_permitted_opens(host, port);
00273 xfree(patterns);
00274 goto next_option;
00275 }
00276 cp = "tunnel=\"";
00277 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
00278 char *tun = NULL;
00279 opts += strlen(cp);
00280 tun = xmalloc(strlen(opts) + 1);
00281 i = 0;
00282 while (*opts) {
00283 if (*opts == '"')
00284 break;
00285 tun[i++] = *opts++;
00286 }
00287 if (!*opts) {
00288 debug("%.100s, line %lu: missing end quote",
00289 file, linenum);
00290 auth_debug_add("%.100s, line %lu: missing end quote",
00291 file, linenum);
00292 xfree(tun);
00293 forced_tun_device = -1;
00294 goto bad_option;
00295 }
00296 tun[i] = 0;
00297 forced_tun_device = a2tun(tun, NULL);
00298 xfree(tun);
00299 if (forced_tun_device == SSH_TUNID_ERR) {
00300 debug("%.100s, line %lu: invalid tun device",
00301 file, linenum);
00302 auth_debug_add("%.100s, line %lu: invalid tun device",
00303 file, linenum);
00304 forced_tun_device = -1;
00305 goto bad_option;
00306 }
00307 auth_debug_add("Forced tun device: %d", forced_tun_device);
00308 opts++;
00309 goto next_option;
00310 }
00311 next_option:
00312
00313
00314
00315
00316 if (!*opts)
00317 fatal("Bugs in auth-options.c option processing.");
00318 if (*opts == ' ' || *opts == '\t')
00319 break;
00320 if (*opts != ',')
00321 goto bad_option;
00322 opts++;
00323
00324 }
00325
00326 if (!use_privsep)
00327 auth_debug_send();
00328
00329
00330 return 1;
00331
00332 bad_option:
00333 logit("Bad options in %.100s file, line %lu: %.50s",
00334 file, linenum, opts);
00335 auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
00336 file, linenum, opts);
00337
00338 if (!use_privsep)
00339 auth_debug_send();
00340
00341
00342 return 0;
00343 }