Gentoo Wiki ArchivesGentoo Wiki

HOWTO_Use_gnome-keyring_to_store_SSH_passphrases

Contents

Introduction

This HOWTO is intended for Gnome users who use the ssh-agent utility to achieve passwordless logins with SSH, when their RSA/DSA keys are protected by a passphrase. This tutorial assumes you already use public-key authentication and does NOT cover setting this up. Basic familiarity with (bash) shell scripting, C programming, and the ssh-agent and ssh-add commands is required.

When faced with a key that is protected by a passphrase, ssh-add will either prompt for the passphrase from the user's tty, if run from a terminal, or read the passphrase from the output of the command specified in the SSH_ASKPASS environment variable (or /usr/lib/misc/ssh-askpass if unspecified) (see man ssh-add).

A small tool programmed in the C language is presented, providing basic command-line access to the Gnome keyring. This tool, coupled with a few trivial shell scripts, provides the link between ssh-add and the Gnome keyring. This approach allows multiple keys where the passphrases are different to be added to the ssh-agent with only your Gnome keyring passphrase needed.

Warning: The Gnome keyring library (libgnome-keyring) is under development, and the API is likely to change in future versions. The current stable version of gnome-keyring at the time of writing is 0.6.0. The C-language tool presented here uses this version. This tool must be regarded as UNSTABLE to future versions of the Gnome keyring, and changes may be required.

Part 1: gnome-keyring-query

This section describes the C-language tool, called gnome-keyring-query, that will provide limited command-line access to the Gnome keyring for the purposes of this HOWTO and possibly other applications requiring basic access to the Gnome keyring.

gnome-keyring-query has the capability to store and retrieve simple name/passphrase pairs in the default keyring. Unlike applications like Nautilus and Evolution, no additional fields are stored, with the exception of a 'magic' field to distinguish keys created by gnome-keyring-query from those created by other applications. In the context of this HOWTO, nothing more than this is required. gnome-keyring-query will only read passphrases that it created.

Use of the tool will be as follows:

Usage:
    gnome-keyring-query <mode> <name>
Parameters:
    mode  - either 'get' or 'set' (without quotes)
    name  - a name to identify the key
Notes:
    If mode is 'get', then the password is dumped to stdout.
    If mode is 'set', then the password is read from stdin.

For example, you wish to store the passphrase to your dev.gentoo.org DSA key. Choose a simple name for the passphrase, e.g: "gentoo-dsa", and enter the following command:

$ echo -n "letmein123" | gnome-keyring-query set gentoo-dsa

The Gnome Keyring Manager tool (gnome-extra/gnome-keyring-manager) will list your passphrase in the default keyring.

To fetch your key, simply enter:

$ gnome-keyring-query get gentoo-dsa
letmein123

The source code is provided in the PUBLIC DOMAIN, AS-IS, without warranty:

Code: gnome-keyring-query.c

(note scrollbar on bottom)

 #include <stdlib.h>
 #include <stdio.h>
 
 #include <glib.h>
 #include "gnome-keyring.h"
 
 
 #define APPLICATION_NAME "gnome-keyring-query"
 #define MAX_PASSWORD_LENGTH 100
 
 
 char * get_password(const char * name);
 int    set_password(const char * name, const char * password);
 
 
 void usage()
 {
     puts("Usage:\n"
          "    " APPLICATION_NAME " <mode> <name>\n"
          "Parameters:\n"
          "    mode     - either 'get' or 'set' (without quotes)\n"
          "    name     - a name to identify the key\n"
          "Notes:\n"
          "    If mode is 'get', then the password is dumped to stdout.\n"
          "    If mode is 'set', then the password is read from stdin.\n");
     exit(EXIT_FAILURE);
 }
 
 
 int main(int argc, char * argv[])
 {
     enum
     {
         MODE_GET, MODE_SET
     } mode;
     char * name;
     char * password;
     
     g_set_application_name(APPLICATION_NAME);
     
     if (argc != 3)
         usage();
         
     if (g_ascii_strcasecmp(argv[1], "get") == 0)
         mode = MODE_GET;
     else if (g_ascii_strcasecmp(argv[1], "set") == 0)
         mode = MODE_SET;
     else
     {
         fprintf(stderr, "Invalid mode: %s\n", argv[1]);
         exit(EXIT_FAILURE);
     }
     
     name = argv[2];
     
     switch (mode)
     {
         case MODE_GET:
             password = get_password(name);
             if (!password)
             {
                 fprintf(stderr, "Failed to get password: %s\n", name);
                 exit(EXIT_FAILURE);
             }
             
             puts(password);
             g_free(password);
             break;
             
         case MODE_SET:
             password = g_malloc(MAX_PASSWORD_LENGTH);
             *password = '\0';
             fgets(password, MAX_PASSWORD_LENGTH, stdin);
             
             if (!set_password(name, password))
             {
                 fprintf(stderr, "Failed to set password: %s\n", name);
                 exit(EXIT_FAILURE);
             }
             
             g_free(password);
             break;
     }
     
     return 0;
 }
 
 
 char * get_password(const char * name)
 {
     GnomeKeyringAttributeList * attributes;
     GnomeKeyringResult result;
     GList * found_list;
     GList * i;
     GnomeKeyringFound * found;
     char * password;
     
     attributes = g_array_new(FALSE, FALSE, sizeof (GnomeKeyringAttribute));
     gnome_keyring_attribute_list_append_string(attributes,
             "name",
             name);
     gnome_keyring_attribute_list_append_string(attributes,
             "magic",
             APPLICATION_NAME);
     
     result = gnome_keyring_find_items_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET,
             attributes,
             &found_list);
     gnome_keyring_attribute_list_free(attributes);
     
     if (result != GNOME_KEYRING_RESULT_OK)
         return NULL;
     
     for (i = found_list; i != NULL; i = i->next)
     {
         found = i->data;
         password = g_strdup(found->secret);
         break;
     }
     gnome_keyring_found_list_free(found_list);
     
     return password;
 }
 
 
 int set_password(const char * name, const char * password)
 {
     GnomeKeyringAttributeList * attributes;
     GnomeKeyringResult result;
     guint item_id;
     
     attributes = g_array_new(FALSE, FALSE, sizeof (GnomeKeyringAttribute));
     gnome_keyring_attribute_list_append_string(attributes,
             "name",
             name);
     gnome_keyring_attribute_list_append_string(attributes,
             "magic",
             APPLICATION_NAME);
     
     result = gnome_keyring_item_create_sync(NULL,
             GNOME_KEYRING_ITEM_GENERIC_SECRET,
             name,
             attributes,
             password,
             TRUE,
             &item_id);
     gnome_keyring_attribute_list_free(attributes);
     
     return (result == GNOME_KEYRING_RESULT_OK);
 }

