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

pythonPackages.pcsclite: refactor #21991

Merged
merged 1 commit into from Jan 20, 2017
Merged

Conversation

layus
Copy link
Member

@layus layus commented Jan 19, 2017

  • hardcode lipcsclite path
  • remove runtime dependency on swig
  • add myself as maintainer

@7c6f434c 7c6f434c merged commit 5acb6c2 into NixOS:master Jan 20, 2017
@fadenb
Copy link
Contributor

fadenb commented Feb 8, 2017

@layus @7c6f434c: This commit breaks the pgp card feature of my yubikey on my system ("gpg: OpenPGP card not available: No such device"). Reverting the commit and rebuilding my system instantly fixes the issue.

At the moment I do not have the time to debug this properly but wanted to let you know that there might be an issue.

@layus
Copy link
Member Author

layus commented Feb 8, 2017

Pinging @jonslp for he was the original author. That being said, I would appreciate if you could dig into this issue. I have no yubikey to play with, and it works with my bank cards ;-).

Also, what platform / python version are you using ?

@ghost
Copy link

ghost commented Feb 8, 2017

I'll try and take a look - I'm not sure why the python smartcard library would upset your system, it should be dormant unless installed/used and it wasn't part of Nix until the first commit was merged.

I have noticed some issues around sleeping my laptop causing GPG to stop working, and the fix was to restart the pcsclite daemon (although sudo gpg2 --card-status worked before restart) so I wondered it it was a permissions problem. My system also has additional udev entries to support U2F so I haven't isolated the problem yet.

Is it possible that reverting the commit and then runningnixos-rebuild switch restarted pcsclite?

(reposted from the correct account)

@eqyiel
Copy link
Contributor

eqyiel commented Feb 10, 2017

I have the same problem as @fadenb, can no longer use my Yubikey.

I can get --card-status to do something with root:

% gpg2 --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device
% sudo gpg2 --card-status
Reader ...........: 1050:0115:X:0
Application ID ...: D2760001240102000006038228730000
Version ..........: 2.0
Manufacturer .....: Yubico
Serial number ....: 03822873
Name of cardholder: Ruben Maher
Language prefs ...: en
Sex ..............: male
URL of public key : https://rkm.id.au/pubkey.txt
Login data .......: eqyiel
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 2
Signature key ....: 120A 486A 653C B77A 7F78  769E 32CF FFCA 503F CDAF
      created ....: 2016-02-07 07:03:10
Encryption key....: FFEC 9291 736D 8C49 6E42  5CD5 94E3 72F3 DC1F AA3D
      created ....: 2016-02-07 07:03:39
Authentication key: D6C0 6673 7534 B01E 3289  F549 3EA5 B597 1592 B446
      created ....: 2016-02-07 07:04:54
General key info..: [none]

And restarting pcscd.service has no effect:

% gpg2 --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device
% sudo systemctl restart pcscd
% gpg2 --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device

@ghost
Copy link

ghost commented Feb 10, 2017

I played around too. When it works with sudo, it is not using pcsdlite. That still works if you totally stop the daemon. Look at the Reader line - when it's working normally it says 'Yubikey' in there.

I ran strace against gpg2 and discovered all the talking to the smartcard is actually through the gpg-agent if you have one running. I restarted the pcscd.service, pcscd.socket and gpg-agent and it fixed it. I haven't worked out which one was the real culprit. I was hoping it was fixed by some of the recent systemd fixes that went into pcsclite, but I think the issue may be with libusb beneath.

@eqyiel
Copy link
Contributor

eqyiel commented Feb 10, 2017

@jonslp can you share the commands you used to restart those services in a way that fixes it? It won't work for me:

% sudo systemctl stop pcscd.service && sudo systemctl restart pcscd.socket && kill $(pidof gpg-agent) && eval "$(gpg-agent --daemon --enable-ssh-support --sh)"
Warning: Stopping pcscd.service, but it can still be activated by:
  pcscd.socket
% lsusb
Bus 001 Device 003: ID 1050:0115 Yubico.com Yubikey NEO(-N) U2F+CCID
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
% gpg2 --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device

