You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test.php 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <?php
  2. if (!class_exists('rcmail_install', false) || !is_object($RCI)) {
  3. die("Not allowed! Please open installer/index.php instead.");
  4. }
  5. ?>
  6. <form action="index.php?_step=3" method="post">
  7. <h3>Check config file</h3>
  8. <?php
  9. if ($read_config = is_readable(RCUBE_CONFIG_DIR . 'defaults.inc.php')) {
  10. $config = $RCI->load_config_file(RCUBE_CONFIG_DIR . 'defaults.inc.php');
  11. if (!empty($config)) {
  12. $RCI->pass('defaults.inc.php');
  13. }
  14. else {
  15. $RCI->fail('defaults.inc.php', 'Syntax error');
  16. }
  17. }
  18. else {
  19. $RCI->fail('defaults.inc.php', 'Unable to read default config file?');
  20. }
  21. echo '<br />';
  22. if ($read_config = is_readable(RCUBE_CONFIG_DIR . 'config.inc.php')) {
  23. $config = $RCI->load_config_file(RCUBE_CONFIG_DIR . 'config.inc.php');
  24. if (!empty($config)) {
  25. $RCI->pass('config.inc.php');
  26. }
  27. else {
  28. $RCI->fail('config.inc.php', 'Syntax error');
  29. }
  30. }
  31. else {
  32. $RCI->fail('config.inc.php', 'Unable to read file. Did you create the config file?');
  33. }
  34. echo '<br />';
  35. if ($RCI->configured && ($messages = $RCI->check_config())) {
  36. if (is_array($messages['replaced'])) {
  37. echo '<h3 class="warning">Replaced config options</h3>';
  38. echo '<p class="hint">The following config options have been replaced or renamed. ';
  39. echo 'Please update them accordingly in your config files.</p>';
  40. echo '<ul class="configwarings">';
  41. foreach ($messages['replaced'] as $msg) {
  42. echo html::tag('li', null, html::span('propname', $msg['prop']) .
  43. ' was replaced by ' . html::span('propname', $msg['replacement']));
  44. }
  45. echo '</ul>';
  46. }
  47. if (is_array($messages['obsolete'])) {
  48. echo '<h3>Obsolete config options</h3>';
  49. echo '<p class="hint">You still have some obsolete or inexistent properties set. This isn\'t a problem but should be noticed.</p>';
  50. echo '<ul class="configwarings">';
  51. foreach ($messages['obsolete'] as $msg) {
  52. echo html::tag('li', null, html::span('propname', $msg['prop']) . ($msg['name'] ? ':&nbsp;' . $msg['name'] : ''));
  53. }
  54. echo '</ul>';
  55. }
  56. echo '<p class="suggestion">OK, lazy people can download the updated config file here: ';
  57. echo html::a(array('href' => './?_mergeconfig=1'), 'config.inc.php') . ' &nbsp;';
  58. echo "</p>";
  59. if (is_array($messages['dependencies'])) {
  60. echo '<h3 class="warning">Dependency check failed</h3>';
  61. echo '<p class="hint">Some of your configuration settings require other options to be configured or additional PHP modules to be installed</p>';
  62. echo '<ul class="configwarings">';
  63. foreach ($messages['dependencies'] as $msg) {
  64. echo html::tag('li', null, html::span('propname', $msg['prop']) . ': ' . $msg['explain']);
  65. }
  66. echo '</ul>';
  67. }
  68. }
  69. ?>
  70. <h3>Check if directories are writable</h3>
  71. <p>Roundcube may need to write/save files into these directories</p>
  72. <?php
  73. $dirs[] = $RCI->config['temp_dir'] ? $RCI->config['temp_dir'] : 'temp';
  74. if ($RCI->config['log_driver'] != 'syslog')
  75. $dirs[] = $RCI->config['log_dir'] ? $RCI->config['log_dir'] : 'logs';
  76. foreach ($dirs as $dir) {
  77. $dirpath = rcube_utils::is_absolute_path($dir) ? $dir : INSTALL_PATH . $dir;
  78. if (is_writable(realpath($dirpath))) {
  79. $RCI->pass($dir);
  80. $pass = true;
  81. }
  82. else {
  83. $RCI->fail($dir, 'not writeable for the webserver');
  84. }
  85. echo '<br />';
  86. }
  87. if (!$pass) {
  88. echo '<p class="hint">Use <tt>chmod</tt> or <tt>chown</tt> to grant write privileges to the webserver</p>';
  89. }
  90. ?>
  91. <h3>Check DB config</h3>
  92. <?php
  93. $db_working = false;
  94. if ($RCI->configured) {
  95. if (!empty($RCI->config['db_dsnw'])) {
  96. $DB = rcube_db::factory($RCI->config['db_dsnw'], '', false);
  97. $DB->set_debug((bool)$RCI->config['sql_debug']);
  98. $DB->db_connect('w');
  99. if (!($db_error_msg = $DB->is_error())) {
  100. $RCI->pass('DSN (write)');
  101. echo '<br />';
  102. $db_working = true;
  103. }
  104. else {
  105. $RCI->fail('DSN (write)', $db_error_msg);
  106. echo '<p class="hint">Make sure that the configured database exists and that the user has write privileges<br />';
  107. echo 'DSN: ' . $RCI->config['db_dsnw'] . '</p>';
  108. }
  109. }
  110. else {
  111. $RCI->fail('DSN (write)', 'not set');
  112. }
  113. }
  114. else {
  115. $RCI->fail('DSN (write)', 'Could not read config file');
  116. }
  117. // initialize db with schema found in /SQL/*
  118. if ($db_working && $_POST['initdb']) {
  119. if (!($success = $RCI->init_db($DB))) {
  120. $db_working = false;
  121. echo '<p class="warning">Please try to inizialize the database manually as described in the INSTALL guide.
  122. Make sure that the configured database extists and that the user as write privileges</p>';
  123. }
  124. }
  125. else if ($db_working && $_POST['updatedb']) {
  126. if (!($success = $RCI->update_db($_POST['version']))) {
  127. echo '<p class="warning">Database schema update failed.</p>';
  128. }
  129. }
  130. // test database
  131. if ($db_working) {
  132. $db_read = $DB->query("SELECT count(*) FROM " . $DB->quote_identifier($RCI->config['db_prefix'] . 'users'));
  133. if ($DB->is_error()) {
  134. $RCI->fail('DB Schema', "Database not initialized");
  135. echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
  136. $db_working = false;
  137. }
  138. else if ($err = $RCI->db_schema_check($DB, $update = !empty($_POST['updatedb']))) {
  139. $RCI->fail('DB Schema', "Database schema differs");
  140. echo '<ul style="margin:0"><li>' . join("</li>\n<li>", $err) . "</li></ul>";
  141. $select = $RCI->versions_select(array('name' => 'version'));
  142. $select->add('0.9 or newer', '');
  143. echo '<p class="suggestion">You should run the update queries to get the schema fixed.<br/><br/>Version to update from: ' . $select->show() . '&nbsp;<input type="submit" name="updatedb" value="Update" /></p>';
  144. $db_working = false;
  145. }
  146. else {
  147. $RCI->pass('DB Schema');
  148. echo '<br />';
  149. }
  150. }
  151. // more database tests
  152. if ($db_working) {
  153. // write test
  154. $insert_id = md5(uniqid());
  155. $db_write = $DB->query("INSERT INTO " . $DB->quote_identifier($RCI->config['db_prefix'] . 'session')
  156. . " (`sess_id`, `created`, `ip`, `vars`) VALUES (?, ".$DB->now().", '127.0.0.1', 'foo')", $insert_id);
  157. if ($db_write) {
  158. $RCI->pass('DB Write');
  159. $DB->query("DELETE FROM " . $DB->quote_identifier($RCI->config['db_prefix'] . 'session')
  160. . " WHERE `sess_id` = ?", $insert_id);
  161. }
  162. else {
  163. $RCI->fail('DB Write', $RCI->get_error());
  164. }
  165. echo '<br />';
  166. // check timezone settings
  167. $tz_db = 'SELECT ' . $DB->unixtimestamp($DB->now()) . ' AS tz_db';
  168. $tz_db = $DB->query($tz_db);
  169. $tz_db = $DB->fetch_assoc($tz_db);
  170. $tz_db = (int) $tz_db['tz_db'];
  171. $tz_local = (int) time();
  172. $tz_diff = $tz_local - $tz_db;
  173. // sometimes db and web servers are on separate hosts, so allow a 30 minutes delta
  174. if (abs($tz_diff) > 1800) {
  175. $RCI->fail('DB Time', "Database time differs {$td_ziff}s from PHP time");
  176. }
  177. else {
  178. $RCI->pass('DB Time');
  179. }
  180. }
  181. ?>
  182. <h3>Test filetype detection</h3>
  183. <?php
  184. if ($errors = $RCI->check_mime_detection()) {
  185. $RCI->fail('Fileinfo/mime_content_type configuration');
  186. if (!empty($RCI->config['mime_magic'])) {
  187. echo '<p class="hint">Try setting the <tt>mime_magic</tt> config option to <tt>null</tt>.</p>';
  188. }
  189. else {
  190. echo '<p class="hint">Check the <a href="http://www.php.net/manual/en/function.finfo-open.php">Fileinfo functions</a> of your PHP installation.<br/>';
  191. echo 'The path to the magic.mime file can be set using the <tt>mime_magic</tt> config option in Roundcube.</p>';
  192. }
  193. }
  194. else {
  195. $RCI->pass('Fileinfo/mime_content_type configuration');
  196. echo "<br/>";
  197. }
  198. if ($errors = $RCI->check_mime_extensions()) {
  199. $RCI->fail('Mimetype to file extension mapping');
  200. echo '<p class="hint">Please set a valid path to your webserver\'s mime.types file to the <tt>mime_types</tt> config option.<br/>';
  201. echo 'If you can\'t find such a file, download it from <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types">svn.apache.org</a>.</p>';
  202. }
  203. else {
  204. $RCI->pass('Mimetype to file extension mapping');
  205. echo "<br/>";
  206. }
  207. ?>
  208. <h3>Test SMTP config</h3>
  209. <p>
  210. Server: <?php echo rcube_utils::parse_host($RCI->getprop('smtp_server', 'PHP mail()')); ?><br />
  211. Port: <?php echo $RCI->getprop('smtp_port'); ?><br />
  212. <?php
  213. if ($RCI->getprop('smtp_server')) {
  214. $user = $RCI->getprop('smtp_user', '(none)');
  215. $pass = $RCI->getprop('smtp_pass', '(none)');
  216. if ($user == '%u') {
  217. $user_field = new html_inputfield(array('name' => '_smtp_user'));
  218. $user = $user_field->show($_POST['_smtp_user']);
  219. }
  220. if ($pass == '%p') {
  221. $pass_field = new html_passwordfield(array('name' => '_smtp_pass'));
  222. $pass = $pass_field->show();
  223. }
  224. echo "User: $user<br />";
  225. echo "Password: $pass<br />";
  226. }
  227. $from_field = new html_inputfield(array('name' => '_from', 'id' => 'sendmailfrom'));
  228. $to_field = new html_inputfield(array('name' => '_to', 'id' => 'sendmailto'));
  229. ?>
  230. </p>
  231. <?php
  232. if (isset($_POST['sendmail'])) {
  233. echo '<p>Trying to send email...<br />';
  234. $from = idn_to_ascii(trim($_POST['_from']));
  235. $to = idn_to_ascii(trim($_POST['_to']));
  236. if (preg_match('/^' . $RCI->email_pattern . '$/i', $from) &&
  237. preg_match('/^' . $RCI->email_pattern . '$/i', $to)
  238. ) {
  239. $headers = array(
  240. 'From' => $from,
  241. 'To' => $to,
  242. 'Subject' => 'Test message from Roundcube',
  243. );
  244. $body = 'This is a test to confirm that Roundcube can send email.';
  245. $smtp_response = array();
  246. // send mail using configured SMTP server
  247. if ($RCI->getprop('smtp_server')) {
  248. $CONFIG = $RCI->config;
  249. if (!empty($_POST['_smtp_user'])) {
  250. $CONFIG['smtp_user'] = $_POST['_smtp_user'];
  251. }
  252. if (!empty($_POST['_smtp_pass'])) {
  253. $CONFIG['smtp_pass'] = $_POST['_smtp_pass'];
  254. }
  255. $mail_object = new Mail_mime();
  256. $send_headers = $mail_object->headers($headers);
  257. $SMTP = new rcube_smtp();
  258. $SMTP->connect(rcube_utils::parse_host($RCI->getprop('smtp_server')),
  259. $RCI->getprop('smtp_port'), $CONFIG['smtp_user'], $CONFIG['smtp_pass']);
  260. $status = $SMTP->send_mail($headers['From'], $headers['To'],
  261. ($foo = $mail_object->txtHeaders($send_headers)), $body);
  262. $smtp_response = $SMTP->get_response();
  263. }
  264. else { // use mail()
  265. $header_str = 'From: ' . $headers['From'];
  266. if (ini_get('safe_mode'))
  267. $status = mail($headers['To'], $headers['Subject'], $body, $header_str);
  268. else
  269. $status = mail($headers['To'], $headers['Subject'], $body, $header_str, '-f'.$headers['From']);
  270. if (!$status)
  271. $smtp_response[] = 'Mail delivery with mail() failed. Check your error logs for details';
  272. }
  273. if ($status) {
  274. $RCI->pass('SMTP send');
  275. }
  276. else {
  277. $RCI->fail('SMTP send', join('; ', $smtp_response));
  278. }
  279. }
  280. else {
  281. $RCI->fail('SMTP send', 'Invalid sender or recipient');
  282. }
  283. echo '</p>';
  284. }
  285. ?>
  286. <table>
  287. <tbody>
  288. <tr>
  289. <td><label for="sendmailfrom">Sender</label></td>
  290. <td><?php echo $from_field->show($_POST['_from']); ?></td>
  291. </tr>
  292. <tr>
  293. <td><label for="sendmailto">Recipient</label></td>
  294. <td><?php echo $to_field->show($_POST['_to']); ?></td>
  295. </tr>
  296. </tbody>
  297. </table>
  298. <p><input type="submit" name="sendmail" value="Send test mail" /></p>
  299. <h3>Test IMAP config</h3>
  300. <?php
  301. $default_hosts = $RCI->get_hostlist();
  302. if (!empty($default_hosts)) {
  303. $host_field = new html_select(array('name' => '_host', 'id' => 'imaphost'));
  304. $host_field->add($default_hosts);
  305. }
  306. else {
  307. $host_field = new html_inputfield(array('name' => '_host', 'id' => 'imaphost'));
  308. }
  309. $user_field = new html_inputfield(array('name' => '_user', 'id' => 'imapuser'));
  310. $pass_field = new html_passwordfield(array('name' => '_pass', 'id' => 'imappass'));
  311. ?>
  312. <table>
  313. <tbody>
  314. <tr>
  315. <td><label for="imaphost">Server</label></td>
  316. <td><?php echo $host_field->show($_POST['_host']); ?></td>
  317. </tr>
  318. <tr>
  319. <td>Port</td>
  320. <td><?php echo $RCI->getprop('default_port'); ?></td>
  321. </tr>
  322. <tr>
  323. <td><label for="imapuser">Username</label></td>
  324. <td><?php echo $user_field->show($_POST['_user']); ?></td>
  325. </tr>
  326. <tr>
  327. <td><label for="imappass">Password</label></td>
  328. <td><?php echo $pass_field->show(); ?></td>
  329. </tr>
  330. </tbody>
  331. </table>
  332. <?php
  333. if (isset($_POST['imaptest']) && !empty($_POST['_host']) && !empty($_POST['_user'])) {
  334. echo '<p>Connecting to ' . rcube::Q($_POST['_host']) . '...<br />';
  335. $imap_host = trim($_POST['_host']);
  336. $imap_port = $RCI->getprop('default_port');
  337. $a_host = parse_url($imap_host);
  338. if ($a_host['host']) {
  339. $imap_host = $a_host['host'];
  340. $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null;
  341. if (isset($a_host['port']))
  342. $imap_port = $a_host['port'];
  343. else if ($imap_ssl && $imap_ssl != 'tls' && (!$imap_port || $imap_port == 143))
  344. $imap_port = 993;
  345. }
  346. $imap_host = idn_to_ascii($imap_host);
  347. $imap_user = idn_to_ascii($_POST['_user']);
  348. $imap = new rcube_imap(null);
  349. $imap->set_options(array(
  350. 'auth_type' => $RCI->getprop('imap_auth_type'),
  351. 'debug' => $RCI->getprop('imap_debug'),
  352. 'socket_options' => $RCI->getprop('imap_conn_options'),
  353. ));
  354. if ($imap->connect($imap_host, $imap_user, $_POST['_pass'], $imap_port, $imap_ssl)) {
  355. $RCI->pass('IMAP connect', 'SORT capability: ' . ($imap->get_capability('SORT') ? 'yes' : 'no'));
  356. $imap->close();
  357. }
  358. else {
  359. $RCI->fail('IMAP connect', $RCI->get_error());
  360. }
  361. }
  362. ?>
  363. <p><input type="submit" name="imaptest" value="Check login" /></p>
  364. </form>
  365. <hr />
  366. <p class="warning">
  367. After completing the installation and the final tests please <b>remove</b> the whole
  368. installer folder from the document root of the webserver or make sure that
  369. <tt>enable_installer</tt> option in <tt>config.inc.php</tt> is disabled.<br />
  370. <br />
  371. These files may expose sensitive configuration data like server passwords and encryption keys
  372. to the public. Make sure you cannot access this installer from your browser.
  373. </p>