summaryrefslogtreecommitdiff
path: root/auth-options.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth-options.c')
-rw-r--r--auth-options.c169
1 files changed, 161 insertions, 8 deletions
diff --git a/auth-options.c b/auth-options.c
index ab085c233..129301765 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -44,6 +44,7 @@ int no_agent_forwarding_flag = 0;
44int no_x11_forwarding_flag = 0; 44int no_x11_forwarding_flag = 0;
45int no_pty_flag = 0; 45int no_pty_flag = 0;
46int no_user_rc = 0; 46int no_user_rc = 0;
47int key_is_cert_authority = 0;
47 48
48/* "command=" option. */ 49/* "command=" option. */
49char *forced_command = NULL; 50char *forced_command = NULL;
@@ -64,6 +65,7 @@ auth_clear_options(void)
64 no_pty_flag = 0; 65 no_pty_flag = 0;
65 no_x11_forwarding_flag = 0; 66 no_x11_forwarding_flag = 0;
66 no_user_rc = 0; 67 no_user_rc = 0;
68 key_is_cert_authority = 0;
67 while (custom_environment) { 69 while (custom_environment) {
68 struct envstring *ce = custom_environment; 70 struct envstring *ce = custom_environment;
69 custom_environment = ce->next; 71 custom_environment = ce->next;
@@ -76,7 +78,6 @@ auth_clear_options(void)
76 } 78 }
77 forced_tun_device = -1; 79 forced_tun_device = -1;
78 channel_clear_permitted_opens(); 80 channel_clear_permitted_opens();
79 auth_debug_reset();
80} 81}
81 82
82/* 83/*
@@ -96,6 +97,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
96 return 1; 97 return 1;
97 98
98 while (*opts && *opts != ' ' && *opts != '\t') { 99 while (*opts && *opts != ' ' && *opts != '\t') {
100 cp = "cert-authority";
101 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
102 key_is_cert_authority = 1;
103 opts += strlen(cp);
104 goto next_option;
105 }
99 cp = "no-port-forwarding"; 106 cp = "no-port-forwarding";
100 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 107 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
101 auth_debug_add("Port forwarding disabled."); 108 auth_debug_add("Port forwarding disabled.");
@@ -356,9 +363,6 @@ next_option:
356 /* Process the next option. */ 363 /* Process the next option. */
357 } 364 }
358 365
359 if (!use_privsep)
360 auth_debug_send();
361
362 /* grant access */ 366 /* grant access */
363 return 1; 367 return 1;
364 368
@@ -368,9 +372,158 @@ bad_option:
368 auth_debug_add("Bad options in %.100s file, line %lu: %.50s", 372 auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
369 file, linenum, opts); 373 file, linenum, opts);
370 374
371 if (!use_privsep)
372 auth_debug_send();
373
374 /* deny access */ 375 /* deny access */
375 return 0; 376 return 0;
376} 377}
378
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)
385{
386 u_char *name = NULL, *data_blob = NULL;
387 u_int nlen, dlen, clen;
388 Buffer c, data;
389 int ret = -1;
390
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);
403 buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
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) {
408 error("Certificate constraints corrupt");
409 goto out;
410 }
411 buffer_append(&data, data_blob, dlen);
412 debug3("found certificate constraint \"%.100s\" len %u",
413 name, dlen);
414 if (strlen(name) != nlen) {
415 error("Certificate constraint name contains \\0");
416 goto out;
417 }
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;
435 }
436 if (strlen(command) != clen) {
437 error("force-command constrain contains \\0");
438 goto out;
439 }
440 if (cert_forced_command != NULL) {
441 error("Certificate has multiple "
442 "force-command constraints");
443 xfree(command);
444 goto out;
445 }
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 constrain 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
494 if (buffer_len(&data) != 0) {
495 error("Certificate constraint \"%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 }
504
505 /* successfully parsed all constraints */
506 ret = 0;
507
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 }
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;
528}
529