Escape the password for WinRM certificate XML

This patch escapes the password formatted into a hand-crafted
XML for the WinRM certificate mapping. Without it, using passwords
such as 'P@ssw&d' will make the WinRM certificate auth plugin to
fail with a "The WS-Management service cannot process the request
because the XML is invalid.", which is actually true, since the resulting
XML is not valid, due to the unescaped and sign.

Change-Id: Ia93ab13a4ae5783c1fed5fbb748902bda84e9b65
Closes-Bug: #1441884
This commit is contained in:
Claudiu Popa 2015-04-09 02:22:53 +03:00
parent a118f260ce
commit 917fef98ce
2 changed files with 14 additions and 6 deletions

View File

@ -14,6 +14,7 @@
import importlib
import unittest
from xml.sax import saxutils
try:
import unittest.mock as mock
@ -267,10 +268,14 @@ class WinRMConfigTests(unittest.TestCase):
'subject': 'subject',
'uri': 'fake:\\uri'}
mock_get_xml_bool.return_value = True
fake_password = "Pa&ssw0rd!"
fake_username = 'fake user'
expected_password = saxutils.escape(fake_password)
expected_username = saxutils.escape(fake_username)
self._winrmconfig.create_cert_mapping(
issuer='issuer', subject='subject', username='fake user',
password='fake password', uri='fake:\\uri', enabled=True)
issuer='issuer', subject='subject', username=fake_username,
password=fake_password, uri='fake:\\uri', enabled=True)
mock_get_xml_bool.assert_called_once_with(True)
mock_create_resource.assert_called_once_with(
@ -281,8 +286,8 @@ class WinRMConfigTests(unittest.TestCase):
'<p:Password>%(password)s</p:Password>'
'<p:UserName>%(username)s</p:UserName>'
'</p:certmapping>' % {'enabled': True,
'username': 'fake user',
'password': 'fake password'})
'username': expected_username,
'password': expected_password})
@mock.patch('cloudbaseinit.utils.windows.winrmconfig.WinRMConfig.'
'_get_resource')

View File

@ -17,6 +17,7 @@ import re
from win32com import client
from xml.etree import ElementTree
from xml.sax import saxutils
CBT_HARDENING_LEVEL_NONE = "none"
@ -127,6 +128,8 @@ class WinRMConfig(object):
resource_uri = self._SERVICE_CERTMAPPING_URI % {'issuer': issuer,
'subject': subject,
'uri': uri}
escaped_password = saxutils.escape(password)
escaped_username = saxutils.escape(username)
self._create_resource(
resource_uri,
'<p:certmapping xmlns:p="http://schemas.microsoft.com/wbem/wsman/'
@ -135,8 +138,8 @@ class WinRMConfig(object):
'<p:Password>%(password)s</p:Password>'
'<p:UserName>%(username)s</p:UserName>'
'</p:certmapping>' % {'enabled': self._get_xml_bool(enabled),
'username': username,
'password': password})
'username': escaped_username,
'password': escaped_password})
def get_listener(self, protocol=LISTENER_PROTOCOL_HTTPS, address="*"):
resource_uri = self._SERVICE_LISTENER_URI % {'protocol': protocol,