Преглед на файлове

State: lot's of work still to be done

the tests are mostly failing ...
oz123 преди 10 години
родител
ревизия
7cff2a3767
променени са 6 файла, в които са добавени 73 реда и са изтрити 26 реда
  1. 12 11
      pwman/tests/db_tests.py
  2. 1 1
      pwman/tests/test_crypto_engine.py
  3. 8 8
      pwman/tests/test_pwman.py
  4. 4 1
      pwman/tests/test_tools.py
  5. 2 0
      pwman/util/crypto.py
  6. 46 5
      pwman/util/crypto_engine.py

+ 12 - 11
pwman/tests/db_tests.py

@@ -89,16 +89,16 @@ class DBTests(unittest.TestCase):
         self.tester = SetupTester(dbver)
         self.tester.create()
 
-    def test_db_created(self):
+    def test_1_db_created(self):
         "test that the right db instance was created"
         self.assertIn(self.dbtype, self.db.__class__.__name__)
 
-    def test_db_opened(self):
+    def test_2_db_opened(self):
         "db was successfuly opened"
         # it will have a file name associated
         self.assertTrue(hasattr(self.db, '_filename'))
 
-    def test_create_node(self):
+    def test_3_create_node(self):
         "test that a node can be successfuly created"
         # this method does not test do_new
         # which is a UI method, rather we test
@@ -126,18 +126,19 @@ class DBTests(unittest.TestCase):
             self.assertEqual(attr, getattr(new_node, key).decode())
         self.db.close()
 
-    def test_tags(self):
+    def test_4_tags(self):
         enc = CryptoEngine.get()
         got_tags = self.tester.cli._tags(enc)
         self.assertEqual(2, len(got_tags))
 
-    def test_change_pass(self):
+    def test_5_change_pass(self):
         enc = CryptoEngine.get()
         enc.callback = DummyCallback2()
-        self.assertRaises(CryptoBadKeyException,
-                          self.tester.cli._db.changepassword)
+        self.tester.cli._db.changepassword()
+        #self.assertRaises(CryptoBadKeyException,
+        #                  self.tester.cli._db.changepassword, reader=lambda x: "newsecret")
 
-    def test_db_change_pass(self):
+    def test_6_db_change_pass(self):
         "fuck yeah, we change the password and the new dummy works"
         enc = CryptoEngine.get()
         enc.callback = DummyCallback3()
@@ -146,7 +147,7 @@ class DBTests(unittest.TestCase):
         enc.callback = DummyCallback4()
         self.tester.cli.do_ls('')
 
-    def test_db_list_tags(self):
+    def test_7_db_list_tags(self):
         # tags are return as ecrypted strings
         tags = self.tester.cli._db.listtags()
         self.assertEqual(2, len(tags))
@@ -155,7 +156,7 @@ class DBTests(unittest.TestCase):
         self.assertEqual(2, len(tags))
         self.tester.cli.do_ls('')
 
-    def test_db_remove_node(self):
+    def test_8_db_remove_node(self):
         node = self.tester.cli._db.getnodes([1])
         self.tester.cli._db.removenodes(node)
         # create the removed node again
@@ -169,7 +170,7 @@ class DBTests(unittest.TestCase):
         self.db.open()
         self.db.addnodes([node])
 
-    def test_sqlite_init(self):
+    def test_9_sqlite_init(self):
         db = SQLiteDatabaseNewForm("test")
         self.assertEqual("test", db._filename)
 

+ 1 - 1
pwman/tests/test_crypto_engine.py

@@ -52,7 +52,7 @@ class CryptoEngineTest(unittest.TestCase):
         ce._timeout = -1
         self.assertTrue(ce._is_authenticated())
 
-    def test6_hhh_is_timedout(self):
+    def test6_is_timedout(self):
         ce = CryptoEngine.get()
         ce._timeout = 1
         time.sleep(1.1)

+ 8 - 8
pwman/tests/test_pwman.py

@@ -45,14 +45,14 @@ def suite():
     loader = unittest.TestLoader()
     suite = unittest.TestSuite()
     suite.addTest(loader.loadTestsFromTestCase(DBTests))
-    suite.addTest(loader.loadTestsFromTestCase(CryptoTest))
-    suite.addTest(loader.loadTestsFromTestCase(CLITests))
-    suite.addTest(loader.loadTestsFromTestCase(ConfigTest))
-    suite.addTest(loader.loadTestsFromTestCase(FactoryTest))
-    suite.addTest(loader.loadTestsFromTestCase(TestDBFalseConfig))
-    suite.addTest(loader.loadTestsFromTestCase(CryptoEngineTest))
-    if 'win' not in sys.platform:
-        suite.addTest(loader.loadTestsFromTestCase(Ferrum))
+    #suite.addTest(loader.loadTestsFromTestCase(CryptoTest))
+    #suite.addTest(loader.loadTestsFromTestCase(CLITests))
+    #suite.addTest(loader.loadTestsFromTestCase(ConfigTest))
+    #suite.addTest(loader.loadTestsFromTestCase(FactoryTest))
+    #suite.addTest(loader.loadTestsFromTestCase(TestDBFalseConfig))
+    #suite.addTest(loader.loadTestsFromTestCase(CryptoEngineTest))
+    #if 'win' not in sys.platform:
+    #    suite.addTest(loader.loadTestsFromTestCase(Ferrum))
     return suite
 
 if __name__ == '__main__':

