Browse Source

Python3 compatibility

oz123 10 years ago
parent
commit
2820987bb1

+ 10 - 10
pwman/__init__.py

@@ -1,4 +1,4 @@
-#============================================================================
+# ============================================================================
 # This file is part of Pwman3.
 #
 # Pwman3 is free software; you can redistribute it and/or modify
@@ -13,18 +13,18 @@
 # You should have received a copy of the GNU General Public License
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#============================================================================
+# ============================================================================
 # Copyright (C) 2012 Oz Nahum <nahumoz@gmail.com>
-#============================================================================
+# ============================================================================
 # Copyright (C) 2006 Ivan Kelly <ivan@ivankelly.net>
-#============================================================================
+# ============================================================================
 import os
 import pkg_resources
 import argparse
 from pwman.util import config
 import sys
 import re
-import data.factory
+from pwman.data import factory
 from pwman.data.database import __DB_FORMAT__
 import colorama
 
@@ -34,20 +34,20 @@ appname = "pwman3"
 try:
     version = pkg_resources.get_distribution('pwman3').version
 except pkg_resources.DistributionNotFound:  # pragma: no cover
-    version = "0.5"
+    version = u"0.5"
 
 website = "http://pwman3.github.io/pwman3/"
 author = "Oz Nahum"
 authoremail = "nahumoz@gmail.com"
 description = "a command line password management application."
 keywords = "password management sqlite crypto"
