Blame doc/specs/draft-morgan-pam.raw

Packit 7e982e
Open-PAM working group            ##              A.G. Morgan
Packit 7e982e
Internet Draft:                   ##              Dec 8, 2001
Packit 7e982e
Document: draft-morgan-pam-08.txt ##
Packit 7e982e
Expires: June 8, 2002             ##
Packit 7e982e
Obsoletes: draft-morgan-pam-07.txt##
Packit 7e982e
Packit 7e982e
## Pluggable Authentication Modules (PAM) ##
Packit 7e982e
Packit 7e982e
#$  Status of this memo
Packit 7e982e
Packit 7e982e
This document is a draft specification. Its contents are subject to
Packit 7e982e
change with revision. The latest version of this draft may be obtained
Packit 7e982e
from here:
Packit 7e982e
Packit 7e982e
  http://www.kernel.org/pub/linux/libs/pam/pre/doc/
Packit 7e982e
Packit 7e982e
As
Packit 7e982e
Packit 7e982e
  Linux-PAM-'version'-docs.tar.gz
Packit 7e982e
Packit 7e982e
It is also contained in the Linux-PAM tar ball.
Packit 7e982e
Packit 7e982e
#$  Abstract
Packit 7e982e
Packit 7e982e
This document is concerned with the definition of a general
Packit 7e982e
infrastructure for module based authentication.  The infrastructure is
Packit 7e982e
named Pluggable Authentication Modules (PAM for short).
Packit 7e982e
Packit 7e982e
#$  Introduction
Packit 7e982e
Packit 7e982e
Computers are tools.  They provide services to people and other
Packit 7e982e
computers (collectively we shall call these _users_ entities).  In
Packit 7e982e
order to provide convenient, reliable and individual service to
Packit 7e982e
different entities, it is common for entities to be labelled.  Having
Packit 7e982e
defined a label as referring to a some specific entity, the label is
Packit 7e982e
used for the purpose of protecting and allocating data resources.
Packit 7e982e
Packit 7e982e
All modern operating systems have a notion of labelled entities and
Packit 7e982e
all modern operating systems face a common problem: how to
Packit 7e982e
authenticate the association of a predefined label with applicant
Packit 7e982e
entities.
Packit 7e982e
Packit 7e982e
There are as many authentication methods as one might care to count.
Packit 7e982e
None of them are perfect and none of them are invulnerable.  In
Packit 7e982e
general, any given authentication method becomes weaker over time.  It
Packit 7e982e
is common then for new authentication methods to be developed in
Packit 7e982e
response to newly discovered weaknesses in the old authentication
Packit 7e982e
methods.
Packit 7e982e
Packit 7e982e
The problem with inventing new authentication methods is the fact that
Packit 7e982e
old applications do not support them.  This contributes to an inertia
Packit 7e982e
that discourages the overhaul of weakly protected systems.  Another
Packit 7e982e
problem is that individuals (people) are frequently powerless to layer
Packit 7e982e
the protective authentication around their systems.  They are forced
Packit 7e982e
to rely on single (lowest common denominator) authentication schemes
Packit 7e982e
even in situations where this is far from appropriate.
Packit 7e982e
Packit 7e982e
PAM, as discussed in this document, is a generalization of the
Packit 7e982e
approach first introduced in [#$R#{OSF_RFC_PAM}].  In short, it is a
Packit 7e982e
general framework of interfaces that abstract the process of
Packit 7e982e
authentication.  With PAM, a service provider can custom protect
Packit 7e982e
individual services to the level that they deem is appropriate.
Packit 7e982e
Packit 7e982e
PAM has nothing explicit to say about transport layer encryption.
Packit 7e982e
Within the context of this document encryption and/or compression of
Packit 7e982e
data exchanges are application specific (strictly between client and
Packit 7e982e
server) and orthogonal to the process of authentication.
Packit 7e982e
Packit 7e982e
#$  Definitions
Packit 7e982e
Packit 7e982e
Here we pose the authentication problem as one of configuring defined
Packit 7e982e
interfaces between two entities.
Packit 7e982e
Packit 7e982e
#$$#{players}  Players in the authentication process
Packit 7e982e
Packit 7e982e
PAM reserves the following words to specify unique entities in the
Packit 7e982e
authentication process:
Packit 7e982e
Packit 7e982e
  applicant
Packit 7e982e
	the entity (user) initiating an application for service
Packit 7e982e
	[PAM associates the PAM_RUSER _item_ with this requesting user].
Packit 7e982e
Packit 7e982e
  arbitrator
Packit 7e982e
	the entity (user) under whose identity the service application
Packit 7e982e
	is negotiated and with whose authority service is granted.
Packit 7e982e
Packit 7e982e
  user
Packit 7e982e
	the entity (user) whose identity is being authenticated
Packit 7e982e
	[PAM associates the PAM_USER _item_ with this identity].
Packit 7e982e
Packit 7e982e
  server
Packit 7e982e
	the application that provides service, or acts as an
Packit 7e982e
	authenticated gateway to the requested service.  This
Packit 7e982e
	application is completely responsible for the server end of
Packit 7e982e
	the transport layer connecting the server to the client.
Packit 7e982e
	PAM makes no assumptions about how data is encapsulated for
Packit 7e982e
	exchanges between the server and the client, only that full
Packit 7e982e
	octet sequences can be freely exchanged without corruption.
Packit 7e982e
Packit 7e982e
  client
Packit 7e982e
	application providing the direct/primary interface to
Packit 7e982e
	applicant.  This application is completely responsible
Packit 7e982e
	for the client end of the transport layer connecting the
Packit 7e982e
	server to the client.  PAM makes no assumptions about how data
Packit 7e982e
	is encapsulated for exchanges between the server and the
Packit 7e982e
	client, only that full octet sequences can be freely
Packit 7e982e
	exchanged without corruption.
Packit 7e982e
Packit 7e982e
  module
Packit 7e982e
	authentication binary that provides server-side support for
Packit 7e982e
	some (arbitrary) authentication method.
Packit 7e982e
Packit 7e982e
  agent
Packit 7e982e
	authentication binary that provides client-side support for
Packit 7e982e
	some (arbitrary) authentication method.
Packit 7e982e
Packit 7e982e
Here is a diagram to help orient the reader:
Packit 7e982e
Packit 7e982e
##               +-------+              +--------+ ##
Packit 7e982e
##      . . . . .| agent |             .| module | ##
Packit 7e982e
##      .        +-------+             .+--------+ ##
Packit 7e982e
##      V            |                 .    |      ##
Packit 7e982e
##      .            |                 V    |      ##
Packit 7e982e
## +---------+   +-------+             . +------+  ##
Packit 7e982e
## |         |   |libpamc|             . |libpam|  ##
Packit 7e982e
## |         |   +-------+             . +------+  ##
Packit 7e982e
## |applicant|       |                 .    |      ##
Packit 7e982e
## |         |   +--------+           +----------+ ##
Packit 7e982e
## |         |---| client |-----------|  server  | ##
Packit 7e982e
## +---------+   +--------+           +----------+ ##
Packit 7e982e
Packit 7e982e
Solid lines connecting the boxes represent two-way interaction.  The
Packit 7e982e
dotted-directed lines indicate an optional connection beteween the
Packit 7e982e
plugin module (agent) and the server (applicant). In the case of the
Packit 7e982e
module, this represents the module invoking the 'conversation'
Packit 7e982e
callback function provided to libpam by the server application when it
Packit 7e982e
inititializes the libpam library. In the case of the agent, this may
Packit 7e982e
be some out-of-PAM API interaction (for example directly displaying a
Packit 7e982e
dialog box under X).
Packit 7e982e
Packit 7e982e
#$$  Defined Data Types
Packit 7e982e
Packit 7e982e
In this draft, we define two composite data types, the text string and
Packit 7e982e
the binary prompt. They are the data types used to communicate
Packit 7e982e
authentication requests and responses.
Packit 7e982e
Packit 7e982e
#$$$#{text_string}  text string
Packit 7e982e
Packit 7e982e
The text string is a simple sequence of non-NUL (NUL = 0x00)
Packit 7e982e
octets. Terminated with a single NUL (0x00) octet. The character set
Packit 7e982e
employed in the octet sequence may be negotiated out of band, but
Packit 7e982e
defaults to utf-8.
Packit 7e982e
Packit 7e982e
## --------------------------- ##
Packit 7e982e
## [  character data  |  NUL ] ##
Packit 7e982e
## [  octet sequence  | 0x00 ] ##
Packit 7e982e
## --------------------------- ##
Packit 7e982e
Packit 7e982e
Within the rest of this text, PAM text strings are delimited with a
Packit 7e982e
pair of double quotes. Example, "this" = {'t';'h';'i';'s';0x00}.
Packit 7e982e
Packit 7e982e
#$$$#{binary_prompt}  binary prompt
Packit 7e982e
Packit 7e982e
A binary prompt consists of a stream of octets arranged as follows:
Packit 7e982e
Packit 7e982e
## ---------------------------------------- ##
Packit 7e982e
## [  u32   |   u8    | (length-5 octets) ] ##
Packit 7e982e
## [ length | control |       data        ] ##
Packit 7e982e
## ---------------------------------------- ##
Packit 7e982e
Packit 7e982e
That is, a 32-bit unsigned integer in network byte order, a single
Packit 7e982e
unsigned byte of control information and a sequence of octets of
Packit 7e982e
length (length-5). The composition of the _data_ is context dependent
Packit 7e982e
but is generally not a concern for either the server or the client. It
Packit 7e982e
is very much the concern of modules and agents.
Packit 7e982e
Packit 7e982e
For purposes of interoperability, we define the following control
Packit 7e982e
characters as legal.
Packit 7e982e
Packit 7e982e
## value    symbol             description           ##
Packit 7e982e
## ------------------------------------------------- ##
Packit 7e982e
## 0x01     PAM_BPC_OK       - continuation packet   ##
Packit 7e982e
## 0x02     PAM_BPC_SELECT   - initialization packet ##
Packit 7e982e
## 0x03     PAM_BPC_DONE     - termination packet    ##
Packit 7e982e
## 0x04     PAM_BPC_FAIL     - unable to execute     ##
Packit 7e982e
Packit 7e982e
The following control characters are only legal for exchanges between
Packit 7e982e
an agent and a client (it is the responsibility of the client to
Packit 7e982e
enforce this rule in the face of a rogue server):
Packit 7e982e
Packit 7e982e
## 0x41     PAM_BPC_GETENV   - obtain client env.var  ##
Packit 7e982e
## 0x42     PAM_BPC_PUTENV   - set client env.var     ##
Packit 7e982e
## 0x43     PAM_BPC_TEXT     - display message        ##
Packit 7e982e
## 0x44     PAM_BPC_ERROR    - display error message  ##
Packit 7e982e
## 0x45     PAM_BPC_PROMPT   - echo'd text prompt     ##
Packit 7e982e
## 0x46     PAM_BPC_PASS     - non-echo'd text prompt ##
Packit 7e982e
## 0x46     PAM_BPC_STATUS   - ping all active clients##
Packit 7e982e
## 0x47     PAM_BPC_ABORT    - please abort session   ##
Packit 7e982e
Packit 7e982e
Note, length is always equal to the total length of the binary
Packit 7e982e
prompt and represented by a network ordered unsigned 32 bit integer.
Packit 7e982e
Packit 7e982e
#$$$$#{agent_ids} PAM_BPC_SELECT binary prompts
Packit 7e982e
Packit 7e982e
Binary prompts of control type PAM_BPC_SELECT have a defined
Packit 7e982e
data part. It is composed of three elements:
Packit 7e982e
Packit 7e982e
	{agent_id;'/';data}
Packit 7e982e
Packit 7e982e
The agent_id is a sequence of characters satisfying the following
Packit 7e982e
regexp:
Packit 7e982e
Packit 7e982e
	/^[a-z0-9\_]+(@[a-z0-9\_.]+)?$/
Packit 7e982e
Packit 7e982e
and has a specific form for each independent agent.
Packit 7e982e
Packit 7e982e
o Agent_ids that do not contain an at-sign (@) are to be considered as
Packit 7e982e
  representing some authentication mode that is a "public
Packit 7e982e
  standard" see reference [#$R#{PAM_STD_AGENTIDS}]. Registered names
Packit 7e982e
  MUST NOT contain an at-sign (@).
Packit 7e982e
Packit 7e982e
o Anyone can define additional agents by using names in the format
Packit 7e982e
  name@domainname, e.g. "ouragent@example.com". The part following
Packit 7e982e
  the at-sign MUST be a valid fully qualified internet domain name
Packit 7e982e
  [RFC-1034] controlled by the person or organization defining the
Packit 7e982e
  name. (Said another way, if you control the email address that
Packit 7e982e
  your agent has as an identifier, they you are entitled to use
Packit 7e982e
  this identifier.) It is up to each domain how it manages its local
Packit 7e982e
  namespace.
Packit 7e982e
Packit 7e982e
The '/' character is a mandatory delimiter, indicating the end of the
Packit 7e982e
agent_id. The trailing data is of a format specific to the agent with
Packit 7e982e
the given agent_id.
Packit 7e982e
Packit 7e982e
Packit 7e982e
#$$  Special cases
Packit 7e982e
Packit 7e982e
In a previous section (#{players}) we identified the most general
Packit 7e982e
selection of authentication participants.  In the case of network
Packit 7e982e
authentication, it is straightforward to ascribe identities to the
Packit 7e982e
defined participants.  However, there are also special (less general)
Packit 7e982e
cases that we recognize here.
Packit 7e982e
Packit 7e982e
The primary authentication step, when a user is directly introduced
Packit 7e982e
into a computer system (log's on to a workstation) is a special case.
Packit 7e982e
In this situation, the client and the server are generally one
Packit 7e982e
application.  Before authenticating such a user, the applicant is
Packit 7e982e
formally unknown: PAM_RUSER is NULL.
Packit 7e982e
Packit 7e982e
Some client-server implementations (telnet for example) provide
Packit 7e982e
effective full tty connections. In these cases, the four simple text
Packit 7e982e
string prompting cases (see below) can be handled as in the primary
Packit 7e982e
login step. In other words, the server absorbs most of the overhead of
Packit 7e982e
propagating authentication messages. In these cases, there needs to be
Packit 7e982e
special client/server support for handling binary prompts.
Packit 7e982e
Packit 7e982e
In some circumstances, a legacy network transfer protocol can carry
Packit 7e982e
authentication information. In such cases, a desire to support legacy
Packit 7e982e
clients (with no client-side support for PAM) will neccessitate the
Packit 7e982e
'hardcoding' of an agent protocol into the server application. Whilst
Packit 7e982e
against the spirit of PAM, this special casing can be managed by the
Packit 7e982e
server's 'conversation function' (see below). The guiding principle
Packit 7e982e
when implementing such support is for the application developer to
Packit 7e982e
relegate the authentication process to the PAM module -- simply
Packit 7e982e
performing a transcription of data from binary-prompt to legacy
Packit 7e982e
network 'packet' and visa-versa for propagating replies back to the
Packit 7e982e
driving PAM module. A common case of this is with network protocols
Packit 7e982e
that define an initialization packet of "user+password". In such cases
Packit 7e982e
one should attempt to support the "userpass" agent-id and its defined
Packit 7e982e
protocol.
Packit 7e982e
Packit 7e982e
#$  Defined interfaces for information flow
Packit 7e982e
Packit 7e982e
Here, we discuss the information exchange interfaces between the
Packit 7e982e
players in the authentication process. It should be understood that
Packit 7e982e
the server side is responsible for driving the authentication of the
Packit 7e982e
applicant. Notably, every request received by the client from the
Packit 7e982e
server must be matched with a single response from the client to the
Packit 7e982e
server.
Packit 7e982e
Packit 7e982e
#$$#{applicant_client}  Applicant <-> client
Packit 7e982e
Packit 7e982e
Once the client is invoked, requests to the applicant entity are
Packit 7e982e
initiated by the client application.  General clients are able to make
Packit 7e982e
the following requests directly to an applicant:
Packit 7e982e
Packit 7e982e
   echo text string
Packit 7e982e
   echo error text string
Packit 7e982e
   prompt with text string for echo'd text string input
Packit 7e982e
   prompt with text string for concealed text string input
Packit 7e982e
Packit 7e982e
the nature of the interface provided by the client for the benefit of
Packit 7e982e
the applicant entity is client specific and not defined by PAM.
Packit 7e982e
Packit 7e982e
#$$#{client_agent}  Client <-> agent
Packit 7e982e
Packit 7e982e
In general, authentication schemes require more modes of exchange than
Packit 7e982e
the four defined in the previous section (#{applicant_client}).  This
Packit 7e982e
provides a role for client-loadable agents.  The client and agent
Packit 7e982e
exchange binary-messages that can have one of the following forms:
Packit 7e982e
Packit 7e982e
   client -> agent
Packit 7e982e
	binary prompt agent expecting binary prompt reply to client
Packit 7e982e
Packit 7e982e
   agent -> client
Packit 7e982e
	binary prompt reply from agent to clients binary prompt
Packit 7e982e
Packit 7e982e
Following the acceptance of a binary prompt by the agent, the agent
Packit 7e982e
may attempt to exchange information with the client before returning
Packit 7e982e
its binary prompt reply. Permitted exchanges are binary prompts of the
Packit 7e982e
following types:
Packit 7e982e
Packit 7e982e
   agent -> client
Packit 7e982e
	set environment variable (A)
Packit 7e982e
	get environment variable (B)
Packit 7e982e
	echo text string (C)
Packit 7e982e
	echo error text string (D)
Packit 7e982e
	prompt for echo'd text string input (E)
Packit 7e982e
	prompt for concealed text string input (F)
Packit 7e982e
Packit 7e982e
In response to these prompts, the client must legitimately respond
Packit 7e982e
with a corresponding binary prompt reply. We list a complete set of
Packit 7e982e
example exchanges, including each type of legitimate response (passes
Packit 7e982e
and a single fail):
Packit 7e982e
Packit 7e982e
## Type | Agent request                  | Client response         ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (A)  | {13;PAM_BPC_PUTENV;"FOO=BAR"}  | {5;PAM_BPC_OK;}         ##
Packit 7e982e
##      | {10;PAM_BPC_PUTENV;"FOO="}     | {5;PAM_BPC_OK;}         ##
Packit 7e982e
##      | {9;PAM_BPC_PUTENV;"FOO"}  (*)  | {5;PAM_BPC_OK;}         ##
Packit 7e982e
##      | {9;PAM_BPC_PUTENV;"BAR"}  (*)  | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (B)  | {10;PAM_BPC_GETENV;"TERM"}     | {11;PAM_BPC_OK;"vt100"} ##
Packit 7e982e
##      | {9;PAM_BPC_GETENV;"FOO"}       | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (C)  | {12;PAM_BPC_TEXT;"hello!"}     | {5;PAM_BPC_OK;}         ##
Packit 7e982e
##      | {12;PAM_BPC_TEXT;"hello!"}     | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (D)  | {11;PAM_BPC_ERROR;"ouch!"}     | {5;PAM_BPC_OK;}         ##
Packit 7e982e
##      | {11;PAM_BPC_ERROR;"ouch!"}     | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (E)  | {13;PAM_BPC_PROMPT;"login: "}  | {9;PAM_BPC_OK;"joe"}    ##
Packit 7e982e
##      | {13;PAM_BPC_PROMPT;"login: "}  | {6;PAM_BPC_OK;""}       ##
Packit 7e982e
##      | {13;PAM_BPC_PROMPT;"login: "}  | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
## --------------------------------------------------------------- ##
Packit 7e982e
## (F)  | {16;PAM_BPC_PASS;"password: "} | {9;PAM_BPC_OK;"XYZ"}    ##
Packit 7e982e
##      | {16;PAM_BPC_PASS;"password: "} | {6;PAM_BPC_OK;""}       ##
Packit 7e982e
##      | {16;PAM_BPC_PASS;"password: "} | {5;PAM_BPC_FAIL;}       ##
Packit 7e982e
Packit 7e982e
(*) Used to attempt the removal of a pre-existing environment
Packit 7e982e
variable.
Packit 7e982e
Packit 7e982e
#$$  Client <-> server
Packit 7e982e
Packit 7e982e
Once the client has established a connection with the server (the
Packit 7e982e
nature of the transport protocol is not specified by PAM), the server
Packit 7e982e
is responsible for driving the authentication process.
Packit 7e982e
Packit 7e982e
General servers can request the following from the client:
Packit 7e982e
Packit 7e982e
   (to be forwarded by the client to the applicant)
Packit 7e982e
	echo text string
Packit 7e982e
	echo error text string
Packit 7e982e
	prompt for echo'd text string response
Packit 7e982e
	prompt for concealed text string response
Packit 7e982e
Packit 7e982e
   (to be forwarded by the client to the appropriate agent)
Packit 7e982e
	binary prompt for a binary prompt response
Packit 7e982e
Packit 7e982e
Client side agents are required to process binary prompts.  The
Packit 7e982e
agents' binary prompt responses are returned to the server.
Packit 7e982e
Packit 7e982e
#$$  Server <-> module
Packit 7e982e
Packit 7e982e
Modules drive the authentication process.  The server provides a
Packit 7e982e
conversation function with which it encapsulates module-generated
Packit 7e982e
requests and exchanges them with the client. Every message sent by a
Packit 7e982e
module should be acknowledged.
Packit 7e982e
Packit 7e982e
General conversation functions can support the following five
Packit 7e982e
conversation requests:
Packit 7e982e
Packit 7e982e
   echo text string
Packit 7e982e
   echo error string
Packit 7e982e
   prompt for echo'd text string response
Packit 7e982e
   prompt for concealed text string response
Packit 7e982e
   binary prompt for binary prompt response
Packit 7e982e
Packit 7e982e
The server is responsible for redirecting these requests to the
Packit 7e982e
client.
Packit 7e982e
Packit 7e982e
#$  C API for application interfaces (client and server)
Packit 7e982e
Packit 7e982e
#$$  Applicant <-> client
Packit 7e982e
Packit 7e982e
No API is defined for this interface.  The interface is considered to
Packit 7e982e
be specific to the client application.  Example applications include
Packit 7e982e
terminal login, (X)windows login, machine file transfer applications.
Packit 7e982e
Packit 7e982e
All that is important is that the client application is able to
Packit 7e982e
present the applicant with textual output and to receive textual
Packit 7e982e
input from the applicant.  The forms of textual exchange are listed
Packit 7e982e
in an earlier section (#{applicant_client}).  Other methods of
Packit 7e982e
data input/output are better suited to being handled via an
Packit 7e982e
authentication agent.
Packit 7e982e
Packit 7e982e
#$$  Client <-> agent
Packit 7e982e
Packit 7e982e
The client makes use of a general API for communicating with
Packit 7e982e
agents. The client is not required to communicate directly with
Packit 7e982e
available agents, instead a layer of abstraction (in the form of a
Packit 7e982e
library: libpamc) takes care of loading and maintaining communication
Packit 7e982e
with all requested agents. This layer of abstraction will choose which
Packit 7e982e
agents to interact with based on the content of binary prompts it
Packit 7e982e
receives that have the control type PAM_BPC_SELECT.
Packit 7e982e
Packit 7e982e
#$$$  Client <-> libpamc
Packit 7e982e
Packit 7e982e
#$$$$  Compilation information
Packit 7e982e
Packit 7e982e
The C-header file provided for client-agent abstraction is included
Packit 7e982e
with the following source line:
Packit 7e982e
Packit 7e982e
	\#include <security/pam_client.h>
Packit 7e982e
Packit 7e982e
The library providing the corresponding client-agent abstraction
Packit 7e982e
functions is, libpamc.
Packit 7e982e
Packit 7e982e
	cc .... -lpamc
Packit 7e982e
Packit 7e982e
#$$$$  Initializing libpamc
Packit 7e982e
Packit 7e982e
The libpamc library is initialized with a call to the following
Packit 7e982e
function:
Packit 7e982e
Packit 7e982e
	pamc_handle_t pamc_start(void);
Packit 7e982e
Packit 7e982e
This function is responsible for configuring the library and
Packit 7e982e
registering the location of available agents. The location of the
Packit 7e982e
available agents on the system is implementation specific.
Packit 7e982e
Packit 7e982e
pamc_start() function returns NULL on failure. Otherwise, the return
Packit 7e982e
value is a pointer to an opaque data type which provides a handle to
Packit 7e982e
the libpamc library. On systems where threading is available, the
Packit 7e982e
libpamc libraray is thread safe provided a single (pamc_handler_t *)
Packit 7e982e
is used by each thread.
Packit 7e982e
Packit 7e982e
#$$$$  Client (Applicant) selection of agents
Packit 7e982e
Packit 7e982e
For the purpose of applicant and client review of available agents,
Packit 7e982e
the following function is provided.
Packit 7e982e
Packit 7e982e
	char **pamc_list_agents(pamc_handle_t pch);
Packit 7e982e
Packit 7e982e
This returns a list of pointers to the agent_id's of the agents which
Packit 7e982e
are available on the system. The list is terminated by a NULL pointer.
Packit 7e982e
It is the clients responsibility to free this memory area by calling
Packit 7e982e
free() on each agent id and the block of agent_id pointers in the
Packit 7e982e
result.
Packit 7e982e
Packit 7e982e
PAM represents a server-driven authentication model, so by default
Packit 7e982e
any available agent may be invoked in the authentication process.
Packit 7e982e
Packit 7e982e
#$$$$$  Client demands agent
Packit 7e982e
Packit 7e982e
If the client requires that a specific authentication agent is
Packit 7e982e
satisfied during the authentication process, then the client should
Packit 7e982e
call the following function, immediately after obtaining a
Packit 7e982e
pamc_handle_t from pamc_start().
Packit 7e982e
Packit 7e982e
	int pamc_load(pamc_handle_t pch, const char *agent_id);
Packit 7e982e
Packit 7e982e
agent_id is a PAM text string (see section #{agent_ids}) and is not
Packit 7e982e
suffixed with a '/' delimiter. The return value for this function is:
Packit 7e982e
Packit 7e982e
	PAM_BPC_TRUE    - agent located and loaded.
Packit 7e982e
	PAM_BPC_FALSE   - agent is not available.
Packit 7e982e
Packit 7e982e
Note, although the agent is loaded, no data is fed to it. The agent's
Packit 7e982e
opportunity to inform the client that it does not trust the server is
Packit 7e982e
when the agent is shutdown.
Packit 7e982e
Packit 7e982e
#$$$$$  Client marks agent as unusable
Packit 7e982e
Packit 7e982e
The applicant might prefer that a named agent is marked as not
Packit 7e982e
available.  To do this, the client would invoke the following function
Packit 7e982e
immediately after obtaining a pamc_handle_t from pam_start().
Packit 7e982e
Packit 7e982e
	int pamc_disable(pamc_handle_t pch, const char *agent_id);
Packit 7e982e
Packit 7e982e
here agent_id is a PAM text string containing an agent_id (section
Packit 7e982e
#{agent_ids}).
Packit 7e982e
Packit 7e982e
The return value for this function is:
Packit 7e982e
Packit 7e982e
	PAM_BPC_TRUE    - agent is disabled. This is the response
Packit 7e982e
	                  independent of whether the agent is locally
Packit 7e982e
	                  available.
Packit 7e982e
Packit 7e982e
	PAM_BPC_FALSE   - agent cannot be disabled (this may be because
Packit 7e982e
	                  it has already been invoked).
Packit 7e982e
Packit 7e982e
#$$$$  Allocating and manipulating binary prompts
Packit 7e982e
Packit 7e982e
All conversation between an client and an agent takes place with
Packit 7e982e
respect to binary prompts. A binary prompt (see section #{binary_prompt}), is
Packit 7e982e
obtained, resized and deleted via the following C-macro:
Packit 7e982e
Packit 7e982e
 CREATION of a binary prompt with control X1 and data length Y1:
Packit 7e982e
Packit 7e982e
	pamc_bp_t prompt = NULL;
Packit 7e982e
	PAM_BP_RENEW(&prompt, X1, Y1);
Packit 7e982e
Packit 7e982e
 REPLACEMENT of a binary prompt with a control X2 and data length Y2:
Packit 7e982e
Packit 7e982e
	PAM_BP_RENEW(&prompt, X2, Y2);
Packit 7e982e
Packit 7e982e
 DELETION of a binary prompt (the referenced prompt is scrubbed):
Packit 7e982e
Packit 7e982e
	PAM_BP_RENEW(&prompt, 0, 0);
Packit 7e982e
Packit 7e982e
Note, the PAM_BP_RENEW macro always overwrites any prompt that you
Packit 7e982e
call it with, deleting and liberating the old contents in a secure
Packit 7e982e
fashion. Also note that PAM_BP_RENEW, when returning a prompt of data
Packit 7e982e
size Y1>0, will always append a '\0' byte to the end of the prompt (at
Packit 7e982e
data offset Y1). It is thus, by definition, acceptable to treat the
Packit 7e982e
data contents of a binary packet as a text string (see #{text_string}).
Packit 7e982e
Packit 7e982e
 FILLING a binary prompt from a memory pointer U1 from offset O1 of
Packit 7e982e
   length L1:
Packit 7e982e
Packit 7e982e
	PAM_BP_FILL(prompt, O1, L1, U1);
Packit 7e982e
Packit 7e982e
 the CONTROL type for the packet can be obtained as follows:
Packit 7e982e
Packit 7e982e
	control = PAM_PB_CONTROL(prompt);
Packit 7e982e
Packit 7e982e
 the LENGTH of a data within the prompt (_excluding_ its header
Packit 7e982e
 information) can be obtained as follows:
Packit 7e982e
Packit 7e982e
	length = PAM_BP_LENGTH(prompt);
Packit 7e982e
Packit 7e982e
 the total SIZE of the prompt (_including_ its header information)
Packit 7e982e
 can be obtained as follows:
Packit 7e982e
Packit 7e982e
        size = PAM_BP_SIZE(prompt);
Packit 7e982e
Packit 7e982e
 EXTRACTING data from a binary prompt from offset O2 of length L2 to
Packit 7e982e
   a memory pointer U2:
Packit 7e982e
Packit 7e982e
	PAM_BP_EXTRACT(prompt, O2, L2, U2);
Packit 7e982e
Packit 7e982e
 If you require direct access to the raw prompt DATA, you should use
Packit 7e982e
 the following macro:
Packit 7e982e
Packit 7e982e
	__u8 *raw_data = PAM_BP_DATA(prompt);
Packit 7e982e
Packit 7e982e
#$$$$  Client<->agent conversations
Packit 7e982e
Packit 7e982e
All exchanges of binary prompts with agents are handled with the
Packit 7e982e
single function:
Packit 7e982e
Packit 7e982e
	int pamc_converse(pamc_handle_t *pch, pamc_bp_t *prompt_p);
Packit 7e982e
Packit 7e982e
The return value for pamc_converse(...) is PAM_BPC_TRUE when there is
Packit 7e982e
a response packet and PAM_BPC_FALSE when the client is unable to
Packit 7e982e
handle the request represented by the original prompt. In this latter
Packit 7e982e
case, *prompt_p is set to NULL.
Packit 7e982e
Packit 7e982e
This function takes a binary prompt and returns a replacement binary
Packit 7e982e
prompt that is either a request from an agent to be acted upon by the
Packit 7e982e
client or the 'result' which should be forwarded to the server. In the
Packit 7e982e
former case, the following macro will return 1 (PAM_BPC_TRUE) and in
Packit 7e982e
all other cases, 0 (PAM_BPC_FALSE):
Packit 7e982e
Packit 7e982e
	PAM_BPC_FOR_CLIENT(/* pamc_bp_t */ prompt)
Packit 7e982e
Packit 7e982e
Note, all non-NULL binary prompts returned by pamc_converse(...), are
Packit 7e982e
terminated with a '\0', even when the full length of the prompt (as
Packit 7e982e
returned by the agent) does not contain this delimiter. This is a
Packit 7e982e
defined property of the PAM_BP_RENEW macro, and can be relied upon.
Packit 7e982e
Packit 7e982e
Important security note: in certain implementations, agents are
Packit 7e982e
implemented by executable binaries, which are transparently loaded and
Packit 7e982e
managed by the PAM client library. To ensure there is never a leakage
Packit 7e982e
of elevated privilege to an unprivileged agent, the client application
Packit 7e982e
should go to some effort to lower its level of privilege. It remains
Packit 7e982e
the responsibility of the applicant and the client to ensure that it
Packit 7e982e
is not compromised by a rogue agent.
Packit 7e982e
Packit 7e982e
#$$$$  Status of agents
Packit 7e982e
Packit 7e982e
	int pamc_status(pamc_handle_t *pch, pamc_bp_t *prompt_p);
Packit 7e982e
Packit 7e982e
At any time, the client may ping all active agents for their status
Packit 7e982e
(with a PAM_BPC_STATUS binary prompt). If any agent replies with
Packit 7e982e
PAM_BPC_ABORT, the client is responsible for terminating the
Packit 7e982e
connection to the server and then terminating all agents with a call
Packit 7e982e
to pamc_end(). In such cases, the return value of pamc_status() is
Packit 7e982e
PAM_BPC_FALSE.
Packit 7e982e
Packit 7e982e
If the return status of pamc_status() is PAM_BPC_TRUE and *prompt_p is
Packit 7e982e
non-NULL, then an agent is requesting access to a server module.
Packit 7e982e
Packit 7e982e
XXX - how this information gets propagated to the server, and
Packit 7e982e
      ultimately to the server's module is yet to be determined.
Packit 7e982e
Packit 7e982e
#$$$$  Termination of agents
Packit 7e982e
Packit 7e982e
When closing the authentication session and severing the connection
Packit 7e982e
between a client and a selection of agents, the following function is
Packit 7e982e
used:
Packit 7e982e
Packit 7e982e
	int pamc_end(pamc_handle_t *pch);
Packit 7e982e
Packit 7e982e
Following a call to pamc_end, the pamc_handle_t will be invalid.
Packit 7e982e
Packit 7e982e
The return value for this function is one of the following:
Packit 7e982e
Packit 7e982e
	PAM_BPC_TRUE	- all invoked agents are content with
Packit 7e982e
			  authentication (the server is _not_ judged
Packit 7e982e
			  _un_trustworthy by any agent)
Packit 7e982e
Packit 7e982e
	PAM_BPC_FALSE	- one or more agents were unsatisfied at
Packit 7e982e
			  being terminated.  In general, the client
Packit 7e982e
			  should terminate its connection to the
Packit 7e982e
			  server and indicate to the applicant that
Packit 7e982e
			  the server is untrusted.
Packit 7e982e
Packit 7e982e
#$$$ libpamc <-> agents
Packit 7e982e
Packit 7e982e
The agents are manipulated from within libpamc. Each agent is an
Packit 7e982e
executable in its own right. This permits the agent to have access to
Packit 7e982e
sensitive data not accessible directly from the client. The mode of
Packit 7e982e
communication between libpamc and an agent is through a pair of
Packit 7e982e
pipes. The agent reads binary prompts (section #{binary_prompt})
Packit 7e982e
through its standard input file descriptor and writes response (to the
Packit 7e982e
server) binary prompts and instruction binary prompts (instructions
Packit 7e982e
for the client) through its standard output file descriptor.
Packit 7e982e
Packit 7e982e
#$$ Client <-> server
Packit 7e982e
Packit 7e982e
This interface is concerned with the exchange of text and binary
Packit 7e982e
prompts between the client application and the server application.  No
Packit 7e982e
API is provided for this as it is considered specific to the transport
Packit 7e982e
protocol shared by the client and the server.
Packit 7e982e
Packit 7e982e
#$$ Server <-> modules
Packit 7e982e
Packit 7e982e
The server makes use of a general API for communicating with
Packit 7e982e
modules. The client is not required to communicate directly with
Packit 7e982e
available modules. By abstracting the authentication interface, it
Packit 7e982e
becomes possible for the local administrator to make a run time
Packit 7e982e
decision about the authentication method adopted by the server.
Packit 7e982e
Packit 7e982e
#$$$ Functions and definitions available to servers and modules
Packit 7e982e
Packit 7e982e
[This section will document the following functions
Packit 7e982e
Packit 7e982e
	pam_set_item()
Packit 7e982e
	pam_get_item()
Packit 7e982e
	pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec)
Packit 7e982e
	pam_get_env(pam_handle_t *pamh, const char *varname)
Packit 7e982e
	pam_strerror(pam_handle_t *pamh, int pam_errno)
Packit 7e982e
Packit 7e982e
Event driven support (XXX work in progress)
Packit 7e982e
Packit 7e982e
	pam_register_event() - app or module associates an event poller/handler
Packit 7e982e
	pam_select_event()   - query for any outstanding event and act on any
Packit 7e982e
]
Packit 7e982e
Packit 7e982e
#$$$ Server <-> libpam
Packit 7e982e
Packit 7e982e
[This section will document the following pam_ calls:
Packit 7e982e
Packit 7e982e
	pam_start
Packit 7e982e
	pam_end
Packit 7e982e
	pam_authenticate (*)
Packit 7e982e
	pam_setcred
Packit 7e982e
	pam_acct_mgmt
Packit 7e982e
	pam_open_session
Packit 7e982e
	pam_close_session
Packit 7e982e
	pam_chauthtok (*)
Packit 7e982e
Packit 7e982e
The asterisked functions may return PAM_INCOMPLETE. In such cases, the
Packit 7e982e
application should be aware that the conversation function was called
Packit 7e982e
and that it returned PAM_CONV_AGAIN to a module. The correct action
Packit 7e982e
for the application to take in response to receiving PAM_INCOMPLETE,
Packit 7e982e
is to acquire the replies so that the next time the conversation
Packit 7e982e
function is called it will be able to provide the desired
Packit 7e982e
responses. And then recall pam_authenticate (pam_chauthtok) with the
Packit 7e982e
same arguments. Libpam will arrange that the module stack is resumed
Packit 7e982e
from the module that returned before. This functionality is required
Packit 7e982e
for programs whose user interface is maintained by an event loop. ]
Packit 7e982e
Packit 7e982e
#$$$ libpam <-> modules
Packit 7e982e
Packit 7e982e
[This section will document the following pam_ and pam_sm_ calls:
Packit 7e982e
Packit 7e982e
functions provided by libpam
Packit 7e982e
Packit 7e982e
	pam_set_data
Packit 7e982e
	pam_get_data
Packit 7e982e
Packit 7e982e
functions provided to libpam by each module
Packit 7e982e
Packit 7e982e
  groups:
Packit 7e982e
	AUTHENTICATION
Packit 7e982e
		pam_sm_authenticate
Packit 7e982e
		pam_sm_setcred
Packit 7e982e
	ACCOUNT
Packit 7e982e
		pam_sm_acct_mgmt
Packit 7e982e
	SESSION
Packit 7e982e
		pam_sm_open_session
Packit 7e982e
		pam_sm_close_session
Packit 7e982e
	AUTHENTICATION TOKEN MANAGEMENT
Packit 7e982e
		pam_sm_chauthtok
Packit 7e982e
]
Packit 7e982e
Packit 7e982e
#$$$ The conversation function
Packit 7e982e
Packit 7e982e
The server application, as part of its initialization of libpam,
Packit 7e982e
provides a conversation function for use by modules and libpam. The
Packit 7e982e
purpose of the conversation function is to enable direct communication
Packit 7e982e
to the applicant ultimately via the client and selected agents.
Packit 7e982e
Packit 7e982e
[ this section will contain a definition for the conversation
Packit 7e982e
  function, the conversation structure (appdata etc), and legitimate
Packit 7e982e
  return codes for the application supplied function.
Packit 7e982e
Packit 7e982e
	PAM_SUCCESS           - ok conversation completed
Packit 7e982e
	PAM_CONV_ERR          - conversation failed
Packit 7e982e
	PAM_CONV_AGAIN        - application needs control to complete conv
Packit 7e982e
	PAM_CONV_RECONSIDER   - application believes module should check if
Packit 7e982e
	                        it still needs to converse for this info
Packit 7e982e
 ]
Packit 7e982e
Packit 7e982e
#$  Security considerations
Packit 7e982e
Packit 7e982e
This document is devoted to standardizing authentication
Packit 7e982e
infrastructure: everything in this document has implications for
Packit 7e982e
security.
Packit 7e982e
Packit 7e982e
#$  Contact
Packit 7e982e
Packit 7e982e
The email list for discussing issues related to this document is
Packit 7e982e
<pam-list@redhat.com>.
Packit 7e982e
Packit 7e982e
#$  References
Packit 7e982e
Packit 7e982e
[#{OSF_RFC_PAM}]  OSF RFC 86.0, "Unified Login with Pluggable Authentication
Packit 7e982e
     Modules (PAM)", October 1995
Packit 7e982e
Packit 7e982e
[#{PAM_STD_AGENTIDS}] Definitions for standard agents, "REGISTERED
Packit 7e982e
     AGENTS AND THEIR AGENT-ID'S", to be found here:
Packit 7e982e
Packit 7e982e
## http://www.kernel.org/pub/linux/libs/pam/pre/doc/std-agent-ids.txt ##
Packit 7e982e
Packit 7e982e
#$  Author's Address
Packit 7e982e
Packit 7e982e
Andrew G. Morgan
Packit 7e982e
Email: morgan@kernel.org
Packit 7e982e
Packit 7e982e
## $Id$ ##