devlooped / CredentialManager

Packages the official Git Credential Manager cross-platform credential store implementation supporting Windows, macOS and Linux for use as a NS2.0 library with no UI or external dependencies.
https://clarius.org/CredentialManager
MIT License
9 stars 0 forks source link

GitCredentialManager.Trace2Exception: 'Failed to decrypt file '/home/bairog/.password-store/myapp/https/foo.com/myusr.gpg' with gpg #108

Closed bairog closed 2 months ago

bairog commented 2 months ago

Describe the Bug

I've installed WSL2 (Ubuntu 22.04.4 LTS distro) on my Windows 11 23H2 x64 Pro. I've configured GPG/pass compatible files credential store for gpg-id admin <admin@admin.com>. I've created .NET 6.0 console application (Visual Studio 2022) with sample code from this repository and started debugging on WSL2. I've got an exception on credential retrieve with Credential cred = store.Get("https://foo.com", "myusr");:

GitCredentialManager.Trace2Exception: 'Failed to decrypt file '/home/admin/.password-store/myapp/https/foo.com/myusr.gpg' with gpg. exit=2, out=, err=gpg: encrypted with 3072-bit RSA key, ID 9C0994D00C0203A4, created 2024-07-29 "admin admin@admin.com" gpg: public key decryption failed: Inappropriate ioctl for device gpg: decryption failed: No secret key

Is it a bug or how to fix that? Thank you.

Steps to Reproduce

using GitCredentialManager;
using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ICredentialStore store = CredentialManager.Create("myapp");

            // Store a credential
            store.AddOrUpdate("https://foo.com", "myusr", "mypwd");

            // Retrieve a credential
            ICredential cred = store.Get("https://foo.com", "myusr");
        }
    }
}

Expected Behavior

Credential is retreived with no problem.

Exception with Stack Trace

Exception thrown: 'GitCredentialManager.Trace2Exception' in Devlooped.CredentialManager.dll
An unhandled exception of type 'GitCredentialManager.Trace2Exception' occurred in Devlooped.CredentialManager.dll: 'Failed to decrypt file '/home/admin/.password-store/myapp/https/foo.com/myusr.gpg' with gpg. exit=2, out=, err=gpg: encrypted with 3072-bit RSA key, ID 9C0994D00C0203A4, created 2024-07-29
      "admin<admin@admin.com>"
gpg: public key decryption failed: Inappropriate ioctl for device
gpg: decryption failed: No secret key'
Stack trace:
 >   at GitCredentialManager.Gpg.DecryptFile(String path)
 >   at GitCredentialManager.Interop.Posix.GpgPassCredentialStore.TryDeserializeCredential(String path, FileCredential& credential)
 >   at GitCredentialManager.PlaintextCredentialStore.<Enumerate>d__18.MoveNext()
 >   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
 >   at GitCredentialManager.PlaintextCredentialStore.AddOrUpdate(String service, String account, String secret)
 >   at ConsoleApp1.Program.Main(String[] args) in D:\ConsoleApp1\ConsoleApp1\Program.cs:line 14

Version Info

Devlooped.CredentialManager Version="2.5.0.1"

Back this issue Back this issue

bairog commented 2 months ago

Sample code works only if I don't enter a passphrase to protect my gpg key (that I generate with gpg --gen-key). But if I enter any passphrase - described exception is thrown. Looks like OS waits for a passphrase to be entered. Is there any workaround?

bairog commented 2 months ago

Ok, looks like WSL2 terminal window is treated as Headless/TTY-only session and therefore according to GCM docs I need to add export GPG_TTY=$(tty) to ~/.bashrc or ~/.profile file. After that a prompt started to open WSL2 terminal window (or in a GUI window if Seahorse is installed): image If GPG key passphrase is not empty GPG/pass compatible files credential store also requires user interaction (via GUI or terminal prompt)? Is there any workaround to enter a passphrase via API?

kzu commented 2 months ago

I'm pretty sure that's by design of the underlying API from GCM. This API is tested to work with all providers that don't require a passkey across all supported OSes on CI on every commit.

Buy that's the core scenario: to work on non-interactive usage, not to try to automate UI that's driven by the OS.

bairog commented 2 months ago

@kzu "to work on non-interactive usage" - do you mean gpg key without any passphrase is the only option? Secret Service API definitelly require GUI, Git credential cache is not persistent, Plaintext files are not secure at all. So GPG/pass compatible files is the only non-interactive store available on Linux, right?

kzu commented 2 months ago

I guess. But as I said, that's all external to this library.