diff options
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index aace7ca15..add77136e 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.60 2016/11/30 02:57:40 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -560,7 +560,7 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert) | |||
560 | 560 | ||
561 | static int | 561 | static int |
562 | process_principals(FILE *f, char *file, struct passwd *pw, | 562 | process_principals(FILE *f, char *file, struct passwd *pw, |
563 | struct sshkey_cert *cert) | 563 | const struct sshkey_cert *cert) |
564 | { | 564 | { |
565 | char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; | 565 | char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; |
566 | u_long linenum = 0; | 566 | u_long linenum = 0; |
@@ -630,14 +630,17 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) | |||
630 | * returns 1 if the principal is allowed or 0 otherwise. | 630 | * returns 1 if the principal is allowed or 0 otherwise. |
631 | */ | 631 | */ |
632 | static int | 632 | static int |
633 | match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | 633 | match_principals_command(struct passwd *user_pw, const struct sshkey *key) |
634 | { | 634 | { |
635 | const struct sshkey_cert *cert = key->cert; | ||
635 | FILE *f = NULL; | 636 | FILE *f = NULL; |
636 | int ok, found_principal = 0; | 637 | int r, ok, found_principal = 0; |
637 | struct passwd *pw; | 638 | struct passwd *pw; |
638 | int i, ac = 0, uid_swapped = 0; | 639 | int i, ac = 0, uid_swapped = 0; |
639 | pid_t pid; | 640 | pid_t pid; |
640 | char *tmp, *username = NULL, *command = NULL, **av = NULL; | 641 | char *tmp, *username = NULL, *command = NULL, **av = NULL; |
642 | char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL; | ||
643 | char serial_s[16]; | ||
641 | void (*osigchld)(int); | 644 | void (*osigchld)(int); |
642 | 645 | ||
643 | if (options.authorized_principals_command == NULL) | 646 | if (options.authorized_principals_command == NULL) |
@@ -675,10 +678,38 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | |||
675 | command); | 678 | command); |
676 | goto out; | 679 | goto out; |
677 | } | 680 | } |
681 | if ((ca_fp = sshkey_fingerprint(cert->signature_key, | ||
682 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { | ||
683 | error("%s: sshkey_fingerprint failed", __func__); | ||
684 | goto out; | ||
685 | } | ||
686 | if ((key_fp = sshkey_fingerprint(key, | ||
687 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { | ||
688 | error("%s: sshkey_fingerprint failed", __func__); | ||
689 | goto out; | ||
690 | } | ||
691 | if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) { | ||
692 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
693 | goto out; | ||
694 | } | ||
695 | if ((r = sshkey_to_base64(key, &keytext)) != 0) { | ||
696 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
697 | goto out; | ||
698 | } | ||
699 | snprintf(serial_s, sizeof(serial_s), "%llu", | ||
700 | (unsigned long long)cert->serial); | ||
678 | for (i = 1; i < ac; i++) { | 701 | for (i = 1; i < ac; i++) { |
679 | tmp = percent_expand(av[i], | 702 | tmp = percent_expand(av[i], |
680 | "u", user_pw->pw_name, | 703 | "u", user_pw->pw_name, |
681 | "h", user_pw->pw_dir, | 704 | "h", user_pw->pw_dir, |
705 | "t", sshkey_ssh_name(key), | ||
706 | "T", sshkey_ssh_name(cert->signature_key), | ||
707 | "f", key_fp, | ||
708 | "F", ca_fp, | ||
709 | "k", keytext, | ||
710 | "K", catext, | ||
711 | "i", cert->key_id, | ||
712 | "s", serial_s, | ||
682 | (char *)NULL); | 713 | (char *)NULL); |
683 | if (tmp == NULL) | 714 | if (tmp == NULL) |
684 | fatal("%s: percent_expand failed", __func__); | 715 | fatal("%s: percent_expand failed", __func__); |
@@ -713,6 +744,10 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | |||
713 | restore_uid(); | 744 | restore_uid(); |
714 | free(command); | 745 | free(command); |
715 | free(username); | 746 | free(username); |
747 | free(ca_fp); | ||
748 | free(key_fp); | ||
749 | free(catext); | ||
750 | free(keytext); | ||
716 | return found_principal; | 751 | return found_principal; |
717 | } | 752 | } |
718 | /* | 753 | /* |
@@ -723,18 +758,18 @@ static int | |||
723 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | 758 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) |
724 | { | 759 | { |
725 | char line[SSH_MAX_PUBKEY_BYTES]; | 760 | char line[SSH_MAX_PUBKEY_BYTES]; |
726 | const char *reason; | ||
727 | int found_key = 0; | 761 | int found_key = 0; |
728 | u_long linenum = 0; | 762 | u_long linenum = 0; |
729 | Key *found; | 763 | Key *found; |
730 | char *fp; | ||
731 | 764 | ||
732 | found_key = 0; | 765 | found_key = 0; |
733 | 766 | ||
734 | found = NULL; | 767 | found = NULL; |
735 | auth_start_parse_options(); | 768 | auth_start_parse_options(); |
736 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 769 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
737 | char *cp, *key_options = NULL; | 770 | char *cp, *key_options = NULL, *fp = NULL; |
771 | const char *reason = NULL; | ||
772 | |||
738 | if (found != NULL) | 773 | if (found != NULL) |
739 | key_free(found); | 774 | key_free(found); |
740 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); | 775 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); |
@@ -799,10 +834,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
799 | authorized_principals == NULL ? pw->pw_name : NULL, | 834 | authorized_principals == NULL ? pw->pw_name : NULL, |
800 | &reason) != 0) | 835 | &reason) != 0) |
801 | goto fail_reason; | 836 | goto fail_reason; |
802 | if (auth_cert_options(key, pw) != 0) { | 837 | if (auth_cert_options(key, pw, &reason) != 0) |
803 | free(fp); | 838 | goto fail_reason; |
804 | continue; | ||
805 | } | ||
806 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | 839 | verbose("Accepted certificate ID \"%s\" (serial %llu) " |
807 | "signed by %s CA %s via %s", key->cert->key_id, | 840 | "signed by %s CA %s via %s", key->cert->key_id, |
808 | (unsigned long long)key->cert->serial, | 841 | (unsigned long long)key->cert->serial, |
@@ -865,7 +898,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
865 | found_principal = 1; | 898 | found_principal = 1; |
866 | } | 899 | } |
867 | /* Try querying command if specified */ | 900 | /* Try querying command if specified */ |
868 | if (!found_principal && match_principals_command(pw, key->cert)) | 901 | if (!found_principal && match_principals_command(pw, key)) |
869 | found_principal = 1; | 902 | found_principal = 1; |
870 | /* If principals file or command is specified, then require a match */ | 903 | /* If principals file or command is specified, then require a match */ |
871 | use_authorized_principals = principals_file != NULL || | 904 | use_authorized_principals = principals_file != NULL || |
@@ -881,8 +914,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
881 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) | 914 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) |
882 | goto fail_reason; | 915 | goto fail_reason; |
883 | auth_start_parse_options(); | 916 | auth_start_parse_options(); |
884 | if (auth_cert_options(key, pw) != 0) | 917 | if (auth_cert_options(key, pw, &reason) != 0) |
885 | goto out; | 918 | goto fail_reason; |
886 | 919 | ||
887 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " | 920 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " |
888 | "%s CA %s via %s", key->cert->key_id, | 921 | "%s CA %s via %s", key->cert->key_id, |