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 script could really use some restructuring as it has grown quite rapidly
19 // but is not very 'clean'. Feel free to get some structure into this thing.
21 /** force verbose error reporting and turn on display of errors */
22 error_reporting(E_ALL
);
23 ini_set('display_errors',1);
25 /** Blockcopy from init.php. Cleans globals. */
26 if ((bool) ini_get('register_globals') &&
27 strtolower(ini_get('register_globals'))!='off') {
29 * Remove all globals that are not reserved by PHP
30 * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
32 foreach ($GLOBALS as $key => $value) {
34 case 'HTTP_POST_VARS':
38 case 'HTTP_COOKIE_VARS':
40 case 'HTTP_SERVER_VARS':
44 case 'HTTP_POST_FILES':
47 case 'HTTP_SESSION_VARS':
54 unset($GLOBALS[$key]);
57 // Unset variables used in foreach
58 unset($GLOBALS['key']);
59 unset($GLOBALS['value']);
64 * Displays error messages and warnings
65 * @param string $str message
66 * @param boolean $fatal fatal error or only warning
68 function do_err($str, $fatal = TRUE) {
69 global $IND, $warnings;
70 $level = $fatal ?
'FATAL ERROR:' : 'WARNING:';
71 echo '<p>'.$IND.'<font color="red"><b>' . $level . '</b></font> ' .$str. "</p>\n";
73 echo '</body></html>';
82 define('SM_PATH', '../');
83 /** load minimal function set */
84 require(SM_PATH
. 'include/constants.php');
85 require(SM_PATH
. 'functions/global.php');
86 require(SM_PATH
. 'functions/strings.php');
87 $SQM_INTERNAL_VERSION = explode('.', SM_VERSION
, 3);
88 $SQM_INTERNAL_VERSION[2] = intval($SQM_INTERNAL_VERSION[2]);
90 /** set default value in order to block remote access */
91 $allow_remote_configtest=false;
93 /** Load all configuration files before output begins */
95 /* load default configuration */
96 require(SM_PATH
. 'config/config_default.php');
97 /* reset arrays in default configuration */
98 $ldap_server = array();
102 $theme[0]['PATH'] = SM_PATH
. 'themes/default_theme.php';
103 $theme[0]['NAME'] = 'Default';
104 $aTemplateSet = array();
105 $aTemplateSet[0]['ID'] = 'default';
106 $aTemplateSet[0]['NAME'] = 'Default';
107 /* load site configuration */
108 if (file_exists(SM_PATH
. 'config/config.php')) {
109 require(SM_PATH
. 'config/config.php');
111 /* load local configuration overrides */
112 if (file_exists(SM_PATH
. 'config/config_local.php')) {
113 require(SM_PATH
. 'config/config_local.php');
117 global $disable_plugins;
118 $squirrelmail_plugin_hooks = array();
119 if (!$disable_plugins && file_exists(SM_PATH
. 'config/plugin_hooks.php')) {
120 require(SM_PATH
. 'config/plugin_hooks.php');
123 /** Warning counter */
127 $IND = str_repeat(' ',4);
130 * get_location starts session and must be run before output is started.
132 $test_location = get_location();
134 ?
><!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
135 "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
138 <meta name
="robots" content
="noindex,nofollow">
139 <title
>SquirrelMail configtest
</title
>
142 <h1
>SquirrelMail configtest
</h1
>
144 <p
>This script will
try to check some aspects of your SquirrelMail configuration
145 and point you to errors whereever it can find them
. You need to go run
<tt
>conf
.pl
</tt
>
146 in the
<tt
>config
/</tt
> directory first before you run this script
.</p
>
150 $included = array_map('basename', get_included_files() );
151 if(!in_array('config.php', $included)) {
152 if(!file_exists(SM_PATH
. 'config/config.php')) {
153 do_err('Config file '.SM_PATH
. 'config/config.php does not exist!<br />'.
154 'You need to run <tt>conf.pl</tt> first.');
156 do_err('Could not read '.SM_PATH
.'config/config.php! Check file permissions.');
158 if(!in_array('strings.php', $included)) {
159 do_err('Could not include '.SM_PATH
.'functions/strings.php!<br />'.
160 'Check permissions on that file.');
163 /* Block remote use of script */
164 if (! $allow_remote_configtest) {
165 sqGetGlobalVar('REMOTE_ADDR',$client_ip,SQ_SERVER
);
166 sqGetGlobalVar('SERVER_ADDR',$server_ip,SQ_SERVER
);
168 if ((! isset($client_ip) ||
$client_ip!='127.0.0.1') &&
169 (! isset($client_ip) ||
! isset($server_ip) ||
$client_ip!=$server_ip)) {
170 do_err('Enable "Allow remote configtest" option in squirrelmail configuration in order to use this script.');
174 echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" . SM_VERSION
. "</b></td></tr>\n" .
175 '<tr><td>Config file version:</td><td><b>' . $config_version . "</b></td></tr>\n" .
176 '<tr><td>Config file last modified:</td><td><b>' .
177 date ('d F Y H:i:s', filemtime(SM_PATH
. 'config/config.php')) .
178 "</b></td></tr>\n</table>\n</p>\n\n";
180 /* check $config_version */
181 if ($config_version!='1.5.0') {
182 do_err('Configuration file version does not match required version. Please update your configuration file.');
186 /* checking PHP specs */
188 echo "Checking PHP configuration...<br />\n";
190 if(!check_php_version(4,1,0)) {
191 do_err('Insufficient PHP version: '. PHP_VERSION
. '! Minimum required: 4.1.0');
194 echo $IND . 'PHP version ' . PHP_VERSION
. ' OK. (You have: ' . phpversion() . ". Minimum: 4.1.0)<br />\n";
196 /* register_globals check: test for boolean false and any string that is not equal to 'off' */
198 if ((bool) ini_get('register_globals') &&
199 strtolower(ini_get('register_globals'))!='off') {
200 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);
204 /* variables_order check */
206 // FIXME(?): Hmm, how do we distinguish between when an ini setting is
207 // not available (ini_set() returns empty string) and when
208 // the administrator set the value to an empty string? The
209 // latter is sure to be highly rare, so for now, just assume
210 // that empty value means the setting isn't even available
211 // (could also check PHP version when this setting was implemented)
212 // although, we'll also warn the user if it is empty, with
214 $variables_order = strtoupper(ini_get('variables_order'));
215 if (empty($variables_order))
216 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);
217 else if (strpos($variables_order, 'G') === FALSE
218 ||
strpos($variables_order, 'P') === FALSE
219 ||
strpos($variables_order, 'C') === FALSE
220 ||
strpos($variables_order, 'S') === FALSE) {
221 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);
223 echo $IND . "variables_order OK: $variables_order.<br />\n";
227 /* gpc_order check (removed from PHP as of v5.0) */
229 if (!check_php_version(5)) {
230 // FIXME(?): Hmm, how do we distinguish between when an ini setting is
231 // not available (ini_set() returns empty string) and when
232 // the administrator set the value to an empty string? The
233 // latter is sure to be highly rare, so for now, just assume
234 // that empty value means the setting isn't even available
235 // (could also check PHP version when this setting was implemented)
236 // although, we'll also warn the user if it is empty, with
238 $gpc_order = strtoupper(ini_get('gpc_order'));
239 if (empty($gpc_order))
240 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);
241 else if (strpos($gpc_order, 'G') === FALSE
242 ||
strpos($gpc_order, 'P') === FALSE
243 ||
strpos($gpc_order, 'C') === FALSE) {
244 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);
246 echo $IND . "gpc_order OK: $gpc_order.<br />\n";
251 /* check PHP extensions */
253 $php_exts = array('session','pcre');
254 $diff = array_diff($php_exts, get_loaded_extensions());
256 do_err('Required PHP extensions missing: '.implode(', ',$diff) );
259 echo $IND . "PHP extensions OK.<br />\n";
261 /* dangerous php settings */
263 * mbstring.func_overload allows to replace original string and regexp functions
264 * with their equivalents from php mbstring extension. It causes problems when
265 * scripts analyze 8bit strings byte after byte or use 8bit strings in regexp tests.
266 * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
267 * and .htaccess files (php 4.3.5).
269 if (function_exists('mb_internal_encoding') &&
270 check_php_version(4,2,0) &&
271 (int)ini_get('mbstring.func_overload')!=0) {
272 $mb_error='You have enabled mbstring overloading.'
273 .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
278 * Do not use SquirrelMail with magic_quotes_* on.
280 if ( get_magic_quotes_runtime() ||
get_magic_quotes_gpc() ||
281 ( (bool) ini_get('magic_quotes_sybase') && ini_get('magic_quotes_sybase') != 'off' )
283 $magic_quotes_warning='You have enabled any one of <tt>magic_quotes_runtime</tt>, '
284 .'<tt>magic_quotes_gpc</tt> or <tt>magic_quotes_sybase</tt> in your PHP '
285 .'configuration. We recommend all those settings to be off. SquirrelMail '
286 .'may work with them on, but when experiencing stray backslashes in your mail '
287 .'or other strange behaviour, it may be advisable to turn them off.';
288 do_err($magic_quotes_warning,false);
294 echo "Checking paths...<br />\n";
296 if(!file_exists($data_dir)) {
297 // data_dir is not that important in db_setups.
298 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
299 $data_dir_error = "Data dir ($data_dir) does not exist!\n";
300 echo $IND .'<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
302 do_err("Data dir ($data_dir) does not exist!");
305 // don't check if errors
306 if(!isset($data_dir_error) && !is_dir($data_dir)) {
307 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
308 $data_dir_error = "Data dir ($data_dir) is not a directory!\n";
309 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
311 do_err("Data dir ($data_dir) is not a directory!");
314 // datadir should be executable - but no clean way to test on that
315 if(!isset($data_dir_error) && !is_writable($data_dir)) {
316 if (isset($prefs_dsn) && ! empty($prefs_dsn)) {
317 $data_dir_error = "Data dir ($data_dir) is not writable!\n";
318 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
320 do_err("Data dir ($data_dir) is not writable!");
324 if (isset($data_dir_error)) {
325 echo " Some plugins might need access to data directory.<br />\n";
327 // todo_ornot: actually write something and read it back.
328 echo $IND . "Data dir OK.<br />\n";
331 if($data_dir == $attachment_dir) {
332 echo $IND . "Attachment dir is the same as data dir.<br />\n";
333 if (isset($data_dir_error)) {
334 do_err($data_dir_error);
337 if(!file_exists($attachment_dir)) {
338 do_err("Attachment dir ($attachment_dir) does not exist!");
340 if (!is_dir($attachment_dir)) {
341 do_err("Attachment dir ($attachment_dir) is not a directory!");
343 if (!is_writable($attachment_dir)) {
344 do_err("I cannot write to attachment dir ($attachment_dir)!");
346 echo $IND . "Attachment dir OK.<br />\n";
350 echo "Checking plugins...<br />\n";
352 /* check plugins and themes */
353 //FIXME: check requirements given in plugin _info() function, such
354 // as required PHP extensions, Pear packages, other plugins, SM version, etc
355 // see development docs for list of returned info from that function
356 $bad_plugins = array(
357 'attachment_common', // Integrated into SquirrelMail 1.2 core
358 'auto_prune_sent', // Obsolete: See Proon Automatic Folder Pruning plugin
359 'compose_new_window', // Integrated into SquirrelMail 1.4 core
360 'delete_move_next', // Integrated into SquirrelMail 1.5 core
361 'disk_quota', // Obsolete: See Check Quota plugin
362 'email_priority', // Integrated into SquirrelMail 1.2 core
363 'emoticons', // Obsolete: See HTML Mail plugin
364 'focus_change', // Integrated into SquirrelMail 1.2 core
365 'folder_settings', // Integrated into SquirrelMail 1.5.1 core
366 'global_sql_addressbook', // Integrated into SquirrelMail 1.4 core
367 'hancock', // Not Working: See Random Signature Taglines plugin
368 'msg_flags', // Integrated into SquirrelMail 1.5.1 core
369 'message_source', // Added to SquirrelMail 1.4 Core Plugins (message_details)
370 'motd', // Integrated into SquirrelMail 1.2 core
371 'paginator', // Integrated into SquirrelMail 1.2 core
372 'printer_friendly', // Integrated into SquirrelMail 1.2 core
373 'procfilter', // Obsolete: See Server Side Filter plugin
374 'redhat_php_cgi_fix', // Integrated into SquirrelMail 1.1.1 core
375 'send_to_semicolon', // Integrated into SquirrelMail 1.4.1 core
376 'spamassassin', // Not working beyond SquirrelMail 1.2.7: See Spamassassin SpamFilter (Frontend) v2 plugin
377 'sqcalendar', // Added to SquirrelMail 1.2 Core Plugins (calendar)
378 'sqclock', // Integrated into SquirrelMail 1.2 core
379 'sql_squirrel_logger', // Obsolete: See Squirrel Logger plugin
380 'tmda', // Obsolete: See TMDA Tools plugin
381 'vacation', // Obsolete: See Vacation Local plugin
382 'view_as_html', // Integrated into SquirrelMail 1.5.1 core
383 'xmailer' // Integrated into SquirrelMail 1.2 core
386 if (isset($plugins[0])) {
387 foreach($plugins as $plugin) {
388 if(!file_exists(SM_PATH
.'plugins/'.$plugin)) {
389 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot find it.', FALSE);
390 } elseif (!is_readable(SM_PATH
.'plugins/'.$plugin.'/setup.php')) {
391 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot read its setup.php file.', FALSE);
392 } elseif (in_array($plugin, $bad_plugins)) {
393 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);
396 // load plugin functions
397 include_once(SM_PATH
. 'functions/plugin.php');
398 // turn on output buffering in order to prevent output of new lines
400 foreach ($plugins as $name) {
403 // get output and remove whitespace
404 $output = trim(ob_get_contents());
406 // if plugins output more than newlines and spacing, stop script execution.
407 if (!empty($output)) {
408 $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);
409 do_err($plugin_load_error);
412 * Print plugin versions
414 echo $IND . "Plugin versions...<br />\n";
415 foreach ($plugins as $name) {
416 $plugin_version = get_plugin_version($name);
417 echo $IND . $IND . $name . ' ' . (empty($plugin_version) ?
'??' : $plugin_version) . "<br />\n";
419 // check if this plugin has any other plugin
420 // dependencies and if they are satisfied
422 $failed_dependencies = check_plugin_dependencies($name);
423 if ($failed_dependencies === SQ_INCOMPATIBLE
) {
424 do_err($name . ' is NOT COMPATIBLE with this version of SquirrelMail', FALSE);
426 else if (is_array($failed_dependencies)) {
427 $missing_plugins = '';
428 foreach ($failed_dependencies as $depend_name => $depend_requirements) {
429 $missing_plugins .= ', ' . $depend_name . ' (version ' . $depend_requirements['version'] . ', ' . ($depend_requirements['activate'] ?
'must be activated' : 'need not be activated') . ')';
431 do_err($name . ' is missing some dependencies: ' . trim($missing_plugins, ', '), FALSE);
436 * This hook was added in 1.5.2 and 1.4.10. Each plugins should print an error
437 * message and return TRUE if there are any errors in its setup/configuration.
439 $plugin_err = boolean_hook_function('configtest', $null, 1);
441 do_err('Some plugin tests failed.');
443 echo $IND . "Plugins OK.<br />\n";
446 echo $IND . "Plugins are not enabled in config.<br />\n";
448 foreach($theme as $thm) {
449 if(!file_exists($thm['PATH'])) {
450 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').', FALSE);
451 } elseif(!is_readable($thm['PATH'])) {
452 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').', FALSE);
456 echo $IND . "Themes OK.<br />\n";
458 if ( $squirrelmail_default_language != 'en_US' ) {
459 $loc_path = SM_PATH
.'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
460 if( ! file_exists( $loc_path ) ) {
461 do_err('You have set <i>' . $squirrelmail_default_language .
462 '</i> as your default language, but I cannot find this translation (should be '.
463 'in <tt>' . $loc_path . '</tt>). Please note that you have to download translations '.
464 'separately from the main SquirrelMail package.', FALSE);
465 } elseif ( ! is_readable( $loc_path ) ) {
466 do_err('You have set <i>' . $squirrelmail_default_language .
467 '</i> as your default language, but I cannot read this translation (file '.
468 'in <tt>' . $loc_path . '</tt> unreadable).', FALSE);
470 echo $IND . "Default language OK.<br />\n";
473 echo $IND . "Default language OK.<br />\n";
476 echo $IND . "Base URL detected as: <tt>" . htmlspecialchars($test_location) .
477 "</tt> (location base " . (empty($config_location_base) ?
'autodetected' : 'set to <tt>' .
478 htmlspecialchars($config_location_base)."</tt>") . ")<br />\n";
480 /* check minimal requirements for other security options */
483 if($use_smtp_tls == 1 ||
$use_imap_tls == 1) {
484 if(!check_php_version(4,3,0)) {
485 do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
487 if(!extension_loaded('openssl')) {
488 do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
491 /* starttls extensions */
492 if($use_smtp_tls === 2 ||
$use_imap_tls === 2) {
493 if (! function_exists('stream_socket_enable_crypto')) {
494 do_err('If you want to use STARTTLS extension, you need stream_socket_enable_crypto() function from PHP 5.1.0 and newer.');
498 if ($smtp_auth_mech=='digest-md5' ||
$imap_auth_mech =='digest-md5') {
499 if (!extension_loaded('xml')) {
500 do_err('You need the PHP XML extension to use Digest-MD5 authentication!');
504 /* check outgoing mail */
506 echo "Checking outgoing mail service....<br />\n";
509 // is_executable also checks for existance, but we want to be as precise as possible with the errors
510 if(!file_exists($sendmail_path)) {
511 do_err("Location of sendmail program incorrect ($sendmail_path)!");
513 if(!is_executable($sendmail_path)) {
514 do_err("I cannot execute the sendmail program ($sendmail_path)!");
517 echo $IND . "sendmail OK<br />\n";
519 $stream = fsockopen( ($use_smtp_tls==1?
'tls://':'').$smtpServerAddress, $smtpPort,
520 $errorNumber, $errorString);
522 do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
523 "Server error: ($errorNumber) ".htmlspecialchars($errorString));
526 // check for SMTP code; should be 2xx to allow us access
527 $smtpline = fgets($stream, 1024);
528 if(((int) $smtpline{0}) > 3) {
529 do_err("Error connecting to SMTP server. Server error: ".
530 htmlspecialchars($smtpline));
533 /* smtp starttls checks */
534 if ($use_smtp_tls===2) {
535 // if something breaks, script should close smtp connection on exit.
538 fwrite($stream,"EHLO $client_ip\r\n");
542 while ($line=fgets($stream, 1024)){
543 if (preg_match("/^250(-|\s)(\S*)\s+(\S.*)/",$line,$match)||
544 preg_match("/^250(-|\s)(\S*)\s+/",$line,$match)) {
545 if (!isset($match[3])) {
546 // simple one word extension
547 $ehlo[strtoupper($match[2])]='';
549 // ehlo-keyword + ehlo-param
550 $ehlo[strtoupper($match[2])]=trim($match[3]);
552 if ($match[1]==' ') {
564 do_err('SMTP EHLO failed. You need ESMTP support for SMTP STARTTLS');
565 } elseif (!array_key_exists('STARTTLS',$ehlo)) {
566 do_err('STARTTLS support is not declared by SMTP server.');
569 fwrite($stream,"STARTTLS\r\n");
570 $starttls_response=fgets($stream, 1024);
571 if ($starttls_response[0]!=2) {
572 $starttls_cmd_err = 'SMTP STARTTLS failed. Server replied: '
573 .htmlspecialchars($starttls_response);
574 do_err($starttls_cmd_err);
575 } elseif(! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT
)) {
576 do_err('Failed to enable encryption on SMTP STARTTLS connection.');
578 echo $IND . "SMTP STARTTLS extension looks OK.<br />\n";
580 // According to RFC we should second ehlo call here.
583 fputs($stream, 'QUIT');
585 echo $IND . 'SMTP server OK (<tt><small>'.
586 trim(htmlspecialchars($smtpline))."</small></tt>)<br />\n";
588 /* POP before SMTP */
589 if($pop_before_smtp) {
590 $stream = fsockopen($smtpServerAddress, 110, $err_no, $err_str);
592 do_err("Error connecting to POP Server ($smtpServerAddress:110) "
593 . $err_no . ' : ' . htmlspecialchars($err_str));
596 $tmp = fgets($stream, 1024);
597 if (substr($tmp, 0, 3) != '+OK') {
598 do_err("Error connecting to POP Server ($smtpServerAddress:110)"
599 . ' '.htmlspecialchars($tmp));
601 fputs($stream, 'QUIT');
603 echo $IND . "POP-before-SMTP OK.<br />\n";
608 * Check the IMAP server
610 echo "Checking IMAP service....<br />\n";
612 /** Can we open a connection? */
613 $stream = fsockopen( ($use_imap_tls==1?
'tls://':'').$imapServerAddress, $imapPort,
614 $errorNumber, $errorString);
616 do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
617 "Server error: ($errorNumber) ".
618 htmlspecialchars($errorString));
621 /** Is the first response 'OK'? */
622 $imapline = fgets($stream, 1024);
623 if(substr($imapline, 0,4) != '* OK') {
624 do_err('Error connecting to IMAP server. Server error: '.
625 htmlspecialchars($imapline));
628 echo $IND . 'IMAP server ready (<tt><small>'.
629 htmlspecialchars(trim($imapline))."</small></tt>)<br />\n";
631 /** Check capabilities */
632 fputs($stream, "A001 CAPABILITY\r\n");
634 while ($line=fgets($stream, 1024)){
635 if (preg_match("/A001.*/",$line)) {
642 /* don't display capabilities before STARTTLS */
643 if ($use_imap_tls===2 && stristr($capline, 'STARTTLS') === false) {
644 do_err('Your server doesn\'t support STARTTLS.');
645 } elseif($use_imap_tls===2) {
646 /* try starting starttls */
647 fwrite($stream,"A002 STARTTLS\r\n");
648 $starttls_line=fgets($stream, 1024);
649 if (! preg_match("/^A002 OK.*/i",$starttls_line)) {
650 $imap_starttls_err = 'IMAP STARTTLS failed. Server replied: '
651 .htmlspecialchars($starttls_line);
652 do_err($imap_starttls_err);
653 } elseif (! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT
)) {
654 do_err('Failed to enable encryption on IMAP connection.');
656 echo $IND . "IMAP STARTTLS extension looks OK.<br />\n";
659 // get new capability line
660 fwrite($stream,"A003 CAPABILITY\r\n");
662 while ($line=fgets($stream, 1024)){
663 if (preg_match("/A003.*/",$line)) {
671 echo $IND . 'Capabilities: <tt>'.htmlspecialchars($capline)."</tt><br />\n";
673 if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
674 do_err('Your server doesn\'t allow plaintext logins. '.
675 'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
676 'in the SquirrelMail configuration.', FALSE);
679 if (stristr($capline, 'XMAGICTRASH') !== false) {
680 $magic_trash = 'It looks like IMAP_MOVE_EXPUNGE_TO_TRASH option is turned on '
681 .'in your Courier IMAP configuration. Courier does not provide tools that '
682 .'allow to detect folder used for Trash or commands are not documented. '
683 .'SquirrelMail can\'t detect special trash folder. SquirrelMail manages '
684 .'all message deletion or move operations internally and '
685 .'IMAP_MOVE_EXPUNGE_TO_TRASH option can cause errors in message and '
686 .'folder management operations. Please turn off IMAP_MOVE_EXPUNGE_TO_TRASH '
687 .'option in Courier imapd configuration.';
688 do_err($magic_trash,false);
691 /* add warning about IMAP delivery */
692 if (stristr($capline, 'XCOURIEROUTBOX') !== false) {
693 $courier_outbox = 'OUTBOX setting is enabled in your Courier imapd '
694 .'configuration. SquirrelMail uses standard SMTP protocol or sendmail '
695 .'binary to send emails. Courier IMAP delivery method is not supported'
696 .' and can create duplicate email messages.';
697 do_err($courier_outbox,false);
700 /** OK, close connection */
701 fputs($stream, "A004 LOGOUT\r\n");
704 echo "Checking internationalization (i18n) settings...<br />\n";
705 echo "$IND gettext - ";
706 if (function_exists('gettext')) {
707 echo 'Gettext functions are available.'
708 .' On some systems you must have appropriate system locales compiled.'
711 /* optional setlocale() tests. Should work only on glibc systems. */
712 if (sqgetGlobalVar('testlocales',$testlocales,SQ_GET
)) {
713 include_once(SM_PATH
. 'include/languages.php');
714 echo $IND . $IND . 'Testing translations:<br>';
715 foreach ($languages as $lang_code => $lang_data) {
716 /* don't test aliases */
717 if (isset($lang_data['NAME'])) {
718 /* locale can be $lang_code or $lang_data['LOCALE'] */
719 if (isset($lang_data['LOCALE'])) {
720 $setlocale = $lang_data['LOCALE'];
722 $setlocale = $lang_code;
724 /* prepare information about tested locales */
725 if (is_array($setlocale)) {
726 $display_locale = implode(', ',$setlocale);
727 $locale_count = count($setlocale);
729 $display_locale = $setlocale;
732 $tested_locales_msg = 'Tested '.htmlspecialchars($display_locale).' '
733 .($locale_count>1 ?
'locales':'locale'). '.';
735 echo $IND . $IND .$IND . $lang_data['NAME'].' (' .$lang_code. ') - ';
736 $retlocale = sq_setlocale(LC_ALL
,$setlocale);
737 if (is_bool($retlocale)) {
738 echo '<font color="red">unsupported</font>. ';
739 echo $tested_locales_msg;
743 .' setlocale() returned "'.htmlspecialchars($retlocale).'"';
748 echo $IND . $IND . '<a href="configtest.php">Don\'t test translations</a>';
750 echo $IND . $IND . '<a href="configtest.php?testlocales=1">Test translations</a>. '
751 .'This test is not accurate and might work only on some systems.'
755 /* end of translation tests */
757 echo 'Gettext functions are unavailable.'
758 .' SquirrelMail will use slower internal gettext functions.'
761 echo "$IND mbstring - ";
762 if (function_exists('mb_detect_encoding')) {
763 echo "Mbstring functions are available.<br />\n";
765 echo 'Mbstring functions are unavailable.'
766 ." Japanese translation won't work.<br />\n";
768 echo "$IND recode - ";
769 if (function_exists('recode')) {
770 echo "Recode functions are available.<br />\n";
771 } elseif (isset($use_php_recode) && $use_php_recode) {
772 echo "Recode functions are unavailable.<br />\n";
773 do_err('Your configuration requires recode support, but recode support is missing.');
775 echo "Recode functions are unavailable.<br />\n";
777 echo "$IND iconv - ";
778 if (function_exists('iconv')) {
779 echo "Iconv functions are available.<br />\n";
780 } elseif (isset($use_php_iconv) && $use_php_iconv) {
781 echo "Iconv functions are unavailable.<br />\n";
782 do_err('Your configuration requires iconv support, but iconv support is missing.');
784 echo "Iconv functions are unavailable.<br />\n";
786 // same test as in include/init.php + date_default_timezone_set check
787 echo "$IND timezone - ";
788 if ( (!ini_get('safe_mode')) ||
function_exists('date_default_timezone_set') ||
789 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
790 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars')) ) {
791 echo "Webmail users can change their time zone settings. \n";
793 echo "Webmail users can't change their time zone settings. \n";
795 if (isset($_ENV['TZ'])) {
796 echo 'Default time zone is '.htmlspecialchars($_ENV['TZ']);
798 echo 'Current time zone is '.date('T');
803 echo "Checking database functions...<br />\n";
804 if($addrbook_dsn ||
$prefs_dsn ||
$addrbook_global_dsn) {
805 @include_once
('DB.php');
806 if (class_exists('DB')) {
807 echo "$IND PHP Pear DB support is present.<br />\n";
809 'dbase' => 'dbase_open',
810 'fbsql' => 'fbsql_connect',
811 'interbase' => 'ibase_connect',
812 'informix' => 'ifx_connect',
813 'msql' => 'msql_connect',
814 'mssql' => 'mssql_connect',
815 'mysql' => 'mysql_connect',
816 'mysqli' => 'mysqli_connect',
817 'oci8' => 'ocilogon',
818 'odbc' => 'odbc_connect',
819 'pgsql' => 'pg_connect',
820 'sqlite' => 'sqlite_open',
821 'sybase' => 'sybase_connect'
826 $dsns['preferences'] = $prefs_dsn;
829 $dsns['addressbook'] = $addrbook_dsn;
831 if($addrbook_global_dsn) {
832 $dsns['global addressbook'] = $addrbook_global_dsn;
835 foreach($dsns as $type => $dsn) {
836 $aDsn = explode(':', $dsn);
837 $dbtype = array_shift($aDsn);
838 if(isset($db_functions[$dbtype]) && function_exists($db_functions[$dbtype])) {
839 echo "$IND$dbtype database support present.<br />\n";
841 // now, test this interface:
843 $dbh = DB
::connect($dsn, true);
844 if (DB
::isError($dbh)) {
845 do_err('Database error: '. htmlspecialchars(DB
::errorMessage($dbh)) .
846 ' in ' .$type .' DSN.');
849 echo "$IND$type database connect successful.<br />\n";
852 do_err($dbtype.' database support not present!');
856 $db_error='Required PHP PEAR DB support is not available.'
857 .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
858 .' The include path is now:<tt>' . ini_get('include_path') . '</tt>.';
862 echo $IND."not using database functionality.<br />\n";
866 echo "Checking LDAP functions...<br />\n";
867 if( empty($ldap_server) ) {
868 echo $IND."not using LDAP functionality.<br />\n";
870 if ( !function_exists('ldap_connect') ) {
871 do_err('Required LDAP support is not available.');
873 echo "$IND LDAP support present.<br />\n";
874 foreach ( $ldap_server as $param ) {
876 $linkid = @ldap_connect
($param['host'], (empty($param['port']) ?
389 : $param['port']) );
879 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
881 if ( !empty($param['protocol']) &&
882 !ldap_set_option($linkid, LDAP_OPT_PROTOCOL_VERSION
, $param['protocol']) ) {
883 do_err('Unable to set LDAP protocol');
886 if ( empty($param['binddn']) ) {
887 $bind = @ldap_bind
($linkid);
889 $bind = @ldap_bind
($param['binddn'], $param['bindpw']);
893 echo "$IND LDAP Bind Successful <br />";
895 do_err('Unable to Bind to LDAP Server');
898 @ldap_close
($linkid);
900 do_err('Connection to LDAP failed');
906 echo '<hr width="75%" align="center">';
907 echo '<h2 align="center">Summary</h2>';
908 $footer = '<hr width="75%" align="center">';
910 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>';
914 <p
>Congratulations
, your SquirrelMail setup looks fine to me
!</p
>
916 <p
><a href
="login.php">Login now
</a
></p
>