📄 current-draft.txt
字号:
agents' binary prompt responses are returned to the server. 5.4 Server <-> module Modules drive the authentication process. The server provides a conversation function with which it encapsulates module-generated requests and exchanges them with the client. Every message sent by a module should be acknowledged. General conversation functions can support the following five conversation requests: echo text string echo error string prompt for echo'd text string response prompt for concealed text string response binary prompt for binary prompt response The server is responsible for redirecting these requests to the client. 6 C API for application interfaces (client and server) 6.1 Applicant <-> client No API is defined for this interface. The interface is considered to be specific to the client application. Example applications include terminal login, (X)windows login, machine file transfer applications. All that is important is that the client application is able to present the applicant with textual output and to receive textual input from the applicant. The forms of textual exchange are listed in an earlier section (5.1). Other methods of data input/output are better suited to being handled via an authentication agent. 6.2 Client <-> agent The client makes use of a general API for communicating with agents. The client is not required to communicate directly with available agents, instead a layer of abstraction (in the form of a library: libpamc) takes care of loading and maintaining communication with all requested agents. This layer of abstraction will choose which agents to interact with based on the content of binary prompts it receives that have the control type PAM_BPC_SELECT. 6.2.1 Client <-> libpamc 6.2.1.1 Compilation information The C-header file provided for client-agent abstraction is included with the following source line: #include <security/pam_client.h> The library providing the corresponding client-agent abstraction functions is, libpamc. cc .... -lpamc 6.2.1.2 Initializing libpamc The libpamc library is initialized with a call to the following function: pamc_handle_t pamc_start(void); This function is responsible for configuring the library and registering the location of available agents. The location of the available agents on the system is implementation specific. pamc_start() function returns NULL on failure. Otherwise, the return value is a pointer to an opaque data type which provides a handle to the libpamc library. On systems where threading is available, the libpamc libraray is thread safe provided a single (pamc_handler_t *) is used by each thread. 6.2.1.3 Client (Applicant) selection of agents For the purpose of applicant and client review of available agents, the following function is provided. char **pamc_list_agents(pamc_handle_t pch); This returns a list of pointers to the agent_id's of the agents which are available on the system. The list is terminated by a NULL pointer. It is the clients responsibility to free this memory area by calling free() on each agent id and the block of agent_id pointers in the result. PAM represents a server-driven authentication model, so by default any available agent may be invoked in the authentication process. 6.2.1.3.1 Client demands agent If the client requires that a specific authentication agent is satisfied during the authentication process, then the client should call the following function, immediately after obtaining a pamc_handle_t from pamc_start(). int pamc_load(pamc_handle_t pch, const char *agent_id); agent_id is a PAM text string (see section 4.2.2.1) and is not suffixed with a '/' delimiter. The return value for this function is: PAM_BPC_TRUE - agent located and loaded. PAM_BPC_FALSE - agent is not available. Note, although the agent is loaded, no data is fed to it. The agent's opportunity to inform the client that it does not trust the server is when the agent is shutdown. 6.2.1.3.2 Client marks agent as unusable The applicant might prefer that a named agent is marked as not available. To do this, the client would invoke the following function immediately after obtaining a pamc_handle_t from pam_start(). int pamc_disable(pamc_handle_t pch, const char *agent_id); here agent_id is a PAM text string containing an agent_id (section 4.2.2.1). The return value for this function is: PAM_BPC_TRUE - agent is disabled. This is the response independent of whether the agent is locally available. PAM_BPC_FALSE - agent cannot be disabled (this may be because it has already been invoked). 6.2.1.4 Allocating and manipulating binary prompts All conversation between an client and an agent takes place with respect to binary prompts. A binary prompt (see section 4.2.2), is obtained, resized and deleted via the following C-macro: CREATION of a binary prompt with control X1 and data length Y1: pamc_bp_t prompt = NULL; PAM_BP_RENEW(&prompt, X1, Y1); REPLACEMENT of a binary prompt with a control X2 and data length Y2: PAM_BP_RENEW(&prompt, X2, Y2); DELETION of a binary prompt (the referenced prompt is scrubbed): PAM_BP_RENEW(&prompt, 0, 0); Note, the PAM_BP_RENEW macro always overwrites any prompt that you call it with, deleting and liberating the old contents in a secure fashion. Also note that PAM_BP_RENEW, when returning a prompt of data size Y1>0, will always append a '\0' byte to the end of the prompt (at data offset Y1). It is thus, by definition, acceptable to treat the data contents of a binary packet as a text string (see 4.2.1). FILLING a binary prompt from a memory pointer U1 from offset O1 of length L1: PAM_BP_FILL(prompt, O1, L1, U1); the CONTROL type for the packet can be obtained as follows: control = PAM_PB_CONTROL(prompt); the LENGTH of a data within the prompt (_excluding_ its header information) can be obtained as follows: length = PAM_BP_LENGTH(prompt); the total SIZE of the prompt (_including_ its header information) can be obtained as follows: size = PAM_BP_SIZE(prompt); EXTRACTING data from a binary prompt from offset O2 of length L2 to a memory pointer U2: PAM_BP_EXTRACT(prompt, O2, L2, U2); If you require direct access to the raw prompt DATA, you should use the following macro: __u8 *raw_data = PAM_BP_DATA(prompt); 6.2.1.5 Client<->agent conversations All exchanges of binary prompts with agents are handled with the single function: int pamc_converse(pamc_handle_t *pch, pamc_bp_t *prompt_p); The return value for pamc_converse(...) is PAM_BPC_TRUE when there is a response packet and PAM_BPC_FALSE when the client is unable to handle the request represented by the original prompt. In this latter case, *prompt_p is set to NULL. This function takes a binary prompt and returns a replacement binary prompt that is either a request from an agent to be acted upon by the client or the 'result' which should be forwarded to the server. In the former case, the following macro will return 1 (PAM_BPC_TRUE) and in all other cases, 0 (PAM_BPC_FALSE): PAM_BPC_FOR_CLIENT(/* pamc_bp_t */ prompt) Note, all non-NULL binary prompts returned by pamc_converse(...), are terminated with a '\0', even when the full length of the prompt (as returned by the agent) does not contain this delimiter. This is a defined property of the PAM_BP_RENEW macro, and can be relied upon. Important security note: in certain implementations, agents are implemented by executable binaries, which are transparently loaded and managed by the PAM client library. To ensure there is never a leakage of elevated privilege to an unprivileged agent, the client application should go to some effort to lower its level of privilege. It remains the responsibility of the applicant and the client to ensure that it is not compromised by a rogue agent. 6.2.1.6 Termination of agents When closing the authentication session and severing the connection between a client and a selection of agents, the following function is used: int pamc_end(pamc_handle_t *pch); Following a call to pamc_end, the pamc_handle_t will be invalid. The return value for this function is one of the following: PAM_BPC_TRUE - all invoked agents are content with authentication (the server is _not_ judged _un_trustworthy by any agent) PAM_BPC_FALSE - one or more agents were unsatisfied at being terminated. In general, the client should terminate its connection to the server and indicate to the applicant that the server is untrusted. 6.2.2 libpamc <-> agents The agents are manipulated from within libpamc. Each agent is an executable in its own right. This permits the agent to have access to sensitive data not accessible directly from the client. The mode of communication between libpamc and an agent is through a pair of pipes. The agent reads binary prompts (section 4.2.2) through its standard input file descriptor and writes response (to the server) binary prompts and instruction binary prompts (instructions for the client) through its standard output file descriptor. 6.3 Client <-> server This interface is concerned with the exchange of text and binary prompts between the client application and the server application. No API is provided for this as it is considered specific to the transport protocol shared by the client and the server. 6.4 Server <-> modules The server makes use of a general API for communicating with modules. The client is not required to communicate directly with available modules. By abstracting the authentication interface, it becomes possible for the local administrator to make a run time decision about the authentication method adopted by the server. 6.4.1 Functions and definitions available to servers and modules [This section will document the following functions pam_set_item() pam_get_item() pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec) pam_get_env(pam_handle_t *pamh, const char *varname) pam_strerror(pam_handle_t *pamh, int pam_errno) ] 6.4.2 Server <-> libpam [This section will document the following pam_ calls: pam_start pam_end pam_authenticate (*) pam_setcred pam_acct_mgmt pam_open_session pam_close_session pam_chauthtok (*) The asterisked functions may return PAM_INCOMPLETE. In such cases, the application should be aware that the conversation function was called and that it returned PAM_CONV_AGAIN to a module. The correct action for the application to take in response to receiving PAM_INCOMPLETE, is to acquire the replies so that the next time the conversation function is called it will be able to provide the desired responses. And then recall pam_authenticate (pam_chauthtok) with the same arguments. Libpam will arrange that the module stack is resumed from the module that returned before. This functionality is required for programs whose user interface is maintained by an event loop. ] 6.4.3 libpam <-> modules [This section will document the following pam_ and pam_sm_ calls: functions provided by libpam pam_set_data pam_get_data functions provided to libpam by each module groups: AUTHENTICATION pam_sm_authenticate pam_sm_setcred ACCOUNT pam_sm_acct_mgmt SESSION pam_sm_open_session pam_sm_close_session AUTHENTICATION TOKEN MANAGEMENT pam_sm_chauthtok ] 7 Security considerations This document is devoted to standardizing authentication infrastructure: everything in this document has implications for security. 8 Contact The email list for discussing issues related to this document is <pam-list@redhat.com>. 9 References [1] OSF RFC 86.0, "Unified Login with Pluggable Authentication Modules (PAM)", October 1995 10 Author's Address Andrew G. Morgan Email: morgan@ftp.kernel.org $Id: current-draft.txt,v 1.1 2001/01/05 22:07:00 kiavik Exp $
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -