|
|
460745 |
From f0851afdf0abd516dcd707e6e3ec0086f09f6090 Mon Sep 17 00:00:00 2001
|
|
|
ac7d03 |
From: Jan Cholasta <jcholast@redhat.com>
|
|
|
ac7d03 |
Date: Thu, 16 Mar 2017 09:44:21 +0000
|
|
|
ac7d03 |
Subject: [PATCH] Remove csrgen
|
|
|
ac7d03 |
|
|
|
ac7d03 |
This reverts commits:
|
|
|
ac7d03 |
* 72de679eb445c975ec70cd265d37d4927823ce5b
|
|
|
ac7d03 |
* 177f07e163d6d591a1e609d35e0a6f6f5347551e
|
|
|
ac7d03 |
* 80be18162921268be9c8981495c9e8a4de0c85cd
|
|
|
ac7d03 |
* 83e2c2b65eeb5a3aa4a59c0535e9177aac5e4637
|
|
|
ac7d03 |
* ada91c20588046bb147fc701718d3da4d2c080ca
|
|
|
ac7d03 |
* 4350dcdea22fd2284836315d0ae7d38733a7620e
|
|
|
ac7d03 |
* 39a5d9c5aae77687f67d9be02457733bdfb99ead
|
|
|
ac7d03 |
* a26cf0d7910dd4c0a4da08682b4be8d3d94ba520
|
|
|
ac7d03 |
* afd7c05d11432304bfdf183832a21d419f363689
|
|
|
ac7d03 |
* f1a1c6eca1b294f24174d7b0e1f78de46d9d5b05
|
|
|
ac7d03 |
* fc58eff6a3d7fe805e612b8b002304d8b9cd4ba9
|
|
|
ac7d03 |
* 10ef5947860f5098182b1f95c08c1158e2da15f9
|
|
|
ac7d03 |
|
|
|
ac7d03 |
https://bugzilla.redhat.com/show_bug.cgi?id=1432630
|
|
|
ac7d03 |
---
|
|
|
ac7d03 |
freeipa.spec.in | 18 -
|
|
|
ac7d03 |
ipaclient/csrgen.py | 398 ---------------------
|
|
|
ac7d03 |
ipaclient/csrgen/profiles/caIPAserviceCert.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/profiles/userCert.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/dataDNS.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/dataEmail.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/dataHostCN.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/dataSubjectBase.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/dataUsernameCN.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/syntaxSAN.json | 15 -
|
|
|
ac7d03 |
ipaclient/csrgen/rules/syntaxSubject.json | 16 -
|
|
|
ac7d03 |
ipaclient/csrgen/templates/certutil_base.tmpl | 11 -
|
|
|
ac7d03 |
ipaclient/csrgen/templates/openssl_base.tmpl | 35 --
|
|
|
ac7d03 |
ipaclient/csrgen/templates/openssl_macros.tmpl | 29 --
|
|
|
ac7d03 |
ipaclient/plugins/cert.py | 96 +----
|
|
|
ac7d03 |
ipaclient/plugins/csrgen.py | 120 -------
|
|
|
ac7d03 |
ipaclient/setup.py | 11 +-
|
|
|
ac7d03 |
ipalib/errors.py | 28 --
|
|
|
ac7d03 |
ipatests/setup.py | 2 -
|
|
|
ac7d03 |
ipatests/test_ipaclient/__init__.py | 7 -
|
|
|
ac7d03 |
.../data/test_csrgen/profiles/profile.json | 8 -
|
|
|
ac7d03 |
.../data/test_csrgen/rules/basic.json | 12 -
|
|
|
ac7d03 |
.../data/test_csrgen/rules/options.json | 18 -
|
|
|
ac7d03 |
.../scripts/caIPAserviceCert_certutil.sh | 11 -
|
|
|
ac7d03 |
.../scripts/caIPAserviceCert_openssl.sh | 34 --
|
|
|
ac7d03 |
.../data/test_csrgen/scripts/userCert_certutil.sh | 11 -
|
|
|
ac7d03 |
.../data/test_csrgen/scripts/userCert_openssl.sh | 34 --
|
|
|
ac7d03 |
.../data/test_csrgen/templates/identity_base.tmpl | 1 -
|
|
|
ac7d03 |
ipatests/test_ipaclient/test_csrgen.py | 298 ---------------
|
|
|
ac7d03 |
29 files changed, 2 insertions(+), 1316 deletions(-)
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen.py
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/profiles/caIPAserviceCert.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/profiles/userCert.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/dataDNS.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/dataEmail.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/dataHostCN.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/dataSubjectBase.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/dataUsernameCN.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/syntaxSAN.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/rules/syntaxSubject.json
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/templates/certutil_base.tmpl
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/templates/openssl_base.tmpl
|
|
|
ac7d03 |
delete mode 100644 ipaclient/csrgen/templates/openssl_macros.tmpl
|
|
|
ac7d03 |
delete mode 100644 ipaclient/plugins/csrgen.py
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/__init__.py
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/profiles/profile.json
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/rules/basic.json
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/rules/options.json
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_certutil.sh
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_openssl.sh
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_certutil.sh
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_openssl.sh
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/templates/identity_base.tmpl
|
|
|
ac7d03 |
delete mode 100644 ipatests/test_ipaclient/test_csrgen.py
|
|
|
ac7d03 |
|
|
|
ac7d03 |
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
|
|
b38368 |
index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15a556d2f3 100644
|
|
|
ac7d03 |
--- a/freeipa.spec.in
|
|
|
ac7d03 |
+++ b/freeipa.spec.in
|
|
|
ac7d03 |
@@ -194,7 +194,6 @@ BuildRequires: python-sssdconfig
|
|
|
ac7d03 |
BuildRequires: python-nose
|
|
|
ac7d03 |
BuildRequires: python-paste
|
|
|
ac7d03 |
BuildRequires: systemd-python
|
|
|
ac7d03 |
-BuildRequires: python2-jinja2
|
|
|
ac7d03 |
BuildRequires: python-augeas
|
|
|
ac7d03 |
|
|
|
ac7d03 |
%if 0%{?with_python3}
|
|
|
ac7d03 |
@@ -232,7 +231,6 @@ BuildRequires: python3-libsss_nss_idmap
|
|
|
ac7d03 |
BuildRequires: python3-nose
|
|
|
ac7d03 |
BuildRequires: python3-paste
|
|
|
ac7d03 |
BuildRequires: python3-systemd
|
|
|
ac7d03 |
-BuildRequires: python3-jinja2
|
|
|
ac7d03 |
BuildRequires: python3-augeas
|
|
|
ac7d03 |
%endif # with_python3
|
|
|
ac7d03 |
%endif # with_lint
|
|
|
ac7d03 |
@@ -541,7 +539,6 @@ Requires: %{name}-client-common = %{version}-%{release}
|
|
|
ac7d03 |
Requires: %{name}-common = %{version}-%{release}
|
|
|
ac7d03 |
Requires: python2-ipalib = %{version}-%{release}
|
|
|
ac7d03 |
Requires: python-dns >= 1.15
|
|
|
ac7d03 |
-Requires: python2-jinja2
|
|
|
ac7d03 |
|
|
|
ac7d03 |
%description -n python2-ipaclient
|
|
|
ac7d03 |
IPA is an integrated solution to provide centrally managed Identity (users,
|
|
|
ac7d03 |
@@ -564,7 +561,6 @@ Requires: %{name}-client-common = %{version}-%{release}
|
|
|
ac7d03 |
Requires: %{name}-common = %{version}-%{release}
|
|
|
ac7d03 |
Requires: python3-ipalib = %{version}-%{release}
|
|
|
ac7d03 |
Requires: python3-dns >= 1.15
|
|
|
ac7d03 |
-Requires: python3-jinja2
|
|
|
ac7d03 |
|
|
|
ac7d03 |
%description -n python3-ipaclient
|
|
|
ac7d03 |
IPA is an integrated solution to provide centrally managed Identity (users,
|
|
|
ac7d03 |
@@ -1425,13 +1421,6 @@ fi
|
|
|
ac7d03 |
%dir %{python_sitelib}/ipaclient/remote_plugins
|
|
|
ac7d03 |
%{python_sitelib}/ipaclient/remote_plugins/*.py*
|
|
|
ac7d03 |
%{python_sitelib}/ipaclient/remote_plugins/2_*/*.py*
|
|
|
ac7d03 |
-%dir %{python_sitelib}/ipaclient/csrgen
|
|
|
ac7d03 |
-%dir %{python_sitelib}/ipaclient/csrgen/profiles
|
|
|
ac7d03 |
-%{python_sitelib}/ipaclient/csrgen/profiles/*.json
|
|
|
ac7d03 |
-%dir %{python_sitelib}/ipaclient/csrgen/rules
|
|
|
ac7d03 |
-%{python_sitelib}/ipaclient/csrgen/rules/*.json
|
|
|
ac7d03 |
-%dir %{python_sitelib}/ipaclient/csrgen/templates
|
|
|
ac7d03 |
-%{python_sitelib}/ipaclient/csrgen/templates/*.tmpl
|
|
|
ac7d03 |
%{python_sitelib}/ipaclient-*.egg-info
|
|
|
ac7d03 |
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@@ -1455,13 +1444,6 @@ fi
|
|
|
ac7d03 |
%{python3_sitelib}/ipaclient/remote_plugins/__pycache__/*.py*
|
|
|
ac7d03 |
%{python3_sitelib}/ipaclient/remote_plugins/2_*/*.py
|
|
|
ac7d03 |
%{python3_sitelib}/ipaclient/remote_plugins/2_*/__pycache__/*.py*
|
|
|
ac7d03 |
-%dir %{python3_sitelib}/ipaclient/csrgen
|
|
|
ac7d03 |
-%dir %{python3_sitelib}/ipaclient/csrgen/profiles
|
|
|
ac7d03 |
-%{python3_sitelib}/ipaclient/csrgen/profiles/*.json
|
|
|
ac7d03 |
-%dir %{python3_sitelib}/ipaclient/csrgen/rules
|
|
|
ac7d03 |
-%{python3_sitelib}/ipaclient/csrgen/rules/*.json
|
|
|
ac7d03 |
-%dir %{python3_sitelib}/ipaclient/csrgen/templates
|
|
|
ac7d03 |
-%{python3_sitelib}/ipaclient/csrgen/templates/*.tmpl
|
|
|
ac7d03 |
%{python3_sitelib}/ipaclient-*.egg-info
|
|
|
ac7d03 |
|
|
|
ac7d03 |
%endif # with_python3
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 8fb0b32c05490812b75f87db69f9df1ca38107f7..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen.py
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,398 +0,0 @@
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import collections
|
|
|
ac7d03 |
-import errno
|
|
|
ac7d03 |
-import json
|
|
|
ac7d03 |
-import os.path
|
|
|
ac7d03 |
-import pipes
|
|
|
ac7d03 |
-import traceback
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import pkg_resources
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import jinja2
|
|
|
ac7d03 |
-import jinja2.ext
|
|
|
ac7d03 |
-import jinja2.sandbox
|
|
|
ac7d03 |
-import six
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-from ipalib import api
|
|
|
ac7d03 |
-from ipalib import errors
|
|
|
ac7d03 |
-from ipalib.text import _
|
|
|
ac7d03 |
-from ipapython.ipa_log_manager import log_mgr
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if six.PY3:
|
|
|
ac7d03 |
- unicode = str
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-__doc__ = _("""
|
|
|
ac7d03 |
-Routines for constructing certificate signing requests using IPA data and
|
|
|
ac7d03 |
-stored templates.
|
|
|
ac7d03 |
-""")
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-logger = log_mgr.get_logger(__name__)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class IndexableUndefined(jinja2.Undefined):
|
|
|
ac7d03 |
- def __getitem__(self, key):
|
|
|
ac7d03 |
- return jinja2.Undefined(
|
|
|
ac7d03 |
- hint=self._undefined_hint, obj=self._undefined_obj,
|
|
|
ac7d03 |
- name=self._undefined_name, exc=self._undefined_exception)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class IPAExtension(jinja2.ext.Extension):
|
|
|
ac7d03 |
- """Jinja2 extension providing useful features for CSR generation rules."""
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, environment):
|
|
|
ac7d03 |
- super(IPAExtension, self).__init__(environment)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- environment.filters.update(
|
|
|
ac7d03 |
- quote=self.quote,
|
|
|
ac7d03 |
- required=self.required,
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def quote(self, data):
|
|
|
ac7d03 |
- return pipes.quote(data)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def required(self, data, name):
|
|
|
ac7d03 |
- if not data:
|
|
|
ac7d03 |
- raise errors.CSRTemplateError(
|
|
|
ac7d03 |
- reason=_('Required CSR generation rule %(name)s is missing data') %
|
|
|
ac7d03 |
- {'name': name})
|
|
|
ac7d03 |
- return data
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class Formatter(object):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- Class for processing a set of CSR generation rules into a template.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- The template can be rendered with user and database data to produce a
|
|
|
ac7d03 |
- script, which generates a CSR when run.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- Subclasses of Formatter should set the value of base_template_name to the
|
|
|
ac7d03 |
- filename of a base template with spaces for the processed rules.
|
|
|
ac7d03 |
- Additionally, they should override the _get_template_params method to
|
|
|
ac7d03 |
- produce the correct output for the base template.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- base_template_name = None
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, csr_data_dir=None):
|
|
|
ac7d03 |
- # chain loaders:
|
|
|
ac7d03 |
- # 1) csr_data_dir/templates
|
|
|
ac7d03 |
- # 2) /etc/ipa/csrgen/templates
|
|
|
ac7d03 |
- # 3) ipaclient/csrgen/templates
|
|
|
ac7d03 |
- loaders = []
|
|
|
ac7d03 |
- if csr_data_dir is not None:
|
|
|
ac7d03 |
- loaders.append(jinja2.FileSystemLoader(
|
|
|
ac7d03 |
- os.path.join(csr_data_dir, 'templates'))
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
- loaders.append(jinja2.FileSystemLoader(
|
|
|
ac7d03 |
- os.path.join(api.env.confdir, 'csrgen/templates'))
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
- loaders.append(jinja2.PackageLoader('ipaclient', 'csrgen/templates'))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- self.jinja2 = jinja2.sandbox.SandboxedEnvironment(
|
|
|
ac7d03 |
- loader=jinja2.ChoiceLoader(loaders),
|
|
|
ac7d03 |
- extensions=[jinja2.ext.ExprStmtExtension, IPAExtension],
|
|
|
ac7d03 |
- keep_trailing_newline=True, undefined=IndexableUndefined)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- self.passthrough_globals = {}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _define_passthrough(self, call):
|
|
|
ac7d03 |
- """Some macros are meant to be interpreted during the final render, not
|
|
|
ac7d03 |
- when data rules are interpolated into syntax rules. This method allows
|
|
|
ac7d03 |
- those macros to be registered so that calls to them are passed through
|
|
|
ac7d03 |
- to the prepared rule rather than interpreted.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def passthrough(caller):
|
|
|
ac7d03 |
- return u'{%% call %s() %%}%s{%% endcall %%}' % (call, caller())
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- parts = call.split('.')
|
|
|
ac7d03 |
- current_level = self.passthrough_globals
|
|
|
ac7d03 |
- for part in parts[:-1]:
|
|
|
ac7d03 |
- if part not in current_level:
|
|
|
ac7d03 |
- current_level[part] = {}
|
|
|
ac7d03 |
- current_level = current_level[part]
|
|
|
ac7d03 |
- current_level[parts[-1]] = passthrough
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def build_template(self, rules):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- Construct a template that can produce CSR generator strings.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :param rules: list of FieldMapping to use to populate the template.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :returns: jinja2.Template that can be rendered to produce the CSR data.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- syntax_rules = []
|
|
|
ac7d03 |
- for field_mapping in rules:
|
|
|
ac7d03 |
- data_rules_prepared = [
|
|
|
ac7d03 |
- self._prepare_data_rule(rule)
|
|
|
ac7d03 |
- for rule in field_mapping.data_rules]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- data_sources = []
|
|
|
ac7d03 |
- for rule in field_mapping.data_rules:
|
|
|
ac7d03 |
- data_source = rule.options.get('data_source')
|
|
|
ac7d03 |
- if data_source:
|
|
|
ac7d03 |
- data_sources.append(data_source)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- syntax_rules.append(self._prepare_syntax_rule(
|
|
|
ac7d03 |
- field_mapping.syntax_rule, data_rules_prepared,
|
|
|
ac7d03 |
- field_mapping.description, data_sources))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- template_params = self._get_template_params(syntax_rules)
|
|
|
ac7d03 |
- base_template = self.jinja2.get_template(
|
|
|
ac7d03 |
- self.base_template_name, globals=self.passthrough_globals)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- combined_template_source = base_template.render(**template_params)
|
|
|
ac7d03 |
- except jinja2.UndefinedError:
|
|
|
ac7d03 |
- logger.debug(traceback.format_exc())
|
|
|
ac7d03 |
- raise errors.CSRTemplateError(reason=_(
|
|
|
ac7d03 |
- 'Template error when formatting certificate data'))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- logger.debug(
|
|
|
ac7d03 |
- 'Formatting with template: %s' % combined_template_source)
|
|
|
ac7d03 |
- combined_template = self.jinja2.from_string(combined_template_source)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return combined_template
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _wrap_conditional(self, rule, condition):
|
|
|
ac7d03 |
- rule = '{%% if %s %%}%s{%% endif %%}' % (condition, rule)
|
|
|
ac7d03 |
- return rule
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _wrap_required(self, rule, description):
|
|
|
ac7d03 |
- template = '{%% filter required("%s") %%}%s{%% endfilter %%}' % (
|
|
|
ac7d03 |
- description, rule)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return template
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _prepare_data_rule(self, data_rule):
|
|
|
ac7d03 |
- template = data_rule.template
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- data_source = data_rule.options.get('data_source')
|
|
|
ac7d03 |
- if data_source:
|
|
|
ac7d03 |
- template = self._wrap_conditional(template, data_source)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return template
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _prepare_syntax_rule(
|
|
|
ac7d03 |
- self, syntax_rule, data_rules, description, data_sources):
|
|
|
ac7d03 |
- logger.debug('Syntax rule template: %s' % syntax_rule.template)
|
|
|
ac7d03 |
- template = self.jinja2.from_string(
|
|
|
ac7d03 |
- syntax_rule.template, globals=self.passthrough_globals)
|
|
|
ac7d03 |
- is_required = syntax_rule.options.get('required', False)
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- prepared_template = template.render(datarules=data_rules)
|
|
|
ac7d03 |
- except jinja2.UndefinedError:
|
|
|
ac7d03 |
- logger.debug(traceback.format_exc())
|
|
|
ac7d03 |
- raise errors.CSRTemplateError(reason=_(
|
|
|
ac7d03 |
- 'Template error when formatting certificate data'))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- if data_sources:
|
|
|
ac7d03 |
- combinator = ' %s ' % syntax_rule.options.get(
|
|
|
ac7d03 |
- 'data_source_combinator', 'or')
|
|
|
ac7d03 |
- condition = combinator.join(data_sources)
|
|
|
ac7d03 |
- prepared_template = self._wrap_conditional(
|
|
|
ac7d03 |
- prepared_template, condition)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- if is_required:
|
|
|
ac7d03 |
- prepared_template = self._wrap_required(
|
|
|
ac7d03 |
- prepared_template, description)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return prepared_template
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _get_template_params(self, syntax_rules):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- Package the syntax rules into fields expected by the base template.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :param syntax_rules: list of prepared syntax rules to be included in
|
|
|
ac7d03 |
- the template.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :returns: dict of values needed to render the base template.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- raise NotImplementedError('Formatter class must be subclassed')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class OpenSSLFormatter(Formatter):
|
|
|
ac7d03 |
- """Formatter class supporting the openssl command-line tool."""
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- base_template_name = 'openssl_base.tmpl'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- # Syntax rules are wrapped in this data structure, to keep track of whether
|
|
|
ac7d03 |
- # each goes in the extension or the root section
|
|
|
ac7d03 |
- SyntaxRule = collections.namedtuple(
|
|
|
ac7d03 |
- 'SyntaxRule', ['template', 'is_extension'])
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, *args, **kwargs):
|
|
|
ac7d03 |
- super(OpenSSLFormatter, self).__init__(*args, **kwargs)
|
|
|
ac7d03 |
- self._define_passthrough('openssl.section')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _get_template_params(self, syntax_rules):
|
|
|
ac7d03 |
- parameters = [rule.template for rule in syntax_rules
|
|
|
ac7d03 |
- if not rule.is_extension]
|
|
|
ac7d03 |
- extensions = [rule.template for rule in syntax_rules
|
|
|
ac7d03 |
- if rule.is_extension]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return {'parameters': parameters, 'extensions': extensions}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _prepare_syntax_rule(
|
|
|
ac7d03 |
- self, syntax_rule, data_rules, description, data_sources):
|
|
|
ac7d03 |
- """Overrides method to pull out whether rule is an extension or not."""
|
|
|
ac7d03 |
- prepared_template = super(OpenSSLFormatter, self)._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, description, data_sources)
|
|
|
ac7d03 |
- is_extension = syntax_rule.options.get('extension', False)
|
|
|
ac7d03 |
- return self.SyntaxRule(prepared_template, is_extension)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class CertutilFormatter(Formatter):
|
|
|
ac7d03 |
- base_template_name = 'certutil_base.tmpl'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _get_template_params(self, syntax_rules):
|
|
|
ac7d03 |
- return {'options': syntax_rules}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class FieldMapping(object):
|
|
|
ac7d03 |
- """Representation of the rules needed to construct a complete cert field.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- Attributes:
|
|
|
ac7d03 |
- description: str, a name or description of this field, to be used in
|
|
|
ac7d03 |
- messages
|
|
|
ac7d03 |
- syntax_rule: Rule, the rule defining the syntax of this field
|
|
|
ac7d03 |
- data_rules: list of Rule, the rules that produce data to be stored in
|
|
|
ac7d03 |
- this field
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- __slots__ = ['description', 'syntax_rule', 'data_rules']
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, description, syntax_rule, data_rules):
|
|
|
ac7d03 |
- self.description = description
|
|
|
ac7d03 |
- self.syntax_rule = syntax_rule
|
|
|
ac7d03 |
- self.data_rules = data_rules
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class Rule(object):
|
|
|
ac7d03 |
- __slots__ = ['name', 'template', 'options']
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, name, template, options):
|
|
|
ac7d03 |
- self.name = name
|
|
|
ac7d03 |
- self.template = template
|
|
|
ac7d03 |
- self.options = options
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class RuleProvider(object):
|
|
|
ac7d03 |
- def rules_for_profile(self, profile_id, helper):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- Return the rules needed to build a CSR using the given profile.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :param profile_id: str, name of the CSR generation profile to use
|
|
|
ac7d03 |
- :param helper: str, name of tool (e.g. openssl, certutil) that will be
|
|
|
ac7d03 |
- used to create CSR
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- :returns: list of FieldMapping, filled out with the appropriate rules
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- raise NotImplementedError('RuleProvider class must be subclassed')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class FileRuleProvider(RuleProvider):
|
|
|
ac7d03 |
- def __init__(self, csr_data_dir=None):
|
|
|
ac7d03 |
- self.rules = {}
|
|
|
ac7d03 |
- self._csrgen_data_dirs = []
|
|
|
ac7d03 |
- if csr_data_dir is not None:
|
|
|
ac7d03 |
- self._csrgen_data_dirs.append(csr_data_dir)
|
|
|
ac7d03 |
- self._csrgen_data_dirs.append(
|
|
|
ac7d03 |
- os.path.join(api.env.confdir, 'csrgen')
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
- self._csrgen_data_dirs.append(
|
|
|
ac7d03 |
- pkg_resources.resource_filename('ipaclient', 'csrgen')
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _open(self, subdir, filename):
|
|
|
ac7d03 |
- for data_dir in self._csrgen_data_dirs:
|
|
|
ac7d03 |
- path = os.path.join(data_dir, subdir, filename)
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- return open(path)
|
|
|
ac7d03 |
- except IOError as e:
|
|
|
ac7d03 |
- if e.errno != errno.ENOENT:
|
|
|
ac7d03 |
- raise
|
|
|
ac7d03 |
- raise IOError(
|
|
|
ac7d03 |
- errno.ENOENT,
|
|
|
ac7d03 |
- "'{}' not found in {}".format(
|
|
|
ac7d03 |
- os.path.join(subdir, filename),
|
|
|
ac7d03 |
- ", ".join(self._csrgen_data_dirs)
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _rule(self, rule_name, helper):
|
|
|
ac7d03 |
- if (rule_name, helper) not in self.rules:
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- with self._open('rules', '%s.json' % rule_name) as f:
|
|
|
ac7d03 |
- ruleset = json.load(f)
|
|
|
ac7d03 |
- except IOError:
|
|
|
ac7d03 |
- raise errors.NotFound(
|
|
|
ac7d03 |
- reason=_('Ruleset %(ruleset)s does not exist.') %
|
|
|
ac7d03 |
- {'ruleset': rule_name})
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- matching_rules = [r for r in ruleset['rules']
|
|
|
ac7d03 |
- if r['helper'] == helper]
|
|
|
ac7d03 |
- if len(matching_rules) == 0:
|
|
|
ac7d03 |
- raise errors.EmptyResult(
|
|
|
ac7d03 |
- reason=_('No transformation in "%(ruleset)s" rule supports'
|
|
|
ac7d03 |
- ' helper "%(helper)s"') %
|
|
|
ac7d03 |
- {'ruleset': rule_name, 'helper': helper})
|
|
|
ac7d03 |
- elif len(matching_rules) > 1:
|
|
|
ac7d03 |
- raise errors.RedundantMappingRule(
|
|
|
ac7d03 |
- ruleset=rule_name, helper=helper)
|
|
|
ac7d03 |
- rule = matching_rules[0]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- options = {}
|
|
|
ac7d03 |
- if 'options' in ruleset:
|
|
|
ac7d03 |
- options.update(ruleset['options'])
|
|
|
ac7d03 |
- if 'options' in rule:
|
|
|
ac7d03 |
- options.update(rule['options'])
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- self.rules[(rule_name, helper)] = Rule(
|
|
|
ac7d03 |
- rule_name, rule['template'], options)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return self.rules[(rule_name, helper)]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def rules_for_profile(self, profile_id, helper):
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- with self._open('profiles', '%s.json' % profile_id) as f:
|
|
|
ac7d03 |
- profile = json.load(f)
|
|
|
ac7d03 |
- except IOError:
|
|
|
ac7d03 |
- raise errors.NotFound(
|
|
|
ac7d03 |
- reason=_('No CSR generation rules are defined for profile'
|
|
|
ac7d03 |
- ' %(profile_id)s') % {'profile_id': profile_id})
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- field_mappings = []
|
|
|
ac7d03 |
- for field in profile:
|
|
|
ac7d03 |
- syntax_rule = self._rule(field['syntax'], helper)
|
|
|
ac7d03 |
- data_rules = [self._rule(name, helper) for name in field['data']]
|
|
|
ac7d03 |
- field_mappings.append(FieldMapping(
|
|
|
ac7d03 |
- syntax_rule.name, syntax_rule, data_rules))
|
|
|
ac7d03 |
- return field_mappings
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class CSRGenerator(object):
|
|
|
ac7d03 |
- FORMATTERS = {
|
|
|
ac7d03 |
- 'openssl': OpenSSLFormatter,
|
|
|
ac7d03 |
- 'certutil': CertutilFormatter,
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self, rule_provider):
|
|
|
ac7d03 |
- self.rule_provider = rule_provider
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def csr_script(self, principal, config, profile_id, helper):
|
|
|
ac7d03 |
- render_data = {'subject': principal, 'config': config}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- formatter = self.FORMATTERS[helper]()
|
|
|
ac7d03 |
- rules = self.rule_provider.rules_for_profile(profile_id, helper)
|
|
|
ac7d03 |
- template = formatter.build_template(rules)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- script = template.render(render_data)
|
|
|
ac7d03 |
- except jinja2.UndefinedError:
|
|
|
ac7d03 |
- logger.debug(traceback.format_exc())
|
|
|
ac7d03 |
- raise errors.CSRTemplateError(reason=_(
|
|
|
ac7d03 |
- 'Template error when formatting certificate data'))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return script
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/profiles/caIPAserviceCert.json b/ipaclient/csrgen/profiles/caIPAserviceCert.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 114d2ffd4e0d8eae833eaa594f6a17a79da909be..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/profiles/caIPAserviceCert.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-[
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "syntax": "syntaxSubject",
|
|
|
ac7d03 |
- "data": [
|
|
|
ac7d03 |
- "dataHostCN",
|
|
|
ac7d03 |
- "dataSubjectBase"
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "syntax": "syntaxSAN",
|
|
|
ac7d03 |
- "data": [
|
|
|
ac7d03 |
- "dataDNS"
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-]
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/profiles/userCert.json b/ipaclient/csrgen/profiles/userCert.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index d6cf5cfffcfadd604fc3e8283d1be15767278c7a..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/profiles/userCert.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-[
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "syntax": "syntaxSubject",
|
|
|
ac7d03 |
- "data": [
|
|
|
ac7d03 |
- "dataUsernameCN",
|
|
|
ac7d03 |
- "dataSubjectBase"
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "syntax": "syntaxSAN",
|
|
|
ac7d03 |
- "data": [
|
|
|
ac7d03 |
- "dataEmail"
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-]
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/dataDNS.json b/ipaclient/csrgen/rules/dataDNS.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 2663f114123a5a73b23f6a41c1b9b3162f157ea1..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/dataDNS.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "DNS = {{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "dns:{{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/dataEmail.json b/ipaclient/csrgen/rules/dataEmail.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 2eae9fb25e4f09d52ec5e29e2643236641c5cecd..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/dataEmail.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "email = {{subject.mail.0}}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "email:{{subject.mail.0|quote}}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "data_source": "subject.mail.0"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/dataHostCN.json b/ipaclient/csrgen/rules/dataHostCN.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 5c415bb8cf8911ad8c24820d2466beb57f0d9a82..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/dataHostCN.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/dataSubjectBase.json b/ipaclient/csrgen/rules/dataSubjectBase.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 309dfb1ed57b0dfe282386181a4c887228545c55..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/dataSubjectBase.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "{{config.ipacertificatesubjectbase.0}}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "{{config.ipacertificatesubjectbase.0|quote}}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "data_source": "config.ipacertificatesubjectbase.0"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/dataUsernameCN.json b/ipaclient/csrgen/rules/dataUsernameCN.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 37e7e0113ef3146a97383355285dc1d319029e0e..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/dataUsernameCN.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "CN={{subject.uid.0}}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "CN={{subject.uid.0|quote}}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "data_source": "subject.uid.0"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/syntaxSAN.json b/ipaclient/csrgen/rules/syntaxSAN.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 122eb12443e053490ac50a3984d02a62be61e7aa..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/syntaxSAN.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,15 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "subjectAltName = @{% call openssl.section() %}{{ datarules|join('\n') }}{% endcall %}",
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "extension": true
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "--extSAN {{ datarules|join(',') }}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/rules/syntaxSubject.json b/ipaclient/csrgen/rules/syntaxSubject.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index af6ec03d3390ba8f9fac99ed3b6c485f4c1cd64f..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/rules/syntaxSubject.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,16 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "distinguished_name = {% call openssl.section() %}{{ datarules|reverse|join('\n') }}{% endcall %}"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "-s {{ datarules|join(',') }}"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "required": true,
|
|
|
ac7d03 |
- "data_source_combinator": "and"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/templates/certutil_base.tmpl b/ipaclient/csrgen/templates/certutil_base.tmpl
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index a5556fda0e6ed854dfe67b816044b36db77d5f76..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/templates/certutil_base.tmpl
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,11 +0,0 @@
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 1 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> [<any> <certutil> <args>]"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-shift
|
|
|
ac7d03 |
-certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" {{ options|join(' ') }} "$@"
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/templates/openssl_base.tmpl b/ipaclient/csrgen/templates/openssl_base.tmpl
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 22b16862e88eb44c4176ee9c4580188f5b240854..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/templates/openssl_base.tmpl
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,35 +0,0 @@
|
|
|
ac7d03 |
-{% raw -%}
|
|
|
ac7d03 |
-{% import "openssl_macros.tmpl" as openssl -%}
|
|
|
ac7d03 |
-{%- endraw %}
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 2 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> <keyfile> <other openssl arguments>"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CONFIG="$(mktemp)"
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-KEYFILE="$2"
|
|
|
ac7d03 |
-shift; shift
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-echo \
|
|
|
ac7d03 |
-{% raw %}{% filter quote %}{% endraw -%}
|
|
|
ac7d03 |
-[ req ]
|
|
|
ac7d03 |
-prompt = no
|
|
|
ac7d03 |
-encrypt_key = no
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-{{ parameters|join('\n') }}
|
|
|
ac7d03 |
-{% raw %}{% set rendered_extensions -%}{% endraw %}
|
|
|
ac7d03 |
-{{ extensions|join('\n') }}
|
|
|
ac7d03 |
-{% raw -%}
|
|
|
ac7d03 |
-{%- endset -%}
|
|
|
ac7d03 |
-{% if rendered_extensions -%}
|
|
|
ac7d03 |
-req_extensions = {% call openssl.section() %}{{ rendered_extensions }}{% endcall %}
|
|
|
ac7d03 |
-{% endif %}
|
|
|
ac7d03 |
-{{ openssl.openssl_sections|join('\n\n') }}
|
|
|
ac7d03 |
-{% endfilter %}{%- endraw %} > "$CONFIG"
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-openssl req -new -config "$CONFIG" -out "$CSR" -key "$KEYFILE" "$@"
|
|
|
ac7d03 |
-rm "$CONFIG"
|
|
|
ac7d03 |
diff --git a/ipaclient/csrgen/templates/openssl_macros.tmpl b/ipaclient/csrgen/templates/openssl_macros.tmpl
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index d31b8fef5f2d85e1b3d5ecf425f00ec9c22ac301..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/csrgen/templates/openssl_macros.tmpl
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,29 +0,0 @@
|
|
|
ac7d03 |
-{# List containing rendered sections to be included at end #}
|
|
|
ac7d03 |
-{% set openssl_sections = [] %}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-{#
|
|
|
ac7d03 |
-List containing one entry for each section name allocated. Because of
|
|
|
ac7d03 |
-scoping rules, we need to use a list so that it can be a "per-render global"
|
|
|
ac7d03 |
-that gets updated in place. Real globals are shared by all templates with the
|
|
|
ac7d03 |
-same environment, and variables defined in the macro don't persist after the
|
|
|
ac7d03 |
-macro invocation ends.
|
|
|
ac7d03 |
-#}
|
|
|
ac7d03 |
-{% set openssl_section_num = [] %}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-{% macro section() -%}
|
|
|
ac7d03 |
-{% set name -%}
|
|
|
ac7d03 |
-sec{{ openssl_section_num|length -}}
|
|
|
ac7d03 |
-{% endset -%}
|
|
|
ac7d03 |
-{% do openssl_section_num.append('') -%}
|
|
|
ac7d03 |
-{% set contents %}{{ caller() }}{% endset -%}
|
|
|
ac7d03 |
-{% if contents -%}
|
|
|
ac7d03 |
-{% set sectiondata = formatsection(name, contents) -%}
|
|
|
ac7d03 |
-{% do openssl_sections.append(sectiondata) -%}
|
|
|
ac7d03 |
-{% endif -%}
|
|
|
ac7d03 |
-{{ name -}}
|
|
|
ac7d03 |
-{% endmacro %}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-{% macro formatsection(name, contents) -%}
|
|
|
ac7d03 |
-[ {{ name }} ]
|
|
|
ac7d03 |
-{{ contents -}}
|
|
|
ac7d03 |
-{% endmacro %}
|
|
|
ac7d03 |
diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
|
|
|
ac7d03 |
index 93cd3cef1a14925bc0795b32e97e44d69897be5c..8195e04fc43ffbd8ca6589d2652559198759d9e6 100644
|
|
|
ac7d03 |
--- a/ipaclient/plugins/cert.py
|
|
|
ac7d03 |
+++ b/ipaclient/plugins/cert.py
|
|
|
ac7d03 |
@@ -20,10 +20,6 @@
|
|
|
ac7d03 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ac7d03 |
|
|
|
ac7d03 |
import base64
|
|
|
ac7d03 |
-import subprocess
|
|
|
ac7d03 |
-from tempfile import NamedTemporaryFile as NTF
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import six
|
|
|
ac7d03 |
|
|
|
ac7d03 |
from ipaclient.frontend import MethodOverride
|
|
|
ac7d03 |
from ipalib import errors
|
|
|
ac7d03 |
@@ -33,9 +29,6 @@ from ipalib.parameters import File, Flag, Str
|
|
|
ac7d03 |
from ipalib.plugable import Registry
|
|
|
ac7d03 |
from ipalib.text import _
|
|
|
ac7d03 |
|
|
|
ac7d03 |
-if six.PY3:
|
|
|
ac7d03 |
- unicode = str
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
register = Registry()
|
|
|
ac7d03 |
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@@ -77,99 +70,12 @@ class CertRetrieveOverride(MethodOverride):
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@register(override=True, no_fail=True)
|
|
|
ac7d03 |
class cert_request(CertRetrieveOverride):
|
|
|
ac7d03 |
- takes_options = CertRetrieveOverride.takes_options + (
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'database?',
|
|
|
ac7d03 |
- label=_('Path to NSS database'),
|
|
|
ac7d03 |
- doc=_('Path to NSS database to use for private key'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'private_key?',
|
|
|
ac7d03 |
- label=_('Path to private key file'),
|
|
|
ac7d03 |
- doc=_('Path to PEM file containing a private key'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'password_file?',
|
|
|
ac7d03 |
- label=_(
|
|
|
ac7d03 |
- 'File containing a password for the private key or database'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'csr_profile_id?',
|
|
|
ac7d03 |
- label=_('Name of CSR generation profile (if not the same as'
|
|
|
ac7d03 |
- ' profile_id)'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
def get_args(self):
|
|
|
ac7d03 |
for arg in super(cert_request, self).get_args():
|
|
|
ac7d03 |
if arg.name == 'csr':
|
|
|
ac7d03 |
- arg = arg.clone_retype(arg.name, File, required=False)
|
|
|
ac7d03 |
+ arg = arg.clone_retype(arg.name, File)
|
|
|
ac7d03 |
yield arg
|
|
|
ac7d03 |
|
|
|
ac7d03 |
- def forward(self, csr=None, **options):
|
|
|
ac7d03 |
- database = options.pop('database', None)
|
|
|
ac7d03 |
- private_key = options.pop('private_key', None)
|
|
|
ac7d03 |
- csr_profile_id = options.pop('csr_profile_id', None)
|
|
|
ac7d03 |
- password_file = options.pop('password_file', None)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- if csr is None:
|
|
|
ac7d03 |
- if database:
|
|
|
ac7d03 |
- helper = u'certutil'
|
|
|
ac7d03 |
- helper_args = ['-d', database]
|
|
|
ac7d03 |
- if password_file:
|
|
|
ac7d03 |
- helper_args += ['-f', password_file]
|
|
|
ac7d03 |
- elif private_key:
|
|
|
ac7d03 |
- helper = u'openssl'
|
|
|
ac7d03 |
- helper_args = [private_key]
|
|
|
ac7d03 |
- if password_file:
|
|
|
ac7d03 |
- helper_args += ['-passin', 'file:%s' % password_file]
|
|
|
ac7d03 |
- else:
|
|
|
ac7d03 |
- raise errors.InvocationError(
|
|
|
ac7d03 |
- message=u"One of 'database' or 'private_key' is required")
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- with NTF() as scriptfile, NTF() as csrfile:
|
|
|
ac7d03 |
- # If csr_profile_id is passed, that takes precedence.
|
|
|
ac7d03 |
- # Otherwise, use profile_id. If neither are passed, the default
|
|
|
ac7d03 |
- # in cert_get_requestdata will be used.
|
|
|
ac7d03 |
- profile_id = csr_profile_id
|
|
|
ac7d03 |
- if profile_id is None:
|
|
|
ac7d03 |
- profile_id = options.get('profile_id')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- self.api.Command.cert_get_requestdata(
|
|
|
ac7d03 |
- profile_id=profile_id,
|
|
|
ac7d03 |
- principal=options.get('principal'),
|
|
|
ac7d03 |
- out=unicode(scriptfile.name),
|
|
|
ac7d03 |
- helper=helper)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- helper_cmd = [
|
|
|
ac7d03 |
- 'bash', '-e', scriptfile.name, csrfile.name] + helper_args
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- subprocess.check_output(helper_cmd)
|
|
|
ac7d03 |
- except subprocess.CalledProcessError as e:
|
|
|
ac7d03 |
- raise errors.CertificateOperationError(
|
|
|
ac7d03 |
- error=(
|
|
|
ac7d03 |
- _('Error running "%(cmd)s" to generate CSR:'
|
|
|
ac7d03 |
- ' %(err)s') %
|
|
|
ac7d03 |
- {'cmd': ' '.join(helper_cmd), 'err': e.output}))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- csr = unicode(csrfile.read())
|
|
|
ac7d03 |
- except IOError as e:
|
|
|
ac7d03 |
- raise errors.CertificateOperationError(
|
|
|
ac7d03 |
- error=(_('Unable to read generated CSR file: %(err)s')
|
|
|
ac7d03 |
- % {'err': e}))
|
|
|
ac7d03 |
- if not csr:
|
|
|
ac7d03 |
- raise errors.CertificateOperationError(
|
|
|
ac7d03 |
- error=(_('Generated CSR was empty')))
|
|
|
ac7d03 |
- else:
|
|
|
ac7d03 |
- if database is not None or private_key is not None:
|
|
|
ac7d03 |
- raise errors.MutuallyExclusiveError(reason=_(
|
|
|
ac7d03 |
- "Options 'database' and 'private_key' are not compatible"
|
|
|
ac7d03 |
- " with 'csr'"))
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return super(cert_request, self).forward(csr, **options)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@register(override=True, no_fail=True)
|
|
|
ac7d03 |
class cert_show(CertRetrieveOverride):
|
|
|
ac7d03 |
diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index a0d99ef06445de268cd1872a025d0613e245ae6c..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipaclient/plugins/csrgen.py
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,120 +0,0 @@
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import six
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-from ipaclient.csrgen import CSRGenerator, FileRuleProvider
|
|
|
ac7d03 |
-from ipalib import api
|
|
|
ac7d03 |
-from ipalib import errors
|
|
|
ac7d03 |
-from ipalib import output
|
|
|
ac7d03 |
-from ipalib import util
|
|
|
ac7d03 |
-from ipalib.frontend import Local, Str
|
|
|
ac7d03 |
-from ipalib.parameters import Principal
|
|
|
ac7d03 |
-from ipalib.plugable import Registry
|
|
|
ac7d03 |
-from ipalib.text import _
|
|
|
ac7d03 |
-from ipapython import dogtag
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if six.PY3:
|
|
|
ac7d03 |
- unicode = str
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-register = Registry()
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-__doc__ = _("""
|
|
|
ac7d03 |
-Commands to build certificate requests automatically
|
|
|
ac7d03 |
-""")
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-@register()
|
|
|
ac7d03 |
-class cert_get_requestdata(Local):
|
|
|
ac7d03 |
- __doc__ = _('Gather data for a certificate signing request.')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- NO_CLI = True
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- takes_options = (
|
|
|
ac7d03 |
- Principal(
|
|
|
ac7d03 |
- 'principal',
|
|
|
ac7d03 |
- label=_('Principal'),
|
|
|
ac7d03 |
- doc=_('Principal for this certificate (e.g.'
|
|
|
ac7d03 |
- ' HTTP/test.example.com)'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'profile_id?',
|
|
|
ac7d03 |
- label=_('Profile ID'),
|
|
|
ac7d03 |
- doc=_('CSR Generation Profile to use'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'helper',
|
|
|
ac7d03 |
- label=_('Name of CSR generation tool'),
|
|
|
ac7d03 |
- doc=_('Name of tool (e.g. openssl, certutil) that will be used to'
|
|
|
ac7d03 |
- ' create CSR'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'out?',
|
|
|
ac7d03 |
- doc=_('Write CSR generation script to file'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- has_output = (
|
|
|
ac7d03 |
- output.Output(
|
|
|
ac7d03 |
- 'result',
|
|
|
ac7d03 |
- type=dict,
|
|
|
ac7d03 |
- doc=_('Dictionary mapping variable name to value'),
|
|
|
ac7d03 |
- ),
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- has_output_params = (
|
|
|
ac7d03 |
- Str(
|
|
|
ac7d03 |
- 'script',
|
|
|
ac7d03 |
- label=_('Generation script'),
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def execute(self, *args, **options):
|
|
|
ac7d03 |
- if 'out' in options:
|
|
|
ac7d03 |
- util.check_writable_file(options['out'])
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- principal = options.get('principal')
|
|
|
ac7d03 |
- profile_id = options.get('profile_id')
|
|
|
ac7d03 |
- if profile_id is None:
|
|
|
ac7d03 |
- profile_id = dogtag.DEFAULT_PROFILE
|
|
|
ac7d03 |
- helper = options.get('helper')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- if self.api.env.in_server:
|
|
|
ac7d03 |
- backend = self.api.Backend.ldap2
|
|
|
ac7d03 |
- else:
|
|
|
ac7d03 |
- backend = self.api.Backend.rpcclient
|
|
|
ac7d03 |
- if not backend.isconnected():
|
|
|
ac7d03 |
- backend.connect()
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- try:
|
|
|
ac7d03 |
- if principal.is_host:
|
|
|
ac7d03 |
- principal_obj = api.Command.host_show(
|
|
|
ac7d03 |
- principal.hostname, all=True)
|
|
|
ac7d03 |
- elif principal.is_service:
|
|
|
ac7d03 |
- principal_obj = api.Command.service_show(
|
|
|
ac7d03 |
- unicode(principal), all=True)
|
|
|
ac7d03 |
- elif principal.is_user:
|
|
|
ac7d03 |
- principal_obj = api.Command.user_show(
|
|
|
ac7d03 |
- principal.username, all=True)
|
|
|
ac7d03 |
- except errors.NotFound:
|
|
|
ac7d03 |
- raise errors.NotFound(
|
|
|
ac7d03 |
- reason=_("The principal for this request doesn't exist."))
|
|
|
ac7d03 |
- principal_obj = principal_obj['result']
|
|
|
ac7d03 |
- config = api.Command.config_show()['result']
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- generator = CSRGenerator(FileRuleProvider())
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(
|
|
|
ac7d03 |
- principal_obj, config, profile_id, helper)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- result = {}
|
|
|
ac7d03 |
- if 'out' in options:
|
|
|
ac7d03 |
- with open(options['out'], 'wb') as f:
|
|
|
ac7d03 |
- f.write(script)
|
|
|
ac7d03 |
- else:
|
|
|
ac7d03 |
- result = dict(script=script)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- return dict(
|
|
|
ac7d03 |
- result=result
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
diff --git a/ipaclient/setup.py b/ipaclient/setup.py
|
|
|
ac7d03 |
index f5be7ea61f554f04d7bde46c84182f6148820600..e3f31d2b9c46a2668a0e9264ea0cfda06aeeaa2e 100644
|
|
|
ac7d03 |
--- a/ipaclient/setup.py
|
|
|
ac7d03 |
+++ b/ipaclient/setup.py
|
|
|
ac7d03 |
@@ -43,18 +43,10 @@ if __name__ == '__main__':
|
|
|
ac7d03 |
"ipaclient.remote_plugins.2_156",
|
|
|
ac7d03 |
"ipaclient.remote_plugins.2_164",
|
|
|
ac7d03 |
],
|
|
|
ac7d03 |
- package_data={
|
|
|
ac7d03 |
- 'ipaclient': [
|
|
|
ac7d03 |
- 'csrgen/profiles/*.json',
|
|
|
ac7d03 |
- 'csrgen/rules/*.json',
|
|
|
ac7d03 |
- 'csrgen/templates/*.tmpl',
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
install_requires=[
|
|
|
ac7d03 |
"cryptography",
|
|
|
ac7d03 |
"ipalib",
|
|
|
ac7d03 |
"ipapython",
|
|
|
ac7d03 |
- "jinja2",
|
|
|
ac7d03 |
"python-yubico",
|
|
|
ac7d03 |
"pyusb",
|
|
|
ac7d03 |
"qrcode",
|
|
|
ac7d03 |
@@ -63,6 +55,5 @@ if __name__ == '__main__':
|
|
|
ac7d03 |
extras_require={
|
|
|
ac7d03 |
"install": ["ipaplatform"],
|
|
|
ac7d03 |
"otptoken_yubikey": ["yubico", "usb"]
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- zip_safe=False,
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
)
|
|
|
ac7d03 |
diff --git a/ipalib/errors.py b/ipalib/errors.py
|
|
|
ac7d03 |
index 6aaca708a02e609f11c4aa5ef5fe2b4a8ae8a941..88707ac313fa7c5ec247b3f9b71f96925f5627e2 100644
|
|
|
ac7d03 |
--- a/ipalib/errors.py
|
|
|
ac7d03 |
+++ b/ipalib/errors.py
|
|
|
ac7d03 |
@@ -1422,34 +1422,6 @@ class HTTPRequestError(RemoteRetrieveError):
|
|
|
ac7d03 |
format = _('Request failed with status %(status)s: %(reason)s')
|
|
|
ac7d03 |
|
|
|
ac7d03 |
|
|
|
ac7d03 |
-class RedundantMappingRule(SingleMatchExpected):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- **4036** Raised when more than one rule in a CSR generation ruleset matches
|
|
|
ac7d03 |
- a particular helper.
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- For example:
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- >>> raise RedundantMappingRule(ruleset='syntaxSubject', helper='certutil')
|
|
|
ac7d03 |
- Traceback (most recent call last):
|
|
|
ac7d03 |
- ...
|
|
|
ac7d03 |
- RedundantMappingRule: Mapping ruleset "syntaxSubject" has more than one
|
|
|
ac7d03 |
- rule for the certutil helper.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- errno = 4036
|
|
|
ac7d03 |
- format = _('Mapping ruleset "%(ruleset)s" has more than one rule for the'
|
|
|
ac7d03 |
- ' %(helper)s helper')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class CSRTemplateError(ExecutionError):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- **4037** Raised when evaluation of a CSR generation template fails
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- errno = 4037
|
|
|
ac7d03 |
- format = _('%(reason)s')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
class BuiltinError(ExecutionError):
|
|
|
ac7d03 |
"""
|
|
|
ac7d03 |
**4100** Base class for builtin execution errors (*4100 - 4199*).
|
|
|
ac7d03 |
diff --git a/ipatests/setup.py b/ipatests/setup.py
|
|
|
ac7d03 |
index 46d51ff1ccdec7b2288955b8e5abdc2b971d3d17..fe65626ec7fe09701810a99a5fb8a8ede9697f46 100644
|
|
|
ac7d03 |
--- a/ipatests/setup.py
|
|
|
ac7d03 |
+++ b/ipatests/setup.py
|
|
|
ac7d03 |
@@ -38,7 +38,6 @@ if __name__ == '__main__':
|
|
|
ac7d03 |
"ipatests.test_cmdline",
|
|
|
ac7d03 |
"ipatests.test_install",
|
|
|
ac7d03 |
"ipatests.test_integration",
|
|
|
ac7d03 |
- "ipatests.test_ipaclient",
|
|
|
ac7d03 |
"ipatests.test_ipalib",
|
|
|
ac7d03 |
"ipatests.test_ipapython",
|
|
|
ac7d03 |
"ipatests.test_ipaserver",
|
|
|
ac7d03 |
@@ -52,7 +51,6 @@ if __name__ == '__main__':
|
|
|
ac7d03 |
package_data={
|
|
|
ac7d03 |
'ipatests.test_install': ['*.update'],
|
|
|
ac7d03 |
'ipatests.test_integration': ['scripts/*'],
|
|
|
ac7d03 |
- 'ipatests.test_ipaclient': ['data/*/*/*'],
|
|
|
ac7d03 |
'ipatests.test_ipalib': ['data/*'],
|
|
|
ac7d03 |
'ipatests.test_pkcs10': ['*.csr'],
|
|
|
ac7d03 |
"ipatests.test_ipaserver": ['data/*'],
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/__init__.py b/ipatests/test_ipaclient/__init__.py
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 0c428910cabe103af3ac9bfe4cdde6678acd1585..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/__init__.py
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,7 +0,0 @@
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-"""
|
|
|
ac7d03 |
-Sub-package containing unit tests for `ipaclient` package.
|
|
|
ac7d03 |
-"""
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/profiles/profile.json b/ipatests/test_ipaclient/data/test_csrgen/profiles/profile.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 676f91bef696109976826e6e61be091718172798..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/profiles/profile.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,8 +0,0 @@
|
|
|
ac7d03 |
-[
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "syntax": "basic",
|
|
|
ac7d03 |
- "data": [
|
|
|
ac7d03 |
- "options"
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-]
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/rules/basic.json b/ipatests/test_ipaclient/data/test_csrgen/rules/basic.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index feba3e91e53c5c9becb44c0d2190b5a98c04a928..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/rules/basic.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,12 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "openssl_rule"
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "certutil_rule"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ]
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/rules/options.json b/ipatests/test_ipaclient/data/test_csrgen/rules/options.json
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 111a6d80c8faf27376dac342a18aede1fb1242ef..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/rules/options.json
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,18 +0,0 @@
|
|
|
ac7d03 |
-{
|
|
|
ac7d03 |
- "rules": [
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "openssl",
|
|
|
ac7d03 |
- "template": "openssl_rule",
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "helper_option": true
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- },
|
|
|
ac7d03 |
- {
|
|
|
ac7d03 |
- "helper": "certutil",
|
|
|
ac7d03 |
- "template": "certutil_rule"
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- "options": {
|
|
|
ac7d03 |
- "global_option": true
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-}
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_certutil.sh b/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_certutil.sh
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 74a704c2dd1765c7b775fded8ed957715b264b91..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_certutil.sh
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,11 +0,0 @@
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 1 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> [<any> <certutil> <args>]"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-shift
|
|
|
ac7d03 |
-certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" -s CN=machine.example.com,O=DOMAIN.EXAMPLE.COM --extSAN dns:machine.example.com "$@"
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_openssl.sh b/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_openssl.sh
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 811bfd763e27678adaf681a430e909b24680aeda..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_openssl.sh
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,34 +0,0 @@
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 2 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> <keyfile> <other openssl arguments>"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CONFIG="$(mktemp)"
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-KEYFILE="$2"
|
|
|
ac7d03 |
-shift; shift
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-echo \
|
|
|
ac7d03 |
-'[ req ]
|
|
|
ac7d03 |
-prompt = no
|
|
|
ac7d03 |
-encrypt_key = no
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-distinguished_name = sec0
|
|
|
ac7d03 |
-req_extensions = sec2
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec0 ]
|
|
|
ac7d03 |
-O=DOMAIN.EXAMPLE.COM
|
|
|
ac7d03 |
-CN=machine.example.com
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec1 ]
|
|
|
ac7d03 |
-DNS = machine.example.com
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec2 ]
|
|
|
ac7d03 |
-subjectAltName = @sec1
|
|
|
ac7d03 |
-' > "$CONFIG"
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-openssl req -new -config "$CONFIG" -out "$CSR" -key "$KEYFILE" "$@"
|
|
|
ac7d03 |
-rm "$CONFIG"
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_certutil.sh b/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_certutil.sh
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 4aaeda07aabd4c36d277e339d0b761f7a8a54baf..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_certutil.sh
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,11 +0,0 @@
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 1 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> [<any> <certutil> <args>]"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-shift
|
|
|
ac7d03 |
-certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" -s CN=testuser,O=DOMAIN.EXAMPLE.COM --extSAN email:testuser@example.com "$@"
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_openssl.sh b/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_openssl.sh
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 2edf067a528456877025f63dca76d68e7edde41e..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_openssl.sh
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,34 +0,0 @@
|
|
|
ac7d03 |
-#!/bin/bash -e
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-if [[ $# -lt 2 ]]; then
|
|
|
ac7d03 |
-echo "Usage: $0 <outfile> <keyfile> <other openssl arguments>"
|
|
|
ac7d03 |
-echo "Called as: $0 $@"
|
|
|
ac7d03 |
-exit 1
|
|
|
ac7d03 |
-fi
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-CONFIG="$(mktemp)"
|
|
|
ac7d03 |
-CSR="$1"
|
|
|
ac7d03 |
-KEYFILE="$2"
|
|
|
ac7d03 |
-shift; shift
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-echo \
|
|
|
ac7d03 |
-'[ req ]
|
|
|
ac7d03 |
-prompt = no
|
|
|
ac7d03 |
-encrypt_key = no
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-distinguished_name = sec0
|
|
|
ac7d03 |
-req_extensions = sec2
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec0 ]
|
|
|
ac7d03 |
-O=DOMAIN.EXAMPLE.COM
|
|
|
ac7d03 |
-CN=testuser
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec1 ]
|
|
|
ac7d03 |
-email = testuser@example.com
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-[ sec2 ]
|
|
|
ac7d03 |
-subjectAltName = @sec1
|
|
|
ac7d03 |
-' > "$CONFIG"
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-openssl req -new -config "$CONFIG" -out "$CSR" -key "$KEYFILE" "$@"
|
|
|
ac7d03 |
-rm "$CONFIG"
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/data/test_csrgen/templates/identity_base.tmpl b/ipatests/test_ipaclient/data/test_csrgen/templates/identity_base.tmpl
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 79111ab686b4fe25227796509b3cd3fcb54af728..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/data/test_csrgen/templates/identity_base.tmpl
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1 +0,0 @@
|
|
|
ac7d03 |
-{{ options|join(";") }}
|
|
|
ac7d03 |
diff --git a/ipatests/test_ipaclient/test_csrgen.py b/ipatests/test_ipaclient/test_csrgen.py
|
|
|
ac7d03 |
deleted file mode 100644
|
|
|
ac7d03 |
index 556f8e096976387d24057084c06d53bcb9998a69..0000000000000000000000000000000000000000
|
|
|
ac7d03 |
--- a/ipatests/test_ipaclient/test_csrgen.py
|
|
|
ac7d03 |
+++ /dev/null
|
|
|
ac7d03 |
@@ -1,298 +0,0 @@
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
|
|
ac7d03 |
-#
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-import os
|
|
|
ac7d03 |
-import pytest
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-from ipaclient import csrgen
|
|
|
ac7d03 |
-from ipalib import errors
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-BASE_DIR = os.path.dirname(__file__)
|
|
|
ac7d03 |
-CSR_DATA_DIR = os.path.join(BASE_DIR, 'data', 'test_csrgen')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-@pytest.fixture
|
|
|
ac7d03 |
-def formatter():
|
|
|
ac7d03 |
- return csrgen.Formatter(csr_data_dir=CSR_DATA_DIR)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-@pytest.fixture
|
|
|
ac7d03 |
-def rule_provider():
|
|
|
ac7d03 |
- return csrgen.FileRuleProvider(csr_data_dir=CSR_DATA_DIR)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-@pytest.fixture
|
|
|
ac7d03 |
-def generator():
|
|
|
ac7d03 |
- return csrgen.CSRGenerator(csrgen.FileRuleProvider())
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class StubRuleProvider(csrgen.RuleProvider):
|
|
|
ac7d03 |
- def __init__(self):
|
|
|
ac7d03 |
- self.syntax_rule = csrgen.Rule(
|
|
|
ac7d03 |
- 'syntax', '{{datarules|join(",")}}', {})
|
|
|
ac7d03 |
- self.data_rule = csrgen.Rule('data', 'data_template', {})
|
|
|
ac7d03 |
- self.field_mapping = csrgen.FieldMapping(
|
|
|
ac7d03 |
- 'example', self.syntax_rule, [self.data_rule])
|
|
|
ac7d03 |
- self.rules = [self.field_mapping]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def rules_for_profile(self, profile_id, helper):
|
|
|
ac7d03 |
- return self.rules
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class IdentityFormatter(csrgen.Formatter):
|
|
|
ac7d03 |
- base_template_name = 'identity_base.tmpl'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def __init__(self):
|
|
|
ac7d03 |
- super(IdentityFormatter, self).__init__(csr_data_dir=CSR_DATA_DIR)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def _get_template_params(self, syntax_rules):
|
|
|
ac7d03 |
- return {'options': syntax_rules}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class IdentityCSRGenerator(csrgen.CSRGenerator):
|
|
|
ac7d03 |
- FORMATTERS = {'identity': IdentityFormatter}
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class test_Formatter(object):
|
|
|
ac7d03 |
- def test_prepare_data_rule_with_data_source(self, formatter):
|
|
|
ac7d03 |
- data_rule = csrgen.Rule('uid', '{{subject.uid.0}}',
|
|
|
ac7d03 |
- {'data_source': 'subject.uid.0'})
|
|
|
ac7d03 |
- prepared = formatter._prepare_data_rule(data_rule)
|
|
|
ac7d03 |
- assert prepared == '{% if subject.uid.0 %}{{subject.uid.0}}{% endif %}'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_data_rule_no_data_source(self, formatter):
|
|
|
ac7d03 |
- """Not a normal case, but we should handle it anyway"""
|
|
|
ac7d03 |
- data_rule = csrgen.Rule('uid', 'static_text', {})
|
|
|
ac7d03 |
- prepared = formatter._prepare_data_rule(data_rule)
|
|
|
ac7d03 |
- assert prepared == 'static_text'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_syntax_rule_with_data_sources(self, formatter):
|
|
|
ac7d03 |
- syntax_rule = csrgen.Rule(
|
|
|
ac7d03 |
- 'example', '{{datarules|join(",")}}', {})
|
|
|
ac7d03 |
- data_rules = ['{{subject.field1}}', '{{subject.field2}}']
|
|
|
ac7d03 |
- data_sources = ['subject.field1', 'subject.field2']
|
|
|
ac7d03 |
- prepared = formatter._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, 'example', data_sources)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert prepared == (
|
|
|
ac7d03 |
- '{% if subject.field1 or subject.field2 %}{{subject.field1}},'
|
|
|
ac7d03 |
- '{{subject.field2}}{% endif %}')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_syntax_rule_with_combinator(self, formatter):
|
|
|
ac7d03 |
- syntax_rule = csrgen.Rule('example', '{{datarules|join(",")}}',
|
|
|
ac7d03 |
- {'data_source_combinator': 'and'})
|
|
|
ac7d03 |
- data_rules = ['{{subject.field1}}', '{{subject.field2}}']
|
|
|
ac7d03 |
- data_sources = ['subject.field1', 'subject.field2']
|
|
|
ac7d03 |
- prepared = formatter._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, 'example', data_sources)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert prepared == (
|
|
|
ac7d03 |
- '{% if subject.field1 and subject.field2 %}{{subject.field1}},'
|
|
|
ac7d03 |
- '{{subject.field2}}{% endif %}')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_syntax_rule_required(self, formatter):
|
|
|
ac7d03 |
- syntax_rule = csrgen.Rule('example', '{{datarules|join(",")}}',
|
|
|
ac7d03 |
- {'required': True})
|
|
|
ac7d03 |
- data_rules = ['{{subject.field1}}']
|
|
|
ac7d03 |
- data_sources = ['subject.field1']
|
|
|
ac7d03 |
- prepared = formatter._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, 'example', data_sources)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert prepared == (
|
|
|
ac7d03 |
- '{% filter required("example") %}{% if subject.field1 %}'
|
|
|
ac7d03 |
- '{{subject.field1}}{% endif %}{% endfilter %}')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_syntax_rule_passthrough(self, formatter):
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- Calls to macros defined as passthrough are still call tags in the final
|
|
|
ac7d03 |
- template.
|
|
|
ac7d03 |
- """
|
|
|
ac7d03 |
- formatter._define_passthrough('example.macro')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- syntax_rule = csrgen.Rule(
|
|
|
ac7d03 |
- 'example',
|
|
|
ac7d03 |
- '{% call example.macro() %}{{datarules|join(",")}}{% endcall %}',
|
|
|
ac7d03 |
- {})
|
|
|
ac7d03 |
- data_rules = ['{{subject.field1}}']
|
|
|
ac7d03 |
- data_sources = ['subject.field1']
|
|
|
ac7d03 |
- prepared = formatter._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, 'example', data_sources)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert prepared == (
|
|
|
ac7d03 |
- '{% if subject.field1 %}{% call example.macro() %}'
|
|
|
ac7d03 |
- '{{subject.field1}}{% endcall %}{% endif %}')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_prepare_syntax_rule_no_data_sources(self, formatter):
|
|
|
ac7d03 |
- """Not a normal case, but we should handle it anyway"""
|
|
|
ac7d03 |
- syntax_rule = csrgen.Rule(
|
|
|
ac7d03 |
- 'example', '{{datarules|join(",")}}', {})
|
|
|
ac7d03 |
- data_rules = ['rule1', 'rule2']
|
|
|
ac7d03 |
- data_sources = []
|
|
|
ac7d03 |
- prepared = formatter._prepare_syntax_rule(
|
|
|
ac7d03 |
- syntax_rule, data_rules, 'example', data_sources)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert prepared == 'rule1,rule2'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class test_FileRuleProvider(object):
|
|
|
ac7d03 |
- def test_rule_basic(self, rule_provider):
|
|
|
ac7d03 |
- rule_name = 'basic'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- rule1 = rule_provider._rule(rule_name, 'openssl')
|
|
|
ac7d03 |
- rule2 = rule_provider._rule(rule_name, 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert rule1.template == 'openssl_rule'
|
|
|
ac7d03 |
- assert rule2.template == 'certutil_rule'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rule_global_options(self, rule_provider):
|
|
|
ac7d03 |
- rule_name = 'options'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- rule1 = rule_provider._rule(rule_name, 'openssl')
|
|
|
ac7d03 |
- rule2 = rule_provider._rule(rule_name, 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert rule1.options['global_option'] is True
|
|
|
ac7d03 |
- assert rule2.options['global_option'] is True
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rule_helper_options(self, rule_provider):
|
|
|
ac7d03 |
- rule_name = 'options'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- rule1 = rule_provider._rule(rule_name, 'openssl')
|
|
|
ac7d03 |
- rule2 = rule_provider._rule(rule_name, 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert rule1.options['helper_option'] is True
|
|
|
ac7d03 |
- assert 'helper_option' not in rule2.options
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rule_nosuchrule(self, rule_provider):
|
|
|
ac7d03 |
- with pytest.raises(errors.NotFound):
|
|
|
ac7d03 |
- rule_provider._rule('nosuchrule', 'openssl')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rule_nosuchhelper(self, rule_provider):
|
|
|
ac7d03 |
- with pytest.raises(errors.EmptyResult):
|
|
|
ac7d03 |
- rule_provider._rule('basic', 'nosuchhelper')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rules_for_profile_success(self, rule_provider):
|
|
|
ac7d03 |
- rules = rule_provider.rules_for_profile('profile', 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- assert len(rules) == 1
|
|
|
ac7d03 |
- field_mapping = rules[0]
|
|
|
ac7d03 |
- assert field_mapping.syntax_rule.name == 'basic'
|
|
|
ac7d03 |
- assert len(field_mapping.data_rules) == 1
|
|
|
ac7d03 |
- assert field_mapping.data_rules[0].name == 'options'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_rules_for_profile_nosuchprofile(self, rule_provider):
|
|
|
ac7d03 |
- with pytest.raises(errors.NotFound):
|
|
|
ac7d03 |
- rule_provider.rules_for_profile('nosuchprofile', 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class test_CSRGenerator(object):
|
|
|
ac7d03 |
- def test_userCert_OpenSSL(self, generator):
|
|
|
ac7d03 |
- principal = {
|
|
|
ac7d03 |
- 'uid': ['testuser'],
|
|
|
ac7d03 |
- 'mail': ['testuser@example.com'],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- config = {
|
|
|
ac7d03 |
- 'ipacertificatesubjectbase': [
|
|
|
ac7d03 |
- 'O=DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(principal, config, 'userCert', 'openssl')
|
|
|
ac7d03 |
- with open(os.path.join(
|
|
|
ac7d03 |
- CSR_DATA_DIR, 'scripts', 'userCert_openssl.sh')) as f:
|
|
|
ac7d03 |
- expected_script = f.read()
|
|
|
ac7d03 |
- assert script == expected_script
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_userCert_Certutil(self, generator):
|
|
|
ac7d03 |
- principal = {
|
|
|
ac7d03 |
- 'uid': ['testuser'],
|
|
|
ac7d03 |
- 'mail': ['testuser@example.com'],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- config = {
|
|
|
ac7d03 |
- 'ipacertificatesubjectbase': [
|
|
|
ac7d03 |
- 'O=DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(
|
|
|
ac7d03 |
- principal, config, 'userCert', 'certutil')
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- with open(os.path.join(
|
|
|
ac7d03 |
- CSR_DATA_DIR, 'scripts', 'userCert_certutil.sh')) as f:
|
|
|
ac7d03 |
- expected_script = f.read()
|
|
|
ac7d03 |
- assert script == expected_script
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_caIPAserviceCert_OpenSSL(self, generator):
|
|
|
ac7d03 |
- principal = {
|
|
|
ac7d03 |
- 'krbprincipalname': [
|
|
|
ac7d03 |
- 'HTTP/machine.example.com@DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- config = {
|
|
|
ac7d03 |
- 'ipacertificatesubjectbase': [
|
|
|
ac7d03 |
- 'O=DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(
|
|
|
ac7d03 |
- principal, config, 'caIPAserviceCert', 'openssl')
|
|
|
ac7d03 |
- with open(os.path.join(
|
|
|
ac7d03 |
- CSR_DATA_DIR, 'scripts', 'caIPAserviceCert_openssl.sh')) as f:
|
|
|
ac7d03 |
- expected_script = f.read()
|
|
|
ac7d03 |
- assert script == expected_script
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_caIPAserviceCert_Certutil(self, generator):
|
|
|
ac7d03 |
- principal = {
|
|
|
ac7d03 |
- 'krbprincipalname': [
|
|
|
ac7d03 |
- 'HTTP/machine.example.com@DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
- config = {
|
|
|
ac7d03 |
- 'ipacertificatesubjectbase': [
|
|
|
ac7d03 |
- 'O=DOMAIN.EXAMPLE.COM'
|
|
|
ac7d03 |
- ],
|
|
|
ac7d03 |
- }
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(
|
|
|
ac7d03 |
- principal, config, 'caIPAserviceCert', 'certutil')
|
|
|
ac7d03 |
- with open(os.path.join(
|
|
|
ac7d03 |
- CSR_DATA_DIR, 'scripts', 'caIPAserviceCert_certutil.sh')) as f:
|
|
|
ac7d03 |
- expected_script = f.read()
|
|
|
ac7d03 |
- assert script == expected_script
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
-class test_rule_handling(object):
|
|
|
ac7d03 |
- def test_optionalAttributeMissing(self, generator):
|
|
|
ac7d03 |
- principal = {'uid': 'testuser'}
|
|
|
ac7d03 |
- rule_provider = StubRuleProvider()
|
|
|
ac7d03 |
- rule_provider.data_rule.template = '{{subject.mail}}'
|
|
|
ac7d03 |
- rule_provider.data_rule.options = {'data_source': 'subject.mail'}
|
|
|
ac7d03 |
- generator = IdentityCSRGenerator(rule_provider)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(
|
|
|
ac7d03 |
- principal, {}, 'example', 'identity')
|
|
|
ac7d03 |
- assert script == '\n'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_twoDataRulesOneMissing(self, generator):
|
|
|
ac7d03 |
- principal = {'uid': 'testuser'}
|
|
|
ac7d03 |
- rule_provider = StubRuleProvider()
|
|
|
ac7d03 |
- rule_provider.data_rule.template = '{{subject.mail}}'
|
|
|
ac7d03 |
- rule_provider.data_rule.options = {'data_source': 'subject.mail'}
|
|
|
ac7d03 |
- rule_provider.field_mapping.data_rules.append(csrgen.Rule(
|
|
|
ac7d03 |
- 'data2', '{{subject.uid}}', {'data_source': 'subject.uid'}))
|
|
|
ac7d03 |
- generator = IdentityCSRGenerator(rule_provider)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- script = generator.csr_script(principal, {}, 'example', 'identity')
|
|
|
ac7d03 |
- assert script == ',testuser\n'
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- def test_requiredAttributeMissing(self):
|
|
|
ac7d03 |
- principal = {'uid': 'testuser'}
|
|
|
ac7d03 |
- rule_provider = StubRuleProvider()
|
|
|
ac7d03 |
- rule_provider.data_rule.template = '{{subject.mail}}'
|
|
|
ac7d03 |
- rule_provider.data_rule.options = {'data_source': 'subject.mail'}
|
|
|
ac7d03 |
- rule_provider.syntax_rule.options = {'required': True}
|
|
|
ac7d03 |
- generator = IdentityCSRGenerator(rule_provider)
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- with pytest.raises(errors.CSRTemplateError):
|
|
|
ac7d03 |
- _script = generator.csr_script(
|
|
|
ac7d03 |
- principal, {}, 'example', 'identity')
|
|
|
ac7d03 |
--
|
|
|
460745 |
2.13.5
|
|
|
ac7d03 |
|