summaryrefslogtreecommitdiff
path: root/sshsig.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-23 23:31:52 +0000
committerDamien Miller <djm@mindrot.org>2020-01-25 11:27:29 +1100
commit72a8bea2d748c8bd7f076a8b39a52082c79ae95f (patch)
tree14bea4a63d81af371d75708384811f5829a38267 /sshsig.c
parent0585b5697201f5d8b32e6f1b0fee7e188268d30d (diff)
upstream: ssh-keygen -Y find-principals fixes based on feedback
from Markus: use "principals" instead of principal, as allowed_signers lines may list multiple. When the signing key is a certificate, emit only principals that match the certificate principal list. NB. the command -Y name changes: "find-principal" => "find-principals" ok markus@ OpenBSD-Commit-ID: ab575946ff9a55624cd4e811bfd338bf3b1d0faf
Diffstat (limited to 'sshsig.c')
-rw-r--r--sshsig.c74
1 files changed, 63 insertions, 11 deletions
diff --git a/sshsig.c b/sshsig.c
index e9f4baa76..e63a36e1e 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -868,13 +868,64 @@ sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
868} 868}
869 869
870static int 870static int
871get_matching_principal_from_line(const char *path, u_long linenum, char *line, 871cert_filter_principals(const char *path, u_long linenum,
872 char **principalsp, const struct sshkey *cert)
873{
874 char *cp, *oprincipals, *principals;
875 const char *reason;
876 struct sshbuf *nprincipals;
877 int r = SSH_ERR_INTERNAL_ERROR, success = 0;
878
879 oprincipals = principals = *principalsp;
880 *principalsp = NULL;
881
882 if ((nprincipals = sshbuf_new()) == NULL)
883 return SSH_ERR_ALLOC_FAIL;
884
885 while ((cp = strsep(&principals, ",")) != NULL && *cp != '\0') {
886 if (strcspn(cp, "!?*") != strlen(cp)) {
887 debug("%s:%lu: principal \"%s\" not authorized: "
888 "contains wildcards", path, linenum, cp);
889 continue;
890 }
891 /* Check against principals list in certificate */
892 if ((r = sshkey_cert_check_authority(cert, 0, 1,
893 cp, &reason)) != 0) {
894 debug("%s:%lu: principal \"%s\" not authorized: %s",
895 path, linenum, cp, reason);
896 continue;
897 }
898 if ((r = sshbuf_putf(nprincipals, "%s%s",
899 sshbuf_len(nprincipals) != 0 ? "," : "", cp)) != 0) {
900 error("%s: buffer error", __func__);
901 goto out;
902 }
903 }
904 if (sshbuf_len(nprincipals) == 0) {
905 error("%s:%lu: no valid principals found", path, linenum);
906 r = SSH_ERR_KEY_CERT_INVALID;
907 goto out;
908 }
909 if ((principals = sshbuf_dup_string(nprincipals)) == NULL) {
910 error("%s: buffer error", __func__);
911 goto out;
912 }
913 /* success */
914 success = 1;
915 *principalsp = principals;
916 out:
917 sshbuf_free(nprincipals);
918 free(oprincipals);
919 return success ? 0 : r;
920}
921
922static int
923get_matching_principals_from_line(const char *path, u_long linenum, char *line,
872 const struct sshkey *sign_key, char **principalsp) 924 const struct sshkey *sign_key, char **principalsp)
873{ 925{
874 struct sshkey *found_key = NULL; 926 struct sshkey *found_key = NULL;
875 char *principals = NULL; 927 char *principals = NULL;
876 int r, found = 0; 928 int r, found = 0;
877 const char *reason = NULL;
878 struct sshsigopt *sigopts = NULL; 929 struct sshsigopt *sigopts = NULL;
879 930
880 if (principalsp != NULL) 931 if (principalsp != NULL)
@@ -894,11 +945,12 @@ get_matching_principal_from_line(const char *path, u_long linenum, char *line,
894 found = 1; 945 found = 1;
895 } else if (sigopts->ca && sshkey_is_cert(sign_key) && 946 } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
896 sshkey_equal_public(sign_key->cert->signature_key, found_key)) { 947 sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
897 /* Match of certificate's CA key */ 948 /* Remove principals listed in file but not allowed by cert */
898 if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 949 if ((r = cert_filter_principals(path, linenum,
899 principals, &reason)) != 0) { 950 &principals, sign_key)) != 0) {
900 error("%s:%lu: certificate not authorized: %s", 951 /* error already displayed */
901 path, linenum, reason); 952 debug("%s:%lu: cert_filter_principals: %s",
953 path, linenum, ssh_err(r));
902 goto done; 954 goto done;
903 } 955 }
904 debug("%s:%lu: matched certificate CA key", path, linenum); 956 debug("%s:%lu: matched certificate CA key", path, linenum);
@@ -920,8 +972,8 @@ get_matching_principal_from_line(const char *path, u_long linenum, char *line,
920} 972}
921 973
922int 974int
923sshsig_find_principal(const char *path, const struct sshkey *sign_key, 975sshsig_find_principals(const char *path, const struct sshkey *sign_key,
924 char **principal) 976 char **principals)
925{ 977{
926 FILE *f = NULL; 978 FILE *f = NULL;
927 char *line = NULL; 979 char *line = NULL;
@@ -939,8 +991,8 @@ sshsig_find_principal(const char *path, const struct sshkey *sign_key,
939 991
940 while (getline(&line, &linesize, f) != -1) { 992 while (getline(&line, &linesize, f) != -1) {
941 linenum++; 993 linenum++;
942 r = get_matching_principal_from_line(path, linenum, line, 994 r = get_matching_principals_from_line(path, linenum, line,
943 sign_key, principal); 995 sign_key, principals);
944 free(line); 996 free(line);
945 line = NULL; 997 line = NULL;
946 if (r == SSH_ERR_KEY_NOT_FOUND) 998 if (r == SSH_ERR_KEY_NOT_FOUND)