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 41b34aed2..20f3309e1 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; |
@@ -629,14 +629,17 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) | |||
629 | * returns 1 if the principal is allowed or 0 otherwise. | 629 | * returns 1 if the principal is allowed or 0 otherwise. |
630 | */ | 630 | */ |
631 | static int | 631 | static int |
632 | match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | 632 | match_principals_command(struct passwd *user_pw, const struct sshkey *key) |
633 | { | 633 | { |
634 | const struct sshkey_cert *cert = key->cert; | ||
634 | FILE *f = NULL; | 635 | FILE *f = NULL; |
635 | int ok, found_principal = 0; | 636 | int r, ok, found_principal = 0; |
636 | struct passwd *pw; | 637 | struct passwd *pw; |
637 | int i, ac = 0, uid_swapped = 0; | 638 | int i, ac = 0, uid_swapped = 0; |
638 | pid_t pid; | 639 | pid_t pid; |
639 | char *tmp, *username = NULL, *command = NULL, **av = NULL; | 640 | char *tmp, *username = NULL, *command = NULL, **av = NULL; |
641 | char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL; | ||
642 | char serial_s[16]; | ||
640 | void (*osigchld)(int); | 643 | void (*osigchld)(int); |
641 | 644 | ||
642 | if (options.authorized_principals_command == NULL) | 645 | if (options.authorized_principals_command == NULL) |
@@ -674,10 +677,38 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | |||
674 | command); | 677 | command); |
675 | goto out; | 678 | goto out; |
676 | } | 679 | } |
680 | if ((ca_fp = sshkey_fingerprint(cert->signature_key, | ||
681 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { | ||
682 | error("%s: sshkey_fingerprint failed", __func__); | ||
683 | goto out; | ||
684 | } | ||
685 | if ((key_fp = sshkey_fingerprint(key, | ||
686 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { | ||
687 | error("%s: sshkey_fingerprint failed", __func__); | ||
688 | goto out; | ||
689 | } | ||
690 | if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) { | ||
691 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
692 | goto out; | ||
693 | } | ||
694 | if ((r = sshkey_to_base64(key, &keytext)) != 0) { | ||
695 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
696 | goto out; | ||
697 | } | ||
698 | snprintf(serial_s, sizeof(serial_s), "%llu", | ||
699 | (unsigned long long)cert->serial); | ||
677 | for (i = 1; i < ac; i++) { | 700 | for (i = 1; i < ac; i++) { |
678 | tmp = percent_expand(av[i], | 701 | tmp = percent_expand(av[i], |
679 | "u", user_pw->pw_name, | 702 | "u", user_pw->pw_name, |
680 | "h", user_pw->pw_dir, | 703 | "h", user_pw->pw_dir, |
704 | "t", sshkey_ssh_name(key), | ||
705 | "T", sshkey_ssh_name(cert->signature_key), | ||
706 | "f", key_fp, | ||
707 | "F", ca_fp, | ||
708 | "k", keytext, | ||
709 | "K", catext, | ||
710 | "i", cert->key_id, | ||
711 | "s", serial_s, | ||
681 | (char *)NULL); | 712 | (char *)NULL); |
682 | if (tmp == NULL) | 713 | if (tmp == NULL) |
683 | fatal("%s: percent_expand failed", __func__); | 714 | fatal("%s: percent_expand failed", __func__); |
@@ -712,6 +743,10 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) | |||
712 | restore_uid(); | 743 | restore_uid(); |
713 | free(command); | 744 | free(command); |
714 | free(username); | 745 | free(username); |
746 | free(ca_fp); | ||
747 | free(key_fp); | ||
748 | free(catext); | ||
749 | free(keytext); | ||
715 | return found_principal; | 750 | return found_principal; |
716 | } | 751 | } |
717 | /* | 752 | /* |
@@ -722,17 +757,17 @@ static int | |||
722 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | 757 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) |
723 | { | 758 | { |
724 | char line[SSH_MAX_PUBKEY_BYTES]; | 759 | char line[SSH_MAX_PUBKEY_BYTES]; |
725 | const char *reason; | ||
726 | int found_key = 0; | 760 | int found_key = 0; |
727 | u_long linenum = 0; | 761 | u_long linenum = 0; |
728 | Key *found; | 762 | Key *found; |
729 | char *fp; | ||
730 | 763 | ||
731 | found_key = 0; | 764 | found_key = 0; |
732 | 765 | ||
733 | found = NULL; | 766 | found = NULL; |
734 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 767 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
735 | char *cp, *key_options = NULL; | 768 | char *cp, *key_options = NULL, *fp = NULL; |
769 | const char *reason = NULL; | ||
770 | |||
736 | if (found != NULL) | 771 | if (found != NULL) |
737 | key_free(found); | 772 | key_free(found); |
738 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); | 773 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); |
@@ -797,10 +832,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
797 | authorized_principals == NULL ? pw->pw_name : NULL, | 832 | authorized_principals == NULL ? pw->pw_name : NULL, |
798 | &reason) != 0) | 833 | &reason) != 0) |
799 | goto fail_reason; | 834 | goto fail_reason; |
800 | if (auth_cert_options(key, pw) != 0) { | 835 | if (auth_cert_options(key, pw, &reason) != 0) |
801 | free(fp); | 836 | goto fail_reason; |
802 | continue; | ||
803 | } | ||
804 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | 837 | verbose("Accepted certificate ID \"%s\" (serial %llu) " |
805 | "signed by %s CA %s via %s", key->cert->key_id, | 838 | "signed by %s CA %s via %s", key->cert->key_id, |
806 | (unsigned long long)key->cert->serial, | 839 | (unsigned long long)key->cert->serial, |
@@ -863,7 +896,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
863 | found_principal = 1; | 896 | found_principal = 1; |
864 | } | 897 | } |
865 | /* Try querying command if specified */ | 898 | /* Try querying command if specified */ |
866 | if (!found_principal && match_principals_command(pw, key->cert)) | 899 | if (!found_principal && match_principals_command(pw, key)) |
867 | found_principal = 1; | 900 | found_principal = 1; |
868 | /* If principals file or command is specified, then require a match */ | 901 | /* If principals file or command is specified, then require a match */ |
869 | use_authorized_principals = principals_file != NULL || | 902 | use_authorized_principals = principals_file != NULL || |
@@ -878,8 +911,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
878 | if (key_cert_check_authority(key, 0, 1, | 911 | if (key_cert_check_authority(key, 0, 1, |
879 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) | 912 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) |
880 | goto fail_reason; | 913 | goto fail_reason; |
881 | if (auth_cert_options(key, pw) != 0) | 914 | if (auth_cert_options(key, pw, &reason) != 0) |
882 | goto out; | 915 | goto fail_reason; |
883 | 916 | ||
884 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " | 917 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " |
885 | "%s CA %s via %s", key->cert->key_id, | 918 | "%s CA %s via %s", key->cert->key_id, |