Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Use libsecret instead of gnome-keyring.
Browse files Browse the repository at this point in the history
  • Loading branch information
Oden committed Nov 19, 2016
1 parent dad012e commit 85becc1
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ addons:
packages:
- xvfb
- gnome-keyring
- libgnome-keyring-dev
- libsecret-1-dev

env:
- CC=clang CXX=clang++ npm_config_clang=1
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Status](https://travis-ci.org/atom/node-keytar.svg?branch=master)](https://travi

A native Node module to get, add, replace, and delete passwords in system's
keychain. On OS X the passwords are managed by the Keychain, on Linux they are
managed by Gnome Keyring and on Windows they are managed by Credential Vault.
managed by the Secret Service API/libsecret, and on Windows they are managed by Credential Vault.

## Installing

Expand All @@ -15,9 +15,13 @@ npm install keytar

### On Linux

Currently this library uses the gnome-keyring so you may need to run `sudo apt-get install libgnome-keyring-dev` before `npm install`ing.
Currently this library uses `libsecret` so you may need to install it before `npm install`ing.

If you are using a Red Hat-based system you need to run `sudo yum install libgnome-keyring-devel`.
Depending on your distribution, you will need to run the following command:

* Debian/Ubuntu: `sudo apt-get install libsecret-1-dev`
* Red Hat-based: `sudo yum install libsecret-devel`
* Arch Linux: `sudo pacman -S libsecret`

## Building
* Clone the repository
Expand Down
6 changes: 3 additions & 3 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@
'src/keytar_posix.cc',
],
'cflags': [
'<!(pkg-config --cflags gnome-keyring-1)',
'<!(pkg-config --cflags libsecret-1)',
'-Wno-missing-field-initializers',
'-Wno-deprecated-declarations',
],
'link_settings': {
'ldflags': [
'<!(pkg-config --libs-only-L --libs-only-other gnome-keyring-1)',
'<!(pkg-config --libs-only-L --libs-only-other libsecret-1)',
],
'libraries': [
'<!(pkg-config --libs-only-l gnome-keyring-1)',
'<!(pkg-config --libs-only-l libsecret-1)',
],
},
}],
Expand Down
116 changes: 75 additions & 41 deletions src/keytar_posix.cc
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
#include "keytar.h"

#include <gnome-keyring.h>
#include <libsecret/secret.h>
#include <stdio.h>

namespace keytar {

namespace {

const GnomeKeyringPasswordSchema kGnomeSchema = {
GNOME_KEYRING_ITEM_GENERIC_SECRET, {
{ "service", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
{ "account", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
{ NULL }
static const SecretSchema schema = {
"org.freedesktop.Secret.Generic", SECRET_SCHEMA_NONE, {
{ "service", SECRET_SCHEMA_ATTRIBUTE_STRING },
{ "account", SECRET_SCHEMA_ATTRIBUTE_STRING }
}
};

Expand All @@ -20,57 +19,92 @@ const GnomeKeyringPasswordSchema kGnomeSchema = {
bool AddPassword(const std::string& service,
const std::string& account,
const std::string& password) {
GnomeKeyringResult result = gnome_keyring_store_password_sync(
&kGnomeSchema,
NULL, // Default keyring.
(service + "/" + account).c_str(), // Display name.
password.c_str(),
"service", service.c_str(),
"account", account.c_str(),
NULL);
return result == GNOME_KEYRING_RESULT_OK;
GError *error = NULL;

secret_password_store_sync(
&schema, // The schema.
SECRET_COLLECTION_DEFAULT, // Default collection.
(service + "/" + account).c_str(), // The label.
password.c_str(), // The password.
NULL, // Cancellable. (unneeded)
&error, // Reference to the error.
"service", service.c_str(),
"account", account.c_str(),
NULL); // End of arguments.

if (error != NULL) {
g_error_free(error);
return false;
}

return true;
}

bool GetPassword(const std::string& service,
const std::string& account,
std::string* password) {
gchar* raw_passwords;
GnomeKeyringResult result = gnome_keyring_find_password_sync(
&kGnomeSchema,
&raw_passwords,
"service", service.c_str(),
"account", account.c_str(),
NULL);
if (result != GNOME_KEYRING_RESULT_OK)
GError *error = NULL;

gchar *raw_password = secret_password_lookup_sync(
&schema, // The schema.
NULL, // Cancellable. (unneeded)
&error, // Reference to the error.
"service", service.c_str(),
"account", account.c_str(),
NULL); // End of arguments.

if (error != NULL) {
g_error_free(error);
return false;
}

if (raw_password == NULL)
return false;

if (raw_passwords != NULL)
*password = raw_passwords;
gnome_keyring_free_password(raw_passwords);
*password = raw_password;
secret_password_free(raw_password);
return true;
}

bool DeletePassword(const std::string& service, const std::string& account) {
return gnome_keyring_delete_password_sync(
&kGnomeSchema,
"service", service.c_str(),
"account", account.c_str(),
NULL) == GNOME_KEYRING_RESULT_OK;
GError *error = NULL;

gboolean deleted = secret_password_clear_sync(
&schema, // The schema.
NULL, // Cancellable. (unneeded)
&error, // Reference to the error.
"service", service.c_str(),
"account", account.c_str(),
NULL); // End of arguments.

if (error != NULL) {
g_error_free(error);
return false;
}

return deleted;
}

bool FindPassword(const std::string& service, std::string* password) {
gchar* raw_passwords;
GnomeKeyringResult result = gnome_keyring_find_password_sync(
&kGnomeSchema,
&raw_passwords,
"service", service.c_str(),
NULL);
if (result != GNOME_KEYRING_RESULT_OK)
GError *error = NULL;

gchar *raw_password = secret_password_lookup_sync(
&schema, // The schema.
NULL, // Cancellable. (unneeded)
&error, // Reference to the error.
"service", service.c_str(),
NULL); // End of arguments.

if (error != NULL) {
g_error_free(error);
return false;
}

if (raw_password == NULL)
return false;

if (raw_passwords != NULL)
*password = raw_passwords;
gnome_keyring_free_password(raw_passwords);
*password = raw_password;
secret_password_free(raw_password);
return true;
}

Expand Down

0 comments on commit 85becc1

Please sign in to comment.