forked from duosecurity/duo_api_php
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCurlRequester.php
More file actions
119 lines (100 loc) · 3.71 KB
/
CurlRequester.php
File metadata and controls
119 lines (100 loc) · 3.71 KB
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
<?php
namespace DuoAPI;
define('DEFAULT_CA_CERTS', __DIR__."/ca_certs.pem");
class CurlRequester implements Requester
{
public $ch;
public function __construct()
{
$this->ch = curl_init();
}
public function options($options)
{
assert(is_array($options));
/*
* These are the cURL options we support. The key represents the
* cURL option, and the value represents the key in the options
* argument.
*/
$possible_options = [
CURLOPT_TIMEOUT => "timeout",
CURLOPT_CAINFO => "ca",
CURLOPT_USERAGENT => "user_agent",
CURLOPT_PROXY => "proxy_url",
CURLOPT_PROXYPORT => "proxy_port",
];
$curl_options = array_filter($possible_options, function ($option) use ($options) {
return array_key_exists($option, $options);
});
foreach ($curl_options as $key => $value) {
$curl_options[$key] = $options[$value];
}
if (!isset($curl_options[CURLOPT_CAINFO])) {
$curl_options[CURLOPT_CAINFO] = DEFAULT_CA_CERTS;
};
if ($curl_options[CURLOPT_CAINFO] == "IGNORE") {
unset($curl_options[CURLOPT_CAINFO]);
};
// Mandatory configuration options
$curl_options[CURLOPT_RETURNTRANSFER] = 1;
$curl_options[CURLOPT_FOLLOWLOCATION] = 1;
$curl_options[CURLOPT_SSL_VERIFYPEER] = true;
$curl_options[CURLOPT_SSL_VERIFYHOST] = 2;
curl_setopt_array($this->ch, $curl_options);
}
public function execute($url, $method, $headers, $body = null)
{
assert(is_string($url));
assert(is_string($method));
assert(is_array($headers));
assert(is_string($body) || is_null($body));
$headers = array_map(function ($key, $value) {
return sprintf("%s: %s", $key, $value);
}, array_keys($headers), array_values($headers));
curl_setopt($this->ch, CURLOPT_URL, $url);
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
if ($method === "POST") {
curl_setopt($this->ch, CURLOPT_POST, true);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, null);
} elseif ($method === "GET") {
curl_setopt($this->ch, CURLOPT_HTTPGET, true);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, null);
} else {
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method);
}
$result = curl_exec($this->ch);
$http_status_code = null;
$success = true;
if ($result === false) {
$error = curl_error($this->ch);
$errno = curl_errno($this->ch);
/**
* We could simply leave the result as FALSE and return that, but
* let's convert it to what looks like an actual Duo web response.
* This is beneficial because it simplifies the two error cases
* we expect:
*
* 1. We had some sort of malformed request and Duo rejected it.
*
* 2. We couldn't reach Duo (this is the case we'd expect to
* return FALSE).
*/
$result = json_encode(
[
'stat' => 'FAIL',
'code' => $errno,
'message' => $error,
]
);
$success = false;
} else {
$http_status_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
}
return [
"response" => $result,
"success" => $success,
"http_status_code" => $http_status_code
];
}
}