Page MenuHome GnuPG

authentication with USB token, screen lock on token removal
Open, NormalPublic


Possibly, PAM module with SCDaemon, replacing Poldi.

  • authentication for a user
    • host sends the token a challenge to ask signing by auth key
    • host examines the signature if its valid against the public key
  • no special configuration is preferred
    • let us consider use of ~/.ssh/authorized_keys to identify the public key of auth key?
      • it means, when ssh login can be done with the auth key, local login should be also allowed using the token

Event Timeline

gniibe triaged this task as Normal priority.Mar 1 2022, 8:38 AM
gniibe created this task.

Possibly, it could be done with pam_exec
developing a simple executable (or even small shell script).

It may be simpler if we can enhance scdaemon to have an option for PKAUTH, say, --challenge-response, so that it generates a challenge and verify signature internally.

Here is an experimental shell script for testing:

It doesn't support all possible use cases, but some, when popup of pinentry is OK.

It is not good for login manager and screen lock (when unlock), because use of GUI pinentry is not relevant.

Improvements are needed for:

  • Not using gpg-connect-agent (through gpg-agent), but connect scdaemon directly, by assuan protocol
  • It should accept "INQUIRE" of assuan protocol, for PIN interaction
  • Then, user interaction (asking PIN, or asking selection of keys) should be done stdio/stdout, so that it can be through PAM

BTW, there are various use cases for authentication(s), it is better to focus on the part of device and crypto (USB Token and scdaemon).

The rest should be handled by PAM configuration.

  • if it can skip usual passphrase authentication
  • if it's two factor authentication (that is, along with usual passphrase authentication)
  • if it can be used for a session by single time input of passphrase (PIN of USB token == login passphrase); enable USB token at the start of a session

More things to be considered:

  • How to connect scdaemon
  • How to invoke scdaemon

If it is compatible to Poldi, it is:

  • It depends on use case of authentication
    • For login authentication, it is by system, root
      • Invoke scdaemon spawing a process
    • For sudo/screen lock, it is by a user in question
      • Ask gpg-agent for the socket name to scdaemon
        • if no scdaemon, it is invoked by gpg-agent, by asking the sockent name
      • connect to that socket

I write a prototype in Python using pyassuan:

It is used like:

$ python3 -v /run/user/1000/gnupg/S.scdaemon
Please unlock the card

Hit RET means cancelling unlocking the card.

Wrote a pam module which interacts a user for auth:

And updated

This is the one for login authentication (which invokes scdaemon to authenticate, instead of connecting by socket).

Using the above, I configured /etc/pam.d/lightdm by:

--- /etc/pam.d/lightdm.bak	2022-05-17 17:52:50.362767660 +0900
+++ /etc/pam.d/lightdm	2022-05-17 17:53:02.090916824 +0900
@@ -7,7 +7,11 @@
 session      required readenv=1
 session      required readenv=1 envfile=/etc/default/locale
-@include common-auth
+# @include common-auth
+auth	[success=1 default=ignore] log=/tmp/x1 /usr/bin/python3 /home/gniibe/work/ -v
+auth	requisite
+auth	required
 -auth  optional

Then, it works as expected.

NOTE that when you change the PAM configuration file under /etc/pam.d/, you should have another terminal by root (for example, with a virtual console terminal), so that you can change back it even if failure. (Or else, your system will have no way to recover.)

This is updated version of gpg-auth, which clears the authentication state before trying PKAUTH.
Access is controlled by ~/.ssh/authorized_keys.

The exit status is 0 (true), when success. 1 (false) when somthing wrong.

It works with GnuPG 2.3.5 or later, when a user can use scdaemon through gpg-agent.

This may be useful for a user to restrict use of some program only with the card/token.

With cmatrix command and pinentry-gtk2, I now do experiment with this script:

By the command line:

gnome-terminal --hide-menubar --window --full-screen -- ./

it is possible for the full screen terminal to occupy the whole display.

A user can stop cmatrix screen saver, by typing a key. Then, it invokes script.

I think that if this 'screenlock' runs just after logging-in, it is virtually login with an authentication using a card/token, with no PAM configuration.

I added the last line, to recover tty state:

Note that this doesn't work if pinentry is pinentry-gnome3. pinentry-qt works well, too, because it supports curses fallback.

A concrete example use case in my mind is:

  • (Usual display manager (authentication by password or no-password))
  • session starts with "locked" state of screen
    • In the beginning, user needs to "unlock" the screen, by scdaemon authentication
  • (optionally, if needed) our-own-screen-locker should detect device removal, then, automatically locks the screen
  • our-own-screen-locker should detect idling user session, then, disabling the card, automatically locks the screen
  • our-own-screen-locker does authentication by scdaemon when it unlocks the screen

I did some research about scree lockers (xtrlock, slock, swaylock, etc.).

I think that writhing Authentication Module would be a good option, for now.