[Freeipa-devel] [freeipa PR#433][synchronized] csrgen: Allow some certificate fields to be specified by the user

2017-04-16 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/433
Author: LiptonB
 Title: #433: csrgen: Allow some certificate fields to be specified by the user
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/433/head:pr433
git checkout pr433
From bf80c8e7c5ae1e67a497b06819ef56bfedc4339a Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Thu, 28 Jul 2016 16:21:44 -0400
Subject: [PATCH 1/3] csrgen: Implement fields that prompt user for data

Allows some data to be user-specified rather than coming out of the
database. The provided data can be formatted with jinja2 rules just as
database values can.

https://fedorahosted.org/freeipa/ticket/4899
---
 ipaclient/csrgen.py| 35 --
 ipaclient/csrgen/rules/dataEmailUserSpecified.json | 16 ++
 ipaclient/plugins/csrgen.py| 10 +--
 ipatests/test_ipaclient/test_csrgen.py | 11 +++
 4 files changed, 63 insertions(+), 9 deletions(-)
 create mode 100644 ipaclient/csrgen/rules/dataEmailUserSpecified.json

diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 0f52a8b..67442f6 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -372,8 +372,9 @@ def __init__(self, rule_provider, formatter_class=OpenSSLFormatter):
 self.rule_provider = rule_provider
 self.formatter = formatter_class()
 
-def csr_config(self, principal, config, profile_id):
-render_data = {'subject': principal, 'config': config}
+def csr_config(self, principal, config, userdata, profile_id):
+render_data = {
+'subject': principal, 'config': config, 'userdata': userdata}
 
 rules = self.rule_provider.rules_for_profile(profile_id)
 template = self.formatter.build_template(rules)
@@ -387,6 +388,36 @@ def csr_config(self, principal, config, profile_id):
 
 return config
 
+def get_user_prompts(self, profile_id):
+prompts = {}
+rules = self.rule_provider.rules_for_profile(profile_id)
+
+for field_mapping in rules:
+for rule in field_mapping.data_rules:
+if 'prompt' in rule.options:
+try:
+var = rule.options['data_source']
+except KeyError:
+raise errors.CSRTemplateError(reason=_(
+'Certificate mapping rule %(rule)s has a prompt'
+' but no data_source set') % {'rule': rule.name})
+if var in prompts:
+raise errors.CSRTemplateError(reason=_(
+'More than one data rule in this profile prompts'
+' for the %(item)s data item') % {'item': var})
+var_parts = var.split('.')
+if len(var_parts) != 2 or var_parts[0] != 'userdata':
+raise errors.CSRTemplateError(
+reason=_(
+'Format of variable name in rule %(rule)s is'
+' incorrect. Rules that prompt for data must'
+' use a variable "userdata."') %
+{'rule': rule.name})
+
+prompts[var_parts[1]] = rule.options['prompt']
+
+return prompts
+
 
 class CSRLibraryAdaptor(object):
 def get_subject_public_key_info(self):
diff --git a/ipaclient/csrgen/rules/dataEmailUserSpecified.json b/ipaclient/csrgen/rules/dataEmailUserSpecified.json
new file mode 100644
index 000..3fb2fb1
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataEmailUserSpecified.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+{
+  "helper": "openssl",
+  "template": "email = {{userdata.email}}"
+},
+{
+  "helper": "certutil",
+  "template": "email:{{userdata.email|quote}}"
+}
+  ],
+  "options": {
+"data_source": "userdata.email",
+"prompt": "Email address"
+  }
+}
diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py
index 568a79f..6503f57 100644
--- a/ipaclient/plugins/csrgen.py
+++ b/ipaclient/plugins/csrgen.py
@@ -90,6 +90,9 @@ def execute(self, *args, **options):
 if not backend.isconnected():
 backend.connect()
 
+generator = csrgen.CSRGenerator(csrgen.FileRuleProvider())
+prompts = generator.get_user_prompts(profile_id, helper)
+
 try:
 if principal.is_host:
 principal_obj = api.Command.host_show(
@@ -106,9 +109,12 @@ def execute(self, *args, **options):
 principal_obj = principal_obj['result']
 config = api.Command.config_show()['result']
 
-generator = csrgen.CSRGenerator(csr

[Freeipa-devel] [freeipa PR#717][opened] csrgen: Finish NSS support

2017-04-16 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/717
Author: LiptonB
 Title: #717: csrgen: Finish NSS support
Action: opened

PR body:
"""
I took the approach of generating a new key for each request, as keys already 
stored in a database are difficult to name precisely. I also had to add another 
hook to `CSRLibraryAdaptor` that is called after the cert is returned from the 
server, so that we could add the cert to the database as desired.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/717/head:pr717
git checkout pr717
From 171ead1704ef9f5d28b361cb6555dc31540fa4b5 Mon Sep 17 00:00:00 2001
From: Ben Lipton <ben.lip...@gmail.com>
Date: Thu, 30 Mar 2017 22:39:40 -0400
Subject: [PATCH] csrgen: Finish NSS support

https://pagure.io/freeipa/issue/4899
---
 ipaclient/csrgen.py   | 130 +-
 ipaclient/plugins/cert.py |  21 +++-
 2 files changed, 102 insertions(+), 49 deletions(-)

diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 0f52a8b..7724099 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -10,16 +10,17 @@
 import os.path
 import pipes
 import subprocess
+import tempfile
 import traceback
 
 import pkg_resources
 
 from cryptography.hazmat.backends import default_backend
-from cryptography.hazmat.primitives.asymmetric import padding
+from cryptography.hazmat.primitives.asymmetric import padding, rsa
 from cryptography.hazmat.primitives import hashes
 from cryptography.hazmat.primitives.serialization import (
-load_pem_private_key, Encoding, PublicFormat)
-from cryptography.x509 import load_pem_x509_certificate
+load_pem_private_key, Encoding, NoEncryption, PrivateFormat, PublicFormat)
+from cryptography.x509 import load_der_x509_certificate
 import jinja2
 import jinja2.ext
 import jinja2.sandbox
@@ -389,39 +390,28 @@ def csr_config(self, principal, config, profile_id):
 
 
 class CSRLibraryAdaptor(object):
-def get_subject_public_key_info(self):
-raise NotImplementedError('Use a subclass of CSRLibraryAdaptor')
-
-def sign_csr(self, certification_request_info):
-"""Sign a CertificationRequestInfo.
+def key(self):
+"""Return the private key to be used in the cert.
 
-Returns: str, a DER-encoded signed CSR.
+Returns: cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
+representing the private key.
 """
 raise NotImplementedError('Use a subclass of CSRLibraryAdaptor')
 
-
-class OpenSSLAdaptor(object):
-def __init__(self, key_filename, password_filename):
-self.key_filename = key_filename
-self.password_filename = password_filename
-
-def key(self):
-with open(self.key_filename, 'r') as key_file:
-key_bytes = key_file.read()
-password = None
-if self.password_filename is not None:
-with open(self.password_filename, 'r') as password_file:
-password = password_file.read().strip()
-
-key = load_pem_private_key(key_bytes, password, default_backend())
-return key
-
 def get_subject_public_key_info(self):
+"""Return the public key info for the cert.
+
+Returns: str, a DER-encoded SubjectPublicKeyInfo structure.
+"""
 pubkey_info = self.key().public_key().public_bytes(
 Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
 return pubkey_info
 
 def sign_csr(self, certification_request_info):
+"""Sign a CertificationRequestInfo.
+
+Returns: str, a DER-encoded signed CSR.
+"""
 reqinfo = decoder.decode(
 certification_request_info, rfc2314.CertificationRequestInfo())[0]
 csr = rfc2314.CertificationRequest()
@@ -442,32 +432,78 @@ def sign_csr(self, certification_request_info):
 csr.setComponentByName('signature', asn1sig)
 return encoder.encode(csr)
 
+def process_cert(self, cert):
+"""Perform any required post-processing on the certificate."""
 
-class NSSAdaptor(object):
-def __init__(self, database, password_filename):
-self.database = database
+
+class OpenSSLAdaptor(CSRLibraryAdaptor):
+def __init__(self, key_filename, password_filename):
+self.key_filename = key_filename
 self.password_filename = password_filename
-self.nickname = base64.b32encode(os.urandom(40))
+self._key = None
 
-def get_subject_public_key_info(self):
-temp_cn = base64.b32encode(os.urandom(40))
+def key(self):
+if self._key is None:
+with open(self.key_filename, 'r') as key_file:
+key_bytes = key_file.read()
+password = None
+if self.password_filename i

[Freeipa-devel] [freeipa PR#542][comment] Implementation independent interface for CSR generation

2017-04-03 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/542
Title: #542: Implementation independent interface for CSR generation

LiptonB commented:
"""
@HonzaCholasta, thanks! I have an attempt at NSS support in progress. It
might take me a few more days to get it ready to send out, but I think it's
close.

On Mon, Apr 3, 2017 at 3:45 AM Jan Cholasta <notificati...@github.com>
wrote:

> @LiptonB <https://github.com/LiptonB>, superb, thank you!
>
> Have you made any progress with NSS support? If not, I can add it in a
> subsequent PR, if you agree.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/freeipa/freeipa/pull/542#issuecomment-291070970>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AAcj_faOJ9GWrYO3aT4sxV7gx6_fBfUIks5rsKOggaJpZM4MUefo>
> .
>

"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/542#issuecomment-291172628
-- 
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

[Freeipa-devel] [freeipa PR#542][comment] Implementation independent interface for CSR generation

2017-03-22 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/542
Title: #542: Implementation independent interface for CSR generation

LiptonB commented:
"""
Thanks for the clarification, @HonzaCholasta. (And for the timely intervention 
in #579 to make it actually invisible).

A new version is pushed, which uses CFFI and the unmodified openssl config 
format, and removes the `helper` abstraction as requested. NSS support is still 
broken for now, I haven't had a chance to look into the change you suggested. 
Let me know what you think.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/542#issuecomment-288569409
-- 
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

[Freeipa-devel] [freeipa PR#542][comment] Implementation independent interface for CSR generation

2017-03-22 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/542
Title: #542: Implementation independent interface for CSR generation

LiptonB commented:
"""
Thanks for the clarification, @HonzaCholasta. (And for the timely intervention 
in #579 to make it actually invisible).

A new version is pushed, which uses CFFI and the unmodified openssl config 
format, and removes the `helper` abstraction as requested. NSS support is still 
broken for now, I haven't had a chance to look into the change you suggested. 
Let me know what you think.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/542#issuecomment-288569409
-- 
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

[Freeipa-devel] [freeipa PR#542][synchronized] Implementation independent interface for CSR generation

2017-03-22 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/542
Author: LiptonB
 Title: #542: Implementation independent interface for CSR generation
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/542/head:pr542
git checkout pr542
From 3aab3e2cb40bde4d4bed5c01ce04d028706ec210 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 21 Mar 2017 12:21:30 -0400
Subject: [PATCH 1/4] csrgen: Remove helper abstraction

All requests now use the OpenSSL formatter. However, we keep Formatter
a separate class so that it can be changed out for tests.

https://pagure.io/freeipa/issue/4899
---
 ipaclient/csrgen.py| 71 ++--
 ipaclient/csrgen/rules/dataDNS.json| 13 +--
 ipaclient/csrgen/rules/dataEmail.json  | 13 +--
 ipaclient/csrgen/rules/dataHostCN.json | 13 +--
 ipaclient/csrgen/rules/dataSubjectBase.json| 13 +--
 ipaclient/csrgen/rules/dataUsernameCN.json | 13 +--
 ipaclient/csrgen/rules/syntaxSAN.json  | 19 ++---
 ipaclient/csrgen/rules/syntaxSubject.json  | 13 +--
 ipaclient/csrgen/templates/certutil_base.tmpl  | 11 ---
 ipaclient/plugins/csrgen.py|  2 +-
 .../data/test_csrgen/configs/caIPAserviceCert.conf | 34 
 .../data/test_csrgen/configs/userCert.conf | 34 
 .../data/test_csrgen/rules/basic.json  | 13 +--
 .../data/test_csrgen/rules/options.json| 18 +---
 .../scripts/caIPAserviceCert_certutil.sh   | 11 ---
 .../scripts/caIPAserviceCert_openssl.sh| 34 
 .../data/test_csrgen/scripts/userCert_certutil.sh  | 11 ---
 .../data/test_csrgen/scripts/userCert_openssl.sh   | 34 
 ipatests/test_ipaclient/test_csrgen.py | 98 +-
 19 files changed, 145 insertions(+), 323 deletions(-)
 delete mode 100644 ipaclient/csrgen/templates/certutil_base.tmpl
 create mode 100644 ipatests/test_ipaclient/data/test_csrgen/configs/caIPAserviceCert.conf
 create mode 100644 ipatests/test_ipaclient/data/test_csrgen/configs/userCert.conf
 delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_certutil.sh
 delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/caIPAserviceCert_openssl.sh
 delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_certutil.sh
 delete mode 100644 ipatests/test_ipaclient/data/test_csrgen/scripts/userCert_openssl.sh

diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 8fb0b32..8ca0722 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -244,13 +244,6 @@ def _prepare_syntax_rule(
 return self.SyntaxRule(prepared_template, is_extension)
 
 
-class CertutilFormatter(Formatter):
-base_template_name = 'certutil_base.tmpl'
-
-def _get_template_params(self, syntax_rules):
-return {'options': syntax_rules}
-
-
 class FieldMapping(object):
 """Representation of the rules needed to construct a complete cert field.
 
@@ -279,13 +272,11 @@ def __init__(self, name, template, options):
 
 
 class RuleProvider(object):
-def rules_for_profile(self, profile_id, helper):
+def rules_for_profile(self, profile_id):
 """
 Return the rules needed to build a CSR using the given profile.
 
 :param profile_id: str, name of the CSR generation profile to use
-:param helper: str, name of tool (e.g. openssl, certutil) that will be
-used to create CSR
 
 :returns: list of FieldMapping, filled out with the appropriate rules
 """
@@ -321,40 +312,31 @@ def _open(self, subdir, filename):
 )
 )
 
-def _rule(self, rule_name, helper):
-if (rule_name, helper) not in self.rules:
+def _rule(self, rule_name):
+if rule_name not in self.rules:
 try:
 with self._open('rules', '%s.json' % rule_name) as f:
-ruleset = json.load(f)
+ruleconf = json.load(f)
 except IOError:
 raise errors.NotFound(
-reason=_('Ruleset %(ruleset)s does not exist.') %
-{'ruleset': rule_name})
+reason=_('No generation rule %(rulename)s found.') %
+{'rulename': rule_name})
 
-matching_rules = [r for r in ruleset['rules']
-  if r['helper'] == helper]
-if len(matching_rules) == 0:
+try:
+rule = ruleconf['rule']
+except KeyError:
 raise errors.EmptyResult(
-reason=_('No transformation in "%(ruleset)s" rule supports'
- ' helper "%(helper)s"') %
-{'ruleset': rule_name, 'helper': hel

[Freeipa-devel] [freeipa PR#542][comment] Implementation independent interface for CSR generation

2017-03-15 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/542
Title: #542: Implementation independent interface for CSR generation

LiptonB commented:
"""
Regarding this comment from @MartinBasti in #590:

> > For the record, #542 removes the helper parameter of cert-get-requestdata, 
> > and will be modified to remove the concept of different helpers entirely, 
> > though I haven't had a chance to make that change yet.
> 
> today is 4.5 release so you have to keep some level of backward compatibility 
> in that PR

What level of backward compatibility is required? Is it not ok to remove 
helpers? I thought the purpose of making `cert-get-requestdata` an internal, 
client-side API was that it would be ok to change the parameters as we figured 
out how it should work.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/542#issuecomment-286819264
-- 
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

[Freeipa-devel] [freeipa PR#433][comment] csrgen: Allow some certificate fields to be specified by the user

2017-03-15 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/433
Title: #433: csrgen: Allow some certificate fields to be specified by the user

LiptonB commented:
"""
Rebased, thanks.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/433#issuecomment-286816039
-- 
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

[Freeipa-devel] [freeipa PR#590][comment] Validate user input for cert-get-requestdata

2017-03-15 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/590
Title: #590: Validate user input for cert-get-requestdata

LiptonB commented:
"""
I don't think one could really add a new helper without modifying the code, so 
there's probably no need to allow arbitrary strings. Given that, StrEnum seems 
appropriate.

For the record, https://github.com/freeipa/freeipa/pull/542 is going to be 
modified to remove the `helper` parameter of `cert-get-requestdata` entirely, 
though I haven't had a chance to make the change yet.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/590#issuecomment-286787004
-- 
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

[Freeipa-devel] [freeipa PR#433][synchronized] csrgen: Allow some certificate fields to be specified by the user

2017-03-15 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/433
Author: LiptonB
 Title: #433: csrgen: Allow some certificate fields to be specified by the user
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/433/head:pr433
git checkout pr433
From 61a825b57f923ca7b641bca5f436d4b41f3acfb8 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Thu, 28 Jul 2016 16:21:44 -0400
Subject: [PATCH 1/3] csrgen: Implement fields that prompt user for data

Allows some data to be user-specified rather than coming out of the
database. The provided data can be formatted with jinja2 rules just as
database values can.

https://fedorahosted.org/freeipa/ticket/4899
---
 ipaclient/csrgen.py| 35 --
 ipaclient/csrgen/rules/dataEmailUserSpecified.json | 16 ++
 ipaclient/plugins/csrgen.py|  9 --
 ipatests/test_ipaclient/test_csrgen.py | 15 +-
 4 files changed, 64 insertions(+), 11 deletions(-)
 create mode 100644 ipaclient/csrgen/rules/dataEmailUserSpecified.json

diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 8fb0b32..41a4352 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -381,8 +381,9 @@ class CSRGenerator(object):
 def __init__(self, rule_provider):
 self.rule_provider = rule_provider
 
-def csr_script(self, principal, config, profile_id, helper):
-render_data = {'subject': principal, 'config': config}
+def csr_script(self, principal, config, userdata, profile_id, helper):
+render_data = {
+'subject': principal, 'config': config, 'userdata': userdata}
 
 formatter = self.FORMATTERS[helper]()
 rules = self.rule_provider.rules_for_profile(profile_id, helper)
@@ -396,3 +397,33 @@ def csr_script(self, principal, config, profile_id, helper):
 'Template error when formatting certificate data'))
 
 return script
+
+def get_user_prompts(self, profile_id, helper):
+prompts = {}
+rules = self.rule_provider.rules_for_profile(profile_id, helper)
+
+for field_mapping in rules:
+for rule in field_mapping.data_rules:
+if 'prompt' in rule.options:
+try:
+var = rule.options['data_source']
+except KeyError:
+raise errors.CSRTemplateError(reason=_(
+'Certificate mapping rule %(rule)s has a prompt'
+' but no data_source set') % {'rule': rule.name})
+if var in prompts:
+raise errors.CSRTemplateError(reason=_(
+'More than one data rule in this profile prompts'
+' for the %(item)s data item') % {'item': var})
+var_parts = var.split('.')
+if len(var_parts) != 2 or var_parts[0] != 'userdata':
+raise errors.CSRTemplateError(
+reason=_(
+'Format of variable name in rule %(rule)s is'
+' incorrect. Rules that prompt for data must'
+' use a variable "userdata."') %
+{'rule': rule.name})
+
+prompts[var_parts[1]] = rule.options['prompt']
+
+return prompts
diff --git a/ipaclient/csrgen/rules/dataEmailUserSpecified.json b/ipaclient/csrgen/rules/dataEmailUserSpecified.json
new file mode 100644
index 000..3fb2fb1
--- /dev/null
+++ b/ipaclient/csrgen/rules/dataEmailUserSpecified.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+{
+  "helper": "openssl",
+  "template": "email = {{userdata.email}}"
+},
+{
+  "helper": "certutil",
+  "template": "email:{{userdata.email|quote}}"
+}
+  ],
+  "options": {
+"data_source": "userdata.email",
+"prompt": "Email address"
+  }
+}
diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py
index a0d99ef..0cc67f7 100644
--- a/ipaclient/plugins/csrgen.py
+++ b/ipaclient/plugins/csrgen.py
@@ -87,6 +87,9 @@ def execute(self, *args, **options):
 if not backend.isconnected():
 backend.connect()
 
+generator = CSRGenerator(FileRuleProvider())
+prompts = generator.get_user_prompts(profile_id, helper)
+
 try:
 if principal.is_host:
 principal_obj = api.Command.host_show(
@@ -103,10 +106,12 @@ def execute(self, *args, **options):
 principal_obj = principal_obj['result']
 config = api.Command.config_show()['result']
 
-generator = CSRGenerator(FileRuleProvider())
+userdata 

[Freeipa-devel] [freeipa PR#590][comment] Validate user input for cert-get-requestdata

2017-03-15 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/590
Title: #590: Validate user input for cert-get-requestdata

LiptonB commented:
"""
I don't think one could really add a new helper without modifying the code, so 
there's probably no need to allow arbitrary strings. Given that, StrEnum seems 
appropriate.

For the record, https://github.com/freeipa/freeipa/pull/542 is going to be 
modified to remove the `helper` parameter of `cert-get-requestdata` entirely, 
though I haven't had a chance to make the change yet.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/590#issuecomment-286787004
-- 
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

[Freeipa-devel] [freeipa PR#542][comment] Implementation independent interface for CSR generation

2017-03-07 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/542
Title: #542: Implementation independent interface for CSR generation

LiptonB commented:
"""
Thanks for the feedback. I will put together a new version using CFFI and the 
`openssl req` format for subject names.

Regarding helpers, this code has all CSR generation go through the 
`CertificationRequestInfo`-based flow, so the other helpers can't actually be 
accessed. Maybe we should remove the helper/formatter abstraction entirely, and 
have the new format (raw openssl config) be the only jinja template available. 
This makes things simpler but will remove all support for NSS databases until 
we add it to the new flow. What do you think? (An alternative would be to 
remove only the `openssl` helper, and add a `CertificationRequestInfoFormatter` 
in its place).
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/542#issuecomment-284727415
-- 
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

[Freeipa-devel] [freeipa PR#542][synchronized] Implementation independent interface for CSR generation

2017-03-06 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/542
Author: LiptonB
 Title: #542: Implementation independent interface for CSR generation
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/542/head:pr542
git checkout pr542
From 6f678a1c68769daf5b2f80cbf65a5b6b1c99f7a1 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Fri, 7 Oct 2016 10:39:40 -0400
Subject: [PATCH 1/3] csrgen: Add "certmonger" helper to produce simplified
 openssl configs

The resulting file is similar to the config accepted by `openssl req`,
but instead of a section for the subject name, it contains a single
config item, `cm_template_subject`, in the format that certmonger
accepts for its certificate subject names.

https://pagure.io/freeipa/issue/4899
---
 install/share/csrgen/Makefile.am|  1 +
 install/share/csrgen/rules/dataDNS.json |  2 +-
 install/share/csrgen/rules/dataEmail.json   |  2 +-
 install/share/csrgen/rules/dataHostCN.json  |  2 +-
 install/share/csrgen/rules/dataSubjectBase.json |  2 +-
 install/share/csrgen/rules/dataUsernameCN.json  |  2 +-
 install/share/csrgen/rules/syntaxSAN.json   |  2 +-
 install/share/csrgen/rules/syntaxSubject.json   |  4 
 install/share/csrgen/templates/certmonger_base.tmpl | 17 +
 ipaclient/csrgen.py |  7 ++-
 10 files changed, 34 insertions(+), 7 deletions(-)
 create mode 100644 install/share/csrgen/templates/certmonger_base.tmpl

diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
index 12c62c4..53324fe 100644
--- a/install/share/csrgen/Makefile.am
+++ b/install/share/csrgen/Makefile.am
@@ -20,6 +20,7 @@ rule_DATA =\
 templatedir = $(IPA_DATA_DIR)/csrgen/templates
 template_DATA =			\
 	templates/certutil_base.tmpl	\
+	templates/certmonger_base.tmpl	\
 	templates/openssl_base.tmpl	\
 	templates/openssl_macros.tmpl	\
 	$(NULL)
diff --git a/install/share/csrgen/rules/dataDNS.json b/install/share/csrgen/rules/dataDNS.json
index 2663f11..263eae0 100644
--- a/install/share/csrgen/rules/dataDNS.json
+++ b/install/share/csrgen/rules/dataDNS.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "DNS = {{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataEmail.json b/install/share/csrgen/rules/dataEmail.json
index 2eae9fb..5c4dbe8 100644
--- a/install/share/csrgen/rules/dataEmail.json
+++ b/install/share/csrgen/rules/dataEmail.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "email = {{subject.mail.0}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataHostCN.json b/install/share/csrgen/rules/dataHostCN.json
index 5c415bb..8c17e8a 100644
--- a/install/share/csrgen/rules/dataHostCN.json
+++ b/install/share/csrgen/rules/dataHostCN.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataSubjectBase.json b/install/share/csrgen/rules/dataSubjectBase.json
index 309dfb1..489dd49 100644
--- a/install/share/csrgen/rules/dataSubjectBase.json
+++ b/install/share/csrgen/rules/dataSubjectBase.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "{{config.ipacertificatesubjectbase.0}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataUsernameCN.json b/install/share/csrgen/rules/dataUsernameCN.json
index 37e7e01..d294ab2 100644
--- a/install/share/csrgen/rules/dataUsernameCN.json
+++ b/install/share/csrgen/rules/dataUsernameCN.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "CN={{subject.uid.0}}"
 },
 {
diff --git a/install/share/csrgen/rules/syntaxSAN.json b/install/share/csrgen/rules/syntaxSAN.json
index 122eb12..00b1808 100644
--- a/install/share/csrgen/rules/syntaxSAN.json
+++ b/install/share/csrgen/rules/syntaxSAN.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "templ

[Freeipa-devel] [freeipa PR#542][opened] Implementation independent interface for CSR generation

2017-03-06 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/542
Author: LiptonB
 Title: #542: Implementation independent interface for CSR generation
Action: opened

PR body:
"""
@HonzaCholasta and everyone, here is where I am so far on the 
[CertificationRequestInfo-based interface for CSR 
generation](https://www.redhat.com/archives/freeipa-devel/2017-February/msg00104.html).

As I see it, there are a few rough edges still, so I'd like to get your 
opinion, especially about these things:
- For feeding to `build_requestinfo` we want a config file, not a script, so I 
needed to add another formatter/helper that omits the bash code that's there 
for other helpers.
- While openssl has a library function for creating cert extensions from the 
config file format, the logic for creating the subject name from the config 
format is implemented within the `openssl req` command rather than the library. 
In `build_requestinfo` I copied [the code from 
certmonger](https://pagure.io/certmonger/blob/master/f/src/csrgen-o.c#_193-223) 
that creates the subject name, which takes a simpler format. So the new 
formatter is called "certmonger" and uses that format.
- I'm not sure where in the freeipa project the code for `build_requestinfo` 
should go, how to work it into the build process, and where it should be 
installed. Right now I just have a TODO to do so. Or did you mean for that code 
to be run via CFFI as well?
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/542/head:pr542
git checkout pr542
From 6f678a1c68769daf5b2f80cbf65a5b6b1c99f7a1 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Fri, 7 Oct 2016 10:39:40 -0400
Subject: [PATCH 1/3] csrgen: Add "certmonger" helper to produce simplified
 openssl configs

The resulting file is similar to the config accepted by `openssl req`,
but instead of a section for the subject name, it contains a single
config item, `cm_template_subject`, in the format that certmonger
accepts for its certificate subject names.

https://pagure.io/freeipa/issue/4899
---
 install/share/csrgen/Makefile.am|  1 +
 install/share/csrgen/rules/dataDNS.json |  2 +-
 install/share/csrgen/rules/dataEmail.json   |  2 +-
 install/share/csrgen/rules/dataHostCN.json  |  2 +-
 install/share/csrgen/rules/dataSubjectBase.json |  2 +-
 install/share/csrgen/rules/dataUsernameCN.json  |  2 +-
 install/share/csrgen/rules/syntaxSAN.json   |  2 +-
 install/share/csrgen/rules/syntaxSubject.json   |  4 
 install/share/csrgen/templates/certmonger_base.tmpl | 17 +
 ipaclient/csrgen.py |  7 ++-
 10 files changed, 34 insertions(+), 7 deletions(-)
 create mode 100644 install/share/csrgen/templates/certmonger_base.tmpl

diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
index 12c62c4..53324fe 100644
--- a/install/share/csrgen/Makefile.am
+++ b/install/share/csrgen/Makefile.am
@@ -20,6 +20,7 @@ rule_DATA =\
 templatedir = $(IPA_DATA_DIR)/csrgen/templates
 template_DATA =			\
 	templates/certutil_base.tmpl	\
+	templates/certmonger_base.tmpl	\
 	templates/openssl_base.tmpl	\
 	templates/openssl_macros.tmpl	\
 	$(NULL)
diff --git a/install/share/csrgen/rules/dataDNS.json b/install/share/csrgen/rules/dataDNS.json
index 2663f11..263eae0 100644
--- a/install/share/csrgen/rules/dataDNS.json
+++ b/install/share/csrgen/rules/dataDNS.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "DNS = {{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataEmail.json b/install/share/csrgen/rules/dataEmail.json
index 2eae9fb..5c4dbe8 100644
--- a/install/share/csrgen/rules/dataEmail.json
+++ b/install/share/csrgen/rules/dataEmail.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "email = {{subject.mail.0}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataHostCN.json b/install/share/csrgen/rules/dataHostCN.json
index 5c415bb..8c17e8a 100644
--- a/install/share/csrgen/rules/dataHostCN.json
+++ b/install/share/csrgen/rules/dataHostCN.json
@@ -1,7 +1,7 @@
 {
   "rules": [
 {
-  "helper": "openssl",
+  "helper": ["openssl", "certmonger"],
   "template": "CN={{subject.krbprincipalname.0.partition('/')[2].partition('@')[0]}}"
 },
 {
diff --git a/install/share/csrgen/rules/dataSubjectBase.json b/install/share/csrgen/rules/dataSubjectBase.json
index 309d

[Freeipa-devel] [freeipa PR#433][synchronized] csrgen: Allow some certificate fields to be specified by the user

2017-03-06 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/433
Author: LiptonB
 Title: #433: csrgen: Allow some certificate fields to be specified by the user
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/433/head:pr433
git checkout pr433
From 3da67abcba6af0409a1195efd60581f6b28ad217 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Thu, 28 Jul 2016 16:21:44 -0400
Subject: [PATCH 1/3] csrgen: Implement fields that prompt user for data

Allows some data to be user-specified rather than coming out of the
database. The provided data can be formatted with jinja2 rules just as
database values can.

https://fedorahosted.org/freeipa/ticket/4899
---
 install/share/csrgen/Makefile.am   |  1 +
 .../share/csrgen/rules/dataEmailUserSpecified.json | 16 ++
 ipaclient/csrgen.py| 35 --
 ipaclient/plugins/csrgen.py|  9 --
 ipatests/test_ipaclient/test_csrgen.py | 15 +-
 5 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 install/share/csrgen/rules/dataEmailUserSpecified.json

diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
index 12c62c4..ad4412e 100644
--- a/install/share/csrgen/Makefile.am
+++ b/install/share/csrgen/Makefile.am
@@ -10,6 +10,7 @@ ruledir = $(IPA_DATA_DIR)/csrgen/rules
 rule_DATA =\
 	rules/dataDNS.json		\
 	rules/dataEmail.json		\
+	rules/dataEmailUserSpecified.json	\
 	rules/dataHostCN.json		\
 	rules/dataUsernameCN.json	\
 	rules/dataSubjectBase.json	\
diff --git a/install/share/csrgen/rules/dataEmailUserSpecified.json b/install/share/csrgen/rules/dataEmailUserSpecified.json
new file mode 100644
index 000..3fb2fb1
--- /dev/null
+++ b/install/share/csrgen/rules/dataEmailUserSpecified.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+{
+  "helper": "openssl",
+  "template": "email = {{userdata.email}}"
+},
+{
+  "helper": "certutil",
+  "template": "email:{{userdata.email|quote}}"
+}
+  ],
+  "options": {
+"data_source": "userdata.email",
+"prompt": "Email address"
+  }
+}
diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 96100ae..f00cc10 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -345,8 +345,9 @@ class CSRGenerator(object):
 def __init__(self, rule_provider):
 self.rule_provider = rule_provider
 
-def csr_script(self, principal, config, profile_id, helper):
-render_data = {'subject': principal, 'config': config}
+def csr_script(self, principal, config, userdata, profile_id, helper):
+render_data = {
+'subject': principal, 'config': config, 'userdata': userdata}
 
 formatter = self.FORMATTERS[helper]()
 rules = self.rule_provider.rules_for_profile(profile_id, helper)
@@ -360,3 +361,33 @@ def csr_script(self, principal, config, profile_id, helper):
 'Template error when formatting certificate data'))
 
 return script
+
+def get_user_prompts(self, profile_id, helper):
+prompts = {}
+rules = self.rule_provider.rules_for_profile(profile_id, helper)
+
+for field_mapping in rules:
+for rule in field_mapping.data_rules:
+if 'prompt' in rule.options:
+try:
+var = rule.options['data_source']
+except KeyError:
+raise errors.CSRTemplateError(reason=_(
+'Certificate mapping rule %(rule)s has a prompt'
+' but no data_source set') % {'rule': rule.name})
+if var in prompts:
+raise errors.CSRTemplateError(reason=_(
+'More than one data rule in this profile prompts'
+' for the %(item)s data item') % {'item': var})
+var_parts = var.split('.')
+if len(var_parts) != 2 or var_parts[0] != 'userdata':
+raise errors.CSRTemplateError(
+reason=_(
+'Format of variable name in rule %(rule)s is'
+' incorrect. Rules that prompt for data must'
+' use a variable "userdata."') %
+{'rule': rule.name})
+
+prompts[var_parts[1]] = rule.options['prompt']
+
+return prompts
diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py
index 0d6eca0..e8563e5 100644
--- a/ipaclient/plugins/csrgen.py
+++ b/ipaclient/plugins/csrgen.py
@@ -85,6 +85,9 @@ def execute(self, *args, **options):
 if not backend.isconnecte

[Freeipa-devel] [freeipa PR#537][comment] test_csrgen: adjusted comparison test scripts for CSRGenerator

2017-03-06 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/537
Title: #537: test_csrgen: adjusted comparison test scripts for CSRGenerator

LiptonB commented:
"""
Thanks for catching this, sorry about the breakage. The change looks good to me.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/537#issuecomment-284432624
-- 
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

[Freeipa-devel] [freeipa PR#534][comment] Move csrgen templates into ipaclient package

2017-03-06 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/534
Title: #534: Move csrgen templates into ipaclient package

LiptonB commented:
"""
I think this is a much better way to make it configurable than how I had it, 
and the implementation looks good to me. Thanks!
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/534#issuecomment-284427183
-- 
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

[Freeipa-devel] [freeipa PR#534][comment] Move csrgen templates into ipaclient package

2017-03-02 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/534
Title: #534: Move csrgen templates into ipaclient package

LiptonB commented:
"""
Oops, sorry about the breakage. This seems fine to me, although I hadn't really 
been thinking of the templates and rules as data files. They're intended to be 
possible to modify, more like config files. (Come to think of it, `/usr/share` 
wasn't that appropriate for them either). So, that and the fact that they're 
now duplicated between `python2.*/site-packages` and `python3.*/site-packages` 
give me pause (especially if the user might edit them), but I don't have strong 
feelings about it.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/534#issuecomment-283851563
-- 
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

[Freeipa-devel] [freeipa PR#434][comment] csrgen: Automate full cert request flow

2017-02-27 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/434
Title: #434: csrgen: Automate full cert request flow

LiptonB commented:
"""
@HonzaCholasta thanks, updated!
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/434#issuecomment-282931634
-- 
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

[Freeipa-devel] [freeipa PR#434][synchronized] csrgen: Automate full cert request flow

2017-02-27 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/434
Author: LiptonB
 Title: #434: csrgen: Automate full cert request flow
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/434/head:pr434
git checkout pr434
From 81be8bb7632a51fb8d886d192019329f56e1bc8d Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Mon, 22 Aug 2016 10:46:02 -0400
Subject: [PATCH 1/3] csrgen: Automate full cert request flow

Allows the `ipa cert-request` command to generate its own CSR. It no
longer requires a CSR passed on the command line, instead it creates a
config (bash script) with `cert-get-requestdata`, then runs it to build
a CSR, and submits that CSR.

Example usage (NSS database):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --database /tmp/certs

Example usage (PEM private key file):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --private-key /tmp/key.pem

https://fedorahosted.org/freeipa/ticket/4899
---
 ipaclient/plugins/cert.py   | 76 -
 ipaclient/plugins/csrgen.py |  5 ++-
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
index 1075972..5d712b5 100644
--- a/ipaclient/plugins/cert.py
+++ b/ipaclient/plugins/cert.py
@@ -19,6 +19,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import subprocess
+from tempfile import NamedTemporaryFile as NTF
+
+import six
+
 from ipaclient.frontend import MethodOverride
 from ipalib import errors
 from ipalib import x509
@@ -27,17 +32,86 @@
 from ipalib.plugable import Registry
 from ipalib.text import _
 
+if six.PY3:
+unicode = str
+
 register = Registry()
 
 
 @register(override=True, no_fail=True)
 class cert_request(MethodOverride):
+takes_options = (
+Str(
+'database?',
+label=_('Path to NSS database'),
+doc=_('Path to NSS database to use for private key'),
+),
+Str(
+'private_key?',
+label=_('Path to private key file'),
+doc=_('Path to PEM file containing a private key'),
+),
+)
+
 def get_args(self):
 for arg in super(cert_request, self).get_args():
 if arg.name == 'csr':
-arg = arg.clone_retype(arg.name, File)
+arg = arg.clone_retype(arg.name, File, required=False)
 yield arg
 
+def forward(self, csr=None, **options):
+database = options.pop('database', None)
+private_key = options.pop('private_key', None)
+
+if csr is None:
+if database:
+helper = u'certutil'
+helper_args = ['-d', database]
+elif private_key:
+helper = u'openssl'
+helper_args = [private_key]
+else:
+raise errors.InvocationError(
+message=u"One of 'database' or 'private_key' is required")
+
+with NTF() as scriptfile, NTF() as csrfile:
+profile_id = options.get('profile_id')
+
+self.api.Command.cert_get_requestdata(
+profile_id=profile_id,
+principal=options.get('principal'),
+out=unicode(scriptfile.name),
+helper=helper)
+
+helper_cmd = [
+'bash', '-e', scriptfile.name, csrfile.name] + helper_args
+
+try:
+subprocess.check_output(helper_cmd)
+except subprocess.CalledProcessError as e:
+raise errors.CertificateOperationError(
+error=(
+_('Error running "%(cmd)s" to generate CSR:'
+  ' %(err)s') %
+{'cmd': ' '.join(helper_cmd), 'err': e.output}))
+
+try:
+csr = unicode(csrfile.read())
+except IOError as e:
+raise errors.CertificateOperationError(
+error=(_('Unable to read generated CSR file: %(err)s')
+   % {'err': e}))
+if not csr:
+raise errors.CertificateOperationError(
+error=(_('Generated CSR was empty')))
+else:
+if database is not None or private_key is not None:
+raise errors.MutuallyExclusiveError(reason=_(
+"Options 'database' and 'private_key' are not compatible"
+" with 'csr'"))
+
+return super(cert_request, self).forward(csr, **options)
+
 
 @register(override=True, no_fail=True)
 class cert_show(MethodOverride):
diff --g

[Freeipa-devel] [freeipa PR#434][comment] csrgen: Automate full cert request flow

2017-02-09 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/434
Title: #434: csrgen: Automate full cert request flow

LiptonB commented:
"""
Thanks for the comments, and sorry about submitting this with lint errors. I 
think I've followed all of your suggestions, let me know what you think.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/434#issuecomment-278648710
-- 
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

[Freeipa-devel] [freeipa PR#434][synchronized] csrgen: Automate full cert request flow

2017-02-09 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/434
Author: LiptonB
 Title: #434: csrgen: Automate full cert request flow
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/434/head:pr434
git checkout pr434
From 5b4d2410d960084af766d44c112452604d0816c2 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Mon, 22 Aug 2016 10:46:02 -0400
Subject: [PATCH 1/4] csrgen: Automate full cert request flow

Allows the `ipa cert-request` command to generate its own CSR. It no
longer requires a CSR passed on the command line, instead it creates a
config (bash script) with `cert-get-requestdata`, then runs it to build
a CSR, and submits that CSR.

Example usage (NSS database):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --database /tmp/certs

Example usage (PEM private key file):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --private-key /tmp/key.pem

https://fedorahosted.org/freeipa/ticket/4899
---
 API.txt   |  2 +-
 ipaclient/plugins/cert.py | 83 ++-
 ipaserver/plugins/cert.py |  7 ++--
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index 543cec5..ac38514 100644
--- a/API.txt
+++ b/API.txt
@@ -788,7 +788,7 @@ option: Flag('add', autofill=True, default=False)
 option: Flag('all', autofill=True, cli_name='all', default=False)
 option: Str('cacn?', autofill=True, cli_name='ca', default=u'ipa')
 option: Principal('principal')
-option: Str('profile_id?')
+option: Str('profile_id', autofill=True, default=u'caIPAserviceCert')
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Str('request_type', autofill=True, default=u'pkcs10')
 option: Str('version?')
diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
index 1075972..339b1d0 100644
--- a/ipaclient/plugins/cert.py
+++ b/ipaclient/plugins/cert.py
@@ -19,6 +19,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import subprocess
+import tempfile
+
+import six
+
 from ipaclient.frontend import MethodOverride
 from ipalib import errors
 from ipalib import x509
@@ -27,17 +32,93 @@
 from ipalib.plugable import Registry
 from ipalib.text import _
 
+if six.PY3:
+unicode = str
+
 register = Registry()
 
 
 @register(override=True, no_fail=True)
 class cert_request(MethodOverride):
+takes_options = (
+Str(
+'database?',
+label=_('Path to NSS database'),
+doc=_('Path to NSS database to use for private key'),
+),
+Str(
+'private_key?',
+label=_('Path to private key file'),
+doc=_('Path to PEM file containing a private key'),
+),
+)
+
 def get_args(self):
 for arg in super(cert_request, self).get_args():
 if arg.name == 'csr':
-arg = arg.clone_retype(arg.name, File)
+arg = arg.clone_retype(arg.name, File, required=False)
 yield arg
 
+def forward(self, csr=None, **options):
+database = options.pop('database', None)
+private_key = options.pop('private_key', None)
+
+if csr is None:
+if database:
+helper = u'certutil'
+helper_args = ['-d', database]
+elif private_key:
+helper = u'openssl'
+helper_args = [private_key]
+else:
+raise errors.InvocationError(
+message=u"One of 'database' or 'private_key' is required")
+
+with tempfile.NamedTemporaryFile(
+) as scriptfile, tempfile.NamedTemporaryFile() as csrfile:
+# profile_id is optional for cert_request, but not for
+# cert_get_requestdata, so pass the default explicitly when
+# necessary
+profile_id = options.get('profile_id')
+if profile_id is None:
+profile_id = self.get_default_of('profile_id')
+
+self.api.Command.cert_get_requestdata(
+profile_id=profile_id,
+principal=options.get('principal'),
+out=unicode(scriptfile.name),
+helper=helper)
+
+helper_cmd = [
+'bash', '-e', scriptfile.name, csrfile.name] + helper_args
+
+try:
+subprocess.check_output(helper_cmd)
+except subprocess.CalledProcessError as e:
+raise errors.CertificateOperationError(
+error=(
+_('Error running "%(cmd)s" to generate CSR:'
+  ' %(err)s') %
+{'

[Freeipa-devel] [freeipa PR#433][comment] csrgen: Allow some certificate fields to be specified by the user

2017-02-09 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/433
Title: #433: csrgen: Allow some certificate fields to be specified by the user

LiptonB commented:
"""
Sorry for submitting this with lint errors - fixed now.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/433#issuecomment-278637593
-- 
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

[Freeipa-devel] [freeipa PR#433][synchronized] csrgen: Allow some certificate fields to be specified by the user

2017-02-08 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/433
Author: LiptonB
 Title: #433: csrgen: Allow some certificate fields to be specified by the user
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/433/head:pr433
git checkout pr433
From 96f4e25a4770bd2076390301adcee53d55086fa2 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Thu, 28 Jul 2016 16:21:44 -0400
Subject: [PATCH 1/5] csrgen: Implement fields that prompt user for data

Allows some data to be user-specified rather than coming out of the
database. The provided data can be formatted with jinja2 rules just as
database values can.

https://fedorahosted.org/freeipa/ticket/4899
---
 install/share/csrgen/Makefile.am   |  1 +
 .../share/csrgen/rules/dataEmailUserSpecified.json | 16 ++
 ipaclient/csrgen.py| 36 --
 ipaclient/plugins/csrgen.py|  9 --
 ipatests/test_ipaclient/test_csrgen.py | 15 -
 5 files changed, 66 insertions(+), 11 deletions(-)
 create mode 100644 install/share/csrgen/rules/dataEmailUserSpecified.json

diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
index 12c62c4..ad4412e 100644
--- a/install/share/csrgen/Makefile.am
+++ b/install/share/csrgen/Makefile.am
@@ -10,6 +10,7 @@ ruledir = $(IPA_DATA_DIR)/csrgen/rules
 rule_DATA =\
 	rules/dataDNS.json		\
 	rules/dataEmail.json		\
+	rules/dataEmailUserSpecified.json	\
 	rules/dataHostCN.json		\
 	rules/dataUsernameCN.json	\
 	rules/dataSubjectBase.json	\
diff --git a/install/share/csrgen/rules/dataEmailUserSpecified.json b/install/share/csrgen/rules/dataEmailUserSpecified.json
new file mode 100644
index 000..3fb2fb1
--- /dev/null
+++ b/install/share/csrgen/rules/dataEmailUserSpecified.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+{
+  "helper": "openssl",
+  "template": "email = {{userdata.email}}"
+},
+{
+  "helper": "certutil",
+  "template": "email:{{userdata.email|quote}}"
+}
+  ],
+  "options": {
+"data_source": "userdata.email",
+"prompt": "Email address"
+  }
+}
diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 96100ae..2c1c5fc 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -345,8 +345,9 @@ class CSRGenerator(object):
 def __init__(self, rule_provider):
 self.rule_provider = rule_provider
 
-def csr_script(self, principal, config, profile_id, helper):
-render_data = {'subject': principal, 'config': config}
+def csr_script(self, principal, config, userdata, profile_id, helper):
+render_data = {
+'subject': principal, 'config': config, 'userdata': userdata}
 
 formatter = self.FORMATTERS[helper]()
 rules = self.rule_provider.rules_for_profile(profile_id, helper)
@@ -360,3 +361,34 @@ def csr_script(self, principal, config, profile_id, helper):
 'Template error when formatting certificate data'))
 
 return script
+
+def get_user_prompts(self, profile_id, helper):
+prompts = {}
+syntax_rules = []
+rules = self.rule_provider.rules_for_profile(profile_id, helper)
+
+for field_mapping in rules:
+for rule in field_mapping.data_rules:
+if 'prompt' in rule.options:
+try:
+var = rule.options['data_source']
+except KeyError:
+raise errors.CertificateMappingError(reason=_(
+'Certificate mapping rule %(rule)s has a prompt'
+' but no data_source set') % {'rule': rule.name})
+if var in prompts:
+raise errors.CertificateMappingError(reason=_(
+'More than one data rule in this profile prompts'
+' for the %(item)s data item') % {'item': var})
+var_parts = var.split('.')
+if len(var_parts) != 2 or var_parts[0] != 'userdata':
+raise errors.CertificateMappingError(
+reason=_(
+'Format of variable name in rule %(rule)s is'
+' incorrect. Rules that prompt for data must'
+' use a variable "userdata."') %
+{'rule': rule.name})
+
+prompts[var_parts[1]] = rule.options['prompt']
+
+return prompts
diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py
index 0669a47..d480946 100644
--- a/ipaclient/plugins/csrgen.py
+++ b/ipaclient/plugins/csrgen.py
@@ -82,6 +82,9 @@ def execute(self, *args

[Freeipa-devel] [freeipa PR#434][synchronized] csrgen: Automate full cert request flow

2017-02-08 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/434
Author: LiptonB
 Title: #434: csrgen: Automate full cert request flow
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/434/head:pr434
git checkout pr434
From 5b4d2410d960084af766d44c112452604d0816c2 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Mon, 22 Aug 2016 10:46:02 -0400
Subject: [PATCH 1/3] csrgen: Automate full cert request flow

Allows the `ipa cert-request` command to generate its own CSR. It no
longer requires a CSR passed on the command line, instead it creates a
config (bash script) with `cert-get-requestdata`, then runs it to build
a CSR, and submits that CSR.

Example usage (NSS database):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --database /tmp/certs

Example usage (PEM private key file):
$ ipa cert-request --principal host/test.example.com --profile-id caIPAserviceCert --private-key /tmp/key.pem

https://fedorahosted.org/freeipa/ticket/4899
---
 API.txt   |  2 +-
 ipaclient/plugins/cert.py | 83 ++-
 ipaserver/plugins/cert.py |  7 ++--
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index 543cec5..ac38514 100644
--- a/API.txt
+++ b/API.txt
@@ -788,7 +788,7 @@ option: Flag('add', autofill=True, default=False)
 option: Flag('all', autofill=True, cli_name='all', default=False)
 option: Str('cacn?', autofill=True, cli_name='ca', default=u'ipa')
 option: Principal('principal')
-option: Str('profile_id?')
+option: Str('profile_id', autofill=True, default=u'caIPAserviceCert')
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Str('request_type', autofill=True, default=u'pkcs10')
 option: Str('version?')
diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
index 1075972..339b1d0 100644
--- a/ipaclient/plugins/cert.py
+++ b/ipaclient/plugins/cert.py
@@ -19,6 +19,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import subprocess
+import tempfile
+
+import six
+
 from ipaclient.frontend import MethodOverride
 from ipalib import errors
 from ipalib import x509
@@ -27,17 +32,93 @@
 from ipalib.plugable import Registry
 from ipalib.text import _
 
+if six.PY3:
+unicode = str
+
 register = Registry()
 
 
 @register(override=True, no_fail=True)
 class cert_request(MethodOverride):
+takes_options = (
+Str(
+'database?',
+label=_('Path to NSS database'),
+doc=_('Path to NSS database to use for private key'),
+),
+Str(
+'private_key?',
+label=_('Path to private key file'),
+doc=_('Path to PEM file containing a private key'),
+),
+)
+
 def get_args(self):
 for arg in super(cert_request, self).get_args():
 if arg.name == 'csr':
-arg = arg.clone_retype(arg.name, File)
+arg = arg.clone_retype(arg.name, File, required=False)
 yield arg
 
+def forward(self, csr=None, **options):
+database = options.pop('database', None)
+private_key = options.pop('private_key', None)
+
+if csr is None:
+if database:
+helper = u'certutil'
+helper_args = ['-d', database]
+elif private_key:
+helper = u'openssl'
+helper_args = [private_key]
+else:
+raise errors.InvocationError(
+message=u"One of 'database' or 'private_key' is required")
+
+with tempfile.NamedTemporaryFile(
+) as scriptfile, tempfile.NamedTemporaryFile() as csrfile:
+# profile_id is optional for cert_request, but not for
+# cert_get_requestdata, so pass the default explicitly when
+# necessary
+profile_id = options.get('profile_id')
+if profile_id is None:
+profile_id = self.get_default_of('profile_id')
+
+self.api.Command.cert_get_requestdata(
+profile_id=profile_id,
+principal=options.get('principal'),
+out=unicode(scriptfile.name),
+helper=helper)
+
+helper_cmd = [
+'bash', '-e', scriptfile.name, csrfile.name] + helper_args
+
+try:
+subprocess.check_output(helper_cmd)
+except subprocess.CalledProcessError as e:
+raise errors.CertificateOperationError(
+error=(
+_('Error running "%(cmd)s" to generate CSR:'
+  ' %(err)s') %
+{'

[Freeipa-devel] [freeipa PR#434][opened] csrgen: Automate full cert request flow

2017-02-04 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/434
Author: LiptonB
 Title: #434: csrgen: Automate full cert request flow
Action: opened

PR body:
"""
Adds `--autogenerate` flag to `ipa cert-request` command. It no longer
requires a CSR passed on the command line, instead it creates a config
(bash script) with `cert-get-requestdata`, then runs it to build a CSR,
and submits that CSR.

Example usage (NSS database):
$ ipa cert-request --autogenerate --principal blipton --profile-id userCert 
--database /tmp/certs

Example usage (PEM private key file):
$ ipa cert-request --autogenerate --principal blipton --profile-id userCert 
--private-key /tmp/key.pem
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/434/head:pr434
git checkout pr434
From 8660c571d93b20847d59a6c40f1764ffbda13e5f Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Mon, 22 Aug 2016 10:46:02 -0400
Subject: [PATCH 1/2] csrgen: Automate full cert request flow

Adds `--autogenerate` flag to `ipa cert-request` command. It no longer
requires a CSR passed on the command line, instead it creates a config
(bash script) with `cert-get-requestdata`, then runs it to build a CSR,
and submits that CSR.

Example usage (NSS database):
$ ipa cert-request --autogenerate --principal blipton --profile-id userCert --database /tmp/certs

Example usage (PEM private key file):
$ ipa cert-request --autogenerate --principal blipton --profile-id userCert --private-key /tmp/key.pem

https://fedorahosted.org/freeipa/ticket/4899
---
 API.txt   |  2 +-
 ipaclient/plugins/cert.py | 90 ++-
 ipaserver/plugins/cert.py |  7 ++--
 3 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index 543cec5..ac38514 100644
--- a/API.txt
+++ b/API.txt
@@ -788,7 +788,7 @@ option: Flag('add', autofill=True, default=False)
 option: Flag('all', autofill=True, cli_name='all', default=False)
 option: Str('cacn?', autofill=True, cli_name='ca', default=u'ipa')
 option: Principal('principal')
-option: Str('profile_id?')
+option: Str('profile_id', autofill=True, default=u'caIPAserviceCert')
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Str('request_type', autofill=True, default=u'pkcs10')
 option: Str('version?')
diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
index 1075972..bc29378 100644
--- a/ipaclient/plugins/cert.py
+++ b/ipaclient/plugins/cert.py
@@ -19,6 +19,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import os
+import subprocess
+import tempfile
+
 from ipaclient.frontend import MethodOverride
 from ipalib import errors
 from ipalib import x509
@@ -32,12 +36,96 @@
 
 @register(override=True, no_fail=True)
 class cert_request(MethodOverride):
+takes_options = (
+Str(
+'database?',
+label=_('Path to NSS database'),
+doc=_('Path to NSS database to use for private key'),
+),
+Str(
+'private_key?',
+label=_('Path to private key file'),
+doc=_('Path to PEM file containing a private key'),
+),
+Flag(
+'autogenerate',
+label=_('Automatically generate CSR for request using LDAP data'),
+)
+)
+
 def get_args(self):
 for arg in super(cert_request, self).get_args():
 if arg.name == 'csr':
-arg = arg.clone_retype(arg.name, File)
+arg = arg.clone_retype(arg.name, File, required=False)
 yield arg
 
+def forward(self, *keys, **options):
+autogenerate = options.pop('autogenerate', False)
+database = options.pop('database', None)
+private_key = options.pop('private_key', None)
+
+if autogenerate:
+if database:
+helper = u'certutil'
+helper_args = ['-d', database]
+elif private_key:
+helper = u'openssl'
+helper_args = [private_key]
+else:
+raise errors.InvocationError(
+format="One of 'database' or 'private_key' is required")
+
+scriptfile = tempfile.NamedTemporaryFile(delete=False)
+scriptfile.close()
+csrfile = tempfile.NamedTemporaryFile(delete=False)
+csrfile.close()
+csrfilename = csrfile.name
+
+# profile_id is optional for cert_request, but not for
+# cert_get_requestdata, so pass the default explicitly when
+# necessary
+profile_id = options.get('profile_id')
+if profile_id is None:
+profile_id = self.get_default_of('profile_id')
+
+requestdata = self.api.Command.cert_get

[Freeipa-devel] [freeipa PR#433][opened] csrgen: Allow some certificate fields to be specified by the user

2017-02-04 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/433
Author: LiptonB
 Title: #433: csrgen: Allow some certificate fields to be specified by the user
Action: opened

PR body:
"""
These patches allow CSR generation rules to contain a "prompt," which will 
cause data to be requested from the user and interpolated into the CSR.

The second commit runs the prompt through gettext. As I asked about 
[here](https://www.redhat.com/archives/freeipa-devel/2016-August/msg00823.html),
 I'm not sure if this is useful because the prompt strings in the rule files 
won't be recognized as translatable. But I decided to include the commit for 
discussion.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/433/head:pr433
git checkout pr433
From 96f4e25a4770bd2076390301adcee53d55086fa2 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Thu, 28 Jul 2016 16:21:44 -0400
Subject: [PATCH 1/3] csrgen: Implement fields that prompt user for data

Allows some data to be user-specified rather than coming out of the
database. The provided data can be formatted with jinja2 rules just as
database values can.

https://fedorahosted.org/freeipa/ticket/4899
---
 install/share/csrgen/Makefile.am   |  1 +
 .../share/csrgen/rules/dataEmailUserSpecified.json | 16 ++
 ipaclient/csrgen.py| 36 --
 ipaclient/plugins/csrgen.py|  9 --
 ipatests/test_ipaclient/test_csrgen.py | 15 -
 5 files changed, 66 insertions(+), 11 deletions(-)
 create mode 100644 install/share/csrgen/rules/dataEmailUserSpecified.json

diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am
index 12c62c4..ad4412e 100644
--- a/install/share/csrgen/Makefile.am
+++ b/install/share/csrgen/Makefile.am
@@ -10,6 +10,7 @@ ruledir = $(IPA_DATA_DIR)/csrgen/rules
 rule_DATA =\
 	rules/dataDNS.json		\
 	rules/dataEmail.json		\
+	rules/dataEmailUserSpecified.json	\
 	rules/dataHostCN.json		\
 	rules/dataUsernameCN.json	\
 	rules/dataSubjectBase.json	\
diff --git a/install/share/csrgen/rules/dataEmailUserSpecified.json b/install/share/csrgen/rules/dataEmailUserSpecified.json
new file mode 100644
index 000..3fb2fb1
--- /dev/null
+++ b/install/share/csrgen/rules/dataEmailUserSpecified.json
@@ -0,0 +1,16 @@
+{
+  "rules": [
+{
+  "helper": "openssl",
+  "template": "email = {{userdata.email}}"
+},
+{
+  "helper": "certutil",
+  "template": "email:{{userdata.email|quote}}"
+}
+  ],
+  "options": {
+"data_source": "userdata.email",
+"prompt": "Email address"
+  }
+}
diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py
index 96100ae..2c1c5fc 100644
--- a/ipaclient/csrgen.py
+++ b/ipaclient/csrgen.py
@@ -345,8 +345,9 @@ class CSRGenerator(object):
 def __init__(self, rule_provider):
 self.rule_provider = rule_provider
 
-def csr_script(self, principal, config, profile_id, helper):
-render_data = {'subject': principal, 'config': config}
+def csr_script(self, principal, config, userdata, profile_id, helper):
+render_data = {
+'subject': principal, 'config': config, 'userdata': userdata}
 
 formatter = self.FORMATTERS[helper]()
 rules = self.rule_provider.rules_for_profile(profile_id, helper)
@@ -360,3 +361,34 @@ def csr_script(self, principal, config, profile_id, helper):
 'Template error when formatting certificate data'))
 
 return script
+
+def get_user_prompts(self, profile_id, helper):
+prompts = {}
+syntax_rules = []
+rules = self.rule_provider.rules_for_profile(profile_id, helper)
+
+for field_mapping in rules:
+for rule in field_mapping.data_rules:
+if 'prompt' in rule.options:
+try:
+var = rule.options['data_source']
+except KeyError:
+raise errors.CertificateMappingError(reason=_(
+'Certificate mapping rule %(rule)s has a prompt'
+' but no data_source set') % {'rule': rule.name})
+if var in prompts:
+raise errors.CertificateMappingError(reason=_(
+'More than one data rule in this profile prompts'
+' for the %(item)s data item') % {'item': var})
+var_parts = var.split('.')
+if len(var_parts) != 2 or var_parts[0] != 'userdata':
+raise errors.CertificateMappingError(
+reason=_(
+'Format of variable name in rule %(rule)

[Freeipa-devel] [freeipa PR#337][comment] Client-side CSR autogeneration (take 2)

2017-01-30 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/337
Title: #337: Client-side CSR autogeneration (take 2)

LiptonB commented:
"""
@HonzaCholasta, updated, please take a look. I standardized on "CSR generation 
profile" because the names of the objects in the code and the directory that 
stores them are already "profiles," and because "template" is what the code 
calls the Jinja2 syntax that's built from the profile and the rules. But if you 
strongly prefer "template" to mean the collection of rules to use for 
generation I'm ok with changing it, I'd just want to change the code and 
filenames to be consistent as well.

Thanks for clarifying about the reference from `certprofile` to the CSR profile 
rather than the other way around. That seems fine to me too, especially if it's 
considered a default CSR profile rather than the only allowable one. Should I 
add that field to `certprofile` when I make the PR that adds `cert-request 
--autogenerate`?
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/337#issuecomment-276093846
-- 
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

[Freeipa-devel] [freeipa PR#337][synchronized] Client-side CSR autogeneration (take 2)

2017-01-30 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/337
Author: LiptonB
 Title: #337: Client-side CSR autogeneration (take 2)
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/337/head:pr337
git checkout pr337
From 43189fa00bbab51bac8d52a467397ab04cc88005 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/5] csrgen: Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 configure.ac   |   1 +
 freeipa.spec.in|  11 +
 install/share/Makefile.am  |   1 +
 install/share/csr/templates/ipa_macros.tmpl|  42 +++
 install/share/csrgen/Makefile.am   |  27 ++
 install/share/csrgen/templates/certutil_base.tmpl  |  14 +
 install/share/csrgen/templates/openssl_base.tmpl   |  35 +++
 install/share/csrgen/templates/openssl_macros.tmpl |  29 ++
 ipaclient/csrgen.py| 320 +
 ipaclient/plugins/csrgen.py| 114 
 ipaclient/setup.py |   1 +
 ipalib/errors.py   |  28 ++
 ipaplatform/base/paths.py  |   1 +
 13 files changed, 624 insertions(+)
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csrgen/Makefile.am
 create mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen.py
 create mode 100644 ipaclient/plugins/csrgen.py

diff --git a/configure.ac b/configure.ac
index 6cd3a89..ff5f7b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -533,6 +533,7 @@ 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/freeipa.spec.in b/freeipa.spec.in
index a7e05f3..ba2e294 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -153,6 +153,7 @@ BuildRequires:  python-sssdconfig
 BuildRequires:  python-nose
 BuildRequires:  python-paste
 BuildRequires:  systemd-python
+BuildRequires:  python2-jinja2
 
 %if 0%{?with_python3}
 # FIXME: this depedency is missing - server will not work
@@ -190,6 +191,7 @@ BuildRequires:  python3-libsss_nss_idmap
 BuildRequires:  python3-nose
 BuildRequires:  python3-paste
 BuildRequires:  python3-systemd
+BuildRequires:  python3-jinja2
 %endif # with_python3
 %endif # with_lint
 
@@ -489,6 +491,7 @@ Requires: %{name}-client-common = %{version}-%{release}
 Requires: %{name}-common = %{version}-%{release}
 Requires: python2-ipalib = %{version}-%{release}
 Requires: python-dns >= 1.15
+Requires: python2-jinja2
 
 %description -n python2-ipaclient
 IPA is an integrated solution to provide centrally managed Identity (users,
@@ -511,6 +514,7 @@ Requires: %{name}-client-common = %{version}-%{release}
 Requires: %{name}-common = %{version}-%{release}
 Requires: python3-ipalib = %{version}-%{release}
 Requires: python3-dns >= 1.15
+Requires: python3-jinja2
 
 %description -n python3-ipaclient
 IPA is an integrated solution to provide centrally managed Identity (users,
@@ -1217,6 +1221,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csrgen
+%dir %{_usr}/share/ipa/csrgen/templates
+%{_usr}/share/ipa/csrgen/templates/*.tmpl
+%dir %{_usr}/share/ipa/csrgen/profiles
+%{_usr}/share/ipa/csrgen/profiles/*.json
+%dir %{_usr}/share/ipa/csrgen/rules
+%{_usr}/share/ipa/csrgen/rules/*.json
 %dir %{_usr}/share/ipa/html
 %{_usr}/share/ipa/html/ffconfig.js
 %{_usr}/share/ipa/html/ffconfig_page.js
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 10de84d..715912d 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csrgen\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ b/install/share/csr/templates/ipa_macros.tmpl
@@ -0,0 +1,42 @@
+{% set rendersyntax = {} %}
+
+{% set renderdata = {} %}
+
+{# Wrapper for syntax rules. We render 

[Freeipa-devel] [freeipa PR#337][synchronized] Client-side CSR autogeneration (take 2)

2017-01-30 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/337
Author: LiptonB
 Title: #337: Client-side CSR autogeneration (take 2)
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/337/head:pr337
git checkout pr337
From 43189fa00bbab51bac8d52a467397ab04cc88005 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/5] csrgen: Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 configure.ac   |   1 +
 freeipa.spec.in|  11 +
 install/share/Makefile.am  |   1 +
 install/share/csr/templates/ipa_macros.tmpl|  42 +++
 install/share/csrgen/Makefile.am   |  27 ++
 install/share/csrgen/templates/certutil_base.tmpl  |  14 +
 install/share/csrgen/templates/openssl_base.tmpl   |  35 +++
 install/share/csrgen/templates/openssl_macros.tmpl |  29 ++
 ipaclient/csrgen.py| 320 +
 ipaclient/plugins/csrgen.py| 114 
 ipaclient/setup.py |   1 +
 ipalib/errors.py   |  28 ++
 ipaplatform/base/paths.py  |   1 +
 13 files changed, 624 insertions(+)
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csrgen/Makefile.am
 create mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen.py
 create mode 100644 ipaclient/plugins/csrgen.py

diff --git a/configure.ac b/configure.ac
index 6cd3a89..ff5f7b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -533,6 +533,7 @@ 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/freeipa.spec.in b/freeipa.spec.in
index a7e05f3..ba2e294 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -153,6 +153,7 @@ BuildRequires:  python-sssdconfig
 BuildRequires:  python-nose
 BuildRequires:  python-paste
 BuildRequires:  systemd-python
+BuildRequires:  python2-jinja2
 
 %if 0%{?with_python3}
 # FIXME: this depedency is missing - server will not work
@@ -190,6 +191,7 @@ BuildRequires:  python3-libsss_nss_idmap
 BuildRequires:  python3-nose
 BuildRequires:  python3-paste
 BuildRequires:  python3-systemd
+BuildRequires:  python3-jinja2
 %endif # with_python3
 %endif # with_lint
 
@@ -489,6 +491,7 @@ Requires: %{name}-client-common = %{version}-%{release}
 Requires: %{name}-common = %{version}-%{release}
 Requires: python2-ipalib = %{version}-%{release}
 Requires: python-dns >= 1.15
+Requires: python2-jinja2
 
 %description -n python2-ipaclient
 IPA is an integrated solution to provide centrally managed Identity (users,
@@ -511,6 +514,7 @@ Requires: %{name}-client-common = %{version}-%{release}
 Requires: %{name}-common = %{version}-%{release}
 Requires: python3-ipalib = %{version}-%{release}
 Requires: python3-dns >= 1.15
+Requires: python3-jinja2
 
 %description -n python3-ipaclient
 IPA is an integrated solution to provide centrally managed Identity (users,
@@ -1217,6 +1221,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csrgen
+%dir %{_usr}/share/ipa/csrgen/templates
+%{_usr}/share/ipa/csrgen/templates/*.tmpl
+%dir %{_usr}/share/ipa/csrgen/profiles
+%{_usr}/share/ipa/csrgen/profiles/*.json
+%dir %{_usr}/share/ipa/csrgen/rules
+%{_usr}/share/ipa/csrgen/rules/*.json
 %dir %{_usr}/share/ipa/html
 %{_usr}/share/ipa/html/ffconfig.js
 %{_usr}/share/ipa/html/ffconfig_page.js
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 10de84d..715912d 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csrgen\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ b/install/share/csr/templates/ipa_macros.tmpl
@@ -0,0 +1,42 @@
+{% set rendersyntax = {} %}
+
+{% set renderdata = {} %}
+
+{# Wrapper for syntax rules. We render 

[Freeipa-devel] [freeipa PR#337][synchronized] Client-side CSR autogeneration (take 2)

2017-01-24 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/337
Author: LiptonB
 Title: #337: Client-side CSR autogeneration (take 2)
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/337/head:pr337
git checkout pr337
From 4ead459036761600c43c414cb91a21c591ad906a Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/8] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 configure.ac   |   1 +
 freeipa.spec.in|   9 +
 install/share/Makefile.am  |   1 +
 install/share/csr/templates/ipa_macros.tmpl|  42 +++
 install/share/csrgen/Makefile.am   |  27 ++
 install/share/csrgen/templates/certutil_base.tmpl  |  14 +
 install/share/csrgen/templates/openssl_base.tmpl   |  35 +++
 install/share/csrgen/templates/openssl_macros.tmpl |  29 ++
 ipaclient/csrgen.py| 320 +
 ipaclient/plugins/csrgen.py| 116 
 ipalib/errors.py   |  28 ++
 ipaplatform/base/paths.py  |   1 +
 12 files changed, 623 insertions(+)
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csrgen/Makefile.am
 create mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen.py
 create mode 100644 ipaclient/plugins/csrgen.py

diff --git a/configure.ac b/configure.ac
index e8a4701..01fc81e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -530,6 +530,7 @@ 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/freeipa.spec.in b/freeipa.spec.in
index c4420a0..8396105 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -147,6 +147,7 @@ BuildRequires:  python-sssdconfig
 BuildRequires:  python-nose
 BuildRequires:  python-paste
 BuildRequires:  systemd-python
+BuildRequires:  python2-jinja2
 
 %if 0%{?with_python3}
 # FIXME: this depedency is missing - server will not work
@@ -602,6 +603,7 @@ Requires: python-dns >= 1.15
 Requires: python-enum34
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python2-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1208,6 +1210,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csrgen
+%dir %{_usr}/share/ipa/csrgen/templates
+%{_usr}/share/ipa/csrgen/templates/*.tmpl
+%dir %{_usr}/share/ipa/csrgen/profiles
+%{_usr}/share/ipa/csrgen/profiles/*.json
+%dir %{_usr}/share/ipa/csrgen/rules
+%{_usr}/share/ipa/csrgen/rules/*.json
 %dir %{_usr}/share/ipa/html
 %{_usr}/share/ipa/html/ffconfig.js
 %{_usr}/share/ipa/html/ffconfig_page.js
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 10de84d..715912d 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csrgen\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ b/install/share/csr/templates/ipa_macros.tmpl
@@ -0,0 +1,42 @@
+{% set rendersyntax = {} %}
+
+{% set renderdata = {} %}
+
+{# Wrapper for syntax rules. We render the contents of the rule into a
+variable, so that if we find that none of the contained data rules rendered we
+can suppress the whole syntax rule. That is, a syntax rule is rendered either
+if no data rules are specified (unusual) or if at least one of the data rules
+rendered successfully. #}
+{% macro syntaxrule() -%}
+{% do rendersyntax.update(none=true, any=false) -%}
+{% set contents -%}
+{{ caller() -}}
+{% endset -%}
+{% if rendersyntax['none'] or rendersyntax['any'] -%}
+{{ contents -}}
+{% endif -%}
+{% endmacro %}
+
+{# Wrapper for data rules. A data rule is rendered only when all of the data
+fields it contains have data available. #}
+{% macro datarule() -%}
+{% do rendersyntax.update(none=false) -%}
+{% do renderdata.update(all=true) -%}
+{% set contents

[Freeipa-devel] [freeipa PR#337][comment] Client-side CSR autogeneration (take 2)

2017-01-24 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/337
Title: #337: Client-side CSR autogeneration (take 2)

LiptonB commented:
"""
@HonzaCholasta, I think we're on the same page, then. I removed the dogtag 
profile and the validation from the `profile_id` parameter, and rebased the PR 
against master.

For the `cert-request --autogenerate` functionality, I will think about where 
in the CSR profile to store a link to the IPA profile to use.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/337#issuecomment-274837474
-- 
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

[Freeipa-devel] [freeipa PR#10][closed] Client-side CSR autogeneration

2017-01-24 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/10
Author: LiptonB
 Title: #10: Client-side CSR autogeneration
Action: closed

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10
-- 
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

[Freeipa-devel] [freeipa PR#337][comment] Client-side CSR autogeneration (take 2)

2017-01-23 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/337
Title: #337: Client-side CSR autogeneration (take 2)

LiptonB commented:
"""
@HonzaCholasta, I think I see what you mean about these templates not being 
dependent on dogtag, and I'm fine with removing the `userCert` dogtag profile 
from this PR if you don't think it's relevant. Is it ok to leave the `userCert` 
CSR generation profile, as an example of what the tool can do?

So, do you mean we should no longer consider CSR generation profiles to be 
associated with IPA profiles? In 
https://github.com/LiptonB/freeipa/tree/local-cert-build I have code that 
allows you to run `ipa cert-request --autogenerate --principal someserver 
--profile-id caIPAserviceCert` and get a cert for the server back in one step. 
It uses the `caIPAserviceCert` CSR profile to make a CSR that works with the 
`caIPAserviceCert` IPA profile. So it seems to me that having the profiles 
linked makes the cert generation experience simpler, and that was the original 
way this feature was proposed to me. But, if you'd rather have them not be 
linked, should I modify this command so the CSR profile is specified with a 
separate flag from the IPA one?
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/337#issuecomment-274712673
-- 
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

[Freeipa-devel] [freeipa PR#337][comment] Client-side CSR autogeneration (take 2)

2017-01-18 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/337
Title: #337: Client-side CSR autogeneration (take 2)

LiptonB commented:
"""
@tiran Thanks to the team for resuming the review, too! Added the dependency, 
does that look right?
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/337#issuecomment-273658159
-- 
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

[Freeipa-devel] [freeipa PR#337][synchronized] Client-side CSR autogeneration (take 2)

2017-01-18 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/337
Author: LiptonB
 Title: #337: Client-side CSR autogeneration (take 2)
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/337/head:pr337
git checkout pr337
From 4ead459036761600c43c414cb91a21c591ad906a Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/8] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 configure.ac   |   1 +
 freeipa.spec.in|   9 +
 install/share/Makefile.am  |   1 +
 install/share/csr/templates/ipa_macros.tmpl|  42 +++
 install/share/csrgen/Makefile.am   |  27 ++
 install/share/csrgen/templates/certutil_base.tmpl  |  14 +
 install/share/csrgen/templates/openssl_base.tmpl   |  35 +++
 install/share/csrgen/templates/openssl_macros.tmpl |  29 ++
 ipaclient/csrgen.py| 320 +
 ipaclient/plugins/csrgen.py| 116 
 ipalib/errors.py   |  28 ++
 ipaplatform/base/paths.py  |   1 +
 12 files changed, 623 insertions(+)
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csrgen/Makefile.am
 create mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen.py
 create mode 100644 ipaclient/plugins/csrgen.py

diff --git a/configure.ac b/configure.ac
index e8a4701..01fc81e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -530,6 +530,7 @@ 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/freeipa.spec.in b/freeipa.spec.in
index c4420a0..8396105 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -147,6 +147,7 @@ BuildRequires:  python-sssdconfig
 BuildRequires:  python-nose
 BuildRequires:  python-paste
 BuildRequires:  systemd-python
+BuildRequires:  python2-jinja2
 
 %if 0%{?with_python3}
 # FIXME: this depedency is missing - server will not work
@@ -602,6 +603,7 @@ Requires: python-dns >= 1.15
 Requires: python-enum34
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python2-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1208,6 +1210,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csrgen
+%dir %{_usr}/share/ipa/csrgen/templates
+%{_usr}/share/ipa/csrgen/templates/*.tmpl
+%dir %{_usr}/share/ipa/csrgen/profiles
+%{_usr}/share/ipa/csrgen/profiles/*.json
+%dir %{_usr}/share/ipa/csrgen/rules
+%{_usr}/share/ipa/csrgen/rules/*.json
 %dir %{_usr}/share/ipa/html
 %{_usr}/share/ipa/html/ffconfig.js
 %{_usr}/share/ipa/html/ffconfig_page.js
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 10de84d..715912d 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csrgen\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ b/install/share/csr/templates/ipa_macros.tmpl
@@ -0,0 +1,42 @@
+{% set rendersyntax = {} %}
+
+{% set renderdata = {} %}
+
+{# Wrapper for syntax rules. We render the contents of the rule into a
+variable, so that if we find that none of the contained data rules rendered we
+can suppress the whole syntax rule. That is, a syntax rule is rendered either
+if no data rules are specified (unusual) or if at least one of the data rules
+rendered successfully. #}
+{% macro syntaxrule() -%}
+{% do rendersyntax.update(none=true, any=false) -%}
+{% set contents -%}
+{{ caller() -}}
+{% endset -%}
+{% if rendersyntax['none'] or rendersyntax['any'] -%}
+{{ contents -}}
+{% endif -%}
+{% endmacro %}
+
+{# Wrapper for data rules. A data rule is rendered only when all of the data
+fields it contains have data available. #}
+{% macro datarule() -%}
+{% do rendersyntax.update(none=false) -%}
+{% do renderdata.update(all=true) -%}
+{% set contents

[Freeipa-devel] [freeipa PR#337][synchronized] Client-side CSR autogeneration (take 2)

2017-01-17 Thread LiptonB
   URL: https://github.com/freeipa/freeipa/pull/337
Author: LiptonB
 Title: #337: Client-side CSR autogeneration (take 2)
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/337/head:pr337
git checkout pr337
From 4ead459036761600c43c414cb91a21c591ad906a Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/7] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 configure.ac   |   1 +
 freeipa.spec.in|   9 +
 install/share/Makefile.am  |   1 +
 install/share/csr/templates/ipa_macros.tmpl|  42 +++
 install/share/csrgen/Makefile.am   |  27 ++
 install/share/csrgen/templates/certutil_base.tmpl  |  14 +
 install/share/csrgen/templates/openssl_base.tmpl   |  35 +++
 install/share/csrgen/templates/openssl_macros.tmpl |  29 ++
 ipaclient/csrgen.py| 320 +
 ipaclient/plugins/csrgen.py| 116 
 ipalib/errors.py   |  28 ++
 ipaplatform/base/paths.py  |   1 +
 12 files changed, 623 insertions(+)
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csrgen/Makefile.am
 create mode 100644 install/share/csrgen/templates/certutil_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_base.tmpl
 create mode 100644 install/share/csrgen/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/csrgen.py
 create mode 100644 ipaclient/plugins/csrgen.py

diff --git a/configure.ac b/configure.ac
index e8a4701..01fc81e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -530,6 +530,7 @@ 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/freeipa.spec.in b/freeipa.spec.in
index c4420a0..8396105 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -147,6 +147,7 @@ BuildRequires:  python-sssdconfig
 BuildRequires:  python-nose
 BuildRequires:  python-paste
 BuildRequires:  systemd-python
+BuildRequires:  python2-jinja2
 
 %if 0%{?with_python3}
 # FIXME: this depedency is missing - server will not work
@@ -602,6 +603,7 @@ Requires: python-dns >= 1.15
 Requires: python-enum34
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python2-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1208,6 +1210,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csrgen
+%dir %{_usr}/share/ipa/csrgen/templates
+%{_usr}/share/ipa/csrgen/templates/*.tmpl
+%dir %{_usr}/share/ipa/csrgen/profiles
+%{_usr}/share/ipa/csrgen/profiles/*.json
+%dir %{_usr}/share/ipa/csrgen/rules
+%{_usr}/share/ipa/csrgen/rules/*.json
 %dir %{_usr}/share/ipa/html
 %{_usr}/share/ipa/html/ffconfig.js
 %{_usr}/share/ipa/html/ffconfig_page.js
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 10de84d..715912d 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csrgen\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ b/install/share/csr/templates/ipa_macros.tmpl
@@ -0,0 +1,42 @@
+{% set rendersyntax = {} %}
+
+{% set renderdata = {} %}
+
+{# Wrapper for syntax rules. We render the contents of the rule into a
+variable, so that if we find that none of the contained data rules rendered we
+can suppress the whole syntax rule. That is, a syntax rule is rendered either
+if no data rules are specified (unusual) or if at least one of the data rules
+rendered successfully. #}
+{% macro syntaxrule() -%}
+{% do rendersyntax.update(none=true, any=false) -%}
+{% set contents -%}
+{{ caller() -}}
+{% endset -%}
+{% if rendersyntax['none'] or rendersyntax['any'] -%}
+{{ contents -}}
+{% endif -%}
+{% endmacro %}
+
+{# Wrapper for data rules. A data rule is rendered only when all of the data
+fields it contains have data available. #}
+{% macro datarule() -%}
+{% do rendersyntax.update(none=false) -%}
+{% do renderdata.update(all=true) -%}
+{% set contents

[Freeipa-devel] [freeipa PR#10][comment] Client-side CSR autogeneration

2016-10-20 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/10
Title: #10: Client-side CSR autogeneration

LiptonB commented:
"""
Updated to fix conflicts with master again. I'm not sure what's up with Travis, 
it seems to be checking out PR #109 instead of this one for the pep8 check:

```
$ cd freeipa/freeipa
$ git fetch origin +refs/pull/109/merge:
remote: Counting objects: 78053, done.
remote: Compressing objects: 100% (14671/14671), done.
remote: Total 78053 (delta 64375), reused 76890 (delta 63219), pack-reused 0
Receiving objects: 100% (78053/78053), 28.18 MiB | 18.03 MiB/s, done.
Resolving deltas: 100% (64375/64375), completed with 841 local objects.
From https://github.com/freeipa/freeipa
 * branchrefs/pull/109/merge -> FETCH_HEAD
$ git checkout -qf FETCH_HEAD
```
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-255217025
-- 
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

[Freeipa-devel] [freeipa PR#10][comment] Client-side CSR autogeneration

2016-10-10 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/10
Title: #10: Client-side CSR autogeneration

LiptonB commented:
"""
Thanks, I've updated the code based on your comments (force pushed to fix 
conflicts with master). And thanks for pointing out that email! I don't know 
how I missed it, but I will respond shortly.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-252676408
-- 
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

[Freeipa-devel] [freeipa PR#10][comment] Client-side CSR autogeneration

2016-10-03 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/10
Title: #10: Client-side CSR autogeneration

LiptonB commented:
"""
@jcholast, when you get a chance, could you take another look at this and let 
me know what else is needed?
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-251130680
-- 
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

[Freeipa-devel] [freeipa PR#10][comment] Client-side CSR autogeneration

2016-09-19 Thread LiptonB
  URL: https://github.com/freeipa/freeipa/pull/10
Title: #10: Client-side CSR autogeneration

LiptonB commented:
"""
`csrgen` sounds good to me. The new modules have now been moved to 
`ipaclient.plugins.csrgen`, `ipaclient.csrgen`, and 
`ipatests.test_ipaclient.test_csrgen`.

FYI: I force pushed a few minutes after adding these commits to fix a pep8 
error.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-247984688
-- 
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

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronized)

2016-09-15 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronized

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10
From eeeb57fa9ff1642dbd1e32fbfe435052de2541ee Mon Sep 17 00:00:00 2001
From: Ben Lipton 
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 01/11] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 freeipa.spec.in |   8 +
 install/configure.ac|   1 +
 install/share/Makefile.am   |   1 +
 install/share/csr/Makefile.am   |  27 +++
 install/share/csr/templates/certutil_base.tmpl  |  14 ++
 install/share/csr/templates/ipa_macros.tmpl |  42 
 install/share/csr/templates/openssl_base.tmpl   |  35 +++
 install/share/csr/templates/openssl_macros.tmpl |  29 +++
 ipaclient/plugins/certmapping.py| 105 +
 ipalib/certmapping.py   | 285 
 ipalib/errors.py|   9 +
 ipapython/templating.py |  31 +++
 12 files changed, 587 insertions(+)
 create mode 100644 install/share/csr/Makefile.am
 create mode 100644 install/share/csr/templates/certutil_base.tmpl
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csr/templates/openssl_base.tmpl
 create mode 100644 install/share/csr/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/plugins/certmapping.py
 create mode 100644 ipalib/certmapping.py
 create mode 100644 ipapython/templating.py

diff --git a/freeipa.spec.in b/freeipa.spec.in
index e3ad5b6..ab8e8e6 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -507,6 +507,7 @@ Requires: python-custodia
 Requires: python-dns >= 1.11.1
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1178,6 +1179,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csr
+%dir %{_usr}/share/ipa/csr/templates
+%{_usr}/share/ipa/csr/templates/*.tmpl
+%dir %{_usr}/share/ipa/csr/profiles
+%{_usr}/share/ipa/csr/profiles/*.json
+%dir %{_usr}/share/ipa/csr/rules
+%{_usr}/share/ipa/csr/rules/*.json
 %dir %{_usr}/share/ipa/ffextension
 %{_usr}/share/ipa/ffextension/bootstrap.js
 %{_usr}/share/ipa/ffextension/install.rdf
diff --git a/install/configure.ac b/install/configure.ac
index 81f17b9..365f0e9 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -87,6 +87,7 @@ AC_CONFIG_FILES([
 share/Makefile
 share/advise/Makefile
 share/advise/legacy/Makefile
+share/csr/Makefile
 share/profiles/Makefile
 share/schema.d/Makefile
 ui/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index d8845ee..0a15635 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csr\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/Makefile.am b/install/share/csr/Makefile.am
new file mode 100644
index 000..5a8ef5c
--- /dev/null
+++ b/install/share/csr/Makefile.am
@@ -0,0 +1,27 @@
+NULL =
+
+profiledir = $(IPA_DATA_DIR)/csr/profiles
+profile_DATA =\
+	$(NULL)
+
+ruledir = $(IPA_DATA_DIR)/csr/rules
+rule_DATA =\
+	$(NULL)
+
+templatedir = $(IPA_DATA_DIR)/csr/templates
+template_DATA =			\
+	templates/certutil_base.tmpl	\
+	templates/openssl_base.tmpl	\
+	templates/openssl_macros.tmpl	\
+	templates/ipa_macros.tmpl	\
+	$(NULL)
+
+EXTRA_DIST =\
+	$(profile_DATA)			\
+	$(rule_DATA)			\
+	$(template_DATA)		\
+	$(NULL)
+
+MAINTAINERCLEANFILES =			\
+	*~\
+	Makefile.in
diff --git a/install/share/csr/templates/certutil_base.tmpl b/install/share/csr/templates/certutil_base.tmpl
new file mode 100644
index 000..6c6425f
--- /dev/null
+++ b/install/share/csr/templates/certutil_base.tmpl
@@ -0,0 +1,14 @@
+{% raw -%}
+{% import "ipa_macros.tmpl" as ipa -%}
+{%- endraw %}
+#!/bin/bash -e
+
+if [[ $# -lt 1 ]]; then
+echo "Usage: $0  [  ]"
+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/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ 

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronize)

2016-09-14 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronize

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10
From eeeb57fa9ff1642dbd1e32fbfe435052de2541ee Mon Sep 17 00:00:00 2001
From: Ben Lipton 
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 01/10] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 freeipa.spec.in |   8 +
 install/configure.ac|   1 +
 install/share/Makefile.am   |   1 +
 install/share/csr/Makefile.am   |  27 +++
 install/share/csr/templates/certutil_base.tmpl  |  14 ++
 install/share/csr/templates/ipa_macros.tmpl |  42 
 install/share/csr/templates/openssl_base.tmpl   |  35 +++
 install/share/csr/templates/openssl_macros.tmpl |  29 +++
 ipaclient/plugins/certmapping.py| 105 +
 ipalib/certmapping.py   | 285 
 ipalib/errors.py|   9 +
 ipapython/templating.py |  31 +++
 12 files changed, 587 insertions(+)
 create mode 100644 install/share/csr/Makefile.am
 create mode 100644 install/share/csr/templates/certutil_base.tmpl
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csr/templates/openssl_base.tmpl
 create mode 100644 install/share/csr/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/plugins/certmapping.py
 create mode 100644 ipalib/certmapping.py
 create mode 100644 ipapython/templating.py

diff --git a/freeipa.spec.in b/freeipa.spec.in
index e3ad5b6..ab8e8e6 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -507,6 +507,7 @@ Requires: python-custodia
 Requires: python-dns >= 1.11.1
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1178,6 +1179,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csr
+%dir %{_usr}/share/ipa/csr/templates
+%{_usr}/share/ipa/csr/templates/*.tmpl
+%dir %{_usr}/share/ipa/csr/profiles
+%{_usr}/share/ipa/csr/profiles/*.json
+%dir %{_usr}/share/ipa/csr/rules
+%{_usr}/share/ipa/csr/rules/*.json
 %dir %{_usr}/share/ipa/ffextension
 %{_usr}/share/ipa/ffextension/bootstrap.js
 %{_usr}/share/ipa/ffextension/install.rdf
diff --git a/install/configure.ac b/install/configure.ac
index 81f17b9..365f0e9 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -87,6 +87,7 @@ AC_CONFIG_FILES([
 share/Makefile
 share/advise/Makefile
 share/advise/legacy/Makefile
+share/csr/Makefile
 share/profiles/Makefile
 share/schema.d/Makefile
 ui/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index d8845ee..0a15635 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csr\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/Makefile.am b/install/share/csr/Makefile.am
new file mode 100644
index 000..5a8ef5c
--- /dev/null
+++ b/install/share/csr/Makefile.am
@@ -0,0 +1,27 @@
+NULL =
+
+profiledir = $(IPA_DATA_DIR)/csr/profiles
+profile_DATA =\
+	$(NULL)
+
+ruledir = $(IPA_DATA_DIR)/csr/rules
+rule_DATA =\
+	$(NULL)
+
+templatedir = $(IPA_DATA_DIR)/csr/templates
+template_DATA =			\
+	templates/certutil_base.tmpl	\
+	templates/openssl_base.tmpl	\
+	templates/openssl_macros.tmpl	\
+	templates/ipa_macros.tmpl	\
+	$(NULL)
+
+EXTRA_DIST =\
+	$(profile_DATA)			\
+	$(rule_DATA)			\
+	$(template_DATA)		\
+	$(NULL)
+
+MAINTAINERCLEANFILES =			\
+	*~\
+	Makefile.in
diff --git a/install/share/csr/templates/certutil_base.tmpl b/install/share/csr/templates/certutil_base.tmpl
new file mode 100644
index 000..6c6425f
--- /dev/null
+++ b/install/share/csr/templates/certutil_base.tmpl
@@ -0,0 +1,14 @@
+{% raw -%}
+{% import "ipa_macros.tmpl" as ipa -%}
+{%- endraw %}
+#!/bin/bash -e
+
+if [[ $# -lt 1 ]]; then
+echo "Usage: $0  [  ]"
+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/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ 

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronize)

2016-09-07 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronize

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10
From eeeb57fa9ff1642dbd1e32fbfe435052de2541ee Mon Sep 17 00:00:00 2001
From: Ben Lipton 
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/8] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 freeipa.spec.in |   8 +
 install/configure.ac|   1 +
 install/share/Makefile.am   |   1 +
 install/share/csr/Makefile.am   |  27 +++
 install/share/csr/templates/certutil_base.tmpl  |  14 ++
 install/share/csr/templates/ipa_macros.tmpl |  42 
 install/share/csr/templates/openssl_base.tmpl   |  35 +++
 install/share/csr/templates/openssl_macros.tmpl |  29 +++
 ipaclient/plugins/certmapping.py| 105 +
 ipalib/certmapping.py   | 285 
 ipalib/errors.py|   9 +
 ipapython/templating.py |  31 +++
 12 files changed, 587 insertions(+)
 create mode 100644 install/share/csr/Makefile.am
 create mode 100644 install/share/csr/templates/certutil_base.tmpl
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csr/templates/openssl_base.tmpl
 create mode 100644 install/share/csr/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/plugins/certmapping.py
 create mode 100644 ipalib/certmapping.py
 create mode 100644 ipapython/templating.py

diff --git a/freeipa.spec.in b/freeipa.spec.in
index e3ad5b6..ab8e8e6 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -507,6 +507,7 @@ Requires: python-custodia
 Requires: python-dns >= 1.11.1
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1178,6 +1179,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csr
+%dir %{_usr}/share/ipa/csr/templates
+%{_usr}/share/ipa/csr/templates/*.tmpl
+%dir %{_usr}/share/ipa/csr/profiles
+%{_usr}/share/ipa/csr/profiles/*.json
+%dir %{_usr}/share/ipa/csr/rules
+%{_usr}/share/ipa/csr/rules/*.json
 %dir %{_usr}/share/ipa/ffextension
 %{_usr}/share/ipa/ffextension/bootstrap.js
 %{_usr}/share/ipa/ffextension/install.rdf
diff --git a/install/configure.ac b/install/configure.ac
index 81f17b9..365f0e9 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -87,6 +87,7 @@ AC_CONFIG_FILES([
 share/Makefile
 share/advise/Makefile
 share/advise/legacy/Makefile
+share/csr/Makefile
 share/profiles/Makefile
 share/schema.d/Makefile
 ui/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index d8845ee..0a15635 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csr\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/Makefile.am b/install/share/csr/Makefile.am
new file mode 100644
index 000..5a8ef5c
--- /dev/null
+++ b/install/share/csr/Makefile.am
@@ -0,0 +1,27 @@
+NULL =
+
+profiledir = $(IPA_DATA_DIR)/csr/profiles
+profile_DATA =\
+	$(NULL)
+
+ruledir = $(IPA_DATA_DIR)/csr/rules
+rule_DATA =\
+	$(NULL)
+
+templatedir = $(IPA_DATA_DIR)/csr/templates
+template_DATA =			\
+	templates/certutil_base.tmpl	\
+	templates/openssl_base.tmpl	\
+	templates/openssl_macros.tmpl	\
+	templates/ipa_macros.tmpl	\
+	$(NULL)
+
+EXTRA_DIST =\
+	$(profile_DATA)			\
+	$(rule_DATA)			\
+	$(template_DATA)		\
+	$(NULL)
+
+MAINTAINERCLEANFILES =			\
+	*~\
+	Makefile.in
diff --git a/install/share/csr/templates/certutil_base.tmpl b/install/share/csr/templates/certutil_base.tmpl
new file mode 100644
index 000..6c6425f
--- /dev/null
+++ b/install/share/csr/templates/certutil_base.tmpl
@@ -0,0 +1,14 @@
+{% raw -%}
+{% import "ipa_macros.tmpl" as ipa -%}
+{%- endraw %}
+#!/bin/bash -e
+
+if [[ $# -lt 1 ]]; then
+echo "Usage: $0  [  ]"
+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/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ 

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (comment)

2016-09-06 Thread LiptonB
LiptonB commented on a pull request

"""
I've added a commit (Use data_sources option to define which fields are 
rendered) that simplifies the way we avoid rendering rules whose source data 
are missing, as discussed here: 
https://www.redhat.com/archives/freeipa-devel/2016-September/msg00051.html. I 
prefer this approach to the macros in the original implementation, but I'm 
leaving it as a separate commit in case you would like to compare them.
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-245096157
-- 
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

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronize)

2016-09-06 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronize

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10
From eeeb57fa9ff1642dbd1e32fbfe435052de2541ee Mon Sep 17 00:00:00 2001
From: Ben Lipton 
Date: Tue, 5 Jul 2016 14:19:35 -0400
Subject: [PATCH 1/6] Add code to generate scripts that generate CSRs

Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.

https://fedorahosted.org/freeipa/ticket/4899
---
 freeipa.spec.in |   8 +
 install/configure.ac|   1 +
 install/share/Makefile.am   |   1 +
 install/share/csr/Makefile.am   |  27 +++
 install/share/csr/templates/certutil_base.tmpl  |  14 ++
 install/share/csr/templates/ipa_macros.tmpl |  42 
 install/share/csr/templates/openssl_base.tmpl   |  35 +++
 install/share/csr/templates/openssl_macros.tmpl |  29 +++
 ipaclient/plugins/certmapping.py| 105 +
 ipalib/certmapping.py   | 285 
 ipalib/errors.py|   9 +
 ipapython/templating.py |  31 +++
 12 files changed, 587 insertions(+)
 create mode 100644 install/share/csr/Makefile.am
 create mode 100644 install/share/csr/templates/certutil_base.tmpl
 create mode 100644 install/share/csr/templates/ipa_macros.tmpl
 create mode 100644 install/share/csr/templates/openssl_base.tmpl
 create mode 100644 install/share/csr/templates/openssl_macros.tmpl
 create mode 100644 ipaclient/plugins/certmapping.py
 create mode 100644 ipalib/certmapping.py
 create mode 100644 ipapython/templating.py

diff --git a/freeipa.spec.in b/freeipa.spec.in
index e3ad5b6..ab8e8e6 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -507,6 +507,7 @@ Requires: python-custodia
 Requires: python-dns >= 1.11.1
 Requires: python-netifaces >= 0.10.4
 Requires: pyusb
+Requires: python-jinja2
 
 Conflicts: %{alt_name}-python < %{version}
 
@@ -1178,6 +1179,13 @@ fi
 %{_usr}/share/ipa/advise/legacy/*.template
 %dir %{_usr}/share/ipa/profiles
 %{_usr}/share/ipa/profiles/*.cfg
+%dir %{_usr}/share/ipa/csr
+%dir %{_usr}/share/ipa/csr/templates
+%{_usr}/share/ipa/csr/templates/*.tmpl
+%dir %{_usr}/share/ipa/csr/profiles
+%{_usr}/share/ipa/csr/profiles/*.json
+%dir %{_usr}/share/ipa/csr/rules
+%{_usr}/share/ipa/csr/rules/*.json
 %dir %{_usr}/share/ipa/ffextension
 %{_usr}/share/ipa/ffextension/bootstrap.js
 %{_usr}/share/ipa/ffextension/install.rdf
diff --git a/install/configure.ac b/install/configure.ac
index 81f17b9..365f0e9 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -87,6 +87,7 @@ AC_CONFIG_FILES([
 share/Makefile
 share/advise/Makefile
 share/advise/legacy/Makefile
+share/csr/Makefile
 share/profiles/Makefile
 share/schema.d/Makefile
 ui/Makefile
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index d8845ee..0a15635 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 SUBDIRS =  \
 	advise\
+	csr\
 	profiles			\
 	schema.d			\
 	$(NULL)
diff --git a/install/share/csr/Makefile.am b/install/share/csr/Makefile.am
new file mode 100644
index 000..5a8ef5c
--- /dev/null
+++ b/install/share/csr/Makefile.am
@@ -0,0 +1,27 @@
+NULL =
+
+profiledir = $(IPA_DATA_DIR)/csr/profiles
+profile_DATA =\
+	$(NULL)
+
+ruledir = $(IPA_DATA_DIR)/csr/rules
+rule_DATA =\
+	$(NULL)
+
+templatedir = $(IPA_DATA_DIR)/csr/templates
+template_DATA =			\
+	templates/certutil_base.tmpl	\
+	templates/openssl_base.tmpl	\
+	templates/openssl_macros.tmpl	\
+	templates/ipa_macros.tmpl	\
+	$(NULL)
+
+EXTRA_DIST =\
+	$(profile_DATA)			\
+	$(rule_DATA)			\
+	$(template_DATA)		\
+	$(NULL)
+
+MAINTAINERCLEANFILES =			\
+	*~\
+	Makefile.in
diff --git a/install/share/csr/templates/certutil_base.tmpl b/install/share/csr/templates/certutil_base.tmpl
new file mode 100644
index 000..6c6425f
--- /dev/null
+++ b/install/share/csr/templates/certutil_base.tmpl
@@ -0,0 +1,14 @@
+{% raw -%}
+{% import "ipa_macros.tmpl" as ipa -%}
+{%- endraw %}
+#!/bin/bash -e
+
+if [[ $# -lt 1 ]]; then
+echo "Usage: $0  [  ]"
+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/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl
new file mode 100644
index 000..e790d4e
--- /dev/null
+++ 

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (comment)

2016-08-31 Thread LiptonB
LiptonB commented on a pull request

"""
As discussed elsewhere, this script generation is a fairly low-level operation; 
you have to specify the helper and know how to run the script. Most users will 
probably want a command that just takes in a private key location and a profile 
and requests the cert for them. In case you'd like to look at it now, I have an 
implementation of that in a separate branch, which I'll create a pull request 
for after this one is complete: 
https://github.com/freeipa/freeipa/compare/master...LiptonB:local-cert-build
"""

See the full comment at 
https://github.com/freeipa/freeipa/pull/10#issuecomment-243811501
-- 
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

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronize)

2016-08-26 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronize

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10


freeipa-pr-10.patch
Description: application/text/diff
-- 
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

[Freeipa-devel] [freeipa PR#10] Client-side CSR autogeneration (synchronize)

2016-08-26 Thread LiptonB
LiptonB's pull request #10: "Client-side CSR autogeneration" was synchronize

See the full pull-request at https://github.com/freeipa/freeipa/pull/10
... or pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/10/head:pr10
git checkout pr10


freeipa-pr-10.patch
Description: application/text/diff
-- 
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