forked from tweakier/duo_auth
-
Notifications
You must be signed in to change notification settings - Fork 4
/
duo_auth.php
132 lines (89 loc) · 3.76 KB
/
duo_auth.php
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
122
123
124
125
126
127
128
129
130
131
132
<?php
# import namespace\class for use Duo Web v4 SDK (Software Development Kit) - Duo Universal Prompt from composer ./vendor/duosecurity/duo_universal_php/src/Client.php & DuoException.php
use \Duo\DuoUniversal\Client;
use \Duo\DuoUniversal\DuoException;
##########
# define new class plugin inside RoundCube Plugin App environment (RoundCube API SDK)
class duo_auth extends rcube_plugin {
##########
# define hook's set inside calling current RoundCube instance (fully initialize RoundCube proccess instance)
function init() {
$rcmail = rcmail::get_instance();
$this->add_hook('login_after', array($this, '_main_handler_process_'));
$this->add_hook('send_page', array($this, '_blocking_access_'));
}
##########
# main Duo Web v4 SDK script user authenticator
function _main_handler_process_() {
$rcmail = rcmail::get_instance();
$username = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST, true));
$e = null;
$config = parse_ini_file("duo_auth.conf");
if (isset($config["username"]) && in_array($username, $config["username"])) {
header("Location: {$config["rc_path"]}?_task=mail");
exit;
} elseif (isset($config["ipaddr"])) {
foreach($config["ipaddr"] as $ipaddr) {
if ($this->ipaddr($_SERVER['REMOTE_ADDR'], $ipaddr)) {
header("Location: {$config["rc_path"]}?_task=mail");
exit;
}
}
} else {
try {
$duo_client = new Client($config['client_id'], $config['client_secret'], $config['api_hostname'], $config['redirect_uri']);
} catch (DuoException $e) {
throw new ErrorException("*** Duo config error. Verify the values in duo_auth.conf are correct ***\n" . $e->getMessage());
}
$failmode = strtoupper($config['failmode']);
try {
$duo_client->healthCheck();
} catch (DuoException $e) {
$e->getMessage();
if ($duo_failmode == "open") {
header("Location: {$config["rc_path"]}?_task=mail");
exit;
} else {
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
}
session_destroy();
header("Location: {$config["rc_path"]}");
exit;
}
}
if ($e !== null) {
} else {
$state = $duo_client->generateState();
$duo_value = array("state:" => $state, "username:" => $username, "session_id:" => session_id());
$_SESSION["_duo_auth_"] = $duo_value;
$prompt_uri = $duo_client->createAuthUrl($username, $state);
header("Location: $prompt_uri");
exit;
}
}
}
##########
# function blocking access while 2FA not finished
function _blocking_access_() {
$rc_path = parse_ini_file("duo.conf", true);
if (isset($_SESSION["_duo_auth_"])) {
header("Location: {$rc_path["rc_path"]["rc_path"]}your_page_name_blocking_access_while_2FA_not_approved.htm");
exit;
} else {}
}
##########
# private function ipv4 address handler
private function ipaddr($ip, $cidr) {
if (!preg_match('/\//',$cidr)) {$cidr=$cidr . "/32";}
list ($net, $mask) = explode ('/', $cidr);
$ip_net = ip2long ($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);
$ip_ip = ip2long ($ip);
return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask));
}
##########
}
?>