The program may be compiled as follows:

$ gcc `pkg-config --cflags --libs gnome-keyring-1 glib-2.0` -o gnome-keyring-query gnome-keyring-query.c

/usr/local/bin is a suitable place to install the program:

# cp gnome-keyring-query /usr/local/bin/
# chmod +x /usr/local/bin/gnome-keyring-query

Part 2: Shell scripts

The caveat with ssh-add's use of the program specified in the SSH_ASKPASS environment variable, is that it does not provide any mechanism for passing arguments to the program. Since the gnome-keyring-query tool was developed for generality, it requires command-line arguments to function. A trivial wrapper script needs to be supplied for each individual key you wish to add using this method. The sole purpose of the script is to launch the gnome-keyring-query tool with the appropriate arguments as a single command able to be executed by ssh-add.

Following the example earlier, such a script would look like this:

File: ~/ssh-askpass-gentoo-dsa.sh
#!/bin/sh
exec gnome-keyring-query get gentoo-dsa

Using gnome-keyring-query set ..., add all your passphrases to the Gnome keyring. Then, create a script like the one above for each. Your home directory would be an appropriate place to create these scripts.

Part 3: Executing ssh-add - tying it all together

The final step is to create the script that will do the work. It's purpose is to set the SSH_ASKPASS environment variable and run ssh-add for each key you want to add. This script can be called by your session manager (e.g: gnome-session) when you log in. Because your Gnome keyring will still be locked just after you log in, you will be presented with the familiar keyring passphrase prompt as the script reads the first passphrase from the keyring. Once done, the passphrases to all your SSH keys will be read from it and the keys added to your ssh-agent.

The following example uses the Gentoo DSA key from earlier examples, and two other keys:

File: ~/my-ssh-add.sh
#!/bin/sh
SSH_ASKPASS="~/ssh-askpass-gentoo-dsa.sh"      ssh-add ~/.ssh/id_dsa-gentoo < /dev/null
SSH_ASKPASS="~/ssh-askpass-sourceforge-rsa.sh" ssh-add ~/.ssh/id_rsa-sf < /dev/null
SSH_ASKPASS="~/ssh-askpass-localkeys.sh"       ssh-add < /dev/null

Since /dev/null is obviously not a tty, piping it to ssh-add forces ssh-add to consult the SSH_ASKPASS environment variable (see Introduction) and run the command there. If this was omitted, ssh-add would wait indefinitely for a passphrase from gnome-session, which is never going to give it. Alternatively if you called the script manually from a terminal (obviously a tty), ssh-add would simply prompt you for the passphrase like it did before you started this tutorial.

Your home directory is a good place for this file too.

You may have this script executed by gnome-session by adding it to the list in System » Preferences » Sessions » 'Startup Programs' tab

Summary

The following files were created in this tutorial:

FileDescription
/usr/local/bin/gnome-keyring-queryCommand-line tool to give shell scripts basic access to the GNOME keyring.
gnome-keyring-query.cSource code for gnome-keyring-query tool.
~/ssh-askpass-*.shVarious scripts intended to be run by ssh-add itself, that execute the gnome-keyring-query tool with the appropriate arguments supplying the right passphrases to ssh-add.
~/my-ssh-add.shSingle script suitable to be called upon login that sets up the SSH_ASKPASS environment variable to each ssh-askpass-*.sh script and runs ssh-add for each key.

See also

Retrieved from "http://www.gentoo-wiki.info/Store_SSH_passphrases_in_gnome-keyring"

Last modified: Sat, 06 Sep 2008 23:08:00 +1000 Hits: 21,716

Created by NickStallman.net, Luxury Homes Australia
Real estate agents should list their apartments, townhouses and units in Australia.