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

+ 1 - 1
pwman/tests/__init__.py

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

+ 4 - 0
pwman/tests/crypto_tests.py

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

+ 11 - 9
pwman/tests/db_tests.py

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

+ 13 - 10
pwman/ui/base.py

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

+ 18 - 8
pwman/util/crypto.py

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

+ 3 - 3
setup.py

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