Index: osc/conf.py
===================================================================
--- osc/conf.py	(revision 5802)
+++ osc/conf.py	(working copy)
@@ -37,6 +37,14 @@
 import OscConfigParser
 from osc import oscerr
 
+try:
+    import gobject
+    gobject.set_application_name('osc')
+    import gnomekeyring
+    GNOME_KEYRING = gnomekeyring.is_available()
+except:
+    GNOME_KEYRING = False
+
 # being global to this module, this dict can be accessed from outside
 # it will hold the parsed configuration
 config = { }
@@ -62,6 +70,7 @@
              'http_debug': '0',
              'traceback': '0',
              'post_mortem': '0',
+             'gnome_keyring': '1',
              'cookiejar': '~/.osc_cookiejar',
              # disable project tracking by default
              'do_package_tracking': '0',
@@ -111,12 +120,17 @@
 # print call traces in case of errors
 #traceback = 1
     
+# use GNOME keyring for credentials if available
+#gnome_keyring = 0
+    
 [%(apisrv)s]
 user = %(user)s
 pass = %(pass)s
 # additional headers to pass to a request, e.g. for special authentication
 #http_headers = Host: foofoobar,
 #       User: mumblegack
+# Force using of keyring for this API
+#keyring = 1
 """
 
 
@@ -252,6 +266,16 @@
     conf_template = custom_template or new_conf_template
     config = DEFAULTS.copy()
     config.update(entries)
+    if config['gnome_keyring'] and GNOME_KEYRING:
+        protocol, host = \
+            parse_apisrv_url(None, config['apisrv'])
+        gnomekeyring.set_network_password_sync(
+            user = config['user'],
+            password = config['pass'],
+            protocol = protocol,
+            server = host)
+        config['user'] = ''
+        config['pass'] = ''
     sio = StringIO.StringIO(conf_template.strip() % config)
     cp = OscConfigParser.OscConfigParser(DEFAULTS)
     cp.readfp(sio)
@@ -270,13 +294,41 @@
     finally:
         if file: file.close()
 
+def add_section(filename, url, user, passwd):
+    """
+    Add a section to config file for new api url.
+    """
+    global config
+    cp = get_configParser(filename)
+    try:
+        cp.add_section(url)
+    except OscConfigParser.ConfigParser.DuplicateSectionError:
+        # Section might have existed, but was empty
+        pass
+    if config['gnome_keyring'] and GNOME_KEYRING:
+        protocol, host = \
+            parse_apisrv_url(None, url)
+        gnomekeyring.set_network_password_sync(
+            user = user,
+            password = passwd,
+            protocol = protocol,
+            server = host)
+        cp.set(url, 'keyring', '1')
+    else:
+        cp.set(url, 'user', user)
+        cp.set(url, 'pass', passwd)
+    file = open(filename, 'w')
+    cp.write(file, True)
+    if file: file.close()
 
+
 def get_config(override_conffile = None, 
                override_apisrv = None,
                override_debug = None, 
                override_http_debug = None, 
                override_traceback = None,
-               override_post_mortem = None):
+               override_post_mortem = None,
+               override_no_gnome_keyring = None):
     """do the actual work (see module documentation)"""
     import os
     import sys
@@ -332,13 +384,35 @@
     # the following regexp does _not_ support quoted commas within the value.
     http_header_regexp = re.compile(r"\s*(.*?)\s*:\s*(.*?)\s*(?:,\s*|\Z)")
 
+    # 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_gnome_keyring: 
+        config['gnome_keyring'] = False
+
     for url in [ x for x in cp.sections() if x != 'general' ]:
-        dummy, host = \
+        protocol, host = \
             parse_apisrv_url(config['scheme'], url)
-        #FIXME: this could actually be the ideal spot to take defaults
-        #from the general section.
-        user         = cp.get(url, 'user')
-        password     = cp.get(url, 'pass')
+        user = None
+        # Read from gnome keyring if available
+        if config['gnome_keyring'] and GNOME_KEYRING:
+            try:
+                gk_data = gnomekeyring.find_network_password_sync(
+                    protocol = protocol,
+                    server = host)
+                password = gk_data[0]['password']
+                user = gk_data[0]['user']
+            except gnomekeyring.NoMatchError:
+                # Fallback to file based auth.
+                pass
+        # Read credentials from config
+        if user is None:
+            #FIXME: this could actually be the ideal spot to take defaults
+            #from the general section.
+            user         = cp.get(url, 'user')
+            password     = cp.get(url, 'pass')
+            if cp.has_option(url, 'keyring') and cp.get(url, 'keyring'):
+                # This APIURL was configured to use keyring by
+                continue
 
         if cp.has_option(url, 'http_headers'):
             http_headers = cp.get(url, 'http_headers')
Index: osc/commandline.py
===================================================================
--- osc/commandline.py	(revision 5802)
+++ osc/commandline.py	(working copy)
@@ -59,6 +59,8 @@
         optparser.add_option('-c', '--config', dest='conffile',
                       metavar='FILE',
                       help='specify alternate configuration file')
+        optparser.add_option('--no-gnome-keyring', action='store_true',
+                      help='disable usage of GNOME Keyring')
         return optparser
 
 
@@ -70,7 +72,8 @@
                             override_debug = self.options.debug,
                             override_http_debug = self.options.http_debug,
                             override_traceback = self.options.traceback,
-                            override_post_mortem = self.options.post_mortem)
+                            override_post_mortem = self.options.post_mortem,
+                            override_no_gnome_keyring = self.options.no_gnome_keyring)
         except oscerr.NoConfigfile, e:
             print >>sys.stderr, e.msg
             print >>sys.stderr, 'Creating osc configuration file %s ...' % e.file
@@ -87,13 +90,7 @@
             import getpass
             user = raw_input('Username: ')
             passwd = getpass.getpass()
-            cp = conf.get_configParser()
-            cp.add_section(e.url)
-            cp.set(e.url, 'user', user)
-            cp.set(e.url, 'pass', passwd)
-            file = open(e.file, 'w')
-            cp.write(file, True)
-            if file: file.close()
+            conf.add_section(e.file, e.url, user, passwd)
             if try_again: self.postoptparse(try_again = False)
 
         self.conf = conf
