URL: https://github.com/freeipa/freeipa/pull/534
Author: tiran
 Title: #534: Move csrgen templates into ipaclient package
Action: opened

PR body:
"""
csrgen broke packaging of ipaclient for PyPI. All csrgen related
resources are now package data of ipaclient package. Package data is
accessed with Jinja's PackageLoader() or through pkg_resources.

https://pagure.io/freeipa/issue/6714

Signed-off-by: Christian Heimes <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/534/head:pr534
git checkout pr534
From 779b561839a659371c5d18dbd1f18e3a016ec730 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Thu, 2 Mar 2017 16:09:53 +0100
Subject: [PATCH] Move csrgen templates into ipaclient package

csrgen broke packaging of ipaclient for PyPI. All csrgen related
resources are now package data of ipaclient package. Package data is
accessed with Jinja's PackageLoader() or through pkg_resources.

https://pagure.io/freeipa/issue/6714

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 configure.ac                                       |  1 -
 install/share/Makefile.am                          |  1 -
 install/share/csrgen/Makefile.am                   | 35 ----------------------
 .../share/csrgen/profiles/caIPAserviceCert.json    | 15 ----------
 install/share/csrgen/profiles/userCert.json        | 15 ----------
 install/share/csrgen/rules/dataDNS.json            | 15 ----------
 install/share/csrgen/rules/dataEmail.json          | 15 ----------
 install/share/csrgen/rules/dataHostCN.json         | 15 ----------
 install/share/csrgen/rules/dataSubjectBase.json    | 15 ----------
 install/share/csrgen/rules/dataUsernameCN.json     | 15 ----------
 install/share/csrgen/rules/syntaxSAN.json          | 15 ----------
 install/share/csrgen/rules/syntaxSubject.json      | 16 ----------
 install/share/csrgen/templates/certutil_base.tmpl  | 11 -------
 install/share/csrgen/templates/openssl_base.tmpl   | 35 ----------------------
 install/share/csrgen/templates/openssl_macros.tmpl | 29 ------------------
 ipaclient/csrgen.py                                | 21 +++++++++----
 ipaclient/csrgen/profiles/caIPAserviceCert.json    | 15 ++++++++++
 ipaclient/csrgen/profiles/userCert.json            | 15 ++++++++++
 ipaclient/csrgen/rules/dataDNS.json                | 15 ++++++++++
 ipaclient/csrgen/rules/dataEmail.json              | 15 ++++++++++
 ipaclient/csrgen/rules/dataHostCN.json             | 15 ++++++++++
 ipaclient/csrgen/rules/dataSubjectBase.json        | 15 ++++++++++
 ipaclient/csrgen/rules/dataUsernameCN.json         | 15 ++++++++++
 ipaclient/csrgen/rules/syntaxSAN.json              | 15 ++++++++++
 ipaclient/csrgen/rules/syntaxSubject.json          | 16 ++++++++++
 ipaclient/csrgen/templates/certutil_base.tmpl      | 11 +++++++
 ipaclient/csrgen/templates/openssl_base.tmpl       | 35 ++++++++++++++++++++++
 ipaclient/csrgen/templates/openssl_macros.tmpl     | 29 ++++++++++++++++++
 ipaclient/setup.py                                 | 10 ++++++-
 ipaplatform/base/paths.py                          |  1 -
 30 files changed, 235 insertions(+), 256 deletions(-)
 delete mode 100644 install/share/csrgen/Makefile.am
 delete mode 100644 install/share/csrgen/profiles/caIPAserviceCert.json
 delete mode 100644 install/share/csrgen/profiles/userCert.json
 delete mode 100644 install/share/csrgen/rules/dataDNS.json
 delete mode 100644 install/share/csrgen/rules/dataEmail.json
 delete mode 100644 install/share/csrgen/rules/dataHostCN.json
 delete mode 100644 install/share/csrgen/rules/dataSubjectBase.json
 delete mode 100644 install/share/csrgen/rules/dataUsernameCN.json
 delete mode 100644 install/share/csrgen/rules/syntaxSAN.json
 delete mode 100644 install/share/csrgen/rules/syntaxSubject.json
 delete mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 delete mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 delete mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen/profiles/caIPAserviceCert.json
 create mode 100644 ipaclient/csrgen/profiles/userCert.json
 create mode 100644 ipaclient/csrgen/rules/dataDNS.json
 create mode 100644 ipaclient/csrgen/rules/dataEmail.json
 create mode 100644 ipaclient/csrgen/rules/dataHostCN.json
 create mode 100644 ipaclient/csrgen/rules/dataSubjectBase.json
 create mode 100644 ipaclient/csrgen/rules/dataUsernameCN.json
 create mode 100644 ipaclient/csrgen/rules/syntaxSAN.json
 create mode 100644 ipaclient/csrgen/rules/syntaxSubject.json
 create mode 100644 ipaclient/csrgen/templates/certutil_base.tmpl
 create mode 100644 ipaclient/csrgen/templates/openssl_base.tmpl
 create mode 100644 ipaclient/csrgen/templates/openssl_macros.tmpl

diff --git a/configure.ac b/configure.ac
index 31bfa8a..4a3ba15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -463,7 +463,6 @@ AC_CONFIG_FILES([
     install/share/Makefile
     install/share/advise/Makefile
     install/share/advise/legacy/Makefile
-    install/share/csrgen/Makefile
     install/share/profiles/Makefile
     install/share/schema.d/Makefile
     install/ui/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index bbf6ce1..1e8f0d5 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,7 +2,6 @@ NULL =
 
 SUBDIRS =  				\
 	advise				\
-	csrgen				\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
deleted file mode 100644
index 12c62c4..0000000
--- a/install/share/csrgen/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-NULL =
-
-profiledir = $(IPA_DATA_DIR)/csrgen/profiles
-profile_DATA =				\
-	profiles/caIPAserviceCert.json	\
-	profiles/userCert.json		\
-	$(NULL)
-
-ruledir = $(IPA_DATA_DIR)/csrgen/rules
-rule_DATA =				\
-	rules/dataDNS.json		\
-	rules/dataEmail.json		\
-	rules/dataHostCN.json		\
-	rules/dataUsernameCN.json	\
-	rules/dataSubjectBase.json	\
-	rules/syntaxSAN.json		\
-	rules/syntaxSubject.json	\
-	$(NULL)
-
-templatedir = $(IPA_DATA_DIR)/csrgen/templates
-template_DATA =			\
-	templates/certutil_base.tmpl	\
-	templates/openssl_base.tmpl	\
-	templates/openssl_macros.tmpl	\
-	$(NULL)
-
-EXTRA_DIST =				\
-	$(profile_DATA)			\
-	$(rule_DATA)			\
-	$(template_DATA)		\
-	$(NULL)
-
-MAINTAINERCLEANFILES =			\
-	*~				\
-	Makefile.in
diff --git a/install/share/csrgen/profiles/caIPAserviceCert.json b/install/share/csrgen/profiles/caIPAserviceCert.json
deleted file mode 100644
index 114d2ff..0000000
--- a/install/share/csrgen/profiles/caIPAserviceCert.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-    {
-        "syntax": "syntaxSubject",
-        "data": [
-            "dataHostCN",
-            "dataSubjectBase"
-        ]
-    },
-    {
-        "syntax": "syntaxSAN",
-        "data": [
-            "dataDNS"
-        ]
-    }
-]
diff --git a/install/share/csrgen/profiles/userCert.json b/install/share/csrgen/profiles/userCert.json
deleted file mode 100644
index d6cf5cf..0000000
--- a/install/share/csrgen/profiles/userCert.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-    {
-        "syntax": "syntaxSubject",
-        "data": [
-            "dataUsernameCN",
-            "dataSubjectBase"
-        ]
-    },
-    {
-        "syntax": "syntaxSAN",
-        "data": [
-            "dataEmail"
-        ]
-    }
-]
diff --git a/install/share/csrgen/rules/dataDNS.json b/install/share/csrgen/rules/dataDNS.json
deleted file mode 100644
index 2663f11..0000000
--- a/install/share/csrgen/rules/dataDNS.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "DNS = {{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
-    },
-    {
-      "helper": "certutil",
-      "template": "dns:{{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
-    }
-  ],
-  "options": {
-    "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
-  }
-}
diff --git a/install/share/csrgen/rules/dataEmail.json b/install/share/csrgen/rules/dataEmail.json
deleted file mode 100644
index 2eae9fb..0000000
--- a/install/share/csrgen/rules/dataEmail.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "email = {{subject.mail.0}}"
-    },
-    {
-      "helper": "certutil",
-      "template": "email:{{subject.mail.0|quote}}"
-    }
-  ],
-  "options": {
-    "data_source": "subject.mail.0"
-  }
-}
diff --git a/install/share/csrgen/rules/dataHostCN.json b/install/share/csrgen/rules/dataHostCN.json
deleted file mode 100644
index 5c415bb..0000000
--- a/install/share/csrgen/rules/dataHostCN.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
-    },
-    {
-      "helper": "certutil",
-      "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
-    }
-  ],
-  "options": {
-    "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
-  }
-}
diff --git a/install/share/csrgen/rules/dataSubjectBase.json b/install/share/csrgen/rules/dataSubjectBase.json
deleted file mode 100644
index 309dfb1..0000000
--- a/install/share/csrgen/rules/dataSubjectBase.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "{{config.ipacertificatesubjectbase.0}}"
-    },
-    {
-      "helper": "certutil",
-      "template": "{{config.ipacertificatesubjectbase.0|quote}}"
-    }
-  ],
-  "options": {
-    "data_source": "config.ipacertificatesubjectbase.0"
-  }
-}
diff --git a/install/share/csrgen/rules/dataUsernameCN.json b/install/share/csrgen/rules/dataUsernameCN.json
deleted file mode 100644
index 37e7e01..0000000
--- a/install/share/csrgen/rules/dataUsernameCN.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "CN={{subject.uid.0}}"
-    },
-    {
-      "helper": "certutil",
-      "template": "CN={{subject.uid.0|quote}}"
-    }
-  ],
-  "options": {
-    "data_source": "subject.uid.0"
-  }
-}
diff --git a/install/share/csrgen/rules/syntaxSAN.json b/install/share/csrgen/rules/syntaxSAN.json
deleted file mode 100644
index 122eb12..0000000
--- a/install/share/csrgen/rules/syntaxSAN.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "subjectAltName = @{% call openssl.section() %}{{ datarules|join('\n') }}{% endcall %}",
-      "options": {
-        "extension": true
-      }
-    },
-    {
-      "helper": "certutil",
-      "template": "--extSAN {{ datarules|join(',') }}"
-    }
-  ]
-}
diff --git a/install/share/csrgen/rules/syntaxSubject.json b/install/share/csrgen/rules/syntaxSubject.json
deleted file mode 100644
index af6ec03..0000000
--- a/install/share/csrgen/rules/syntaxSubject.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "rules": [
-    {
-      "helper": "openssl",
-      "template": "distinguished_name = {% call openssl.section() %}{{ datarules|reverse|join('\n') }}{% endcall %}"
-    },
-    {
-      "helper": "certutil",
-      "template": "-s {{ datarules|join(',') }}"
-    }
-  ],
-  "options": {
-    "required": true,
-    "data_source_combinator": "and"
-  }
-}
diff --git a/install/share/csrgen/templates/certutil_base.tmpl b/install/share/csrgen/templates/certutil_base.tmpl
deleted file mode 100644
index a5556fd..0000000
--- a/install/share/csrgen/templates/certutil_base.tmpl
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash -e
-
-if [[ $# -lt 1 ]]; then
-echo "Usage: $0 <outfile> [<any> <certutil> <args>]"
-echo "Called as: $0 $@"
-exit 1
-fi
-
-CSR="$1"
-shift
-certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" {{ options|join(' ') }} "$@"
diff --git a/install/share/csrgen/templates/openssl_base.tmpl b/install/share/csrgen/templates/openssl_base.tmpl
deleted file mode 100644
index 22b1686..0000000
--- a/install/share/csrgen/templates/openssl_base.tmpl
+++ /dev/null
@@ -1,35 +0,0 @@
-{% raw -%}
-{% import "openssl_macros.tmpl" as openssl -%}
-{%- endraw %}
-#!/bin/bash -e
-
-if [[ $# -lt 2 ]]; then
-echo "Usage: $0 <outfile> <keyfile> <other openssl arguments>"
-echo "Called as: $0 $@"
-exit 1
-fi
-
-CONFIG="$(mktemp)"
-CSR="$1"
-KEYFILE="$2"
-shift; shift
-
-echo \
-{% raw %}{% filter quote %}{% endraw -%}
-[ req ]
-prompt = no
-encrypt_key = no
-
-{{ parameters|join('\n') }}
-{% raw %}{% set rendered_extensions -%}{% endraw %}
-{{ extensions|join('\n') }}
-{% raw -%}
-{%- endset -%}
-{% if rendered_extensions -%}
-req_extensions = {% call openssl.section() %}{{ rendered_extensions }}{% endcall %}
-{% endif %}
-{{ openssl.openssl_sections|join('\n\n') }}
-{% endfilter %}{%- endraw %} > "$CONFIG"
-
-openssl req -new -config "$CONFIG" -out "$CSR" -key "$KEYFILE" "$@"
-rm "$CONFIG"
diff --git a/install/share/csrgen/templates/openssl_macros.tmpl b/install/share/csrgen/templates/openssl_macros.tmpl
deleted file mode 100644
index d31b8fe..0000000
--- a/install/share/csrgen/templates/openssl_macros.tmpl
+++ /dev/null
@@ -1,29 +0,0 @@
-{# List containing rendered sections to be included at end #}
-{% set openssl_sections = [] %}
-
-{#
-List containing one entry for each section name allocated. Because of
-scoping rules, we need to use a list so that it can be a "per-render global"
-that gets updated in place. Real globals are shared by all templates with the
-same environment, and variables defined in the macro don't persist after the
-macro invocation ends.
-#}
-{% set openssl_section_num = [] %}
-
-{% macro section() -%}
-{% set name -%}
-sec{{ openssl_section_num|length -}}
-{% endset -%}
-{% do openssl_section_num.append('') -%}
-{% set contents %}{{ caller() }}{% endset -%}
-{% if contents -%}
-{% set sectiondata = formatsection(name, contents) -%}
-{% do openssl_sections.append(sectiondata) -%}
-{% endif -%}
-{{ name -}}
-{% endmacro %}
-
-{% macro formatsection(name, contents) -%}
-[ {{ name }} ]
-{{ contents -}}
-{% endmacro %}
diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 96100ae..8c41e39 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -8,6 +8,8 @@
 import pipes
 import traceback
 
+import pkg_resources
+
 import jinja2
 import jinja2.ext
 import jinja2.sandbox
@@ -15,7 +17,6 @@
 
 from ipalib import errors
 from ipalib.text import _
-from ipaplatform.paths import paths
 from ipapython.ipa_log_manager import log_mgr
 
 if six.PY3:
@@ -72,10 +73,14 @@ class Formatter(object):
     """
     base_template_name = None
 
-    def __init__(self, csr_data_dir=paths.CSR_DATA_DIR):
+    def __init__(self, csr_data_dir=None):
+        if csr_data_dir is not None:
+            loader = jinja2.FileSystemLoader(
+                os.path.join(csr_data_dir, 'templates'))
+        else:
+            loader = jinja2.PackageLoader('ipaclient', 'csrgen/templates')
         self.jinja2 = jinja2.sandbox.SandboxedEnvironment(
-            loader=jinja2.FileSystemLoader(
-                os.path.join(csr_data_dir, 'templates')),
+            loader=loader,
             extensions=[jinja2.ext.ExprStmtExtension, IPAExtension],
             keep_trailing_newline=True, undefined=IndexableUndefined)
 
@@ -277,9 +282,13 @@ def rules_for_profile(self, profile_id, helper):
 
 
 class FileRuleProvider(RuleProvider):
-    def __init__(self, csr_data_dir=paths.CSR_DATA_DIR):
+    def __init__(self, csr_data_dir=None):
         self.rules = {}
-        self.csr_data_dir = csr_data_dir
+        if csr_data_dir is None:
+            self.csr_data_dir = pkg_resources.resource_filename(
+                'ipaclient', 'csrgen')
+        else:
+            self.csr_data_dir = csr_data_dir
 
     def _rule(self, rule_name, helper):
         if (rule_name, helper) not in self.rules:
