Code Monkey home page Code Monkey logo

keyring's Introduction

image

image

tests

Ruff

image

image

image

Join the chat at https://gitter.im/jaraco/keyring

The Python keyring library provides an easy way to access the system keyring service from python. It can be used in any application that needs safe password storage.

These recommended keyring backends are supported:

Other keyring implementations are available through Third-Party Backends.

Installation - Linux

On Linux, the KWallet backend relies on dbus-python, which does not always install correctly when using pip (compilation is needed). For best results, install dbus-python as a system package.

Compatibility - macOS

macOS keychain supports macOS 11 (Big Sur) and later requires Python 3.8.7 or later with the "universal2" binary. See #525 for details.

Using Keyring

The basic usage of keyring is pretty simple: just call keyring.set_password and keyring.get_password:

>>> import keyring
>>> keyring.set_password("system", "username", "password")
>>> keyring.get_password("system", "username")
'password'

Command-line Utility

Keyring supplies a keyring command which is installed with the package. After installing keyring in most environments, the command should be available for setting, getting, and deleting passwords. For more usage information, invoke with no arguments or with --help as so:

$ keyring --help
$ keyring set system username
Password for 'username' in 'system':
$ keyring get system username
password

The command-line functionality is also exposed as an executable package, suitable for invoking from Python like so:

$ python -m keyring --help
$ python -m keyring set system username
Password for 'username' in 'system':
$ python -m keyring get system username
password

Tab Completion

If installed via a package manager (apt, pacman, nix, homebrew, etc), these shell completions may already have been distributed with the package (no action required).

Keyring provides tab completion if the completion extra is installed:

$ pip install 'keyring[completion]'

Then, generate shell completions, something like:

$ keyring --print-completion bash | sudo tee /usr/share/bash-completion/completions/keyring
$ keyring --print-completion zsh | sudo tee /usr/share/zsh/site-functions/_keyring
$ keyring --print-completion tcsh | sudo tee /etc/profile.d/keyring.csh

Note: the path of /usr/share is mainly for GNU/Linux. For other OSs, consider:

  • macOS (Homebrew x86): /usr/local/share
  • macOS (Homebrew ARM): /opt/homebrew/share
  • Android (Termux): /data/data/com.termux/files/usr/share
  • Windows (mingw64 of msys2): /mingw64/share
  • ...

After installing the shell completions, enable them following your shell's recommended instructions. e.g.:

  • bash: install bash-completion, and ensure . /usr/share/bash-completion/bash_completion in ~/.bashrc.
  • zsh: ensure autoload -Uz compinit && compinit appears in ~/.zshrc, then grep -w keyring ~/.zcompdump to verify keyring appears, indicating it was installed correctly.

Configuring

The python keyring lib contains implementations for several backends. The library will attempt to automatically choose the most suitable backend for the current environment. Users may also specify the preferred keyring in a config file or by calling the set_keyring() function.

Config file path

The configuration is stored in a file named "keyringrc.cfg" found in a platform-specific location. To determine where the config file is stored, run keyring diagnose.

Config file content

To specify a keyring backend, set the default-keyring option to the full path of the class for that backend, such as keyring.backends.macOS.Keyring.

If keyring-path is indicated, keyring will add that path to the Python module search path before loading the backend.

For example, this config might be used to load the SimpleKeyring from the simplekeyring module in the ./demo directory (not implemented):

[backend]
default-keyring=simplekeyring.SimpleKeyring
keyring-path=demo

Third-Party Backends

In addition to the backends provided by the core keyring package for the most common and secure use cases, there are additional keyring backend implementations available for other use cases. Simply install them to make them available:

Write your own keyring backend

The interface for the backend is defined by keyring.backend.KeyringBackend. Every backend should derive from that base class and define a priority attribute and three functions: get_password(), set_password(), and delete_password(). The get_credential() function may be defined if desired.

See the backend module for more detail on the interface of this class.

Keyring employs entry points to allow any third-party package to implement backends without any modification to the keyring itself. Those interested in creating new backends are encouraged to create new, third-party packages in the keyrings namespace, in a manner modeled by the keyrings.alt package. See the setup.cfg file in that project for hints on how to create the requisite entry points. Backends that prove essential may be considered for inclusion in the core library, although the ease of installing these third-party packages should mean that extensions may be readily available.

To create an extension for Keyring, please submit a pull request to have your extension mentioned as an available extension.

Runtime Configuration

Keyring additionally allows programmatic configuration of the backend calling the api set_keyring(). The indicated backend will subsequently be used to store and retrieve passwords.

To invoke set_keyring:

# define a new keyring class which extends the KeyringBackend
import keyring.backend

class TestKeyring(keyring.backend.KeyringBackend):
    """A test keyring which always outputs the same password
    """
    priority = 1

    def set_password(self, servicename, username, password):
        pass

    def get_password(self, servicename, username):
        return "password from TestKeyring"

    def delete_password(self, servicename, username):
        pass

# set the keyring for keyring lib
keyring.set_keyring(TestKeyring())

# invoke the keyring lib
try:
    keyring.set_password("demo-service", "tarek", "passexample")
    print("password stored successfully")
except keyring.errors.PasswordSetError:
    print("failed to store password")
print("password", keyring.get_password("demo-service", "tarek"))

Disabling Keyring

In many cases, uninstalling keyring will never be necessary. Especially on Windows and macOS, the behavior of keyring is usually degenerate, meaning it will return empty values to the caller, allowing the caller to fall back to some other behavior.

In some cases, the default behavior of keyring is undesirable and it would be preferable to disable the keyring behavior altogether. There are several mechanisms to disable keyring:

  • Uninstall keyring. Most applications are tolerant to keyring not being installed. Uninstalling keyring should cause those applications to fall back to the behavior without keyring. This approach affects the Python environment where keyring would otherwise have been installed.
  • Configure the Null keyring in the environment. Set PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring in the environment, and the Null (degenerate) backend will be used. This approach affects all uses of Keyring where that variable is set.
  • Permanently configure the Null keyring for the user by running keyring --disable or python -m keyring --disable. This approach affects all uses of keyring for that user.

Altering Keyring Behavior

Keyring provides a mechanism to alter the keyring's behavior through environment variables. Each backend implements a KeyringBackend.set_properties_from_env, which when invoked will find all environment variables beginning with KEYRING_PROPERTY_{NAME} and will set a property for each {NAME.lower()} on the keyring. This method is invoked during initialization for the default/configured keyring.

This mechanism may be used to set some useful values on various keyrings, including:

  • keychain; macOS, path to an alternate keychain file
  • appid; Linux/SecretService, alternate ID for the application

Using Keyring on Ubuntu 16.04

The following is a complete transcript for installing keyring in a virtual environment on Ubuntu 16.04. No config file was used:

$ sudo apt install python3-venv libdbus-glib-1-dev
$ cd /tmp
$ pyvenv py3
$ source py3/bin/activate
$ pip install -U pip
$ pip install secretstorage dbus-python
$ pip install keyring
$ python
>>> import keyring
>>> keyring.get_keyring()
<keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8>
>>> keyring.set_password("system", "username", "password")
>>> keyring.get_password("system", "username")
'password'

Using Keyring on headless Linux systems

It is possible to use the SecretService backend on Linux systems without X11 server available (only D-Bus is required). In this case:

  • Install the GNOME Keyring daemon.
  • Start a D-Bus session, e.g. run dbus-run-session -- sh and run the following commands inside that shell.
  • Run gnome-keyring-daemon with --unlock option. The description of that option says:

    Read a password from stdin, and use it to unlock the login keyring or create it if the login keyring does not exist.

    When that command is started, enter a password into stdin and press Ctrl+D (end of data). After that, the daemon will fork into the background (use --foreground option to block).

  • Now you can use the SecretService backend of Keyring. Remember to run your application in the same D-Bus session as the daemon.

Using Keyring on headless Linux systems in a Docker container

It is possible to use keyring with the SecretService backend in Docker containers as well. All you need to do is install the necessary dependencies and add the --privileged flag to avoid any Operation not permitted errors when attempting to unlock the system's keyring.

The following is a complete transcript for installing keyring on a Ubuntu 18:04 container:

docker run -it -d --privileged ubuntu:18.04

$ apt-get update
$ apt install -y gnome-keyring python3-venv python3-dev
$ python3 -m venv venv
$ source venv/bin/activate # source a virtual environment to avoid polluting your system
$ pip3 install --upgrade pip
$ pip3 install keyring
$ dbus-run-session -- sh # this will drop you into a new D-bus shell
$ echo 'somecredstorepass' | gnome-keyring-daemon --unlock # unlock the system's keyring

