Last active
March 5, 2019 03:58
-
-
Save adamhotep/e5798989187b393789c1 to your computer and use it in GitHub Desktop.
Simple command-line interface to GNOME keyring
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} |
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
@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
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.