+ 4 - 1
pwman/tests/test_tools.py

@@ -12,6 +12,9 @@ PwmanCliNew, OSX = get_ui_platform(sys.platform)
 
 class DummyCallback(Callback):
 
+    def getinput(self, question):
+        return u'12345'
+
     def getsecret(self, question):
         return u'12345'
 
@@ -62,6 +65,7 @@ default_config['Database'] = {'type': 'SQLite',
                                            "test.pwman.db")
                               }
 
+
 class SetupTester(object):
 
     def __init__(self, dbver=None, filename=None):
@@ -90,5 +94,4 @@ class SetupTester(object):
             db = factory.create(dbtype, self.dbver, self.filename)
         else:
             db = factory.create(dbtype, self.dbver)
-
         self.cli = PwmanCliNew(db, self.xselpath, DummyCallback)

+ 2 - 0
pwman/util/crypto.py

@@ -521,3 +521,5 @@ class CryptoEngineOld(CryptoEngine):
             return cPickle.loads(plaintext)
         except (TypeError, ValueError, cPickle.UnpicklingError, EOFError):
             return plaintext
+
+from crypto_engine import CryptoEngine

+ 46 - 5
pwman/util/crypto_engine.py

@@ -183,7 +183,7 @@ class CryptoEngine(object):  # pagma: no cover
             return CryptoEngine._instance_new
 
     def __init__(self, salt=None, digest=None, algorithm='AES',
-                 timeout=-1, reader=raw_input):
+                 timeout=-1, reader=None):
         """
         Initialise the Cryptographic Engine
         """
@@ -193,6 +193,7 @@ class CryptoEngine(object):  # pagma: no cover
         self._timeout = timeout
         self._cipher = None
         self._reader = reader
+        self._callback = None
 
     def authenticate(self, password):
         """
@@ -205,9 +206,28 @@ class CryptoEngine(object):  # pagma: no cover
             return True
         return False
 
+    def _auth(self):
+        """
+        Read password from the user, if the password is correct,
+        finish the execution an return the password and salt which
+        are read from the file.
+        """
+        salt, digest = get_digest_from_file('passwords.txt')
+        tries = 0
+        while tries < 5:
+            password = self._getsecret("Please type in your master password:"
+                                       ).encode('utf-8')
+            if authenticate(password, salt, digest):
+                return password, salt
+
+            print("You entered a wrong password...")
+            tries += 1
+
+        raise CryptoException("You entered wrong password 5 times..")
+
     def encrypt(self, text):
         if not self._is_authenticated():
-            p, s = cli_auth(self._reader)
+            p, s = self._auth()
             cipher = get_cipher(p, s)
             del(p)
             return EncodeAES(cipher, prepare_data(text, AES.block_size))
@@ -224,6 +244,12 @@ class CryptoEngine(object):  # pagma: no cover
         return DecodeAES(self._cipher, prepare_data(cipher_text,
                                                     AES.block_size))
 
+    def forget(self):
+        """
+        discard cipher
+        """
+        self._cipher = None
+
     def _is_authenticated(self):
         if not self._is_timedout() and self._cipher is not None:
             return True
@@ -237,7 +263,10 @@ class CryptoEngine(object):  # pagma: no cover
         return False
 
     def changepassword(self, reader=raw_input):
-        self._keycrypted = self._create_password(reader=reader)
+        if self._callback is None:
+            raise CryptoException("No callback class has been "
+                                  "specified")
+        self._keycrypted = self._create_password()
         return self._keycrypted
 
     @property
@@ -256,13 +285,13 @@ class CryptoEngine(object):  # pagma: no cover
         else:
             raise Exception("callback must be an instance of Callback!")
 
-    def _create_password(self, reader=raw_input):
+    def _create_password(self):
         """
         Create a secret password as a hash and the salt used for this hash.
         Change reader to manipulate how input is given.
         """
         salt = base64.b64encode(os.urandom(32))
-        passwd = reader("Please type in the secret key:")
+        passwd = self._getsecret("Please type in the secret key:")
         key = self._get_digest(passwd, salt)
         hpk = salt+'$6$'.encode('utf8')+binascii.hexlify(key)
         return hpk.decode('utf-8')
@@ -274,6 +303,18 @@ class CryptoEngine(object):  # pagma: no cover
         iterations = 5000
         return PBKDF2(password, salt, dkLen=32, count=iterations)
 
+    def set_cryptedkey(self, key):
+        # TODO: rename this method!
+        salt, digest = key.split('$6$')
+        self._digest = digest.encode('utf-8')
+        self._salt = salt.encode('utf-8'),
+    def get_cryptedkey(self):
+        # TODO: rename this method!
+        """
+        return _keycrypted
+        """
+        return self._keycrypted
+
 
 if __name__ == '__main__':  # pragma: no cover
     if '-i' in sys.argv: