[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#778353: marked as done (unblock: python-oslo.utils/0.2.0-1 (fixing CVE-2014-7231))



Your message dated Tue, 17 Feb 2015 16:45:30 +0100
with message-id <20150217154530.GC17992@dogguy.org>
and subject line Re: Bug#778353: pre-approval for unblock: python-oslo.utils/0.2.0-1 (fixing CVE-2014-7231)
has caused the Debian Bug report #778353,
regarding unblock: python-oslo.utils/0.2.0-1 (fixing CVE-2014-7231)
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
778353: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=778353
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Dear release team,

Moritz Mühlenhoff (aka jmm) made me aware of CVE-2014-7231, which has been
fixed in the release 0.2.0 of python-oslo.utils. This version has never been
uploaded to Sid (I uploaded it to Experimental instead), as I didn't want to
risk changing anything in OpenStack Icehouse in Jessie.

But since it fixes CVE-2014-7231, I'd like now to have version 0.2.0 replacing
version 0.1.1 in Jessie. Indeed, the patch available here:

https://review.openstack.org/gitweb?p=openstack%2Foslo.utils.git;a=commitdiff;h=e0425691d90bce0bbe847a9ff49468ce0fab5486

which fixes the issue, cannot be applied on top of version 0.1.1. I don't want
to risk doing a backport by myself, and would very much prefer to use what's
been done by upstream, which is "gated" (eg: tested by a CI / CD system).

Note that upstream currently declares that any version of python-oslo.utils
lower than version 1.0.0 can work with OpenStack Icehouse currently in Jessie,
as per the "global-requirements.txt" maintained for OpenStack Icehouse:

https://github.com/openstack/requirements/blob/stable/icehouse/global-requirements.txt#L53

So even version 0.3.0 would work, and may even be preferred, since that's what
the OpenStack gate uses right now to test Icehouse.

I have attached the debdiff between 0.1.1-1, and 0.2.0-1 (as per the package I
uploaded in Experimental, available in snapshot.d.o).

Will the release team accept such an unblock? Do I have your go-ahead to
upload version 0.2.0-1 to Sid?

Cheers,

Thomas Goirand (zigo)
diff -Nru python-oslo.utils-0.1.1/debian/changelog python-oslo.utils-0.2.0/debian/changelog
--- python-oslo.utils-0.1.1/debian/changelog	2014-08-07 10:19:33.000000000 +0200
+++ python-oslo.utils-0.2.0/debian/changelog	2014-09-05 10:07:10.000000000 +0200
@@ -1,3 +1,10 @@
+python-oslo.utils (0.2.0-1) experimental; urgency=medium
+
+  * New upstream release.
+  * Uploading to experimental before Jessie's freeze.
+
+ -- Thomas Goirand <zigo@debian.org>  Fri, 05 Sep 2014 15:50:43 +0800
+
 python-oslo.utils (0.1.1-1) unstable; urgency=medium
 
   * Initial release. (Closes: #757325)
diff -Nru python-oslo.utils-0.1.1/debian/gbp.conf python-oslo.utils-0.2.0/debian/gbp.conf
--- python-oslo.utils-0.1.1/debian/gbp.conf	2014-08-07 10:19:33.000000000 +0200
+++ python-oslo.utils-0.2.0/debian/gbp.conf	2014-09-05 10:07:10.000000000 +0200
@@ -1,6 +1,6 @@
 [DEFAULT]
 upstream-branch = master
-debian-branch = debian/unstable
+debian-branch = debian/experimental
 upstream-tag = %(version)s
 compression = xz
 
diff -Nru python-oslo.utils-0.1.1/debian/rules python-oslo.utils-0.2.0/debian/rules
--- python-oslo.utils-0.1.1/debian/rules	2014-08-07 10:19:33.000000000 +0200
+++ python-oslo.utils-0.2.0/debian/rules	2014-09-05 10:07:10.000000000 +0200
@@ -24,18 +24,18 @@
 
 override_dh_auto_test:
 ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS)))
-        @echo "===> Running tests"
-        set -e && set -x && for i in 2.7 $(PYTHON3S) ; do \
-                PYMAJOR=`echo $$i | cut -d'.' -f1` ; \
-                echo "===> Testing with python$$i (python$$PYMAJOR)" ; \
-                rm -rf .testrepository ; \
-                testr-python$$PYMAJOR init ; \
-                TEMP_REZ=`mktemp -t` && \
-                PYTHONPATH=$(CURDIR) PYTHON=python$$i testr-python$$PYMAJOR run --subunit | tee $$TEMP_REZ | subunit2pyunit ; \
-                cat $$TEMP_REZ | subunit-filter -s --no-passthrough | subunit-stats ; \
-                rm -f $$TEMP_REZ ; \
-                testr-python$$PYMAJOR slowest ; \
-        done
+	@echo "===> Running tests"
+	set -e ; set -x ; for i in 2.7 ; do \
+		PYMAJOR=`echo $$i | cut -d'.' -f1` ; \
+		echo "===> Testing with python$$i (python$$PYMAJOR)" ; \
+		rm -rf .testrepository ; \
+		testr-python$$PYMAJOR init ; \
+		TEMP_REZ=`mktemp -t` ; \
+		PYTHONPATH=$(CURDIR) PYTHON=python$$i testr-python$$PYMAJOR run --subunit | tee $$TEMP_REZ | subunit2pyunit ; \
+		cat $$TEMP_REZ | subunit-filter -s --no-passthrough | subunit-stats ; \
+		rm -f $$TEMP_REZ ; \
+		testr-python$$PYMAJOR slowest ; \
+	done
 endif
 
 override_dh_clean:
diff -Nru python-oslo.utils-0.1.1/oslo/utils/strutils.py python-oslo.utils-0.2.0/oslo/utils/strutils.py
--- python-oslo.utils-0.1.1/oslo/utils/strutils.py	2014-07-28 19:20:33.000000000 +0200
+++ python-oslo.utils-0.2.0/oslo/utils/strutils.py	2014-08-15 19:53:57.000000000 +0200
@@ -50,6 +50,39 @@
 SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+")
 
 
+# NOTE(flaper87): The following globals are used by `mask_password`
+_SANITIZE_KEYS = ['adminPass', 'admin_pass', 'password', 'admin_password']
+
+# NOTE(ldbragst): Let's build a list of regex objects using the list of
+# _SANITIZE_KEYS we already have. This way, we only have to add the new key
+# to the list of _SANITIZE_KEYS and we can generate regular expressions
+# for XML and JSON automatically.
+_SANITIZE_PATTERNS_2 = []
+_SANITIZE_PATTERNS_1 = []
+
+# NOTE(amrith): Some regular expressions have only one parameter, some
+# have two parameters. Use different lists of patterns here.
+_FORMAT_PATTERNS_1 = [r'(%(key)s\s*[=]\s*)[^\s^\'^\"]+']
+_FORMAT_PATTERNS_2 = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
+                      r'(%(key)s\s+[\"\']).*?([\"\'])',
+                      r'([-]{2}%(key)s\s+)[^\'^\"^=^\s]+([\s]*)',
+                      r'(<%(key)s>).*?(</%(key)s>)',
+                      r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
+                      r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])',
+                      r'([\'"].*?%(key)s[\'"]\s*,\s*\'--?[A-z]+\'\s*,\s*u?'
+                      '[\'"]).*?([\'"])',
+                      r'(%(key)s\s*--?[A-z]+\s*)\S+(\s*)']
+
+for key in _SANITIZE_KEYS:
+    for pattern in _FORMAT_PATTERNS_2:
+        reg_ex = re.compile(pattern % {'key': key}, re.DOTALL)
+        _SANITIZE_PATTERNS_2.append(reg_ex)
+
+    for pattern in _FORMAT_PATTERNS_1:
+        reg_ex = re.compile(pattern % {'key': key}, re.DOTALL)
+        _SANITIZE_PATTERNS_1.append(reg_ex)
+
+
 def int_from_bool_as_string(subject):
     """Interpret a string as a boolean and return either 1 or 0.
 
@@ -166,3 +199,42 @@
         "ascii", "ignore").decode("ascii")
     value = SLUGIFY_STRIP_RE.sub("", value).strip().lower()
     return SLUGIFY_HYPHENATE_RE.sub("-", value)
+
+
+def mask_password(message, secret="***"):
+    """Replace password with 'secret' in message.
+
+    :param message: The string which includes security information.
+    :param secret: value with which to replace passwords.
+    :returns: The unicode value of message with the password fields masked.
+
+    For example:
+
+    >>> mask_password("'adminPass' : 'aaaaa'")
+    "'adminPass' : '***'"
+    >>> mask_password("'admin_pass' : 'aaaaa'")
+    "'admin_pass' : '***'"
+    >>> mask_password('"password" : "aaaaa"')
+    '"password" : "***"'
+    >>> mask_password("'original_password' : 'aaaaa'")
+    "'original_password' : '***'"
+    >>> mask_password("u'original_password' :   u'aaaaa'")
+    "u'original_password' :   u'***'"
+    """
+    message = six.text_type(message)
+
+    # NOTE(ldbragst): Check to see if anything in message contains any key
+    # specified in _SANITIZE_KEYS, if not then just return the message since
+    # we don't have to mask any passwords.
+    if not any(key in message for key in _SANITIZE_KEYS):
+        return message
+
+    substitute = r'\g<1>' + secret + r'\g<2>'
+    for pattern in _SANITIZE_PATTERNS_2:
+        message = re.sub(pattern, substitute, message)
+
+    substitute = r'\g<1>' + secret
+    for pattern in _SANITIZE_PATTERNS_1:
+        message = re.sub(pattern, substitute, message)
+
+    return message
diff -Nru python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-critical.pot python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-critical.pot
--- python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-critical.pot	1970-01-01 01:00:00.000000000 +0100
+++ python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-critical.pot	2014-08-15 19:53:57.000000000 +0200
@@ -0,0 +1,19 @@
+# Translations template for oslo.utils.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the oslo.utils project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: oslo.utils 0.1.1\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-08-11 06:10+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
diff -Nru python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-error.pot python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-error.pot
--- python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-error.pot	1970-01-01 01:00:00.000000000 +0100
+++ python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-error.pot	2014-08-15 19:53:57.000000000 +0200
@@ -0,0 +1,29 @@
+# Translations template for oslo.utils.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the oslo.utils project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: oslo.utils 0.1.1\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-08-11 06:10+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
+#: oslo/utils/excutils.py:76
+#, python-format
+msgid "Original exception being dropped: %s"
+msgstr ""
+
+#: oslo/utils/excutils.py:105
+#, python-format
+msgid "Unexpected exception occurred %d time(s)... retrying."
+msgstr ""
+
diff -Nru python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-info.pot python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-info.pot
--- python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-info.pot	1970-01-01 01:00:00.000000000 +0100
+++ python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-info.pot	2014-08-15 19:53:57.000000000 +0200
@@ -0,0 +1,19 @@
+# Translations template for oslo.utils.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the oslo.utils project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: oslo.utils 0.1.1\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-08-11 06:10+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
diff -Nru python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-warning.pot python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-warning.pot
--- python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils-log-warning.pot	1970-01-01 01:00:00.000000000 +0100
+++ python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils-log-warning.pot	2014-08-15 19:53:57.000000000 +0200
@@ -0,0 +1,31 @@
+# Translations template for oslo.utils.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the oslo.utils project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: oslo.utils 0.1.1\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-08-11 06:10+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
+#: oslo/utils/netutils.py:151
+msgid "tcp_keepidle not available on your system"
+msgstr ""
+
+#: oslo/utils/netutils.py:158
+msgid "tcp_keepintvl not available on your system"
+msgstr ""
+
+#: oslo/utils/netutils.py:165
+msgid "tcp_keepcnt not available on your system"
+msgstr ""
+
diff -Nru python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils.pot python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils.pot
--- python-oslo.utils-0.1.1/oslo.utils/locale/oslo.utils.pot	2014-07-28 19:20:33.000000000 +0200
+++ python-oslo.utils-0.2.0/oslo.utils/locale/oslo.utils.pot	2014-08-15 19:53:57.000000000 +0200
@@ -6,9 +6,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: oslo.utils 5621114\n"
+"Project-Id-Version: oslo.utils 0.1.1\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2014-07-11 13:25+0200\n"
+"POT-Creation-Date: 2014-08-11 06:10+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,48 +17,18 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 1.3\n"
 
-#: oslo/utils/strutils.py:92 oslo/utils/openstack/common/strutils.py:92
+#: oslo/utils/strutils.py:92
 #, python-format
 msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s"
 msgstr ""
 
-#: oslo/utils/strutils.py:197 oslo/utils/openstack/common/strutils.py:197
+#: oslo/utils/strutils.py:126
 #, python-format
 msgid "Invalid unit system: \"%s\""
 msgstr ""
 
-#: oslo/utils/strutils.py:206 oslo/utils/openstack/common/strutils.py:206
+#: oslo/utils/strutils.py:135
 #, python-format
 msgid "Invalid string format: %s"
 msgstr ""
 
-#: oslo/utils/openstack/common/gettextutils.py:320
-msgid "Message objects do not support addition."
-msgstr ""
-
-#: oslo/utils/openstack/common/gettextutils.py:330
-msgid ""
-"Message objects do not support str() because they may contain non-ascii "
-"characters. Please use unicode() or translate() instead."
-msgstr ""
-
-#: oslo/utils/openstack/common/log.py:327
-#, python-format
-msgid "Deprecated: %s"
-msgstr ""
-
-#: oslo/utils/openstack/common/log.py:436
-#, python-format
-msgid "Error loading logging config %(log_config)s: %(err_msg)s"
-msgstr ""
-
-#: oslo/utils/openstack/common/log.py:487
-#, python-format
-msgid "syslog facility must be one of: %s"
-msgstr ""
-
-#: oslo/utils/openstack/common/log.py:725
-#, python-format
-msgid "Fatal call to deprecated config: %(msg)s"
-msgstr ""
-
diff -Nru python-oslo.utils-0.1.1/tests/test_strutils.py python-oslo.utils-0.2.0/tests/test_strutils.py
--- python-oslo.utils-0.1.1/tests/test_strutils.py	2014-07-28 19:20:33.000000000 +0200
+++ python-oslo.utils-0.2.0/tests/test_strutils.py	2014-08-15 19:53:57.000000000 +0200
@@ -259,3 +259,290 @@
             self.assertAlmostEqual(actual, expected)
 
 StringToBytesTest.generate_scenarios()
+
+
+class MaskPasswordTestCase(test_base.BaseTestCase):
+
+    def test_json(self):
+        # Test 'adminPass' w/o spaces
+        payload = """{'adminPass':'mypassword'}"""
+        expected = """{'adminPass':'***'}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'adminPass' with spaces
+        payload = """{ 'adminPass' : 'mypassword' }"""
+        expected = """{ 'adminPass' : '***' }"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' w/o spaces
+        payload = """{'admin_pass':'mypassword'}"""
+        expected = """{'admin_pass':'***'}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' with spaces
+        payload = """{ 'admin_pass' : 'mypassword' }"""
+        expected = """{ 'admin_pass' : '***' }"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' w/o spaces
+        payload = """{'admin_password':'mypassword'}"""
+        expected = """{'admin_password':'***'}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' with spaces
+        payload = """{ 'admin_password' : 'mypassword' }"""
+        expected = """{ 'admin_password' : '***' }"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' w/o spaces
+        payload = """{'password':'mypassword'}"""
+        expected = """{'password':'***'}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' with spaces
+        payload = """{ 'password' : 'mypassword' }"""
+        expected = """{ 'password' : '***' }"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+    def test_xml(self):
+        # Test 'adminPass' w/o spaces
+        payload = """<adminPass>mypassword</adminPass>"""
+        expected = """<adminPass>***</adminPass>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'adminPass' with spaces
+        payload = """<adminPass>
+                        mypassword
+                     </adminPass>"""
+        expected = """<adminPass>***</adminPass>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' w/o spaces
+        payload = """<admin_pass>mypassword</admin_pass>"""
+        expected = """<admin_pass>***</admin_pass>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' with spaces
+        payload = """<admin_pass>
+                        mypassword
+                     </admin_pass>"""
+        expected = """<admin_pass>***</admin_pass>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' w/o spaces
+        payload = """<admin_password>mypassword</admin_password>"""
+        expected = """<admin_password>***</admin_password>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' with spaces
+        payload = """<admin_password>
+                        mypassword
+                     </admin_password>"""
+        expected = """<admin_password>***</admin_password>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' w/o spaces
+        payload = """<password>mypassword</password>"""
+        expected = """<password>***</password>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' with spaces
+        payload = """<password>
+                        mypassword
+                     </password>"""
+        expected = """<password>***</password>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+    def test_xml_attribute(self):
+        # Test 'adminPass' w/o spaces
+        payload = """adminPass='mypassword'"""
+        expected = """adminPass='***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'adminPass' with spaces
+        payload = """adminPass = 'mypassword'"""
+        expected = """adminPass = '***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'adminPass' with double quotes
+        payload = """adminPass = "mypassword\""""
+        expected = """adminPass = "***\""""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' w/o spaces
+        payload = """admin_pass='mypassword'"""
+        expected = """admin_pass='***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' with spaces
+        payload = """admin_pass = 'mypassword'"""
+        expected = """admin_pass = '***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_pass' with double quotes
+        payload = """admin_pass = "mypassword\""""
+        expected = """admin_pass = "***\""""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' w/o spaces
+        payload = """admin_password='mypassword'"""
+        expected = """admin_password='***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' with spaces
+        payload = """admin_password = 'mypassword'"""
+        expected = """admin_password = '***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'admin_password' with double quotes
+        payload = """admin_password = "mypassword\""""
+        expected = """admin_password = "***\""""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' w/o spaces
+        payload = """password='mypassword'"""
+        expected = """password='***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' with spaces
+        payload = """password = 'mypassword'"""
+        expected = """password = '***'"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        # Test 'password' with double quotes
+        payload = """password = "mypassword\""""
+        expected = """password = "***\""""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+    def test_json_message(self):
+        payload = """body: {"changePassword": {"adminPass": "1234567"}}"""
+        expected = """body: {"changePassword": {"adminPass": "***"}}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """body: {"rescue": {"admin_pass": "1234567"}}"""
+        expected = """body: {"rescue": {"admin_pass": "***"}}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """body: {"rescue": {"admin_password": "1234567"}}"""
+        expected = """body: {"rescue": {"admin_password": "***"}}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """body: {"rescue": {"password": "1234567"}}"""
+        expected = """body: {"rescue": {"password": "***"}}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+    def test_xml_message(self):
+        payload = """<?xml version="1.0" encoding="UTF-8"?>
+<rebuild
+    xmlns="http://docs.openstack.org/compute/api/v1.1";
+    name="foobar"
+    imageRef="http://openstack.example.com/v1.1/32278/images/70a599e0-31e7";
+    accessIPv4="1.2.3.4"
+    accessIPv6="fe80::100"
+    adminPass="seekr3t">
+  <metadata>
+    <meta key="My Server Name">Apache1</meta>
+  </metadata>
+</rebuild>"""
+        expected = """<?xml version="1.0" encoding="UTF-8"?>
+<rebuild
+    xmlns="http://docs.openstack.org/compute/api/v1.1";
+    name="foobar"
+    imageRef="http://openstack.example.com/v1.1/32278/images/70a599e0-31e7";
+    accessIPv4="1.2.3.4"
+    accessIPv6="fe80::100"
+    adminPass="***">
+  <metadata>
+    <meta key="My Server Name">Apache1</meta>
+  </metadata>
+</rebuild>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    admin_pass="MySecretPass"/>"""
+        expected = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    admin_pass="***"/>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    admin_password="MySecretPass"/>"""
+        expected = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    admin_password="***"/>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+        payload = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    password="MySecretPass"/>"""
+        expected = """<?xml version="1.0" encoding="UTF-8"?>
+<rescue xmlns="http://docs.openstack.org/compute/api/v1.1";
+    password="***"/>"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+    def test_mask_password(self):
+        payload = "test = 'password'  :   'aaaaaa'"
+        expected = "test = 'password'  :   '111'"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='111'))
+
+        payload = 'mysqld --password "aaaaaa"'
+        expected = 'mysqld --password "****"'
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='****'))
+
+        payload = 'mysqld --password aaaaaa'
+        expected = 'mysqld --password ???'
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='???'))
+
+        payload = 'mysqld --password = "aaaaaa"'
+        expected = 'mysqld --password = "****"'
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='****'))
+
+        payload = "mysqld --password = 'aaaaaa'"
+        expected = "mysqld --password = '****'"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='****'))
+
+        payload = "mysqld --password = aaaaaa"
+        expected = "mysqld --password = ****"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='****'))
+
+        payload = "test = password =   aaaaaa"
+        expected = "test = password =   111"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='111'))
+
+        payload = "test = password=   aaaaaa"
+        expected = "test = password=   111"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='111'))
+
+        payload = "test = password =aaaaaa"
+        expected = "test = password =111"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='111'))
+
+        payload = "test = password=aaaaaa"
+        expected = "test = password=111"
+        self.assertEqual(expected,
+                         strutils.mask_password(payload, secret='111'))
+
+        payload = 'test = "original_password" : "aaaaaaaaa"'
+        expected = 'test = "original_password" : "***"'
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = 'test = "param1" : "value"'
+        expected = 'test = "param1" : "value"'
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = """{'adminPass':'mypassword'}"""
+        payload = six.text_type(payload)
+        expected = """{'adminPass':'***'}"""
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = ("test = 'node.session.auth.password','-v','mypassword',"
+                   "'nomask'")
+        expected = ("test = 'node.session.auth.password','-v','***',"
+                    "'nomask'")
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = ("test = 'node.session.auth.password', '--password', "
+                   "'mypassword', 'nomask'")
+        expected = ("test = 'node.session.auth.password', '--password', "
+                    "'***', 'nomask'")
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = ("test = 'node.session.auth.password', '--password', "
+                   "'mypassword'")
+        expected = ("test = 'node.session.auth.password', '--password', "
+                    "'***'")
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = "test = node.session.auth.password -v mypassword nomask"
+        expected = "test = node.session.auth.password -v *** nomask"
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = ("test = node.session.auth.password --password mypassword "
+                   "nomask")
+        expected = ("test = node.session.auth.password --password *** "
+                    "nomask")
+        self.assertEqual(expected, strutils.mask_password(payload))
+
+        payload = ("test = node.session.auth.password --password mypassword")
+        expected = ("test = node.session.auth.password --password ***")
+        self.assertEqual(expected, strutils.mask_password(payload))

--- End Message ---
--- Begin Message ---
On Tue, Feb 17, 2015 at 03:32:04PM +0100, Thomas Goirand <zigo@debian.org> wrote:
> 
> Uploaded, retitling the unblock bug accordingly.
> 

Unblocked.

Regards,

-- 
Mehdi Dogguy

--- End Message ---

Reply to: