protected function GenerateSQL(&$master, &$sql, &$opts, $cmd, $queryinfo, $args, $subquery) { switch ($cmd) { case "SELECT": $supported = array("DBPREFIX" => $this->dbprefix, "PRECOLUMN" => array("DISTINCT" => "bool", "SUBQUERIES" => true), "FROM" => array("SUBQUERIES" => true), "WHERE" => array("SUBQUERIES" => true), "GROUP BY" => true, "HAVING" => true, "ORDER BY" => true, "LIMIT" => ", "); return $this->ProcessSELECT($master, $sql, $opts, $queryinfo, $args, $subquery, $supported); case "INSERT": $supported = array("DBPREFIX" => $this->dbprefix, "PREINTO" => array("LOW_PRIORITY" => "bool", "DELAYED" => "bool", "HIGH_PRIORITY" => "bool", "IGNORE" => "bool"), "SELECT" => true); return $this->ProcessINSERT($master, $sql, $opts, $queryinfo, $args, $subquery, $supported); case "UPDATE": $supported = array("DBPREFIX" => $this->dbprefix, "PRETABLE" => array("LOW_PRIORITY" => "bool", "IGNORE" => "bool"), "WHERE" => array("SUBQUERIES" => true), "ORDER BY" => true, "LIMIT" => ", "); return $this->ProcessUPDATE($master, $sql, $opts, $queryinfo, $args, $subquery, $supported); case "DELETE": $supported = array("DBPREFIX" => $this->dbprefix, "PREFROM" => array("LOW_PRIORITY" => "bool", "QUICK" => "bool", "IGNORE" => "bool"), "WHERE" => array("SUBQUERIES" => true), "ORDER BY" => true, "LIMIT" => ", "); return $this->ProcessDELETE($master, $sql, $opts, $queryinfo, $args, $subquery, $supported); case "SET": return array("success" => false, "errorcode" => "skip_sql_query"); case "USE": $this->dbprefix = $this->GetDBPrefix($queryinfo); return array("success" => false, "errorcode" => "skip_sql_query"); case "TRUNCATE TABLE": $supported = array("DBPREFIX" => $this->dbprefix, "PREFROM" => array()); $queryinfo = array($queryinfo[0]); return $this->ProcessDELETE($master, $sql, $opts, $queryinfo, $args, $subquery, $supported); } return array("success" => false, "error" => CSDB::DB_Translate("Unknown query command '%s'.", $cmd), "errorcode" => "unknown_query_command"); }
function SSO_OutputHeartbeat() { global $sso_db, $sso_db_temp_sessions, $sso_sessionrow, $sso_session_info, $sso_indexphp; if ($sso_session_info["initmsg"] != "" || $sso_session_info["files"]) { $sso_session_info["initmsg"] = ""; $sso_session_info["files"] = 0; SSO_SaveSessionInfo(); } if ($sso_sessionrow->heartbeat > 0) { $sso_db->Query("UPDATE", array($sso_db_temp_sessions, array("updated" => CSDB::ConvertToDBTime(time())), array("heartbeat" => "heartbeat - 1"), "WHERE" => "id = ? AND heartbeat > 0"), $sso_sessionrow->id); } ?> <script type="text/javascript"> if (typeof(window.jQuery) == 'undefined') { document.write('<' + 'script type="text/javascript" src="<?php echo htmlspecialchars(SSO_ROOT_URL . "/" . SSO_SUPPORT_PATH . "/jquery-1.11.0.min.js"); ?> " /' + '><' + '/script' + '>'); document.write('<' + 'script type="text/javascript"' + '>jQuery.noConflict();<' + '/script' + '>'); } </script> <script type="text/javascript"> function SSO_Heartbeat() { jQuery('#sso_heartbeat').load('<?php echo SSO_ROOT_URL . "/" . $sso_indexphp; ?> ', { 'sso_ajax' : 1, 'sso_id' : '<?php echo htmlspecialchars(BB_JSSafe($_REQUEST["sso_id"])); ?> ', 'sso_action' : 'sso_heartbeat' }); } jQuery(function() { setInterval(SSO_Heartbeat, 3300000); }); </script> <div id="sso_heartbeat" style="display: none;"></div> <?php }
protected function ProcessCREATE_TABLE(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported) { $master = true; if (isset($supported["TEMPORARY"]) && isset($queryinfo["TEMPORARY"]) && $queryinfo["TEMPORARY"]) { $cmd = $supported["TEMPORARY"]; } else { $cmd = "CREATE TABLE"; } $prefix = isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : ""; $sql = $cmd . " " . $this->QuoteIdentifier($prefix . $queryinfo[0]); if (isset($queryinfo["SELECT"])) { if (!isset($supported["AS_SELECT"]) || !$supported["AS_SELECT"]) { return array("success" => false, CSDB::DB_Translate("CREATE TABLE AS SELECT not supported."), "create_table_select_unsupported"); } $sql2 = ""; $opts2 = array(); $queryinfo2 = array_shift($queryinfo["SELECT"]); if (count($queryinfo["SELECT"]) == 1 && is_array($queryinfo["SELECT"][0])) { $queryinfo["SELECT"] = $queryinfo["SELECT"][0]; } $result = $this->GenerateSQL($master, $sql2, $opts2, "SELECT", $queryinfo2, $queryinfo["SELECT"], false); if (!$result["success"]) { return $result; } if (isset($supported["PRE_AS"])) { foreach ($supported["PRE_AS"] as $key => $mode) { if (isset($queryinfo[$key])) { if ($mode == "bool" && $queryinfo[$key]) { $sql .= " " . $key; } } } } $sql .= " AS " . $sql2; } else { $sql2 = array(); foreach ($queryinfo[1] as $key => $info) { $sql3 = $this->QuoteIdentifier($key); $result = $this->ProcessColumnDefinition($info); if (!$result["success"]) { return $result; } $sql2[] = $sql3 . $result["sql"]; } if (isset($supported["PROCESSKEYS"]) && $supported["PROCESSKEYS"] && isset($queryinfo[2]) && is_array($queryinfo[2])) { foreach ($queryinfo[2] as $info) { $result = $this->ProcessKeyDefinition($info); if (!$result["success"]) { return $result; } if ($result["sql"] != "") { $sql2[] = $result["sql"]; } } } $sql .= " (\n"; if (count($sql2)) { $sql .= "\t" . implode(",\n\t", $sql2) . "\n"; } $sql .= ")"; foreach ($supported["POSTCREATE"] as $key => $mode) { if (isset($queryinfo[$key])) { if ($mode == "bool" && $queryinfo[$key]) { $sql .= " " . $key; } else { if ($mode == "string") { $sql .= " " . $key . " " . $queryinfo[$key]; } } } } } $opts = $args; return array("success" => true); }
public function ProcessFrontend() { global $sso_rng, $sso_provider, $sso_settings, $sso_session_info; $redirect_uri = BB_GetRequestHost() . SSO_ROOT_URL . "/index.php?sso_provider=" . urlencode($sso_provider) . "&sso_google_action=signin"; if (isset($_REQUEST["sso_google_action"]) && $_REQUEST["sso_google_action"] == "signin") { // Recover the language settings. if (!isset($sso_session_info["sso_google_info"])) { $this->DisplayError(BB_Translate("Unable to authenticate the request.")); return; } $url = BB_GetRequestHost() . SSO_ROOT_URL . "/index.php?sso_provider=" . urlencode($sso_provider) . "&sso_google_action=signin2"; if (isset($_REQUEST["state"])) { $url .= "&state=" . urlencode($_REQUEST["state"]); } if (isset($_REQUEST["code"])) { $url .= "&code=" . urlencode($_REQUEST["code"]); } if (isset($_REQUEST["error"])) { $url .= "&error=" . urlencode($_REQUEST["error"]); } $url .= "&lang=" . urlencode($sso_session_info["sso_google_info"]["lang"]); header("Location: " . $url); } else { if (isset($_REQUEST["sso_google_action"]) && $_REQUEST["sso_google_action"] == "signin2") { // Validate the token. if (!isset($_REQUEST["state"]) || !isset($sso_session_info["sso_google_info"]) || $_REQUEST["state"] !== $sso_session_info["sso_google_info"]["token"]) { $this->DisplayError(BB_Translate("Unable to authenticate the request.")); return; } // Check for token expiration. if (CSDB::ConvertFromDBTime($sso_session_info["sso_google_info"]["expires"]) < time()) { $this->DisplayError(BB_Translate("Verification token has expired.")); return; } if (isset($_REQUEST["error"])) { if ($_REQUEST["error"] == "access_denied") { $message = BB_Translate("The request to sign in with Google was denied."); } else { $message = BB_Translate("The error message returned was '%s'.", $_REQUEST["error"]); } $this->DisplayError(BB_Translate("Sign in failed. %s", $message)); return; } if (!isset($_REQUEST["code"])) { $this->DisplayError(BB_Translate("Sign in failed. Authorization code missing.")); return; } // Get an access token from the authorization code. require_once SSO_ROOT_PATH . "/" . SSO_SUPPORT_PATH . "/http.php"; require_once SSO_ROOT_PATH . "/" . SSO_SUPPORT_PATH . "/web_browser.php"; $url = "https://accounts.google.com/o/oauth2/token"; $options = array("postvars" => array("code" => $_REQUEST["code"], "client_id" => $sso_settings["sso_google"]["client_id"], "client_secret" => $sso_settings["sso_google"]["client_secret"], "redirect_uri" => $redirect_uri, "grant_type" => "authorization_code")); $web = new WebBrowser(); $result = $web->Process($url, "auto", $options); if (!$result["success"]) { $this->DisplayError(BB_Translate("Sign in failed. Error retrieving URL for Google access token. %s", $result["error"])); } else { if ($result["response"]["code"] != 200) { $this->DisplayError(BB_Translate("Sign in failed. The Google access token server returned: %s", $result["response"]["code"] . " " . $result["response"]["meaning"])); } else { // Get the access token. $data = @json_decode($result["body"], true); if ($data === false || !isset($data["access_token"])) { $this->DisplayError(BB_Translate("Sign in failed. Error retrieving access token from Google.")); } else { // Get the user's profile information. $url = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" . urlencode($data["access_token"]); $result = $web->Process($url); if (!$result["success"]) { $this->DisplayError(BB_Translate("Sign in failed. Error retrieving URL for Google profile information. %s", $result["error"])); } else { if ($result["response"]["code"] != 200) { $this->DisplayError(BB_Translate("Sign in failed. The Google profile information server returned: %s", $result["response"]["code"] . " " . $result["response"]["meaning"])); } else { $profile = @json_decode($result["body"], true); if ($profile === false) { $this->DisplayError(BB_Translate("Sign in failed. Error retrieving profile information from Google.")); } $origprofile = $profile; // Remove unverified e-mail addresses. if (!isset($profile["verified_email"]) || !$profile["verified_email"]) { unset($profile["verified_email"]); unset($profile["email"]); } // Convert most profile fields into strings. foreach ($profile as $key => $val) { if (is_string($val)) { continue; } if (is_bool($val)) { $val = (string) (int) $val; } else { if (is_numeric($val)) { $val = (string) $val; } else { if (is_object($val) && isset($val->id) && isset($val->name)) { $val = $val->name; } } } $profile[$key] = $val; } $mapinfo = array(); foreach (self::$fieldmap as $key => $info) { $key2 = $sso_settings["sso_google"]["map_" . $key]; if ($key2 != "" && isset($profile[$key])) { $mapinfo[$key2] = $profile[$key]; } } SSO_ActivateUser($profile["id"], serialize($origprofile), $mapinfo); // Only falls through on account lockout or a fatal error. $this->DisplayError(BB_Translate("User activation failed.")); } } } } } } else { // Create internal data packet. $token = $sso_rng->GenerateString(); $sso_session_info["sso_google_info"] = array("lang" => isset($_REQUEST["lang"]) ? $_REQUEST["lang"] : "", "token" => $token, "expires" => CSDB::ConvertToDBTime(time() + 30 * 60)); if (!SSO_SaveSessionInfo()) { $this->DisplayError(BB_Translate("Unable to save session information.")); return; } // Calculate the required scope. $scope = array("https://www.googleapis.com/auth/userinfo.profile" => true); foreach (self::$fieldmap as $key => $info) { if ($info["extra"] != "" && $sso_settings["sso_google"]["map_" . $key] != "") { $scope[$info["extra"]] = true; } } // Get the login redirection URL. $options = array("response_type" => "code", "client_id" => $sso_settings["sso_google"]["client_id"], "redirect_uri" => $redirect_uri, "scope" => implode(" ", array_keys($scope)), "state" => $token); $options2 = array(); foreach ($options as $key => $val) { $options2[] = urlencode($key) . "=" . urlencode($val); } $url = "https://accounts.google.com/o/oauth2/auth?" . implode("&", $options2); SSO_ExternalRedirect($url); } } }
public function RunRowFilter(&$row, &$filteropts, &$fetchnext) { switch ($filteropts["mode"]) { case "INSERT": // Use the private function provided above to get the Last Inserted ID $this->lastid = $this->GetOracleInsertID($filteropts["queryinfo"][0]); break; } if (!$fetchnext) { parent::RunRowFilter($row, $filteropts, $fetchnext); } }
public function RunRowFilter(&$row, &$filteropts, &$fetchnext) { switch ($filteropts["mode"]) { case "INSERT": if ($row !== false) { $key = $filteropts["queryinfo"]["AUTO INCREMENT"]; $this->lastid = $row->{$key}; } break; } if (!$fetchnext) { parent::RunRowFilter($row, $filteropts, $fetchnext); } }
public function RunRowFilter(&$row, &$filteropts, &$fetchnext) { switch ($filteropts["mode"]) { case "SHOW DATABASES": if ($row !== false) { $row->name = $row->Database; unset($row->Database); } break; case "SHOW TABLES": if ($row !== false) { foreach ($row as $key => $val) { if (substr($key, 0, 10) == "Tables_in_") { $row->name = $val; unset($row->{$key}); } } } break; case "SHOW CREATE DATABASE": if ($row !== false) { $opts = array($row->Database); $str = $row->{"Create Database"}; $pos = strpos($str, "/*!40100"); if ($pos !== false) { $pos2 = strpos($str, "*/", $pos); if ($pos2 !== false) { $str = " " . trim(substr($str, $pos + 8, $pos2 - $pos - 8)) . " "; $pos = strpos($str, " CHARACTER SET "); if ($pos !== false) { $pos += 15; $pos2 = strpos($str, " ", $pos); if ($pos2 !== false) { $opts["CHARACTER SET"] = substr($str, $pos, $pos2 - $pos); } } $pos = strpos($str, " COLLATE "); if ($pos !== false) { $pos += 9; $pos2 = strpos($str, " ", $pos); if ($pos2 !== false) { $opts["COLLATE"] = substr($str, $pos, $pos2 - $pos); } } } } $row->cmd = "CREATE DATABASE"; $row->opts = $opts; } break; case "SHOW CREATE TABLE": if ($row !== false) { $opts = array($row->Table, array(), array()); $str = $row->{"Create Table"}; if (strtoupper(substr($str, 0, 23)) == "CREATE TEMPORARY TABLE ") { $opts["TEMPORARY"] = true; } $pos = stripos($str, " TABLE "); if ($pos !== false) { $str = substr($str, $pos + 7); $ident = true; $id = $this->ExtractIdentifier($str, $ident); $str = trim($str); if ($str[0] == "(") { $str = trim(substr($str, 1)); // Process columns and keys. $colextras = array("NOT NULL", "NULL", "DEFAULT", "AUTO_INCREMENT", "UNIQUE KEY", "UNIQUE", "PRIMARY KEY", "PRIMARY", "COMMENT", "REFERENCES"); $keytypes = array("CONSTRAINT" => true, "INDEX" => true, "KEY" => true, "FULLTEXT" => true, "SPATIAL" => true, "PRIMARY" => true, "UNIQUE" => true, "FOREIGN" => true, "CHECK" => true); $keyextras = array("PRIMARY KEY", "INDEX", "KEY", "UNIQUE INDEX", "UNIQUE KEY", "UNIQUE", "FULLTEXT INDEX", "FULLTEXT KEY", "FULLTEXT", "SPATIAL INDEX", "SPATIAL KEY", "SPATIAL", "FOREIGN KEY", "CHECK"); while ($str != "" && $str[0] != ")") { $id = $this->ExtractIdentifier($str, $ident); if ($ident || !isset($keytypes[strtoupper($id)])) { // Column. Extract data type and options/values. $pos = strpos($str, "("); $pos2 = strpos($str, " "); if ($pos === false) { $pos = strlen($str); } if ($pos2 === false) { $pos2 = strlen($str); } if ($pos < $pos2) { $type = substr($str, 0, $pos); $str = trim(substr($str, $pos + 1)); $typeopts = array(); while ($str != "" && $str[0] != ")") { $typeopts[] = $this->ExtractAndUnescapeValue($str); if ($str != "" && $str[0] == ",") { $str = trim(substr($str, 1)); } } $str = trim(substr($str, 1)); } else { $type = substr($str, 0, $pos2); $str = trim(substr($str, $pos2 + 1)); $typeopts = array(); } // Process data type. Stop processing on an unknown column type. $extras = array(); switch (strtoupper($type)) { case "BIT": $opts2 = array("INTEGER"); if (!count($typeopts) || $typeopts[0] <= 8) { $opts2[] = 1; } else { if ($typeopts[0] <= 16) { $opts2[] = 2; } else { if ($typeopts[0] <= 24) { $opts2[] = 3; } else { if ($typeopts[0] <= 32) { $opts2[] = 4; } else { $opts2[] = 8; } } } } $opts2["UNSIGNED"] = true; break; case "TINYINT": $opts2 = array("INTEGER", 1); $extras = array("UNSIGNED" => "keep", "ZEROFILL" => "ignore"); break; case "SMALLINT": $opts2 = array("INTEGER", 2); $extras = array("UNSIGNED" => "keep", "ZEROFILL" => "ignore"); break; case "MEDIUMINT": $opts2 = array("INTEGER", 3); $extras = array("UNSIGNED" => "keep", "ZEROFILL" => "ignore"); break; case "INT": case "INTEGER": $opts2 = array("INTEGER", 4); $extras = array("UNSIGNED" => "keep", "ZEROFILL" => "ignore"); break; case "BIGINT": $opts2 = array("INTEGER", 8); $extras = array("UNSIGNED" => "keep", "ZEROFILL" => "ignore"); break; case "DOUBLE": case "REAL": $opts2 = array("FLOAT", 8); $extras = array("UNSIGNED" => "ignore", "ZEROFILL" => "ignore"); break; case "FLOAT": $opts2 = array("FLOAT", 4); $extras = array("UNSIGNED" => "ignore", "ZEROFILL" => "ignore"); break; case "DECIMAL": case "NUMERIC": $opts2[] = array("DECIMAL", count($typeopts) ? $typeopts[0] : 10, count($typeopts) > 1 ? $typeopts[1] : 0); $extras = array("UNSIGNED" => "ignore", "ZEROFILL" => "ignore"); break; case "DATE": $opts2 = array("DATE"); break; case "TIME": $opts2 = array("TIME"); break; case "DATETIME": case "TIMESTAMP": $opts2 = array("DATETIME"); break; case "YEAR": $opts2 = array("INTEGER", 4); break; case "CHAR": $opts2 = array("STRING", 1, count($typeopts) ? $typeopts[0] : 255, "FIXED" => true); $extras = array("CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "VARCHAR": $opts2 = array("STRING", $typeopts[0] > 255 ? 2 : 1, $typeopts[0]); $extras = array("CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "TINYTEXT": $opts2 = array("STRING", 1, 255); $extras = array("BINARY" => "ignore", "CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "TEXT": $opts2 = array("STRING", 2); $extras = array("BINARY" => "ignore", "CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "MEDIUMTEXT": $opts2 = array("STRING", 3); $extras = array("BINARY" => "ignore", "CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "LONGTEXT": $opts2 = array("STRING", 4); $extras = array("BINARY" => "ignore", "CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "ENUM": $opts2 = array("STRING", 1, 255); $extras = array("CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "SET": $opts2 = array("STRING", 2); $extras = array("CHARACTER SET" => "ignore_with_opt", "COLLATE" => "ignore_with_opt"); break; case "BINARY": $opts2 = array("BINARY", 1, count($typeopts) ? $typeopts[0] : 255, "FIXED" => true); break; case "VARBINARY": $opts2 = array("BINARY", $typeopts[0] > 255 ? 2 : 1, $typeopts[0]); break; case "TINYBLOB": $opts2 = array("BINARY", 1, 255); break; case "BLOB": $opts2 = array("BINARY", 2); break; case "MEDIUMBLOB": $opts2 = array("BINARY", 3); break; case "LONGBLOB": $opts2 = array("BINARY", 4); break; default: return; } do { $found = false; foreach ($extras as $extra => $rule) { if (strtoupper(substr($str, 0, strlen($extra))) == $extra) { $str = trim(substr($str, strlen($extra))); if ($rule == "keep") { $opts2[$extra] = true; } else { if ($rule == "ignore_with_opt") { $this->ExtractIdentifier($str, $ident); } } $found = true; } } } while ($found); while ($str != "" && $str[0] != "," && $str[0] != ")") { foreach ($colextras as $extra) { if (strtoupper(substr($str, 0, strlen($extra))) == $extra) { $str = trim(substr($str, strlen($extra))); switch ($extra) { case "NOT NULL": $opts2["NOT NULL"] = true; break; case "NULL": break; case "DEFAULT": $opts2["DEFAULT"] = $this->ExtractAndUnescapeValue($str); break; case "AUTO_INCREMENT": $opts2["AUTO INCREMENT"] = true; break; case "UNIQUE KEY": case "UNIQUE": $opts2["UNIQUE KEY"] = true; break; case "PRIMARY KEY": case "PRIMARY": $opts2["PRIMARY KEY"] = true; break; case "COMMENT": $opts2["COMMENT"] = $this->ExtractAndUnescapeValue($str); break; case "REFERENCES": $opts2["REFERENCES"] = $this->ExtractReferencesInfo($str); break; } } } } if (isset($filteropts["hints"]) && isset($filteropts["hints"][$id])) { $opts2 = $filteropts["hints"][$id]; } $opts[1][$id] = $opts2; } else { // Key or constraint. $opts2 = array(); if (strtoupper($id) == "CONSTRAINT") { $id = $this->ExtractIdentifier($str, $ident); $id2 = strtoupper($id); if ($ident || !isset($keytypes[strtoupper($id)])) { $opts2["CONSTRAINT"] = $id; $id = $this->ExtractIdentifier($str, $ident); } } $str = $id . " " . $str; foreach ($keyextras as $extra) { if (strtoupper(substr($str, 0, strlen($extra))) == $extra) { $str = trim(substr($str, strlen($extra))); switch ($extra) { case "PRIMARY KEY": $opts2[] = "PRIMARY"; while ($str != "" && $str[0] != "(") { $id = $this->ExtractIdentifier($str, $ident); if (!$ident && strtoupper($id) == "USING") { $opts2["USING"] = $this->ExtractIdentifier($str, $ident); } } $opts2[] = $this->ExtractMultipleIdentifiers($str); break; case "INDEX": case "KEY": $opts2[] = "KEY"; while ($str != "" && $str[0] != "(") { $id = $this->ExtractIdentifier($str, $ident); if (!$ident && strtoupper($id) == "USING") { $opts2["USING"] = $this->ExtractIdentifier($str, $ident); } else { $opts2["NAME"] = $id; } } $opts2[] = $this->ExtractMultipleIdentifiers($str); break; case "UNIQUE INDEX": case "UNIQUE KEY": case "UNIQUE": $opts2[] = "UNIQUE"; while ($str != "" && $str[0] != "(") { $id = $this->ExtractIdentifier($str, $ident); if (!$ident && strtoupper($id) == "USING") { $opts2["USING"] = $this->ExtractIdentifier($str, $ident); } else { $opts2["NAME"] = $id; } } $opts2[] = $this->ExtractMultipleIdentifiers($str); break; case "FULLTEXT INDEX": case "FULLTEXT KEY": case "FULLTEXT": $opts2[] = "FULLTEXT"; while ($str != "" && $str[0] != "(") { $opts2["NAME"] = $this->ExtractIdentifier($str, $ident); } $opts2[] = $this->ExtractMultipleIdentifiers($str); break; case "SPATIAL INDEX": case "SPATIAL KEY": case "SPATIAL": // GIS is not portable. while ($str != "" && $str[0] != "(") { $this->ExtractIdentifier($str, $ident); } $this->ExtractMultipleIdentifiers($str); break; case "FOREIGN KEY": $opts2[] = "FOREIGN"; while ($str != "" && $str[0] != "(") { $opts2["NAME"] = $this->ExtractIdentifier($str, $ident); } $opts2[] = $this->ExtractMultipleIdentifiers($str); $opts2[] = $this->ExtractReferencesInfo($str); break; case "CHECK": $pos = strpos($str, ")"); $str = substr($str, $pos + 1); break; } } } while ($str != "" && $str[0] != "," && $str[0] != ")") { $id = $this->ExtractIdentifier($str, $ident); if (!$ident && strtoupper($id) == "USING") { $opts2["USING"] = $this->ExtractIdentifier($str, $ident); } } if (isset($opts2[0])) { $opts[2][] = $opts2; } } if ($str != "" && $str[0] == ",") { $str = trim(substr($str, 1)); } $str = trim($str); } // Process the last line. $str = trim(substr($str, 1)); $extras = array("ENGINE", "TYPE", "AUTO_INCREMENT", "AVG_ROW_LENGTH", "DEFAULT CHARACTER SET", "CHARACTER SET", "DEFAULT CHARSET", "CHARSET", "CHECKSUM", "DEFAULT COLLATE", "COLLATE", "COMMENT", "CONNECTION", "DATA DIRECTORY", "DELAY_KEY_WRITE", "INDEX DIRECTORY", "INSERT_METHOD", "MAX_ROWS", "MIN_ROWS", "PACK_KEYS", "PASSWORD", "ROW_FORMAT"); do { $found = false; foreach ($extras as $extra) { if (strtoupper(substr($str, 0, strlen($extra))) == $extra) { $str = trim(substr($str, strlen($extra))); if ($str[0] == "=") { $str = trim(substr($str, 1)); } switch ($extra) { case "ENGINE": case "TYPE": $opts["ENGINE"] = $this->ExtractAndUnescapeValue($str); break; case "DEFAULT CHARACTER SET": case "CHARACTER SET": case "DEFAULT CHARSET": case "CHARSET": $opts["CHARACTER SET"] = $this->ExtractAndUnescapeValue($str); break; case "DEFAULT COLLATE": case "COLLATE": $opts["COLLATE"] = $this->ExtractAndUnescapeValue($str); break; case "AUTO_INCREMENT": case "AVG_ROW_LENGTH": case "CHECKSUM": case "COMMENT": case "CONNECTION": case "DATA DIRECTORY": case "DELAY_KEY_WRITE": case "INDEX DIRECTORY": case "INSERT_METHOD": case "MAX_ROWS": case "MIN_ROWS": case "PACK_KEYS": case "PASSWORD": case "ROW_FORMAT": $this->ExtractAndUnescapeValue($str); break; } $found = true; } } } while ($found); } } $row->cmd = "CREATE TABLE"; $row->opts = $opts; } break; } parent::RunRowFilter($row, $filteropts, $fetchnext); }
public function CustomFrontend() { global $g_sso_login_modules, $sso_settings, $sso_header, $sso_footer, $sso_target_url, $sso_db, $sso_session_info, $sso_rng; $messages = array("errors" => array(), "warnings" => array(), "success" => ""); $info = $this->GetInfo(); if ($info["cookiekey"] != "" && $info["cookieiv"] != "" && $info["cookiekey2"] != "" && $info["cookieiv2"] != "") { // Initialize active modules. $this->activemodules = array(); foreach ($g_sso_login_modules as $key => $info2) { if ($sso_settings["sso_login"]["modules"][$key]["_a"]) { $module = "sso_login_module_" . $key; $this->activemodules[$key] = new $module(); } } $sso_db_sso_login_users = SSO_DB_PREFIX . "p_sso_login_users"; if (isset($_REQUEST["id"]) && isset($_COOKIE["sso_l_rme"])) { // Decrypt data. $info2 = @base64_decode($_COOKIE["sso_l_rme"]); if ($info2 !== false) { $info2 = Blowfish::ExtractDataPacket($info2, pack("H*", $info["cookiekey"]), array("mode" => "CBC", "iv" => pack("H*", $info["cookieiv"]), "key2" => pack("H*", $info["cookiekey2"]), "iv2" => pack("H*", $info["cookieiv2"]), "lightweight" => true)); } if ($info2 !== false) { $info2 = @unserialize($info2); } if ($info2 !== false) { $id = (int) $_REQUEST["id"]; if (isset($info2[$id]) && is_array($info2[$id]) && count($info2[$id]) == 2) { // Load database information and verify the sign in. $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "id = ?"), $sso_db_sso_login_users, $id); if ($userrow && (!isset($userrow->verified) || $userrow->verified)) { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo !== false && isset($userinfo["sso_remember_me"]) && isset($userinfo["sso_remember_me"][$info2[$userrow->id][0]])) { $info3 = $userinfo["sso_remember_me"][$info2[$userrow->id][0]]; $ts = CSDB::ConvertFromDBTime($info3["expires"]); if ($ts > time()) { $data = $info3["salt"] . ":" . $info2[$userrow->id][1]; if (sso_login::VerifyPasswordInfo($data, $info3["hash"], $info3["rounds"])) { // Sign in is now verified to be valid. if (!$info3["bypass"] && ($sso_settings["sso_login"]["require_two_factor"] || isset($userinfo["two_factor_method"]) && $userinfo["two_factor_method"] != "")) { // Go to two-factor authentication page. $methods = array(); foreach ($this->activemodules as $key => &$instance) { $name = $instance->GetTwoFactorName(false); if ($name !== false) { $methods[$key] = true; } } if ($sso_settings["sso_login"]["require_two_factor"] && (!isset($userinfo["two_factor_method"]) || !isset($methods[$userinfo["two_factor_method"]]))) { $messages["errors"][] = BB_Translate("A valid two-factor authentication method for this account is not available. Use account recovery to restore access to the account."); } else { $sso_session_info["sso_login_two_factor"] = array("id" => $userrow->id, "v" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 5 * 60)); if (!SSO_SaveSessionInfo()) { $messages["errors"][] = BB_Translate("Login exists but a fatal error occurred. Fatal error: Unable to save session information."); } else { $this->activemodules[$userinfo["two_factor_method"]]->SendTwoFactorCode($messages, $userrow, $userinfo); if (!count($messages["errors"])) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=two_factor&sso_v=" . urlencode($sso_session_info["sso_login_two_factor"]["v"])); exit; } } } } else { // Login succeeded. Activate the user. $mapinfo = array(); if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { $mapinfo[$sso_settings["sso_login"]["map_email"]] = $userrow->email; } if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username") { $mapinfo[$sso_settings["sso_login"]["map_username"]] = $userrow->username; } $origuserinfo = $userinfo; foreach ($this->activemodules as &$instance) { $instance->LoginAddMap($mapinfo, $userrow, $userinfo, false); } // If a module updated $userinfo, then update the database. if (serialize($userinfo) !== serialize($origuserinfo)) { $userinfo2 = SSO_EncryptDBData($userinfo); try { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } } if (!count($messages["errors"])) { SSO_ActivateUser($userrow->id, $userinfo["extra"], $mapinfo, CSDB::ConvertFromDBTime($userrow->created)); // Only falls through on account lockout or a fatal error. $messages["errors"][] = BB_Translate("User activation failed."); } } } } } } } } } echo $sso_header; SSO_OutputHeartbeat(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <div class="sso_main_messages_wrap"> <div class="sso_main_messages"> <?php if (count($messages["errors"])) { ?> <div class="sso_main_messageerror"><?php echo htmlspecialchars($messages["errors"][0]); ?> </div> <?php } ?> <div class="sso_main_messageerror"><?php echo htmlspecialchars(BB_Translate("An error occurred while processing the remembered sign in. You will have to sign in normally.")); ?> </div> </div> </div> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> </div> </div> <?php echo $sso_footer; } }
public function ProcessFrontend() { global $sso_settings, $sso_rng, $sso_provider, $sso_target_url, $sso_session_info, $sso_session_id, $sso_db; if (isset($sso_session_info["setlogin_result"]) && !isset($_REQUEST["tryagain"])) { // Check the secret. if (!isset($_REQUEST["sso_setlogin_secret"]) || !isset($sso_session_info["setlogin_info"]) || $_REQUEST["sso_setlogin_secret"] !== $sso_session_info["setlogin_info"]["secret"]) { $this->DisplayError(BB_Translate("Unable to authenticate the request.")); return; } // Should be nearly impossible to get here since browser redirects are executed almost immediately. if (CSDB::ConvertFromDBTime($sso_session_info["setlogin_info"]["expires"]) < time()) { $this->DisplayError(BB_Translate("Verification token has expired.")); return; } // The user is signed in. Activate the account. $sso_db_sso_remote_users = SSO_DB_PREFIX . "p_sso_remote_users"; try { $id = $sso_db->GetOne("SELECT", array("id", "FROM" => "?", "WHERE" => "remote_id = ? AND user_id = ?"), $sso_db_sso_remote_users, $this->info["row"]->id, $sso_session_info["setlogin_result"]["user_id"]); if ($id === false) { $sso_db->Query("INSERT", array($sso_db_sso_remote_users, array("remote_id" => $this->info["row"]->id, "user_id" => $sso_session_info["setlogin_result"]["user_id"], "created" => CSDB::ConvertToDBTime(time())), "AUTO INCREMENT" => "id")); $id = $sso_db->GetInsertID(); } $mapinfo = $sso_session_info["setlogin_result"]["protected_fields"]; $mapinfo[$sso_settings["sso_remote"]["map_remote_id"]] = $this->info["row"]->id; SSO_ActivateUser($id, serialize($sso_session_info["setlogin_info"]), $mapinfo, false, $this->info["row_info"]["automate"]); // Only falls through on account lockout or a fatal error. $this->DisplayError(BB_Translate("User activation failed.")); } catch (Exception $e) { $this->DisplayError("A database error has occurred. Most likely cause: Bad SQL query."); } } else { // Check the API key information. $info = unserialize($this->info["apirow"]->info); if ($info["type"] != "remote") { $this->DisplayError(BB_Translate("The target client API key is not a remote API key.")); return; } if ($info["url"] == "") { $this->DisplayError(BB_Translate("The target client API key URL is missing.")); return; } // Set up the session so that the endpoint works. unset($sso_session_info["setlogin_result"]); $token = $sso_rng->GenerateString(); $sso_session_info["setlogin_info"] = array("provider" => $sso_provider, "apikey_id" => $this->info["apirow"]->id, "redirect_url" => BB_GetRequestHost() . $sso_target_url, "token" => $token, "secret" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 30 * 60)); if (!SSO_SaveSessionInfo()) { $this->DisplayError(BB_Translate("Unable to save session information.")); return; } // Redirect to the remote host. $url = $info["url"] . (strpos($info["url"], "?") === false ? "?" : "&") . "from_sso_server=1&sso_setlogin_id=" . urlencode($sso_session_id[1]) . "&sso_setlogin_token=" . urlencode($token) . (isset($_REQUEST["lang"]) ? "&sso_lang=" . urlencode($_REQUEST["lang"]) : ""); SSO_ExternalRedirect($url); } }
function SSO_ValidateUser() { global $sso_rng, $sso_db, $sso_db_user_sessions, $sso_db_temp_sessions, $sso_session_info, $sso_apirow, $sso_sessionrow, $sso_sessionrow2, $sso_ipaddr, $sso_settings; try { // Browser gets a token representing the new session in the temporary session. $sso_session_info["new_id2"] = $sso_rng->GenerateString(); $sso_db->Query("UPDATE", array($sso_db_temp_sessions, array("info" => serialize($sso_session_info)), "WHERE" => "id = ?"), $sso_sessionrow->id); // Validate the session. $sso_db->Query("UPDATE", array($sso_db_user_sessions, array("updated" => CSDB::ConvertToDBTime(time()), "info" => serialize(array("validated" => true, "ipaddr" => $sso_ipaddr["ipv6"]))), "WHERE" => "id = ?"), $sso_sessionrow2->id); // Build the redirect. $redirect = str_replace(array("\r", "\n"), "", base64_decode($sso_session_info["url"])); $redirect .= (strpos($redirect, "?") === false ? "?" : "&") . "from_sso_server=1&sso_id=" . urlencode($sso_session_info["new_id2"]) . "&sso_id2=" . urlencode($_REQUEST["sso_id"]); // Set the namespace cookie. if (isset($sso_settings[""]["namespacekey2"])) { $namespaces = SSO_LoadNamespaces(true); $namespaces[$sso_apirow->namespace] = $_COOKIE["sso_server_id2"]; $data = serialize($namespaces); $data = base64_encode(Blowfish::CreateDataPacket($data, pack("H*", $sso_settings[""]["namespacekey"]), array("prefix" => $sso_rng->GenerateString(), "mode" => "CBC", "iv" => pack("H*", $sso_settings[""]["namespaceiv"]), "key2" => pack("H*", $sso_settings[""]["namespacekey2"]), "iv2" => pack("H*", $sso_settings[""]["namespaceiv2"]), "lightweight" => true))); SetCookieFixDomain("sso_server_ns", $data, 0, "", "", SSO_IsSSLRequest(), true); } // Set the exposed namespace cookie if the option is enabled. if (isset($sso_settings[""]["expose_namespaces"]) && $sso_settings[""]["expose_namespaces"] && isset($sso_settings[""]["namespacekey4"])) { $namespaces = SSO_LoadNamespaces(false); $namespaces[$sso_apirow->namespace] = $sso_sessionrow2->id; $data = serialize($namespaces); $data = base64_encode(Blowfish::CreateDataPacket($data, pack("H*", $sso_settings[""]["namespacekey3"]), array("prefix" => $sso_rng->GenerateString(), "mode" => "CBC", "iv" => pack("H*", $sso_settings[""]["namespaceiv3"]), "key2" => pack("H*", $sso_settings[""]["namespacekey4"]), "iv2" => pack("H*", $sso_settings[""]["namespaceiv4"]), "lightweight" => true))); $host = str_replace(array("http://", "https://"), "", BB_GetRequestHost()); SetCookieFixDomain("sso_server_ns2", $data, 0, "/", $host, false, true); } // Redirect back to the client. SSO_ExternalRedirect($redirect, true); } catch (Exception $e) { // Don't do anything here. Just catch the database exception and let the code fall through. // It should be nearly impossible to get here in the first place. } return false; }
$db->Query("CREATE TABLE", array($sso_db_tags, array("id" => array("INTEGER", 4, "UNSIGNED" => true, "NOT NULL" => true, "PRIMARY KEY" => true, "AUTO INCREMENT" => true), "tag_name" => array("STRING", 1, 50, "NOT NULL" => true), "tag_desc" => array("STRING", 1, 255, "NOT NULL" => true), "enabled" => array("INTEGER", 1, "NOT NULL" => true), "created" => array("DATETIME", "NOT NULL" => true)), array(array("UNIQUE", array("tag_name"), "NAME" => $sso_db_tags . "_tag_name")))); } catch (Exception $e) { InstallError("Unable to create the database table '" . htmlspecialchars($sso_db_tags) . "'. " . htmlspecialchars($e->getMessage())); } try { $db->Query("INSERT", array($sso_db_tags, array("tag_name" => $_REQUEST["sso_site_admin"], "tag_desc" => "", "enabled" => 1, "created" => CSDB::ConvertToDBTime(time())))); } catch (Exception $e) { InstallError("Unable to insert '" . htmlspecialchars($_REQUEST["sso_site_admin"]) . "' into database table '" . htmlspecialchars($sso_db_tags) . "'. " . htmlspecialchars($e->getMessage())); } try { $db->Query("INSERT", array($sso_db_tags, array("tag_name" => $_REQUEST["sso_admin"], "tag_desc" => "", "enabled" => 1, "created" => CSDB::ConvertToDBTime(time())))); } catch (Exception $e) { InstallError("Unable to insert '" . htmlspecialchars($_REQUEST["sso_admin"]) . "' into database table '" . htmlspecialchars($sso_db_tags) . "'. " . htmlspecialchars($e->getMessage())); } try { $db->Query("INSERT", array($sso_db_tags, array("tag_name" => $_REQUEST["sso_locked"], "tag_desc" => "", "enabled" => 1, "created" => CSDB::ConvertToDBTime(time())))); } catch (Exception $e) { InstallError("Unable to insert '" . htmlspecialchars($_REQUEST["sso_locked"]) . "' into database table '" . htmlspecialchars($sso_db_tags) . "'. " . htmlspecialchars($e->getMessage())); } } if (!$ipcachefound) { try { $db->Query("CREATE TABLE", array($sso_db_ipcache, array("id" => array("INTEGER", 8, "UNSIGNED" => true, "NOT NULL" => true, "PRIMARY KEY" => true, "AUTO INCREMENT" => true), "ipaddr" => array("STRING", 1, 50, "NOT NULL" => true), "created" => array("DATETIME", "NOT NULL" => true), "info" => array("STRING", 3, "NOT NULL" => true)), array(array("UNIQUE", array("ipaddr"), "NAME" => $sso_db_ipcache . "_ipaddr"), array("KEY", array("created"), "NAME" => $sso_db_ipcache . "_created")))); } catch (Exception $e) { InstallError("Unable to create the database table '" . htmlspecialchars($sso_db_ipcache) . "'. " . htmlspecialchars($e->getMessage())); } } InstallSuccess("Successfully created database tables and data in '" . htmlspecialchars($_REQUEST["db_name"]) . "'."); $sso_fields = array(); $sso_settings = array(); if (!SSO_SaveSettings()) {
BB_SetPageMessage("error", "Please specify an IP address or pattern."); } $ts = time(); $result = $sso_db->Query("SELECT", array("*", "FROM" => "?", "WHERE" => "created >= ?", "ORDER BY" => "created DESC"), $sso_db_ipcache, CSDB::ConvertToDBTime(time() - 2 * 24 * 60 * 60)); while ($row = $result->NextRow()) { $ipaddr = IPAddr::NormalizeIP($row->ipaddr); $info = unserialize($row->info); $spammer = false; if (isset($info["spaminfo"])) { foreach ($sso_providers as $provider => &$instance) { if (isset($info["spaminfo"][$provider]) && $info["spaminfo"][$provider]["spammer"]) { $spammer = true; } } } $rows[] = array(htmlspecialchars($ipaddr["ipv4"] != "" ? $ipaddr["ipv4"] : $ipaddr["shortipv6"]), htmlspecialchars(BB_Translate($spammer ? "Yes" : "No")), BB_FormatTimestamp("M j, Y @ g:i A", CSDB::ConvertFromDBTime($row->created)), "<a href=\"" . BB_GetRequestURLBase() . "?action=viewipaddr&id=" . $row->id . "&sec_t=" . BB_CreateSecurityToken("viewipaddr") . "\">" . htmlspecialchars(BB_Translate("View")) . "</a>"); } $table = array("title" => "Last 48 Hours", "type" => "table", "cols" => array("IP Address", "Spammer?", "Created", "Options"), "rows" => $rows, "desc" => "New IP addresses in the last 48 hours."); } $contentopts = array("desc" => "Manage the IP address cache.", "htmldesc" => $desc, "nonce" => "action", "hidden" => array("action" => "manageipcache"), "fields" => array($table, "split", array("title" => "Find IP Address", "type" => "text", "name" => "ipaddr", "value" => BB_GetValue("ipaddr", ""), "desc" => "Enter an IP address or IP address pattern to search for. (e.g. '10.0.0-15,17.*')")), "submit" => "Search", "focus" => false); BB_GeneratePage("Manage IP Cache", $sso_menuopts, $contentopts); } else { if ($sso_site_admin && isset($_REQUEST["action"]) && $_REQUEST["action"] == "resetsessions") { $sso_db->Query("TRUNCATE TABLE", array($sso_db_user_sessions)); $sso_db->Query("TRUNCATE TABLE", array($sso_db_temp_sessions)); BB_RedirectPage("success", "Successfully reset all sessions."); } else { $contentopts = array("desc" => "Pick an option from the menu."); BB_GeneratePage("Home", $sso_menuopts, $contentopts); } }
BB_SetLanguage(SSO_ROOT_PATH . "/" . SSO_LANG_PATH . "/", SSO_ADMIN_LANG); // Initialize the global CSPRNG instance. $sso_rng = new CSPRNG(); // Connect to the database and generate database globals. SSO_DBConnect(true); // Load in fields without admin select. SSO_LoadFields(false); // Load in $sso_settings and initialize it. SSO_LoadSettings(); // Get system clock drift. $sso_clockdrift = isset($sso_settings[""]["clock_drift"]) ? $sso_settings[""]["clock_drift"] : 300; // Allow developers to inject code here. if (file_exists(SSO_ROOT_PATH . "/cron_hook.php")) { require_once SSO_ROOT_PATH . "/cron_hook.php"; } // Run cleanup queries. try { $sso_db->Query("DELETE", array($sso_db_temp_sessions, "WHERE" => "updated < ?"), CSDB::ConvertToDBTime(time() - 60 * 60)); $sso_db->Query("DELETE", array($sso_db_temp_sessions, "WHERE" => "heartbeat = ? AND updated < ?"), SSO_HEARTBEAT_LIMIT, CSDB::ConvertToDBTime(time() - $sso_clockdrift)); $sso_db->Query("DELETE", array($sso_db_user_sessions, "WHERE" => "updated < ?"), CSDB::ConvertToDBTime(time() - $sso_clockdrift)); $sso_db->Query("DELETE", array($sso_db_ipcache, "WHERE" => "created < ?"), CSDB::ConvertToDBTime(time() - 24 * 60 * 60 * $sso_settings[""]["iprestrict"]["ip_cache_len"])); } catch (Exception $e) { echo "Database query error. " . $e->getMessage() . "\n\n"; } if ($sso_verbose) { echo "Time taken: " . number_format(microtime(true) - $sso_start, 2) . " sec\n"; if (function_exists("memory_get_peak_usage")) { echo "Maximum RAM used: " . number_format(memory_get_peak_usage(), 0) . "\n"; } echo "Done.\n"; }
if (isset($sso_session_info2["new_id"]) && isset($sso_session_info2["rid"]) && $sso_session_info2["new_id"] == $sso_data["sso_id"] && $sso_session_info2["rid"] == $sso_data["rid"]) { if (!isset($sso_data["delete_old"]) || $sso_data["delete_old"] == 0) { $result["rinfo"] = base64_decode($sso_sessionrow2->recoverinfo); } else { $sso_db->Query("DELETE", array($sso_db_temp_sessions, "WHERE" => "id = ?"), $sso_sessionrow2->id); $result = array("success" => true); } } } } if (!$result["success"]) { SSO_EndpointError("Unable to delete the old session."); } // Update the user session. if (!isset($sso_data["delete_old"]) || $sso_data["delete_old"] == 0) { $sso_db->Query("UPDATE", array($sso_db_user_sessions, array("updated" => CSDB::ConvertToDBTime(time() + (int) $sso_data["expires"])), "WHERE" => "id = ?"), $sso_sessionrow->id); } // Update the user account. if ($userupdated) { $info2 = $sso_user_info; $info3 = SSO_CreateEncryptedUserInfo($info2); $sso_db->Query("UPDATE", array($sso_db_users, array("info" => serialize($info2), "info2" => $info3), "WHERE" => "id = ?"), $sso_userrow->id); } SSO_EndpointOutput($result); } else { if ($sso_data["action"] == "logout") { if ($sso_apikey_info["type"] != "normal") { SSO_EndpointError("Invalid API key type."); } // Remove the session and all sessions in the same namespace. if (!isset($sso_data["sso_id"])) {
private function UpdateIPAddrInfo($inclogins) { global $sso_ipaddr_info; $info = $this->GetInfo(); if (isset($sso_ipaddr_info["sso_login_modules"]["sso_recaptcha"])) { $result = $sso_ipaddr_info["sso_login_modules"]["sso_recaptcha"]; } else { $result = array("ts" => CSDB::ConvertToDBTime(time()), "logins" => 0); } // Check expirations and reset if necessary. if (CSDB::ConvertFromDBTime($result["ts"]) < time() - $info["login_interval"]) { $result["ts"] = CSDB::ConvertToDBTime(time()); $result["logins"] = 0; } // Increment requested. if ($inclogins && $result["logins"] < $info["login_attempts"]) { $result["logins"]++; } $sso_ipaddr_info["sso_login_modules"]["sso_recaptcha"] = $result; // Save the information. SSO_SaveIPAddrInfo(); }
public function ProcessFrontend() { global $g_sso_login_modules, $sso_settings, $sso_rng, $sso_header, $sso_footer, $sso_target_url, $sso_db, $sso_ipaddr_info, $sso_session_info, $sso_providers; if (!isset($sso_ipaddr_info["sso_login_modules"])) { $sso_ipaddr_info["sso_login_modules"] = array(); } // Initialize active modules. $this->activemodules = array(); foreach ($g_sso_login_modules as $key => $info) { if ($sso_settings["sso_login"]["modules"][$key]["_a"]) { $module = "sso_login_module_" . $key; $this->activemodules[$key] = new $module(); } } $sso_db_sso_login_users = SSO_DB_PREFIX . "p_sso_login_users"; if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "module" && isset($_REQUEST["sso_login_module"]) && isset($this->activemodules[$_REQUEST["sso_login_module"]])) { $this->activemodules[$_REQUEST["sso_login_module"]]->CustomFrontend(); } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "verify" && $sso_settings["sso_login"]["open_reg"]) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->VerifyCheck($messages); } if (!count($messages["errors"])) { if (!isset($_REQUEST["sso_v"]) || !isset($sso_session_info["sso_login_verify"])) { $messages["errors"][] = BB_Translate("Invalid URL. Verification missing."); } else { if (trim($_REQUEST["sso_v"]) !== $sso_session_info["sso_login_verify"]["v"]) { $messages["errors"][] = BB_Translate("Invalid verification string specified."); } else { try { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("verified" => 1), "WHERE" => "id = ?"), $sso_session_info["sso_login_verify"]["id"]); } catch (Exception $e) { $messages["errors"][] = BB_Translate("Verification failed. Database query error."); } if (!count($messages["errors"])) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_msg=verified"); exit; } } } } echo $sso_header; SSO_OutputHeartbeat(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, false); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> </div> </div> <?php echo $sso_footer; } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "signup_check" && $sso_settings["sso_login"]["open_reg"]) { $result = $this->SignupUpdateCheck(true, false, false, false); foreach ($result["errors"] as $error) { echo "<div class=\"sso_main_formerror\">" . htmlspecialchars($error) . "</div>"; } foreach ($result["warnings"] as $warning) { echo "<div class=\"sso_main_formwarning\">" . htmlspecialchars($warning) . "</div>"; } if (!count($result["errors"]) && !count($result["warnings"])) { if ($result["success"] != "") { echo "<div class=\"sso_main_formokay\">" . htmlspecialchars($result["success"]) . "</div>"; } else { if (isset($result["htmlsuccess"]) && $result["htmlsuccess"] != "") { echo "<div class=\"sso_main_formokay\">" . $result["htmlsuccess"] . "</div>"; } } } } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "signup" && $sso_settings["sso_login"]["open_reg"]) { if (SSO_FrontendFieldValue("submit") === false) { $messages = false; } else { $messages = $this->SignupUpdateCheck(false, false, false, false); if (!count($messages["errors"])) { // Create the account. $username = SSO_FrontendFieldValue("username", ""); $email = SSO_FrontendFieldValue("email", ""); $verified = true; if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { $result = SMTP::MakeValidEmailAddress($email); $email = $result["email"]; $verified = $sso_settings["sso_login"]["email_verify_subject"] == "" || $sso_settings["sso_login"]["email_verify_msg"] == ""; } $salt = $sso_rng->GenerateString(); $data = $username . ":" . $email . ":" . $salt . ":" . SSO_FrontendFieldValue("createpass"); $passwordinfo = self::HashPasswordInfo($data, $sso_settings["sso_login"]["password_mode"], $sso_settings["sso_login"]["password_minrounds"]); if (!$passwordinfo["success"]) { $messages["errors"][] = BB_Translate("Unexpected cryptography error."); } else { $userinfo = array(); $userinfo["extra"] = $sso_rng->GenerateString(); $userinfo["two_factor_key"] = $sso_session_info["sso_login_two_factor_key"]; $userinfo["two_factor_method"] = SSO_FrontendFieldValue("two_factor_method", ""); foreach ($this->activemodules as &$instance) { $instance->SignupAddInfo($userinfo, false); } $userinfo["salt"] = $salt; $userinfo["rounds"] = (int) $passwordinfo["rounds"]; $userinfo["password"] = bin2hex($passwordinfo["hash"]); $userinfo2 = SSO_EncryptDBData($userinfo); try { if ($sso_settings["sso_login"]["install_type"] == "email_username") { $sso_db->Query("INSERT", array($sso_db_sso_login_users, array("username" => $username, "email" => $email, "verified" => (int) $verified, "created" => CSDB::ConvertToDBTime(time()), "info" => $userinfo2), "AUTO INCREMENT" => "id")); } else { if ($sso_settings["sso_login"]["install_type"] == "email") { $sso_db->Query("INSERT", array($sso_db_sso_login_users, array("email" => $email, "verified" => (int) $verified, "created" => CSDB::ConvertToDBTime(time()), "info" => $userinfo2), "AUTO INCREMENT" => "id")); } else { if ($sso_settings["sso_login"]["install_type"] == "username") { $sso_db->Query("INSERT", array($sso_db_sso_login_users, array("username" => $username, "created" => CSDB::ConvertToDBTime(time()), "info" => $userinfo2), "AUTO INCREMENT" => "id")); } else { $messages["errors"][] = BB_Translate("Fatal error: Login system is broken."); } } } // Send verification e-mail. if (!count($messages["errors"])) { $userid = $sso_db->GetInsertID(); } if (!count($messages["errors"]) && !$verified) { $this->SendVerificationEmail($userid, $userinfo, $messages, $username, $email); } } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } if (!count($messages["errors"])) { foreach ($this->activemodules as &$instance) { $instance->SignupDone($userid, false); } header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_msg=" . ($verified ? "verified" : "verify")); exit; } } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS($sso_target_url . "&sso_login_action=signup_check&sso_ajax=1"); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> <div class="sso_main_form_wrap sso_login_signup_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Sign up")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=signup"); ?> " autocomplete="off"> <?php if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Your E-mail Address")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text sso_login_changehook" type="text" name="<?php echo SSO_FrontendField("email"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("email", "")); ?> " /></div> </div> <?php } if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username") { ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Choose Username")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text sso_login_changehook" type="text" name="<?php echo SSO_FrontendField("username"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("username", "")); ?> " /></div> </div> <?php } ?> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Choose Password")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text sso_login_changehook" type="password" name="<?php echo SSO_FrontendField("createpass"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("createpass", "")); ?> " /></div> </div> <?php $outputmap = array(); // Two-factor authentication dropdown. $outputmap2 = array(); $method = SSO_FrontendFieldValue("two_factor_method", ""); foreach ($this->activemodules as $key => &$instance) { $name = $instance->GetTwoFactorName(); if ($name !== false) { $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap2, $order, $key, "<option value=\"" . htmlspecialchars($key) . "\"" . ($method == $key ? " selected" : "") . ">" . htmlspecialchars($name) . "</option>"); } } if (!$sso_settings["sso_login"]["require_two_factor"] && count($outputmap2)) { SSO_AddSortedOutput($outputmap2, 0, "", "<option value=\"\"" . ($method == "" ? " selected" : "") . ">" . htmlspecialchars(BB_Translate("None")) . "</option>"); } if (count($outputmap2)) { if (!isset($sso_session_info["sso_login_two_factor_key"])) { $sso_session_info["sso_login_two_factor_key"] = self::GenerateOTPKey(10); SSO_SaveSessionInfo(); } ob_start(); ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Choose Two-Factor Authentication Method")); ?> </div> <div class="sso_main_formdata"><select class="sso_main_dropdown sso_login_changehook_two_factor" name="<?php echo SSO_FrontendField("two_factor_method"); ?> "> <?php SSO_DisplaySortedOutput($outputmap2); ?> </select></div> <div class="sso_main_formdesc"><?php echo htmlspecialchars(BB_Translate($sso_settings["sso_login"]["require_two_factor"] ? "Required. Two-factor authentication vastly improves the security of your account." : "Optional. Two-factor authentication vastly improves the security of your account.")); ?> </div> </div> <?php $order = $sso_settings["sso_login"]["two_factor_order"]; SSO_AddSortedOutput($outputmap, $order, "two_factor", ob_get_contents()); ob_end_clean(); } // Add active module output. foreach ($this->activemodules as $key => &$instance) { ob_start(); $instance->GenerateSignup(false); $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap, $order, $key, ob_get_contents()); ob_end_clean(); } SSO_DisplaySortedOutput($outputmap); ?> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Sign up")); ?> " /> </div> </form> </div> </div> </div> <?php echo $sso_footer; } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "update_info") { // Check the session and load the user account. $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->UpdateInfoCheck($messages, false, false); } $userrow = false; if (!count($messages["errors"])) { if (!isset($_REQUEST["sso_v"]) || !isset($sso_session_info["sso_login_update"])) { $messages["errors"][] = BB_Translate("Invalid URL. Verification missing."); } else { if (trim($_REQUEST["sso_v"]) !== $sso_session_info["sso_login_update"]["v"]) { $messages["errors"][] = BB_Translate("Invalid verification string specified."); } else { if (!isset($sso_session_info["sso_login_update"]["expires"]) || CSDB::ConvertFromDBTime($sso_session_info["sso_login_update"]["expires"]) < time()) { $messages["errors"][] = BB_Translate("Update information is expired or invalid."); } else { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "id = ?"), $sso_db_sso_login_users, $sso_session_info["sso_login_update"]["id"]); if ($userrow === false) { $messages["errors"][] = BB_Translate("Update information is expired or invalid."); } else { if (!isset($userrow->username)) { $userrow->username = ""; } if (!isset($userrow->email)) { $userrow->email = ""; } if (!isset($userrow->verified)) { $userrow->verified = 1; } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("User check failed. Database query error."); } } } } } if (!count($messages["errors"])) { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { $messages["errors"][] = BB_Translate("Error loading user information."); } } if (isset($_REQUEST["sso_ajax"])) { if (!count($messages["errors"])) { $messages = $this->SignupUpdateCheck(true, $userrow, $userinfo, false); } foreach ($messages["errors"] as $error) { echo "<div class=\"sso_main_formerror\">" . htmlspecialchars($error) . "</div>"; } foreach ($messages["warnings"] as $warning) { echo "<div class=\"sso_main_formwarning\">" . htmlspecialchars($warning) . "</div>"; } if (!count($messages["errors"]) && !count($messages["warnings"])) { if ($messages["success"] != "") { echo "<div class=\"sso_main_formokay\">" . htmlspecialchars($messages["success"]) . "</div>"; } else { if ($messages["htmlsuccess"] != "") { echo "<div class=\"sso_main_formokay\">" . $messages["htmlsuccess"] . "</div>"; } } } } else { if (count($messages["errors"])) { echo $sso_header; SSO_OutputHeartbeat(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, false); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> </div> </div> <?php echo $sso_footer; } else { $messagesheader = false; $messages = false; if (SSO_FrontendFieldValue("submit") === false) { if (isset($_REQUEST["sso_msg"])) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->InitMessages($messages); } } } else { $messages = $this->SignupUpdateCheck(false, $userrow, $userinfo, false); if (!count($messages["errors"])) { // Update the account. if ($sso_settings["sso_login"]["change_username"] && ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username")) { $username = SSO_FrontendFieldValue("update_username", ""); } else { $username = $userrow->username; } if ($sso_settings["sso_login"]["change_email"] && ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email")) { $email = SSO_FrontendFieldValue("update_email", ""); $result = SMTP::MakeValidEmailAddress($email); $email = $result["email"]; $verified = $sso_settings["sso_login"]["email_verify_subject"] == "" || $sso_settings["sso_login"]["email_verify_msg"] == "" || $userrow->email == $email; } else { $email = $userrow->email; $verified = $userrow->verified; } if (SSO_FrontendFieldValue("update_pass", "") != "") { $salt = $sso_rng->GenerateString(); $data = $username . ":" . $email . ":" . $salt . ":" . SSO_FrontendFieldValue("update_pass"); $passwordinfo = self::HashPasswordInfo($data, $sso_settings["sso_login"]["password_mode"], $sso_settings["sso_login"]["password_minrounds"]); if (!$passwordinfo["success"]) { $messages["errors"][] = BB_Translate("Unexpected cryptography error."); } else { $numrounds = (int) $passwordinfo["rounds"]; $password = bin2hex($passwordinfo["hash"]); } } else { if ($username != $userrow->username || $email != $userrow->email) { $messages["errors"][] = BB_Translate("Please enter a new password."); } else { $salt = $userinfo["salt"]; $numrounds = $userinfo["rounds"]; $password = $userinfo["password"]; } } if (SSO_FrontendFieldValue("reset_two_factor_key", "") == "yes") { $sso_session_info["sso_login_two_factor_key"] = self::GenerateOTPKey(10); SSO_SaveSessionInfo(); $messages["errors"][] = BB_Translate("Two-factor authentication security key has been reset."); } if (!count($messages["errors"])) { $userinfo["two_factor_key"] = $sso_session_info["sso_login_two_factor_key"]; $userinfo["two_factor_method"] = SSO_FrontendFieldValue("update_two_factor_method", ""); foreach ($this->activemodules as &$instance) { $instance->UpdateAddInfo($userinfo); } $userinfo["salt"] = $salt; $userinfo["rounds"] = $numrounds; $userinfo["password"] = $password; $userinfo2 = SSO_EncryptDBData($userinfo); try { if ($sso_settings["sso_login"]["install_type"] == "email_username") { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("username" => $username, "email" => $email, "verified" => (int) $verified, "info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } else { if ($sso_settings["sso_login"]["install_type"] == "email") { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("email" => $email, "verified" => (int) $verified, "info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } else { if ($sso_settings["sso_login"]["install_type"] == "username") { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("username" => $username, "info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } else { $messages["errors"][] = BB_Translate("Fatal error: Login system is broken."); } } } // Send verification e-mail. $userid = $userrow->id; if (!count($messages["errors"]) && !$verified) { $this->SendVerificationEmail($userid, $userinfo, $messages, $username, $email); } } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } if (!count($messages["errors"])) { foreach ($this->activemodules as &$instance) { $instance->UpdateInfoDone($userid); } header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_msg=" . ($verified ? "updated" : "verify")); exit; } } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS($sso_target_url . "&sso_login_action=update_info&sso_v=" . urlencode($_REQUEST["sso_v"]) . "&sso_ajax=1"); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> <div class="sso_main_form_wrap sso_login_updateinfo_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Update Information")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=update_info&sso_v=" . urlencode($_REQUEST["sso_v"])); ?> " autocomplete="off"> <?php if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Your E-mail Address")); ?> </div> <div class="sso_main_formdata"><?php if ($sso_settings["sso_login"]["change_email"]) { ?> <input class="sso_main_text sso_login_changehook" type="text" name="<?php echo SSO_FrontendField("update_email"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("update_email", $userrow->email)); ?> " /><?php } else { ?> <input type="hidden" name="<?php echo SSO_FrontendField("update_email"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("update_email", $userrow->email)); ?> " /><div class="sso_main_static"><?php echo htmlspecialchars($userrow->email); ?> </div><?php } ?> </div> </div> <?php } if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username") { ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Your Username")); ?> </div> <div class="sso_main_formdata"><?php if ($sso_settings["sso_login"]["change_username"]) { ?> <input class="sso_main_text sso_login_changehook" type="text" name="<?php echo SSO_FrontendField("update_username"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("update_username", $userrow->username)); ?> " /><?php } else { ?> <input type="hidden" name="<?php echo SSO_FrontendField("update_username"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("update_username", $userrow->username)); ?> " /><div class="sso_main_static"><?php echo htmlspecialchars($userrow->username); ?> </div><?php } ?> </div> </div> <?php } ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("New Password")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text sso_login_changehook" type="password" name="<?php echo SSO_FrontendField("update_pass"); ?> " value="<?php echo htmlspecialchars(SSO_FrontendFieldValue("update_pass", "")); ?> " /></div> <div class="sso_main_formdesc"><?php echo htmlspecialchars(BB_Translate("Optional. Will change the password for the account.")); ?> </div> </div> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <?php $outputmap = array(); // Two-factor authentication dropdown. $outputmap2 = array(); $method = SSO_FrontendFieldValue("update_two_factor_method", isset($updateinfo["two_factor_method"]) ? $updateinfo["two_factor_method"] : ""); foreach ($this->activemodules as $key => &$instance) { $name = $instance->GetTwoFactorName(); if ($name !== false) { $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap2, $order, $key, "<option value=\"" . htmlspecialchars($key) . "\"" . ($method == $key ? " selected" : "") . ">" . htmlspecialchars($name) . "</option>"); } } if (!$sso_settings["sso_login"]["require_two_factor"] && count($outputmap2)) { SSO_AddSortedOutput($outputmap2, 0, "", "<option value=\"\"" . ($method == "" ? " selected" : "") . ">" . htmlspecialchars(BB_Translate("None")) . "</option>"); } if (count($outputmap2)) { if (!isset($sso_session_info["sso_login_two_factor_key"])) { $sso_session_info["sso_login_two_factor_key"] = self::GenerateOTPKey(10); SSO_SaveSessionInfo(); } ob_start(); ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Choose Two-Factor Authentication Method")); ?> </div> <div class="sso_main_formdata"><select class="sso_main_dropdown sso_login_changehook_two_factor" name="<?php echo SSO_FrontendField("update_two_factor_method"); ?> "> <?php SSO_DisplaySortedOutput($outputmap2); ?> </select></div> <div class="sso_main_formdesc"><?php echo htmlspecialchars(BB_Translate($sso_settings["sso_login"]["require_two_factor"] ? "Required. Two-factor authentication vastly improves the security of your account." : "Optional. Two-factor authentication vastly improves the security of your account.")); ?> </div> <div class="sso_main_formtwofactorreset"><input id="sso_two_factor_reset" type="checkbox" name="<?php echo SSO_FrontendField("reset_two_factor_key"); ?> " value="yes"> <label for="sso_two_factor_reset"><?php echo htmlspecialchars(BB_Translate("Reset two-factor authentication security key")); ?> </label></div> </div> <?php $order = $sso_settings["sso_login"]["two_factor_order"]; SSO_AddSortedOutput($outputmap, $order, "two_factor", ob_get_contents()); ob_end_clean(); } // Add active module output. foreach ($this->activemodules as $key => &$instance) { ob_start(); $instance->GenerateUpdateInfo($userrow, $userinfo); $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap, $order, $key, ob_get_contents()); ob_end_clean(); } SSO_DisplaySortedOutput($outputmap); ?> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Update")); ?> " /> </div> </form> </div> </div> </div> <?php } } } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "recover2" && isset($_REQUEST["sso_method"]) && $this->IsRecoveryAllowed()) { // Load and validate the recovery options. $userrow = false; if (isset($sso_session_info["sso_login_recover"]) && isset($sso_session_info["sso_login_recover"]["id"]) && isset($sso_session_info["sso_login_recover"]["method"]) && $sso_session_info["sso_login_recover"]["method"] == $_REQUEST["sso_method"]) { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "id = ?"), $sso_db_sso_login_users, $sso_session_info["sso_login_recover"]["id"]); if ($userrow) { if (!isset($userrow->username)) { $userrow->username = ""; } if (!isset($userrow->email)) { $userrow->email = ""; } if (!isset($userrow->verified)) { $userrow->verified = 1; } } } catch (Exception $e) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=recover&sso_msg=recovery_db_error"); exit; } } if ($userrow === false) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=recover&sso_msg=recovery_expired_invalid"); exit; } $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=recover&sso_msg=recovery_db_user_error"); exit; } $messagesheader = false; $messages = false; if (SSO_FrontendFieldValue("submit") === false) { if (isset($_REQUEST["sso_msg"])) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->InitMessages($messages); } } } else { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->RecoveryCheck2($messages, false); } if (!count($messages["errors"])) { foreach ($this->activemodules as &$instance) { $instance->RecoveryCheck2($messages, $userinfo); } if (!count($messages["errors"])) { $sso_session_info["sso_login_update"] = array("id" => $userrow->id, "v" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 30 * 60)); $sso_session_info["sso_login_two_factor_key"] = isset($userinfo["two_factor_key"]) && $userinfo["two_factor_key"] != "" ? $userinfo["two_factor_key"] : self::GenerateOTPKey(10); if (!SSO_SaveSessionInfo()) { $result["errors"][] = BB_Translate("Recovery was successful but a fatal error occurred. Fatal error: Unable to save session information."); } else { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=update_info&sso_v=" . urlencode($sso_session_info["sso_login_update"]["v"])); exit; } } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, $messagesheader); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> <div class="sso_main_form_wrap sso_login_recover_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Restore Access")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=recover2&sso_method=" . urlencode($_REQUEST["sso_method"])); ?> " autocomplete="off"> <?php $outputmap = array(); foreach ($this->activemodules as $key => &$instance) { ob_start(); $instance->GenerateRecovery2($messages); $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap, $order, $key, ob_get_contents()); ob_end_clean(); } SSO_DisplaySortedOutput($outputmap); ?> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Next")); ?> " /> </div> </form> </div> </div> </div> <?php echo $sso_footer; } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "recover" && $this->IsRecoveryAllowed()) { $messagesheader = false; $messages = false; if (SSO_FrontendFieldValue("submit") === false) { if (isset($_REQUEST["sso_msg"])) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); if ($_REQUEST["sso_msg"] == "recovery_db_error") { $messages["warnings"][] = BB_Translate("A database error occurred while attempting to load recovery information."); } else { if ($_REQUEST["sso_msg"] == "recovery_expired_invalid") { $messages["errors"][] = BB_Translate("Recovery information is expired or invalid."); } else { if ($_REQUEST["sso_msg"] == "recovery_db_user_error") { $messages["errors"][] = BB_Translate("User information in the database is corrupted."); } else { foreach ($this->activemodules as &$instance) { $instance->InitMessages($messages); } } } } } } else { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); $user = SSO_FrontendFieldValue("user_recover"); $method = SSO_FrontendFieldValue("recover_method"); if ($user === false || $user == "" || $method === false || $method == "") { $messages["errors"][] = BB_Translate("Please fill in the fields."); } else { foreach ($this->activemodules as &$instance) { $instance->RecoveryCheck($messages, false); } if (!count($messages["errors"])) { $userrow = false; if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "email = ?"), $sso_db_sso_login_users, $user); if ($userrow) { if (!isset($userrow->username)) { $userrow->username = ""; } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("User check failed. Database query error."); } } else { if ($sso_settings["sso_login"]["install_type"] == "username") { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "username = ?"), $sso_db_sso_login_users, $user); if ($userrow) { if (!isset($userrow->email)) { $userrow->email = ""; } if (!isset($userrow->verified)) { $userrow->verified = 1; } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("User check failed. Database query error."); } } else { $messages["errors"][] = BB_Translate("Login system is broken."); } } if ($userrow === false) { $messages["errors"][] = BB_Translate("Invalid login."); } else { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { $messages["errors"][] = BB_Translate("Error loading user information."); } else { foreach ($this->activemodules as &$instance) { $instance->RecoveryCheck($messages, $userinfo); } } } if (!count($messages["errors"])) { if ($method == "email" && $userrow->email != "") { $sso_session_info["sso_login_update"] = array("id" => $userrow->id, "v" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 30 * 60)); $sso_session_info["sso_login_two_factor_key"] = isset($userinfo["two_factor_key"]) && $userinfo["two_factor_key"] != "" ? $userinfo["two_factor_key"] : self::GenerateOTPKey(10); if (!SSO_SaveSessionInfo()) { $messages["errors"][] = BB_Translate("Login exists but a fatal error occurred. Fatal error: Unable to save session information."); } else { $fromaddr = BB_PostTranslate($sso_settings["sso_login"]["email_recover_from"] != "" ? $sso_settings["sso_login"]["email_recover_from"] : SSO_SMTP_FROM); $subject = BB_Translate($sso_settings["sso_login"]["email_recover_subject"]); $verifyurl = BB_GetRequestHost() . $sso_target_url . ($sso_settings["sso_login"]["email_session"] == "all" ? "&sso_id=" . urlencode($_REQUEST["sso_id"]) : "") . "&sso_login_action=update_info&sso_v=" . urlencode($sso_session_info["sso_login_update"]["v"]); $htmlmsg = str_ireplace(array("@USERNAME@", "@EMAIL@", "@VERIFY@"), array(htmlspecialchars($userrow->username), htmlspecialchars($userrow->email), htmlspecialchars($verifyurl)), BB_PostTranslate($sso_settings["sso_login"]["email_recover_msg"])); $textmsg = str_ireplace(array("@USERNAME@", "@EMAIL@", "@VERIFY@"), array($userrow->username, $userrow->email, $verifyurl), BB_PostTranslate($sso_settings["sso_login"]["email_recover_msg_text"])); foreach ($this->activemodules as &$instance) { $instance->ModifyEmail($userinfo, $htmlmsg, $textmsg); } $result = SSO_SendEmail($fromaddr, $userrow->email, $subject, $htmlmsg, $textmsg); if (!$result["success"]) { $messages["errors"][] = BB_Translate("Login exists but a fatal error occurred. Fatal error: Unable to send verification e-mail. %s", $result["error"]); } else { foreach ($this->activemodules as &$instance) { $instance->RecoveryDone($messages, $method, $userrow, $userinfo); } if (!count($messages["errors"])) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_msg=recovery_email_sent"); exit; } } } } else { foreach ($this->activemodules as &$instance) { $instance->RecoveryDone($messages, $method, $userrow, $userinfo); } } } } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, $messagesheader); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> <div class="sso_main_form_wrap sso_login_recover_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Restore Access")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=recover"); ?> " autocomplete="off"> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { echo htmlspecialchars(BB_Translate("E-mail Address")); } else { if ($sso_settings["sso_login"]["install_type"] == "username") { echo htmlspecialchars(BB_Translate("Username")); } else { echo htmlspecialchars(BB_Translate("Login system is broken.")); } } ?> </div> <div class="sso_main_formdata"><input class="sso_main_text" type="text" name="<?php echo SSO_FrontendField("user_recover"); ?> " /></div> </div> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Recovery Method")); ?> </div> <div class="sso_main_formdata"><select class="sso_main_dropdown" name="<?php echo SSO_FrontendField("recover_method"); ?> "> <?php $method = SSO_FrontendFieldValue("recover_method", ""); if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { echo "<option value=\"email\"" . ($method == "email" ? " selected" : "") . ">" . htmlspecialchars(BB_Translate("E-mail")) . "</option>"; } foreach ($this->activemodules as &$instance) { $instance->AddRecoveryMethod($method); } ?> </select></div> </div> <?php $outputmap = array(); foreach ($this->activemodules as $key => &$instance) { ob_start(); $instance->GenerateRecovery($messages); $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap, $order, $key, ob_get_contents()); ob_end_clean(); } SSO_DisplaySortedOutput($outputmap); ?> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Next")); ?> " /> </div> </form> </div> </div> </div> <?php echo $sso_footer; } else { if (isset($_REQUEST["sso_login_action"]) && $_REQUEST["sso_login_action"] == "two_factor") { // Check the session and load the user account. $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->TwoFactorCheck($messages, false); } $userrow = false; if (!count($messages["errors"])) { if (!isset($_REQUEST["sso_v"]) || !isset($sso_session_info["sso_login_two_factor"])) { $messages["errors"][] = BB_Translate("Invalid URL. Verification missing."); } else { if (trim($_REQUEST["sso_v"]) !== $sso_session_info["sso_login_two_factor"]["v"]) { $messages["errors"][] = BB_Translate("Invalid verification string specified."); } else { if (!isset($sso_session_info["sso_login_two_factor"]["expires"]) || CSDB::ConvertFromDBTime($sso_session_info["sso_login_two_factor"]["expires"]) < time()) { $messages["errors"][] = BB_Translate("Two-factor information is expired or invalid."); } else { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "id = ?"), $sso_db_sso_login_users, $sso_session_info["sso_login_two_factor"]["id"]); if ($userrow === false) { $messages["errors"][] = BB_Translate("Two-factor information is expired or invalid."); } else { if (!isset($userrow->username)) { $userrow->username = ""; } if (!isset($userrow->email)) { $userrow->email = ""; } if (!isset($userrow->verified)) { $userrow->verified = 1; } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("User check failed. Database query error."); } } } } } $method = BB_Translate("Unknown/Invalid."); if (!count($messages["errors"])) { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { $messages["errors"][] = BB_Translate("Error loading user information."); } else { // Check the two-factor authentication method. $methods = array(); foreach ($this->activemodules as $key => &$instance) { $name = $instance->GetTwoFactorName(false); if ($name !== false) { $methods[$key] = $name; } } if (isset($userinfo["two_factor_method"]) && isset($methods[$userinfo["two_factor_method"]])) { $method = $methods[$userinfo["two_factor_method"]]; } else { $messages["errors"][] = BB_Translate("A valid two-factor authentication method for this account is not available. Use account recovery to restore access to the account."); } } } if (count($messages["errors"])) { echo $sso_header; SSO_OutputHeartbeat(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, false); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> </div> </div> <?php echo $sso_footer; } else { $messagesheader = false; $messages = false; if (SSO_FrontendFieldValue("submit") === false) { if (isset($_REQUEST["sso_msg"])) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->InitMessages($messages); } } } else { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); foreach ($this->activemodules as &$instance) { $instance->TwoFactorCheck($messages, $userinfo); } if (count($messages["errors"])) { foreach ($this->activemodules as &$instance) { $instance->TwoFactorFailed($messages, $userinfo); } } else { // Login with two-factor authentication succeeded. Activate the user. $mapinfo = array(); if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { $mapinfo[$sso_settings["sso_login"]["map_email"]] = $userrow->email; } if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username") { $mapinfo[$sso_settings["sso_login"]["map_username"]] = $userrow->username; } $origuserinfo = $userinfo; foreach ($this->activemodules as &$instance) { $instance->LoginAddMap($mapinfo, $userrow, $userinfo, false); } // If a module updated $userinfo, then update the database. if (serialize($userinfo) !== serialize($origuserinfo)) { $userinfo2 = SSO_EncryptDBData($userinfo); try { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } } if (!count($messages["errors"])) { SSO_ActivateUser($userrow->id, $userinfo["extra"], $mapinfo, CSDB::ConvertFromDBTime($userrow->created)); // Only falls through on account lockout or a fatal error. $messages["errors"][] = BB_Translate("User activation failed."); } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, $messagesheader); ?> <div class="sso_login_signin"><a href="<?php echo htmlspecialchars($sso_target_url); ?> "><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </a></div> <div class="sso_main_form_wrap sso_login_recover_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Two-Factor Authentication")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=two_factor&sso_v=" . urlencode($_REQUEST["sso_v"])); ?> " autocomplete="off"> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Enter Two-Factor Authentication Code")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text" type="text" name="<?php echo SSO_FrontendField("two_factor_code"); ?> " /></div> <div class="sso_main_formdesc"><?php echo htmlspecialchars(BB_Translate("From %s.", $method)); ?> </div> </div> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Sign in")); ?> " /> </div> </form> </div> </div> </div> <?php echo $sso_footer; } } else { $messagesheader = false; $messages = false; if (SSO_FrontendFieldValue("submit") === false) { if (isset($_REQUEST["sso_msg"])) { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); if ($_REQUEST["sso_msg"] == "verified") { $messages["success"] = BB_Translate("Your account is ready to use."); } else { if ($_REQUEST["sso_msg"] == "verify") { $messages["warnings"][] = BB_Translate("Account must be verified before it can be used. Check your e-mail."); } else { if ($_REQUEST["sso_msg"] == "recovery_email_sent") { $messages["warnings"][] = BB_Translate("Account recovery URL sent. Check your e-mail."); } else { if ($_REQUEST["sso_msg"] == "updated") { $messages["success"] = BB_Translate("Your account information has been updated and is ready to use."); } else { if ($_REQUEST["sso_msg"] == "two_factor_auth_expired") { $messages["errors"][] = BB_Translate("Two-factor authentication expired. Sign in again."); } else { foreach ($this->activemodules as &$instance) { $instance->InitMessages($messages); } } } } } } } } else { $messages = array("errors" => array(), "warnings" => array(), "success" => ""); $user = SSO_FrontendFieldValue("user"); $password = SSO_FrontendFieldValue("password"); if ($user === false || $user == "" || $password === false || $password == "") { $messages["errors"][] = BB_Translate("Please fill in the fields."); } else { $recoveryallowed = $this->IsRecoveryAllowed(false); foreach ($this->activemodules as &$instance) { $instance->LoginCheck($messages, false, $recoveryallowed); } if (!count($messages["errors"])) { $userrow = false; if (strpos($user, "@") !== false && ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email")) { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "email = ?"), $sso_db_sso_login_users, $user); if ($userrow) { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { $userrow = false; } else { if (!isset($userrow->username)) { $userrow->username = ""; } $data = $userrow->username . ":" . $userrow->email . ":" . $userinfo["salt"] . ":" . $password; if (!self::VerifyPasswordInfo($data, $userinfo["password"], $userinfo["rounds"])) { $userrow = false; } } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("Login failed. Database query error."); } } if ($userrow === false && ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username")) { try { $userrow = $sso_db->GetRow("SELECT", array("*", "FROM" => "?", "WHERE" => "username = ?"), $sso_db_sso_login_users, $user); if ($userrow) { $userinfo = SSO_DecryptDBData($userrow->info); if ($userinfo === false) { $userrow = false; } else { if (!isset($userrow->email)) { $userrow->email = ""; } if (!isset($userrow->verified)) { $userrow->verified = 1; } $data = $userrow->username . ":" . $userrow->email . ":" . $userinfo["salt"] . ":" . $password; if (!self::VerifyPasswordInfo($data, $userinfo["password"], $userinfo["rounds"])) { $userrow = false; } } } } catch (Exception $e) { $messages["errors"][] = BB_Translate("Login failed. Database query error."); } } if ($userrow === false) { $messages["errors"][] = BB_Translate("Invalid login."); } else { // Make sure the password is stored securely. If not, transparently update the hash information in the database. if ($userinfo["rounds"] < $sso_settings["sso_login"]["password_minrounds"]) { $userinfo["salt"] = $sso_rng->GenerateString(); $data = $userrow->username . ":" . $userrow->email . ":" . $userinfo["salt"] . ":" . $password; $passwordinfo = self::HashPasswordInfo($data, $sso_settings["sso_login"]["password_mode"], $sso_settings["sso_login"]["password_minrounds"]); if ($passwordinfo["success"]) { $userinfo["rounds"] = (int) $passwordinfo["rounds"]; $userinfo["password"] = bin2hex($passwordinfo["hash"]); $userinfo2 = SSO_EncryptDBData($userinfo); try { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } } } foreach ($this->activemodules as &$instance) { $instance->LoginCheck($messages, $userinfo, $recoveryallowed); } } if (!count($messages["errors"])) { // Go to two-factor authentication page. $methods = array(); foreach ($this->activemodules as $key => &$instance) { $name = $instance->GetTwoFactorName(false); if ($name !== false) { $methods[$key] = true; } } // Resend the verification e-mail. if (!$userrow->verified) { $this->SendVerificationEmail($userrow->id, $userinfo, $messages, $userrow->username, $userrow->email); } else { if (!$recoveryallowed && SSO_FrontendFieldValue("update_info", "") == "yes") { $sso_session_info["sso_login_update"] = array("id" => $userrow->id, "v" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 30 * 60)); $sso_session_info["sso_login_two_factor_key"] = isset($userinfo["two_factor_key"]) && $userinfo["two_factor_key"] != "" ? $userinfo["two_factor_key"] : self::GenerateOTPKey(10); if (!SSO_SaveSessionInfo()) { $messages["errors"][] = BB_Translate("Login exists but a fatal error occurred. Fatal error: Unable to save session information."); } else { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=update_info&sso_v=" . urlencode($sso_session_info["sso_login_update"]["v"])); exit; } } else { if ($sso_settings["sso_login"]["require_two_factor"] || isset($userinfo["two_factor_method"]) && $userinfo["two_factor_method"] != "" && (count($methods) || ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email"))) { if ($sso_settings["sso_login"]["require_two_factor"] && (!isset($userinfo["two_factor_method"]) || !isset($methods[$userinfo["two_factor_method"]]))) { $messages["errors"][] = BB_Translate("A valid two-factor authentication method for this account is not available. Use account recovery to restore access to the account."); } else { $sso_session_info["sso_login_two_factor"] = array("id" => $userrow->id, "v" => $sso_rng->GenerateString(), "expires" => CSDB::ConvertToDBTime(time() + 5 * 60)); if (!SSO_SaveSessionInfo()) { $messages["errors"][] = BB_Translate("Login exists but a fatal error occurred. Fatal error: Unable to save session information."); } else { $this->activemodules[$userinfo["two_factor_method"]]->SendTwoFactorCode($messages, $userrow, $userinfo); if (!count($messages["errors"])) { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=two_factor&sso_v=" . urlencode($sso_session_info["sso_login_two_factor"]["v"])); exit; } } } } else { // Login succeeded. Activate the user. $mapinfo = array(); if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "email") { $mapinfo[$sso_settings["sso_login"]["map_email"]] = $userrow->email; } if ($sso_settings["sso_login"]["install_type"] == "email_username" || $sso_settings["sso_login"]["install_type"] == "username") { $mapinfo[$sso_settings["sso_login"]["map_username"]] = $userrow->username; } $origuserinfo = $userinfo; foreach ($this->activemodules as &$instance) { $instance->LoginAddMap($mapinfo, $userrow, $userinfo, false); } // If a module updated $userinfo, then update the database. if (serialize($userinfo) !== serialize($origuserinfo)) { $userinfo2 = SSO_EncryptDBData($userinfo); try { $sso_db->Query("UPDATE", array($sso_db_sso_login_users, array("info" => $userinfo2), "WHERE" => "id = ?"), $userrow->id); } catch (Exception $e) { $messages["errors"][] = BB_Translate("Database query error."); } } if (!count($messages["errors"])) { SSO_ActivateUser($userrow->id, $userinfo["extra"], $mapinfo, CSDB::ConvertFromDBTime($userrow->created)); // Only falls through on account lockout or a fatal error. $messages["errors"][] = BB_Translate("User activation failed."); } } } } } } } } echo $sso_header; SSO_OutputHeartbeat(); $this->OutputJS(); ?> <div class="sso_main_wrap sso_login"> <div class="sso_main_wrap_inner"> <?php $this->DisplayMessages($messages, $messagesheader); if ($sso_settings["sso_login"]["open_reg"]) { ?> <div class="sso_login_signup"><a href="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=signup"); ?> "><?php echo htmlspecialchars(BB_Translate("Sign up")); ?> </a></div> <?php } ?> <div class="sso_main_form_wrap sso_login_signin_form"> <div class="sso_main_form_header"><?php echo htmlspecialchars(BB_Translate("Sign in")); ?> </div> <form class="sso_main_form" name="sso_login_form" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="<?php echo htmlspecialchars($sso_target_url); ?> " autocomplete="off"> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php if ($sso_settings["sso_login"]["install_type"] == "email_username") { echo htmlspecialchars(BB_Translate("Username or E-mail Address")); } else { if ($sso_settings["sso_login"]["install_type"] == "username") { echo htmlspecialchars(BB_Translate("Username")); } else { if ($sso_settings["sso_login"]["install_type"] == "email") { echo htmlspecialchars(BB_Translate("E-mail Address")); } else { echo htmlspecialchars(BB_Translate("Login system is broken.")); } } } ?> </div> <div class="sso_main_formdata"><input class="sso_main_text" type="text" name="<?php echo SSO_FrontendField("user"); ?> " /></div> </div> <script type="text/javascript"> jQuery('input.sso_main_text:first').focus(); </script> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Password")); ?> </div> <div class="sso_main_formdata"><input class="sso_main_text" type="password" name="<?php echo SSO_FrontendField("password"); ?> " /></div> </div> <?php $outputmap = array(); foreach ($this->activemodules as $key => &$instance) { ob_start(); $instance->GenerateLogin($messages); $order = isset($sso_settings["sso_login"]["modules"][$key]["_s"]) ? $sso_settings["sso_login"]["modules"][$key]["_s"] : $instance->DefaultOrder(); SSO_AddSortedOutput($outputmap, $order, $key, ob_get_contents()); ob_end_clean(); } SSO_DisplaySortedOutput($outputmap); if (!$this->IsRecoveryAllowed(false)) { ?> <div class="sso_main_formitem"> <div class="sso_main_formtitle"><?php echo htmlspecialchars(BB_Translate("Update Information")); ?> </div> <div class="sso_main_formdata"><input id="sso_norecovery_updateinfo" type="checkbox" name="<?php echo SSO_FrontendField("update_info"); ?> " value="yes"<?php if (SSO_FrontendFieldValue("update_info", "") == "yes") { echo " checked"; } ?> /> <label for="sso_norecovery_updateinfo">Change account information upon successful sign in</label></div> </div> <?php } ?> <div class="sso_main_formsubmit"> <input type="submit" name="<?php echo SSO_FrontendField("submit"); ?> " value="<?php echo htmlspecialchars(BB_Translate("Sign in")); ?> " /> </div> </form> </div> <?php if ($this->IsRecoveryAllowed()) { ?> <div class="sso_login_recover_changeinfo"><a href="<?php echo htmlspecialchars($sso_target_url . "&sso_login_action=recover"); ?> "><?php echo htmlspecialchars(BB_Translate("Can't access your account?")); ?> </a></div> <?php } ?> </div> </div> <?php echo $sso_footer; } } } } } } } } }
protected function ProcessKeyDefinition($info) { $sql = ""; if (isset($info["CONSTRAINT"])) { $sql .= "CONSTRAINT " . $info["CONSTRAINT"] . " "; } $type = strtoupper($info[0]); foreach ($info[1] as $num => $field) { $info[1][$num] = $this->QuoteIdentifier($field); } switch ($type) { case "PRIMARY": $sql .= "PRIMARY KEY"; $sql .= " (" . implode(", ", $info[1]) . ")"; break; case "KEY": // SQLite CREATE TABLE doesn't support regular KEY indexes, but ALTER TABLE does. break; case "UNIQUE": $sql .= "UNIQUE"; $sql .= " (" . implode(", ", $info[1]) . ")"; break; case "FULLTEXT": // SQLite doesn't support FULLTEXT indexes. break; case "FOREIGN": $sql .= "FOREIGN KEY"; $sql .= " (" . implode(", ", $info[1]) . ")"; $sql .= " REFERENCES " . $this->ProcessReferenceDefinition($info[2]); break; default: return array("success" => false, "error" => CSDB::DB_Translate("Unknown key type '%s'.", $type), "errorcode" => "unknown_key_type"); } return array("success" => true, "sql" => $sql); }
public function LoginCheck(&$result, $userinfo, $recoveryallowed) { global $sso_target_url; if ($userinfo !== false) { $info = $this->GetInfo(); if ($info["expire"] > 0 && (!isset($userinfo["sso_password"]) || !isset($userinfo["sso_password"]["expires"]) || CSDB::ConvertFromDBTime($userinfo["sso_password"]["expires"]) <= time())) { if (!$recoveryallowed) { if (SSO_FrontendFieldValue("update_info", "") != "yes") { $result["errors"][] = BB_Translate("Password has expired. Check the checkbox under 'Update Information' and sign in again to change your password."); } } else { header("Location: " . BB_GetRequestHost() . $sso_target_url . "&sso_login_action=recover&sso_msg=sso_login_password_expired"); exit; } } } }