File/program/install.php

Description

/program/install.php - the main entrypoint for website installation

This is one of the main entry points for Website@School. Other main entry points are /admin.php, /cron.php, /file.php and /index.php. There is also /program/manual.php. Main entry points all define the constant WASENTRY. This is used in various include()ed files to detect break-in attempts.

  • author: Peter Fokker <peter@berestijn.nl>
  • version: $Id: install.php,v 1.30 2016/06/16 14:19:20 peter Exp $
  • copyright: Copyright (C) 2008-2016 Ingenieursbureau PSD/Peter Fokker
  • todo: how prevent third party-access to install.php after initial install? .htaccess? !exists(../config.php)?
  • todo: we should make sure that autosession is disabled in php.ini, otherwise was won't work
  • todo: we should make sure that we can actually set cookies (necessary when logging in).
  • todo: we should make sure that register globals is off
  • license: GNU AGPLv3+Additional Terms
Classes
Class Description
 class InstallWizard class for performing installation tasks
Includes
 include_once (dirname(__FILE__)."/version.php") (line 59)
 include_once (dirname(__FILE__)."/lib/utf8lib.php") (line 60)
Constants
INSTALL_DIALOG_CANCELLED = 11 (line 52)
INSTALL_DIALOG_CMS = 4 (line 45)
INSTALL_DIALOG_COMPATIBILITY = 6 (line 47)
INSTALL_DIALOG_CONFIRM = 7 (line 48)
INSTALL_DIALOG_DATABASE = 3 (line 44)
INSTALL_DIALOG_DONE = 9 (line 50)
INSTALL_DIALOG_DOWNLOAD = 10 (line 51)
INSTALL_DIALOG_FINISH = 8 (line 49)
INSTALL_DIALOG_INSTALLTYPE = 1 (line 42)
INSTALL_DIALOG_LANGUAGE = 0 (line 41)
INSTALL_DIALOG_LICENSE = 2 (line 43)
INSTALL_DIALOG_USER = 5 (line 46)
PROJECT_SITE = websiteatschool.eu (line 53)
WASENTRY = __FILE__ (line 37)

Valid entry points define WASENTRY; prevents direct access to include()'s.

Functions
install_script_name (line 4051)

determine the name of the executing script (the entry point)

this routine tries to reach consensus about the name of the script that was the entry point. This is not as easy as it sounds. Here are some real-world examples in three variations:

  • http://exemplum.eu/was/index.php
  • http://exemplum.eu/was/index.php?area=1&node=23
  • http://exemplum.eu/was/index.php/1/23/Welcome
The object of the excercises in the examples below is to arriva at the value '/was/index.php' using the elements from the global array $_SERVER. Note that the case for index.php has additional variations, e.g.
  • http://exemplum.eu/was
  • http://exemplum.eu/was/?area=1&node=23
Example 1 - a simple Linux-server and http://exemplum.eu/was/index.php
    DOCUMENT_ROOT   => /home/httpd/htdocs SCRIPT_FILENAME => /home/httpd/htdocs/was/index.php REQUEST_URI     => /was/index.php SCRIPT_NAME     => /was/index.php PHP_SELF        => /was/index.php PATH_INFO       => (undefined)

Example 2 - a simple Linux-server and http://exemplum.eu/was/index.php?area=1&node=23

    DOCUMENT_ROOT   => /home/httpd/htdocs SCRIPT_FILENAME => /home/httpd/htdocs/was/index.php REQUEST_URI     => /was/index.php?area=1&node=23 SCRIPT_NAME     => /was/index.php PHP_SELF        => /was/index.php PATH_INFO       => (undefined)

Example 3 - a simple Linux-server and http://exemplum.eu/was/index.php/1/23/Welcome

    DOCUMENT_ROOT   => /home/httpd/htdocs SCRIPT_FILENAME => /home/httpd/htdocs/was/index.php REQUEST_URI     => /was/index.php/1/23/Welcome SCRIPT_NAME     => /was/index.php PHP_SELF        => /was/index.php/1/23/Welcome PATH_INFO       => /1/23/Welcome

Example 4 - an ISP running php via CGI and http://exemplum.eu/was/index.php

    DOCUMENT_ROOT   => /usr/local/WWW/E/e/exemplum/htdocs SCRIPT_FILENAME => /usr/local/WWW/E/e/exemplum/htdocs/cgi-bin/php REQUEST_URI     => /was/index.php SCRIPT_NAME     => /cgi-bin/php PHP_SELF        => /was/index.php PATH_INFO       => /was/index.php

Example 5 - an ISP running php via CGI and http://exemplum.eu/was/index.php?area=1&node=23

    DOCUMENT_ROOT   => /usr/local/WWW/E/e/exemplum/htdocs SCRIPT_FILENAME => /usr/local/WWW/E/e/exemplum/htdocs/cgi-bin/php REQUEST_URI     => /was/index.php?area=1&node=23 SCRIPT_NAME     => /cgi-bin/php PHP_SELF        => /was/index.php PATH_INFO       => /was/index.php

Example 6 - an ISP running php via CGI and http://exemplum.eu/was/index.php/1/23/Welcome

    Server reply: No input file specified.

Simply using SCRIPT_NAME as per PHP Documentation won't work (see examples 4 and 5). Simply using PHP_SELF is also problematic (see example 3) because it equates to user input. Another problem is the use of symbolic links. The ISP running php via CGI shows this value for __FILE__ (in index.php):

__FILE__ => /usr/local/WWW/E/.5c1/e/exemplum/htdocs/was/index.php

so this simple assertion of the calculated value '/was/index.php' fails:

$DOCUMENT_ROOT.'/was/index.php' == __FILE__

because of the '/.5c1' within the __FILE__ path. However, this might be solved by looking at the realpath() of the left hand side because that resolves the 'hidden' link within $DOCUMENT_ROOT.

All in all the parameter REQUEST_URI shows the most consistent information never mind the appended parameters like node=23, so we start there.

The strategy is as follows.

  1. If REQUEST_URI begins with SCRIPT_NAME then SCRIPT_NAME is the answer (works for 1/2/3)
  2. If REQUEST_URI begins with PHP_SELF then PHP_SELF is the answer (works for 4/5)
If these two attempts fail, we try a different approach. We can determine the filename of the script (via basename($full_wasentry_path)) and try to match that with either SCRIPT_NAME or PHP_SELF. Specifically we look at the case there the filename is omitted ie. http://exemplum.eu/was/ instead of http://exemplum.eu/was/index.php. This yields a REQUEST_URI that fails in tests 1 and 2 above.

3. If (basename(__FILE__) == basename(SCRIPT_NAME) then SCRIPT_NAME is the likely answer (works for 1/2/3) 4. If (basename(__FILE__) == basename(PHP_SELF) then PHP_SELF is the likely answer (works for 4/5)

Finally, as a double check we assert that the DOCUMENT_ROOT together with the answer actually yields the __FILE__ path (resolving symlinks along the way). If it doesn't I'd say there is something going terribly wrong, wrong enought to warrant an emergency exit.

In other words: if there is only a slight doubt about the correct answer we simply die();

Note that an almost identical routine wasentry_script_name() is used in the main program via init.php.

  • return: path of entry point relative to the document root, e.g. '/was/program/install.php' or we die() on error
string install_script_name (string $full_wasentry_path)
  • string $full_wasentry_path: full path of the entry point, e.g. '/home/httpd/htdocs/was/program/install.php'

Documentation generated on Tue, 28 Jun 2016 19:09:53 +0200 by phpDocumentor 1.4.0