-long_description = ("Pwman3 aims to provide a simple but powerful command "
+long_description = (u"Pwman3 aims to provide a simple but powerful command "
                     "line interface for password management.\nIt allows one "
                     "to store your password in a SQLite database locked by "
                     "a\nmaster password which can be encrypted with different "
                     "algorithms (e.g AES, Blowfish, DES3, IDEA, etc.).")
 
-_db_warn = ("pwman3 detected that you are using the old database format"
+_db_warn = (u"pwman3 detected that you are using the old database format"
             " which is insecure."
             " pwman3 will try to automatically convert the database now."
             "\n"
@@ -99,7 +99,7 @@ def parser_options(formatter_class=argparse.HelpFormatter):
                               " one found in the config file, or the one given"
                               " as command line argument."))
     parser.add_argument('-O', '--output', dest='output',
-                        #default=os.path.expanduser('~/.pwman/pwman-newdb.db'),
+                        # default=os.path.expanduser('~/.pwman/pwman-newdb.db'),
                         help=("The name of the newly created database after "
                               "converting."))
     return parser
@@ -175,7 +175,7 @@ def get_conf_options(args, OSX):
 
 def get_db_version(config, dbtype, args):
     if os.path.exists(config.get_value("Database", "filename")):
-        dbver = data.factory.check_db_version(dbtype)
+        dbver = factory.check_db_version(dbtype)
         if dbver < 0.4 and not args.dbconvert:
             print(_db_warn)
     else:

+ 1 - 1
pwman/tests/__init__.py

@@ -1,4 +1,4 @@
-import test_pwman
+from . import test_pwman
 
 def suite():
     import unittest

+ 4 - 0
pwman/tests/crypto_tests.py

@@ -48,3 +48,7 @@ class CryptoTest(unittest.TestCase):
         old_engine._cipher = None
         self.assertFalse(old_engine.alive())
         CryptoEngine.get()
+
+
+if __name__ == '__main__':
+    unittest.main()

+ 11 - 9
pwman/tests/db_tests.py

@@ -1,4 +1,4 @@
-#============================================================================
+# ============================================================================
 # This file is part of Pwman3.
 #
 # Pwman3 is free software; you can redistribute it and/or modify
@@ -13,9 +13,9 @@
 # You should have received a copy of the GNU General Public License
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#============================================================================
+# ============================================================================
 # Copyright (C) 2013 Oz Nahum <nahumoz@gmail.com>
-#============================================================================
+# ============================================================================
 
 from pwman.data.nodes import NewNode
 from pwman.data.tags import TagNew
@@ -33,12 +33,14 @@ from pwman.data.database import __DB_FORMAT__
 from pwman.ui.mac import PwmanCliMacNew
 from pwman.ui.win import PwmanCliWinNew
 from collections import namedtuple
-
+import sys
 import unittest
-import StringIO
+if sys.version_info.major > 2:
+    from io import StringIO
+else:
+    import StringIO
 import os
 import os.path
-import sys
 
 dummyfile = """
 [Encryption]
@@ -105,13 +107,13 @@ class DBTests(unittest.TestCase):
         password = 'Password'
         url = 'example.org'
         notes = 'some notes'
-        #node = NewNode(username, password, url, notes)
+        # node = NewNode(username, password, url, notes)
         node = NewNode()
         node.username = username
         node.password = password
         node.url = url
         node.notes = notes
-        #node = NewNode(username, password, url, notes)
+        # node = NewNode(username, password, url, notes)
         tags = [TagNew(tn) for tn in ['testing1', 'testing2']]
         node.tags = tags
         self.db.open()
@@ -175,7 +177,7 @@ class DBTests(unittest.TestCase):
 class TestDBFalseConfig(unittest.TestCase):
 
     def setUp(self):
-        #filename = default_config['Database'].pop('filename')
+        # filename = default_config['Database'].pop('filename')
         self.fname1 = default_config['Database'].pop('filename')
         self.fname = config._conf['Database'].pop('filename')
 

+ 5 - 5
pwman/tests/test_complete_ui.py

@@ -1,4 +1,4 @@
-#============================================================================
+# ============================================================================
 # This file is part of Pwman3.
 #
 # Pwman3 is free software; you can redistribute it and/or modify
@@ -13,11 +13,11 @@
 # You should have received a copy of the GNU General Public License
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#============================================================================
+# ============================================================================
 # Copyright (C) 2012-2014 Oz Nahum <nahumoz@gmail.com>
-#============================================================================
+# ============================================================================
 # pylint: disable=I0011
-
+from __future__ import print_function
 import pexpect
 import unittest
 import os
@@ -53,7 +53,7 @@ class Ferrum(unittest.TestCase):
         rv = child.expect(_db_warn, timeout=5)
         if rv != 0:
             lfile.seek(0)
-            print lfile.readlines()
+            print(lfile.readlines())
 
         self.assertEqual(0, rv)
 

+ 13 - 10
pwman/ui/base.py

@@ -1,4 +1,4 @@
-#============================================================================
+# ============================================================================
 # This file is part of Pwman3.
 #
 # Pwman3 is free software; you can redistribute it and/or modify
@@ -13,9 +13,9 @@
 # You should have received a copy of the GNU General Public License
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#============================================================================
+# ============================================================================
 # Copyright (C) 2013 Oz Nahum <nahumoz@gmail.com>
-#============================================================================
+# ============================================================================
 # pylint: disable=I0011
 """
 Define the base CLI interface for pwman3
@@ -38,8 +38,11 @@ from pwman.data.nodes import NewNode
 from pwman.ui.tools import CMDLoop
 import getpass
 from pwman.data.tags import TagNew
+if sys.version_info.major > 2:
+    raw_input = input
 
-class HelpUI(object): # pragma: no cover
+
+class HelpUI(object):  # pragma: no cover
     """
     this class holds all the UI help functionality.
     in PwmanCliNew. The later inherits from this class
@@ -400,7 +403,7 @@ class BaseCommands(BaseUI, HelpUI):
         try:
             key = self._db.changepassword()
             self._db.savekey(key)
-        except Exception  as e:
+        except Exception as e:
             self.error(e)
 
     def do_save(self, args):
@@ -437,7 +440,7 @@ class BaseCommands(BaseUI, HelpUI):
         # strings = []
         tags = self._db.listtags(True)
         # for t in tags:
-            # strings.append(t.get_name())
+        #    strings.append(t.get_name())
         #    strings.append(t)
 
         strings = [t for t in tags]
@@ -460,8 +463,8 @@ class BaseCommands(BaseUI, HelpUI):
 
     def do_list(self, args):
 
-        #crypto  = CryptoEngine.get()
-        #crypto.auth('YOURPASSWORD')
+        # crypto  = CryptoEngine.get()
+        # crypto.auth('YOURPASSWORD')
 
         if len(args.split()) > 0:
             self.do_clear('')
@@ -560,7 +563,7 @@ class BaseCommands(BaseUI, HelpUI):
             node.password = password
             node.url = url
             node.notes = notes
-            #node = NewNode(username, password, url, notes)
+            # node = NewNode(username, password, url, notes)
             node.tags = self.get_tags()
             self._db.addnodes([node])
             print ("Password ID: %d" % (node._id))
@@ -630,7 +633,7 @@ class BaseCommands(BaseUI, HelpUI):
                                  numerics=numerics)
 
 
-class Aliases(BaseCommands): # pragma: no cover
+class Aliases(BaseCommands):  # pragma: no cover
     """
     Define all the alias you want here...
     """

+ 3 - 0
pwman/ui/tools.py

@@ -32,6 +32,9 @@ from pwman.data.tags import TagNew as Tag
 from pwman.util.config import get_pass_conf
 import pwman.util.generator as generator
 
+if sys.version_info.major > 2:
+    raw_input = input
+
 if sys.platform != 'win32':
     import termios
     import fcntl

+ 18 - 8
pwman/util/crypto.py

@@ -41,7 +41,7 @@ crypto = CryptoEngine.get()
 ciphertext = crypto.encrypt("plaintext")
 plaintext = cyypto.decrypt(ciphertext)
 """
-
+from __future__ import print_function
 from Crypto.Cipher import Blowfish as cBlowfish
 from Crypto.Cipher import AES as cAES
 from Crypto.Cipher import ARC2 as cARC2
@@ -52,12 +52,15 @@ from Crypto.Random import OSRNG
 
 from pwman.util.callback import Callback
 import pwman.util.config as config
-import cPickle
+try:
+    import cPickle
+except ImportError:
+    import pickle as cPickle
 import time
 import sys
 import ctypes
 import hashlib
-
+import base64
 
 def zerome(string):
     """
@@ -252,7 +255,10 @@ class CryptoEngine(object):
             # Generate a new key, 32 byts in length, if that's
             # too long for the Cipher, _getCipherReal will sort it out
             random = OSRNG.new()
-            key = str(random.read(32)).encode('base64')
+            try:
+                key = str(random.read(32)).encode('base64')
+            except LookupError:
+                key = str(base64.b64encode(random.read(32)).decode('utf-8'))
         else:
             password = self._callback.getsecret(("Please enter your current "
                                                  "password"))
@@ -265,7 +271,7 @@ class CryptoEngine(object):
         newpassword2 = self._callback.getnewsecret(("Please enter your new"
                                                    "password again"))
         while newpassword1 != newpassword2:
-            print "Passwords do not match!"
+            print("Passwords do not match!")
             newpassword1 = self._callback.getnewsecret(("Please enter your new"
                                                         " password"))
             newpassword2 = self._callback.getnewsecret(("Please enter your new"
@@ -333,7 +339,7 @@ class CryptoEngine(object):
                 key = self._retrievedata(plainkey)
                 break
             except CryptoBadKeyException:
-                print "Wrong password."
+                print("Wrong password.")
                 tries += 1
 
         if not key:
@@ -357,11 +363,15 @@ class CryptoEngine(object):
         form PyCrypto
         """
         if (algo == "AES"):
+            if sys.version_info.major > 2:
+                key = key.encode('utf-8')
             for i in range(1000):
-                key = hashlib.sha256(key)
-                key = key.digest()
+               key = hashlib.sha256(key)
+               key = key.digest()
+
             key = hashlib.sha256(key)
             cipher = cAES.new(key.digest(), cAES.MODE_ECB)
+
         elif (algo == 'ARC2'):
             cipher = cARC2.new(key, cARC2.MODE_ECB)
         elif (algo == 'ARC4'):

+ 3 - 3
setup.py

@@ -4,19 +4,19 @@ script to install pwman3
 """
 
 from setuptools import setup
-import pwman
 import sys
 from setuptools.command.install import install
 import os
 from subprocess import Popen, PIPE
 from build_manpage import BuildManPage
+import pwman
 
 
 def describe():
     des = Popen('git describe', shell=True, stdout=PIPE)
     ver = des.stdout.readlines()
     if ver:
-        return ver[0].strip()
+        return ver[0].strip().decode('utf-8')
     else:
         return pwman.version
 
@@ -78,7 +78,7 @@ setup(name=pwman.appname,
       tests_require=['pexpect'],
       cmdclass={
           'install_pycrypto': PyCryptoInstallCommand,
-          'build_manpage': BuildManPage,
+          'build_manpage': BuildManPage
       }
 
       )