159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * COPYRIGHT (C) 2007
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ALL RIGHTS RESERVED
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Permission is granted to use, copy, create derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and redistribute this software and such derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for any purpose, so long as the name of The University of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Michigan is not used in any advertising or publicity
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pertaining to the use of distribution of this software
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * without specific, written prior authorization. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * above copyright notice or any other identification of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * University of Michigan is included in any copy of any
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * portion of this software, then the disclaimer below must
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * also be included.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * SUCH DAMAGES.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <errno.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <string.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdio.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdlib.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <unistd.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <regex.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <krb5.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include "pkinit.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef struct _pkinit_cert_info pkinit_cert_info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef enum {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_undefined = 0,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_subject = 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_issuer = 2,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_san = 3,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_eku = 4,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_ku = 5
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} keyword_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankeyword2string(unsigned int kw)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: removed "break"s (lint) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(kw) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_undefined: return "NONE";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_subject: return "SUBJECT";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_issuer: return "ISSUER";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_san: return "SAN";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_eku: return "EKU";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_ku: return "KU";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default: return "INVALID";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef enum {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan relation_none = 0,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan relation_and = 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan relation_or = 2
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} relation_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanrelation2string(unsigned int rel)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: removed "break"s (lint) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(rel) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case relation_none: return "NONE";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case relation_and: return "AND";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case relation_or: return "OR";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default: return "INVALID";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef enum {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwvaltype_undefined = 0,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwvaltype_regexp = 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwvaltype_list = 2
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} kw_value_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankwval2string(unsigned int kwval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: removed "break"s (lint) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(kwval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kwvaltype_undefined: return "NONE";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kwvaltype_regexp: return "REGEXP";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kwvaltype_list: return "LIST";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default: return "INVALID";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct keyword_desc {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *value;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyword_type kwtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_value_type kwvaltype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} matching_keywords[] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "<KU>", 4, kw_ku, kwvaltype_list },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "<EKU>", 5, kw_eku, kwvaltype_list },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "<SAN>", 5, kw_san, kwvaltype_regexp },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "<ISSUER>", 8, kw_issuer, kwvaltype_regexp },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "<SUBJECT>", 9, kw_subject, kwvaltype_regexp },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { NULL, 0, kw_undefined, kwvaltype_undefined},
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct ku_desc {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *value;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int bitval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct ku_desc ku_keywords[] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "digitalSignature", 16, PKINIT_KU_DIGITALSIGNATURE },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "keyEncipherment", 15, PKINIT_KU_KEYENCIPHERMENT },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { NULL, 0, 0 },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct ku_desc eku_keywords[] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "pkinit", 6, PKINIT_EKU_PKINIT },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "msScLogin", 9, PKINIT_EKU_MSSCLOGIN },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "clientAuth", 10, PKINIT_EKU_CLIENTAUTH },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { "emailProtection", 15, PKINIT_EKU_EMAILPROTECTION },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan { NULL, 0, 0 },
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Rule component */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef struct _rule_component {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _rule_component *next;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyword_type kw_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_value_type kwval_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan regex_t regexp; /* Compiled regular expression */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *regsrc; /* The regular expression source (for debugging) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int ku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int eku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} rule_component;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Set rule components */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalantypedef struct _rule_set {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan relation_type relation;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int num_crs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *crs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan} rule_set;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanfree_rule_component(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc->kwval_type == kwvaltype_regexp) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc->regsrc)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(rc->regsrc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan regfree(&rc->regexp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(rc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanfree_rule_set(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_set *rs)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc, *trc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (rc = rs->crs; rc != NULL;) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan trc = rc->next;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_rule_component(context, rc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc = trc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(rs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanparse_list_value(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyword_type type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *value,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *comma;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct ku_desc *ku = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int found;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *bitptr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (value == NULL || value[0] == '\0') {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Missing or empty value for list keyword type %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (type == kw_eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bitptr = &rc->eku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (type == kw_ku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bitptr = &rc->ku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Unknown list keyword type %d\n", __FUNCTION__, type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan do {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan found = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan comma = strchr(value, ',');
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (comma != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = comma - value;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = strlen(value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (type == kw_eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ku = eku_keywords;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (type == kw_ku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ku = ku_keywords;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (; ku->value != NULL; ku++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strncasecmp(value, ku->value, len) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *bitptr |= ku->bitval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan found = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Found value '%s', bitfield is now 0x%x\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, ku->value, *bitptr);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (found) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan value += ku->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*value == ',')
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan value += 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Urecognized value '%s'\n", __FUNCTION__, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } while (found && *value != '\0');
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanparse_rule_component(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char **rule,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *remaining,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component **ret_rule)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyword_type kw_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_value_type kwval_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char err_buf[128];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int ret;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct keyword_desc *kw, *nextkw;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *nk;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int found_next_kw = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *value = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (kw = matching_keywords; kw->value != NULL; kw++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strncmp(*rule, kw->value, kw->length) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kw_type = kw->kwtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwval_type = kw->kwvaltype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *rule += kw->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *remaining -= kw->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (kw->value == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Missing or invalid keyword in rule '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, *rule);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found keyword '%s'\n", __FUNCTION__, kw->value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc = calloc(1, sizeof(*rc));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->next = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->kw_type = kw_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->kwval_type = kwval_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Before procesing the value for this keyword,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (compiling the regular expression or processing the list)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * we need to find the end of it. That means parsing for the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * beginning of the next keyword (or the end of the rule).
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nk = strchr(*rule, '<');
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while (nk != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Possibly another keyword, check it out */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (nextkw = matching_keywords; nextkw->value != NULL; nextkw++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strncmp(nk, nextkw->value, nextkw->length) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Found a keyword, nk points to the beginning */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan found_next_kw = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break; /* Need to break out of the while! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!found_next_kw)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nk = strchr(nk+1, '<'); /* keep looking */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (nk != NULL && found_next_kw)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = (nk - *rule);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = (*remaining);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (len == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Missing value for keyword '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, kw->value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan value = calloc(1, len+1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (value == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(value, *rule, len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *remaining -= len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *rule += len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found value '%s'\n", __FUNCTION__, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (kw->kwvaltype == kwvaltype_regexp) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = regcomp(&rc->regexp, value, REG_EXTENDED);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) regerror(ret, &rc->regexp, err_buf, sizeof(err_buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Error compiling reg-exp '%s': %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, value, err_buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ret;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->regsrc = strdup(value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc->regsrc == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (kw->kwvaltype == kwvaltype_list) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = parse_list_value(context, rc->kw_type, value, rc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Error %d, parsing list values for keyword %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, kw->value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_rule = rc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (value != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && rc != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_rule_component(context, rc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanparse_rule_set(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *rule_in,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_set **out_rs)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *rule;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int remaining;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code ret, retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc = NULL, *trc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_set *rs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rule_in == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule = rule_in;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan remaining = strlen(rule);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs = calloc(1, sizeof(*rs));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rs == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->relation = relation_none;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (remaining > 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rule[0] == '&' && rule[1] == '&') {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->relation = relation_and;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule += 2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan remaining -= 2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (rule_in[0] == '|' && rule_in[1] == '|') {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->relation = relation_or;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule +=2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan remaining -= 2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->num_crs = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while (remaining > 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rs->relation == relation_none && rs->num_crs > 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Assuming AND relation for multiple components in rule '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, rule_in);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->relation = relation_and;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = parse_rule_component(context, &rule, &remaining, &rc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ret;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: After parse_rule_component, remaining %d, rule '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, remaining, rule);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->num_crs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Chain the new component on the end (order matters since
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * we can short-circuit an OR or an AND relation if an
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * earlier check passes
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (trc = rs->crs; trc != NULL && trc->next != NULL; trc = trc->next);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (trc == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs->crs = rc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan trc->next = rc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_rs = rs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && rs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_rule_set(context, rs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanregexp_match(krb5_context context, rule_component *rc, char *value)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: checking %s rule '%s' with value '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type), rc->regsrc, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = regexec(&rc->regexp, value, 0, NULL, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: the result is%s a match\n", __FUNCTION__,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code == REG_NOMATCH ? " NOT" : "");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (code == 0 ? 1: 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancomponent_match(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int match = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal p;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *princ_string;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (rc->kwval_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kwvaltype_regexp:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (rc->kw_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_subject:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan match = regexp_match(context, rc, md->subject_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_issuer:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan match = regexp_match(context, rc, md->issuer_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_san:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->sans == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_unparse_name(context, p, &princ_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan match = regexp_match(context, rc, princ_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_unparsed_name(context, princ_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (match)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: keyword %s, keyword value %s mismatch\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwval2string(kwvaltype_regexp));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kwvaltype_list:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(rc->kw_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_eku:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: checking %s: rule 0x%08x, cert 0x%08x\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->eku_bits, md->eku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((rc->eku_bits & md->eku_bits) == rc->eku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan match = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case kw_ku:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: checking %s: rule 0x%08x, cert 0x%08x\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rc->ku_bits, md->ku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((rc->ku_bits & md->ku_bits) == rc->ku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan match = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: keyword %s, keyword value %s mismatch\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kwval2string(kwvaltype_regexp));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unknown keyword value type %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, rc->kwval_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning match = %d\n", __FUNCTION__, match);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return match;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Returns match_found == 1 only if exactly one certificate matches
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the given rule
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancheck_all_certs(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_set *rs, /* rule to check */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **matchdata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *match_found,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **matching_cert)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int comp_match = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int total_cert_matches = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_component *rc;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int certs_checked = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *save_match = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (match_found == NULL || matching_cert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *matching_cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *match_found = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: matching rule relation is %s with %d components\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, relation2string(rs->relation), rs->num_crs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Loop through all the certs available and count
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * how many match the rule
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->subject_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0, p = md->sans[j]; p != NULL; p = md->sans[++j]) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *san_string;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_unparse_name(context, p, &san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: san: '%s'\n", __FUNCTION__, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_unparsed_name(context, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certs_checked++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (rc = rs->crs; rc != NULL; rc = rc->next) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan comp_match = component_match(context, rc, md);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (comp_match) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: match for keyword type %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, keyword2string(rc->kw_type));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (comp_match && rs->relation == relation_or) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: cert matches rule (OR relation)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan total_cert_matches++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan save_match = md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto nextcert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!comp_match && rs->relation == relation_and) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: cert does not match rule (AND relation)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto nextcert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rc == NULL && comp_match) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: cert matches rule (AND relation)\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan total_cert_matches++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan save_match = md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalannextcert:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: After checking %d certs, we found %d matches\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, certs_checked, total_cert_matches);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (total_cert_matches == 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *match_found = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *matching_cert = save_match;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning %d, match_found %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *match_found);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanfree_all_cert_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **matchdata)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (matchdata == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_handle ch = md->ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_free_matching_data(context, md);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_free_matching_data error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_release(context, ch);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_release error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(matchdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanobtain_all_cert_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data ***all_matching_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, cert_count;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_iter_handle ih = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_handle ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **matchdata = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, &cert_count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_get_count says there are %d certs\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, cert_count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan matchdata = calloc((size_t)cert_count + 1, sizeof(*matchdata));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (matchdata == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_iteration_begin(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, &ih);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_iteration_begin returned %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < cert_count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_iteration_next(context, ih, &ch);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval == PKINIT_ITER_NO_MORE)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: We thought there were %d certs, but "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "crypto_cert_iteration_next stopped after %d?\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, cert_count, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_iteration_next error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_get_matching_data(context, ch, &matchdata[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_get_matching_data error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *all_matching_data = matchdata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ih != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) crypto_cert_iteration_end(context, ih);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (matchdata != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_all_cert_matching_data(context, matchdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning %d, certinfo %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *all_matching_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_cert_matching(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_principal princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_boolean do_select)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int x;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char **rules = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rule_set *rs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int match_found = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **matchdata = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *the_matching_cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If no matching rules, select the default cert and we're done */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_strings(context, krb5_princ_realm(context, princ),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_cert_match", &rules);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rules == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no matching rules found in config file\n", __FUNCTION__);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (do_select == TRUE) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash retval = crypto_cert_select_default(context, plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash req_cryptoctx, id_cryptoctx);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* parse each rule line one at a time and check all the certs against it */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (x = 0; rules[x] != NULL; x++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Processing rule '%s'\n", __FUNCTION__, rules[x]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Free rules from previous time through... */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_rule_set(context, rs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = parse_rule_set(context, rules[x], &rs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval == EINVAL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Ignoring invalid rule pkinit_cert_match = '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, rules[x]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Optimize so that we do not get cert info unless we have
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * valid rules to check. Once obtained, keep it around
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * until we are done.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (matchdata == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = obtain_all_cert_matching_data(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &matchdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval || matchdata == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Error %d obtaining certificate information\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = check_all_certs(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, princ, rs, matchdata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &match_found, &the_matching_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Error %d, checking certs against rule '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, rules[x]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (match_found) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: We have an exact match with rule '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, rules[x]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (match_found && the_matching_cert != NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (do_select == TRUE) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("%s: Selecting the matching cert!\n", __FUNCTION__);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash retval = crypto_cert_select(context, the_matching_cert);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (retval) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("%s: crypto_cert_select error %d, %s\n",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash __FUNCTION__, retval, error_message(retval));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto cleanup;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOENT; /* XXX */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rules != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan profile_free_list(rules);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_rule_set(context, rs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (matchdata != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) free_all_cert_matching_data(context, matchdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}