$ python
>>> import keyring
>>> keyring.get_keyring()
<keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8>
>>> keyring.set_password("system", "username", "password")
>>> keyring.get_password("system", "username")
'password'

Integration

API

The keyring lib has a few functions:

  • get_keyring(): Return the currently-loaded keyring implementation.
  • get_password(service, username): Returns the password stored in the active keyring. If the password does not exist, it will return None.
  • get_credential(service, username): Return a credential object stored in the active keyring. This object contains at least username and password attributes for the specified service, where the returned username may be different from the argument.
  • set_password(service, username, password): Store the password in the keyring.
  • delete_password(service, username): Delete the password stored in keyring. If the password does not exist, it will raise an exception.

In all cases, the parameters (service, username, password) should be Unicode text.

Exceptions

The keyring lib raises the following exceptions:

  • keyring.errors.KeyringError: Base Error class for all exceptions in keyring lib.
  • keyring.errors.InitError: Raised when the keyring cannot be initialized.
  • keyring.errors.PasswordSetError: Raised when the password cannot be set in the keyring.
  • keyring.errors.PasswordDeleteError: Raised when the password cannot be deleted in the keyring.

Get Involved

Python keyring lib is an open community project and eagerly welcomes contributors.

Security Considerations

Each built-in backend may have security considerations to understand before using this library. Authors of tools or libraries utilizing keyring are encouraged to consider these concerns.

As with any list of known security concerns, this list is not exhaustive. Additional issues can be added as needed.

  • macOS Keychain
    • Any Python script or application can access secrets created by keyring from that same Python executable without the operating system prompting the user for a password. To cause any specific secret to prompt for a password every time it is accessed, locate the credential using the Keychain Access application, and in the Access Control settings, remove Python from the list of allowed applications.
  • Freedesktop Secret Service
    • No analysis has been performed
  • KDE4 & KDE5 KWallet
    • No analysis has been performed
  • Windows Credential Locker
    • No analysis has been performed

Making Releases

This project makes use of automated releases and continuous integration. The simple workflow is to tag a commit and push it to Github. If it passes tests in CI, it will be automatically deployed to PyPI.

Other things to consider when making a release:

  • Check that the changelog is current for the intended release.

Running Tests

Tests are continuously run in Github Actions.

To run the tests locally, install and invoke tox.

Background

The project was based on Tarek Ziade's idea in this post. Kang Zhang initially carried it out as a Google Summer of Code project, and Tarek mentored Kang on this project.

For Enterprise

Available as part of the Tidelift Subscription.

This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.

Learn more.

keyring's People

Contributors

bakernet avatar benji-york avatar bswck avatar cournape avatar dimbleby avatar frispete avatar ftruzzi avatar hugovk avatar jaraco avatar jim-easterbrook avatar jonnyjd avatar kangzhang avatar lovetox avatar maciex avatar mata-p avatar mekk avatar mindw avatar mitya57 avatar morguldir avatar multani avatar n8henrie avatar probro27 avatar rl-0x0 avatar sborho avatar scop avatar takluyver avatar tarekziade avatar webknjaz avatar wwuck avatar zooba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keyring's Issues

OSX install broken when using virtualenvs?

This lib seemed way interesting and got a bit of publicity a few weeks ago, so I decided to check it out the usual way: create a virtualenv, pip install the library inside it and play around.

Except I didn't get anywhere: get_password would always return None (with no keychain prompt) and set_password would throw OSError: Can't store password in Keychain, in both cases whatever the service & account are. After a few reinstallations, I tried compiling from scratch (cloning from mercurial and python setup.py build… success. Both tip (4a551eda6bf8) and tag 0.2 build and work perfectly.

Try to python setup.py install it in my virtualenv, failure again (except it now throws keyring.backend.PasswordSetError on set_password, due to being tip I guess).

Tested the same scenario in a fresh OpenSUSE image, no issue.


Log skipped tests

Currently if a test is not performed because the backend is unavailable, it will just tell the test is "OK" while it has been actually skipped.

Until unittest2 and its test skip support is mature enough, just log when a test is skipped instead of silently skipping it.

Depends on patch from <<issue 31>> being applied.


remove requirement for obj C compilation on Mac OS X

it's quite the pain that for this to work on Mac OS X (via say, pip install) i need to have gcc installed. i am going to work around this for my own purposes by falling back to the file-based encryption, but in the future, i wonder if you have looked at this module

https://launchpad.net/keychain.py/

which seems to implement mac os X keychain support without needing any objective C code.


keyring package implements its own Python extension modules to interface to the various backends

The keyring package implements its own Python extension modules to interface to the various backends instead of using the standard Python interfaces provided by the various libraries. For example the gnome keyring is accessible via the "gnomekeyring" Python module.

Relying on custom extension modules also means that many developer tools are required to be available when building the package (a compiler as well as the development versions of the backend provider's libraries).

This file has also been filed downstream at https://bugs.launchpad.net/ubuntu/+source/python-keyring/+bug/660819.


KWallet always opened at import when available

When KWallet is available it is always opened on import of keyring, even if the configuration is set to use another backend.

Therfore you are prompted for the KWallet password even if you don't use it.

Also when GnomeKeyring and KWallet are both available on a System, GnomeKeyring is used per default even within a KDE session.

I've created a fork which fixes this:
https://bitbucket.org/sutupud/python-keyring-lib

regards,
sutu


Configuring a built-in backend doesn't seem to work.

The page for keyring (http://pypi.python.org/pypi/keyring) claims that there are several built-in keyrings, but it's not clear how to configure them. I tried several different options for the default-keyring option, but none of them seem to work:

default-keyring=CryptedFileKeyring
default-keyring=simplekeyring.CryptedFileKeyring
default-keyring=keyring.CryptedFileKeyring
default-keyring=keyring.backend.CryptedFileKeyring

These all fail with various different errors. The last one seems to come closest, with an error of:

TypeError: The keyring must be a subclass of KeyringBackend

It would be nice to have an example on the webpage of how to configure one of the standard keyrings.


"import keyring" asks for all possible keyrings to be opened

Meeting with a keyring import anywhere in the code causes the script/interpreter to be blocked and asks for opening the kwallet and gnome-keyring for no reason.

A simple "help('modules')" would be blocked by this behavior.
It would be nice if import statements didn't actually run any interactive code...


Error on keyring password get/set shouldn't disrupt user action

Currently, if an error occurs on password setting or retrieval that causes an exception to be raised, the user action is interrupted.

This is impractical; if there's anything strange with the keyring, the user should be allowed to just go on working by manually entering the password, and shouldn't need to disable the keyring extensions at all in order to proceed.

Also fixes a condition in the current testcases where the test would randomly work because it did not really set a keyring before being run - i.e. the test success was dependent on the order the tests were run. I had to fix this in order to add a unit test for my enhancement.


Problem importing keyring through ssh

If I try to use keyring through ipython over ssh terminal it doesn't work well because on "import keyring", despite I've created a keyringrc.cfg file with:

default-keyring=keyring.backend.CryptedFileKeyring

the module try to load KDE Gui component.
I've created a patch where KDE Wallet is started only if you are trying to load KDEWallet backend.


WinVaultKeyring only ever returns last password set

WinVaultKeyring appears to only ever returns last password set. Win32CryptoKeyring works as expected.

#!python
>>> import keyring
>>> keyring.get_keyring()
<keyring.backend.WinVaultKeyring object at 0x00BFC170>
>>> keyring.set_password('service1', 'user1', 'password1')
>>> keyring.set_password('service1', 'user2', 'password2')
>>> keyring.get_password('service1', 'user1')
u'password2'
>>> keyring.set_password('service2', 'user3', 'password3')
>>> keyring.get_password('service1', 'user1')
u'password2'
# Now try Win32CryptoKeyring
>>> keyring.set_keyring(keyring.backend.Win32CryptoKeyring())
>>> keyring.set_password('service3', 'user1', 'password1')
>>> keyring.set_password('service3', 'user2', 'password2')
>>> keyring.get_password('service3', 'user1')
'password1'
>>> keyring.set_password('service4', 'user3', 'password3')
>>> keyring.get_password('service3', 'user1')
'password1'

KDEWallet not working anymore!

Hi,

I am using kde 4.6.1 and since some time keyring does not want to use the kdewallet backend.
If I force it in the config file, then libs using keyring just hang waiting for something that never happens…

I don't know how to debug that.

Thanks


Keyring package doesn't work if we use it from Windows service build using Python

I have came across a bug on "import keyring" when called from Windows Service. This was happening due to username default parameter in keyring.getpassbackend.get_password(). get_default_user() was raising exception because Windows service does not run as a logged-in user.

Following patch is required in keyring.getpassbackend.py

#!python

11c11,13
<                            username=get_default_user()):

---
>                            username=None):
>     if username is None:
>         username = get_default_user()

Please reassign this bug to responsible developer.

Thanks.


[OSX] Not installable via easy_install

$ easy_install keyring
Searching for keyring
Reading http://pypi.python.org/simple/keyring/
Reading http://keyring-python.org/
Download error: (8, 'nodename nor servname provided, or not known') -- Some packages may not be found!
Best match: keyring 0.1.macosx-10.3-fat
Downloading http://pypi.python.org/packages/2.6/k/keyring/keyring-0.1.macosx-10.3-fat.tar.gz#md5=8d9240e1ecaf29ec2618312a761d9698
Processing keyring-0.1.macosx-10.3-fat.tar.gz
error: Couldn't find a setup script in /var/folders/0r/0rvdcAjFF+iAIHS44pixXE+++TI/-Tmp-/easy_install-QwZhy2/keyring-0.1.macosx-10.3-fat.tar.gz
$

keyring backends are difficult to enable

The Gnome and KDE backends are difficult to build properly because
setup.py attempts to detect system dependencies and silently fails to
build backends which do not have the correct dependencies installed. A
potential solution would be to use the existing Python interfaces to
these systems instead of the custom-built extension modules currently
used (see https://bitbucket.org/kang/python-keyring-lib/issue/26).


using a config file from the current directory is insecure

Especially since the config file allows arbitrary code to be loaded, using one from whatever directory the user happens to be in when the keyring module runs is insecure.
There doesn't seem to be anything to prevent an unscrupulous person from creating a config file that loads a module that reveals the authentication information.
The config file from the user's home directory should be loaded first, and the current directory's config file loaded only if explicitly enabled in the home directory config file.
Also, the config files should not be used if they are owned by anyone other that the current user, or if they are writable by anyone else.


underlying error if raised while setting password in keyring is not raised.

In the below code if OSError is raised then actually reason for the error is never known.

keyring/backend.py:

class _ExtensionKeyring(KeyringBackend):
    def set_password(self, service, username, password):
        """Overide the set_password() in KeyringBackend.
        """
    try:
        self.keyring_impl.password_set(service, username, password)
    except OSError:
        raise PasswordSetError()

So i think we should change this to.

    try:
        self.keyring_impl.password_set(service, username, password)
    except OSError, e:
        raise PasswordSetError(e)

so that we will know whats the actually error is.

regards,

Moqtar


KWallet unable to find qptrlist.h

Hi,

Trying to compile kwallet extension, the compilation fails due to :

building 'kde_kwallet' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -O2 -fPIC -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/qt4 -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtCore -I/usr/include/kde -I/usr/include/python2.5 -c keyring/backends/kde_kwallet.cpp -o build/temp.linux-i686-2.5/keyring/backends/kde_kwallet.o
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
In file included from /usr/include/kde/kwallet.h:31,
from keyring/backends/kde_kwallet.cpp:5:
/usr/include/kde/dcopobject.h:29:22: error: qptrlist.h: No such file or directory
/usr/include/kde/dcopobject.h:30:24: error: qvaluelist.h: No such file or directory

Although I have these two files :
/usr/include/qt3/qvaluelist.h
/usr/include/qt3/qptrlist.h

I guess the problem is related to the paths of theses files, but it's the way they are installed under Debian.

Help will greatly be appreciated :)


Issues with some characters in crypted_pass.cfg

Hi

I'm trying to use mercurial_keyring which uses keyring and it seems keyring has a problem adding some data in crypted_pass.cfg (which is a INI file I guess) with some keys containing '@' or '/'

I'm copying below a typical session output with mercurial_keyring. The first part shows that keyring keeps prompting for a password and the interesting part is at the end with the crypted_pass.cfg weird content :

#!python

chaica@sid:/tmp$ hg clone https://[email protected]/chaica/test/
http authorization required
realm: Bitbucket.org HTTP
user: chaica (fixed in .hg/hgrc)
password: 
Please set a password for your new keyring
Password: 
Password (again): 
Please input your password for the keyring
Password: 
destination directory: test
requesting all changes
adding changesets
adding manifests
adding file changes
added 9 changesets with 9 changes to 1 files
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
chaica@sid:/tmp$ cd test/
chaica@sid:/tmp/test$ ls
montest.py
chaica@sid:/tmp/test$ vi montest.py 
chaica@sid:/tmp/test$ hg commit montest.py 
No username found, using 'chaica@sid' instead
chaica@sid:/tmp/test$ hg push
http authorization required
realm: Bitbucket.org HTTP
user: chaica (fixed in .hg/hgrc)
password: 
Please input your password for the keyring
Password: 
pushing to https://[email protected]/chaica/test/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
bb/acl: chaica is allowed. accepted payload.
quota: 3.9 KB in use, 1.0 GB available (0.00% used)
chaica@sid:/tmp/test$



#!python

~/home/chaica/crypted_pass.cfg:
[Mercurial]
chaica@@https://bitbucket.org/chaica/test/ = RtlggwByvg==

chaica@@https = //bitbucket.org/chaica/test/ = RtlggwByvg==

Bye,
Carl


NameError: name 'logger' is not defined

I get this error:

...snip...
  File "/u/int5sys/opt/mercurial-1.5/lib/python2.6/site-packages/mercurial/demandimport.py", line 106, in _demandimport
    mod = _origimport(name, globals, locals)
  File "/u/ehaszla/x/lib/python2.6/site-packages/keyring-0.2-py2.6.egg/keyring/core.py", line 122, in <module>
    init_backend()
  File "/u/ehaszla/x/lib/python2.6/site-packages/keyring-0.2-py2.6.egg/keyring/core.py", line 40, in init_backend
    keyring_impl = load_config()
  File "/u/ehaszla/x/lib/python2.6/site-packages/keyring-0.2-py2.6.egg/keyring/core.py", line 116, in load_config
    logger.warning("Keyring Config file does not write correctly.\n" + \
NameError: name 'logger' is not defined

when there is a problem with the keyringrc.cfg file. It looks like the "logger" that core.py is trying to use is defined in init.py, but that isn't being loaded for some reason. Perhaps this is a problem with how mercurial is loading the keyring module?

I installed the keyring and mercurial_keyring modules into a non-default location with "easy_install --prefix /u/ehaszla/x ..." b/c I do not have root access on the machine.

Also, even if using logger worked, the error message it would have displaying is a bit off; it should say something like:

  The keyring config file (~/keyringrc.cfg) is not properly formatted.

OSError: Can's access the keyring now

I first tried to store a password using the keyring module, but realized that it uses the crypt backend. Since I'm using GNOME I installed python-keyring-gnome (on Ubuntu 10.04) and restarted the application.

Now, when my application queries keyring for a password it prints

** Message: secret service operation failed: The name org.freedesktop.secrets was not provided by any .service files

on the command line and returns None (which is actually true). But when I'm trying to store a password it fails with OSError:

#!python

keyring.set_password(service, username, passwd)
  File "/usr/lib/pymodules/python2.6/keyring/core.py", line 33, in set_password
    return _keyring_backend.set_password(service_name, username, password)
  File "/usr/lib/pymodules/python2.6/keyring/backend.py", line 97, in set_password
    return self.keyring_impl.password_set(service, username, password)
OSError: Can's access the keyring now

Gnome keyring broken

The Gnome backend's "_init_backend" method tries to import "gnome_keyring". However, on my machine (Ubuntu Karmic, using the python-gnomekeyring package) the library is actually available under the name "gnomekeyring". As a result, the backend is never picked.

Also, it uses GNOME_DESKTOP_SESSION_ID to determine whether Gnome is running. However, it seems like that might break in the future:

#!bash

$ echo $GNOME_DESKTOP_SESSION_ID
this-is-deprecated

Add python3 support?

Hello,

When trying to install python-keyring, I got the following error:

Traceback (most recent call last):
  File "setup.py", line 12, in <module>
    from extensions import get_extensions
  File "/home/victor/code/pkgbuild/python/python-keyring/src/keyring-0.4/extensions.py", line 9, in <module>
    import commands
ImportError: No module named commands

I think this is linked to this:
http://docs.python.org/library/commands.html

In particular to: "Deprecated since version 2.6: The commands module has been removed in Python 3.0. Use the subprocess module instead."
Could we find a good solution to work with both versions?
Thanks!


Failures happen at random points in the code when GNOME keyring is active but not accessible

I'd like to summarize some problems I've seen when using the keyring library to access the GNOME keyring in situations other than the standard "local desktop" situation.

These situations all have in common that the GNOME keyring is active (so keyring tries to use it instead of falling back to KWallet or a file on disk), but when it comes time to actually use the keyring, something goes wrong:

a) the keyring turns out to be inaccessible, causing an error.

b) the keyring claims it can't find a key, even though it didn't look (the keyring was never unlocked, so it couldn't have looked).

c) the keyring library crashes when trying to write a new key to the keyring.

