Skip to content

Instantly share code, notes, and snippets.

@adamhotep
Last active March 5, 2019 03:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamhotep/e5798989187b393789c1 to your computer and use it in GitHub Desktop.
Save adamhotep/e5798989187b393789c1 to your computer and use it in GitHub Desktop.
Simple command-line interface to GNOME keyring
/*
* gnome-keyring-query, for simple command-line interactions with gnome-keyring.
*
* To compile and install:
*
* sudo apt-get install libgnome-keyring-dev libglib2.0-dev
* gcc `pkg-config --cflags --libs gnome-keyring-1 glib-2.0` -o gnome-keyring-query gnome-keyring-query.c
* chmod +x gnome-keyring-query
* sudo cp -p gnome-keyring-query /usr/local/bin/
*
* Forked from public domain code by author(s) unknown, archived at
* https://web.archive.org/web/20160326164519/http://www.gentoo-wiki.info/Store_SSH_passphrases_in_gnome-keyring
*
* All changes from the original source are Copyright 2014+ Adam Katz
* and are released under the GNU LGPL.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* See <http://www.gnu.org/licenses/> for full license text.
*
* BEERWARE: IF YOU THINK THIS IS WORTH IT, YOU ARE WELCOME TO BUY ME A BEER.
*/
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
/*
* Workaround for deprecation of libgnome-keyring (won't work forever)
* TODO: migrate to libsecret (which looks nontrivial, likely WONTFIX).
* Notes for that:
* https://codereview.chromium.org/292573002
* https://bugs.chromium.org/p/chromium/issues/detail?id=355223
*/
#define GNOME_KEYRING_DEPRECATED
#define GNOME_KEYRING_DEPRECATED_FOR(x)
#include "gnome-keyring.h"
#define APPLICATION_NAME "gnome-keyring-query"
#define VERSION "1.2.20190212"
#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"
"\nVersion: " VERSION "\n"
"https://gist.github.com/adamhotep/e5798989187b393789c1"
);
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);
}
@adamhotep
Copy link
Author

adamhotep commented Jul 26, 2014

I've added this as a gist so it can hold modifications and so it can be added to (either by me or via forking). The original, which lives on a Gentoo wiki archive article describing how to Store SSH passphrases in gnome keyring (dead link, archived here), is pretty much the same as this code. I merely added a version, a license, and a link. That original code was packaged into Arch Linux AUR. I see no indication of it having been packaged for Gentoo or any other distribution.

@qrkourier
Copy link

I was unable to compile with these instructions. The package manage did find and install the prescribed packages.

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=15.10
DISTRIB_CODENAME=wily
DISTRIB_DESCRIPTION="Ubuntu 15.10"

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.2.1-22ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2) 

