Table of Contents
Abstract
PAM-PKCS#11 is a PAM (Pluggable Authentication Module) libary and related tools to perform login into Linux/UNIX systems by mean of X509 Certificates throught any pkcs#11 compliant library
This manual describes how to compile, install, configure and use pam-pkcs11 PAM module and related tools
Copyright (C) 2005 Juan Antonio Martinez <jonsito@teleline.es>
Copyright (C) 2003-2004 of Mario Strasser <mstt@gmx.net>
ScConf library Copyright (C) Antti Tapaninen <aet@cc.hut.fi> and Timo Sirainen <tss@iki.fi>
Release 0.5beta1. 30 Mar 2005
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
PKCS11_login is a set of libraries and tools to control the process of user login by mean of use any system that support the PKCS11 API
The Linux-PAM login module allows a X.509 certificate based user login. The certificate and its dedicated private key are thereby accessed by means of an appropriate PKCS #11 module. For the verification of the users' certificates, locally stored CA certificates as well as either online or locally accessible CRLs are used.
The Pkcs11 Event Manager is a tool to execute comands at insert or removal of SmartCard from reader. Alternatively, you can use the pcsc-lite's [1] based version
The Pkcs11 Inspect tool allow you to look at the contents of a certificate, in order to help you in the procces of Certificate-to-User mapping configuration
The Pklogin Finder tool can be used to check the pam module without need to do the entire login process, just verifying that login names are properly found and matched
Detailed information about the Linux-PAM system can be found in [2] , [3] and [4] The specification of the Cryptographic Token Interface Standard (PKCS #11) is available at [5]
[1] PCSC-Lite: an Open implementation of PCSC API http://pcsclite.alioth.debian.org/
[2] The Linux-PAM System Administrators' Guide http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html
[3] The Linux-PAM Module Writers' Guide http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam_modules.html
[4] The Linux-PAM Application Developers' Guide http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam_appl.html
[5] PKCS #11 - Cryptographic Token Interface Standard http://www.rsasecurity.com/rsalabs/pkcs/pkcs-11/
Table of Contents
Pam-pcks11 is a PAM ( Pluggable Authentication Module ) pluggin to allow to login into a UNIX/Linux System that supports PAM by mean of use Digital Certificates stored in a SmartCard
To do this, a pkcs11 library is needed to access the Cards. Details on how certificates are stored/retrieved, etc are hidden to pam-pkcs11 and handled by pkcs11 library. This allows independence of the module on an specific card
The PKCS #11 modules must full-fit the requirements given by the RSA Asymmetric Client Signing Profile, which has been specified in the PKCS #11 Conformance Profile Specification [6] by RSA Laboratories.
To approve the ownership of a certificate, that is, to allow the owner of a certificate to login as a particular user, Pam-pkcs11 uses several modules called mappers that perform cert-to-loggin mapping. See Chapter 11, What is a cert mapper? section
[Note: This is still a work in progress, any suggestions for improvements or alternative matching algorithms are welcome.]
bash# tar -xvzf pkcs11_login-X.Y.tar.gz bash# cd pkcs11_login-X.Y |
bash# ./bootstrap |
bash# ./configure bash# make bash# make install |
bash# rpmbuild -ta /path/to/pkcs11_login.X.Y.tar.gz bash# rpm -v -i /usr/src/redhat/RPMS/i386/pkcs11_login-X.Y-Z.i386.rpm bash# rpm -v -i /usr/src/redhat/RPMS/i386/pkcs11_login-tools-X.Y-Z.i386.rpm |
NOTES
Configuration of pam-pkcs11 involves two steps:
This chapter explain pam-pkcs11 configuration-related issues. Next one relies on generic PAM options. You should read this manual and study provided configuration sample files before doing any change.
You must know:
Configuration file is based on the scconf library
Parameters and data are grouped into blocks. blocks can be nested in a sort of XML tree
pam-pkcs11 config file looks like:
pam-pkcs11 { global options ... use_pkcs11_module= pkcs11 module to be used pkcs11_module module1 { module1 specific options } pkcs11_module module2 { module2 specific options } [...] use_mappers= mapper1, mapper2,... ; mapper mapper1 { mapper1 specific options } mapper mapper2 { mapper2 specific options } [...] mapper mapperN { mapperN specific options } } |
For detailed description see pam_pkcs11.conf.example file
Details on scconf syntax and API are provided in src/scconf/README.scconf file
PAM-pkcs11 needs a list of recognized Certificate authorities, to properly validate certificates. Same applies to Certificate Revocation Lists (if configured to use)
So the process to setup ca and crl entries is:
bash# cd /path/to/ca/dir bash# /usr/bin/make_hash_link.sh |
NOTE: Due to OpenSSL library limitations, CA entries must reside in the local filesystem, and can not be accessed from a remote server. So althought user auth can be done in a remote way, certificate validation must be done locally.
If your elected mapper module(s) uses login mapping, you'll need to create and setup mapping files. Some examples are provided in source code.
As a general rule, a mapping file has a newline terminated list of certificate contents -> login entries:
Certificate1 entry data -> login1 Certificate2 data -> login2 Certificate2 data -> login3 |
Remember that this file is parsed in order, returning on first match
As you can see bellow, mapfile specification doesn't need to be a regular file: you can retrieve data from any legal URL. Anyway, data format must be preserved. See the section called “How to use mapfiles” for additional info
Table of Contents
To make use of the PKCS #11 login module replace the line
auth requisite pam_unix2.so ... |
with
auth sufficient pam_pkcs11.so ... |
in the pam.d/serviceXXX configuration files.
Some mappers doesn't map to an existing user. To allow correct login, you may need to install also pam-mkhomedir in session pam stack See http://www.kernel.org/pub/linux/libs/pam for details
The following options are recognised for pam-pkcs11.so:
Next options should be taken from configuration file, but is up to the user to specify them from command line. If so, it takes precedence over configuration file
Next options are pkcs11 module specific:
Filename of the PKCS #11 module. The default value is /etc/pkcs11/pkcs11_module.so
Note that this option takes precedence over "module" entry in proper pkcs11_module section, but this section is still needed
Slot-number to use. One for the first, two for the second and so on. The default value is zero which means to use the first slot with an available token.
Path to the directory where the CA certificates are stored. The directory must contain an openssl hash-link to each certificate. The default value is /etc/pkcs11/cacerts.
Pam-pkcs11 provides an utility: make_hash_link.sh that can be used to create hash links to certificate files. Hashes are used to check certification validity and revocation
Here comes preferred way to insert pam-pkcs11 into pam stack:
[jantonio@jonsy pkcs11_login-0.4.1]$ cat /etc/pam.d/login #%PAM-1.0 auth sufficient pam_pkcs11.so debug config_file=/etc/pkcs11/pam_pkcs11.conf auth required pam_securetty.so auth required pam_stack.so service=system-auth auth required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth session optional pam_console.so |
An alternate way is to explicite options. This is not recommended, but still possible:
#%PAM-1.0 auth sufficient pam_pkcs11.so nullok debug try_first_pass \ config_file=/etc/pkcs11/pam_pkcs11.conf \ pkcs11_module=/usr/lib/pkcs11/pkcs11_module.so \ ca_dir=/etc/cacerts/ crl_dir=/etc/cacerts/ crl_policy=auto auth required pam_securetty.so auth required pam_stack.so service=system-auth auth required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth session optional pam_console.so |
In this second example, configuration file is still needed to get mapper module options and flags
Starting at pkcs11_login-0.4.2 a new feature is provided: pam-pkcs11 can deduce user name from certificate, without login prompt
This is done when pam_get_user() call returns null or empty string. In this case, pam-pcks11 use the module mapper "find" feature instead of normal "match".
If the finder list returns ok, evaluated user is set to pam via pam_set_item(PAM_USER) call, and PAM_AUTH_OK is returned
So there are no longer need to enter login name if a certificate is provided and can be mapped to an user
There are to ways for using this feature:
In both cases the procedure follows as:
This feature can be used with pam-mkhomedir.so PAM Session module. In this case, you can create on-the-fly accounts. This scenario is ideal for centralized auth services ( Winbind, ldap, kerberos, RDBMS auth... )
As example, here comes my tested /etc/pam.d/gdm file:
#%PAM-1.0 auth sufficient pam_pkcs11.so debug config_file=/etc/pkcs11/pam_pkcs11.conf auth required pam_env.so auth required pam_stack.so service=system-auth auth required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth session optional pam_mkhomedir.so skel=/etc/skel umask=0022 session optional pam_console.so |
IMPORTANT NOTES: For pam_set_item(PAM_USER) gets success, application using pam must be enought permissions. If this condition is not met, setting user process will fail and proper log message registered. So this feature is mainly provided for logging processes running as root
Improper mapper chain configurations with unauthorized certificates can lead in create fake accounts in the system if pam_mkhomedir.so module is used. So be really carefull when authenticate users directly from certificates
Table of Contents
PAM-PKCS11 includes several tools: card_eventmgr and pkcs11_eventmgr that can be used to monitorize the status of the card reader and dispatch actions on several events. These programs can be used to several actions, like lock screen on card removal
Note that these programs has no direct interaction with pam-pkcs11 module: they are just a card status monitor. It's up to the sysadmin to define and configure actions to take on events
card_eventmgr is a card status monitor based on the PCSC-Lite library
To invoke the program, just type card_eventmgr. Several command lines are recognized:
Here comes an example of configuration file. Its auto-descriptive:
card_eventmgr { # Run in background. daemon = false; # show debug messages debug = false; # polling time in mili-seconds timeout = 1000; # # list of events and actions # # Card inserted event card_insert { # what to do if an action fail? # ignore : continue to next action # return : end action sequence # quit : end program on_error = ignore ; # You can enter several, comma-separated action entries # they will be executed in turn action = "/usr/bin/play /usr/share/sounds/warning.wav", "/usr/X11R6/bin/xscreensaver-command -deactivate"; } # Card has been removed event card_remove { on_error = ignore; action = "/usr/bin/play /usr/share/sounds/error.wav", "/usr/X11R6/bin/xscreensaver-command -lock"; } } |
Starting pam-pkcs11-0.4.4 a new eventmgr tool is provided: pkcs11_eventmgr. It's very similar to card_eventmgr, with some improvements:
Here comes pkcs11_cardmgr sample file, with defaults
# Sample pkcs11_eventmgr configuration file # pkcs11_eventmgr { # Run in background. Implies debug=false daemon = true; # show debug messages debug = false; # polling time in seconds polling_time = 1; # expire time in seconds # default = 0 ( no expire ) expire_time = 0; # pkcs11 module to use pkcs11_module = /usr/lib/pkcs11/opensc-pkcs11.so; # # list of events and actions # Card inserted event card_insert { # what to do if an action fail? # ignore : continue to next action # return : end action sequence # quit : end program on_error = ignore ; # You can enter several, comma-separated action entries # they will be executed in turn action = "/usr/bin/play /usr/share/sounds/warning.wav", "/usr/X11R6/bin/xscreensaver-command -deactivate"; } # Card has been removed event card_remove { on_error = ignore; action = "/usr/bin/play /usr/share/sounds/error.wav", "/usr/X11R6/bin/xscreensaver-command -lock"; } # Too much time card removed event expire_time { on_error = ignore; action = "/bin/false"; } } |
As you can see, on each event you can define a list of actions, and what to do if an action fails
The best way to start card monitoring is at user login into system. If so, note that all event commands will be executed with user privileges. So is up to the user take care that has permissions to execute desired actions
Special checks should be done when invoke setuid/segid programs: these commands usually ignore the user environment and set up their one. So these applications may not work as expected
Command actions are executed via execve("/bin/sh","-c","provided command",null,environ) in order to avoid risk on system() library call
You can use provided configuration sample file. Just add to your .xsession or KDE/GNOME Autostart directory an invocation to card_eventmgr in daemon mode
Additionally you can add this entry to /etc/pam.d/xscreensaver configuration
#%PAM-1.0 # Red Hat says this is right for them, as of 7.3: auth sufficient pam_pkcs11.so debug config_file=/etc/pkcs11/pam_pkcs11.conf auth required pam_stack.so service=system-auth # This is what we were using before: # auth required pam_pwdb.so shadow nullok |
In this case, when card is removed the X screen will lock. When card is re-inserted, screen will prompt for the card PIN, check it and if access granted the screen will unlock
NOTES:
PAM-PKCS#11 provides another tool: pklogin-finder, that can be used to find Cert-to-login maps, outside the PAM environment. This tool can be used to create and test map files, or to check environment and configuration files, without need to use PAM related tools
pklogin_finder uses the same structure and configuration than pam-pkcs11 module. It reads certificate, and try all specified mappers to find a user match. When found, login name is displayed on stdout
To invoke, just type from console:
bash$ pklogin_finder [[no]debug] [config_file=<file>] |
By default, debug is set to false, and config_file to /etc/pkcs11/pam-pkcs11.conf. All PAM related options (nullok, try_first_pass, and so ) in configuration file are ignored
Return values are:
Starting at 0.5 version, a new tool pkcs11_inspect is provided
pkcs11_inspect is a pkcs#11 based tool to explore certificate contents. It's similar to pklogin_finder, but no mapping is done at all: just load mappers chains, and in turn, try to get proper data from certificate (ie: cn_mapper looks for CN entries, and so )
When desired info is found, pkcs11_inspect print found data to stdout, without doing any mapping, that is, mapfile entries in configuration file are ignored
The reason to exist for this tool is to ease the making of mapping files:
Same command line options and configuration file than pklogin_finder applies to pkcs11_inspect command, But note that mapping and ignorecase options will be ignored. See manpage for details
Table of Contents
When a X509 Certificate is providen, there are no direct way to map a cert to a login. With a certificate we can check validity and revocation, but user mapping depends entirely on certificate contents
So we need a configurable, stackable, and definable way to specify cert-to-user mapping.
pam-pkcs11 cert mappers provides several functions to:
Normal pam-pkcs11 login process involves following procedures:
An alternate way of working is by mean of not providing user name:
Last way needs an aditional pam-mkhomedir.so PAM module, that can dinamically create an account
Operations (*) and (**) are the reason for cert-mappers to exist
pam-pkcs11 implements cert mapper in form of dinamyc loaded modules. You can add as many modules as desired, and the system will try all of them in turn, until match is done, or end of list get reached
The mapper list is defined in the configuration file:
pam-pkcs11 { .... use_mappers = mapper1 [ [[,] mapper2 ] ... ] ; .... mapper mapper1 { debug = false; module = /path/to/module.so; [ additional mapper dependent options ] } .... } |
"module" option is mandatory: says pam_pkcs11 where to find dynamic library. Additional entries can be defined but are module dependent
Most of mappers supports the concept of mapfile ,that is, a system to convert a given certificate data item to a user login. The reason are simple:
The mapfile scheme used in pam-pkcs11 is powerfull: it's not only restricted to files, so we can specify HTTP,LDAP,FTP and so connections, to retrieve mapfile. So this scheme is ideal for centralized accounting systems
The common structure of all mapfiles is:
Certificate 1 entry data -> login1 Cert 2 data -> login2 string from -> string to |
That is: a string, the sequence " -> " (space,dash,great,space) and a login
NOTE: It's sintactically correct to specify more than one word in the right-side of a map entry. But be aware that most mappers expect to be returned a single word that provides a user login. Otherwise extrange behaviour may occur. See specific notes on mappers
When a mapper module uses mapfiles, has a structure like:
... mapper my_mapper { ... mapfile = URL; } ... |
URL is an Universal Resource Locator as defined in corresponding RFC:
Note that depending on compile time options pam-pkcs11 may not support all URL syntax. See Install section and use of --use-curl configure option
Provided source code includes several example mapping files
The standard pam-pkcs11 provides following mapper modules:
Assumes CN field on certificate to be the login name.
In either cases, if a mapfile is used, the mapper will try to map CN into a login and use it
Configuration entry is as follow:
# Common Name (CN) to login mapper mapper cn { debug = false; module = /usr/lib/pam_pkcs11/cn_mapper.so; # mapfile = "file:///etc/pkcs11/cn_mapfile; ignorecase = false; mapfile = "none" } |
Extract Certificate Subject and assume it as login.
In either cases, if a mapfile is used, the mapper will try to map subject into a login and use it
Configuration file is like:
# Certificate Subject to login mapper mapper file { debug = false; module = /usr/lib/pam_pkcs11/subject_mapper.so; ignorecase = true; # mapfile = file:///etc/pkcs11/subject_map; mapfile = "none"; } |
The mapping file must follow this structure:
.... Certificate Subject -> login .... |
Note that some certificates handle extrange char mappings ( non utf-8 ) so you must ensure correct byte-to-byte match. You can use provided pkcs11_inspect tool to get and store correct data from certificate
Compare CN against getpwent() library call login or gecos returned values to match user login
Note: newer implementations of getpwent() libraries, use an additional Name Service Swicth (NSS) infrastructure, that allows admins to specify how to obtain requested data. This means you can setup /etc/nsswitch.conf password entries to lookup in to /etc/passwd, or ldap/kerberos/NIS+/YP services
pw_mapper configuration file shows like:mapper pw { debug = true; ignorecase = false; module = /usr/lib/pam_pkcs11/pw_mapper.so; } |
Uses an ldap server to retrieve user name. An aditional file tells module the mapping between Cert fields and LDAP entries
This mapper is still under development
Search certificate in ${HOME}/.eid/autorized_certificates in a similar way as OpenSC does. When used as login finder, returns the user that owns ${HOME} directory where certificate is found
This mapper is still under development
Search certificate public key in ${HOME}/.ssh/autorized_keys in a similar way as OpenSSH does. When used as login finder, returns the user that owns ${HOME} directory where key is found
This mapper is still under development
Email mapper tries to extract an e-mail from certificate. If found does following procedures:
Once we have a mapped user, module does:
Additionaly you can set ignorecase or ignoredomain flags:
Domain check (if set) is done by testing if provided email domain part ( @ie.this.domain ) matches host domain.
Eg user@my.company.com email in host host.in.my.company.com host matches domain
Configuration file entry looks like:
mapper mail { debug = false; module = /usr/lib/pam_pkcs11/mail_mapper.so; # MapFile to use mapfile = file:///etc/pkcs11/mail_mapping; # Some certs store email in uppercase. Take care on this ignorecase = true; # Also check that host matches mx domain ignoredomain = false; } |
Try to find and use Microsoft Universal Principal Name (UPN) extension to evaluate login name
Microsoft Universal Principal Name is a ASN1-encoded UTF8 string with the syntax login@ADS_Domain. When an UPN is found, the mapper extract login part as login user. Then, if ignoredomain is unset, try to match domain.
Configuration file entry looks like:
mapper ms { debug = false; module = /usr/lib/pam_pkcs11/ms_mapper.so; ignorecase = false; ignoredomain = false; domainname = "domain.com"; } |
Try to find and use Kerberos Principal Name as login name. if mapfile is specified, maps KPN into a login
NOTES:
This mapper does not perform PKINIT kerberos authentication, just retrieve and use KPN to map login name. ( PKINIT auth is still a work in progress)
Configuration entry:
mapper krb { debug = false; module = /usr/lib/pam_pkcs11/krb_mapper.so; ignorecase = false; mapfile = "none"; } |
Use Unique ID (UID) field as login name
Similar to CN mapper, but using UID as field to find/match
Configuration entry:
mapper uid { debug = false; module = /usr/lib/pam_pkcs11/uid_mapper.so; ignorecase = false; mapfile = "none"; } |
Evaluates a certificate digest, and try to map result into a login by using a mapfile
Configuration file should provide the digest algorithm. Depending on OpenSSL configuration all of listed bellow may or not be present in your system
Configuration entry:
mapper digest { debug = false; module = /usr/lib/pam_pkcs11/digest_mapper.so; # Algorithm used to evaluate certificate digest # Select one of: # "null","md2","md4","md5","sha","sha1","dss","dss1","ripemd160" algorithm = "sha1"; mapfile = file:///etc/pkcs11/digest_map; } |
Blind access/deny mapper.
If default_match is set to true:
If default_match is set to false:
Configuration entry:
mapper null { debug = false; module = /usr/lib/pam_pkcs11/null_mapper.so; # select behaviour: allways match, or allways fail default_match = false; # on match, select returned user default_user = nobody; } |
Creating new mappers is easy: just study mapper.h file, provide a file that exports required functions, and modify file src/mappers/Makefile.am
Mapper.h provides default implementation for required exports. They should be overriden by user code, but can be used for testing purposes
You can start by using provided src/mappers/generic_mapper.c skeleton file. Just rename, edit, set Makefile.am properly, and recompile