Initial import

This commit is contained in:
Latif Khalifa
2013-10-03 07:31:47 +02:00
parent 9d83e533c0
commit d54d4c277a
29 changed files with 2258 additions and 1 deletions

1
htdocs/lib/.htaccess Normal file
View File

@@ -0,0 +1 @@
deny from all

185
htdocs/lib/DBH.php Normal file
View File

@@ -0,0 +1,185 @@
<?php
/* $Id$ */
class DBH
{
public
$db_name,
$db_pass,
$db_user,
$db_host,
$dbh,
$last_error = "";
function log($line)
{
static $f = false;
static $failed = false;
if ($failed) {
return false;
}
if (!$f) {
$f = @fopen(SITE_ROOT.'/lib/logs/sql.log', 'a');
}
if (!$f) {
$failed = true;
return false;
}
@fwrite($f, "[".date('Y-m-d H:i')."] ".$line."\n");
}
function connect($db_name, $db_host, $db_user, $db_pass)
{
$this->db_name = $db_name;
$this->db_pass = $db_pass;
$this->db_user = $db_user;
$this->db_host = $db_host;
$this->dbh = @mysql_connect($db_host, $db_user, $db_pass);
if (!$this->dbh) {
DBH::log("[error] connection to database failed");
DBH::log("[error] connection string used '$conn_str'");
return false;
}
if (!mysql_select_db($db_name)) {
DBH::log("[error] database {$db_name} dose not exist");
return false;
}
$this->query("SET SQL_MODE='TRADITIONAL'");
$this->query("SET NAMES 'utf8'");
return true;
}
function query($q)
{
$res = @mysql_query($q, $this->dbh);
if (!$res) {
DBH::log("[error] ".$q);
DBH::log("[error_msg] " . mysql_error($this->dbh));
$this->last_error = mysql_error($this->dbh);
$e = debug_backtrace();
$c = count($e);
$btr = "";
for ($i=0; $i<$c; $i++) {
$btr .= "{$e[$i]['class']}::{$e[$i]['function']} {$e[$i]['file']}({$e[$i]['line']})\n";
}
DBH::log("[backtrace]\n".$btr);
return false;
} else {
if ($res !== TRUE) {
$result_id = (int)$res;
if (!isset($this->field_desc[$result_id])) {
$nf = mysql_num_fields($res);
for ($i=0; $i<$nf; $i++) {
$this->field_desc[$result_id][mysql_field_name($res, $i)] = mysql_field_type($res, $i);
}
}
}
DBH::log("[success] ".$q);
return $res;
}
}
function loadFromDbRow(&$obj, $res, $row)
{
foreach ($row as $symbolicName => $nativeName){
if ($nativeName && ($this->field_desc[(int)$res][$symbolicName] == "timestamp" ||
$this->field_desc[(int)$res][$symbolicName] == "date" ||
$this->field_desc[(int)$res][$symbolicName] == "datetime")) {
$obj->{$symbolicName} = strtotime($nativeName);
} else {
$obj->{$symbolicName} = $nativeName;
}
}
return true;
}
function insertID()
{
return @mysql_insert_id($this->dbh);
}
function numRows($res)
{
return @mysql_num_rows($res);
}
function affectedRows()
{
return @mysql_affected_rows($this->dbh);
}
function fieldName($res, $num)
{
return @mysql_field_name($res, $num);
}
function numFields($res)
{
return @mysql_num_fields($res);
}
function fetchRow($res)
{
return @mysql_fetch_assoc($res);
}
function begin()
{
return $this->query('begin');
}
function rollback()
{
return $this->query('rollback');
}
function commit()
{
return $this->query('commit');
}
/* FIXME: port from postgres */
function nextId($seq)
{
$res = $this->query("select nextval('$seq') as n");
if (!$res || !$row = $this->fetchRow($res)) {
return false;
} else {
return (int)$row['n'];
}
}
/* Date time conversion */
function db2unix($s)
{
return strtotime($s);
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

478
htdocs/lib/GoogleOpenID.php Normal file
View File

@@ -0,0 +1,478 @@
<?php
/****************************************************************************
* The GoogleOpenID class
*
* This class implements a gateway to the Google OpenID federated login API
*
* By Andrew Peace (http://www.andrewpeace.com)
* December 6, 2008
* Contact me at http://www.andrewpeace.com/contact.html
*
*
* Usage:
*
* To redirect users to a Google login page, simply create a GoogleOpenID:
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/check.php",
* "ABCDEFG",
* true);
*
* The first argument is the URL you want Google to redirect to when it sends
* its response
*
* The second argument is the association handle you've obtained from Google.
* This parameter is OPTIONAL and can be set to null. However, if it is not
* given or it is set to null, GoogleOpenID will automatically request an
* association handle when it is constructed. This is wastefull! Association
* handles last for two weeks. So, it is better to get and save an association
* handle on your own using GoogleOpenID::getAssociationHandle().
*
* The third argument should be set to true if you want the response to include
* the user's email address. It is optional.
*
* Example:
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/checkauth.php", "ABCDEFG", true);
* $googleGateway->redirect();
*
* OR
*
* $handle = GoogleOpenID::getAssociationHandle(); // <--save this! valid for two weeks!
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/checkauth.php", $handle, true);
* $googleGateway->redirect();
*
*
* When you want to recieve a Google OpenID response, simply pass the given
* parameters to GoogleOpenID::create(). In most cases, you should just be able
* to pass the $_GET variable.
*
* To continue the previous example, the following code would go in checkauth.php
*
* $googleResponse = GoogleOpenID::create($_GET);
* $sucess = $googleResponse->success();//true or false
* $user_identity = $googleResponse->identity();//the user's ID
* $user_email = $googleResponse->email();//the user's email
*
* OR, even easier
*
* $googleResponse = GoogleOpenID::getResponse(); // <-- automatically reads $_GET
*
* Advanced users can create a slightly more customized request using the create
* method. It accepts an associative array of openid parameters and sets those
* that it deems appropriate to set (mostly, the parameters that don't have a
* definite value when interacting with Google)
*
*
* Full class signature:
*
* public static createRequest(String, [String], [Boolean])
* public static getResponse()
* public static create(Array)
* public static getAssociationHandle([String])
* public static getEndPoint()
* public redirect()
* public getArray()
* public endPoint()
* public success()
* public assoc_handle()
* public email()
* public identity()
*
* Features to implement:
*
* -In constructor, fix relative->absolute URL conversion (it is messy/buggy)
* -In getAssociationHandle(), use encryption
* -Verify Google's response with signed, sig etc
****************************************************************************/
class GoogleOpenID{
//the google discover url
const google_discover_url = "https://www.google.com/accounts/o8/id";
//some constant parameters
const openid_ns = "http://specs.openid.net/auth/2.0";
//required for email attribute exchange
const openid_ns_ext1 = "http://openid.net/srv/ax/1.0";
const openid_ext1_mode = "fetch_request";
const openid_ext1_type_email = "http://schema.openid.net/contact/email";
const openid_ext1_required = "email";
//parameters set by constructor
private $mode;//the mode (checkid_setup, id_res, or cancel)
private $response_nonce;
private $return_to;//return URL
private $realm;//the realm that the user is being asked to trust
private $assoc_handle;//the association handle between this service and Google
private $claimed_id;//the id claimed by the user
private $identity;//for google, this is the same as claimed_id
private $signed;
private $sig;
private $email;//the user's email address
//if true, fetch email address
private $require_email;
//private constructor
private function GoogleOpenID($mode, $op_endpoint, $response_nonce, $return_to, $realm, $assoc_handle, $claimed_id, $signed, $sig, $email, $require_email){
//if assoc_handle is null, fetch one
if(is_null($assoc_handle))
$assoc_handle = GoogleOpenID::getAssociationHandle();
//if return_to is a relative URL, make it absolute
if(stripos($return_to, "http://")!==0 &&
stripos($return_to, "https://")!==0){
//if the first character is a slash, delete it
if(substr($return_to, 0, 1)=="/")
$return_to = substr($return_to, 1);
//get the position of server_name
$server_name_pos = stripos($return_to, $_SERVER['SERVER_NAME']);
//if server_name is already at position zero
if($server_name_pos != false && $server_name_pos==0){
$return_to = "http://".$return_to;
} else {
$return_to = "http://".$_SERVER['SERVER_NAME']."/".$return_to;
}//else (server name not at position zero)
}//if return_to is relative
//if realm is null, attempt to set it via return_to
if(is_null($realm)){
//if return_to is set
if(!is_null($return_to)){
$pieces = parse_url($return_to);
$realm = $pieces['scheme']."://".$pieces['host'];
}//if return_to set
}//if realm null
$this->mode = $mode;
$this->op_endpoint = $op_endpoint;
$this->response_nonce = $response_nonce;
$this->return_to = $return_to;
$this->realm = $realm;
$this->assoc_handle = $assoc_handle;
$this->claimed_id = $claimed_id;
$this->identity = $claimed_id;
$this->signed = $signed;
$this->sig = $sig;
$this->email = $email;
$this->require_email = ($require_email) ? true : false;
}//GoogleOpenID
//static creator that accepts only a return_to URL
//this creator should be used when creating a GoogleOpenID for a redirect
public static function createRequest($return_to, $assoc_handle=null, $require_email=false){
return new GoogleOpenID("checkid_setup", null, null, $return_to, null, $assoc_handle, "http://specs.openid.net/auth/2.0/identifier_select", null, null, null, $require_email);
}//createRequest
//static creator that accepts an associative array of parameters and
//sets only the setable attributes (does not overwrite constants)
public static function create($params){
//loop through each parameter
foreach($params as $param => $value){
switch($param){
case "openid_mode":
//check validity of mode
if($value=="checkid_setup" ||
$value=="id_res" ||
$value=="cancel")
$mode = $value;
else
$mode = "cancel";
continue 2;
case "openid_op_endpoint":
$op_endpoint = $value;
continue 2;
case "openid_response_nonce":
$response_nonce = $value;
continue 2;
case "openid_return_to":
$return_to = $value;
continue 2;
case "openid_realm":
$realm = $value;
continue 2;
case "openid_assoc_handle":
$assoc_handle = $value;
continue 2;
case "openid_claimed_id":
$claimed_id = $value;
continue 2;
case "openid_identity":
$claimed_id = $value;
continue 2;
case "openid_signed":
$signed = $value;
continue 2;
case "openid_sig":
$sig = $value;
continue 2;
case "openid_ext1_value_email":
$email = $value;
continue 2;
case "require_email":
$require_email = $value;
continue 2;
default:
continue 2;
}//switch param
}//loop through params
//if require email is not set, set it to false
if(!is_bool($require_email))
$require_email = false;
//if mode is not set, set to default for redirection
if(is_null($mode))
$mode = "checkid_setup";
//if return_to is not set and mode is checkid_setup, throw an error
if(is_null($return_to) && $mode=="checkid_setup")
throw new Exception("GoogleOpenID.create() needs parameter openid.return_to");
//return a new GoogleOpenID with the given parameters
return new GoogleOpenID($mode, $op_endpoint, $response_nonce, $return_to, $realm, $assoc_handle, $claimed_id, $signed, $sig, $email, $require_email);
}//create
//creates and returns a GoogleOpenID from the $_GET variable
public static function getResponse(){
return GoogleOpenID::create($_GET);
}//getResponse
//fetches an association handle from google. association handles are valid
//for two weeks, so coders should do their best to save association handles
//externally and pass them to createRequest()
//NOTE: This function does not use encryption, but it SHOULD! At the time
//I wrote this I wanted it done fast, and I couldn't seem to find a good
//two-way SHA-1 or SHA-256 library for PHP. Encryption is not my thing, so
//it remains unimplemented.
public static function getAssociationHandle($endpoint=null){
//if no endpoint given
if(is_null($endpoint))
//fetch one from Google
$request_url = GoogleOpenID::getEndPoint();
//if endpoint given, set it
else
$request_url = $endpoint;
//append parameters (these never change)
$request_url .= "?openid.ns=".urlencode(GoogleOpenID::openid_ns);
$request_url .= "&openid.mode=associate";
$request_url .= "&openid.assoc_type=HMAC-SHA1";
$request_url .= "&openid.session_type=no-encryption";
//create a CURL session with the request URL
$c = curl_init($request_url);
//set a few options
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
//get the contents of request URL
$request_contents = curl_exec($c);
//close the CURL session
curl_close($c);
//a handle to be returned
$assoc_handle = null;
//split the response into lines
$lines = explode("\n", $request_contents);
//loop through each line
foreach($lines as $line){
//if this line is assoc_handle
if(substr($line, 0, 13)=="assoc_handle:"){
//save the assoc handle
$assoc_handle = substr($line, 13);
//exit the loop
break;
}//if this line is assoc_handle
}//loop through lines
//return the handle
return $assoc_handle;
}//getAssociationHandle
//fetches an endpoint from Google
public static function getEndPoint(){
//fetch the request URL
$request_url = GoogleOpenID::google_discover_url;
//create a CURL session with the request URL
$c = curl_init($request_url);
//set a few options
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
//fetch the contents of the request URL
$request_contents = curl_exec($c);
//close the CURL session
curl_close($c);
//create a DOM document so we can extract the URI element
$domdoc = new DOMDocument();
$domdoc->loadXML($request_contents);
//fetch the contents of the URI element
$uri = $domdoc->getElementsByTagName("URI");
$uri = $uri->item(0)->nodeValue;
//return the given URI
return $uri;
}//getEndPoint
//returns an associative array of all openid parameters for this openid
//session. the array contains all the GET attributes that would be sent
//or that have been recieved, meaning:
//
//if mode = "cancel" returns only the mode and ns attributes
//if mode = "id_res" returns all attributes that are not null
//if mode = "checkid_setup" returns only attributes that need to be sent
// in the HTTP request
public function getArray(){
//an associative array to return
$ret = array();
$ret['openid.ns'] = GoogleOpenID::openid_ns;
//if mode is cancel, return only ns and mode
if($this->mode=="cancel"){
$ret['openid.mode'] = "cancel";
return $ret;
}//if cancel
//set attributes that are returned for all cases
if(!is_null($this->claimed_id)){
$ret['openid.claimed_id'] = $this->claimed_id;
$ret['openid.identity'] = $this->claimed_id;
}
if(!is_null($this->return_to))
$ret['openid.return_to'] = $this->return_to;
if(!is_null($this->realm))
$ret['openid.realm'] = $this->realm;
if(!is_null($this->assoc_handle))
$ret['openid.assoc_handle'] = $this->assoc_handle;
if(!is_null($this->mode))
$ret['openid.mode'] = $this->mode;
//set attributes that are returned only if this is a request
//and if getting email is required OR if this is a response and the
//email is given
if(($this->mode=="checkid_setup" AND $this->require_email) OR
($this->mode=="id_res" AND !is_null($this->email))){
$ret['openid.ns.ext1'] = GoogleOpenID::openid_ns_ext1;
$ret['openid.ext1.mode'] = GoogleOpenID::openid_ext1_mode;
$ret['openid.ext1.type.email'] = GoogleOpenID::openid_ext1_type_email;
$ret['openid.ext1.required'] = GoogleOpenID::openid_ext1_required;
if(!is_null($this->email))
$ret['openid.ext1.value.email'] = $this->email;
}//if redirect and get email
//set attributes that are returned only if this is a response
if($this->mode=="id_res"){
$ret['openid.op_endpoint'] = $this->op_endpoint;
if(!is_null($this->response_nonce))
$ret['openid.response_nonce'] = $this->response_nonce;
if(!is_null($this->signed))
$ret['openid.signed'] = $this->signed;
if(!is_null($this->sig))
$ret['openid.sig'] = $this->sig;
}
//return the array
return $ret;
}//getArray
//sends a request to google and fetches the url to which google is asking
//us to redirect (unless the endpoint is already known, in which case the
//function simply returns it)
public function endPoint(){
//if we know the value of op_endpoint already
if(!is_null($this->op_endpoint))
return $this->op_endpoint;
//fetch the endpoint from Google
$endpoint = GoogleOpenID::getEndPoint();
//save it
$this->op_endpoint = $endpoint;
//return the endpoint
return $endpoint;
}//getedPoint
//returns the URL to which we should send a request (including all GET params)
public function getRequestURL(){
//get all parameters
$params = $this->getArray();
//the base URL
$url = $this->endPoint();
//flag indicating whether to set a '?' or an '&'
$first_attribute = true;
//loop through all params
foreach($params as $param => $value){
//if first attribute print a ?, else print a &
if($first_attribute){
$url .= "?";
$first_attribute = false;
} else {
$url .= "&";
}//else (not first attribute)
$url .= urlencode($param) . "=" . urlencode($value);
}//loop through params
//return the URL
return $url;
}//getRequestURL
//redirects the browser to the appropriate request URL
public function redirect(){
header("Location: ".$this->getRequestURL());
}//redirect
//returns true if the response was a success
public function success(){
return ($this->mode=="id_res");
}//success
//returns the identity given in the response
public function identity(){
if($this->mode!="id_res")
return null;
else
return $this->claimed_id;
}//identity
//returns the email given in the response
public function email(){
if($this->mode!="id_res")
return null;
else
return $this->email;
}//email
//returns the assoc_handle
public function assoc_handle(){
return $this->assoc_handle();
}//assoc_handle
}//class GoogleOpenID
?>

157
htdocs/lib/Layout.php Normal file
View File

@@ -0,0 +1,157 @@
<?php
/**
* Layout.php
* Common html for all pages
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Layout
{
function since($since)
{
$since = time() - $since;
$chunks = array(
array(60 * 60 * 24 * 365 , 'year'),
array(60 * 60 * 24 * 30 , 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24 , 'day'),
array(60 * 60 , 'hour'),
array(60 , 'minute'),
array(1 , 'second')
);
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = ($count == 1) ? '1 '.$name : "$count {$name}s";
return $print;
}
function header()
{
global $S;
$menu = array();
if ($S->isAnonymous())
{
$item = new stdClass;
$item->label = "Login";
$item->link = "/login.php";
$menu[] = $item;
}
else
{
if ($S->user->isAllowed())
{
$item = new stdClass;
$item->label = "Crash reports";
$item->link = "/crashes.php";
$menu[] = $item;
$item = new stdClass;
$item->label = "Statistics";
$item->link = "/statistics.php";
$menu[] = $item;
}
if ($S->user->isAdmin())
{
$item = new stdClass;
$item->label = "Users";
$item->link = "/users.php";
$menu[] = $item;
}
$item = new stdClass;
$item->label = "My Account ({$S->user->email})";
$item->link = "/account.php";
$menu[] = $item;
$item = new stdClass;
$item->label = "Logout";
$item->link = "/logout.php";
$menu[] = $item;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" type="text/css" href="<?php print URL_ROOT ?>/singularity.css"/>
<link rel="shortcut icon" href="<?php print IMG_ROOT ?>/favicon.ico" type="image/x-icon" />
<title>Singularity Viewer Automated Build System</title>
<!--script type="text/javascript">
//<![CDATA[
//]]>
</script-->
</head>
<body>
<div id="everything">
<div id="page-wrapper">
<div id="header"></div>
<div class="container"><a href="<?php print URL_ROOT ?>" style="font-size: 20px;">Automated Crash Report Processing System</a><br/>
<?php for ($i=count($menu) - 1; $i>=0; $i--): ?>
<div class="menuitem"><a href="<?php echo $menu[$i]->link; ?>"><?php echo htmlspecialchars($menu[$i]->label) ?></a></div>
<?php endfor ?>
<br/><br/>
<?php
}
function footer()
{
{ ?>
</div><!-- container -->
<div class="container">
<table style="width: 100%; border: none; padding: 0;"><tr>
<td class="bottom-links"><a href="http://www.singularityviewer.org/">Singularity Main Site</a></td>
<td class="bottom-links"><a href="http://www.singularityviewer.org/about">About</a></td>
<td class="bottom-links"><a href="http://code.google.com/p/singularity-viewer/issues/">Issue Tracker</a></td>
<td class="bottom-links"><a href="https://github.com/singularity-viewer/SingularityViewer">Source Tracker</a></td>
<td width="50%" style="text-align: right;">&copy; 2013 Singularity Viewer Project</td>
</tr></table>
</div>
</div><!-- everything -->
</div><!-- page-wrapper -->
</body>
</html>
<?php
}
}
}

93
htdocs/lib/Option.php Normal file
View File

@@ -0,0 +1,93 @@
<?php
/**
* Option.php
* Simple key-value store for various options
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Option
{
private static $optionArray = array();
/**
* Inits the option class. Must be called before any other method.
*/
public static function init()
{
global $DB;
if(!$result = $DB->query("SELECT * FROM options")) {
return false;
} else {
while ($row = $DB->fetchRow($result)) {
self::$optionArray[$row['name']] = $row['value'];
}
return true;
}
}
/**
* Updates an option.
*
* @param string $name Name of the option
* @param string $value New value for the option
* @return boolean
*/
public static function update($name, $value)
{
global $DB;
$result = $DB->query(kl_str_sql("DELETE FROM options WHERE name=!s", $name));
$result = $DB->query(kl_str_sql("INSERT INTO options (name, value) VALUES(!s,!s)", $name,$value ));
self::$optionArray[$name] = $value;
return $result;
}
/**
* Gets an option.
*
* @param string $name Name of the option
* @return string Value of the option
*/
public static function get($name)
{
if (!isset(self::$optionArray[$name])) {
return NULL;
}
return self::$optionArray[$name];
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

283
htdocs/lib/Session.php Normal file
View File

@@ -0,0 +1,283 @@
<?php
/**
* Session.php
* This class handles sessions
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Session
{
private $cookie;
public $timeout;
public $authenticated;
public $validsession;
/**
* User object containing info about the user.
*
* @var User
*/
public $user;
function __construct()
{
$this->timeout = 604800; // 7 days
$this->authenticated = false;
$this->validsession = false;
$this->cookie = "singularity_sid";
$this->user = new User;
register_shutdown_function(array(&$this, 'shutdown'));
}
function shutdown()
{
if ($this->persist || $this->ser_persist) {
$ser=serialize($this->persist);
if ($ser !== $this->ser_persist) {
$this->ser_persist = $ser == 'N;' ? '' : $ser;
$this->expires=time()+$this->timeout;
$this->update();
}
}
}
function add()
{
global $DB;
$this->sid = md5(uniqid(rand()));
$this->expires=time() + $this->timeout;
$DB->query(kl_str_sql("DELETE from session where sid=!s", $this->sid));
$q = kl_str_sql("INSERT into session (sid, user_id, authenticated, expires, persist) ".
"values (!s, !i, !i, !t, !s)",
$this->sid,
$this->user->user_id,
$this->authenticated,
$this->expires,
$this->ser_persist
);
if ($DB->query($q)) {
setcookie($this->cookie, $this->sid, NULL, '/' . REL_DIR);
return true;
} else {
return false;
}
}
function update()
{
global $DB;
$q = kl_str_sql('UPDATE session SET user_id=!i, authenticated=!i, expires=!t, persist=!s WHERE sid=!s',
$this->user->user_id, $this->authenticated, $this->expires, $this->ser_persist, $this->sid);
if (($res = $DB->query($q)) && $DB->affectedRows()) {
return true;
} else {
return $this->add();
}
}
function remove($sid = false)
{
global $DB;
if (!$sid) {
$sid = $this->sid;
}
$this->sid = NULL;
$this->validsession = false;
$this->authenticated = 0;
$this->user = new User;
$this->persist = NULL;
$this->ser_persist = NULL;
$DB->query(kl_str_sql("DELETE from session where sid=!s", $sid));
setcookie($this->cookie, '', 0, '/' . REL_DIR);
}
function check()
{
global $DB;
if (isset($_GET[$this->cookie])) {
$this->sid = $_GET[$this->cookie];
} else {
$this->sid = $_COOKIE[$this->cookie];
}
$error = true;
if (!$this->sid) {
// No session id. Is anonymous access allowed?
if (Option::get('allow_anon_access') == '1') {
$this->user = new User();
$this->user_id = $this->user->user_id;
$this->add();
} else {
$this->user_id = NULL;
$this->add();
}
$error = false;
} else {
$res = $DB->query(kl_str_sql('SELECT * from session where sid=!s', $this->sid));
if ($res AND $row = $DB->fetchRow($res)) {
$this->authenticated = (int)$row['authenticated'];
$this->expires = strtotime($row['expires']);
$this->ser_persist = $row['persist'];
$this->user_id = (int)$row['user_id'];
if (!$this->user_id) {
$this->user_id = NULL;
}
if ($this->ser_persist) {
$this->persist=@unserialize($this->ser_persist);
}
if ($this->expires >= time()) {
$error = false;
$this->validsession=true;
if (!$this->user = User::get($this->user_id)) {
$error = true;
}
}
if ($this->expires-time() < $this->timeout/2) {
$this->expires=time() + $this->timeout;
setcookie($this->cookie, $this->sid, NULL, '/' . REL_DIR);
if (!$this->update()) {
$error = true;
}
}
}
if ($error) {
if ($this->sid) {
$this->remove($this->sid);
}
$this->add();
}
}
} // End function check
function authenticate($username, $password)
{
$user = User::getByUsername($username);
if ($user AND $user->password === $password) {
$this->user = $user;
$this->user_id = $user->user_id;
$this->authenticated = true;
$this->persist->active_order = null;
$this->update();
return true;
}
return false;
}
function loginRedirect()
{
if ($l = strlen(REL_DIR)) {
$eatchars = $l + 2;
} else {
$eatchars = $l + 1;
}
$caller='/' . substr($_SERVER['PHP_SELF'], $eatchars);
$callerarg = array();
if ($nc = count($_GET)) {
foreach($_GET as $key => $value) {
$callerarg[] = urlencode($key) . '=' . urlencode($value);
}
$callerarg = implode('&', $callerarg);
}
$redirect = '/login.php?caller=' . urlencode($caller);
if ($callerarg) {
$redirect .= "&callerarg=" . urlencode($callerarg);
}
http::redirect($redirect);
}
public function requireUser()
{
if ((Option::get('allow_anon_access') == '0' && $this->isAnonymous())
|| $this->user->isAnonymous()) {
$this->loginRedirect();
} else if (!$this->user->isAllowed()) {
$this->remove($this->sid);
$this->loginRedirect();
}
}
/**
* Returns true if the user is anonymous.
*
* @return boolean
*/
public function isAnonymous()
{
if ($this->authenticated == 0) {
return true;
} else {
return false;
}
}
/**
* Redirects the user to a login screen if he's not logged in as admin.
*/
public function requireAdmin()
{
if ($this->isAdmin() != true) {
$this->remove($this->sid);
$this->loginRedirect();
}
}
/**
* Returns true if user is admin. False if not.
*
* @return boolean
*/
public function isAdmin()
{
return ($this->authenticated && $this->user->isAdmin());
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

205
htdocs/lib/User.php Normal file
View File

@@ -0,0 +1,205 @@
<?php
class User
{
/**
* Returns true if the user has a valid email, false if not.
*
* @return boolean
*/
public function hasValidEmail()
{
return (preg_match(
'/^[-!#$%&\'*+\\.\/0-9=?A-Z^_`{|}~]+'. // the user name
'@'. // the ubiquitous at-sign
'([-0-9A-Z]+\.)+' . // host, sub-, and domain names
'([0-9A-Z]){2,4}$/i', // top-level domain (TLD)
trim($this->email)));
}
/**
* Save the user as a new user.
*
* @return boolean
*/
public function save()
{
global $DB;
$query = kl_str_sql('INSERT INTO users(
name,
email,
login,
password,
is_admin,
is_allowed
) VALUES (!s,!s,!s,!s,!i,!i)',
$this->name,
$this->email,
$this->login,
$this->password,
$this->is_admin,
$this->is_allowed
);
if (!$res = $DB->query($query)) {
return false;
} else {
$this->user_id = $DB->insertID();
return $this->user_id;
}
}
public function update()
{
global $DB;
$query = kl_str_sql('
UPDATE users SET
name=!s,
email=!s,
login=!s,
password=!s,
is_admin=!i,
is_allowed=!i
WHERE user_id=!i',
$this->name,
$this->email,
$this->login,
$this->password,
$this->is_admin,
$this->is_allowed,
$this->user_id
);
//echo $query;
if (!$DB->query($query)) {
return false;
} else {
return true;
}
}
/**
* Get user by id.
*
* @param integer $id
* @return User
*/
public static function get($id)
{
global $DB;
if (is_null($id)) {
return new User();
}
$query = kl_str_sql("SELECT * FROM users WHERE user_id=!i",$id);
if(!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
public function isAnonymous()
{
return !$this->user_id;
}
public function isAdmin()
{
return $this->is_admin;
}
public function isAllowed()
{
return $this->is_allowed;
}
/**
* Get a user by username.
*
* @param string $username
* @return User
*/
public static function getByLogin($username)
{
global $DB;
$query = kl_str_sql('SELECT * FROM users WHERE login=!s', $username);
if(!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
/**
* Get an user by email.
*
* @param string $email
* @return User
*/
public static function getByEmail($email)
{
global $DB;
$query = kl_str_sql('SELECT * FROM users WHERE cust_id!=1 AND email=!s', $email);
if (!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
/**
* Get all users.
*
* @return array Array of User
*/
public static function getAll()
{
global $DB;
$query = kl_str_sql('SELECT * FROM users ORDER BY is_admin DESC, is_allowed DESC, user_id ASC');
if(!$res = $DB->query($query)) {
return false;
} else {
$retval=array();
while($row = $DB->fetchRow($res)) {
$tmp = new User();
$DB->loadFromDbRow($tmp, $res, $row);
$retval[] = $tmp;
}
return $retval;
}
}
function delete(){
global $DB;
$query=kl_str_sql("DELETE FROM users WHERE user_id=!i",$this->user_id);
//echo $query;
if(!$res=$DB->query($query)){
return false;
}
else{
return true;
}
}
public function setImportArray($array)
{
$this->name = $array['name'];
$this->email = $array['email'];
$this->login = $array['login'];
$this->password = $array['password'];
$this->is_admin = $array['is_admin'];
$this->is_allowed = $array['is_allowed'];
}
}
?>

34
htdocs/lib/db_init.sql Normal file
View File

@@ -0,0 +1,34 @@
drop table if exists raw_reports;
drop table if exists users;
drop table if exists options;
drop table if exists session;
create table session(
sid varchar(128) not null primary key,
user_id integer,
authenticated tinyint,
expires datetime,
persist text
);
create table options(
name varchar(128),
value text
);
create table users(
user_id integer not null auto_increment primary key,
name varchar(255),
email varchar(255),
login varchar(255),
password varchar(255),
is_admin tinyint,
is_allowed tinyint
);
create table raw_reports(
report_id integer not null auto_increment primary key,
reported timestamp not null default current_timestamp,
processed integer not null default 0,
raw_data longtext
);

115
htdocs/lib/ext_kl.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
/* $Id$ */
$php_str_sql_options_array = array(
"str_sql_date_format" => "Y-m-d",
"str_sql_datetime_format" => "Y-m-d H:i:s",
"str_sql_quote_func" => "mysql_real_escape_string");
/**
* This method validates the sql insert string must always be used in conjunction with an insert to the db
* @return string
*/
function kl_str_sql()
{
GLOBAL $php_str_sql_options_array;
$f = $php_str_sql_options_array['str_sql_quote_func'];
$narg = func_num_args();
$args = func_get_args();
if ($narg<1) {
trigger_error("At least one parameter required", E_USER_WARNING);
return "";
}
$offset = 0;
$flen = strlen($args[0]);
$res = "";
$narg = 1;
while ($offset < $flen) {
if (false !== ($pos = strpos($args[0],"!", $offset))) {
$res .= substr($args[0], $offset, $pos-$offset);
switch ($args[0][$pos+1]) {
case 's':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".$f($args[$narg])."'";
}
$narg++;
break;
case 'b':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".$f($args[$narg])."'";
}
$narg++;
break;
case 'i':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= (int)($args[$narg]);
}
$narg++;
break;
case 'f':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= (double)($args[$narg]);
}
$narg++;
break;
case 'd':
if (!($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".date($php_str_sql_options_array['str_sql_date_format'], $args[$narg])."'";
}
$narg++;
break;
case 't':
if (!($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".date($php_str_sql_options_array['str_sql_datetime_format'], $args[$narg])."'";
}
$narg++;
break;
default:
$res .= "!".$args[0][$pos+1];
}
$offset = $pos + 2;
} else {
$res .= substr($args[0], $offset);
$offset = $flen;
}
}
return $res;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

132
htdocs/lib/http.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* http.php
* Common http operations such as redirects, etc.
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class http
{
public static function redirectAbsolute($url)
{
Header("Location: $url");
Header("HTTP/1.0 302 Found");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>302 Found</TITLE>
</HEAD><BODY>
<H1>Found</H1>
The document was found <A HREF=\"$url\">here</A>.<P>
</BODY></HTML>
";
exit;
}
public static function redirect($url)
{
http::redirectAbsolute(URL_ROOT . $url);
}
public static function notFound()
{
header("HTTP/1.1 404 Not Found");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL was not found on this server.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function notAllowed()
{
header("HTTP/1.1 405 Method Not Allowed");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>405 Method Not Allowed</TITLE>
</HEAD><BODY>
<H1>Method Not Allowed</H1>
The requested HTTP method is not allowed for this URL.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function notModified()
{
header("HTTP/1.1 304 Not Modified");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>304 Not Modified</TITLE>
</HEAD><BODY>
<H1>Not Modified</H1>
The requested URL has not been modified.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function noCache()
{
header("Expires: Mon, 21 Jan 1980 06:01:01 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
/**
* Send data for download.
*
* @param string $filename
* @param string $data
*/
public static function sendDownload($filename, $data)
{
header('Content-disposition: attachment; filename=' . urlencode($filename));
echo $data;
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

88
htdocs/lib/init.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
if (!defined('SITE_ROOT')) {
exit(1);
}
error_reporting(E_ALL ^ E_NOTICE);
ini_set('display_errors',1);
if (!extension_loaded('kl')) {
require_once SITE_ROOT.'/lib/ext_kl.php';
}
function __autoload($class)
{
require_once(SITE_ROOT . '/lib/' . $class . '.php');
}
/* Directory relative to server root
* No leading or trailing slash.
* Example: http://www.example.com/applications/app1/
*/
define('REL_DIR', '');
if (!defined('URL_ROOT')) {
$init_port = "";
$init_ssl = strlen($_SERVER["HTTPS"]) > 0 ? true:false;
define('USE_SSL', $init_ssl);
$init_url = $init_ssl ? "https://" : "http://";
if ($init_ssl && $_SERVER['PORT']!=443) {
$init_port = $_SERVER['PORT'];
}
if (!$init_ssl && $_SERVER['PORT']!=80) {
$init_port = $_SERVER['PORT'];
}
$init_url .= $_SERVER['HTTP_HOST'];
if ($init_port) {
$init_url .= ":" . $init_port;
}
if (defined('REL_DIR') && strlen(REL_DIR)) {
$init_url .= '/' . REL_DIR;
}
define ('URL_ROOT', $init_url);
}
if (!defined('IMG_ROOT')) {
define('IMG_ROOT', URL_ROOT . '/images');
}
$DB = new DBH();
$DB_NAME = "singucrash";
$DB_USER = 'singucrash';
$DB_PASS = '-*-secrit-*-';
$DB_HOST = 'localhost';
if (!$DB->connect($DB_NAME, $DB_HOST, $DB_USER, $DB_PASS)) {
echo "System is down for mantainence. Please try again later.";
die();
}
Option::init();
$S = new Session();
if (!defined('NO_SESSION') && PHP_SAPI != "cli") {
$S->check();
}
/* Prevent XSS attacks via PHP_SELF */
$_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF']);
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>