\input texinfo                  @c -*- Texinfo -*-
@c Copyright (C) 2000, 2002, 2003, 2004, 2005,
@c               2007, 2008, 2009 Free Software Foundation, Inc.
@c 
@c This file is part of Poldi.
@c
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU General Public License as published by the
@c Free Software Foundation; either version 2 of the License, or (at your
@c option) any later version. A copy of the license is included in the 
@c file 'gpl.texi'.
@c
@setfilename poldi.info
@settitle The `Poldi Reference Manual

@dircategory GNU Utilities
@direntry
* poldi: (poldi).	PAM authentication via OpenPGP smartcards.
@end direntry

@include version.texi

@ifinfo
This file documents `Poldi'.

This is Edition @value{EDITION}, last updated @value{UPDATED}, of
@cite{The Poldi Manual}, for Version @value{VERSION}.

Copyright @copyright{} 2004, 2005, 2006, 2007, 2008, 2009 g10 Code GmbH.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. The text of the license can be found in the
section entitled ``Copying''.
@end ifinfo

@titlepage
@center @titlefont{The Poldi Manual}
@sp 6
@center Edition @value{EDITION}
@sp 1
@center last updated @value{UPDATED}
@sp 1
@center for version @value{VERSION}
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 2004, 2005, 2006, 2007, 2008 g10 Code GmbH.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. The text of the license can be found in the
section entitled ``Copying''.
@end titlepage
@summarycontents
@contents
@page

@ifnottex
@node Top
@top Main Menu
This is Edition @value{EDITION}, last updated @value{UPDATED}, of
@cite{The Poldi Manual}, for Version
@value{VERSION} of Poldi.

Copyright @copyright{} 2004, 2005, 2006, 2007, 2008, 2009 g10 Code GmbH.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. The text of the license can be found in the
section entitled ``Copying''.

@end ifnottex

@menu
* Overview::
* Authentication methods::
* Installation from Source::
* Configuration::
* Configuration Example::
* Testing::
* Notes on Applications::
* Copying::                     The GNU General Public License

@c @detailmenu
@c  --- The Detailed Node Listing ---
@c * Overview::                    Overview
@c * Building::                    Building Poldi
@c @end detailmenu

@end menu

@node Overview
@chapter Overview

Poldi is a PAM module implementing challenge/response based
authentication through the OpenPGP
smartcard@footnote{http://www.g10code.de/p-card.html}.  It makes use of
several GnuPG components@footnote{Libgcrypt, Assuan, Scdaemon, Dirmngr}
and currently supports two authentication methods:

@table @asis
@item ``local-database'' authentication method

This method establishes the mapping between user accounts and
smartcards through a locally administered database.

@item ``X509'' authentication

This method uses the PKI infrastructure provided by Dirmngr for
validating certificates.  OpenPGP smartcards are associated with X509
certificates through the smartcard's ``url'' field; the user account
name to use for authentication is extracted from the certificate.
@end table

This manual is primarily intended for system administrators interested
in setting up authentication through PAM Poldi.

@node Authentication methods
@chapter Authentication methods

This chapter explains the supported authentication methods in detail.

@menu
* Local-database authentication::
* X509 authentication::
@end menu

@node Local-database authentication
@section Local-database authentication

The login process through local database authentication consists
essentially of three parts: looking up the smartcards key on the local
computer, figuring out the desired identity for the login and finally
doing challenge/response authentication against the local key.

Poldi maintains a database, which associates local user accounts with
smartcards (through their serial number).  One smartcard can be
associated with many users and one user can be associated with many
smartcards.

The public keys are stored in files in a subdirectory named
``keys''.  The files are named after the card serial numbers and must
contain the public key as a single S-Expression as it is printed out
by gpg-connect-agent (See below).

The mapping between keys and Unix accounts is to be established by
adding appropriate entries to the user database file named ``users''.
Such an entry is of the following form:

@example
<card serial number> <white space(s)> <account>.
@end example

@node X509 authentication
@section X509 authentication

With X509 authentication smartcards need to be associated with X509
certificates.  This mapping is to be established through the ``url''
field on the OpenPGP smartcard.  The url field is expected to hold
either a valid LDAP url (``ldap://...'') or a file url
(``file:///...'').  After a certificate has been successfully looked
up, it is validated through Dirmngr and a challenge-response
authentication is triggered against the smartcard.  The mapping
between smartcards and local accounts is established through the list
of email addresses contained in the certificate.  Through the
configuration file, Poldi is informed about the ``X509 domain'' to
use.  This domain is used when looking through the list of email
addresses for the local username on the system. Note: semantics might
change.

To illustrate this with an example: lets assume a user is trying to
authenticate himself through Poldi's X509 method.  Poldi looks up the
url field of the user's smartcard and retrieves his X509 certificate.
The certificate contains two e-mail addresses: ``<dude@@example.com>''
and ``<fry@@gnupg.org>''.  Since the administrator set the ``X509
domain'' to ``gnupg.org'' in Poldi's configuration file, Poldi will
pick out the address ``fry@@gnupg.org'' and (after successful
challenge-response authentication) will let the user login as ``fry''.

@node Installation from Source
@chapter Installation from Source

Building and installing Poldi from source should be pretty
straightforward, since it uses the GNU autotools.  Build- and runtime
dependencies may vary with the enabled authentication methods.

Independent from enabled authentication methods, Poldi depends on
Libgpg-error, Libgcrypt, Libassuan, Scdaemon and of course Libpam.

The ``X509'' authentication method additionally has a build-time
dependency on libksba and requires Dirmngr to be properly setup at
runtime.  The ``local database'' authentication method has no
additional requirements.

Details on the building procedure can be found in the file
``INSTALL''.

At least one configure switch should be set:
@code{--with-pam-module-directory}, which specifies the installation
directory for PAM modules.  Alternatively one can copy the built PAM
module (named ``pam_poldi.so'') to the correct place manually.

For building the Poldi package, ``make'' needs to be invoked.

Installing Poldi works by invoking the ``install'' make target.  As
noted before, special care must be taken so that the PAM module ends up
in the correct place.

Poldi requires some directories beneath `SYSCONFDIR/poldi', which is
usually equal to `PREFIX/etc/poldi'. These directories can be created
manually or through the `install-conf-skeleton' make target.

@node Configuration
@chapter Configuration

Poldi can be configured through configuration files and through PAM
arguments.  All configuration files of Poldi are stored beneath
``@code{sysconfdir}/poldi''.

Poldi's main configuration file is
``@code{sysconfdir}/poldi/poldi.conf''.  The syntax of Poldi's
configuration file is identical to the one used by several other GnuPG
components; options and their values are written next to each other,
separated by a white space - one such configuration item per line.

Poldi supports the following authentication method independent
options, which can be specified in the main configuration file and in
the PAM configuration files as arguments to the Poldi PAM module (with
standard double-dash notation).

@table @code
@item log-file FILENAME
Specify the file to use for log messages.
@item auth-method AUTH-METHOD
Specify the authentication method to use.  May be either ``localdb''
or ``x509''.
@item debug
Enable debugging messages.
@item scdaemon-program
Specify scdaemon executable to use.
@item scdaemon-options
Specify scdaemon configuration file to use.
@item modify-environment
This option causes Poldi to add certain Poldi related environment
variables to the PAM environment.  Currently, the following variables
are set:
@table @asis
@item PAM_POLDI_AUTHENTICATED
This variable is set to the empty value.
@item PAM_POLDI_SERIALNO
This variable is set to the serial number of the card used during
authentication.
@item PAM_POLDI_LANG
This variable is set to the value of the LANG data field.  Please note
that the exact semantics of this might change in the future.
@end table
@item quiet
This option causes Poldi to skip most of the
PAM info messages during authentication.  Careful: the exact
semantics of this option might change.  Primarily this is a
workaround for programs like GDM, which collect these info messages
and put them in a dialog box with an OK-button.  When using e.g. GDM
with the quiet option, authentication should work without any
interaction.
@end table

Further configuration depends on the authentication method to use.

@menu
* Configuration for ``local-database'' authentication::
* Configuration for ``X509'' authentication::
@end menu

@node Configuration for ``local-database'' authentication
@section Configuration for ``local-database'' authentication

For the local-database authentication method additional configuration
is required.  All local-database specific configuration files are
stored in the subdirectory ``localdb'':

@table @code
@item File: users
This file contains the mapping between smartcard serial numbers and
local usernames.  Syntax: this file consists of entries - one entry
per line.  Entries are of the form:
"<SERIALNO><WHITESPACES><USERNAME>\n" (without quotation marks and
without angle brackets.  Allowed whitespaces are spaces and tabs.
<SERIALNO> is the serial number of an OpenPGP smartcard.  It can be
obtained by "gpg --card-status" command as ``Application ID''.
<USERNAME> is a valid username on the system.  Comments are opened
with "#" and terminated by a newline.

@item Directory: keys

This directory contains the "key database" for Poldis "local database"
authentication method.  When Poldi needs the key belonging to a given
smartcard serial number, it looks up a file in this directory whose
name is exactly the serial number.

Usually only the system administrator is able to modify this directory
and thus establish the mapping between smartcards and keys.  But it
might make sense for the administrator to make a file in this
directory writable for a ordinary user as well, since this would allow
that user to update his smartcard's key and adjust the mapping himself
without bothering the admin.
@end table


@node Configuration for ``X509'' authentication
@section Configuration for ``X509'' authentication

In case X509 authentication is enabled, Poldi tries to parse another
configuration file, namely ``poldi-x509.conf''.  The following
configuration options are supported for this configuration file:

@table @code
@item dirmngr-socket FILENAME
Specify the socket to be used for communication with Dirmngr.

@item x509-domain STRING
Specify the X509 domain, which is simply a suffix required for
recognizing email addresses contained in user certificates as
belonging to the system on which authentication happens.
@end table

@node Configuration Example
@chapter Configuration Example

@menu
* Example for ``local-database'' authentication::
* Example for ``X509'' authentication::
@end menu

@node Example for ``local-database'' authentication
@section Example for ``local-database'' authentication

Lets assume a new installation of Poldi into the root filesystem,
having configuration files stored beneath /etc/poldi. The user
``moritz'', who got an OpenPGP card with the serial number
``D2760001240101010001000006550000, would like to authenticate himself
through Poldi.

First, the system administrator has to associate the user moritz with
the card's serial number:

@example
$ echo "D2760001240101010001000006550000 moritz" >> /etc/poldi/localdb/users
@end example

Second, the system administrator needs to write the card's key into a
card-specific key file.  Therefore he inserts Moritz' smartcard and
executes:

@example
$ gpg-connect-agent "/datafile /etc/poldi/localdb/keys/D2760001240101010001000006550000" "SCD READKEY --advanced OPENPGP.3" /bye
@end example

The administrator wants to allow Moritz to update his card's key
himself; he/she types:

@example
$ chown moritz /etc/poldi/localdb/keys/D2760001240101010001000006550000
@end example

That's it.

@node Example for ``X509'' authentication
@section Example for ``X509'' authentication

Setting up X509 authentication is more complicated than setting up
localdb authentication, since more components are involved.  This
sections tries to explain the basic steps.

When using localdb authentication, all we need is a list of keys on
the system, against which the challenge-response authentication is
done.  For X509 authentication we need to:

@table @asis
@item ... create X509 certificates
one per smartcard, issued by a certificate authority trusted by Dirmngr
@item ... setup the smartcards
so that they ``point'' to ``their'' certificates
@item ... run Dirmngr
making it listen on a specific socket
@item ... setup Poldi
specifying Dirmngr's socket and the ``X509 domain'' in poldi-x509.conf.
@end table

Lets assume we don't have a certificate authority yet.  For the CA
administration one needs a CA program, like OpenSSL.  It can either be
used directly or through a GUI frontend like ``Tiny CA''.

FIXME: explain situation/goal (x509_domain).

Step 1: Create a CA.  I created my test CA with the following
settings:

@table @asis
@item Common Name: Fnord Inc CA
@item Country Name: DE
@item Organization Name: Fnord Inc
@item Organizational Unit: Testing
@end table

The other options required are rather self-explanatory.  After CA
creation, we need to generate a signing request.  For this,
gpgsm --gen-key can be used (after inserting the users smartcard).
Here is an example session (* at the beginning means user's input):

@example
*    $ gpgsm --gen-key
     gpgsm (GnuPG) 2.1.10; Copyright (C) 2015 Free Software Foundation, Inc.
     This is free software: you are free to change and redistribute it.
     There is NO WARRANTY, to the extent permitted by law.

     Please select what kind of key you want:
        (1) RSA
        (2) Existing key
        (3) Existing key from card
*    Your selection? 3
     Serial number of the card: D276000124010200F517000000010000
     Available keys:
        (1) 101DE7B639FE29F4636BDEECF442A9273AFA6565 OPENPGP.1
        (2) 65F67E742101C7FE6D5B33FCEFCF4F65EAF0688C OPENPGP.2
        (3) 5D6C89682D07CCFC034AF508420BF2276D8018ED OPENPGP.3
*    Your selection? 3
     Possible actions for a RSA key:
        (1) sign, encrypt
        (2) sign
        (3) encrypt
*    Your selection? 2
*    Enter the X.509 subject name: CN=Niibe Yutaka
     Enter email addresses (end with an empty line):
*    > gniibe@@fsij.org
*    > 
     Enter DNS names (optional; end with an empty line):
*    > 
     Enter URIs (optional; end with an empty line):
*    > 
*    Create self-signed certificate? (y/N) y
     These parameters are used:
         Key-Type: card:OPENPGP.3
         Key-Length: 1024
         Key-Usage: sign
         Serial: random
         Name-DN: CN=Niibe Yutaka
         Name-Email: gniibe@@fsij.org

*    Proceed with creation? (y/N) y
     Now creating self-signed certificate.  This may take a while ...
     gpgsm: about to sign the certificate for key: &5D6C89682D07CCFC034AF508420BF2276D8018ED
     gpgsm: certificate created
     Ready.
     -----BEGIN CERTIFICATE-----
     MIIDBDCCAeygAwIBAgIIElClyprjBd8wDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UE
     AxMMTmlpYmUgWXV0YWthMCAXDTE1MTIxNzEwNDI0NloYDzIwNjMwNDA1MTcwMDAw
     WjAXMRUwEwYDVQQDEwxOaWliZSBZdXRha2EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
     DwAwggEKAoIBAQC/XqCK831odBl7Po174AExdRlOcyNSCKfJR18Mrxi8LnKwyjDg
     GH7Z29Qm4XyZvnLkJvSLcYiSx46iDMWbIYH7w1Or57kp/sUzdlj6clmlV8zklVth
     ppYWpFd+x6Qif9CndRKcPr9S1+tbAIlU5k42RG90XnhEQF1/V3MR01mG0Ey9xBAI
     oHizZKX5XAjPheVGdDyZERB7Zry3e8kDrU+OjsVTjzq7oXtCE7EwI5c+pBQdF8qf
     XZC35nAizu0oqQEBne5MsF9ZIBaY/D+hhXVV51oyyCEwNGTr8Ol6KXKK7MWhf16g
     d0zjulwvO9xH88Q0n1eYur3plH+BZVjXOQPrAgMBAAGjUjBQMBoGA1UdEQQTMBGB
     D2duaWliZUBmc2lqLm9yZzARBgorBgEEAdpHAgIBBAMBAf8wDwYDVR0TAQH/BAUw
     AwEB/zAOBgNVHQ8BAf8EBAMCBsAwDQYJKoZIhvcNAQELBQADggEBAKNdnJ/q3eBt
     h42lsahgqyeRvgs7PS+PeqJyOA+36MuHf8/1rdJpqIH/zX6s7S0c/HNqTUKMiB+S
     XRQ9g5JAbldsvurYGCiSLM2bT4evC7odE8v0LOL2oBVuNZshy2jPOyI19598J2E2
     RjrJSqRguYGIG2m9B5Edog3Fe7Cd7aN8Xp69QEylb2gJqYfP1qfpyzAWQi6oE9MH
     NXh1TxDbiSOee8+5PZdgLaIsnuFG37+9c529oaJV6kTm4Qv4eSQF6XemytMgQVOM
     kM1VFCBFd62fdVPHWqI4K9hdUImdKC4KZKT+HNfXo7W1BE6mDQJbutQkcxsFpBTB
     w9T8Z/SIJJc=
     -----END CERTIFICATE-----
     $ 
@end example

Import the new certificate signing request in your CA and sign it,
yielding a new client certificate.  A note on Tiny CA: the program
defaults FIXME mail address.

Export both, the CA certificate and the client certificate, in DER
format.  Export a certificate revocation list (CRL) for your CA in DER
format.

Step 2: Setup OpenPGP smartcard

The OpenPGP smartcard is not a ``real'' PKCS#XYZ (FIXME?) smartcard -
it cannot store X509 certificates.  So instead of ``uploading'' the
certificate to the smartcard, we write an URL to the card, through
which the complete certificate can be retrieved.  Simply fill the
smartcard's ``url'' field with either a ``ldap://'' or a ``file://''
URL, pointing to the certificate.  For LDAP urls to work, the
certificate must be stored on a LDAP server and Dirmngr must be
configured to use that LDAP server.  For testing, one can simply
specify ``file:///some/where/cert-exported-from-ca.crt''.  Editing the
card's data fields is to be done through GnuPG:

@example
$ gpg --card-edit # (or gpg2)
@end example

Step 3: Setup Dirmngr.

For debugging purposes it is usually a good idea to add:
@example
debug-all
log-file /some/where/dirmngr.log
@end example

to dirmngr.conf.

Drop the exported CA certificate in Dirmngr's ``trusted-certs''
directory.

Now, run Dirmngr:

@example
$ eval $(dirmngr --socket /some/where/dirmngr.S --daemon)
@end example

and inform it about the CRL:

@example
$ dirmngr-client --load-crl previously-saved-crl.der
@end example

Check Dirmngr's log file for any errors.

Step 4: Configure Poldi.

Obviously, in the main configuration file poldi.conf, we need:

@example
auth-method x509
@end example

Again, it's a very good idea to also add:

@example
debug
log-file /some/where/poldi.log
@end example

Add the following to ``poldi-x509.conf'':

@example
dirmngr-socket /some/where/dirmngr.S # the socket name previously specified
x509-domain example.com
@end example

Now, things should be ready for trying authentication.

@node Testing
@chapter Testing

Authentication through Poldi should be tested before activating the
module.  For this purpose, the Poldi package includes a simple program
named ``pam-test'', which is suitable for testing PAM authentication.

@menu
* The pam-test program::
@end menu

@node The pam-test program
@section The pam-test program

pam-test is a small program suitable for testing PAM authentication,
without any Poldi specific aspects.  Synopsis:

@example # FIXME
pam-test [options] <service name>
@end example

The program accepts the following options: FIXME.


@node Notes on Applications
@chapter Notes on Applications

Generally speaking, all applications containing a decent PAM
integration should work flawlessly in combination with Poldi.  Sadly,
there are applications out there, which do not use PAM correctly.
Therefore, they might work not too well in case they are configured to
use Poldi.

This chapter attempts to list the most common problems or useful hints
in respect to popular applications.

When applications still ask for e.g. a username although Poldi is
activated for that application, it might be the case that other
authentication modules, which trigger this kind of user interaction, are
configured to run prior to Poldi.

@menu
* login::
* su::
* gdm::
* XScreensaver::
* xdm::
* kdm::
@end menu

@node login
@section login

The `login'-program contained in the `shadow'-package (>= v4.0.3) works
fine together with Poldi.

Usually login is launched by `getty', which might trigger user
interaction, which is not appropriate for use with Poldi (e.g., asking
for a username).  In this case, getty needs to be told to skip the task
of username querying.

The getty-program from the `util-linux'-package can be started with the
`-n' argument in order to not ask for a username.

@node su
@section su

The `su'-program contained in the `shadow'-package (>= v4.0.3) works
fine together with Poldi.

@node gdm
@section gdm

GDM contains two frontends, the `graphical greeter' and the `standard
greeter'.

At least the standard greeter can be used with Poldi just fine; the
graphical greeter obviously asks for usernames prior to triggering PAM
authentication.

@node XScreensaver
@section XScreensaver

XScreensaver (at least Version >= 5.07, possibly earlier versions too)
works quite well with Poldi authentication.  By combining SCDaemons
~/.gnupg/scd-event mechanism with the xscreensaver-command program, one
can easily setup an environment in which the card-removal event triggers
screen locking and the card-insertion event triggers screen unlocking.

Note that this also applies to GNOME Screensaver; one only needs to use
the gnome-screensaver-command program instead of xscreensaver-command.

@node xdm
@section xdm

XDM does ask for usernames prior to triggering PAM authentication, as
such it is not too suitable for use with Poldi.

@node kdm
@section kdm

KDM asks for username and password in it's default configuration,
instead of implementing PAM correctly.

@include gpl.texi

@bye
