1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<?php
/**
* Elgg Simple PAM library
* Contains functions for managing authentication.
* This is not a full implementation of PAM. It supports a single facility
* (authentication) and allows multiple policies (user authentication is the
* default). There are two control flags possible for each module: sufficient
* or required. The entire chain for a policy is processed (or until a
* required module fails). A module fails by returning false or throwing an
* exception. The order that modules are processed is determined by the order
* they are registered. For an example of a PAM, see pam_auth_userpass() in
* sessions.php.
*
* For more information on PAMs see:
* http://www.freebsd.org/doc/en/articles/pam/index.html
*
* @package Elgg
* @subpackage Core
* @author Curverider Ltd
* @link http://elgg.org/
*/
$_PAM_HANDLERS = array();
$_PAM_HANDLERS_MSG = array();
/**
* Register a PAM handler.
*
* @param string $handler The handler function in the format
* pam_handler($credentials = NULL);
* @param string $importance The importance - "sufficient" (default) or "required"
* @param string $policy - the policy type, default is "user"
* @return boolean
*/
function register_pam_handler($handler, $importance = "sufficient", $policy = "user") {
global $_PAM_HANDLERS;
// setup array for this type of pam if not already set
if (!isset($_PAM_HANDLERS[$policy])) {
$_PAM_HANDLERS[$policy] = array();
}
if (is_callable($handler)) {
$_PAM_HANDLERS[$policy][$handler] = new stdClass;
$_PAM_HANDLERS[$policy][$handler]->handler = $handler;
$_PAM_HANDLERS[$policy][$handler]->importance = strtolower($importance);
return true;
}
return false;
}
/**
* Unregisters a PAM handler.
*
* @param string $handler The PAM handler function name
* @param string $policy - the policy type, default is "user"
*/
function unregister_pam_handler($handler, $policy = "user") {
global $_PAM_HANDLERS;
unset($_PAM_HANDLERS[$policy][$handler]);
}
/**
* Attempt to authenticate.
* This function will process all registered PAM handlers or stop when the first
* handler fails. A handler fails by either returning false or throwing an
* exception. The advantage of throwing an exception is that it returns a message
* through the global $_PAM_HANDLERS_MSG which can be used in communication with
* a user. The order that handlers are processed is determined by the order that
* they were registered.
*
* If $credentials are provided the PAM handler should authenticate using the
* provided credentials, if not then credentials should be prompted for or
* otherwise retrieved (eg from the HTTP header or $_SESSION).
*
* @param mixed $credentials Mixed PAM handler specific credentials (e.g. username, password)
* @param string $policy - the policy type, default is "user"
* @return bool true if authenticated, false if not.
*/
function pam_authenticate($credentials = NULL, $policy = "user") {
global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG;
$_PAM_HANDLERS_MSG = array();
$authenticated = false;
foreach ($_PAM_HANDLERS[$policy] as $k => $v) {
$handler = $v->handler;
$importance = $v->importance;
try {
// Execute the handler
if ($handler($credentials)) {
// Explicitly returned true
$_PAM_HANDLERS_MSG[$k] = "Authenticated!";
$authenticated = true;
} else {
$_PAM_HANDLERS_MSG[$k] = "Not Authenticated.";
// If this is required then abort.
if ($importance == 'required') {
return false;
}
}
} catch (Exception $e) {
$_PAM_HANDLERS_MSG[$k] = "$e";
// If this is required then abort.
if ($importance == 'required') {
return false;
}
}
}
return $authenticated;
}
|