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