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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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."