1 | <?php |
||||
2 | /** |
||||
3 | * Server config checks management |
||||
4 | */ |
||||
5 | |||||
6 | declare(strict_types=1); |
||||
7 | |||||
8 | namespace PhpMyAdmin\Config; |
||||
9 | |||||
10 | use PhpMyAdmin\Core; |
||||
11 | use PhpMyAdmin\Sanitize; |
||||
12 | use PhpMyAdmin\Setup\Index as SetupIndex; |
||||
13 | use PhpMyAdmin\Url; |
||||
14 | use PhpMyAdmin\Util; |
||||
15 | use function count; |
||||
16 | use function function_exists; |
||||
17 | use function htmlspecialchars; |
||||
18 | use function implode; |
||||
19 | use function ini_get; |
||||
20 | use function preg_match; |
||||
21 | use function sprintf; |
||||
22 | use function strlen; |
||||
23 | |||||
24 | /** |
||||
25 | * Performs various compatibility, security and consistency checks on current config |
||||
26 | * |
||||
27 | * Outputs results to message list, must be called between SetupIndex::messagesBegin() |
||||
28 | * and SetupIndex::messagesEnd() |
||||
29 | */ |
||||
30 | class ServerConfigChecks |
||||
31 | { |
||||
32 | /** @var ConfigFile configurations being checked */ |
||||
33 | protected $cfg; |
||||
34 | |||||
35 | /** |
||||
36 | * @param ConfigFile $cfg Configuration |
||||
37 | */ |
||||
38 | 12 | public function __construct(ConfigFile $cfg) |
|||
39 | { |
||||
40 | 12 | $this->cfg = $cfg; |
|||
41 | 12 | } |
|||
42 | |||||
43 | /** |
||||
44 | * Perform config checks |
||||
45 | * |
||||
46 | * @return void |
||||
47 | */ |
||||
48 | 12 | public function performConfigChecks() |
|||
49 | { |
||||
50 | 12 | $blowfishSecret = $this->cfg->get('blowfish_secret'); |
|||
51 | 12 | $blowfishSecretSet = false; |
|||
52 | 12 | $cookieAuthUsed = false; |
|||
53 | |||||
54 | [$cookieAuthUsed, $blowfishSecret, $blowfishSecretSet] |
||||
55 | 12 | = $this->performConfigChecksServers( |
|||
56 | 12 | $cookieAuthUsed, |
|||
57 | 6 | $blowfishSecret, |
|||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
58 | 6 | $blowfishSecretSet |
|||
59 | ); |
||||
60 | |||||
61 | 12 | $this->performConfigChecksCookieAuthUsed( |
|||
62 | 12 | $cookieAuthUsed, |
|||
0 ignored issues
–
show
It seems like
$cookieAuthUsed can also be of type integer ; however, parameter $cookieAuthUsed of PhpMyAdmin\Config\Server...gChecksCookieAuthUsed() does only seem to accept boolean , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
63 | 6 | $blowfishSecretSet, |
|||
64 | 6 | $blowfishSecret |
|||
65 | ); |
||||
66 | |||||
67 | // $cfg['AllowArbitraryServer'] |
||||
68 | // should be disabled |
||||
69 | 12 | if ($this->cfg->getValue('AllowArbitraryServer')) { |
|||
70 | 4 | $sAllowArbitraryServerWarn = sprintf( |
|||
71 | 4 | __( |
|||
72 | 'This %soption%s should be disabled as it allows attackers to ' |
||||
73 | . 'bruteforce login to any MySQL server. If you feel this is necessary, ' |
||||
74 | . 'use %srestrict login to MySQL server%s or %strusted proxies list%s. ' |
||||
75 | . 'However, IP-based protection with trusted proxies list may not be ' |
||||
76 | . 'reliable if your IP belongs to an ISP where thousands of users, ' |
||||
77 | 4 | . 'including you, are connected to.' |
|||
78 | ), |
||||
79 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
80 | 4 | '[/a]', |
|||
81 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
82 | 4 | '[/a]', |
|||
83 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
84 | 4 | '[/a]' |
|||
85 | ); |
||||
86 | 4 | SetupIndex::messagesSet( |
|||
87 | 4 | 'notice', |
|||
88 | 4 | 'AllowArbitraryServer', |
|||
89 | 4 | Descriptions::get('AllowArbitraryServer'), |
|||
90 | 4 | Sanitize::sanitizeMessage($sAllowArbitraryServerWarn) |
|||
91 | ); |
||||
92 | } |
||||
93 | |||||
94 | 12 | $this->performConfigChecksLoginCookie(); |
|||
95 | |||||
96 | 12 | $sDirectoryNotice = __( |
|||
97 | 'This value should be double checked to ensure that this directory is ' |
||||
98 | . 'neither world accessible nor readable or writable by other users on ' |
||||
99 | 12 | . 'your server.' |
|||
100 | ); |
||||
101 | |||||
102 | // $cfg['SaveDir'] |
||||
103 | // should not be world-accessible |
||||
104 | 12 | if ($this->cfg->getValue('SaveDir') != '') { |
|||
105 | 4 | SetupIndex::messagesSet( |
|||
106 | 4 | 'notice', |
|||
107 | 4 | 'SaveDir', |
|||
108 | 4 | Descriptions::get('SaveDir'), |
|||
109 | 4 | Sanitize::sanitizeMessage($sDirectoryNotice) |
|||
110 | ); |
||||
111 | } |
||||
112 | |||||
113 | // $cfg['TempDir'] |
||||
114 | // should not be world-accessible |
||||
115 | 12 | if ($this->cfg->getValue('TempDir') != '') { |
|||
116 | 8 | SetupIndex::messagesSet( |
|||
117 | 8 | 'notice', |
|||
118 | 8 | 'TempDir', |
|||
119 | 8 | Descriptions::get('TempDir'), |
|||
120 | 8 | Sanitize::sanitizeMessage($sDirectoryNotice) |
|||
121 | ); |
||||
122 | } |
||||
123 | |||||
124 | 12 | $this->performConfigChecksZips(); |
|||
125 | 12 | } |
|||
126 | |||||
127 | /** |
||||
128 | * Check config of servers |
||||
129 | * |
||||
130 | * @param bool $cookieAuthUsed Cookie auth is used |
||||
131 | * @param string $blowfishSecret Blowfish secret |
||||
132 | * @param bool $blowfishSecretSet Blowfish secret set |
||||
133 | * |
||||
134 | * @return array |
||||
135 | */ |
||||
136 | 12 | protected function performConfigChecksServers( |
|||
137 | $cookieAuthUsed, |
||||
138 | $blowfishSecret, |
||||
139 | $blowfishSecretSet |
||||
140 | ) { |
||||
141 | 12 | $serverCnt = $this->cfg->getServerCount(); |
|||
142 | 12 | for ($i = 1; $i <= $serverCnt; $i++) { |
|||
143 | $cookieAuthServer |
||||
144 | 12 | = ($this->cfg->getValue('Servers/' . $i . '/auth_type') == 'cookie'); |
|||
145 | 12 | $cookieAuthUsed |= $cookieAuthServer; |
|||
146 | 12 | $serverName = $this->performConfigChecksServersGetServerName( |
|||
147 | 12 | $this->cfg->getServerName($i), |
|||
148 | 6 | $i |
|||
149 | ); |
||||
150 | 12 | $serverName = htmlspecialchars($serverName); |
|||
151 | |||||
152 | [$blowfishSecret, $blowfishSecretSet] |
||||
153 | 12 | = $this->performConfigChecksServersSetBlowfishSecret( |
|||
154 | 12 | $blowfishSecret, |
|||
155 | 6 | $cookieAuthServer, |
|||
156 | 6 | $blowfishSecretSet |
|||
157 | ); |
||||
158 | |||||
159 | // $cfg['Servers'][$i]['ssl'] |
||||
160 | // should be enabled if possible |
||||
161 | 12 | if (! $this->cfg->getValue('Servers/' . $i . '/ssl')) { |
|||
162 | 8 | $title = Descriptions::get('Servers/1/ssl') . ' (' . $serverName . ')'; |
|||
163 | 8 | SetupIndex::messagesSet( |
|||
164 | 8 | 'notice', |
|||
165 | 8 | 'Servers/' . $i . '/ssl', |
|||
166 | 6 | $title, |
|||
167 | 8 | __( |
|||
168 | 'You should use SSL connections if your database server ' |
||||
169 | 8 | . 'supports it.' |
|||
170 | ) |
||||
171 | ); |
||||
172 | } |
||||
173 | 12 | $sSecurityInfoMsg = Sanitize::sanitizeMessage(sprintf( |
|||
174 | 12 | __( |
|||
175 | 'If you feel this is necessary, use additional protection settings - ' |
||||
176 | . '%1$shost authentication%2$s settings and %3$strusted proxies list%4%s. ' |
||||
177 | . 'However, IP-based protection may not be reliable if your IP belongs ' |
||||
178 | 12 | . 'to an ISP where thousands of users, including you, are connected to.' |
|||
179 | ), |
||||
180 | 12 | '[a@' . Url::getCommon(['page' => 'servers', 'mode' => 'edit', 'id' => $i]) . '#tab_Server_config]', |
|||
181 | 12 | '[/a]', |
|||
182 | 12 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
183 | 12 | '[/a]' |
|||
184 | )); |
||||
185 | |||||
186 | // $cfg['Servers'][$i]['auth_type'] |
||||
187 | // warn about full user credentials if 'auth_type' is 'config' |
||||
188 | 12 | if ($this->cfg->getValue('Servers/' . $i . '/auth_type') == 'config' |
|||
189 | 12 | && $this->cfg->getValue('Servers/' . $i . '/user') != '' |
|||
190 | 12 | && $this->cfg->getValue('Servers/' . $i . '/password') != '' |
|||
191 | ) { |
||||
192 | 4 | $title = Descriptions::get('Servers/1/auth_type') |
|||
193 | 4 | . ' (' . $serverName . ')'; |
|||
194 | 4 | SetupIndex::messagesSet( |
|||
195 | 4 | 'notice', |
|||
196 | 4 | 'Servers/' . $i . '/auth_type', |
|||
197 | 3 | $title, |
|||
198 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
199 | 4 | __( |
|||
200 | 'You set the [kbd]config[/kbd] authentication type and included ' |
||||
201 | . 'username and password for auto-login, which is not a desirable ' |
||||
202 | . 'option for live hosts. Anyone who knows or guesses your phpMyAdmin ' |
||||
203 | . 'URL can directly access your phpMyAdmin panel. Set %1$sauthentication ' |
||||
204 | 4 | . 'type%2$s to [kbd]cookie[/kbd] or [kbd]http[/kbd].' |
|||
205 | ), |
||||
206 | 4 | '[a@' . Url::getCommon(['page' => 'servers', 'mode' => 'edit', 'id' => $i]) . '#tab_Server]', |
|||
207 | 4 | '[/a]' |
|||
208 | )) |
||||
209 | 4 | . ' ' . $sSecurityInfoMsg |
|||
210 | ); |
||||
211 | } |
||||
212 | |||||
213 | // $cfg['Servers'][$i]['AllowRoot'] |
||||
214 | // $cfg['Servers'][$i]['AllowNoPassword'] |
||||
215 | // serious security flaw |
||||
216 | 12 | if (! $this->cfg->getValue('Servers/' . $i . '/AllowRoot') |
|||
217 | 12 | || ! $this->cfg->getValue('Servers/' . $i . '/AllowNoPassword') |
|||
218 | ) { |
||||
219 | 8 | continue; |
|||
220 | } |
||||
221 | |||||
222 | 4 | $title = Descriptions::get('Servers/1/AllowNoPassword') |
|||
223 | 4 | . ' (' . $serverName . ')'; |
|||
224 | 4 | SetupIndex::messagesSet( |
|||
225 | 4 | 'notice', |
|||
226 | 4 | 'Servers/' . $i . '/AllowNoPassword', |
|||
227 | 3 | $title, |
|||
228 | 4 | __('You allow for connecting to the server without a password.') |
|||
229 | 4 | . ' ' . $sSecurityInfoMsg |
|||
230 | ); |
||||
231 | } |
||||
232 | |||||
233 | return [ |
||||
234 | 12 | $cookieAuthUsed, |
|||
235 | 12 | $blowfishSecret, |
|||
236 | 12 | $blowfishSecretSet, |
|||
237 | ]; |
||||
238 | } |
||||
239 | |||||
240 | /** |
||||
241 | * Set blowfish secret |
||||
242 | * |
||||
243 | * @param string|null $blowfishSecret Blowfish secret |
||||
244 | * @param bool $cookieAuthServer Cookie auth is used |
||||
245 | * @param bool $blowfishSecretSet Blowfish secret set |
||||
246 | * |
||||
247 | * @return array |
||||
248 | */ |
||||
249 | 12 | protected function performConfigChecksServersSetBlowfishSecret( |
|||
250 | $blowfishSecret, |
||||
251 | $cookieAuthServer, |
||||
252 | $blowfishSecretSet |
||||
253 | ): array { |
||||
254 | 12 | if ($cookieAuthServer && $blowfishSecret === null) { |
|||
255 | 4 | $blowfishSecretSet = true; |
|||
256 | 4 | $this->cfg->set('blowfish_secret', Util::generateRandom(32)); |
|||
257 | } |
||||
258 | |||||
259 | return [ |
||||
260 | 12 | $blowfishSecret, |
|||
261 | 12 | $blowfishSecretSet, |
|||
262 | ]; |
||||
263 | } |
||||
264 | |||||
265 | /** |
||||
266 | * Define server name |
||||
267 | * |
||||
268 | * @param string $serverName Server name |
||||
269 | * @param int $serverId Server id |
||||
270 | * |
||||
271 | * @return string Server name |
||||
272 | */ |
||||
273 | 12 | protected function performConfigChecksServersGetServerName( |
|||
274 | $serverName, |
||||
275 | $serverId |
||||
276 | ) { |
||||
277 | 12 | if ($serverName == 'localhost') { |
|||
278 | 12 | return $serverName . ' [' . $serverId . ']'; |
|||
279 | } |
||||
280 | |||||
281 | return $serverName; |
||||
282 | } |
||||
283 | |||||
284 | /** |
||||
285 | * Perform config checks for zip part. |
||||
286 | * |
||||
287 | * @return void |
||||
288 | */ |
||||
289 | 12 | protected function performConfigChecksZips() |
|||
290 | { |
||||
291 | 12 | $this->performConfigChecksServerGZipdump(); |
|||
292 | 12 | $this->performConfigChecksServerBZipdump(); |
|||
293 | 12 | $this->performConfigChecksServersZipdump(); |
|||
294 | 12 | } |
|||
295 | |||||
296 | /** |
||||
297 | * Perform config checks for zip part. |
||||
298 | * |
||||
299 | * @return void |
||||
300 | */ |
||||
301 | 12 | protected function performConfigChecksServersZipdump() |
|||
302 | { |
||||
303 | // $cfg['ZipDump'] |
||||
304 | // requires zip_open in import |
||||
305 | 12 | if ($this->cfg->getValue('ZipDump') && ! $this->functionExists('zip_open')) { |
|||
306 | 4 | SetupIndex::messagesSet( |
|||
307 | 4 | 'error', |
|||
308 | 4 | 'ZipDump_import', |
|||
309 | 4 | Descriptions::get('ZipDump'), |
|||
310 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
311 | 4 | __( |
|||
312 | '%sZip decompression%s requires functions (%s) which are unavailable ' |
||||
313 | 4 | . 'on this system.' |
|||
314 | ), |
||||
315 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Import_export]', |
|||
316 | 4 | '[/a]', |
|||
317 | 4 | 'zip_open' |
|||
318 | )) |
||||
319 | ); |
||||
320 | } |
||||
321 | |||||
322 | // $cfg['ZipDump'] |
||||
323 | // requires gzcompress in export |
||||
324 | 12 | if (! $this->cfg->getValue('ZipDump') || $this->functionExists('gzcompress')) { |
|||
325 | 8 | return; |
|||
326 | } |
||||
327 | |||||
328 | 4 | SetupIndex::messagesSet( |
|||
329 | 4 | 'error', |
|||
330 | 4 | 'ZipDump_export', |
|||
331 | 4 | Descriptions::get('ZipDump'), |
|||
332 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
333 | 4 | __( |
|||
334 | '%sZip compression%s requires functions (%s) which are unavailable on ' |
||||
335 | 4 | . 'this system.' |
|||
336 | ), |
||||
337 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Import_export]', |
|||
338 | 4 | '[/a]', |
|||
339 | 4 | 'gzcompress' |
|||
340 | )) |
||||
341 | ); |
||||
342 | 4 | } |
|||
343 | |||||
344 | /** |
||||
345 | * Check config of servers |
||||
346 | * |
||||
347 | * @param bool $cookieAuthUsed Cookie auth is used |
||||
348 | * @param bool $blowfishSecretSet Blowfish secret set |
||||
349 | * @param string $blowfishSecret Blowfish secret |
||||
350 | * |
||||
351 | * @return void |
||||
352 | */ |
||||
353 | 12 | protected function performConfigChecksCookieAuthUsed( |
|||
354 | $cookieAuthUsed, |
||||
355 | $blowfishSecretSet, |
||||
356 | $blowfishSecret |
||||
357 | ) { |
||||
358 | // $cfg['blowfish_secret'] |
||||
359 | // it's required for 'cookie' authentication |
||||
360 | 12 | if (! $cookieAuthUsed) { |
|||
361 | 4 | return; |
|||
362 | } |
||||
363 | |||||
364 | 8 | if ($blowfishSecretSet) { |
|||
365 | // 'cookie' auth used, blowfish_secret was generated |
||||
366 | 4 | SetupIndex::messagesSet( |
|||
367 | 4 | 'notice', |
|||
368 | 4 | 'blowfish_secret_created', |
|||
369 | 4 | Descriptions::get('blowfish_secret'), |
|||
370 | 4 | Sanitize::sanitizeMessage(__( |
|||
371 | 'You didn\'t have blowfish secret set and have enabled ' |
||||
372 | . '[kbd]cookie[/kbd] authentication, so a key was automatically ' |
||||
373 | . 'generated for you. It is used to encrypt cookies; you don\'t need to ' |
||||
374 | 4 | . 'remember it.' |
|||
375 | )) |
||||
376 | ); |
||||
377 | } else { |
||||
378 | 4 | $blowfishWarnings = []; |
|||
379 | // check length |
||||
380 | 4 | if (strlen($blowfishSecret) < 32) { |
|||
381 | // too short key |
||||
382 | 4 | $blowfishWarnings[] = __( |
|||
383 | 4 | 'Key is too short, it should have at least 32 characters.' |
|||
384 | ); |
||||
385 | } |
||||
386 | // check used characters |
||||
387 | 4 | $hasDigits = (bool) preg_match('/\d/', $blowfishSecret); |
|||
388 | 4 | $hasChars = (bool) preg_match('/\S/', $blowfishSecret); |
|||
389 | 4 | $hasNonword = (bool) preg_match('/\W/', $blowfishSecret); |
|||
390 | 4 | if (! $hasDigits || ! $hasChars || ! $hasNonword) { |
|||
391 | 4 | $blowfishWarnings[] = Sanitize::sanitizeMessage( |
|||
392 | 4 | __( |
|||
393 | 'Key should contain letters, numbers [em]and[/em] ' |
||||
394 | 4 | . 'special characters.' |
|||
395 | ) |
||||
396 | ); |
||||
397 | } |
||||
398 | 4 | if (! empty($blowfishWarnings)) { |
|||
399 | 4 | SetupIndex::messagesSet( |
|||
400 | 4 | 'error', |
|||
401 | 4 | 'blowfish_warnings' . count($blowfishWarnings), |
|||
402 | 4 | Descriptions::get('blowfish_secret'), |
|||
403 | 4 | implode('<br>', $blowfishWarnings) |
|||
404 | ); |
||||
405 | } |
||||
406 | } |
||||
407 | 8 | } |
|||
408 | |||||
409 | /** |
||||
410 | * Check configuration for login cookie |
||||
411 | * |
||||
412 | * @return void |
||||
413 | */ |
||||
414 | 12 | protected function performConfigChecksLoginCookie() |
|||
415 | { |
||||
416 | // $cfg['LoginCookieValidity'] |
||||
417 | // value greater than session.gc_maxlifetime will cause |
||||
418 | // random session invalidation after that time |
||||
419 | 12 | $loginCookieValidity = $this->cfg->getValue('LoginCookieValidity'); |
|||
420 | 12 | if ($loginCookieValidity > ini_get('session.gc_maxlifetime') |
|||
421 | ) { |
||||
422 | 4 | SetupIndex::messagesSet( |
|||
423 | 4 | 'error', |
|||
424 | 4 | 'LoginCookieValidity', |
|||
425 | 4 | Descriptions::get('LoginCookieValidity'), |
|||
426 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
427 | 4 | __( |
|||
428 | '%1$sLogin cookie validity%2$s greater than %3$ssession.gc_maxlifetime%4$s may ' |
||||
429 | . 'cause random session invalidation (currently session.gc_maxlifetime ' |
||||
430 | 4 | . 'is %5$d).' |
|||
431 | ), |
||||
432 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
433 | 4 | '[/a]', |
|||
434 | 4 | '[a@' . Core::getPHPDocLink('session.configuration.php#ini.session.gc-maxlifetime') . ']', |
|||
435 | 4 | '[/a]', |
|||
436 | 4 | ini_get('session.gc_maxlifetime') |
|||
437 | )) |
||||
438 | ); |
||||
439 | } |
||||
440 | |||||
441 | // $cfg['LoginCookieValidity'] |
||||
442 | // should be at most 1800 (30 min) |
||||
443 | 12 | if ($loginCookieValidity > 1800) { |
|||
444 | 4 | SetupIndex::messagesSet( |
|||
445 | 4 | 'notice', |
|||
446 | 4 | 'LoginCookieValidity', |
|||
447 | 4 | Descriptions::get('LoginCookieValidity'), |
|||
448 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
449 | 4 | __( |
|||
450 | '%sLogin cookie validity%s should be set to 1800 seconds (30 minutes) ' |
||||
451 | . 'at most. Values larger than 1800 may pose a security risk such as ' |
||||
452 | 4 | . 'impersonation.' |
|||
453 | ), |
||||
454 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
455 | 4 | '[/a]' |
|||
456 | )) |
||||
457 | ); |
||||
458 | } |
||||
459 | |||||
460 | // $cfg['LoginCookieValidity'] |
||||
461 | // $cfg['LoginCookieStore'] |
||||
462 | // LoginCookieValidity must be less or equal to LoginCookieStore |
||||
463 | 12 | if (($this->cfg->getValue('LoginCookieStore') == 0) |
|||
464 | 12 | || ($loginCookieValidity <= $this->cfg->getValue('LoginCookieStore')) |
|||
465 | ) { |
||||
466 | 8 | return; |
|||
467 | } |
||||
468 | |||||
469 | 4 | SetupIndex::messagesSet( |
|||
470 | 4 | 'error', |
|||
471 | 4 | 'LoginCookieValidity', |
|||
472 | 4 | Descriptions::get('LoginCookieValidity'), |
|||
473 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
474 | 4 | __( |
|||
475 | 'If using [kbd]cookie[/kbd] authentication and %sLogin cookie store%s ' |
||||
476 | . 'is not 0, %sLogin cookie validity%s must be set to a value less or ' |
||||
477 | 4 | . 'equal to it.' |
|||
478 | ), |
||||
479 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
480 | 4 | '[/a]', |
|||
481 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Security]', |
|||
482 | 4 | '[/a]' |
|||
483 | )) |
||||
484 | ); |
||||
485 | 4 | } |
|||
486 | |||||
487 | /** |
||||
488 | * Check GZipDump configuration |
||||
489 | * |
||||
490 | * @return void |
||||
491 | */ |
||||
492 | 12 | protected function performConfigChecksServerBZipdump() |
|||
493 | { |
||||
494 | // $cfg['BZipDump'] |
||||
495 | // requires bzip2 functions |
||||
496 | 12 | if (! $this->cfg->getValue('BZipDump') |
|||
497 | 12 | || ($this->functionExists('bzopen') && $this->functionExists('bzcompress')) |
|||
498 | ) { |
||||
499 | 8 | return; |
|||
500 | } |
||||
501 | |||||
502 | 4 | $functions = $this->functionExists('bzopen') |
|||
503 | ? '' : |
||||
504 | 4 | 'bzopen'; |
|||
505 | 4 | $functions .= $this->functionExists('bzcompress') |
|||
506 | ? '' |
||||
507 | 4 | : ($functions ? ', ' : '') . 'bzcompress'; |
|||
508 | 4 | SetupIndex::messagesSet( |
|||
509 | 4 | 'error', |
|||
510 | 4 | 'BZipDump', |
|||
511 | 4 | Descriptions::get('BZipDump'), |
|||
512 | 4 | Sanitize::sanitizeMessage( |
|||
513 | 4 | sprintf( |
|||
514 | 4 | __( |
|||
515 | '%1$sBzip2 compression and decompression%2$s requires functions (%3$s) which ' |
||||
516 | 4 | . 'are unavailable on this system.' |
|||
517 | ), |
||||
518 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Import_export]', |
|||
519 | 4 | '[/a]', |
|||
520 | 4 | $functions |
|||
521 | ) |
||||
522 | ) |
||||
523 | ); |
||||
524 | 4 | } |
|||
525 | |||||
526 | /** |
||||
527 | * Check GZipDump configuration |
||||
528 | * |
||||
529 | * @return void |
||||
530 | */ |
||||
531 | 12 | protected function performConfigChecksServerGZipdump() |
|||
532 | { |
||||
533 | // $cfg['GZipDump'] |
||||
534 | // requires zlib functions |
||||
535 | 12 | if (! $this->cfg->getValue('GZipDump') |
|||
536 | 12 | || ($this->functionExists('gzopen') && $this->functionExists('gzencode')) |
|||
537 | ) { |
||||
538 | 8 | return; |
|||
539 | } |
||||
540 | |||||
541 | 4 | SetupIndex::messagesSet( |
|||
542 | 4 | 'error', |
|||
543 | 4 | 'GZipDump', |
|||
544 | 4 | Descriptions::get('GZipDump'), |
|||
545 | 4 | Sanitize::sanitizeMessage(sprintf( |
|||
546 | 4 | __( |
|||
547 | '%1$sGZip compression and decompression%2$s requires functions (%3$s) which ' |
||||
548 | 4 | . 'are unavailable on this system.' |
|||
549 | ), |
||||
550 | 4 | '[a@' . Url::getCommon(['page' => 'form', 'formset' => 'Features']) . '#tab_Import_export]', |
|||
551 | 4 | '[/a]', |
|||
552 | 4 | 'gzencode' |
|||
553 | )) |
||||
554 | ); |
||||
555 | 4 | } |
|||
556 | |||||
557 | /** |
||||
558 | * Wrapper around function_exists to allow mock in test |
||||
559 | * |
||||
560 | * @param string $name Function name |
||||
561 | * |
||||
562 | * @return bool |
||||
563 | */ |
||||
564 | 4 | protected function functionExists($name) |
|||
565 | { |
||||
566 | 4 | return function_exists($name); |
|||
567 | } |
||||
568 | } |
||||
569 |