-
Notifications
You must be signed in to change notification settings - Fork 26
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
PIN is (still) requested every time #144
Comments
Hi! I have got a similar problem, on Linux. I didn't check the output of
I thought |
I think I may have the same problem, looking at pcscd logs:
|
It seems to be the way it works in PCSC-lite: see https://pcsclite.apdu.fr/api/pcscd_8h.html#a470bcb4ab0dad6b913bd9e8772b21715 We could try to recompile it with Why are we the only ones affected? Maybe most of other users are using MacOS instead of Linux? |
I recompiled pcsc-lite with this patch: diff --color --unified --recursive --text --color pcsc-lite-1.9.9.orig/src/pcscd.h.in pcsc-lite-1.9.9.new/src/pcscd.h.in
--- pcsc-lite-1.9.9.orig/src/pcscd.h.in 2023-04-27 13:01:58.189410273 +0200
+++ pcsc-lite-1.9.9.new/src/pcscd.h.in 2023-04-27 13:02:55.869596216 +0200
@@ -74,7 +74,7 @@
#define PCSCLITE_STATUS_EVENT_TIMEOUT 10*60*1000 /* 10 minutes */
/* Uncomment the next line if you do NOT want to use auto power off */
-/* #define DISABLE_ON_DEMAND_POWER_ON */
+#define DISABLE_ON_DEMAND_POWER_ON
/* Uncomment the next line if you do not want the card to be powered on
* when inserted */ and it works. Yubikey is not shutdown after 5 seconds anymore 🎉 Now, pcscd is killed after 60 seconds 🤦♂️, if you launch it using systemd: https://ludovicrousseau.blogspot.com/2011/11/pcscd-auto-start-using-systemd.html It would be soooooo easier if age-plugin-yubikey was using an agent! |
That's my guess, as well; as far as I can tell, everybody using I do think having a separate long-running agent would likewise fix the problem (without changes to |
The solution proposed by @peff will work but is not a correct solution. For example in Python using PySCard it could be as simple as: from smartcard.System import readers
from time import sleep
# use the 1st reader
connection = readers()[0].createConnection()
connection.connect()
while True:
sleep(10) |
I'm not sure this is the right solution either. If you use both |
New version of my Python script. Instead of keeping a permanent connection to the card, the new version connects and disconnects immediately so the card is available for other programs. The idea is to repeat that every 4 seconds so before the 5 seconds pcscd auto power off timeout. from smartcard.System import readers
from smartcard.scard import SCARD_LEAVE_CARD
from smartcard.Exceptions import CardConnectionException
from time import sleep
# use the 1st reader
connection = readers()[0].createConnection()
while True:
try:
connection.connect(disposition=SCARD_LEAVE_CARD)
connection.disconnect()
except CardConnectionException:
pass
sleep(4) |
Thanks @LudovicRousseau! For anyone using nixos, I created a flake that exposes a systemd service running this script above. Tested on x86_64-linux and works ok. |
I tried the suggested script earlier and found a few corner cases:
So I was able to shorten my script down to just this: #!/usr/bin/perl
use Chipcard::PCSC;
my $ctx = Chipcard::PCSC->new;
while (1) {
for (grep { /yubikey/i } $ctx->ListReaders) {
Chipcard::PCSC::Card->new($ctx, $_, $Chipcard::PCSC::SCARD_SHARE_SHARED);
}
sleep(4);
} (there's no real reason to write in perl vs python; it was simply what I turned to when initially when writing my version). It seems to work, though I haven't tested it for more than a few minutes. I do still find this approach to be pretty hacky compared to just telling pcscd not to power-off, but I guess hacky is in the eye of the beholder. |
Curiously, I was fighting this issue all yesterday, and finally arrived at this repo to file a bug report, and instead, I found a fix. Not just a fix, but a flakey fix. How good is that? I have lots of YubiKeys and I pull them out and plug them in again whenever. So i had a crack at the script. My version. Seems to work, but tomorrow I will test more. #!/usr/bin/env python3
import os
import logging
from smartcard.System import readers
from smartcard.scard import SCARD_LEAVE_CARD
from smartcard.Exceptions import CardConnectionException
from time import sleep
LOGFILE='/tmp/pcscd-keep-alive.log'
def logger_init(logf = LOGFILE):
# see if LOGFILE exists
try:
inode = os.stat(LOGFILE)
except:
inode = None
# if it exists, remove it
if inode is not None:
try:
os.unlink(LOGFILE)
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")
print(f"{LOGFILE}: cannot unlink")
return None
try:
con = logging.StreamHandler()
fil = logging.FileHandler(LOGFILE)
fmt = logging.Formatter('%(asctime)s - %(message)s')
log = logging.getLogger('pcscd-keep-alive.log')
log.setLevel(logging.DEBUG)
fil.setLevel(logging.DEBUG)
con.setLevel(logging.ERROR)
con.setFormatter(fmt)
fil.setFormatter(fmt)
log.addHandler(con)
log.addHandler(fil)
return log
except:
return None
def debug(msg):
if logger is not None:
logger.debug(msg)
def info(msg):
if logger is not None:
logger.info(msg)
def warn(msg):
if logger is not None:
logger.warning(msg)
logger = logger_init()
info('starting up')
active=set()
while True:
try:
rdr = readers()
cur = set()
for r in rdr:
cur.add(r)
# debug(f"{active=} {cur=}")
for r in rdr:
if r not in active:
active.add(r)
info(f"{r}: plugged in")
try:
conx = r.createConnection()
try:
conx.connect(disposition=SCARD_LEAVE_CARD)
conx.disconnect()
except CardConnectionException as err:
warn(f"{r}: createConnection: {err=}")
except Exception as err:
debug(f"{r}: Unexpected {err=}, {type(err)=}")
except:
debug("not reached")
del conx
except Exception as err:
debug(f"{r}: Unexpected {err=}, {type(err)=}")
except:
debug("not reached")
# keep the active set up-to-date
for r in (active - cur):
info(f"{r}: removed")
active.remove(r)
except Exception as err:
debug(f"Unexpected {err=}, {type(err)=}")
except:
debug("not reached")
sleep(4) |
@peff agreed with you on the approach. Here's my understanding of all the approaches:
|
From https://github.com/str4d/age-plugin-yubikey#agent-support
If you want to cache the PIN you should do that in age or age-plugin-yubikey. |
Environment
What were you trying to do
Trying to decrypt multiple times while having to enter the PIN only once, i.e. running
multiple times.
What happened
The first time I run the command, I'm asked for my PIN and have to touch the key, as expected.
If I run the command a second time immediately afterwards, the PIN is not required and I just have to touch the key.
However, if I wait only a few seconds before running the command the second time, I will be asked for the PIN again.
I believe that there is a correlation to the output of
pcscd -f -d
.After I run the decryption command, the end of the output looks like this:
After about 5 seconds, another two lines appear:
I'm rather confident that this marks the time when the Yubikey will require the PIN again to run another decryption.
I don't know what it means that the device is powered down. I have checked that USB autosuspend is turned off for the key. It might be related to https://ludovicrousseau.blogspot.com/2010/10/card-auto-power-on-and-off.html, but I don't see how this would affect only me.
The text was updated successfully, but these errors were encountered: