From 3d7e66f16ab02f95317e64068279d692a2ea4955 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 10 Jul 2015 19:42:33 +0200 Subject: sslkeylog.py: fix older gdb and python compat Older gdb is upset by appending to a pipe, so fallback to writing instead in such cases. Older python do not allow interpolation in bytes, so use strings and encode it to bytes before writing. Previously tested with GDB 7.9.1 and Python 2.7.10. Now tested with GDB 7.7.1 and Python 2.7.6 on Ubuntu 14.04. --- src/sslkeylog.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sslkeylog.py b/src/sslkeylog.py index 9e00e21..e589e53 100644 --- a/src/sslkeylog.py +++ b/src/sslkeylog.py @@ -35,16 +35,17 @@ To stop capturing keys, detach GDB or invoke 'skl.stop()' ''' import gdb +import errno from os import getenv # Default filename for new Keylog instances. keylog_filename = getenv('SSLKEYLOGFILE', '/dev/stderr') -_SSL_KEYLOG_HEADER = b'# Automatically generated by sslkeylog.py\n' +_SSL_KEYLOG_HEADER = '# Automatically generated by sslkeylog.py\n' def _read_as_hex(value, size): addr = value.address data = gdb.selected_inferior().read_memory(addr, size) - return b''.join(b'%02X' % ord(x) for x in data) + return ''.join('%02X' % ord(x) for x in data) def _ssl_get_master_key(ssl_ptr): session = ssl_ptr['session'] @@ -109,8 +110,8 @@ class Keylog(object): def notify(self, client_random, master_key): '''Puts a new entry in the key log if not already known.''' if client_random not in self.written_items: - line = b'CLIENT_RANDOM %s %s\n' % (client_random, master_key) - self.keylog_file.write(line) + line = 'CLIENT_RANDOM %s %s\n' % (client_random, master_key) + self.keylog_file.write(line.encode('ascii')) # Assume client random is random enough as cache key. cache_key = client_random @@ -129,7 +130,15 @@ class Keylog(object): return False # Byte output is needed for unbuffered I/O - f = open(filename, 'ab', 0) + try: + f = open(filename, 'ab', 0) + except OSError as e: + # Older gdb try to seek when append is requested. If seeking is not + # possible (for stderr or pipes), use plain write mode. + if e.errno == errno.ESPIPE: + f = open(filename, 'wb', 0) + else: + raise if needs_header(f): f.write(_SSL_KEYLOG_HEADER) return cls(f) -- cgit v1.2.1