File 03-osc_gnome_keyring.patch of Package osc
diff --git a/osc/conf.py b/osc/conf.py
index f505171..a56a67b 100644
--- a/osc/conf.py
+++ b/osc/conf.py
@@ -74,6 +74,34 @@ GNOME_KEYRING = False
try:
import keyring
GENERIC_KEYRING = True
+ if 'DISPLAY' in os.environ:
+ # Looks like we have desktop session
+ # Continue to the the normal desktop unlock procedures.
+ pass
+ if 'DBUS_SESSION_BUS_ADDERESS' in os.environ:
+ # Make DBUS has launched
+ pass
+ else:
+ raise SystemExit ("""
+The DBUS_SESSION_BUS_ADDRESS environment variable is not set which
+probably means that DBUS is not running.
+
+If you have just installed osc then you need to logout
+and login again, or source /etc/profile.
+""")
+
+ if 'GNOME_KEYRING_CONTROL' in os.environ:
+ # Make GNOME_KEYRING is started
+ pass
+ else:
+ raise SystemExit ("""
+The GNOME_KEYRING_CONTROL environment variable is not set which
+probably means GNOME KEYRING DAEMON is not running.
+
+If you have just installed osc then you need to logout
+and login again.
+""")
+
except:
try:
import gobject
@@ -83,6 +111,31 @@ except:
except:
pass
+def _unlock_gnome_keyring(prompt):
+ import secretstorage
+ import subprocess
+
+ # Make the .local directory. Otherwise initial keyring creation
+ # will fail.
+ if not os.path.exists(os.path.expanduser('~/.local')):
+ os.makedirs(os.path.expanduser('~/.local'), mode=0o700)
+
+ process = subprocess.Popen(['/usr/bin/gnome-keyring-daemon', '--start',
+ '--components=secrets'],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE)
+ password = getpass.getpass(prompt=prompt)
+ password = (password + '\n').encode('UTF-8')
+ process = subprocess.Popen(['/usr/bin/gnome-keyring-daemon', '--unlock',
+ '--replace', '--components=secrets'],
+ stdin = subprocess.PIPE,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE)
+ stdoutdata,stderrdata = process.communicate(input=password)
+ dbus = secretstorage.dbus_init()
+ collection = secretstorage.get_default_collection(dbus)
+ if collection.is_locked():
+ raise SystemExit('Unable to unlock keyring.')
def _get_processors():
"""
@@ -204,7 +257,7 @@ boolean_opts = ['debug', 'do_package_tracking', 'http_debug', 'post_mortem', 'tr
'status_mtime_heuristic']
integer_opts = ['build-jobs']
-api_host_options = ['user', 'pass', 'passx', 'aliases', 'http_headers', 'realname', 'email', 'sslcertck', 'cafile', 'capath', 'trusted_prj', 'credentials_mgr_class']
+api_host_options = ['user', 'pass', 'passx', 'aliases', 'http_headers', 'realname', 'email', 'sslcertck', 'cafile', 'capath', 'trusted_prj']
new_conf_template = """
[general]
@@ -789,7 +842,17 @@ def write_initial_config(conffile, entries, custom_template='', creds_mgr_descri
creds_mgr = creds_mgr_descriptor.create(cp)
else:
creds_mgr = _get_credentials_manager(config['apiurl'], cp)
- creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+ try:
+ creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+ except keyring.errors.InitError:
+ print ('Creating a new keyring.')
+ _unlock_gnome_keyring('New keyring password: ')
+ creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+ except keyring.errors.KeyringLocked:
+ print ('Unlock keyring.')
+ _unlock_gnome_keyring('Keyring password: ')
+ creds_mgr.set_password(config['apiurl'], config['user'], config['pass'])
+
write_config(conffile, cp)
@@ -906,8 +969,12 @@ def get_config(override_conffile=None,
# override values which we were called with
# This needs to be done before processing API sections as it might be already used there
if override_no_keyring:
- config['use_keyring'] = False
+ print ("Disabling the use of a keyring is not allowed in this environment.")
+ print ("A keyring will still be used.")
+ config['use_keyring'] = True
if override_no_gnome_keyring:
+ print ("Disabling the use of a gnome keyring is not allowed in this environment.")
+ print ("A keyring will still be used.")
config['gnome_keyring'] = False
aliases = {}
@@ -922,7 +989,17 @@ def get_config(override_conffile=None,
user = _extract_user_compat(cp, url, creds_mgr)
if user is None:
raise oscerr.ConfigMissingCredentialsError('No user found in section %s' % url, conffile, url)
- password = creds_mgr.get_password(url, user)
+ try:
+ password = creds_mgr.get_password(url, user)
+ except keyring.errors.InitError:
+ print ('Creating a new keyring.')
+ _unlock_gnome_keyring('New keyring password: ')
+ password = creds_mgr.get_password(url, user)
+ except keyring.errors.KeyringLocked:
+ print ('Unlock keyring.')
+ _unlock_gnome_keyring('Keyring password: ')
+ password = creds_mgr.get_password(url, user)
+
if password is None:
raise oscerr.ConfigMissingCredentialsError('No password found in section %s' % url, conffile, url)
@@ -1048,10 +1125,18 @@ def interactive_config_setup(conffile, apiurl, initial=True):
def select_credentials_manager_descr():
if not credentials.has_keyring_support():
print('To use keyrings please install python-keyring.')
+ if config['creds_mgr']:
+ creds_mgr = config['creds_mgr']
+ else:
+ creds_mgr = DEFAULTS['creds_mgr']
creds_mgr_descriptors = credentials.get_credentials_manager_descriptors()
for i, creds_mgr_descr in enumerate(creds_mgr_descriptors, 1):
- print('%d) %s (%s)' % (i, creds_mgr_descr.name(), creds_mgr_descr.description()))#
- i = raw_input('Select credentials manager: ')
+ if creds_mgr is not None:
+ if creds_mgr == creds_mgr_descr.name():
+ return creds_mgr_descr
+ else:
+ print('%d) %s (%s)' % (i, creds_mgr_descr.name(), creds_mgr_descr.description()))#
+ I = raw_input('Select credentials manager: ')
if not i.isdigit():
sys.exit('Invalid selection')
i = int(i) - 1
@@ -1060,3 +1145,4 @@ def select_credentials_manager_descr():
return creds_mgr_descriptors[i]
# vim: sw=4 et
+