d) the keyring hangs when it should be presenting a GUI for unlocking the keyring

I don't expect all these problems to be solved by new code in the keyring library. In fact, I'd be satisfied if we could figure out workarounds for all of these problems (I do have workarounds for the first two, which are the most common problems, and the third one, which is kind of a dumb mistake).

But, it would be nice if the keyring library had a consistent way of dealing with these situation: either deciding that the GNOME keyring wasn't available after all, and falling back, or raising an exception that an application could catch and use to advice the end-user which workaround to apply.

Let me apologize in advance for not describing these problems in a way that's easy to understand. I don't understand DBus very well. That said, it's pretty easy to duplicate the first three problems yourself and to use dbus-monitor to see what's going on behind the scenes.

Here are the problem scenarios I've discovered:

  1. Start a GNOME desktop session, then 'ssh -X' in from another computer. The keyring library will try to access the GNOME keyring, but since it can't communicate over dbus, gnomekeyring.find_network_password_sync will fail with a gnomekeyring.IOError.

(The workaround is to activate DBus in the SSH session by running export dbus-launch.)

  1. The same error occurs if you SSH in without setting up X forwarding. (The solution is to use ssh -X and export dbus-launch.)
  2. If DBus is set up for a SSH session, but X forwarding is not, get_password() returns None rather than returning a key known to be in the keyring, and set_password() crashes with a keyring.backend.PasswordSetError.

