[libsecret] mock: Port to Python 3



commit 847dd055e433d1b9da9b520ca0b965fc2b9ea3f4
Author: Dmitry Shachnev <mitya57 gmail com>
Date:   Wed Feb 10 20:13:11 2016 +0300

    mock: Port to Python 3
    
    https://bugzilla.gnome.org/show_bug.cgi?id=761834

 libsecret/mock-service.c   |    2 +-
 libsecret/mock/__init__.py |    3 +-
 libsecret/mock/aes.py      |   24 +++++++++++-----------
 libsecret/mock/dh.py       |   48 ++++++++++---------------------------------
 libsecret/mock/hkdf.py     |   12 +++++-----
 libsecret/mock/service.py  |   34 +++++++++++-------------------
 6 files changed, 45 insertions(+), 78 deletions(-)
---
diff --git a/libsecret/mock-service.c b/libsecret/mock-service.c
index f890f1d..99f209e 100644
--- a/libsecret/mock-service.c
+++ b/libsecret/mock-service.c
@@ -88,7 +88,7 @@ service_start (const gchar *mock_script,
        gint output;
 
        gchar *argv[] = {
-               "python", (gchar *)mock_script,
+               "python3", (gchar *)mock_script,
                NULL
        };
 
diff --git a/libsecret/mock/__init__.py b/libsecret/mock/__init__.py
index 2306cbb..9aa641d 100644
--- a/libsecret/mock/__init__.py
+++ b/libsecret/mock/__init__.py
@@ -9,4 +9,5 @@
 # See the included COPYING file for more information.
 #
 
-from service import *
+from .service import SecretItem, SecretCollection, SecretService, SecretPrompt
+from .service import PlainAlgorithm, NotSupported
diff --git a/libsecret/mock/aes.py b/libsecret/mock/aes.py
index 78a36aa..2265fab 100644
--- a/libsecret/mock/aes.py
+++ b/libsecret/mock/aes.py
@@ -18,13 +18,13 @@ import math
 def append_PKCS7_padding(s):
     """return s padded to a multiple of 16-bytes by PKCS7 padding"""
     numpads = 16 - (len(s)%16)
-    return s + numpads*chr(numpads)
+    return s + bytes([numpads] * numpads)
 
 def strip_PKCS7_padding(s):
     """return s stripped of PKCS7 padding"""
     if len(s)%16 or not s:
         raise ValueError("String of len %d can't be PCKS7-padded" % len(s))
-    numpads = ord(s[-1])
+    numpads = s[-1]
     if numpads > 16:
         raise ValueError("String ending with %r can't be PCKS7-padded" % s[-1])
     return s[:-numpads]
@@ -421,7 +421,7 @@ class AESModeOfOperation(object):
         while len(ar) < end - start:
             ar.append(0)
         while i < end:
-            ar[j] = ord(string[i])
+            ar[j] = string[i]
             j += 1
             i += 1
         return ar
@@ -523,7 +523,7 @@ class AESModeOfOperation(object):
         output = []
         plaintext = [0] * 16
         # the output plain text string
-        stringOut = ''
+        result = []
         # char firstRound
         firstRound = True
         if cipherIn != None:
@@ -549,7 +549,7 @@ class AESModeOfOperation(object):
                         else:
                             plaintext[i] = output[i] ^ ciphertext[i]
                     for k in range(end-start):
-                        stringOut += chr(plaintext[k])
+                        result.append(plaintext[k])
                     iput = ciphertext
                 elif mode == self.modeOfOperation["OFB"]:
                     if firstRound:
@@ -567,7 +567,7 @@ class AESModeOfOperation(object):
                         else:
                             plaintext[i] = output[i] ^ ciphertext[i]
                     for k in range(end-start):
-                        stringOut += chr(plaintext[k])
+                        result.append(plaintext[k])
                     iput = output
                 elif mode == self.modeOfOperation["CBC"]:
                     output = self.aes.decrypt(ciphertext, key, size)
@@ -579,12 +579,12 @@ class AESModeOfOperation(object):
                     firstRound = False
                     if originalsize is not None and originalsize < end:
                         for k in range(originalsize-start):
-                            stringOut += chr(plaintext[k])
+                            result.append(plaintext[k])
                     else:
                         for k in range(end-start):
-                            stringOut += chr(plaintext[k])
+                            result.append(plaintext[k])
                     iput = ciphertext
-        return stringOut
+        return bytes(result)
 
 
 def encryptData(key, data, mode=AESModeOfOperation.modeOfOperation["CBC"]):
@@ -640,7 +640,7 @@ def generateRandomKey(keysize):
     """
     if keysize not in (16, 24, 32):
         emsg = 'Invalid keysize, %s. Should be one of (16, 24, 32).'
-        raise ValueError, emsg % keysize
+        raise ValueError(emsg % keysize)
     return os.urandom(keysize)
 
 if __name__ == "__main__":
@@ -650,7 +650,7 @@ if __name__ == "__main__":
     iv = [103,35,148,239,76,213,47,118,255,222,123,176,106,134,98,92]
     mode, orig_len, ciph = moo.encrypt(cleartext, moo.modeOfOperation["CBC"],
             cypherkey, moo.aes.keySize["SIZE_128"], iv)
-    print 'm=%s, ol=%s (%s), ciph=%s' % (mode, orig_len, len(cleartext), ciph)
+    print('m=%s, ol=%s (%s), ciph=%s' % (mode, orig_len, len(cleartext), ciph))
     decr = moo.decrypt(ciph, orig_len, mode, cypherkey,
             moo.aes.keySize["SIZE_128"], iv)
-    print decr
+    print(decr)
diff --git a/libsecret/mock/dh.py b/libsecret/mock/dh.py
index 63a378f..ec118c0 100644
--- a/libsecret/mock/dh.py
+++ b/libsecret/mock/dh.py
@@ -22,52 +22,26 @@
 import math
 import random
 
-PRIME = '\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1' \
-       '\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD' \
-       '\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45' \
-       '\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED' \
-       '\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81' \
-       '\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'
-
-def num_bits(number):
-       if number == 0:
-               return 0
-       s = "%x" % number
-       return ((len(s)-1)*4) + \
-           {'0':0, '1':1, '2':2, '3':2,
-            '4':3, '5':3, '6':3, '7':3,
-            '8':4, '9':4, 'a':4, 'b':4,
-            'c':4, 'd':4, 'e':4, 'f':4,
-           }[s[0]]
+PRIME = b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1' \
+       b'\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD' \
+       b'\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45' \
+       b'\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED' \
+       b'\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81' \
+       b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'
 
 def num_bytes(number):
-       if number == 0:
-               return 0
-       bits = num_bits(number)
-       return int(math.ceil(bits / 8.0))
-
-def bytes_to_number(data):
-       number = 0L
-       multiplier = 1L
-       for count in range(len(data) - 1, -1, -1):
-               number += multiplier * ord(data[count])
-               multiplier *= 256
-       return number
+       return math.ceil(number.bit_length() / 8)
 
 def number_to_bytes(number):
        n_data = num_bytes(number)
-       data = ['' for i in range(0, n_data)]
-       for count in range(n_data - 1, -1, -1):
-               data[count] = chr(number % 256)
-               number >>= 8
-       return "".join(data)
+       return number.to_bytes(n_data, 'big')
 
 def generate_pair():
-       prime = bytes_to_number (PRIME)
+       prime = int.from_bytes(PRIME, 'big')
        base = 2
        # print "mock prime: ", hex(prime)
        # print " mock base: ", hex(base)
-       bits = num_bits(prime)
+       bits = prime.bit_length()
        privat = 0
        while privat == 0:
                privat = random.getrandbits(bits - 1)
@@ -75,7 +49,7 @@ def generate_pair():
        return (privat, publi)
 
 def derive_key(privat, peer):
-       prime = bytes_to_number (PRIME)
+       prime = int.from_bytes(PRIME, 'big')
        key = pow(peer, privat, prime)
        # print " mock ikm2: ", hex(key)
        return number_to_bytes(key)
diff --git a/libsecret/mock/hkdf.py b/libsecret/mock/hkdf.py
index c4424ae..5e8ee9b 100644
--- a/libsecret/mock/hkdf.py
+++ b/libsecret/mock/hkdf.py
@@ -22,7 +22,7 @@ import math
 from binascii import a2b_hex, b2a_hex
 
 class HKDF(object):
-    def __init__(self, ikm, L, salt=None, info="", digestmod = None):
+    def __init__(self, ikm, L, salt=None, info=None, digestmod = None):
         self.ikm = ikm
         self.keylen = L
 
@@ -36,11 +36,11 @@ class HKDF(object):
         self.hashlen = len(self.digest_cons().digest())
 
         if salt is None:
-            self.salt = chr(0)*(self.hashlen)
+            self.salt = b'\x00' * (self.hashlen)
         else:
             self.salt = salt
 
-        self.info = info
+        self.info = info or b''
 
     #extract PRK
     def extract(self):
@@ -51,8 +51,8 @@ class HKDF(object):
     #expand PRK
     def expand(self):
         N = math.ceil(float(self.keylen)/self.hashlen)
-        T = ""
-        temp = ""
+        T = b""
+        temp = b""
         i=0x01
         '''while len(T)<2*self.keylen :
             msg = temp
@@ -66,7 +66,7 @@ class HKDF(object):
         while len(T)<self.keylen :
             msg = temp
             msg += self.info
-            msg += chr(i)
+            msg += bytes((i,))
             h = hmac.new(self.prk, msg, self.digest_cons)
             temp = h.digest()
             i += 1
diff --git a/libsecret/mock/service.py b/libsecret/mock/service.py
index f75ef43..014893a 100644
--- a/libsecret/mock/service.py
+++ b/libsecret/mock/service.py
@@ -17,9 +17,7 @@ import sys
 import time
 import unittest
 
-import aes
-import dh
-import hkdf
+from mock import aes, dh, hkdf
 
 import dbus
 import dbus.service
@@ -54,8 +52,7 @@ def next_identifier(prefix=''):
        return "%s%d" % (prefix, unique_identifier)
 
 def encode_identifier(value):
-       return "".join([(c.isalpha() or c.isdigit()) and c or "_%02x" % ord(c) \
-                              for c in value.encode('utf-8')])
+       return "".join([c.isalnum() and c or "_%02x" % ord(c) for c in value])
 
 def hex_encode(string):
        return "".join([hex(ord(c))[2:].zfill(2) for c in string])
@@ -71,9 +68,9 @@ class PlainAlgorithm():
                return (dbus.String("", variant_level=1), session)
 
        def encrypt(self, key, data):
-               return ("", data)
+               return b"", data
 
-       def decrypt(self, param, data):
+       def decrypt(self, key, params, data):
                if params == "":
                        raise InvalidArgs("invalid secret plain parameter")
                return data
@@ -84,7 +81,7 @@ class AesAlgorithm():
                if type (param) != dbus.ByteArray:
                        raise InvalidArgs("invalid argument passed to OpenSession")
                privat, publi = dh.generate_pair()
-               peer = dh.bytes_to_number(param)
+               peer = int.from_bytes(param, 'big')
                # print "mock publi: ", hex(publi)
                # print " mock peer: ", hex(peer)
                ikm = dh.derive_key(privat, peer)
@@ -95,21 +92,17 @@ class AesAlgorithm():
                return (dbus.ByteArray(dh.number_to_bytes(publi), variant_level=1), session)
 
        def encrypt(self, key, data):
-               key = map(ord, key)
                data = aes.append_PKCS7_padding(data)
                keysize = len(key)
-               iv = [ord(i) for i in os.urandom(16)]
+               iv = os.urandom(16)
                mode = aes.AESModeOfOperation.modeOfOperation["CBC"]
                moo = aes.AESModeOfOperation()
                (mode, length, ciph) = moo.encrypt(data, mode, key, keysize, iv)
-               return ("".join([chr(i) for i in iv]),
-                       "".join([chr(i) for i in ciph]))
+               return iv, ciph
 
        def decrypt(self, key, param, data):
-               key = map(ord, key)
                keysize = len(key)
-               iv = map(ord, param[:16])
-               data = map(ord, data)
+               iv = param[:16]
                moo = aes.AESModeOfOperation()
                mode = aes.AESModeOfOperation.modeOfOperation["CBC"]
                decr = moo.decrypt(data, None, mode, key, keysize, iv)
@@ -197,7 +190,7 @@ class SecretItem(dbus.service.Object):
                self.collection = collection
                self.identifier = identifier
                self.label = label or "Unnamed item"
-               self.secret = secret
+               self.secret = secret.encode('ascii') if isinstance(secret, str) else secret
                self.type = type or "org.freedesktop.Secret.Generic"
                self.attributes = attributes
                self.content_type = content_type
@@ -376,7 +369,7 @@ class SecretCollection(dbus.service.Object):
                self.PropertiesChanged('org.freedesktop.Secret.Collection', { "Locked" : lock }, [])
 
        def perform_delete(self):
-               for item in self.items.values():
+               for item in list(self.items.values()):
                        item.perform_delete()
                del objects[self.path]
                self.service.remove_collection(self)
@@ -529,8 +522,7 @@ class SecretService(dbus.service.Object):
                name = self.bus.get_unique_name()
                if not name:
                        raise NameError("No unique name available")
-               print name
-               sys.stdout.flush()
+               print(name, flush=True)
                loop.run()
 
        def add_session(self, session):
@@ -691,8 +683,8 @@ class SecretService(dbus.service.Object):
 def parse_options(args):
        try:
                opts, args = getopt.getopt(args, "", [])
-       except getopt.GetoptError, err:
-               print str(err)
+       except getopt.GetoptError as err:
+               print(str(err))
                sys.exit(2)
        for o, a in opts:
                assert False, "unhandled option"


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