Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pip + twine installed: pip attempts to continuously create and use a "keyring" #8090

Closed
asottile opened this issue Apr 19, 2020 · 31 comments · Fixed by #8687
Closed

pip + twine installed: pip attempts to continuously create and use a "keyring" #8090

asottile opened this issue Apr 19, 2020 · 31 comments · Fixed by #8687
Labels
C: keyring Related to pip's keyring integration C: network connectivity type: bug A confirmed bug or unintended behavior

Comments

@asottile
Copy link
Contributor

asottile commented Apr 19, 2020

Environment

  • pip version: 20.0.2
$ pip freeze --all
bleach==3.1.4
certifi==2020.4.5.1
cffi==1.14.0
chardet==3.0.4
cryptography==2.9
docutils==0.16
idna==2.9
importlib-metadata==1.6.0
jeepney==0.4.3
keyring==21.2.0
pip==20.0.2
pkginfo==1.5.0.1
pycparser==2.20
Pygments==2.6.1
readme-renderer==25.0
requests==2.23.0
requests-toolbelt==0.9.1
SecretStorage==3.1.2
setuptools==46.1.3
six==1.14.0
tqdm==4.45.0
twine==3.1.1
urllib3==1.25.9
webencodings==0.5.1
wheel==0.34.2
zipp==3.1.0
$ python --version --version
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0]
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic

Description

Upon any pip install command, pip attempts to create a keyring (???) -- at first I thought I was being hacked 🤣 -- here's pip install babi

prompt

Expected behavior

I expect pip to not do that, there's no reason to create a keyring here when it's not going to be used.

How to Reproduce

  1. pip install twine
  2. pip install babi # can be any package, this is the one in the screenshot

Output

(see screenshot above)

I didn't want to create a keyring so I clicked cancel, it prompts again (12 times in total to install babi) and produces output like this:

$ pip install babi
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
Collecting babi
  WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
  Using cached babi-0.0.7-py2.py3-none-any.whl (41 kB)
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
Collecting identify
  WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
  Using cached identify-1.4.14-py2.py3-none-any.whl (97 kB)
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
Collecting babi-grammars
  WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
  Using cached babi_grammars-0.0.13-py2.py3-none-any.whl (351 kB)
Requirement already satisfied: importlib-metadata>=1; python_version < "3.8" in ./venv/lib/python3.6/site-packages (from babi) (1.6.0)
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
Collecting onigurumacffi>=0.0.10
  WARNING: Keyring is skipped due to an exception: Failed to create the collection: Prompt dismissed..
  Using cached onigurumacffi-0.0.14-cp36-abi3-manylinux1_x86_64.whl (528 kB)
Requirement already satisfied: zipp>=0.5 in ./venv/lib/python3.6/site-packages (from importlib-metadata>=1; python_version < "3.8"->babi) (3.1.0)
Requirement already satisfied: cffi>=1 in ./venv/lib/python3.6/site-packages (from onigurumacffi>=0.0.10->babi) (1.14.0)
Requirement already satisfied: pycparser in ./venv/lib/python3.6/site-packages (from cffi>=1->onigurumacffi>=0.0.10->babi) (2.20)
Installing collected packages: identify, babi-grammars, onigurumacffi, babi
Successfully installed babi-0.0.7 babi-grammars-0.0.13 identify-1.4.14 onigurumacffi-0.0.14
@triage-new-issues triage-new-issues bot added the S: needs triage Issues/PRs that need to be triaged label Apr 19, 2020
@pradyunsg
Copy link
Member

/cc @zooba

@gutsytechster

This comment has been minimized.

@asottile

This comment has been minimized.

@asottile
Copy link
Contributor Author

I believe this is linux-specific as well

@asottile
Copy link
Contributor Author

here's how I've been able to take a working machine and "break" it:

mv ~/.local/share/keyrings{,.old}

@gutsytechster

This comment has been minimized.

@asottile

This comment has been minimized.

@gutsytechster

This comment has been minimized.

@asottile

This comment has been minimized.

@pradyunsg pradyunsg added C: network connectivity state: needs eyes Needs a maintainer/triager to take a closer look type: bug A confirmed bug or unintended behavior labels Apr 21, 2020
@triage-new-issues triage-new-issues bot removed S: needs triage Issues/PRs that need to be triaged labels Apr 21, 2020
@tykling

This comment has been minimized.