$ gcc `pkg-config --cflags --libs gnome-keyring-1 glib-2.0` -o ./gnome-keyring-query ./gnome-keyring-query.c
./gnome-keyring-query.c: In function ‘get_password’:
./gnome-keyring-query.c:132:5: warning: ‘gnome_keyring_attribute_list_append_string’ is deprecated: Use 'g_hash_table_replace' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_append_string(attributes,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:145:28: note: declared here
 void                       gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
                            ^
./gnome-keyring-query.c:135:5: warning: ‘gnome_keyring_attribute_list_append_string’ is deprecated: Use 'g_hash_table_replace' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_append_string(attributes,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:145:28: note: declared here
 void                       gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
                            ^
./gnome-keyring-query.c:139:5: warning: ‘gnome_keyring_find_items_sync’ is deprecated: Use 'secret_service_search_sync' instead [-Wdeprecated-declarations]
     result = gnome_keyring_find_items_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:321:20: note: declared here
 GnomeKeyringResult gnome_keyring_find_items_sync  (GnomeKeyringItemType        type,
                    ^
./gnome-keyring-query.c:142:5: warning: ‘gnome_keyring_attribute_list_free’ is deprecated: Use 'g_hash_table_unref' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_free(attributes);
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:155:28: note: declared here
 void                       gnome_keyring_attribute_list_free          (GnomeKeyringAttributeList *attributes);
                            ^
./gnome-keyring-query.c:153:5: warning: ‘gnome_keyring_found_list_free’ is deprecated [-Wdeprecated-declarations]
     gnome_keyring_found_list_free(found_list);
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:174:6: note: declared here
 void gnome_keyring_found_list_free          (GList *found_list);
      ^
./gnome-keyring-query.c: In function ‘set_password’:
./gnome-keyring-query.c:166:5: warning: ‘gnome_keyring_attribute_list_append_string’ is deprecated: Use 'g_hash_table_replace' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_append_string(attributes,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:145:28: note: declared here
 void                       gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
                            ^
./gnome-keyring-query.c:169:5: warning: ‘gnome_keyring_attribute_list_append_string’ is deprecated: Use 'g_hash_table_replace' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_append_string(attributes,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:145:28: note: declared here
 void                       gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
                            ^
./gnome-keyring-query.c:173:5: warning: ‘gnome_keyring_item_create_sync’ is deprecated: Use 'secret_item_create_sync' instead [-Wdeprecated-declarations]
     result = gnome_keyring_item_create_sync(NULL,
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:340:20: note: declared here
 GnomeKeyringResult gnome_keyring_item_create_sync         (const char                                 *keyring,
                    ^
./gnome-keyring-query.c:180:5: warning: ‘gnome_keyring_attribute_list_free’ is deprecated: Use 'g_hash_table_unref' instead [-Wdeprecated-declarations]
     gnome_keyring_attribute_list_free(attributes);
     ^
In file included from ./gnome-keyring-query.c:34:0:
/usr/include/gnome-keyring-1/gnome-keyring.h:155:28: note: declared here
 void                       gnome_keyring_attribute_list_free          (GnomeKeyringAttributeList *attributes);
                            ^
/tmp/cc805G8V.o: In function `main':
gnome-keyring-query.c:(.text+0x2d): undefined reference to `g_set_application_name'
gnome-keyring-query.c:(.text+0x55): undefined reference to `g_ascii_strcasecmp'
gnome-keyring-query.c:(.text+0x7a): undefined reference to `g_ascii_strcasecmp'
gnome-keyring-query.c:(.text+0x128): undefined reference to `g_free'
gnome-keyring-query.c:(.text+0x134): undefined reference to `g_malloc'
gnome-keyring-query.c:(.text+0x1a1): undefined reference to `g_free'
/tmp/cc805G8V.o: In function `get_password':
gnome-keyring-query.c:(.text+0x1d8): undefined reference to `g_array_new'
gnome-keyring-query.c:(.text+0x1f1): undefined reference to `gnome_keyring_attribute_list_append_string'
gnome-keyring-query.c:(.text+0x207): undefined reference to `gnome_keyring_attribute_list_append_string'
gnome-keyring-query.c:(.text+0x21c): undefined reference to `gnome_keyring_find_items_sync'
gnome-keyring-query.c:(.text+0x22b): undefined reference to `gnome_keyring_attribute_list_free'
gnome-keyring-query.c:(.text+0x262): undefined reference to `g_strdup'
gnome-keyring-query.c:(.text+0x273): undefined reference to `gnome_keyring_found_list_free'
/tmp/cc805G8V.o: In function `set_password':
gnome-keyring-query.c:(.text+0x2c0): undefined reference to `g_array_new'
gnome-keyring-query.c:(.text+0x2d9): undefined reference to `gnome_keyring_attribute_list_append_string'
gnome-keyring-query.c:(.text+0x2ef): undefined reference to `gnome_keyring_attribute_list_append_string'
gnome-keyring-query.c:(.text+0x322): undefined reference to `gnome_keyring_item_create_sync'
gnome-keyring-query.c:(.text+0x335): undefined reference to `gnome_keyring_attribute_list_free'
collect2: error: ld returned 1 exit status

@adamhotep
Copy link
Author

adamhotep commented Aug 12, 2016

@qrkourier – Sorry, I must have missed the github notification for that comment.

Looks like the guts of GNOME keyring are slated for removal. This code depends on deprecated methods and GNOME 3.12+ didn't want to let it happen without an explicit workaround. Solved, at least until "deprecated" becomes "obsoleted."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment