4 * SquirrelMail configtest script
6 * @copyright © 2003-2007 The SquirrelMail Project Team
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 * @package squirrelmail
13 /************************************************************
14 * NOTE: you do not need to change this script! *
15 * If it throws errors you need to adjust your config. *
16 ************************************************************/
18 /** This is the configtest page */
19 define('PAGE_NAME', 'configtest');
21 // This script could really use some restructuring as it has grown quite rapidly
22 // but is not very 'clean'. Feel free to get some structure into this thing.
24 /** force verbose error reporting and turn on display of errors */
25 error_reporting(E_ALL
);
26 ini_set('display_errors',1);
28 /** Blockcopy from init.php. Cleans globals. */
29 if ((bool) ini_get('register_globals') &&
30 strtolower(ini_get('register_globals'))!='off') {
32 * Remove all globals that are not reserved by PHP
33 * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
35 foreach ($GLOBALS as $key => $value) {
37 case 'HTTP_POST_VARS':
41 case 'HTTP_COOKIE_VARS':
43 case 'HTTP_SERVER_VARS':
47 case 'HTTP_POST_FILES':
50 case 'HTTP_SESSION_VARS':
57 unset($GLOBALS[$key]);
60 // Unset variables used in foreach
61 unset($GLOBALS['key']);
62 unset($GLOBALS['value']);
67 * Displays error messages and warnings
68 * @param string $str message
69 * @param boolean $fatal fatal error or only warning
71 function do_err($str, $fatal = TRUE) {
72 global $IND, $warnings;
73 $level = $fatal ?
'FATAL ERROR:' : 'WARNING:';
74 echo '<p>'.$IND.'<font color="red"><b>' . $level . '</b></font> ' .$str. "</p>\n";
76 echo '</body></html>';
85 define('SM_PATH', '../');
86 /** load minimal function set */
87 require(SM_PATH
. 'include/constants.php');
88 require(SM_PATH
. 'functions/global.php');
89 require(SM_PATH
. 'functions/strings.php');
90 $SQM_INTERNAL_VERSION = explode('.', SM_VERSION
, 3);
91 $SQM_INTERNAL_VERSION[2] = intval($SQM_INTERNAL_VERSION[2]);
93 /** set default value in order to block remote access */
94 $allow_remote_configtest=false;
96 /** Load all configuration files before output begins */
98 /* load default configuration */
99 require(SM_PATH
. 'config/config_default.php');
100 /* reset arrays in default configuration */
101 $ldap_server = array();
105 $theme[0]['PATH'] = SM_PATH
. 'themes/default_theme.php';
106 $theme[0]['NAME'] = 'Default';
107 $aTemplateSet = array();
108 $aTemplateSet[0]['ID'] = 'default';
109 $aTemplateSet[0]['NAME'] = 'Default';
110 /* load site configuration */
111 if (file_exists(SM_PATH
. 'config/config.php')) {
112 require(SM_PATH
. 'config/config.php');
114 /* load local configuration overrides */
115 if (file_exists(SM_PATH
. 'config/config_local.php')) {
116 require(SM_PATH
. 'config/config_local.php');
120 global $disable_plugins;
121 $squirrelmail_plugin_hooks = array();
122 if (!$disable_plugins && file_exists(SM_PATH
. 'config/plugin_hooks.php')) {
123 require(SM_PATH
. 'config/plugin_hooks.php');
126 /** Warning counter */
130 $IND = str_repeat(' ',4);
133 * get_location starts session and must be run before output is started.
135 $test_location = get_location();
137 ?
><!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
138 "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
141 <meta name
="robots" content
="noindex,nofollow">
142 <title
>SquirrelMail configtest
</title
>
145 <h1
>SquirrelMail configtest
</h1
>
147 <p
>This script will
try to check some aspects of your SquirrelMail configuration
148 and point you to errors whereever it can find them
. You need to go run
<tt
>conf
.pl
</tt
>
149 in the
<tt
>config
/</tt
> directory first before you run this script
.</p
>
153 $included = array_map('basename', get_included_files() );
154 if(!in_array('config.php', $included)) {
155 if(!file_exists(SM_PATH
. 'config/config.php')) {
156 do_err('Config file '.SM_PATH
. 'config/config.php does not exist!<br />'.
157 'You need to run <tt>conf.pl</tt> first.');
159 do_err('Could not read '.SM_PATH
.'config/config.php! Check file permissions.');
161 if(!in_array('strings.php', $included)) {
162 do_err('Could not include '.SM_PATH
.'functions/strings.php!<br />'.
163 'Check permissions on that file.');
166 /* Block remote use of script */
167 if (! $allow_remote_configtest) {
168 sqGetGlobalVar('REMOTE_ADDR',$client_ip,SQ_SERVER
);
169 sqGetGlobalVar('SERVER_ADDR',$server_ip,SQ_SERVER
);
171 if ((! isset($client_ip) ||
$client_ip!='127.0.0.1') &&
172 (! isset($client_ip) ||
! isset($server_ip) ||
$client_ip!=$server_ip)) {
173 do_err('Enable "Allow remote configtest" option in squirrelmail configuration in order to use this script.');
177 echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" . SM_VERSION
. "</b></td></tr>\n" .
178 '<tr><td>Config file version:</td><td><b>' . $config_version . "</b></td></tr>\n" .
179 '<tr><td>Config file last modified:</td><td><b>' .
180 date ('d F Y H:i:s', filemtime(SM_PATH
. 'config/config.php')) .
181 "</b></td></tr>\n</table>\n</p>\n\n";
183 /* check $config_version */
184 if ($config_version!='1.5.0') {
185 do_err('Configuration file version does not match required version. Please update your configuration file.');
189 /* checking PHP specs */
191 echo "Checking PHP configuration...<br />\n";
193 if(!check_php_version(4,1,0)) {
194 do_err('Insufficient PHP version: '. PHP_VERSION
. '! Minimum required: 4.1.0');
197 echo $IND . 'PHP version ' . PHP_VERSION
. ' OK. (You have: ' . phpversion() . ". Minimum: 4.1.0)<br />\n";
199 /* register_globals check: test for boolean false and any string that is not equal to 'off' */
201 if ((bool) ini_get('register_globals') &&
202 strtolower(ini_get('register_globals'))!='off') {
203 do_err('You have register_globals turned on. This is not an error, but it CAN be a security hazard. Consider turning register_globals off.', false);
207 /* variables_order check */
209 // FIXME(?): Hmm, how do we distinguish between when an ini setting is
210 // not available (ini_set() returns empty string) and when
211 // the administrator set the value to an empty string? The
212 // latter is sure to be highly rare, so for now, just assume
213 // that empty value means the setting isn't even available
214 // (could also check PHP version when this setting was implemented)
215 // although, we'll also warn the user if it is empty, with
217 $variables_order = strtoupper(ini_get('variables_order'));
218 if (empty($variables_order))
219 do_err('Your variables_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly', false);
220 else if (strpos($variables_order, 'G') === FALSE
221 ||
strpos($variables_order, 'P') === FALSE
222 ||
strpos($variables_order, 'C') === FALSE
223 ||
strpos($variables_order, 'S') === FALSE) {
224 do_err('Your variables_order setting is insufficient for SquirrelMail to function. It needs at least "GPCS", but you have it set to "' . htmlspecialchars($variables_order) . '"', true);
226 echo $IND . "variables_order OK: $variables_order.<br />\n";
230 /* gpc_order check (removed from PHP as of v5.0) */
232 if (!check_php_version(5)) {
233 // FIXME(?): Hmm, how do we distinguish between when an ini setting is
234 // not available (ini_set() returns empty string) and when
235 // the administrator set the value to an empty string? The
236 // latter is sure to be highly rare, so for now, just assume
237 // that empty value means the setting isn't even available
238 // (could also check PHP version when this setting was implemented)
239 // although, we'll also warn the user if it is empty, with
241 $gpc_order = strtoupper(ini_get('gpc_order'));
242 if (empty($gpc_order))
243 do_err('Your gpc_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly', false);
244 else if (strpos($gpc_order, 'G') === FALSE
245 ||
strpos($gpc_order, 'P') === FALSE
246 ||
strpos($gpc_order, 'C') === FALSE) {
247 do_err('Your gpc_order setting is insufficient for SquirrelMail to function. It needs to be set to "GPC", but you have it set to "' . htmlspecialchars($gpc_order) . '"', true);
249 echo $IND . "gpc_order OK: $gpc_order.<br />\n";
254 /* check PHP extensions */
256 $php_exts = array('session','pcre');
257 $diff = array_diff($php_exts, get_loaded_extensions());
259 do_err('Required PHP extensions missing: '.implode(', ',$diff) );
262 echo $IND . "PHP extensions OK.<br />\n";
264 /* dangerous php settings */
266 * mbstring.func_overload allows to replace original string and regexp functions
267 * with their equivalents from php mbstring extension. It causes problems when
268 * scripts analyze 8bit strings byte after byte or use 8bit strings in regexp tests.
269 * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
270 * and .htaccess files (php 4.3.5).
272 if (function_exists('mb_internal_encoding') &&
273 check_php_version(4,2,0) &&
274 (int)ini_get('mbstring.func_overload')!=0) {
275 $mb_error='You have enabled mbstring overloading.'
276 .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
281 * Do not use SquirrelMail with magic_quotes_* on.
283 if ( get_magic_quotes_runtime() ||
get_magic_quotes_gpc() ||
284 ( (bool) ini_get('magic_quotes_sybase') && ini_get('magic_quotes_sybase') != 'off' )
286 $magic_quotes_warning='You have enabled any one of <tt>magic_quotes_runtime</tt>, '
287 .'<tt>magic_quotes_gpc</tt> or <tt>magic_quotes_sybase</tt> in your PHP '
288 .'configuration. We recommend all those settings to be off. SquirrelMail '
289 .'may work with them on, but when experiencing stray backslashes in your mail '
290 .'or other strange behaviour, it may be advisable to turn them off.';
291 do_err($magic_quotes_warning,false);
297 echo "Checking paths...<br />\n";
299 if(!file_exists($data_dir)) {
300 // data_dir is not that important in db_setups.
301 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
302 $data_dir_error = "Data dir ($data_dir) does not exist!\n";
303 echo $IND .'<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
305 do_err("Data dir ($data_dir) does not exist!");
308 // don't check if errors
309 if(!isset($data_dir_error) && !is_dir($data_dir)) {
310 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
311 $data_dir_error = "Data dir ($data_dir) is not a directory!\n";
312 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
314 do_err("Data dir ($data_dir) is not a directory!");
317 // datadir should be executable - but no clean way to test on that
318 if(!isset($data_dir_error) && !is_writable($data_dir)) {
319 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
320 $data_dir_error = "Data dir ($data_dir) is not writable!\n";
321 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
323 do_err("Data dir ($data_dir) is not writable!");
327 if (isset($data_dir_error)) {
328 echo " Some plugins might need access to data directory.<br />\n";
330 // todo_ornot: actually write something and read it back.
331 echo $IND . "Data dir OK.<br />\n";
334 if($data_dir == $attachment_dir) {
335 echo $IND . "Attachment dir is the same as data dir.<br />\n";
336 if (isset($data_dir_error)) {
337 do_err($data_dir_error);
340 if(!file_exists($attachment_dir)) {
341 do_err("Attachment dir ($attachment_dir) does not exist!");
343 if (!is_dir($attachment_dir)) {
344 do_err("Attachment dir ($attachment_dir) is not a directory!");
346 if (!is_writable($attachment_dir)) {
347 do_err("I cannot write to attachment dir ($attachment_dir)!");
349 echo $IND . "Attachment dir OK.<br />\n";
353 echo "Checking plugins...<br />\n";
355 /* check plugins and themes */
356 //FIXME: check requirements given in plugin _info() function, such
357 // as required PHP extensions, Pear packages, other plugins, SM version, etc
358 // see development docs for list of returned info from that function
359 $bad_plugins = array(
360 'attachment_common', // Integrated into SquirrelMail 1.2 core
361 'auto_prune_sent', // Obsolete: See Proon Automatic Folder Pruning plugin
362 'compose_new_window', // Integrated into SquirrelMail 1.4 core
363 'delete_move_next', // Integrated into SquirrelMail 1.5 core
364 'disk_quota', // Obsolete: See Check Quota plugin
365 'email_priority', // Integrated into SquirrelMail 1.2 core
366 'emoticons', // Obsolete: See HTML Mail plugin
367 'focus_change', // Integrated into SquirrelMail 1.2 core
368 'folder_settings', // Integrated into SquirrelMail 1.5.1 core
369 'global_sql_addressbook', // Integrated into SquirrelMail 1.4 core
370 'hancock', // Not Working: See Random Signature Taglines plugin
371 'msg_flags', // Integrated into SquirrelMail 1.5.1 core
372 'message_source', // Added to SquirrelMail 1.4 Core Plugins (message_details)
373 'motd', // Integrated into SquirrelMail 1.2 core
374 'paginator', // Integrated into SquirrelMail 1.2 core
375 'printer_friendly', // Integrated into SquirrelMail 1.2 core
376 'procfilter', // Obsolete: See Server Side Filter plugin
377 'redhat_php_cgi_fix', // Integrated into SquirrelMail 1.1.1 core
378 'send_to_semicolon', // Integrated into SquirrelMail 1.4.1 core
379 'spamassassin', // Not working beyond SquirrelMail 1.2.7: See Spamassassin SpamFilter (Frontend) v2 plugin
380 'sqcalendar', // Added to SquirrelMail 1.2 Core Plugins (calendar)
381 'sqclock', // Integrated into SquirrelMail 1.2 core
382 'sql_squirrel_logger', // Obsolete: See Squirrel Logger plugin
383 'tmda', // Obsolete: See TMDA Tools plugin
384 'vacation', // Obsolete: See Vacation Local plugin
385 'view_as_html', // Integrated into SquirrelMail 1.5.1 core
386 'xmailer' // Integrated into SquirrelMail 1.2 core
389 if (isset($plugins[0])) {
390 foreach($plugins as $plugin) {
391 if(!file_exists(SM_PATH
.'plugins/'.$plugin)) {
392 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot find it.', FALSE);
393 } elseif (!is_readable(SM_PATH
.'plugins/'.$plugin.'/setup.php')) {
394 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot read its setup.php file.', FALSE);
395 } elseif (in_array($plugin, $bad_plugins)) {
396 do_err('You have enabled the <i>'.$plugin.'</i> plugin, which causes problems with this version of SquirrelMail. Please check the ReleaseNotes or other documentation for more information.', false);
399 // load plugin functions
400 include_once(SM_PATH
. 'functions/plugin.php');
401 // turn on output buffering in order to prevent output of new lines
403 foreach ($plugins as $name) {
406 // get output and remove whitespace
407 $output = trim(ob_get_contents());
409 // if plugins output more than newlines and spacing, stop script execution.
410 if (!empty($output)) {
411 $plugin_load_error = 'Some output is produced when plugins are loaded. Usually this means there is an error in one of the plugin setup or configuration files. The output was: '.htmlspecialchars($output);
412 do_err($plugin_load_error);
415 * Print plugin versions
417 echo $IND . "Plugin versions...<br />\n";
418 foreach ($plugins as $name) {
419 $plugin_version = get_plugin_version($name);
420 $english_name = get_plugin_requirement($name, 'english_name');
421 echo $IND . $IND . (empty($english_name) ?
$name . ' ' : $english_name . ' (' . $name . ') ') . (empty($plugin_version) ?
'??' : $plugin_version) . "<br />\n";
423 // check if this plugin has any other plugin
424 // dependencies and if they are satisfied
426 $failed_dependencies = check_plugin_dependencies($name);
427 if ($failed_dependencies === SQ_INCOMPATIBLE
) {
428 do_err($name . ' is NOT COMPATIBLE with this version of SquirrelMail', FALSE);
430 else if (is_array($failed_dependencies)) {
431 $missing_plugins = '';
432 foreach ($failed_dependencies as $depend_name => $depend_requirements) {
433 $missing_plugins .= ', ' . $depend_name . ' (version ' . $depend_requirements['version'] . ', ' . ($depend_requirements['activate'] ?
'must be activated' : 'need not be activated') . ')';
435 do_err($name . ' is missing some dependencies: ' . trim($missing_plugins, ', '), FALSE);
440 * This hook was added in 1.5.2 and 1.4.10. Each plugins should print an error
441 * message and return TRUE if there are any errors in its setup/configuration.
443 $plugin_err = boolean_hook_function('configtest', $null, 1);
445 do_err('Some plugin tests failed.');
447 echo $IND . "Plugins OK.<br />\n";
450 echo $IND . "Plugins are not enabled in config.<br />\n";
452 foreach($theme as $thm) {
453 if(!file_exists($thm['PATH'])) {
454 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').', FALSE);
455 } elseif(!is_readable($thm['PATH'])) {
456 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').', FALSE);
460 echo $IND . "Themes OK.<br />\n";
462 if ( $squirrelmail_default_language != 'en_US' ) {
463 $loc_path = SM_PATH
.'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
464 if( ! file_exists( $loc_path ) ) {
465 do_err('You have set <i>' . $squirrelmail_default_language .
466 '</i> as your default language, but I cannot find this translation (should be '.
467 'in <tt>' . $loc_path . '</tt>). Please note that you have to download translations '.
468 'separately from the main SquirrelMail package.', FALSE);
469 } elseif ( ! is_readable( $loc_path ) ) {
470 do_err('You have set <i>' . $squirrelmail_default_language .
471 '</i> as your default language, but I cannot read this translation (file '.
472 'in <tt>' . $loc_path . '</tt> unreadable).', FALSE);
474 echo $IND . "Default language OK.<br />\n";
477 echo $IND . "Default language OK.<br />\n";
480 echo $IND . "Base URL detected as: <tt>" . htmlspecialchars($test_location) .
481 "</tt> (location base " . (empty($config_location_base) ?
'autodetected' : 'set to <tt>' .
482 htmlspecialchars($config_location_base)."</tt>") . ")<br />\n";
484 /* check minimal requirements for other security options */
487 if($use_smtp_tls == 1 ||
$use_imap_tls == 1) {
488 if(!check_php_version(4,3,0)) {
489 do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
491 if(!extension_loaded('openssl')) {
492 do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
495 /* starttls extensions */
496 if($use_smtp_tls === 2 ||
$use_imap_tls === 2) {
497 if (! function_exists('stream_socket_enable_crypto')) {
498 do_err('If you want to use STARTTLS extension, you need stream_socket_enable_crypto() function from PHP 5.1.0 and newer.');
502 if ($smtp_auth_mech=='digest-md5' ||
$imap_auth_mech =='digest-md5') {
503 if (!extension_loaded('xml')) {
504 do_err('You need the PHP XML extension to use Digest-MD5 authentication!');
508 /* check outgoing mail */
510 echo "Checking outgoing mail service....<br />\n";
513 // is_executable also checks for existance, but we want to be as precise as possible with the errors
514 if(!file_exists($sendmail_path)) {
515 do_err("Location of sendmail program incorrect ($sendmail_path)!");
517 if(!is_executable($sendmail_path)) {
518 do_err("I cannot execute the sendmail program ($sendmail_path)!");
521 echo $IND . "sendmail OK<br />\n";
523 $stream = fsockopen( ($use_smtp_tls==1?
'tls://':'').$smtpServerAddress, $smtpPort,
524 $errorNumber, $errorString);
526 do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
527 "Server error: ($errorNumber) ".htmlspecialchars($errorString));
530 // check for SMTP code; should be 2xx to allow us access
531 $smtpline = fgets($stream, 1024);
532 if(((int) $smtpline{0}) > 3) {
533 do_err("Error connecting to SMTP server. Server error: ".
534 htmlspecialchars($smtpline));
537 /* smtp starttls checks */
538 if ($use_smtp_tls===2) {
539 // if something breaks, script should close smtp connection on exit.
542 fwrite($stream,"EHLO $client_ip\r\n");
546 while ($line=fgets($stream, 1024)){
547 if (preg_match("/^250(-|\s)(\S*)\s+(\S.*)/",$line,$match)||
548 preg_match("/^250(-|\s)(\S*)\s+/",$line,$match)) {
549 if (!isset($match[3])) {
550 // simple one word extension
551 $ehlo[strtoupper($match[2])]='';
553 // ehlo-keyword + ehlo-param
554 $ehlo[strtoupper($match[2])]=trim($match[3]);
556 if ($match[1]==' ') {
568 do_err('SMTP EHLO failed. You need ESMTP support for SMTP STARTTLS');
569 } elseif (!array_key_exists('STARTTLS',$ehlo)) {
570 do_err('STARTTLS support is not declared by SMTP server.');
573 fwrite($stream,"STARTTLS\r\n");
574 $starttls_response=fgets($stream, 1024);
575 if ($starttls_response[0]!=2) {
576 $starttls_cmd_err = 'SMTP STARTTLS failed. Server replied: '
577 .htmlspecialchars($starttls_response);
578 do_err($starttls_cmd_err);
579 } elseif(! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT
)) {
580 do_err('Failed to enable encryption on SMTP STARTTLS connection.');
582 echo $IND . "SMTP STARTTLS extension looks OK.<br />\n";
584 // According to RFC we should second ehlo call here.
587 fputs($stream, 'QUIT');
589 echo $IND . 'SMTP server OK (<tt><small>'.
590 trim(htmlspecialchars($smtpline))."</small></tt>)<br />\n";
592 /* POP before SMTP */
593 if($pop_before_smtp) {
594 $stream = fsockopen($smtpServerAddress, 110, $err_no, $err_str);
596 do_err("Error connecting to POP Server ($smtpServerAddress:110) "
597 . $err_no . ' : ' . htmlspecialchars($err_str));
600 $tmp = fgets($stream, 1024);
601 if (substr($tmp, 0, 3) != '+OK') {
602 do_err("Error connecting to POP Server ($smtpServerAddress:110)"
603 . ' '.htmlspecialchars($tmp));
605 fputs($stream, 'QUIT');
607 echo $IND . "POP-before-SMTP OK.<br />\n";
612 * Check the IMAP server
614 echo "Checking IMAP service....<br />\n";
616 /** Can we open a connection? */
617 $stream = fsockopen( ($use_imap_tls==1?
'tls://':'').$imapServerAddress, $imapPort,
618 $errorNumber, $errorString);
620 do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
621 "Server error: ($errorNumber) ".
622 htmlspecialchars($errorString));
625 /** Is the first response 'OK'? */
626 $imapline = fgets($stream, 1024);
627 if(substr($imapline, 0,4) != '* OK') {
628 do_err('Error connecting to IMAP server. Server error: '.
629 htmlspecialchars($imapline));
632 echo $IND . 'IMAP server ready (<tt><small>'.
633 htmlspecialchars(trim($imapline))."</small></tt>)<br />\n";
635 /** Check capabilities */
636 fputs($stream, "A001 CAPABILITY\r\n");
638 while ($line=fgets($stream, 1024)){
639 if (preg_match("/A001.*/",$line)) {
646 /* don't display capabilities before STARTTLS */
647 if ($use_imap_tls===2 && stristr($capline, 'STARTTLS') === false) {
648 do_err('Your server doesn\'t support STARTTLS.');
649 } elseif($use_imap_tls===2) {
650 /* try starting starttls */
651 fwrite($stream,"A002 STARTTLS\r\n");
652 $starttls_line=fgets($stream, 1024);
653 if (! preg_match("/^A002 OK.*/i",$starttls_line)) {
654 $imap_starttls_err = 'IMAP STARTTLS failed. Server replied: '
655 .htmlspecialchars($starttls_line);
656 do_err($imap_starttls_err);
657 } elseif (! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT
)) {
658 do_err('Failed to enable encryption on IMAP connection.');
660 echo $IND . "IMAP STARTTLS extension looks OK.<br />\n";
663 // get new capability line
664 fwrite($stream,"A003 CAPABILITY\r\n");
666 while ($line=fgets($stream, 1024)){
667 if (preg_match("/A003.*/",$line)) {
675 echo $IND . 'Capabilities: <tt>'.htmlspecialchars($capline)."</tt><br />\n";
677 if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
678 do_err('Your server doesn\'t allow plaintext logins. '.
679 'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
680 'in the SquirrelMail configuration.', FALSE);
683 if (stristr($capline, 'XMAGICTRASH') !== false) {
684 $magic_trash = 'It looks like IMAP_MOVE_EXPUNGE_TO_TRASH option is turned on '
685 .'in your Courier IMAP configuration. Courier does not provide tools that '
686 .'allow to detect folder used for Trash or commands are not documented. '
687 .'SquirrelMail can\'t detect special trash folder. SquirrelMail manages '
688 .'all message deletion or move operations internally and '
689 .'IMAP_MOVE_EXPUNGE_TO_TRASH option can cause errors in message and '
690 .'folder management operations. Please turn off IMAP_MOVE_EXPUNGE_TO_TRASH '
691 .'option in Courier imapd configuration.';
692 do_err($magic_trash,false);
695 /* add warning about IMAP delivery */
696 if (stristr($capline, 'XCOURIEROUTBOX') !== false) {
697 $courier_outbox = 'OUTBOX setting is enabled in your Courier imapd '
698 .'configuration. SquirrelMail uses standard SMTP protocol or sendmail '
699 .'binary to send emails. Courier IMAP delivery method is not supported'
700 .' and can create duplicate email messages.';
701 do_err($courier_outbox,false);
704 /** OK, close connection */
705 fputs($stream, "A004 LOGOUT\r\n");
708 echo "Checking internationalization (i18n) settings...<br />\n";
709 echo "$IND gettext - ";
710 if (function_exists('gettext')) {
711 echo 'Gettext functions are available.'
712 .' On some systems you must have appropriate system locales compiled.'
715 /* optional setlocale() tests. Should work only on glibc systems. */
716 if (sqgetGlobalVar('testlocales',$testlocales,SQ_GET
)) {
717 include_once(SM_PATH
. 'include/languages.php');
718 echo $IND . $IND . 'Testing translations:<br>';
719 foreach ($languages as $lang_code => $lang_data) {
720 /* don't test aliases */
721 if (isset($lang_data['NAME'])) {
722 /* locale can be $lang_code or $lang_data['LOCALE'] */
723 if (isset($lang_data['LOCALE'])) {
724 $setlocale = $lang_data['LOCALE'];
726 $setlocale = $lang_code;
728 /* prepare information about tested locales */
729 if (is_array($setlocale)) {
730 $display_locale = implode(', ',$setlocale);
731 $locale_count = count($setlocale);
733 $display_locale = $setlocale;
736 $tested_locales_msg = 'Tested '.htmlspecialchars($display_locale).' '
737 .($locale_count>1 ?
'locales':'locale'). '.';
739 echo $IND . $IND .$IND . $lang_data['NAME'].' (' .$lang_code. ') - ';
740 $retlocale = sq_setlocale(LC_ALL
,$setlocale);
741 if (is_bool($retlocale)) {
742 echo '<font color="red">unsupported</font>. ';
743 echo $tested_locales_msg;
747 .' setlocale() returned "'.htmlspecialchars($retlocale).'"';
752 echo $IND . $IND . '<a href="configtest.php">Don\'t test translations</a>';
754 echo $IND . $IND . '<a href="configtest.php?testlocales=1">Test translations</a>. '
755 .'This test is not accurate and might work only on some systems.'
759 /* end of translation tests */
761 echo 'Gettext functions are unavailable.'
762 .' SquirrelMail will use slower internal gettext functions.'
765 echo "$IND mbstring - ";
766 if (function_exists('mb_detect_encoding')) {
767 echo "Mbstring functions are available.<br />\n";
769 echo 'Mbstring functions are unavailable.'
770 ." Japanese translation won't work.<br />\n";
772 echo "$IND recode - ";
773 if (function_exists('recode')) {
774 echo "Recode functions are available.<br />\n";
775 } elseif (isset($use_php_recode) && $use_php_recode) {
776 echo "Recode functions are unavailable.<br />\n";
777 do_err('Your configuration requires recode support, but recode support is missing.');
779 echo "Recode functions are unavailable.<br />\n";
781 echo "$IND iconv - ";
782 if (function_exists('iconv')) {
783 echo "Iconv functions are available.<br />\n";
784 } elseif (isset($use_php_iconv) && $use_php_iconv) {
785 echo "Iconv functions are unavailable.<br />\n";
786 do_err('Your configuration requires iconv support, but iconv support is missing.');
788 echo "Iconv functions are unavailable.<br />\n";
790 // same test as in include/init.php + date_default_timezone_set check
791 echo "$IND timezone - ";
792 if ( (!ini_get('safe_mode')) ||
function_exists('date_default_timezone_set') ||
793 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
794 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars')) ) {
795 echo "Webmail users can change their time zone settings. \n";
797 echo "Webmail users can't change their time zone settings. \n";
799 if (isset($_ENV['TZ'])) {
800 echo 'Default time zone is '.htmlspecialchars($_ENV['TZ']);
802 echo 'Current time zone is '.date('T');
807 echo "Checking database functions...<br />\n";
808 if($addrbook_dsn ||
$prefs_dsn ||
$addrbook_global_dsn) {
809 @include_once
('DB.php');
810 if (class_exists('DB')) {
811 echo "$IND PHP Pear DB support is present.<br />\n";
813 'dbase' => 'dbase_open',
814 'fbsql' => 'fbsql_connect',
815 'interbase' => 'ibase_connect',
816 'informix' => 'ifx_connect',
817 'msql' => 'msql_connect',
818 'mssql' => 'mssql_connect',
819 'mysql' => 'mysql_connect',
820 'mysqli' => 'mysqli_connect',
821 'oci8' => 'ocilogon',
822 'odbc' => 'odbc_connect',
823 'pgsql' => 'pg_connect',
824 'sqlite' => 'sqlite_open',
825 'sybase' => 'sybase_connect'
830 $dsns['preferences'] = $prefs_dsn;
833 $dsns['addressbook'] = $addrbook_dsn;
835 if($addrbook_global_dsn) {
836 $dsns['global addressbook'] = $addrbook_global_dsn;
839 foreach($dsns as $type => $dsn) {
840 $aDsn = explode(':', $dsn);
841 $dbtype = array_shift($aDsn);
842 if(isset($db_functions[$dbtype]) && function_exists($db_functions[$dbtype])) {
843 echo "$IND$dbtype database support present.<br />\n";
845 // now, test this interface:
847 $dbh = DB
::connect($dsn, true);
848 if (DB
::isError($dbh)) {
849 do_err('Database error: '. htmlspecialchars(DB
::errorMessage($dbh)) .
850 ' in ' .$type .' DSN.');
853 echo "$IND$type database connect successful.<br />\n";
856 do_err($dbtype.' database support not present!');
860 $db_error='Required PHP PEAR DB support is not available.'
861 .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
862 .' The include path is now:<tt>' . ini_get('include_path') . '</tt>.';
866 echo $IND."not using database functionality.<br />\n";
870 echo "Checking LDAP functions...<br />\n";
871 if( empty($ldap_server) ) {
872 echo $IND."not using LDAP functionality.<br />\n";
874 if ( !function_exists('ldap_connect') ) {
875 do_err('Required LDAP support is not available.');
877 echo "$IND LDAP support present.<br />\n";
878 foreach ( $ldap_server as $param ) {
880 $linkid = @ldap_connect
($param['host'], (empty($param['port']) ?
389 : $param['port']) );
883 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
885 if ( !empty($param['protocol']) &&
886 !ldap_set_option($linkid, LDAP_OPT_PROTOCOL_VERSION
, $param['protocol']) ) {
887 do_err('Unable to set LDAP protocol');
890 if ( empty($param['binddn']) ) {
891 $bind = @ldap_bind
($linkid);
893 $bind = @ldap_bind
($param['binddn'], $param['bindpw']);
897 echo "$IND LDAP Bind Successful <br />";
899 do_err('Unable to Bind to LDAP Server');
902 @ldap_close
($linkid);
904 do_err('Connection to LDAP failed');
910 echo '<hr width="75%" align="center">';
911 echo '<h2 align="center">Summary</h2>';
912 $footer = '<hr width="75%" align="center">';
914 echo '<p>No fatal errors were found, but there was at least 1 warning. Please check the flagged issue(s) carefully, as correcting them may prevent erratic, undefined, or incorrect behavior (or flat out breakage).</p>';
918 <p
>Congratulations
, your SquirrelMail setup looks fine to me
!</p
>
920 <p
><a href
="login.php">Login now
</a
></p
>