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 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
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;
@@ -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 */
632static int 632static int
633match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) 633match_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
723check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) 758check_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,