@pradyunsg
Copy link
Member

pradyunsg commented May 5, 2020

We need someone familiar with keyring, to look at pip._internal.network.auth and see what would be a good way to resolve this issue. :)

@equaeghe
Copy link

equaeghe commented May 8, 2020

This is a really bad bug. I first thought that I couldn't install anything any more. Then I discovered I could dismiss the pop-up dialog (which blocks all keyboard input for the whole desktop!). I had to dismiss it nine times for a package with two deps.

Version info:

$ pip --version
pip 19.3.1 from /usr/lib/python3.7/site-packages/pip (python 3.7)

I'm on Gentoo Linux with KDE Plasma. By default keyring uses KWallet and it works, I checked.

$ keyring --list-backends
keyring.backends.kwallet.DBusKeyring (priority: 5.1)
keyring.backends.SecretService.Keyring (priority: 5)
keyring.backends.chainer.ChainerBackend (priority: 10)
keyring.backends.fail.Keyring (priority: 0)

@a-jd
Copy link

a-jd commented Jul 2, 2020

Got the same bug after installing twine. Warning threw for pip install practically any package. The solution that worked for me was to just change my password using passwd. I am not sure what is happening in the backend but I gave it a shot after seeing https://askubuntu.com/questions/918712/the-login-keyring-did-not-get-unlocked-when-you-logged-into-your-computer.

@nikolas
Copy link

nikolas commented Jul 16, 2020

I'm seeing this issue with pip 20.1.1 on Fedora 31. Installing anything with pip now takes like 10 minutes.

@hroncok
Copy link
Contributor

hroncok commented Jul 22, 2020

We need someone familiar with keyring, to look at pip._internal.network.auth and see what would be a good way to resolve this issue. :)

Let me see...

@hroncok
Copy link
Contributor

hroncok commented Jul 22, 2020

Previously the logic was:

  • if the response is 401, ask for user and password to supply

Now the logic is:

  • before doing a request, check whether we have user+password for the URL it in the keyring
  • if not, proceed without, if yes, use it
  • if the response is 401, ask for user and password and optionally store it

I believe the proper algorithm should be:

  • if the response is 401, check whether we have user+password for the URL it in the keyring
  • if yes, use it, if not, ask for user and password and optionally store it

I am not familiar with keyring but I don't think that it is needed.

Looking further.

@hroncok
Copy link
Contributor

hroncok commented Jul 22, 2020

I have this naïve patch:

diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py
index ca729fcd..b19825e1 100644
--- a/src/pip/_internal/network/auth.py
+++ b/src/pip/_internal/network/auth.py
@@ -110,7 +110,7 @@ class MultiDomainBasicAuth(AuthBase):
         return None
 
     def _get_new_credentials(self, original_url, allow_netrc=True,
-                             allow_keyring=True):
+                             allow_keyring=False):
         # type: (str, bool, bool) -> AuthInfo
         """Find and return credentials for the specified URL."""
         # Split the credentials and netloc from the url.
@@ -250,8 +250,14 @@ class MultiDomainBasicAuth(AuthBase):
 
         parsed = urllib_parse.urlparse(resp.url)
 
+        # Query the keyring for credentials:
+        username, password = self._get_new_credentials(resp.url,
+                                                       allow_netrc=False,
+                                                       allow_keyring=True)
+
         # Prompt the user for a new username and password
-        username, password, save = self._prompt_for_password(parsed.netloc)
+        if not username or not password:
+            username, password, save = self._prompt_for_password(parsed.netloc)
 
         # Store the new username and password to use for future requests
         self._credentials_to_save = None

The idea is that keyring is only ever queried when handling a 401 response.

I have no idea how to properly test this with a password protected index. Do you have any?


This other patch can suppress any subsequent attempt to query the keyring when the first attempt failed:

diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py
index b19825e1..588ca0d3 100644
--- a/src/pip/_internal/network/auth.py
+++ b/src/pip/_internal/network/auth.py
@@ -44,6 +44,7 @@ except Exception as exc:
 def get_keyring_auth(url, username):
     # type: (str, str) -> Optional[AuthInfo]
     """Return the tuple auth for a given url from keyring."""
+    global keyring
     if not url or not keyring:
         return None
 
@@ -69,6 +70,7 @@ def get_keyring_auth(url, username):
         logger.warning(
             "Keyring is skipped due to an exception: %s", str(exc),
         )
+        keyring = None
     return None

Which can reduce the most annoying aspect of this problem.

@hroncok
Copy link
Contributor

hroncok commented Jul 31, 2020

How can I move this forward? I can submit a PR but I have no idea about how to effectively tests this (nor manually, nor automated).

@chrahunt
Copy link
Member

There is a test here that could act as a starting example. Since I guess this would be a functional test, we could actually install a keyring lookalike in the environment of the pip under test or the real one + a plugin that acts like we dictate using e.g. environment variables or something more complicated.

@hroncok
Copy link
Contributor

hroncok commented Aug 3, 2020

OK, I've opened #8687 but I'd feel more confident if there was some index with user+password I could try manually as well.

hroncok added a commit to hroncok/pip that referenced this issue Aug 3, 2020
hroncok added a commit to hroncok/pip that referenced this issue Aug 3, 2020
@hroncok
Copy link
Contributor

hroncok commented Aug 5, 2020

I'd feel more confident if there was some index with user+password I could try manually as well.

Verified.

bors bot referenced this issue in duckinator/emanate Aug 11, 2020
162: Update pip to 20.2.2 r=duckinator a=pyup-bot


This PR updates [pip](https://pypi.org/project/pip) from **20.2.1** to **20.2.2**.



<details>
  <summary>Changelog</summary>
  
  
   ### 20.2.2
   ```
   ===================

Bug Fixes
---------

- Only attempt to use the keyring once and if it fails, don&#39;t try again.
  This prevents spamming users with several keyring unlock prompts when they
  cannot unlock or don&#39;t want to do so. (`8090 &lt;https://github.com/pypa/pip/issues/8090&gt;`_)
- Fix regression that distributions in system site-packages are not correctly
  found when a virtual environment is configured with ``system-site-packages``
  on. (`8695 &lt;https://github.com/pypa/pip/issues/8695&gt;`_)
- Disable caching for range requests, which causes corrupted wheels
  when pip tries to obtain metadata using the feature ``fast-deps``. (`8701 &lt;https://github.com/pypa/pip/issues/8701&gt;`_, `8716 &lt;https://github.com/pypa/pip/issues/8716&gt;`_)
- Always use UTF-8 to read ``pyvenv.cfg`` to match the built-in ``venv``. (`8717 &lt;https://github.com/pypa/pip/issues/8717&gt;`_)
- 2020 Resolver: Correctly handle marker evaluation in constraints and exclude
  them if their markers do not match the current environment. (`8724 &lt;https://github.com/pypa/pip/issues/8724&gt;`_)
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/pip
  - Changelog: https://pyup.io/changelogs/pip/
  - Homepage: https://pip.pypa.io/
</details>



Co-authored-by: pyup-bot <github-bot@pyup.io>
@bfredl

This comment has been minimized.

@pradyunsg
Copy link
Member

I'm gonna close this since #8744 fixed the bulk of this issue. #8687 is also open right now, but I think it's fine to track that separately. See also: #8719.

Thanks again @hroncok for the PR! ^>^

@asottile
Copy link
Contributor Author

asottile commented Sep 30, 2020

@pradyunsg I disagree with closing this, it still shouldn't prompt at all

EDIT: it also still prompts on every install so it really isn't solved

@pradyunsg pradyunsg reopened this Oct 10, 2020
@pradyunsg
Copy link
Member

Reopened to track #8687 merging.

@JakkuSakura
Copy link

The same as I use twisted. I'm not sure whether they are the same.

@pradyunsg pradyunsg added the C: keyring Related to pip's keyring integration label Nov 5, 2020
hroncok added a commit to hroncok/pip that referenced this issue Dec 29, 2020
hroncok added a commit to hroncok/pip that referenced this issue Dec 29, 2020
hroncok added a commit to hroncok/pip that referenced this issue Dec 29, 2020
hroncok added a commit to hroncok/pip that referenced this issue Jan 4, 2021
@Morsmalleo
Copy link

for me I solved this problem on Kali Linux 2020.4 by going to /home/kali/.local/share/keyrings/ and deleting the default file as well as the Default.keyring file, upon using pip install it prompted me to type a new password as well as confirm that new password, and haven't had a problem since. Hope this helps you guys out.

@warrickball
Copy link

warrickball commented Jan 21, 2021

I just hit this for the first time. I was prompted to create a KDE Wallet, although I use GNOME on Fedora 33. The pip install command succeeded in the background and just left the dialogue box up, which I closed with no side effect. In case it's relevant, here's the pip version.

$ pip --version
pip 20.2.2 from /usr/lib/python3.9/site-packages/pip (python 3.9)

Edit: I just realised this may have been triggered by my recently installing kcachegrind, which installs kf5-kwallet and kf5-kwallet-libs as dependencies.

@uranusjr
Copy link
Member

The pip version does not matter; keyring’s version does.

@warrickball
Copy link

$ dnf list installed | grep kwallet
kf5-kwallet.x86_64                                 5.78.0-1.fc33                       @updates              
kf5-kwallet-libs.x86_64                            5.78.0-1.fc33                       @updates              

@jrd
Copy link

jrd commented Mar 20, 2021

Exporting PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring prevent python from using any keyring

PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring pipenv update does not ask me anything anymore

So, as a temporary solution, one might want to put this in a .env file.

inmantaci added a commit to inmanta/inmanta-core that referenced this issue Apr 27, 2021
Bumps [pip](https://github.com/pypa/pip) from 21.0.1 to 21.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/pypa/pip/blob/main/NEWS.rst">pip's changelog</a>.</em></p>
<blockquote>
<h1>21.1 (2021-04-24)</h1>
<h2>Process</h2>
<ul>
<li>Start installation scheme migration from <code>distutils</code> to <code>sysconfig</code>. A
warning is implemented to detect differences between the two implementations to
encourage user reports, so we can avoid breakages before they happen.</li>
</ul>
<h2>Features</h2>
<ul>
<li>Add the ability for the new resolver to process URL constraints. (<code>[#8253](pypa/pip#8253) &lt;https://github.com/pypa/pip/issues/8253&gt;</code>_)</li>
<li>Add a feature <code>--use-feature=in-tree-build</code> to build local projects in-place
when installing. This is expected to become the default behavior in pip 21.3;
see <code>Installing from local packages &lt;https://pip.pypa.io/en/stable/user_guide/#installing-from-local-packages&gt;</code>_
for more information. (<code>[#9091](pypa/pip#9091) &lt;https://github.com/pypa/pip/issues/9091&gt;</code>_)</li>
<li>Bring back the &quot;(from versions: ...)&quot; message, that was shown on resolution failures. (<code>[#9139](pypa/pip#9139) &lt;https://github.com/pypa/pip/issues/9139&gt;</code>_)</li>
<li>Add support for editable installs for project with only setup.cfg files. (<code>[#9547](pypa/pip#9547) &lt;https://github.com/pypa/pip/issues/9547&gt;</code>_)</li>
<li>Improve performance when picking the best file from indexes during <code>pip install</code>. (<code>[#9748](pypa/pip#9748) &lt;https://github.com/pypa/pip/issues/9748&gt;</code>_)</li>
<li>Warn instead of erroring out when doing a PEP 517 build in presence of
<code>--build-option</code>. Warn when doing a PEP 517 build in presence of
<code>--global-option</code>. (<code>[#9774](pypa/pip#9774) &lt;https://github.com/pypa/pip/issues/9774&gt;</code>_)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li>Fixed <code>--target</code> to work with <code>--editable</code> installs. (<code>[#4390](pypa/pip#4390) &lt;https://github.com/pypa/pip/issues/4390&gt;</code>_)</li>
<li>Add a warning, discouraging the usage of pip as root, outside a virtual environment. (<code>[#6409](pypa/pip#6409) &lt;https://github.com/pypa/pip/issues/6409&gt;</code>_)</li>
<li>Ignore <code>.dist-info</code> directories if the stem is not a valid Python distribution
name, so they don't show up in e.g. <code>pip freeze</code>. (<code>[#7269](pypa/pip#7269) &lt;https://github.com/pypa/pip/issues/7269&gt;</code>_)</li>
<li>Only query the keyring for URLs that actually trigger error 401.
This prevents an unnecessary keyring unlock prompt on every pip install
invocation (even with default index URL which is not password protected). (<code>[#8090](pypa/pip#8090) &lt;https://github.com/pypa/pip/issues/8090&gt;</code>_)</li>
<li>Prevent packages already-installed alongside with pip to be injected into an
isolated build environment during build-time dependency population. (<code>[#8214](pypa/pip#8214) &lt;https://github.com/pypa/pip/issues/8214&gt;</code>_)</li>
<li>Fix <code>pip freeze</code> permission denied error in order to display an understandable error message and offer solutions. (<code>[#8418](pypa/pip#8418) &lt;https://github.com/pypa/pip/issues/8418&gt;</code>_)</li>
<li>Correctly uninstall script files (from setuptools' <code>scripts</code> argument), when installed with <code>--user</code>. (<code>[#8733](pypa/pip#8733) &lt;https://github.com/pypa/pip/issues/8733&gt;</code>_)</li>
<li>New resolver: When a requirement is requested both via a direct URL
(<code>req @ URL</code>) and via version specifier with extras (<code>req[extra]</code>), the
resolver will now be able to use the URL to correctly resolve the requirement
with extras. (<code>[#8785](pypa/pip#8785) &lt;https://github.com/pypa/pip/issues/8785&gt;</code>_)</li>
<li>New resolver: Show relevant entries from user-supplied constraint files in the
error message to improve debuggability. (<code>[#9300](pypa/pip#9300) &lt;https://github.com/pypa/pip/issues/9300&gt;</code>_)</li>
<li>Avoid parsing version to make the version check more robust against lousily
debundled downstream distributions. (<code>[#9348](pypa/pip#9348) &lt;https://github.com/pypa/pip/issues/9348&gt;</code>_)</li>
<li><code>--user</code> is no longer suggested incorrectly when pip fails with a permission
error in a virtual environment. (<code>[#9409](pypa/pip#9409) &lt;https://github.com/pypa/pip/issues/9409&gt;</code>_)</li>
<li>Fix incorrect reporting on <code>Requires-Python</code> conflicts. (<code>[#9541](pypa/pip#9541) &lt;https://github.com/pypa/pip/issues/9541&gt;</code>_)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/pypa/pip/commit/2b2a268d25963727c2a1c805de8f0246b9cd63f6"><code>2b2a268</code></a> Bump for release</li>
<li><a href="https://github.com/pypa/pip/commit/ea761a6575f37b90cf89035ee8be3808cf872184"><code>ea761a6</code></a> Update AUTHORS.txt</li>
<li><a href="https://github.com/pypa/pip/commit/2edd3fdf2af2f09dce5085ef0eb54684b4f9bc04"><code>2edd3fd</code></a> Postpone a deprecation to 21.2</li>
<li><a href="https://github.com/pypa/pip/commit/3cccfbf169bd35133ee25d2543659b9c1e262f8c"><code>3cccfbf</code></a> Rename mislabeled news fragment</li>
<li><a href="https://github.com/pypa/pip/commit/21cd124b5d40b510295c201b9152a65ac3337a37"><code>21cd124</code></a> Fix NEWS.rst placeholder position</li>
<li><a href="https://github.com/pypa/pip/commit/e46bdda9711392fec0c45c1175bae6db847cb30b"><code>e46bdda</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/9827">#9827</a> from pradyunsg/fix-git-improper-tag-handling</li>
<li><a href="https://github.com/pypa/pip/commit/0e4938d269815a5bf1dd8c16e851cb1199fc5317"><code>0e4938d</code></a> 📰</li>
<li><a href="https://github.com/pypa/pip/commit/ca832b2836e0bffa7cf95589acdcd71230f5834e"><code>ca832b2</code></a> Don't split git references on unicode separators</li>
<li><a href="https://github.com/pypa/pip/commit/1320bac4ff80d76b8fba2c8b4b4614a40fb9c6c3"><code>1320bac</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/9814">#9814</a> from pradyunsg/revamp-ci-apr-2021-v2</li>
<li><a href="https://github.com/pypa/pip/commit/e9cc23ffd97cb6d66d32dc3ec27cf832524bb33d"><code>e9cc23f</code></a> Skip checks on PRs only</li>
<li>Additional commits viewable in <a href="https://github.com/pypa/pip/compare/21.0.1...21.1">compare view</a></li>
</ul>
</details>
<br />

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pip&package-manager=pip&previous-version=21.0.1&new-version=21.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually

</details>
@pypa pypa locked as resolved and limited conversation to collaborators Jul 23, 2021
@pradyunsg pradyunsg removed the state: needs eyes Needs a maintainer/triager to take a closer look label Dec 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: keyring Related to pip's keyring integration C: network connectivity type: bug A confirmed bug or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.