Here's the DBus traffic for this case:
http://paste.ubuntu.com/573649/

As you can see, the member=Completed event is sent out, even though I never get the GUI popup asking me to unlock the keyring.

  1. When running in a chroot, set_password() sends a DBus event to prompt the user to unlock their keyring. Here's the DBus traffic for this case (interspersed with a little Python code):

http://paste.ubuntu.com/573648/

Here's the interesting call:

method call sender=:1.3 -> dest=org.freedesktop.secrets serial=7 path=/org/freedesktop/secrets/prompt/p2; interface=org.freedesktop.Secret.Prompt; member=Prompt

This is supposed to trigger the GUI prompt to unlock the GNOME keyring. set_password() hangs after sending this event. The GUI prompt never shows up, even if $DISPLAY is set properly in the chroot.


Unable to build kde_kwallet.so

Hi,

Some package builders, as the Debian package builder (called buildd) using a chrooted environment, provide a $HOME=/nonexistant during the build.

You can try it using the following command in a shell:
HOME=/nonexistant kde4-config --install include

In that case, the command provides the following output :

trying to create local folder /nonexistant: Permission denied
/usr/include/

This output fails the kde_check() function in extensions.py so kde_kwallet.so is not built.

I guess the warning message is provided on stderr, so maybe only catching the output on stdout could solve this issue.

