summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-10-05 09:30:50 +0900
committerkali <kali@leap.se>2012-10-05 09:30:50 +0900
commit7c659fed65f08f2b52f0320c99a456679749e3f3 (patch)
treee0085fd2b4658dd53d7eed450f77e002e5ab5ea5
parentbaefda49d741a6e8149233f292f92221aaf3b675 (diff)
use keyring to store user password
using a quite lame cryptedfile by the moment until dbus bug makes gnome-keyring usable again or we come up with the encrypted database solution. we might want to explore the option of using this python-keyring with the different native backends for win and macosx. for now: we generate a random secret that we store in the qsettings file. so, the whole thing is just to avoid plaintext stuff. for this, we could have done rot13, haha.
-rw-r--r--pkg/requirements.pip2
-rw-r--r--src/leap/crypto/__init__.py0
-rw-r--r--src/leap/crypto/leapkeyring.py63
-rwxr-xr-xsrc/leap/gui/firstrunwizard.py34
4 files changed, 95 insertions, 4 deletions
diff --git a/pkg/requirements.pip b/pkg/requirements.pip
index f244879b..d6c6713f 100644
--- a/pkg/requirements.pip
+++ b/pkg/requirements.pip
@@ -5,3 +5,5 @@ netifaces
python-gnutls==1.1.9 # see https://bugs.launchpad.net/ubuntu/+source/python-gnutls/+bug/1027129
jsonschema
srp
+pycrypto
+keyring
diff --git a/src/leap/crypto/__init__.py b/src/leap/crypto/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/leap/crypto/__init__.py
diff --git a/src/leap/crypto/leapkeyring.py b/src/leap/crypto/leapkeyring.py
new file mode 100644
index 00000000..394142db
--- /dev/null
+++ b/src/leap/crypto/leapkeyring.py
@@ -0,0 +1,63 @@
+import os
+
+import keyring
+
+#############
+# Disclaimer
+#############
+# This currently is not a keyring, it's more like a joke.
+# No, seriously.
+# We're affected by this **bug**
+
+# https://bitbucket.org/kang/python-keyring-lib/issue/65/dbusexception-method-opensession-with
+
+# so using the gnome keyring does not seem feasible right now.
+# I thought this was the next best option to store secrets in plain sight.
+
+# in the future we should move to use the gnome/kde/macosx/win keyrings.
+
+
+class LeapCryptedFileKeyring(keyring.backend.CryptedFileKeyring):
+
+ filename = os.path.expanduser("~/.config/leap/.secrets")
+
+ def __init__(self, seed=None):
+ self.seed = seed
+
+ def _get_new_password(self):
+ # XXX every time this method is called,
+ # $deity kills a kitten.
+ return "secret%s" % self.seed
+
+ def _init_file(self):
+ self.keyring_key = self._get_new_password()
+ self.set_password('keyring_setting', 'pass_ref', 'pass_ref_value')
+
+ def _unlock(self):
+ self.keyring_key = self._get_new_password()
+ print 'keyring key ', self.keyring_key
+ try:
+ ref_pw = self.get_password(
+ 'keyring_setting',
+ 'pass_ref')
+ print 'ref pw ', ref_pw
+ assert ref_pw == "pass_ref_value"
+ except AssertionError:
+ self._lock()
+ raise ValueError('Incorrect password')
+
+
+def leap_set_password(key, value, seed="xxx"):
+ keyring.set_keyring(LeapCryptedFileKeyring(seed=seed))
+ keyring.set_password('leap', key, value)
+
+
+def leap_get_password(key, seed="xxx"):
+ keyring.set_keyring(LeapCryptedFileKeyring(seed=seed))
+ return keyring.get_password('leap', key)
+
+
+if __name__ == "__main__":
+ leap_set_password('test', 'bar')
+ passwd = leap_get_password('test')
+ assert passwd == 'bar'
diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py
index 3b27985f..1012f64c 100755
--- a/src/leap/gui/firstrunwizard.py
+++ b/src/leap/gui/firstrunwizard.py
@@ -8,6 +8,7 @@ sip.setapi('QVariant', 2)
from PyQt4 import QtCore
from PyQt4 import QtGui
+from leap.crypto import leapkeyring
from leap.gui import mainwindow_rc
logger = logging.getLogger(__name__)
@@ -89,7 +90,9 @@ QLabel { color: red;
class FirstRunWizard(QtGui.QWizard):
- def __init__(self, parent=None, providers=None, success_cb=None):
+ def __init__(
+ self, parent=None, providers=None,
+ success_cb=None):
super(FirstRunWizard, self).__init__(
parent,
QtCore.Qt.WindowStaysOnTopHint)
@@ -126,6 +129,7 @@ class FirstRunWizard(QtGui.QWizard):
QtGui.QWizard.setWindowFlags(self, flags)
def focusOutEvent(self, event):
+ # needed ?
self.setFocus(True)
self.activateWindow()
self.raise_()
@@ -137,13 +141,27 @@ class FirstRunWizard(QtGui.QWizard):
gather the info, update settings
and call the success callback.
"""
- logger.debug('chosen provider: %s', self.get_provider())
- logger.debug('username: %s', self.field('userName'))
- logger.debug('remember password: %s', self.field('rememberPassword'))
+ provider = self.get_provider()
+ username = self.field('userName')
+ password = self.field('userPassword')
+ remember_pass = self.field('rememberPassword')
+
+ logger.debug('chosen provider: %s', provider)
+ logger.debug('username: %s', username)
+ logger.debug('remember password: %s', remember_pass)
super(FirstRunWizard, self).accept()
settings = QtCore.QSettings()
settings.setValue("FirstRunWizardDone", True)
+ settings.setValue(
+ "eip_%s_username" % provider,
+ username)
+ settings.setValue("%s_remember_pass" % provider, remember_pass)
+
+ seed = self.get_random_str(10)
+ settings.setValue("%s_seed" % provider, seed)
+
+ leapkeyring.leap_set_password(username, password, seed=seed)
logger.debug('First Run Wizard Done.')
cb = self.success_cb
@@ -154,6 +172,14 @@ class FirstRunWizard(QtGui.QWizard):
provider = self.field('provider_index')
return self.providers[provider]
+ def get_random_str(self, n):
+ from string import (ascii_uppercase, ascii_lowercase, digits)
+ from random import choice
+ return ''.join(choice(
+ ascii_uppercase +
+ ascii_lowercase +
+ digits) for x in range(n))
+
class IntroPage(QtGui.QWizardPage):
def __init__(self, parent=None):