1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* The security of app |
5
|
|
|
* |
6
|
|
|
* @category core |
7
|
|
|
* @author Judicaël Paquet <[email protected]> |
8
|
|
|
* @copyright Copyright (c) 2005-2013 RueDuCommerce.com FR Inc. (http://www.rueducommerce.com) |
9
|
|
|
* @license http://www.rueducommerce.com Tout droit réservé à Rueducommerce.com |
10
|
|
|
* @filesource |
11
|
|
|
* @link http://www.rueducommerce.com |
12
|
|
|
* @since 1.0rc1 |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace Venus\core; |
16
|
|
|
|
17
|
|
|
use \Venus\core\Config as Config; |
18
|
|
|
use \Venus\lib\Request as Request; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* This class manage the security |
22
|
|
|
* |
23
|
|
|
* @category core |
24
|
|
|
* @author Judicaël Paquet <[email protected]> |
25
|
|
|
* @copyright Copyright (c) 2005-2013 RueDuCommerce.com FR Inc. (http://www.rueducommerce.com) |
26
|
|
|
* @license http://www.rueducommerce.com Tout droit réservé à Rueducommerce.com |
27
|
|
|
* @version 3.0.0 |
28
|
|
|
* @link http://www.rueducommerce.com |
29
|
|
|
* @since 1.0rc1 |
30
|
|
|
*/ |
31
|
|
|
|
32
|
|
|
class Security { |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The base Uri to construct the route |
36
|
|
|
* |
37
|
|
|
* @access private |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
|
41
|
|
|
private $_sBaseUri = ''; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Actual user |
45
|
|
|
* |
46
|
|
|
* @access private |
47
|
|
|
* @var string |
48
|
|
|
*/ |
49
|
|
|
|
50
|
|
|
private static $_sLogin = ''; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Actual user |
54
|
|
|
* |
55
|
|
|
* @access private |
56
|
|
|
* @var string |
57
|
|
|
*/ |
58
|
|
|
|
59
|
|
|
private static $_sPassword = ''; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* check security of access |
63
|
|
|
* |
64
|
|
|
* @access public |
65
|
|
|
* @return null|boolean |
66
|
|
|
*/ |
67
|
|
|
|
68
|
|
|
public function checkSecurity() { |
69
|
|
|
|
70
|
|
|
foreach (Config::get('Route') as $sHost => $oHost) { |
|
|
|
|
71
|
|
|
|
72
|
|
|
if ((!strstr($sHost, '/') && $sHost == $_SERVER['HTTP_HOST']) |
73
|
|
|
|| (strstr($sHost, '/') && strstr($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], $sHost))) { |
74
|
|
|
|
75
|
|
View Code Duplication |
if (strstr($sHost, '/') && strstr($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], $sHost)) { |
|
|
|
|
76
|
|
|
|
77
|
|
|
$this->_sBaseUri = preg_replace('#^[^/]+#', '', $sHost); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
if (isset($oSecurity->firewall)) { $oSecurity = $oHost->firewall; } |
|
|
|
|
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
if (isset($oSecurity)) { |
85
|
|
|
|
86
|
|
|
if (isset($oSecurity->authentification) && $oSecurity->authentification === 'http_basic') { |
87
|
|
|
|
88
|
|
|
if (!isset($_SERVER['PHP_AUTH_USER'])) { |
89
|
|
|
|
90
|
|
|
if (!isset($oSecurity->realm)) { $oSecurity->realm = 'Access'; } |
91
|
|
|
if (!isset($oSecurity->cancelled)) { $oSecurity->cancelled = 'Cancelled'; } |
92
|
|
|
|
93
|
|
|
header('WWW-Authenticate: Basic realm="'.$oSecurity->realm.'"'); |
94
|
|
|
header('HTTP/1.0 401 Unauthorized'); |
95
|
|
|
echo $oSecurity->cancelled; |
96
|
|
|
exit; |
97
|
|
|
} else { |
98
|
|
|
|
99
|
|
|
self::$_sLogin = $_SERVER['PHP_AUTH_USER']; |
100
|
|
|
self::$_sPassword = $_SERVER['PHP_AUTH_PW']; |
101
|
|
|
|
102
|
|
|
if (!$this->_checkPasswordIsGood()) { return false; } |
103
|
|
|
if (!$this->_checkAccess()) { return false; } |
104
|
|
|
if (!$this->_checkBlackListIps()) { return false; } |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
else if (isset($oSecurity->authentification) && $oSecurity->authentification === 'http_basic_validate_by_controller') { |
108
|
|
|
|
109
|
|
|
if (!isset($_SERVER['PHP_AUTH_USER'])) { |
110
|
|
|
|
111
|
|
|
if (!isset($oSecurity->realm)) { $oSecurity->realm = 'Access'; } |
112
|
|
|
if (!isset($oSecurity->cancelled)) { $oSecurity->cancelled = 'Cancelled'; } |
113
|
|
|
|
114
|
|
|
header('WWW-Authenticate: Basic realm="'.$oSecurity->realm.'"'); |
115
|
|
|
header('HTTP/1.0 401 Unauthorized'); |
116
|
|
|
echo $oSecurity->cancelled; |
117
|
|
|
exit; |
118
|
|
|
} else { |
119
|
|
|
|
120
|
|
|
self::$_sLogin = $_SERVER['PHP_AUTH_USER']; |
121
|
|
|
self::$_sPassword = $_SERVER['PHP_AUTH_PW']; |
122
|
|
|
|
123
|
|
|
$sControllerName = $oSecurity->controller; |
124
|
|
|
$sActionName = $oSecurity->action; |
125
|
|
|
|
126
|
|
|
$oController = new $sControllerName; |
127
|
|
|
|
128
|
|
|
if (!$oController->$sActionName(self::$_sLogin, self::$_sPassword)) { return false; } |
129
|
|
|
if (!$this->_checkAccess()) { return false; } |
130
|
|
|
if (!$this->_checkBlackListIps()) { return false; } |
131
|
|
|
} |
132
|
|
|
} else if (isset($oSecurity->authentification) && $oSecurity->authentification === 'controller') { |
133
|
|
|
|
134
|
|
|
// it's an action of one controller that it return true or false for the authentification |
135
|
|
|
|
136
|
|
|
$sControllerName = $oSecurity->controller; |
137
|
|
|
$sActionName = $oSecurity->action; |
138
|
|
|
|
139
|
|
|
$oController = new $sControllerName; |
140
|
|
|
|
141
|
|
|
if (!$oController->$sActionName) { return false; } |
142
|
|
|
if (!$this->_checkAccess()) { return false; } |
143
|
|
|
if (!$this->_checkBlackListIps()) { return false; } |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
if (isset($oSecurity->ips) && !in_array($_SERVER['REMOTE_ADDR'], $oSecurity->ips)) { return false; } |
147
|
|
|
|
148
|
|
|
if (isset($oSecurity->requires_channel) && $oSecurity->requires_channel == 'https' && !Request::isHttpsRequest()) { |
149
|
|
|
|
150
|
|
|
return false; |
151
|
|
|
} else if (isset($oSecurity->requires_channel) && $oSecurity->requires_channel == 'http' && ((Request::isHttpRequest() |
152
|
|
|
&& Request::isHttpsRequest()) || !Request::isHttpRequest())) { |
153
|
|
|
|
154
|
|
|
return false; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
return true; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* check access |
163
|
|
|
* |
164
|
|
|
* @access private |
165
|
|
|
* @return bool |
166
|
|
|
*/ |
167
|
|
|
|
168
|
|
|
private function _checkAccess() : bool { |
169
|
|
|
|
170
|
|
|
$oSecurity = Config::get('Security'); |
|
|
|
|
171
|
|
|
|
172
|
|
|
if (isset($oSecurity->access)) { |
173
|
|
|
|
174
|
|
|
foreach ($oSecurity->access as $sPathAccess => $aParams) { |
175
|
|
|
|
176
|
|
|
if (preg_match('#'.$sPathAccess.'#', str_replace($this->_sBaseUri, '', $_SERVER['REQUEST_URI']))) { |
177
|
|
|
|
178
|
|
|
if (in_array($this->getUserRole(), $aParams->roles)) { return true; } else { return false; } |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
return true; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* check if the ips is not in the blacklist |
188
|
|
|
* |
189
|
|
|
* @access private |
190
|
|
|
* @return bool |
191
|
|
|
*/ |
192
|
|
|
|
193
|
|
|
private function _checkBlackListIps() : bool { |
194
|
|
|
|
195
|
|
|
$oSecurity = Config::get('Security'); |
|
|
|
|
196
|
|
|
|
197
|
|
|
if (isset($oSecurity->blacklist_ips)) { |
198
|
|
|
|
199
|
|
|
foreach ($oSecurity->blacklist_ips as $sIp) { |
200
|
|
|
|
201
|
|
|
if ($_SERVER['REMOTE_ADDR'] == $sIp) { return false; } |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
return true; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* check if the password is good |
210
|
|
|
* |
211
|
|
|
* @access private |
212
|
|
|
* @return bool |
213
|
|
|
*/ |
214
|
|
|
|
215
|
|
|
private function _checkPasswordIsGood() : bool { |
216
|
|
|
|
217
|
|
|
$sLogin = self::$_sLogin; |
218
|
|
|
$sPassword = Config::get('Security')->users->$sLogin->password; |
219
|
|
|
|
220
|
|
|
if ($sPassword == self::$_sPassword) { return true; } |
221
|
|
|
else if ($sPassword == md5(self::$_sPassword)) { return true; } |
222
|
|
|
else { return false; } |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* get the user roles |
227
|
|
|
* |
228
|
|
|
* @access public |
229
|
|
|
* @return string |
230
|
|
|
*/ |
231
|
|
|
|
232
|
|
|
public function getUserRole() : string { |
233
|
|
|
|
234
|
|
|
if (self::$_sLogin) { |
235
|
|
|
|
236
|
|
|
$sLogin = self::$_sLogin; |
237
|
|
|
return Config::get('Security')->users->$sLogin->roles; |
238
|
|
|
} else { |
239
|
|
|
|
240
|
|
|
return ''; |
241
|
|
|
} |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* get the user roles |
247
|
|
|
* |
248
|
|
|
* @access public |
249
|
|
|
* @param string $sRole role to test |
250
|
|
|
* @return bool |
251
|
|
|
*/ |
252
|
|
|
|
253
|
|
|
public function isGranted(string $sRole) : bool { |
254
|
|
|
|
255
|
|
|
if ($sRole == $this->getUserRole() || $this->getUserRole() == '') { return true; } else { return false; } |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* set base uri |
260
|
|
|
* |
261
|
|
|
* @access public |
262
|
|
|
* @param string $sBaseUri |
263
|
|
|
* @return \Venus\core\Security |
264
|
|
|
*/ |
265
|
|
|
|
266
|
|
|
public function setBaseUri($sBaseUri) { |
267
|
|
|
|
268
|
|
|
$this->_sBaseUri = $sBaseUri; |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
|