Using msmtp with the GNOME keyring
Using msmtp with gnome keyring
If you use mutt to manage your mail, you are probably using msmtp to manage your mail delivery.
Probably you don’t like the fact that you have you store your SMTP
password unencrypted in your $HOME/.msmtprc file.
Fear no more! Satoru Satoh has added support for the GNOME keyring, and, thanks to Martin Lambers, that’s already in the CVS tree.
So, if you want to use it, follow this easy steps:
$ cvs -d:pserver:anonymous@msmtp.cvs.sourceforge.net:/cvsroot/msmtp login $ cvs -z3 -d:pserver:anonymous@msmtp.cvs.sourceforge.net:/cvsroot/msmtp co -P msmtp $ cd msmtp $ autoreconf -i $ ./configure --with-gnome-keyring --prefix=/usr/local/msmtp-cvs $ make $ sudo make install Check that it is properly compiled with keyring support with: $ ldd /usr/local/msmtp-cvs/bin/msmtp | grep keyring libgnome-keyring.so.0 => /usr/lib/libgnome-keyring.so.0 (0xb7d2c000)
There’s a problem, though. Msmtp has no support for setting this password inside the gnome keyring.
To handle this, i have made this little python script that will help you to do so. Thanks to Satoh again for this post where he explains how the gnome keyring bindings for python work.
Here you have a sample session of this script:
$ ./msmtp-keyring-manage-password.py -s --username=myuser --server=smtp.example.com Password for user 'myuser' in server 'smtp.example.com' ? Confirmation, Password for user 'myuser' in server 'smtp.example.com' ? $ ./msmtp-keyring-manage-password.py -g --username=myuser --server=smtp.example.com Password for user 'myuser' in server 'smtp.example.com' : foo
And here you have the script. You can download it from github, to avoid problems with python and whitespace.
#!/usr/bin/python # -*- coding: utf-8 -*- import gnomekeyring as gk, sys, optparse, getpass def set_keyring_password_for_msmtp_user(user, password, server): # Does it already exist? if get_keyring_password_for_msmtp_user(user, server) is not None: error_msg = "SMTP password for user '%s' in server '%s' does already exists" %(user, server) return (False, error_msg) # get default keyring name. you can also specify it explicitly. keyring = gk.get_default_keyring_sync() # display name for password. display_name = 'SMTP password for %s at %s'%(user, server) # select type. if you want some kind of "network" password, it seems that # appropriate type is network_password because it has a schema already. type = gk.ITEM_NETWORK_PASSWORD usr_attrs = {'user':user, 'server':server, 'protocol':'smtp'} # Now it gets ready to add into the keyring. Do it. # Its id will be returned if success or an exception will be raised id = gk.item_create_sync(keyring, type, display_name, usr_attrs, password, False) return (True, "") def get_keyring_password_for_msmtp_user(user, server): try: results = gk.find_network_password_sync(user=user, server=server, protocol='smtp') except gk.NoMatchError: return None return results[0]["password"] def main(): usage = "%prog [-s|-g] --username myuser --server myserver" parser = optparse.OptionParser(usage=usage) parser.add_option("-s", "--set-password", action="store_true", dest="setpass", help="Set password for msmtp acount") parser.add_option("-g", "--get-password", action="store_true", dest="getpass", help="Get password for msmstp account") parser.add_option("-u", "--username", action="store", dest="username", help="Username for msmtp account") parser.add_option("-e", "--server", action="store", dest="server", help="SMTP server for msmtp account") (opts, args) = parser.parse_args() if not opts.setpass and not opts.getpass: parser.print_help() print "You have to use -s or -g !!" return -1 if not opts.username or not opts.server: parser.print_help() print "You have to use both --username and --server !!" return -1 elif opts.getpass: passwd = get_keyring_password_for_msmtp_user(opts.username, opts.server) print "Password for user '%s' in server '%s' : %s" %(opts.username, opts.server, passwd) else: # setpass msg = "Password for user '%s' in server '%s' ? " %(opts.username, opts.server) passwd = getpass.getpass(msg) passwd_confirmation = getpass.getpass("Confirmation, " + msg) if passwd != passwd_confirmation: print "Password and password confirmation are different, exiting..." return -1 status_ok, error_msg = set_keyring_password_for_msmtp_user(opts.username, passwd, opts.server) if not status_ok: print error_msg return -1 return 0 if __name__ == '__main__': sys.exit(main())
Hope this is useful to somebody!!
Discussion Area - Leave a Comment