Trace here: https://gist.github.com/eqyiel/9a1b2f078c7e1059c4e5139bb8c62f7f

You mentioned in your other post that you have additional udev entries to support U2F, would you mind sharing those?

@ghost
Copy link

ghost commented Feb 10, 2017

The only difference from what I did was to fully stop both the service and the socket, remove the socket from the file system for good measure, then restart it and check it was recreated. Something like
sudo systemctl stop pcscd.service sudo systemctl stop pcscd.socket sudo rm /var/run/pcscd/pcscd.comm sudo systemctl start pcscd.socket pkill gpg-agent

I can't remember how I restarted gpg-agent, however it is running as
gpg-agent --homedir /home/user/.gnupg --use-standard-socket --daemon

and in my sessions where it works, I have my environment as
GPG_TTY=/dev/pts/1 jSSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh SSH_ASKPASS=/nix/store/b0yj3lgf2nivfwkyhzrw2zrgb0abqm28-ksshaskpass-5.8.4/bin/ksshaskpass

@ghost
Copy link

ghost commented Feb 10, 2017

On the udev - it looks like I'm just using the entries that come with libu2fhost. I'm not sure if they're helping or not and I don't think they affect GPG, but I'm not sure as they're for access to /dev/hidraw*

  services.udev = {
    path = [ pkgs.systemd ];
    packages = [ pkgs.libu2f-host ];
    extraRules = ''
      SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="[0-5]", RUN+="${pkgs.systemd}/bin/systemctl hybrid-sleep"

    '';
  };

@ghost
Copy link

ghost commented Feb 10, 2017

And here's the difference in strace before and after restarting gpg-agent
https://gist.github.com/jonslp/c1bfbaf897fa5109871ab2623b4a6792

@layus
Copy link
Member Author

layus commented Feb 10, 2017

I have just checked. The only real change this PR produces is a change in the following source code:

        void* handle=NULL;
        char* dlsym_error;
        const char *lib = NULL;
        #ifdef __APPLE__
            lib = "/System/Library/Frameworks/PCSC.framework/PCSC";
        #else
            lib = "libpcsclite.so.1";
        #endif

        if( bFirstCall )
        {
            dlerror();
            handle = dlopen( lib, RTLD_NOW );
            if( NULL!=handle )
                   ....
            else
            {
                dlsym_error = dlerror();
                if( NULL!= dlsym_error )
                {
                    printf( "Failed to dlopen %s: %s!", lib, (dlsym_error==NULL) ? "" : (char*)dlsym_error );
                }
            }

replacing the lib = "libpcsclite.so.1"; by the full path to libpcsclite.

If this induced an error somewhere, it is because dynamically resolving libpcsclite.so.1 was used before, and is bypassed by a direct link now.

@layus
Copy link
Member Author

layus commented Feb 10, 2017

Bingo! yubikey is doing strange manipulation of LD_LIBRARY_PATH and LD_PRELOAD.
We can see that pycard did not work properly before because eid-viewer also had to wrap itself with LD_LIBRARY_PATH.
In the case of eid-viewer this is a good news. for yubikey, more investigatiosn are needed.

$ ack LD_LIBRARY | grep pcsc
pkgs/development/tools/misc/gpshell/default.nix:17:    wrapProgram "$out/bin/gpshell" --prefix LD_LIBRARY_PATH : "${gppcscconnectionplugin}/lib"
pkgs/tools/security/eid-viewer/default.nix:22:    wrapProgram $out/bin/eid-viewer --suffix LD_LIBRARY_PATH : ${pcsclite}/lib
pkgs/applications/misc/yubioath-desktop/default.nix:21:    makeWrapperArgs = ''--prefix LD_LIBRARY_PATH : "${pcsclite}/lib:${yubikey-personalization}/lib" --prefix LD_PRELOAD : "${yubikey-personalization}/lib/libykpers-1.so"'';

@layus
Copy link
Member Author

layus commented Feb 10, 2017

@jonslp Could you give us some insights on why LD_PRELOAD was used in yubikey-personalization in the first place ?

@ghost
Copy link

ghost commented Feb 10, 2017

I used LD_PRELOAD because the Python interpreter is patched to ignore LD_LIBRARY_PATH for dynamic loading, so it was the easiest way I could think of to make it work. Or at least, I think that's what this patch is doing.

https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/interpreters/python/cpython/2.7/no-ldconfig.patch

So without LD_PRELOAD, pyscard couldn't load the shared objects it needed to work.

@layus
Copy link
Member Author

layus commented Feb 10, 2017

Maybe we could get useful insights from @FRidh as to why it is disabled, but I guess that it is to prevent just what you are doing. By ignoring LD_LIBRARY_PATH, we have control over the origin of libraries.
In nix, we use dynamic loading of fixed paths. A kind of shared static loading if you prefer.

The expected solution in this case is to patch the python sources of yibioath-desktop to hardcode the library location. As an added benefit, libykpers would be automatically detected as a runtime dependency.

The library name appears in yubioath/core/legacy_otp.py at line 96: ykpers = YkPers('ykpers-1', '1'). Replacing that line by ykpers = YkPers("${yubikey-personnalisation}/lib/libykpers....so....") should do it. If I understood this correctly, there would be no need to wrap the executable at all after this.

Now, I am not sure at all that this would solve the issue at hand. But I think it is worth trying. LD_PRELOAD is a hack and should remain so.

@ghost
Copy link

ghost commented Feb 10, 2017

I agree, LD_PRELOAD is a hack and if we can get rid of it, we should. I thought I tried something like that, but I couldn't get the python to do the right thing.

Regardless of what we do about that, I still don't see how this change would affect anything other than components using pyscard. It should not affect GPG as far as I can tell.

It seems more likely that the upgrade from 1.8.17 -> 1.8.20 for pcsclite 4acd692
is causing people problems.

I haven't had my Yubikey very long, so I'm not sure how stable it used to be. I hadn't noticed the problem with gpg being unable to access the card until I used it on the road with my laptop and was using the suspend/hibernate more than I usually do.

@FRidh
Copy link
Member

FRidh commented Feb 10, 2017

Maybe we could get useful insights from @FRidh as to why it is disabled, but I guess that it is to prevent just what you are doing. By ignoring LD_LIBRARY_PATH, we have control over the origin of libraries.
In nix, we use dynamic loading of fixed paths. A kind of shared static loading if you prefer.

That's indeed the reason. In Python code we always need to replace such references, see python-packages.nix for a bunch of examples.

@afldcr
Copy link
Contributor

afldcr commented Feb 16, 2017

Hey y'all-- regarding gpg not being able to see the key, it's actually a bug with gpg itself.

https://bugs.gnupg.org/gnupg/issue2933

It can be "fixed" by adding pcsclite to extraPackages and changing the contents of .gnupg/scdaemon.conf to

pcsc-driver /run/current-system/sw/lib/libpcsclite.so
card-timeout 5
disable-ccid

Kill scdaemon and gpg and gpg will work on non root users again.

That said, the output of pcscd.service is still filled with errors :/

@ghost
Copy link

ghost commented Feb 16, 2017

Thanks for the info - I'll give that a go when I get a chance.

@danielfullmer
Copy link
Contributor

Also, check out the above pull request. It includes some patches from the debian team that has fixed my problems with yubikey+gpg.

danielfullmer added a commit to danielfullmer/nixpkgs that referenced this pull request Feb 18, 2017
The use of smartcard functionality for yubikeys (and presumably other
usb smartcards) was broken in gnupg 2.1.18.  This has apparently already
been fixed in gnupg master, and debian backports the included patches
for 2.1.18.

See also:
https://bugs.gnupg.org/gnupg/issue2933
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852702
NixOS#21991
fpletz pushed a commit that referenced this pull request Feb 20, 2017
The use of smartcard functionality for yubikeys (and presumably other
usb smartcards) was broken in gnupg 2.1.18.  This has apparently already
been fixed in gnupg master, and debian backports the included patches
for 2.1.18.

See also:
https://bugs.gnupg.org/gnupg/issue2933
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852702
#21991
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants