diff --git a/Makefile.am b/Makefile.am
index b335e07..5627854 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,7 +25,8 @@ gnomeblog_PYTHON = 		\
 	rich_entry.py		\
 	html_converter.py	\
 	gnome_blog_globals.py   \
-	proxy.py
+	proxy.py		\
+	blog_keyring.py
 
 
 16icondir = $(datadir)/icons/hicolor/16x16/apps
diff --git a/blog.py b/blog.py
index 05fb211..a5ccdc0 100644
--- a/blog.py
+++ b/blog.py
@@ -1,4 +1,5 @@
 import gconf
+from blog_keyring import BlogKeyring
 
 class FeatureNotSupported(Exception):
     def __init__(self, unknownMethod):
@@ -46,11 +47,13 @@ def uploadImage (image, gconf_prefix):
     return imageurl
 
 def _getSettings(client, gconf_prefix):
+    keyring  = BlogKeyring ()
+
     print "Using prefix %s" % (gconf_prefix)
     username = client.get_string(gconf_prefix + "/blog_username")
-    password = client.get_string(gconf_prefix + "/blog_password")
     protocol = client.get_string(gconf_prefix + "/blog_protocol")
     url      = client.get_string(gconf_prefix + "/xmlrpc_url")
+    password = keyring.get_password (protocol, username)
 
     return username, password, protocol, url
 
diff --git a/blog_keyring.py b/blog_keyring.py
new file mode 100644
index 0000000..5f60edf
--- /dev/null
+++ b/blog_keyring.py
@@ -0,0 +1,36 @@
+import gnomekeyring
+
+# inspired by Sebastian Rittau
+class BlogKeyring (object):
+    def __init__ (self):
+        self.name = "Gnome Blog"
+        self.server = "localhost"
+        # protocol = ""
+        self.keyring = gnomekeyring.get_default_keyring_sync ()
+
+    def get_password (self, blog_type, username):
+        print "getting..."
+        print blog_type
+        print username
+
+        attrs = { "gnome_blog_type": blog_type, "username": username }
+        try:
+            items = gnomekeyring.find_items_sync (gnomekeyring.ITEM_GENERIC_SECRET, attrs);
+            return items[0].secret
+        except gnomekeyring.NoMatchError as message:
+            print "No username or password found for user %s on blog %s (%s)" % (username, blog_type, message)
+            return ""
+        except KeyError as message:
+            print "Error retrieving username: %s" % message
+            return ""
+
+    def set_username_and_password (self, blog_type, username, password):
+        attrs = { "gnome_blog_type": blog_type, "username": username }
+        gnomekeyring.item_create_sync (self.keyring, gnomekeyring.ITEM_GENERIC_SECRET,
+                                       "%s password for %s/%s" % (self.name, blog_type, username), attrs, password, True);
+
+    def update (self, password_entry, protocol_menu, username_entry):
+        self.set_username_and_password (protocol_menu.get_current_key (),
+                                        username_entry.get_text (), password_entry.get_text ())
+        
+    
diff --git a/blogger_prefs.py b/blogger_prefs.py
index c466eed..580db68 100644
--- a/blogger_prefs.py
+++ b/blogger_prefs.py
@@ -1,5 +1,6 @@
 import gtk
 import gconf
+from blog_keyring import BlogKeyring
 
 from gettext import gettext as _
 
@@ -75,10 +76,22 @@ class BloggerPrefs(gtk.Dialog):
         table.attach(LeftLabel(_("Password:")), 0, 1, 3, 4, xoptions=gtk.FILL)
         table.attach(self.blogLabel, 0, 1, 4, 5, xoptions=gtk.FILL)
 
+        usernameEntry = gconf_widgets.Entry(gconf_prefix + "/blog_username")
+
+        # setup the password for live updating from the keyring
+        keyring = BlogKeyring ()
+        passwordEntry = gtk.Entry ()
+        passwordEntry.set_visibility (False)
+        passwordEntry.connect ("changed", keyring.update, self.blogProtocolMenu, usernameEntry);
+        self.blogProtocolMenu.connect ("changed", self._check_for_password, self.blogProtocolMenu, usernameEntry, passwordEntry, keyring)
+        usernameEntry.connect ("changed", self._check_for_password, self.blogProtocolMenu, usernameEntry, passwordEntry, keyring)
+        self._check_for_password (None, self.blogProtocolMenu, usernameEntry, passwordEntry, keyring)
+      
+        
         table.attach(self.blogProtocolMenu, 1, 3, 0, 1)
         table.attach(self.urlEntry, 1, 3, 1, 2)
-        table.attach(gconf_widgets.Entry(gconf_prefix + "/blog_username"), 1, 3, 2, 3)
-        table.attach(gconf_widgets.Entry(gconf_prefix + "/blog_password", True), 1, 3, 3, 4)
+        table.attach(usernameEntry, 1, 3, 2, 3)
+        table.attach(passwordEntry, 1, 3, 3, 4)
         table.attach(self.blogMenu, 1, 2, 4, 5)
         table.attach(self.lookupButton, 2, 3, 4, 5, xoptions=gtk.FILL)
 
@@ -97,6 +110,10 @@ class BloggerPrefs(gtk.Dialog):
         blog_type = client.get_string(gconf_prefix + "/blog_type")
         self._updateBlogType(blog_type)
 
+    def _check_for_password (self, target, protocolMenu, usernameEntry, passwordEntry, keyring):
+        password = keyring.get_password (protocolMenu.get_current_key (), usernameEntry.get_text ());
+        if password is not None and password != "": 
+            passwordEntry.set_text (password)
 
     def _gconfBlogTypeChange (self, client, cnxn_id, entry, what):
         blog_type = entry.value.get_string()
diff --git a/gconf_widgets.py b/gconf_widgets.py
index 1d93782..c892935 100644
--- a/gconf_widgets.py
+++ b/gconf_widgets.py
@@ -54,11 +54,15 @@ class OptionMenu(gtk.OptionMenu):
         gconf_value = entry.value.get_string()
         self._setMenuFromValue(gconf_value)
 
+    def get_current_key (self):
+        try:
+            return self.values[self.get_history ()]
+        except BaseException:
+            print "Could not find last accessed key, returning first."
+            return self.values[0]
+
     def _onChanged(self, optionmenu):
-        index = optionmenu.get_history()
-        value = self.values[index]
-        
-        self.client.set_string(self.gconf_key, value)
+        self.client.set_string(self.gconf_key, self.get_current_key ())
 
 class Entry(gtk.Entry):
     def _onGConfChange (self, client, cnxn_id, entry, what):
diff --git a/protocols/atomBloggerAPI.py b/protocols/atomBloggerAPI.py
index 24749e2..9a10f63 100644
--- a/protocols/atomBloggerAPI.py
+++ b/protocols/atomBloggerAPI.py
@@ -25,14 +25,18 @@ class Blog:
         
         try:
             blogger_service = self._login (username, password)
-        except service.CaptchaRequired, e:
+        except service.CaptchaRequired as message:
             hig_alert.reportError (error_name, _("A captcha was required for authentication.")) # TODO: propagadate captcha
-        except service.BadAuthentication, e:
+            return None
+        except service.BadAuthentication as message:
             hig_alert.reportError (error_name, _("Username or password was invalid."))
-        except service.Error, e:
-            hig_alert.reportError (error_name, _("Failed to login: %s" % e.message))
-        except socket.gaierror, e:
-            hig_alert.reportError (error_name, _("Socket error: %s.  Perhaps try again." % e.message));
+            return None
+        except service.Error as message:
+            hig_alert.reportError (error_name, _("Failed to login: %s" % message))
+            return None
+        except socket.gaierror as message:
+            hig_alert.reportError (error_name, _("Socket error: %s.  Perhaps try again." % message));
+            return None
 
         blog_list = blogger_service.Get ('/feeds/default/blogs'); # is there anyway to sort these by recently used?
 
@@ -54,7 +58,7 @@ class Blog:
             username = username + "@gmail.com";
 
         service = gdata.service.GDataService (username, password)
-        service.source = "GnomeBlog patch"
+        service.source = "Gnome Blog"
         service.service = "blogger"
         service.server = "www.blogger.com"
         service.ProgrammaticLogin ()
@@ -91,23 +95,24 @@ class Blog:
         error_name = _("Could not post entry.")
         try:
             blogger_service = self._login (username, password)
-        except service.CaptchaRequired, e:
+        except service.CaptchaRequired as message:
             hig_alert.reportError (error_name, _("A captcha was required for authentication.")) # TODO; propagate it
             success = False
-        except service.BadAuthentication, e:
+        except service.BadAuthentication as message:
             hig_alert.reportError (error_name, _("Username or password was invalid."))
             success = False
-        except service.Error, e:
-            hig_alert.reportError (error_name, _("Failed to login: %s" % e.message))
+        except service.Error as message:
+            hig_alert.reportError (error_name, _("Failed to login: %s" % message))
             success = False
-        except socket.gaierror, e:
-            hig_alert.reportError (error_name, _("Socket error: %s.  Perhaps try again." % e.message));
+        except socket.gaierror as message:
+            hig_alert.reportError (error_name, _("Socket error: %s.  Perhaps try again." % message));
             success = False
 
-        try:
-            blogger_service.Post (post, "/feeds/%s/posts/default" % blog_id)
-        except service.RequestError, e:
-            hig_alert.reportError (error_name, _("Failed to post: %s" % e.message['body']))
+        if success == True:
+            try:
+                blogger_service.Post (post, "/feeds/%s/posts/default" % blog_id)
+            except service.RequestError as message:
+                hig_alert.reportError (error_name, _("Failed to post: %s" % message['body']))
 
         return success
 
