/** * Retrieve contents from remotely stored file * * @param string $host File host * @param string $directory Directory file is in * @param string $filename Filename of file to retrieve * @param int $port Port to connect to; default: 80 * @param int $timeout Connection timeout in seconds; default: 6 * * @return mixed File data as string if file can be read and there is no * timeout, false if there were errors or the connection timed out * * @throws \src\exception\runtime_exception If data can't be retrieved and no error * message is returned */ public function get($host, $directory, $filename, $port = 80, $timeout = 6) { // Set default values for error variables $this->error_number = 0; $this->error_string = ''; if ($socket = @fsockopen($host, $port, $this->error_number, $this->error_string, $timeout)) { @fputs($socket, "GET {$directory}/{$filename} HTTP/1.0\r\n"); @fputs($socket, "HOST: {$host}\r\n"); @fputs($socket, "Connection: close\r\n\r\n"); $timer_stop = time() + $timeout; stream_set_timeout($socket, $timeout); $file_info = ''; $get_info = false; while (!@feof($socket)) { if ($get_info) { $file_info .= @fread($socket, 1024); } else { $line = @fgets($socket, 1024); if ($line == "\r\n") { $get_info = true; } else { if (stripos($line, '404 not found') !== false) { throw new \src\exception\runtime_exception('FILE_NOT_FOUND', array($filename)); } } } $stream_meta_data = stream_get_meta_data($socket); if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) { throw new \src\exception\runtime_exception('FSOCK_TIMEOUT'); } } @fclose($socket); } else { if ($this->error_string) { $this->error_string = utf8_convert_message($this->error_string); return false; } else { throw new \src\exception\runtime_exception('FSOCK_DISABLED'); } } return $file_info; }
/** * Return the current phpBB3 version from phpBB.com's updatecheck directory */ public static function get_current_version($type) { global $lang; //If we don't want to go out to the Internet we set these if (LOCAL_ONLY) { switch ($type) { case 'phpbb': return PHPBB_VERSION; break; case 'modx': return LATEST_MODX; break; case 'umil': return LATEST_UMIL; break; default: return false; break; } } $errstr = ''; $errno = 0; $host = 'version.phpbb.com'; $port = 80; $timeout = 10; $directory = ''; switch ($type) { case 'phpbb': $filename = 'phpbb/30x.txt'; break; case 'modx': $filename = 'modx/modx_1x.txt'; break; case 'umil': $filename = 'umil/umil.txt'; break; default: return false; } $file_info = ''; $get_info = false; if (file_exists(self::$dir . 'store/data/' . $filename)) { //Get from cache if it's been less than a day since the last update if (time() - filemtime(self::$dir . 'store/data/' . $filename) <= 86400) { $file_info = file_get_contents(self::$dir . 'store/data/' . $filename); } } //Only do this if we couldn't get the cache data if (empty($file_info)) { if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout)) { @fputs($fsock, "GET {$directory}/{$filename} HTTP/1.1\r\n"); @fputs($fsock, "HOST: {$host}\r\n"); @fputs($fsock, "Connection: close\r\n\r\n"); while (!@feof($fsock)) { if ($get_info) { $file_info .= @fread($fsock, 1024); } else { $line = @fgets($fsock, 1024); if ($line == "\r\n") { $get_info = true; } else { if (stripos($line, '404 not found') !== false) { $errstr = $lang['FILE_NOT_FOUND'] . ': ' . $filename; return false; } } } } //Cache the update file $cache = @fopen($root_dir . 'store/data/' . $filename, 'wb'); @fwrite($cache, $file_info); @fclose($cache); @fclose($fsock); } else { if ($errstr) { $errstr = utf8_convert_message($errstr); return false; } else { $errstr = $lang['FSOCK_DISABLED']; return false; } } } $info = explode("\n", $file_info); return $info[0]; }
/** * Pop before smtp authentication */ function pop_before_smtp($hostname, $username, $password) { global $user; if (!($this->socket = @fsockopen($hostname, 110, $errno, $errstr, 10))) { if ($errstr) { $errstr = utf8_convert_message($errstr); } return isset($user->lang['NO_CONNECT_TO_SMTP_HOST']) ? sprintf($user->lang['NO_CONNECT_TO_SMTP_HOST'], $errno, $errstr) : "Could not connect to smtp host : {$errno} : {$errstr}"; } $this->server_send("USER {$username}", true); if ($err_msg = $this->server_parse('+OK', __LINE__)) { return $err_msg; } $this->server_send("PASS {$password}", true); if ($err_msg = $this->server_parse('+OK', __LINE__)) { return $err_msg; } $this->server_send('QUIT'); fclose($this->socket); return false; }
/** * Retrieve contents from remotely stored file */ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 10) { global $user; if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout)) { @fputs($fsock, "GET {$directory}/{$filename} HTTP/1.1\r\n"); @fputs($fsock, "HOST: {$host}\r\n"); @fputs($fsock, "Connection: close\r\n\r\n"); $file_info = ''; $get_info = false; while (!@feof($fsock)) { if ($get_info) { $file_info .= @fread($fsock, 1024); } else { $line = @fgets($fsock, 1024); if ($line == "\r\n") { $get_info = true; } else { if (stripos($line, '404 not found') !== false) { $errstr = $user->lang['FILE_NOT_FOUND'] . ': ' . $filename; return false; } } } } @fclose($fsock); } else { if ($errstr) { $errstr = utf8_convert_message($errstr); return false; } else { $errstr = $user->lang['FSOCK_DISABLED']; return false; } } return $file_info; }
/** * Check if the user provided database parameters are correct * * This function checks the database connection data and also checks for * any other problems that could cause an error during the installation * such as if there is any database table names conflicting. * * Note: The function assumes that $table_prefix has been already validated * with validate_table_prefix(). * * @param string $dbms Selected database type * @param string $dbhost Database host address * @param int $dbport Database port number * @param string $dbuser Database username * @param string $dbpass Database password * @param string $dbname Database name * @param string $table_prefix Database table prefix * * @return array|bool Returns true if test is successful, array of errors otherwise */ public function check_database_connection($dbms, $dbhost, $dbport, $dbuser, $dbpass, $dbname, $table_prefix) { $dbms_info = $this->get_available_dbms($dbms); $dbms_info = $dbms_info[$dbms]; $errors = array(); // Instantiate it and set return on error true /** @var \phpbb\db\driver\driver_interface $db */ $db = new $dbms_info['DRIVER'](); $db->sql_return_on_error(true); // Check that we actually have a database name before going any further if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle'), true) && $dbname === '') { $errors[] = array('title' => 'INST_ERR_DB_NO_NAME'); } // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea if ($dbms_info['SCHEMA'] === 'sqlite' && stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0)) { $errors[] = array('title' => 'INST_ERR_DB_FORUM_PATH'); } // Try to connect to db if (is_array($db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, false, true))) { $db_error = $db->sql_error(); $errors[] = array('title' => 'INST_ERR_DB_CONNECT', 'description' => $db_error['message'] ? utf8_convert_message($db_error['message']) : 'INST_ERR_DB_NO_ERROR'); } else { // Check if there is any table name collisions $temp_prefix = strtolower($table_prefix); $table_ary = array($temp_prefix . 'attachments', $temp_prefix . 'config', $temp_prefix . 'sessions', $temp_prefix . 'topics', $temp_prefix . 'users'); $db_tools_factory = new \phpbb\db\tools\factory(); $db_tools = $db_tools_factory->get($db); $tables = $db_tools->sql_list_tables(); $tables = array_map('strtolower', $tables); $table_intersect = array_intersect($tables, $table_ary); if (sizeof($table_intersect)) { $errors[] = array('title' => 'INST_ERR_PREFIX'); } // Check if database version is supported switch ($dbms) { case 'mysqli': if (version_compare($db->sql_server_info(true), '4.1.3', '<')) { $errors[] = array('title' => 'INST_ERR_DB_NO_MYSQLI'); } break; case 'sqlite': if (version_compare($db->sql_server_info(true), '2.8.2', '<')) { $errors[] = array('title' => 'INST_ERR_DB_NO_SQLITE'); } break; case 'sqlite3': if (version_compare($db->sql_server_info(true), '3.6.15', '<')) { $errors[] = array('title' => 'INST_ERR_DB_NO_SQLITE3'); } break; case 'oracle': $sql = "SELECT *\n\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\tOR PARAMETER = 'NLS_CHARACTERSET'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $stats[$row['parameter']] = $row['value']; } $db->sql_freeresult($result); if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') { $errors[] = array('title' => 'INST_ERR_DB_NO_ORACLE'); } break; case 'postgres': $sql = "SHOW server_encoding;"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') { $errors[] = array('title' => 'INST_ERR_DB_NO_POSTGRES'); } break; } } return empty($errors) ? true : $errors; }
/** * Retrieve contents from remotely stored file */ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 6) { global $user; if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout)) { @fputs($fsock, "GET {$directory}/{$filename} HTTP/1.0\r\n"); @fputs($fsock, "HOST: {$host}\r\n"); @fputs($fsock, "Connection: close\r\n\r\n"); $timer_stop = time() + $timeout; stream_set_timeout($fsock, $timeout); $file_info = ''; $get_info = false; while (!@feof($fsock)) { if ($get_info) { $file_info .= @fread($fsock, 1024); } else { $line = @fgets($fsock, 1024); if ($line == "\r\n") { $get_info = true; } else { if (stripos($line, '404 not found') !== false) { $errstr = $user->lang['FILE_NOT_FOUND'] . ': ' . $filename; return false; } } } $stream_meta_data = stream_get_meta_data($fsock); if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) { $errstr = $user->lang['FSOCK_TIMEOUT']; return false; } } @fclose($fsock); } else { if ($errstr) { $errstr = utf8_convert_message($errstr); return false; } else { $errstr = $user->lang['FSOCK_DISABLED']; return false; } } return $file_info; }
/** * Used to test whether we are able to connect to the database the user has specified * and identify any problems (eg there are already tables with the names we want to use * @param array $dbms should be of the format of an element of the array returned by {@link get_available_dbms get_available_dbms()} * necessary extensions should be loaded already */ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport, $prefix_may_exist = false, $load_dbal = true, $unicode_check = true) { global $phpbb_root_path, $phpEx, $config, $lang; $dbms = $dbms_details['DRIVER']; // Instantiate it and set return on error true $db = new $dbms(); $db->sql_return_on_error(true); // Check that we actually have a database name before going any further..... if ($dbms_details['DRIVER'] != 'phpbb\\db\\driver\\sqlite' && $dbms_details['DRIVER'] != 'phpbb\\db\\driver\\sqlite3' && $dbms_details['DRIVER'] != 'phpbb\\db\\driver\\oracle' && $dbname === '') { $error[] = $lang['INST_ERR_DB_NO_NAME']; return false; } // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea if (($dbms_details['DRIVER'] == 'phpbb\\db\\driver\\sqlite' || $dbms_details['DRIVER'] == 'phpbb\\db\\driver\\sqlite3') && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0) { $error[] = $lang['INST_ERR_DB_FORUM_PATH']; return false; } // Check the prefix length to ensure that index names are not too long and does not contain invalid characters switch ($dbms_details['DRIVER']) { case 'phpbb\\db\\driver\\mysql': case 'phpbb\\db\\driver\\mysqli': if (strspn($table_prefix, '-./\\') !== 0) { $error[] = $lang['INST_ERR_PREFIX_INVALID']; return false; } // no break; // no break; case 'phpbb\\db\\driver\\postgres': $prefix_length = 36; break; case 'phpbb\\db\\driver\\mssql': case 'phpbb\\db\\driver\\mssql_odbc': case 'phpbb\\db\\driver\\mssqlnative': $prefix_length = 90; break; case 'phpbb\\db\\driver\\sqlite': case 'phpbb\\db\\driver\\sqlite3': $prefix_length = 200; break; case 'phpbb\\db\\driver\\oracle': $prefix_length = 6; break; } if (strlen($table_prefix) > $prefix_length) { $error[] = sprintf($lang['INST_ERR_PREFIX_TOO_LONG'], $prefix_length); return false; } // Try and connect ... if (is_array($db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true))) { $db_error = $db->sql_error(); $error[] = $lang['INST_ERR_DB_CONNECT'] . '<br />' . ($db_error['message'] ? utf8_convert_message($db_error['message']) : $lang['INST_ERR_DB_NO_ERROR']); } else { // Likely matches for an existing phpBB installation if (!$prefix_may_exist) { $temp_prefix = strtolower($table_prefix); $table_ary = array($temp_prefix . 'attachments', $temp_prefix . 'config', $temp_prefix . 'sessions', $temp_prefix . 'topics', $temp_prefix . 'users'); $tables = get_tables($db); $tables = array_map('strtolower', $tables); $table_intersect = array_intersect($tables, $table_ary); if (sizeof($table_intersect)) { $error[] = $lang['INST_ERR_PREFIX']; } } // Make sure that the user has selected a sensible DBAL for the DBMS actually installed switch ($dbms_details['DRIVER']) { case 'phpbb\\db\\driver\\mysqli': if (version_compare(mysqli_get_server_info($db->get_db_connect_id()), '4.1.3', '<')) { $error[] = $lang['INST_ERR_DB_NO_MYSQLI']; } break; case 'phpbb\\db\\driver\\sqlite': if (version_compare(sqlite_libversion(), '2.8.2', '<')) { $error[] = $lang['INST_ERR_DB_NO_SQLITE']; } break; case 'phpbb\\db\\driver\\sqlite3': $version = \SQLite3::version(); if (version_compare($version['versionString'], '3.6.15', '<')) { $error[] = $lang['INST_ERR_DB_NO_SQLITE3']; } break; case 'phpbb\\db\\driver\\oracle': if ($unicode_check) { $sql = "SELECT *\n\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\tOR PARAMETER = 'NLS_CHARACTERSET'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $stats[$row['parameter']] = $row['value']; } $db->sql_freeresult($result); if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') { $error[] = $lang['INST_ERR_DB_NO_ORACLE']; } } break; case 'phpbb\\db\\driver\\postgres': if ($unicode_check) { $sql = "SHOW server_encoding;"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') { $error[] = $lang['INST_ERR_DB_NO_POSTGRES']; } } break; } } if ($error_connect && (!isset($error) || !sizeof($error))) { return true; } return false; }
/** * Used to test whether we are able to connect to the database the user has specified * and identify any problems (eg there are already tables with the names we want to use * @param array $dbms should be of the format of an element of the array returned by {@link get_available_dbms get_available_dbms()} * necessary extensions should be loaded already */ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport, $prefix_may_exist = false, $load_dbal = true, $unicode_check = true) { global $phpbb_root_path, $phpEx, $config, $lang; $dbms = $dbms_details['DRIVER']; if ($load_dbal) { // Include the DB layer include $phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx; } // Instantiate it and set return on error true $sql_db = 'dbal_' . $dbms; $db = new $sql_db(); $db->sql_return_on_error(true); // Check that we actually have a database name before going any further..... if ($dbms_details['DRIVER'] != 'sqlite' && $dbms_details['DRIVER'] != 'oracle' && $dbname === '') { $error[] = $lang['INST_ERR_DB_NO_NAME']; return false; } // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea if ($dbms_details['DRIVER'] == 'sqlite' && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0) { $error[] = $lang['INST_ERR_DB_FORUM_PATH']; return false; } // Check the prefix length to ensure that index names are not too long and does not contain invalid characters switch ($dbms_details['DRIVER']) { case 'mysql': case 'mysqli': if (strspn($table_prefix, '-./\\') !== 0) { $error[] = $lang['INST_ERR_PREFIX_INVALID']; return false; } // no break; // no break; case 'postgres': $prefix_length = 36; break; case 'mssql': case 'mssql_odbc': case 'mssqlnative': $prefix_length = 90; break; case 'sqlite': $prefix_length = 200; break; case 'firebird': case 'oracle': $prefix_length = 6; break; } if (strlen($table_prefix) > $prefix_length) { $error[] = sprintf($lang['INST_ERR_PREFIX_TOO_LONG'], $prefix_length); return false; } // Try and connect ... if (is_array($db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true))) { $db_error = $db->sql_error(); $error[] = $lang['INST_ERR_DB_CONNECT'] . '<br />' . ($db_error['message'] ? utf8_convert_message($db_error['message']) : $lang['INST_ERR_DB_NO_ERROR']); } else { // Likely matches for an existing phpBB installation if (!$prefix_may_exist) { $temp_prefix = strtolower($table_prefix); $table_ary = array($temp_prefix . 'attachments', $temp_prefix . 'config', $temp_prefix . 'sessions', $temp_prefix . 'topics', $temp_prefix . 'users'); $tables = get_tables($db); $tables = array_map('strtolower', $tables); $table_intersect = array_intersect($tables, $table_ary); if (sizeof($table_intersect)) { $error[] = $lang['INST_ERR_PREFIX']; } } // Make sure that the user has selected a sensible DBAL for the DBMS actually installed switch ($dbms_details['DRIVER']) { case 'mysqli': if (version_compare(mysqli_get_server_info($db->db_connect_id), '4.1.3', '<')) { $error[] = $lang['INST_ERR_DB_NO_MYSQLI']; } break; case 'sqlite': if (version_compare(sqlite_libversion(), '2.8.2', '<')) { $error[] = $lang['INST_ERR_DB_NO_SQLITE']; } break; case 'firebird': // check the version of FB, use some hackery if we can't get access to the server info if ($db->service_handle !== false && function_exists('ibase_server_info')) { $val = @ibase_server_info($db->service_handle, IBASE_SVC_SERVER_VERSION); preg_match('#V([\\d.]+)#', $val, $match); if ($match[1] < 2) { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD']; } $db_info = @ibase_db_info($db->service_handle, $dbname, IBASE_STS_HDR_PAGES); preg_match('/^\\s*Page size\\s*(\\d+)/m', $db_info, $regs); $page_size = intval($regs[1]); if ($page_size < 8192) { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS']; } } else { $sql = "SELECT *\n\t\t\t\t\t\tFROM RDB{$FUNCTIONS}\n\t\t\t\t\t\tWHERE RDB{$SYSTEM_FLAG} IS NULL\n\t\t\t\t\t\t\tAND RDB{$FUNCTION_NAME} = 'CHAR_LENGTH'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); // if its a UDF, its too old if ($row) { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD']; } else { $sql = 'SELECT 1 FROM RDB$DATABASE WHERE BIN_AND(10, 1) = 0'; $result = $db->sql_query($sql); if (!$result) { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD']; } $db->sql_freeresult($result); } // Setup the stuff for our random table $char_array = array_merge(range('A', 'Z'), range('0', '9')); $char_len = mt_rand(7, 9); $char_array_len = sizeof($char_array) - 1; $final = ''; for ($i = 0; $i < $char_len; $i++) { $final .= $char_array[mt_rand(0, $char_array_len)]; } // Create some random table $sql = 'CREATE TABLE ' . $final . " (\n\t\t\t\t\t\tFIELD1 VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE,\n\t\t\t\t\t\tFIELD2 INTEGER DEFAULT 0 NOT NULL);"; $db->sql_query($sql); // Create an index that should fail if the page size is less than 8192 $sql = 'CREATE INDEX ' . $final . ' ON ' . $final . '(FIELD1, FIELD2);'; $db->sql_query($sql); if (ibase_errmsg() !== false) { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS']; } else { // Kill the old table $db->sql_query('DROP TABLE ' . $final . ';'); } unset($final); } break; case 'oracle': if ($unicode_check) { $sql = "SELECT *\n\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\tOR PARAMETER = 'NLS_CHARACTERSET'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $stats[$row['parameter']] = $row['value']; } $db->sql_freeresult($result); if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') { $error[] = $lang['INST_ERR_DB_NO_ORACLE']; } } break; case 'postgres': if ($unicode_check) { $sql = "SHOW server_encoding;"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') { $error[] = $lang['INST_ERR_DB_NO_POSTGRES']; } } break; } } if ($error_connect && (!isset($error) || !sizeof($error))) { return true; } return false; }