From: "Daniel P. Berrange" <berrange@redhat.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] Scrub VNC passwords from XenD log files
Date: Tue, 5 Dec 2006 19:31:25 +0000 [thread overview]
Message-ID: <20061205193125.GF21067@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1574 bytes --]
The XendDomainInfo and XendConfig classes both log the guest VM config data
to the /var/log/xen/xend.log in many places. Unfortunately the VNC passwords
are stored in plain text in the guest VM config files. So we end up with
plain text passwords in the xend.log file
Now we can make /var/log/xen mode 0700 to protect them from local users,
but it is very common when debugging issues to request that a user attach
the contents of /var/log/xen/xend.log to the bug report ticket, or emails
sent to mailing lists. This will obviously compromise any VNC passwords
to essentially the while world & his dog. What's more, Google will make
it incredibly easy to search for these too.
There are a few potential approaches to this
1. Remove all logging from xend.log
2. Change default log level to only record WARN and higher, so DEBUG
stuff is not recorded normally
3. Scrub the passwords out of the data being logged
4. Do nothing
I really don't like options 1 or 2, because the stuff XenD is logging is
actually incredibly helpful when debugging end user problems. 4 is not
really a viable option either. So we're left with 3.
Thus I am attaching a prototype patch which scrubs VNC passwords out of
the data being logged by XenD.
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
[-- Attachment #2: xen-3.0.4-scrub-passwords.patch --]
[-- Type: text/plain, Size: 5110 bytes --]
diff -r 7df4d8cfba3b tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Tue Dec 05 12:42:29 2006 +0000
+++ b/tools/python/xen/xend/XendConfig.py Tue Dec 05 14:33:34 2006 -0500
@@ -41,6 +41,35 @@ def reverse_dict(adict):
def bool0(v):
return v != '0' and bool(v)
+
+# Recursively copy a data struct, scrubbing out VNC passwords.
+# Will scrub any dict entry with a key of 'vncpasswd' or any
+# 2-element list whose first member is 'vncpasswd'. It will
+# also scrub a string matching '(vncpasswd XYZ)'. Everything
+# else is no-op passthrough
+def scrub_password(data):
+ log.debug("Scrub " + str(type(data)))
+ if type(data) == dict or type(data) == XendConfig:
+ scrubbed = {}
+ for key in data.keys():
+ if key == "vncpasswd":
+ scrubbed[key] = "XXXXXXXX"
+ else:
+ scrubbed[key] = scrub_password(data[key])
+ return scrubbed
+ elif type(data) == list:
+ if len(data) == 2 and type(data[0]) == str and data[0] == 'vncpasswd':
+ return ['vncpasswd', 'XXXXXXXX']
+ else:
+ scrubbed = []
+ for entry in data:
+ scrubbed.append(scrub_password(entry))
+ return scrubbed
+ elif type(data) == str:
+ return re.sub(r'\(vncpasswd\s+[^\)]+\)','(vncpasswd XXXXXX)', data)
+ else:
+ return data
+
# Mapping from XendConfig configuration keys to the old
# legacy configuration keys that map directly.
@@ -269,7 +298,7 @@ class XendConfig(dict):
# output from xc.domain_getinfo
self._dominfo_to_xapi(dominfo)
- log.debug('XendConfig.init: %s' % self)
+ log.debug('XendConfig.init: %s' % scrub_password(self))
# validators go here
self.validate()
diff -r 7df4d8cfba3b tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Tue Dec 05 12:42:29 2006 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py Tue Dec 05 14:33:25 2006 -0500
@@ -40,6 +40,7 @@ from xen.xend import balloon, sxp, uuid,
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendRoot, XendNode, XendConfig
+from xen.xend.XendConfig import scrub_password
from xen.xend.XendBootloader import bootloader
from xen.xend.XendError import XendError, VmError
from xen.xend.XendDevices import XendDevices
@@ -148,7 +149,7 @@ def create(config):
@raise VmError: Invalid configuration or failure to start.
"""
- log.debug("XendDomainInfo.create(%s)", config)
+ log.debug("XendDomainInfo.create(%s)", scrub_password(config))
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
try:
vm.start()
@@ -175,7 +176,7 @@ def recreate(info, priv):
@raise XendError: Errors with configuration.
"""
- log.debug("XendDomainInfo.recreate(%s)", info)
+ log.debug("XendDomainInfo.recreate(%s)", scrub_password(info))
assert not info['dying']
@@ -257,7 +258,7 @@ def restore(config):
@raise XendError: Errors with configuration.
"""
- log.debug("XendDomainInfo.restore(%s)", config)
+ log.debug("XendDomainInfo.restore(%s)", scrub_password(config))
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
resume = True)
try:
@@ -280,7 +281,7 @@ def createDormant(domconfig):
@raise XendError: Errors with configuration.
"""
- log.debug("XendDomainInfo.createDormant(%s)", domconfig)
+ log.debug("XendDomainInfo.createDormant(%s)", scrub_password(domconfig))
# domid does not make sense for non-running domains.
domconfig.pop('domid', None)
@@ -520,11 +521,11 @@ class XendDomainInfo:
@param dev_config: device configuration
@type dev_config: SXP object (parsed config)
"""
- log.debug("XendDomainInfo.device_create: %s" % dev_config)
+ log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config))
dev_type = sxp.name(dev_config)
dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
dev_config_dict = self.info['devices'][dev_uuid][1]
- log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
+ log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict))
devid = self._createDevice(dev_type, dev_config_dict)
self._waitForDevice(dev_type, devid)
return self.getDeviceController(dev_type).sxpr(devid)
@@ -746,7 +747,7 @@ class XendDomainInfo:
to_store.update(self._vcpuDomDetails())
- log.debug("Storing domain details: %s", to_store)
+ log.debug("Storing domain details: %s", scrub_password(to_store))
self._writeDom(to_store)
@@ -1661,7 +1662,7 @@ class XendDomainInfo:
if not self._readVm('xend/restart_count'):
to_store['xend/restart_count'] = str(0)
- log.debug("Storing VM details: %s", to_store)
+ log.debug("Storing VM details: %s", scrub_password(to_store))
self._writeVm(to_store)
self._setVmPermissions()
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2006-12-05 19:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-05 19:31 Daniel P. Berrange [this message]
2006-12-06 12:25 ` [PATCH] Scrub VNC passwords from XenD log files Ewan Mellor
2006-12-06 17:16 ` Daniel P. Berrange
2006-12-06 17:24 ` Ewan Mellor
2006-12-06 19:43 ` Daniel P. Berrange
2006-12-07 12:14 ` Ewan Mellor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061205193125.GF21067@redhat.com \
--to=berrange@redhat.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.