Deleted Added
full compact
auth-options.c (207319) auth-options.c (215116)
1/* $OpenBSD: auth-options.c,v 1.49 2010/03/16 15:46:52 stevesk Exp $ */
1/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be

--- 12 unchanged lines hidden (view full) ---

22
23#include "openbsd-compat/sys-queue.h"
24#include "xmalloc.h"
25#include "match.h"
26#include "log.h"
27#include "canohost.h"
28#include "buffer.h"
29#include "channels.h"
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be

--- 12 unchanged lines hidden (view full) ---

22
23#include "openbsd-compat/sys-queue.h"
24#include "xmalloc.h"
25#include "match.h"
26#include "log.h"
27#include "canohost.h"
28#include "buffer.h"
29#include "channels.h"
30#include "auth-options.h"
31#include "servconf.h"
32#include "misc.h"
33#include "key.h"
30#include "servconf.h"
31#include "misc.h"
32#include "key.h"
33#include "auth-options.h"
34#include "hostfile.h"
35#include "auth.h"
36#ifdef GSSAPI
37#include "ssh-gss.h"
38#endif
39#include "monitor_wrap.h"
40
41/* Flags set authorized_keys flags */

--- 8 unchanged lines hidden (view full) ---

50char *forced_command = NULL;
51
52/* "environment=" options. */
53struct envstring *custom_environment = NULL;
54
55/* "tunnel=" option. */
56int forced_tun_device = -1;
57
34#include "hostfile.h"
35#include "auth.h"
36#ifdef GSSAPI
37#include "ssh-gss.h"
38#endif
39#include "monitor_wrap.h"
40
41/* Flags set authorized_keys flags */

--- 8 unchanged lines hidden (view full) ---

50char *forced_command = NULL;
51
52/* "environment=" options. */
53struct envstring *custom_environment = NULL;
54
55/* "tunnel=" option. */
56int forced_tun_device = -1;
57
58/* "principals=" option. */
59char *authorized_principals = NULL;
60
58extern ServerOptions options;
59
60void
61auth_clear_options(void)
62{
63 no_agent_forwarding_flag = 0;
64 no_port_forwarding_flag = 0;
65 no_pty_flag = 0;

--- 5 unchanged lines hidden (view full) ---

71 custom_environment = ce->next;
72 xfree(ce->s);
73 xfree(ce);
74 }
75 if (forced_command) {
76 xfree(forced_command);
77 forced_command = NULL;
78 }
61extern ServerOptions options;
62
63void
64auth_clear_options(void)
65{
66 no_agent_forwarding_flag = 0;
67 no_port_forwarding_flag = 0;
68 no_pty_flag = 0;

--- 5 unchanged lines hidden (view full) ---

74 custom_environment = ce->next;
75 xfree(ce->s);
76 xfree(ce);
77 }
78 if (forced_command) {
79 xfree(forced_command);
80 forced_command = NULL;
81 }
82 if (authorized_principals) {
83 xfree(authorized_principals);
84 authorized_principals = NULL;
85 }
79 forced_tun_device = -1;
80 channel_clear_permitted_opens();
81}
82
83/*
84 * return 1 if access is granted, 0 if not.
85 * side effect: sets key option flags
86 */

--- 49 unchanged lines hidden (view full) ---

136 auth_debug_add("User rc file execution disabled.");
137 no_user_rc = 1;
138 opts += strlen(cp);
139 goto next_option;
140 }
141 cp = "command=\"";
142 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
143 opts += strlen(cp);
86 forced_tun_device = -1;
87 channel_clear_permitted_opens();
88}
89
90/*
91 * return 1 if access is granted, 0 if not.
92 * side effect: sets key option flags
93 */

--- 49 unchanged lines hidden (view full) ---

