summaryrefslogtreecommitdiff
path: root/auth2-pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r--auth2-pubkey.c61
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
561static int 561static int
562process_principals(FILE *f, char *file, struct passwd *pw, 562process_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 */
631static int 631static int
632match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) 632match_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
722check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) 757check_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,