diff --git a/ipaclient/csrgen/profiles/caIPAserviceCert.json b/ipaclient/csrgen/profiles/caIPAserviceCert.json
new file mode 100644
index 0000000..114d2ff
--- /dev/null
+++ b/ipaclient/csrgen/profiles/caIPAserviceCert.json
@@ -0,0 +1,15 @@
+[
+    {
+        "syntax": "syntaxSubject",
+        "data": [
+            "dataHostCN",
+            "dataSubjectBase"
+        ]
+    },
+    {
+        "syntax": "syntaxSAN",
+        "data": [
+            "dataDNS"
+        ]
+    }
+]
diff --git a/ipaclient/csrgen/profiles/userCert.json b/ipaclient/csrgen/profiles/userCert.json
new file mode 100644
index 0000000..d6cf5cf
--- /dev/null
+++ b/ipaclient/csrgen/profiles/userCert.json
@@ -0,0 +1,15 @@
+[
+    {
+        "syntax": "syntaxSubject",
+        "data": [
+            "dataUsernameCN",
+            "dataSubjectBase"
+        ]
+    },
+    {
+        "syntax": "syntaxSAN",
+        "data": [
+            "dataEmail"
+        ]
+    }
+]
diff --git a/ipaclient/csrgen/rules/dataDNS.json b/ipaclient/csrgen/rules/dataDNS.json
new file mode 100644
index 0000000..2663f11
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataDNS.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "DNS = {{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
+    },
+    {
+      "helper": "certutil",
+      "template": "dns:{{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
+    }
+  ],
+  "options": {
+    "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
+  }
+}
diff --git a/ipaclient/csrgen/rules/dataEmail.json b/ipaclient/csrgen/rules/dataEmail.json
new file mode 100644
index 0000000..2eae9fb
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataEmail.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "email = {{subject.mail.0}}"
+    },
+    {
+      "helper": "certutil",
+      "template": "email:{{subject.mail.0|quote}}"
+    }
+  ],
+  "options": {
+    "data_source": "subject.mail.0"
+  }
+}
diff --git a/ipaclient/csrgen/rules/dataHostCN.json b/ipaclient/csrgen/rules/dataHostCN.json
new file mode 100644
index 0000000..5c415bb
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataHostCN.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
+    },
+    {
+      "helper": "certutil",
+      "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]|quote}}"
+    }
+  ],
+  "options": {
+    "data_source": "subject.krbprincipalname.0.partition('/')[2].partition('@')[0]"
+  }
+}
diff --git a/ipaclient/csrgen/rules/dataSubjectBase.json b/ipaclient/csrgen/rules/dataSubjectBase.json
new file mode 100644
index 0000000..309dfb1
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataSubjectBase.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "{{config.ipacertificatesubjectbase.0}}"
+    },
+    {
+      "helper": "certutil",
+      "template": "{{config.ipacertificatesubjectbase.0|quote}}"
+    }
+  ],
+  "options": {
+    "data_source": "config.ipacertificatesubjectbase.0"
+  }
+}
diff --git a/ipaclient/csrgen/rules/dataUsernameCN.json b/ipaclient/csrgen/rules/dataUsernameCN.json
new file mode 100644
index 0000000..37e7e01
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataUsernameCN.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "CN={{subject.uid.0}}"
+    },
+    {
+      "helper": "certutil",
+      "template": "CN={{subject.uid.0|quote}}"
+    }
+  ],
+  "options": {
+    "data_source": "subject.uid.0"
+  }
+}
diff --git a/ipaclient/csrgen/rules/syntaxSAN.json b/ipaclient/csrgen/rules/syntaxSAN.json
new file mode 100644
index 0000000..122eb12
--- /dev/null
+++ b/ipaclient/csrgen/rules/syntaxSAN.json
@@ -0,0 +1,15 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "subjectAltName = @{% call openssl.section() %}{{ datarules|join('\n') }}{% endcall %}",
+      "options": {
+        "extension": true
+      }
+    },
+    {
+      "helper": "certutil",
+      "template": "--extSAN {{ datarules|join(',') }}"
+    }
+  ]
+}
diff --git a/ipaclient/csrgen/rules/syntaxSubject.json b/ipaclient/csrgen/rules/syntaxSubject.json
new file mode 100644
index 0000000..af6ec03
--- /dev/null
+++ b/ipaclient/csrgen/rules/syntaxSubject.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+    {
+      "helper": "openssl",
+      "template": "distinguished_name = {% call openssl.section() %}{{ datarules|reverse|join('\n') }}{% endcall %}"
+    },
+    {
+      "helper": "certutil",
+      "template": "-s {{ datarules|join(',') }}"
+    }
+  ],
+  "options": {
+    "required": true,
+    "data_source_combinator": "and"
+  }
+}
diff --git a/ipaclient/csrgen/templates/certutil_base.tmpl b/ipaclient/csrgen/templates/certutil_base.tmpl
new file mode 100644
index 0000000..a5556fd
--- /dev/null
+++ b/ipaclient/csrgen/templates/certutil_base.tmpl
@@ -0,0 +1,11 @@
+#!/bin/bash -e
+
+if [[ $# -lt 1 ]]; then
+echo "Usage: $0 <outfile> [<any> <certutil> <args>]"
+echo "Called as: $0 $@"
+exit 1
+fi
+
+CSR="$1"
+shift
+certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" {{ options|join(' ') }} "$@"
diff --git a/ipaclient/csrgen/templates/openssl_base.tmpl b/ipaclient/csrgen/templates/openssl_base.tmpl
new file mode 100644
index 0000000..22b1686
--- /dev/null
+++ b/ipaclient/csrgen/templates/openssl_base.tmpl
@@ -0,0 +1,35 @@
+{% raw -%}
+{% import "openssl_macros.tmpl" as openssl -%}
+{%- endraw %}
+#!/bin/bash -e
+
+if [[ $# -lt 2 ]]; then
+echo "Usage: $0 <outfile> <keyfile> <other openssl arguments>"
+echo "Called as: $0 $@"
+exit 1
+fi
+
+CONFIG="$(mktemp)"
+CSR="$1"
+KEYFILE="$2"
+shift; shift
+
+echo \
+{% raw %}{% filter quote %}{% endraw -%}
+[ req ]
+prompt = no
+encrypt_key = no
+
+{{ parameters|join('\n') }}
+{% raw %}{% set rendered_extensions -%}{% endraw %}
+{{ extensions|join('\n') }}
+{% raw -%}
+{%- endset -%}
+{% if rendered_extensions -%}
+req_extensions = {% call openssl.section() %}{{ rendered_extensions }}{% endcall %}
+{% endif %}
+{{ openssl.openssl_sections|join('\n\n') }}
+{% endfilter %}{%- endraw %} > "$CONFIG"
+
+openssl req -new -config "$CONFIG" -out "$CSR" -key "$KEYFILE" "$@"
+rm "$CONFIG"
diff --git a/ipaclient/csrgen/templates/openssl_macros.tmpl b/ipaclient/csrgen/templates/openssl_macros.tmpl
new file mode 100644
index 0000000..d31b8fe
--- /dev/null
+++ b/ipaclient/csrgen/templates/openssl_macros.tmpl
@@ -0,0 +1,29 @@
+{# List containing rendered sections to be included at end #}
+{% set openssl_sections = [] %}
+
+{#
+List containing one entry for each section name allocated. Because of
+scoping rules, we need to use a list so that it can be a "per-render global"
+that gets updated in place. Real globals are shared by all templates with the
+same environment, and variables defined in the macro don't persist after the
+macro invocation ends.
+#}
+{% set openssl_section_num = [] %}
+
+{% macro section() -%}
+{% set name -%}
+sec{{ openssl_section_num|length -}}
+{% endset -%}
+{% do openssl_section_num.append('') -%}
+{% set contents %}{{ caller() }}{% endset -%}
+{% if contents -%}
+{% set sectiondata = formatsection(name, contents) -%}
+{% do openssl_sections.append(sectiondata) -%}
+{% endif -%}
+{{ name -}}
+{% endmacro %}
+
+{% macro formatsection(name, contents) -%}
+[ {{ name }} ]
+{{ contents -}}
+{% endmacro %}
diff --git a/ipaclient/setup.py b/ipaclient/setup.py
index 93cb1e8..f5be7ea 100644
--- a/ipaclient/setup.py
+++ b/ipaclient/setup.py
@@ -43,6 +43,13 @@
             "ipaclient.remote_plugins.2_156",
             "ipaclient.remote_plugins.2_164",
         ],
+        package_data={
+            'ipaclient': [
+                'csrgen/profiles/*.json',
+                'csrgen/rules/*.json',
+                'csrgen/templates/*.tmpl',
+            ],
+        },
         install_requires=[
             "cryptography",
             "ipalib",
@@ -56,5 +63,6 @@
         extras_require={
             "install": ["ipaplatform"],
             "otptoken_yubikey": ["yubico", "usb"]
-        }
+        },
+        zip_safe=False,
     )
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index e4d4f2e..de4ea23 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -238,7 +238,6 @@ class BasePathNamespace(object):
     SCHEMA_COMPAT_ULDIF = "/usr/share/ipa/schema_compat.uldif"
     IPA_JS_PLUGINS_DIR = "/usr/share/ipa/ui/js/plugins"
     UPDATES_DIR = "/usr/share/ipa/updates/"
-    CSR_DATA_DIR = "/usr/share/ipa/csrgen"
     DICT_WORDS = "/usr/share/dict/words"
     CACHE_IPA_SESSIONS = "/var/cache/ipa/sessions"
     VAR_KERBEROS_KRB5KDC_DIR = "/var/kerberos/krb5kdc/"
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to