<?php
if (!defined('PmWiki') || !defined ('PhpbbRootPath')) {
exit ();
}
$RecipeInfo['AuthPhpbb2Sso']['Version'] = '080401';
$phpbb_root_path = PhpbbRootPath;
// Include the required phpBB files
define('IN_PHPBB', true);
define('MG_KILL_CTRACK', true); // Or the phpBB scripts will report a "hacking attempt"
include($phpbb_root_path . '/config.php');
require_once ($phpbb_root_path . '/includes/db.php'); // Define and instantiate the $db object
require_once ($phpbb_root_path . '/includes/constants.php'); // Get constants for table names etc.
require_once ($phpbb_root_path . '/includes/sessions.php'); // Functions for sessions
// Read the config table into the board_config array
$board_config = GetBoardConfig();
// To start a session we need the IP address of the client
$user_ip = encode_ip(( !empty($HTTP_SERVER_VARS['REMOTE_ADDR']) ) ? $HTTP_SERVER_VARS['REMOTE_ADDR'] : ( ( !empty($HTTP_ENV_VARS['REMOTE_ADDR']) ) ? $HTTP_ENV_VARS['REMOTE_ADDR'] : getenv('REMOTE_ADDR') ));
// Now start a phpBB session
// Registered page number in the sessions table is -20. phpBB2 itself uses 0 till -11
$userdata = session_pagestart($user_ip, -20);
// We now have the $userdata array to play with, as per phpBB2. The array contains the user and session
// information from phpBB.
// Restrict admin pages to phpBB Administrators
SDV($PhpbbAdminGroup, 'siteadmin');
$DefaultPasswords['admin'] = '@' . $PhpbbAdminGroup;
// Suffix for group moderator groups
SDV ($PhpbbGroupModSuffix, 'Moderator');
// Set the author name as used by PMwiki. Author name will be set to 'anonymous' if the
// user is not signed in.
$Author = $userdata['username'];
// Populate variables for AuthUser. Only if the login succeeded, or the user
// will appear to AuthUser as an authenticated used named "anonymous".
if ($userdata['session_logged_in'] == 1) {
$AuthId = $userdata['username'];
AddPhpbbGroups($userdata['user_id']);
if ($userdata['user_level'] == 1) {
$AuthList ['@' . $PhpbbAdminGroup] = 1;
}
}
// Include AuthUser for authorization
require_once ("scripts/authuser.php");
// Set some variables that can be used in the PmWiki templates to visually integrate PmWiki and phpBB:
$SiteUrl = (($board_config['cookie_secure'] ) ? 'https://' : 'http://')
. trim($board_config['server_name'])
. (( $board_config['server_port'] <> 80 ) ? ':' . trim($board_config['server_port']) : '');
$PhpbbUrl = $SiteUrl . '/' . preg_replace('/^\/?(.*?)\/?$/', "\\1", trim($board_config['script_path']));
$PhpbbStyleName = PhpbbStyleInfo('style_name');
$PhpbbTemplate = PhpbbStyleInfo('template_name');
$PhpbbStylesheet = PhpbbStyleInfo('head_stylesheet');
// Inherit compression setting from phpBB
InheritGzip ();
// Handle clients with disabled cookies
if (append_sid('') != '') {
// Buffer the page and append the "sid=" parameter to all local urls after
// the page is complete. Contents of the page are passed through the
// AddSid() function before being send to the client.
ob_start('AddSid');
// Append sid to redirect URL after editing a page. This is passed through
// a header("Location ..."), which cannot be altered by the output buffering
// function AddSid().
$EditRedirectFmt = append_sid('$FullName');
}
// ------------------------------------------------------------------------------------------
//Functions
// Get and set time settings from phpBB:
// * Time and date format
// * Timezone
// * Set format of new entries in the RecentChanges page so new entries are localizable.
function UsePhpbbDateSettings () {
global $TimeFmt, $board_config, $userdata, $RecentChangesFmt;
// Time format, convert from date() to strfdate()
$dateformatcnv = array('d' => '%d', 'D' => '%a', 'j' => '%e', 'l' => '%A', 'N' => '%u',
'w' => '%w', 'W' => '%V', 'F' => '%B', 'm' => '%I', 'M' => '%b',
'n' => '%e', 'o' => '%G', 'Y' => '%Y', 'y' => '%y', 'a' => '%p',
'A' => '%p', 'g' => '%I', 'G' => '%H', 'h' => '%I', 'H' => '%H',
'i' => '%M', 's' => '%S', 'c' => '%Y-%I-%dT%H:%M:%S',
'r' => '%a, %e %b %Y %H:%M:%S');
if ($userdata['user_dateformat'] != '') {
$TimeFmt = strtr($userdata['user_dateformat'], $dateformatcnv);
}
else {
$TimeFmt = strtr($board_config['default_dateformat'], $dateformatcnv);
}
// Timezone
$timezone = -1 * $userdata['user_timezone'];
if ($timezone > 0) {
$timezone = "+$timezone";
}
putenv("TZ=Etc/GMT$timezone");
// Localizable new entries in RecentChanges pages.
$RecentChangesFmt['$SiteGroup.AllRecentChanges'] =
'* [[{$Group}.{$Name}]] . . . {(ftime when="@' . time() . '")} $[by] $AuthorLink: [=$ChangeSummary=]';
$RecentChangesFmt['$Group.RecentChanges'] =
'* [[{$Group}/{$Name}]] . . . {(ftime when="@' . time() . '")} $[by] $AuthorLink: [=$ChangeSummary=]';
$DraftRecentChangesFmt['$Group.RecentDraftChanges'] =
'* [[{$Group}/{$Name}]] . . . {(ftime when="@' . time() . '")} $[by] $AuthorLink: [=$ChangeSummary=]';
}
// Returns information about the theme to be used.
function PhpbbStyleInfo($item) {
global $db, $userdata, $board_config;
static $row;
if (!is_array ($row)) {
if ($userdata['session_logged_in'] == 1) {
$themes_id = $userdata['user_style'];
}
else {
$themes_id = $board_config['default_style'];
}
$sql = "SELECT template_name, head_stylesheet, style_name FROM " . THEMES_TABLE . " WHERE themes_id = $themes_id";
$rowset = $db->sql_query($sql);
$row = $db->sql_fetchrow($rowset) or die ("Error retrieving theme name");
}
return $row[$item];
}
// Read the board cofiguration from the database and pass back
// as an array.
function GetBoardConfig() {
global $db;
$sql = "SELECT * FROM " . CONFIG_TABLE;
$rowset = $db->sql_query($sql);
while ( $row = $db->sql_fetchrow($rowset) ) {
$board_config[$row['config_name']] = $row['config_value'];
}
return $board_config;
}
// Function to create a link to the members profile in the forum on wiki pages.
//
// This can be used with the [[~username]] markup. To activate, add the following line
// to your PmWiki local/config.php:
// Markup ('[[~', '<links','/\\[\\[~(.*?)\\]\\]/e', "PhpbbUserProfile('$1')");
function PhpbbUserProfile ($username) {
global $db, $PhpbbUrl, $phpEx;
// Double quotes are passed escaped (\"), but these are stored as """ in the database
$username = str_replace('\"', '"', $username);
$sql = "SELECT user_id
FROM " . USERS_TABLE . "
WHERE username = \"$username\"";
$rowset = $db->sql_query($sql);
if ($row = $db->sql_fetchrow($rowset)) {
// Found the userID, now pass PmWiki link markup for further processing.
return "[[$PhpbbUrl/profile.$phpEx?mode=viewprofile&u=" . $row['user_id'] . " | $username]]";
}
else {
// If no member was found, just return the name.
return $username;
}
}
// Adds the phpBB group memberships to the $AuthList array
function AddPhpbbGroups($UserId) {
global $db, $AuthList, $PhpbbGroupModSuffix;
$result = array();
$sql = "SELECT g.group_name
, g.group_moderator
FROM " . GROUPS_TABLE . " g
, " . USER_GROUP_TABLE . " ug
WHERE ug.group_id = g.group_id
AND ug.user_id = $UserId
AND g.group_single_user = 0
AND user_pending = 0";
$rowset = $db->sql_query($sql);
while ( $row = $db->sql_fetchrow($rowset) ) {
$AuthList['@' . $row['group_name']] = 1;
if ($row['group_moderator'] == $UserId) {
$AuthList['@' . $row['group_name'] . $PhpbbGroupModSuffix] = 1;
}
}
}
// Output Buffer processor for clients with disabled cookies.
// Add the sesion identifier (sid=) to all links pointing to the local site.
// If the client disabled cookies, this function is called through the
// ob_start() function after the page is complete. The $content variable
// will contain the entire page.
function AddSid ($content) {
global $SiteUrl;
if ((strpos($content, "<meta http-equiv='Refresh'")) === FALSE) {
// Regular page, replace all links
$content = ProcessTag ($content, '<a ', "href='");
$content = ProcessTag ($content, '<form ', "action='");
}
else {
// Page from the Redirect() function, replace the link. The header
// will already be sent, this is handled by the $EditRedirectFmt var.
$content = ProcessTag ($content, "<meta http-equiv='Refresh'", 'URL=');
}
return $content;
}
// Process a specified tag to add the session identifier
function ProcessTag ($content, $tag, $parameter) {
global $SiteUrl;
// Split the page into an array, each element starting with the tag
$links = explode($tag, $content);
// Now process the array
for ($i = 0; $i < count($links); $i++)
{
$parstart = strpos($links[$i], $parameter);
if (! ($parstart === FALSE)) {
// Found a link
$linkstart = $parstart + strlen($parameter);
$linkend = strpos($links[$i], '\'', $linkstart);
$thelink = substr($links[$i], $linkstart, ($linkend - $linkstart) );
// Only replace links starting with our own URL
if (strpos($thelink, $SiteUrl) === 0 ) {
$links[$i] = substr($links[$i], 0, $linkstart) . append_sid($thelink) . substr($links[$i], $linkend);
}
}
}
// And implode back
return implode ($links, $tag);
}
// Inherit Gzip compression if set in phpBB.
// Code copied from phpbb: includes/page_header.php
function InheritGzip () {
global $board_config;
if ( $board_config['gzip_compress'] )
{
$phpver = phpversion();
$useragent = (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) ? $HTTP_SERVER_VARS['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT');
if ( $phpver >= '4.0.4pl1' && ( strstr($useragent,'compatible') || strstr($useragent,'Gecko') ) )
{
if ( extension_loaded('zlib') )
{
ob_start('ob_gzhandler');
}
}
else if ( $phpver > '4.0' )
{
if ( strstr($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') )
{
if ( extension_loaded('zlib') )
{
ob_start();
ob_implicit_flush(0);
header('Content-Encoding: gzip');
}
}
}
}
}
// Sets the $AuthPromptFmt variable, which is displayed when an attempt is made to access
// a page for which the client is not authorized. This function distinguishes between
// anonimous users and users signed in.
function RedirectOnDeny () {
global $userdata, $AuthPromptFmt, $PageStartFmt, $PageEndFmt, $PhpbbUrl
, $PhpbbUrl, $phpEx, $AuthPromptMemberFmt, $AuthPromptAnonymousFmt;
SDV ($AuthPromptMemberFmt, array(&$PageStartFmt, "<br><p>You are not authorized to access this page.</p><br>", &$PageEndFmt));
SDV ($AuthPromptAnonymousFmt, "<html><head>
<meta http-equiv='Refresh' Content='0; URL=$PhpbbUrl/login.$phpEx' />
<title>Redirect</title>
</head><body></body></html>");
if ($userdata['session_logged_in'] == 1) {
$AuthPromptFmt = $AuthPromptMemberFmt;
}
else {
$AuthPromptFmt = $AuthPromptAnonymousFmt;
}
}
// ------------------------------------------------------------------------------------------
// Functions hi-jacked from the phpBB includes/functions.php file.
// We cannot include the file itself, because it contains a function "redirect", which
// is already defined by pmWiki.
// Simplified message_die
function message_die($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '')
{
die ($msg_text);
}
// Encode an IP address to hex
function encode_ip($dotquad_ip)
{
$ip_sep = explode('.', $dotquad_ip);
return sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}
// Decode an IP address from hex
function decode_ip($int_ip)
{
$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
return hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
// Randomiser as used by the sessions.php script
function dss_rand()
{
global $db, $board_config, $dss_seeded;
$val = $board_config['rand_seed'] . microtime();
$val = md5($val);
$board_config['rand_seed'] = md5($board_config['rand_seed'] . $val . 'a');
if($dss_seeded !== true)
{
$sql = "UPDATE " . CONFIG_TABLE . " SET
config_value = '" . $board_config['rand_seed'] . "'
WHERE config_name = 'rand_seed'";
if( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, "Unable to reseed PRNG", "", __LINE__, __FILE__, $sql);
}
$dss_seeded = true;
}
return substr($val, 4, 16);
}