Bye,
Carl Chenet


get_password and set_password never return when using wxPython in KDE

Hi,

When using KDE, and hence, KWallet, combined with a wxPython GUI, the get_passward and set_password never return.

The wallet is accessed normally, but on return the hosting application freezes.

Seems to be somehow an incompatibility between a GTK+ application and KWallet.

Is there anything you can do about this?

Thank you in advance :-)

Great module, btw!


Explicit global _keyring_backend and better dynamic import

Since they matched a closely related functionality in the very same file, those two features were actually merged into a single one.

  1. the way _keyring_backend was used in core.py relied on the way the _keyring_backend name was set during import. This could work but could lead to very strange issues sometimes.

The patch provides an explicit global keyword which allows performing the very same task in a cleaner way. NOTE: _keyring_backend was actually meant to be a global even before this patch, but it was used inconsistenly. Looking at all the functions employing _keyring_backend, they will simply crash with a NameError if _keyring_backend is unset, but how is it set is unclear.

A better approach would be use a registry and not to rely on global, I'll try that in a further patch.

  1. Don't reinvent the wheel and use a tested function to dynamically import Keyring backend classes. This patch employs a function from the Twisted project with small modifications.

Should not use login.keychain on OSX

You're explicitely opening the login.keychain keychain file (in SecKeychainOpen("login.keychain",&keychain)).

login.keychain may not exist. Some versions of the OS created .keychain instead and of course the user is always free to create/delete and set as default whatever keychain he/she likes.

You should, instead of explicitly opening a keychain just pass a NULL to all keychain APIs.


Manually configuring KWallet when it is not available doesn't (immediately) generate an error.

If you configure the KWallet backend...

[backend]
default-keyring=keyring.backend.KDEKWallet

...when KWallet is not available, an exception will be raised when attempting to retrieve a password:

  File ".../eggs/keyring-0.5.1-py2.6.egg/keyring/backend.py", line 206, in get_password
    if kwallet.keyDoesNotExist(network, 'Python', key):
AttributeError: 'NoneType' object has no attribute 'keyDoesNotExist'

Instead an error should be generated as soon as the configuration is acted upon (but not at import time -- doing work at import time isn't friendly).


user-canceling of KDE Wallet dialogs causes unhandled exception

Upon import of kwallet.backends (which is done upon import of kwallet), the KDE Wallet modules are imported and if the import succeeds the wallet is opened.

Opening the wallet will sometimes (if the wallet hasn't been opened in this session) request a password to unlock the wallet or (if the user hasn't granted perminant access to this application) ask if the application is allowed to access the wallet.

If the user declines either of these dialogs an exception will be raised because kwallet is None and a method call is attempted on it.

I've attached a fix for this problem, with tests.


Silent fallback to crypted not good solution

I run Ubuntu Karmic with the default Gnome desktop. Using pip I installed keyring. Even though I have gnome-keyring and the Python bindings installed, because I did not have the libdbus-1-dev and libgnome-keyring-dev packages installed, keyring silently and with no warning decided to install without the Gnome backend and fallback to crypted file in my homedir instead. This sucks.

I think instead the environment check (i.e. what keyring.backend.GnomeKeyring._recommend() does) should be run, and if that returns True but pkg-config fails, I should at least get a big fat warning telling me which dev libs I need to install.


keyring.util omitted from install

I'm using Python 2.7 and distribute 0.6.14 on Windows 64-bit. When I install keyring from source (or from the distribution), it doesn't include sub-packages (keyring.util in particular).

For example,

#!shell

PS C:\Users\jaraco\projects\public\keyring> ./setup install
running install
running build
running build_py
copying keyring\backend.py -> build\lib.win-amd64-2.7\keyring
copying keyring\core.py -> build\lib.win-amd64-2.7\keyring
copying keyring\getpassbackend.py -> build\lib.win-amd64-2.7\keyring
copying keyring\__init__.py -> build\lib.win-amd64-2.7\keyring
running build_ext
running install_lib
copying build\lib.win-amd64-2.7\win32_crypto.pyd -> C:\Python\Lib\site-packages
running install_egg_info
Removing C:\Python\Lib\site-packages\keyring-0.3-py2.7.egg-info
Writing C:\Python\Lib\site-packages\keyring-0.3-py2.7.egg-info

Thereafter, trying to import keyring results in the following ImportError:

C:\> python -c 'import keyring'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\python\lib\site-packages\keyring-0.3-py2.7-win-amd64.egg\keyring\__init__.py", line 9, in <module>
    from core import set_keyring, get_keyring, set_password, get_password
  File "c:\python\lib\site-packages\keyring-0.3-py2.7-win-amd64.egg\keyring\core.py", line 12, in <module>
    from keyring import backend
  File "c:\python\lib\site-packages\keyring-0.3-py2.7-win-amd64.egg\keyring\backend.py", line 11, in <module>
    from keyring.util.escape import escape as escape_for_ini
ImportError: No module named util.escape

Explicitly include 'keyring.util' in the packages parameter to setup seems to resolve the issue.


Fix: gnomekeyring may not work because of mercurial demandimport behaviour

Mercurial demandimport seems to break gnomekeyring.

I've already submitted a patch to the mercurial ml, in the meantime here it is a workaround.

Also, this patch prevents dependency from the global "gnomekeyring" module, but the conditional import should prevent breaking anything.

https://bitbucket.org/Alan/python-keyring-lib/changeset/1aae1b660c54


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.