URL: https://github.com/freeipa/freeipa/pull/112 Author: martbab Title: #112: The first jab at fixing https://fedorahosted.org/freeipa/ticket/5809 Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/112/head:pr112 git checkout pr112
From 6db1f860dd13d90b039e71a08804bdd1f7f5a8fd Mon Sep 17 00:00:00 2001 From: Martin Babinsky <mbabi...@redhat.com> Date: Fri, 23 Sep 2016 15:53:41 +0200 Subject: [PATCH 1/2] Move character escaping function to ipautil Functions `escape_seq` and `unescape_seq` have a generic use-case so it makes sense to move them from `kerberos` to ipautil module so that other modules can reuse them more readily. https://fedorahosted.org/freeipa/ticket/5809 --- ipapython/ipautil.py | 27 +++++++++++++++++++++++++++ ipapython/kerberos.py | 29 ++--------------------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 62d029d..fac76d1 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -1484,3 +1484,30 @@ def is_fips_enabled(): # Consider that the host is not fips-enabled if the file does not exist pass return False + + +def unescape_seq(seq, *args): + """ + unescape (remove '\\') all occurences of sequence in input strings. + + :param seq: sequence to unescape + :param args: input string to process + + :returns: tuple of strings with unescaped sequences + """ + unescape_re = re.compile(r'\\{}'.format(seq)) + + return tuple(re.sub(unescape_re, seq, a) for a in args) + + +def escape_seq(seq, *args): + """ + escape (prepend '\\') all occurences of sequence in input strings + + :param seq: sequence to escape + :param args: input string to process + + :returns: tuple of strings with escaped sequences + """ + + return tuple(a.replace(seq, u'\\{}'.format(seq)) for a in args) diff --git a/ipapython/kerberos.py b/ipapython/kerberos.py index 298dbf1..a8ebc04 100644 --- a/ipapython/kerberos.py +++ b/ipapython/kerberos.py @@ -8,6 +8,8 @@ import re import six +from ipapython.ipautil import escape_seq, unescape_seq + if six.PY3: unicode = str @@ -58,33 +60,6 @@ def split_principal_name(principal_name): return tuple(COMPONENT_SPLIT_RE.split(principal_name)) -def unescape_seq(seq, *args): - """ - unescape (remove '\\') all occurences of sequence in input strings. - - :param seq: sequence to unescape - :param args: input string to process - - :returns: tuple of strings with unescaped sequences - """ - unescape_re = re.compile(r'\\{}'.format(seq)) - - return tuple(re.sub(unescape_re, seq, a) for a in args) - - -def escape_seq(seq, *args): - """ - escape (prepend '\\') all occurences of sequence in input strings - - :param seq: sequence to escape - :param args: input string to process - - :returns: tuple of strings with escaped sequences - """ - - return tuple(a.replace(seq, u'\\{}'.format(seq)) for a in args) - - @six.python_2_unicode_compatible class Principal(object): """ From 49a3535e0eff2a9ed2c3cbc36adff03c96730f69 Mon Sep 17 00:00:00 2001 From: Martin Babinsky <mbabi...@redhat.com> Date: Fri, 23 Sep 2016 15:56:46 +0200 Subject: [PATCH 2/2] mod_nss: use more robust quoting of NSSNickname directive The code which handles configuration of mod_nss module must be more robust when handling NSS nicknames generated from subject names containing quoted RDN values. https://fedorahosted.org/freeipa/ticket/5809 --- ipaserver/install/httpinstance.py | 3 ++- ipaserver/install/installutils.py | 42 +++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 00f8901..7914f4c 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -263,7 +263,8 @@ def __set_mod_nss_port(self): print("Updating port in %s failed." % paths.HTTPD_NSS_CONF) def __set_mod_nss_nickname(self, nickname): - installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSNickname', nickname) + installutils.set_directive( + paths.HTTPD_NSS_CONF, 'NSSNickname', nickname, quote_char="'") def set_mod_nss_protocol(self): installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSProtocol', 'TLSv1.0,TLSv1.1,TLSv1.2', False) diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index bf179a2..2e4fc58 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -376,13 +376,35 @@ def update_file(filename, orig, subst): print("File %s doesn't exist." % filename) return 1 -def set_directive(filename, directive, value, quotes=True, separator=' '): + +def set_directive(filename, directive, value, quotes=True, separator=' ', + quote_char='\"'): """Set a name/value pair directive in a configuration file. - A value of None means to drop the directive. + A value of None means to drop the directive. + + This has only been tested with nss.conf - This has only been tested with nss.conf + :param directive: directive name + :param value: value of the directive + :param quotes: whether to quote `value` in `quote_char`. If true, then + the `quote_char` are first escaped to avoid unparseable directives + :param quote_char: the character used for quoting `value` """ + + def format_directive(directive, value, separator, quotes, quote_char): + directive_sep = "{directive}{separator}".format(directive=directive, + separator=separator) + transformed_value = value + if quotes: + transformed_value = "{quote}{value}{quote}".format( + quote=quote_char, + value="".join(ipautil.escape_seq(quote_char, value)) + ) + + return "{directive_sep}{value}\n".format( + directive_sep=directive_sep, value=transformed_value) + valueset = False st = os.stat(filename) fd = open(filename) @@ -391,19 +413,17 @@ def set_directive(filename, directive, value, quotes=True, separator=' '): if line.lstrip().startswith(directive): valueset = True if value is not None: - if quotes: - newfile.append('%s%s"%s"\n' % (directive, separator, value)) - else: - newfile.append('%s%s%s\n' % (directive, separator, value)) + newfile.append( + format_directive( + directive, value, separator, quotes, quote_char)) else: newfile.append(line) fd.close() if not valueset: if value is not None: - if quotes: - newfile.append('%s%s"%s"\n' % (directive, separator, value)) - else: - newfile.append('%s%s%s\n' % (directive, separator, value)) + newfile.append( + format_directive( + directive, value, separator, quotes, quote_char)) fd = open(filename, "w") fd.write("".join(newfile))
-- 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