143 auth_debug_add("User rc file execution disabled.");
144 no_user_rc = 1;
145 opts += strlen(cp);
146 goto next_option;
147 }
148 cp = "command=\"";
149 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
150 opts += strlen(cp);
151 if (forced_command != NULL)
152 xfree(forced_command);
144 forced_command = xmalloc(strlen(opts) + 1);
145 i = 0;
146 while (*opts) {
147 if (*opts == '"')
148 break;
149 if (*opts == '\\' && opts[1] == '"') {
150 opts += 2;
151 forced_command[i++] = '"';

--- 10 unchanged lines hidden (view full) ---

162 forced_command = NULL;
163 goto bad_option;
164 }
165 forced_command[i] = '\0';
166 auth_debug_add("Forced command: %.900s", forced_command);
167 opts++;
168 goto next_option;
169 }
153 forced_command = xmalloc(strlen(opts) + 1);
154 i = 0;
155 while (*opts) {
156 if (*opts == '"')
157 break;
158 if (*opts == '\\' && opts[1] == '"') {
159 opts += 2;
160 forced_command[i++] = '"';

--- 10 unchanged lines hidden (view full) ---

171 forced_command = NULL;
172 goto bad_option;
173 }
174 forced_command[i] = '\0';
175 auth_debug_add("Forced command: %.900s", forced_command);
176 opts++;
177 goto next_option;
178 }
179 cp = "principals=\"";
180 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
181 opts += strlen(cp);
182 if (authorized_principals != NULL)
183 xfree(authorized_principals);
184 authorized_principals = xmalloc(strlen(opts) + 1);
185 i = 0;
186 while (*opts) {
187 if (*opts == '"')
188 break;
189 if (*opts == '\\' && opts[1] == '"') {
190 opts += 2;
191 authorized_principals[i++] = '"';
192 continue;
193 }
194 authorized_principals[i++] = *opts++;
195 }
196 if (!*opts) {
197 debug("%.100s, line %lu: missing end quote",
198 file, linenum);
199 auth_debug_add("%.100s, line %lu: missing end quote",
200 file, linenum);
201 xfree(authorized_principals);
202 authorized_principals = NULL;
203 goto bad_option;
204 }
205 authorized_principals[i] = '\0';
206 auth_debug_add("principals: %.900s",
207 authorized_principals);
208 opts++;
209 goto next_option;
210 }
170 cp = "environment=\"";
171 if (options.permit_user_env &&
172 strncasecmp(opts, cp, strlen(cp)) == 0) {
173 char *s;
174 struct envstring *new_envstring;
175
176 opts += strlen(cp);
177 s = xmalloc(strlen(opts) + 1);

--- 193 unchanged lines hidden (view full) ---

371 file, linenum, opts);
372 auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
373 file, linenum, opts);
374
375 /* deny access */
376 return 0;
377}
378
211 cp = "environment=\"";
212 if (options.permit_user_env &&
213 strncasecmp(opts, cp, strlen(cp)) == 0) {
214 char *s;
215 struct envstring *new_envstring;
216
217 opts += strlen(cp);
218 s = xmalloc(strlen(opts) + 1);

--- 193 unchanged lines hidden (view full) ---

412 file, linenum, opts);
413 auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
414 file, linenum, opts);
415
416 /* deny access */
417 return 0;
418}
419
379/*
380 * Set options from certificate constraints. These supersede user key options
381 * so this must be called after auth_parse_options().
382 */
383int
384auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
420#define OPTIONS_CRITICAL 1
421#define OPTIONS_EXTENSIONS 2
422static int
423parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
424 u_int which, int crit,
425 int *cert_no_port_forwarding_flag,
426 int *cert_no_agent_forwarding_flag,
427 int *cert_no_x11_forwarding_flag,
428 int *cert_no_pty_flag,
429 int *cert_no_user_rc,
430 char **cert_forced_command,
431 int *cert_source_address_done)
385{
432{
433 char *command, *allowed;
434 const char *remote_ip;
386 u_char *name = NULL, *data_blob = NULL;
387 u_int nlen, dlen, clen;
388 Buffer c, data;
435 u_char *name = NULL, *data_blob = NULL;
436 u_int nlen, dlen, clen;
437 Buffer c, data;
389 int ret = -1;
438 int ret = -1, found;
390
439
391 int cert_no_port_forwarding_flag = 1;
392 int cert_no_agent_forwarding_flag = 1;
393 int cert_no_x11_forwarding_flag = 1;
394 int cert_no_pty_flag = 1;
395 int cert_no_user_rc = 1;
396 char *cert_forced_command = NULL;
397 int cert_source_address_done = 0;
398
399 buffer_init(&data);
400
401 /* Make copy to avoid altering original */
402 buffer_init(&c);
440 buffer_init(&data);
441
442 /* Make copy to avoid altering original */
443 buffer_init(&c);
403 buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
444 buffer_append(&c, optblob, optblob_len);
404
405 while (buffer_len(&c) > 0) {
406 if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
407 (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
445
446 while (buffer_len(&c) > 0) {
447 if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
448 (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
408 error("Certificate constraints corrupt");
449 error("Certificate options corrupt");
409 goto out;
410 }
411 buffer_append(&data, data_blob, dlen);
450 goto out;
451 }
452 buffer_append(&data, data_blob, dlen);
412 debug3("found certificate constraint \"%.100s\" len %u",
453 debug3("found certificate option \"%.100s\" len %u",
413 name, dlen);
414 if (strlen(name) != nlen) {
415 error("Certificate constraint name contains \\0");
416 goto out;
417 }
454 name, dlen);
455 if (strlen(name) != nlen) {
456 error("Certificate constraint name contains \\0");
457 goto out;
458 }
418 if (strcmp(name, "permit-X11-forwarding") == 0)
419 cert_no_x11_forwarding_flag = 0;
420 else if (strcmp(name, "permit-agent-forwarding") == 0)
421 cert_no_agent_forwarding_flag = 0;
422 else if (strcmp(name, "permit-port-forwarding") == 0)
423 cert_no_port_forwarding_flag = 0;
424 else if (strcmp(name, "permit-pty") == 0)
425 cert_no_pty_flag = 0;
426 else if (strcmp(name, "permit-user-rc") == 0)
427 cert_no_user_rc = 0;
428 else if (strcmp(name, "force-command") == 0) {
429 char *command = buffer_get_string_ret(&data, &clen);
430
431 if (command == NULL) {
432 error("Certificate constraint \"%s\" corrupt",
433 name);
434 goto out;
459 found = 0;
460 if ((which & OPTIONS_EXTENSIONS) != 0) {
461 if (strcmp(name, "permit-X11-forwarding") == 0) {
462 *cert_no_x11_forwarding_flag = 0;
463 found = 1;
464 } else if (strcmp(name,
465 "permit-agent-forwarding") == 0) {
466 *cert_no_agent_forwarding_flag = 0;
467 found = 1;
468 } else if (strcmp(name,
469 "permit-port-forwarding") == 0) {
470 *cert_no_port_forwarding_flag = 0;
471 found = 1;
472 } else if (strcmp(name, "permit-pty") == 0) {
473 *cert_no_pty_flag = 0;
474 found = 1;
475 } else if (strcmp(name, "permit-user-rc") == 0) {
476 *cert_no_user_rc = 0;
477 found = 1;
435 }
478 }
436 if (strlen(command) != clen) {
437 error("force-command constraint contains \\0");
438 goto out;
479 }
480 if (!found && (which & OPTIONS_CRITICAL) != 0) {
481 if (strcmp(name, "force-command") == 0) {
482 if ((command = buffer_get_string_ret(&data,
483 &clen)) == NULL) {
484 error("Certificate constraint \"%s\" "
485 "corrupt", name);
486 goto out;
487 }
488 if (strlen(command) != clen) {
489 error("force-command constraint "
490 "contains \\0");
491 goto out;
492 }
493 if (*cert_forced_command != NULL) {
494 error("Certificate has multiple "
495 "force-command options");
496 xfree(command);
497 goto out;
498 }
499 *cert_forced_command = command;
500 found = 1;
439 }
501 }
440 if (cert_forced_command != NULL) {
441 error("Certificate has multiple "
442 "force-command constraints");
443 xfree(command);
444 goto out;
502 if (strcmp(name, "source-address") == 0) {
503 if ((allowed = buffer_get_string_ret(&data,
504 &clen)) == NULL) {
505 error("Certificate constraint "
506 "\"%s\" corrupt", name);
507 goto out;
508 }
509 if (strlen(allowed) != clen) {
510 error("source-address constraint "
511 "contains \\0");
512 goto out;
513 }
514 if ((*cert_source_address_done)++) {
515 error("Certificate has multiple "
516 "source-address options");
517 xfree(allowed);
518 goto out;
519 }
520 remote_ip = get_remote_ipaddr();
521 switch (addr_match_cidr_list(remote_ip,
522 allowed)) {
523 case 1:
524 /* accepted */
525 xfree(allowed);
526 break;
527 case 0:
528 /* no match */
529 logit("Authentication tried for %.100s "
530 "with valid certificate but not "
531 "from a permitted host "
532 "(ip=%.200s).", pw->pw_name,
533 remote_ip);
534 auth_debug_add("Your address '%.200s' "
535 "is not permitted to use this "
536 "certificate for login.",
537 remote_ip);
538 xfree(allowed);
539 goto out;
540 case -1:
541 error("Certificate source-address "
542 "contents invalid");
543 xfree(allowed);
544 goto out;
545 }
546 found = 1;
445 }
547 }
446 cert_forced_command = command;
447 } else if (strcmp(name, "source-address") == 0) {
448 char *allowed = buffer_get_string_ret(&data, &clen);
449 const char *remote_ip = get_remote_ipaddr();
450
451 if (allowed == NULL) {
452 error("Certificate constraint \"%s\" corrupt",
453 name);
454 goto out;
455 }
456 if (strlen(allowed) != clen) {
457 error("source-address constraint contains \\0");
458 goto out;
459 }
460 if (cert_source_address_done++) {
461 error("Certificate has multiple "
462 "source-address constraints");
463 xfree(allowed);
464 goto out;
465 }
466 switch (addr_match_cidr_list(remote_ip, allowed)) {
467 case 1:
468 /* accepted */
469 xfree(allowed);
470 break;
471 case 0:
472 /* no match */
473 logit("Authentication tried for %.100s with "
474 "valid certificate but not from a "
475 "permitted host (ip=%.200s).",
476 pw->pw_name, remote_ip);
477 auth_debug_add("Your address '%.200s' is not "
478 "permitted to use this certificate for "
479 "login.", remote_ip);
480 xfree(allowed);
481 goto out;
482 case -1:
483 error("Certificate source-address contents "
484 "invalid");
485 xfree(allowed);
486 goto out;
487 }
488 } else {
489 error("Certificate constraint \"%s\" is not supported",
490 name);
491 goto out;
492 }
493
548 }
549
494 if (buffer_len(&data) != 0) {
495 error("Certificate constraint \"%s\" corrupt "
550 if (!found) {
551 if (crit) {
552 error("Certificate critical option \"%s\" "
553 "is not supported", name);
554 goto out;
555 } else {
556 logit("Certificate extension \"%s\" "
557 "is not supported", name);
558 }
559 } else if (buffer_len(&data) != 0) {
560 error("Certificate option \"%s\" corrupt "
496 "(extra data)", name);
497 goto out;
498 }
499 buffer_clear(&data);
500 xfree(name);
501 xfree(data_blob);
502 name = data_blob = NULL;
503 }
561 "(extra data)", name);
562 goto out;
563 }
564 buffer_clear(&data);
565 xfree(name);
566 xfree(data_blob);
567 name = data_blob = NULL;
568 }
504
505 /* successfully parsed all constraints */
569 /* successfully parsed all options */
506 ret = 0;
507
570 ret = 0;
571
572 out:
573 if (ret != 0 &&
574 cert_forced_command != NULL &&
575 *cert_forced_command != NULL) {
576 xfree(*cert_forced_command);
577 *cert_forced_command = NULL;
578 }
579 if (name != NULL)
580 xfree(name);
581 if (data_blob != NULL)
582 xfree(data_blob);
583 buffer_free(&data);
584 buffer_free(&c);
585 return ret;
586}
587
588/*
589 * Set options from critical certificate options. These supersede user key
590 * options so this must be called after auth_parse_options().
591 */
592int
593auth_cert_options(Key *k, struct passwd *pw)
594{
595 int cert_no_port_forwarding_flag = 1;
596 int cert_no_agent_forwarding_flag = 1;
597 int cert_no_x11_forwarding_flag = 1;
598 int cert_no_pty_flag = 1;
599 int cert_no_user_rc = 1;
600 char *cert_forced_command = NULL;
601 int cert_source_address_done = 0;
602
603 if (key_cert_is_legacy(k)) {
604 /* All options are in the one field for v00 certs */
605 if (parse_option_list(buffer_ptr(&k->cert->critical),
606 buffer_len(&k->cert->critical), pw,
607 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
608 &cert_no_port_forwarding_flag,
609 &cert_no_agent_forwarding_flag,
610 &cert_no_x11_forwarding_flag,
611 &cert_no_pty_flag,
612 &cert_no_user_rc,
613 &cert_forced_command,
614 &cert_source_address_done) == -1)
615 return -1;
616 } else {
617 /* Separate options and extensions for v01 certs */
618 if (parse_option_list(buffer_ptr(&k->cert->critical),
619 buffer_len(&k->cert->critical), pw,
620 OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
621 &cert_forced_command,
622 &cert_source_address_done) == -1)
623 return -1;
624 if (parse_option_list(buffer_ptr(&k->cert->extensions),
625 buffer_len(&k->cert->extensions), pw,
626 OPTIONS_EXTENSIONS, 1,
627 &cert_no_port_forwarding_flag,
628 &cert_no_agent_forwarding_flag,
629 &cert_no_x11_forwarding_flag,
630 &cert_no_pty_flag,
631 &cert_no_user_rc,
632 NULL, NULL) == -1)
633 return -1;
634 }
635
508 no_port_forwarding_flag |= cert_no_port_forwarding_flag;
509 no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
510 no_x11_forwarding_flag |= cert_no_x11_forwarding_flag;
511 no_pty_flag |= cert_no_pty_flag;
512 no_user_rc |= cert_no_user_rc;
513 /* CA-specified forced command supersedes key option */
514 if (cert_forced_command != NULL) {
515 if (forced_command != NULL)
516 xfree(forced_command);
517 forced_command = cert_forced_command;
518 }
636 no_port_forwarding_flag |= cert_no_port_forwarding_flag;
637 no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
638 no_x11_forwarding_flag |= cert_no_x11_forwarding_flag;
639 no_pty_flag |= cert_no_pty_flag;
640 no_user_rc |= cert_no_user_rc;
641 /* CA-specified forced command supersedes key option */
642 if (cert_forced_command != NULL) {
643 if (forced_command != NULL)
644 xfree(forced_command);
645 forced_command = cert_forced_command;
646 }
519
520 out:
521 if (name != NULL)
522 xfree(name);
523 if (data_blob != NULL)
524 xfree(data_blob);
525 buffer_free(&data);
526 buffer_free(&c);
527 return ret;
647 return 0;
528}
529
648}
649