/*
SSSD
Library for rule based certificate to user mapping - KRB5 matching rules
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2017 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ctype.h>
#include "util/crypto/sss_crypto.h"
#include "lib/certmap/sss_certmap.h"
#include "lib/certmap/sss_certmap_int.h"
{
size_t c = 0;
bool has_dot = false;
return false;
}
if (s[c] != '.' && !isdigit(s[c])) {
return false;
}
if (!has_dot && s[c] == '.') {
has_dot = true;
}
c++;
}
}
{
}
return 0;
}
/*
* The syntax of the MIT Kerberos style matching rules is:
* [KRB5:][relation-operator]component-rule ...
*
* where:
*
* relation-operator
* can be either &&, meaning all component rules must match, or ||,
* meaning only one component rule must match. The default is &&.
*
* component-rule
* can be one of the following. Note that there is no punctuation or whitespace between component rules.
* <SUBJECT>regular-expression
* <ISSUER>regular-expression
* <SAN>regular-expression
* <EKU>extended-key-usage
* <KU>key-usage
*
* see man sss-certmap for more details
*
*/
struct sss_certmap_ctx *ctx,
const char **cur,
struct component_list **_comp)
{
const char *end;
int ret;
goto done;
}
} else {
}
goto done;
}
goto done;
}
ret = 0;
done:
if (ret != 0) {
}
return ret;
}
struct sss_certmap_ctx *ctx,
const char **cur,
struct component_list **_comp)
{
int ret;
char **eku_list;
size_t c;
size_t k;
const char *o;
size_t e = 0;
int eku_list_size;
struct ext_key_usage {
const char *name;
const char *oid;
} ext_key_usage[] = {
/* RFC 3280 section 4.2.1.13 */
{"serverAuth", "1.3.6.1.5.5.7.3.1"},
{"clientAuth", "1.3.6.1.5.5.7.3.2"},
{"codeSigning", "1.3.6.1.5.5.7.3.3"},
{"emailProtection", "1.3.6.1.5.5.7.3.4"},
{"timeStamping", "1.3.6.1.5.5.7.3.8"},
{"OCSPSigning", "1.3.6.1.5.5.7.3.9"},
/* RFC 4556 section 3.2.2 */
{"KPClientAuth", "1.3.6.1.5.2.3.4"},
{"pkinit", "1.3.6.1.5.2.3.4"},
/* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography*/
{"msScLogin", "1.3.6.1.4.1.311.20.2.2"},
{NULL ,0}
};
ret = get_comp_value(mem_ctx, ctx, cur, &comp);
if (ret != 0) {
CM_DEBUG(ctx, "Failed to parse regexp.");
goto done;
}
ret = split_on_separator(mem_ctx, comp->val, ',', true, true,
&eku_list, &eku_list_size);
if (ret != 0) {
CM_DEBUG(ctx, "Failed to split list.");
goto done;
}
comp->eku_oid_list = talloc_zero_array(comp, const char *,
eku_list_size + 1);
if (comp->eku_oid_list == NULL) {
ret = ENOMEM;
goto done;
}
for (c = 0; eku_list[c] != NULL; c++) {
for (k = 0; ext_key_usage[k].name != NULL; k++) {
CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name);
if (strcasecmp(eku_list[c], ext_key_usage[k].name) == 0) {
comp->eku_oid_list[e] = talloc_strdup(comp->eku_oid_list,
ext_key_usage[k].oid);
if (comp->eku_oid_list[e] == NULL) {
ret = ENOMEM;
goto done;
}
e++;
break;
}
}
if (ext_key_usage[k].name == NULL) {
/* check for an dotted-decimal OID */
if (*(eku_list[c]) != '.') {
o = eku_list[c];
if (is_dotted_decimal(o, 0)) {
/* looks like a OID, only '.' and digits */
eku_list[c]);
goto done;
}
e++;
continue;
}
}
goto done;
}
}
if (e == 0) {
}
ret = 0;
done:
if (ret == 0) {
} else {
}
return ret;
}
struct sss_certmap_ctx *ctx,
const char **cur,
struct component_list **_comp)
{
int ret;
char **ku_list;
size_t c;
size_t k;
struct key_usage {
const char *name;
} key_usage[] = {
{"digitalSignature" , SSS_KU_DIGITAL_SIGNATURE},
{"nonRepudiation" , SSS_KU_NON_REPUDIATION},
{"keyEncipherment" , SSS_KU_KEY_ENCIPHERMENT},
{"dataEncipherment" , SSS_KU_DATA_ENCIPHERMENT},
{"keyAgreement" , SSS_KU_KEY_AGREEMENT},
{"keyCertSign" , SSS_KU_KEY_CERT_SIGN},
{"cRLSign" , SSS_KU_CRL_SIGN},
{"encipherOnly" , SSS_KU_ENCIPHER_ONLY},
{"decipherOnly" , SSS_KU_DECIPHER_ONLY},
{NULL ,0}
};
if (ret != 0) {
goto done;
}
if (ret != 0) {
goto done;
}
break;
}
}
/* FIXME: add check for numerical ku */
goto done;
}
}
ret = 0;
done:
if (ret == 0) {
} else {
}
return ret;
}
struct sss_certmap_ctx *ctx,
const char **cur,
struct component_list **_comp)
{
int ret;
if (ret != 0) {
goto done;
}
if (ret != 0) {
goto done;
}
ret = 0;
done:
if (ret == 0) {
} else {
}
return ret;
}
struct san_name {
const char *name;
bool is_string;
} san_names[] = {
/* https://www.ietf.org/rfc/rfc3280.txt section 4.2.1.7 */
{"otherName", SAN_OTHER_NAME, false},
{"rfc822Name", SAN_RFC822_NAME,true},
{"dNSName", SAN_DNS_NAME, true},
{"x400Address", SAN_X400_ADDRESS, false},
{"directoryName", SAN_DIRECTORY_NAME, true},
{"ediPartyName", SAN_EDIPART_NAME, false},
{"uniformResourceIdentifier", SAN_URI, true},
{"iPAddress", SAN_IP_ADDRESS, true},
{"registeredID", SAN_REGISTERED_ID, true},
/* https://www.ietf.org/rfc/rfc4556.txt section 3.2.2 */
{"pkinitSAN", SAN_PKINIT, true},
/* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography */
{"ntPrincipalName", SAN_NT, true},
/* both previous principal types */
{"Principal", SAN_PRINCIPAL, true},
{"stringOtherName", SAN_STRING_OTHER_NAME, true},
};
struct sss_certmap_ctx *ctx,
const char **cur,
char **str_other_name_oid)
{
char *end;
size_t c;
return EINVAL;
}
if (len == 0) {
c= SAN_PRINCIPAL;
} else {
break;
}
}
if (*str_other_name_oid == NULL) {
return ENOMEM;
}
} else {
return EINVAL;
}
}
}
return 0;
}
struct sss_certmap_ctx *ctx,
const char **cur,
struct component_list **_comp)
{
int ret;
if (ret != 0) {
goto done;
}
}
if (ret != 0) {
goto done;
}
} else {
if (ret != 0) {
goto done;
}
&comp->bin_val_len);
/* for some reasons the NSS version of sss_base64_decode might
* return a non-NULL value on error but len is still 0, so better
* check both. */
goto done;
}
}
}
done:
if (ret == 0) {
} else {
}
return ret;
}
const char *rule_start,
struct krb5_match_rule **match_rule)
{
const char *cur;
int ret;
goto done;
}
cur = rule_start;
/* check relation */
rule->r = relation_and;
cur += 2;
rule->r = relation_or;
cur += 2;
} else {
rule->r = relation_and;
}
while (*cur != '\0') {
/* new component must start with '<' */
if (*cur != '<') {
goto done;
}
cur++;
cur += 7;
if (ret != 0) {
goto done;
}
cur += 8;
if (ret != 0) {
goto done;
}
cur += 3;
if (ret != 0) {
goto done;
}
cur += 4;
if (ret != 0) {
goto done;
}
cur += 4;
if (ret != 0) {
goto done;
}
} else {
goto done;
}
}
ret = 0;
done:
if (ret == 0) {
*match_rule = rule;
} else {
}
return ret;
}