Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with Python 2.6 #6

Open
lbeltrame opened this issue Apr 13, 2014 · 3 comments
Open

Incompatible with Python 2.6 #6

lbeltrame opened this issue Apr 13, 2014 · 3 comments

Comments

@lbeltrame
Copy link

The code uses a lot of Python 2.7 conventions, and as such it is incompatible with Python 2.6 (used by CentOS 6 and RHEL 6).

@lbeltrame
Copy link
Author

This patch (no time for a PR at the moment) fixes it:

diff --git a/pacemaker.py b/pacemaker.py
index 5837305..2e542a3 100755
--- a/pacemaker.py
+++ b/pacemaker.py
@@ -44,14 +44,14 @@ def make_hello(sslver, cipher):
     ee 7e 21 c4 1d 2e 9f e9 60 5f 05 b0 ce af 7e b7
     95 8c 33 42 3f d5 00
     '''
-    data += ' '.join('{:02x}'.format(c) for c in cipher)
+    data += ' '.join('{0:02x}'.format(c) for c in cipher)
     data += ' 00' # No compression
     data += ' 00 05' # Extensions length
     # Heartbeat extension
     data += ' 00 0f' # Heartbeat type
     data += ' 00 01' # Length
     data += ' 01'    # mode
-    return bytearray.fromhex(data.replace('\n', ''))
+    return bytearray.fromhex(unicode(data).replace('\n', ''))

 def make_heartbeat(sslver):
     data = '18 ' + sslver
@@ -63,7 +63,7 @@ def make_heartbeat(sslver):
     # heartbeat requests. Therefore request a payload that fits exactly in four
     # records (0x4000 * 4 - 3 - 16 = 0xffed).
     data += ' ff ed'    # Payload Length
-    return bytearray.fromhex(data.replace('\n', ''))
+    return bytearray.fromhex(unicode(data).replace('\n', ''))

 def hexdump(data):
     allzeroes = b'\0' * 16
@@ -78,8 +78,8 @@ def hexdump(data):
             if zerolines >= 2:
                 continue

-        print("{:04x}: {:47}  {}".format(i,
-            ' '.join('{:02x}'.format(c) for c in line),
+        print("{0:04x}: {1:47}  {2}".format(i,
+            ' '.join('{0:02x}'.format(c) for c in line),
             ''.join(chr(c) if c >= 32 and c < 127 else '.' for c in line)))

 class Failure(Exception):
@@ -183,7 +183,7 @@ def read_hb_response(sock, timeout):
             break
         else:
             # Cannot tell whether vulnerable or not!
-            raise Failure('Unexpected record type {}'.format(record_type))
+            raise Failure('Unexpected record type {0}'.format(record_type))

         timeout = end_time - time.time()

@@ -191,7 +191,7 @@ def read_hb_response(sock, timeout):
     if alert:
         lvl, desc = alert[0:1], ord(alert[1:2])
         lvl = 'Warning' if lvl == 1 else 'Fatal'
-        print('Got Alert, level={}, description={}'.format(lvl, desc))
+        print('Got Alert, level={0}, description={1}'.format(lvl, desc))
         if not memory:
             print('Not vulnerable! (Heartbeats disabled or not OpenSSL)')
             return None
@@ -207,7 +207,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
         self.args = self.server.args
         self.sslver = '03 01' # default to TLSv1.0
         remote_addr, remote_port = self.request.getpeername()[:2]
-        print("Connection from: {}:{}".format(remote_addr, remote_port))
+        print("Connection from: {0}:{1}".format(remote_addr, remote_port))

         try:
             # Set timeout to prevent hang on clients that send nothing
@@ -265,7 +265,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
         # The first cipher is fine...
         cipher = bytearray(hnd[off:off+2])

-        self.sslver = '{:02x} {:02x}'.format(ver >> 8, ver & 0xFF)
+        self.sslver = '{0:02x} {1:02x}'.format(ver >> 8, ver & 0xFF)

         # (1) Handshake: ServerHello
         self.request.sendall(make_hello(self.sslver, cipher))
@@ -315,7 +315,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
         self.expect(packet_len == 32, 'Expected SSLRequest length == 32')
         self.expect((caps & 0x800), 'Missing Client SSL support')

-        print("Skipping {} packet bytes...".format(packet_len))
+        print("Skipping {0} packet bytes...".format(packet_len))
         # Skip remainder (minus 2 for caps) to prepare for SSL handshake
         sock.recv(packet_len - 2)

@@ -368,7 +368,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
     def recv_s(self, struct_def, what):
         s = struct.Struct(struct_def)
         data = self.request.recv(s.size)
-        msg = '{}: received only {}/{} bytes'.format(what, len(data), s.size)
+        msg = '{0}: received only {1}/{2} bytes'.format(what, len(data), s.size)
         self.expect(len(data) == s.size, msg)
         return s.unpack(data)

@@ -390,7 +390,7 @@ class PacemakerServer(socketserver.TCPServer):
         self.stopped = True

 def serve(args):
-    print('Listening on {}:{} for {} clients'
+    print('Listening on {0}:{1} for {2} clients'
         .format(args.listen, args.port, args.client))
     server = PacemakerServer(args)
     server.serve_forever()

@Lekensteyn
Copy link
Owner

Thanks for reporting, pacemaker was tested with 2.7.3, 2.7.6, 3.2.3 and 3.4.0, not 2.6.x.

I'll have a look at this later and apply the patch if you did not already create a PR.

Hmm, what about the use of argparse? You need to install that manually as 2.6 does not bundle that module. http://stackoverflow.com/questions/21359400/python-2-6-importerror-no-module-named-argparse

Lekensteyn added a commit that referenced this issue Apr 17, 2014
Thanks to @lbeltrame (#6)
for initial patch!

Only tested with TLS (not FTP, IMAP, etc.) on Debian Squeeze against
cloudflarechallenge.com.
@Lekensteyn
Copy link
Owner

pacemaker and heartbleed.py should work now with Python 2.6

Ugh.. but it breaks Python 3 now. And fixed again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants