<?php
/**
* Greyhound - real web management for Amarok
* Copyright (C) 2008 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
*/
function greyhound_login_page($httpd, $socket)
{
if ( session_check() )
{
$httpd->header('HTTP/1.1 307 Temporary Redirect');
$httpd->header('Location: /');
return;
}
$tried = false;
$success = false;
if ( isset($_POST['username']) && isset($_POST['password']) )
{
$tried = true;
if ( $sessionid = login($_POST['username'], $_POST['password']) )
{
$success = true;
$httpd->setcookie('grey_session', $sessionid, time() + ( 86400 * 3650 ));
}
}
global $theme;
$iphone = ( ( strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') ||
strpos($_SERVER['HTTP_USER_AGENT'], 'iPod') ||
strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') ||
isset($_GET['m']) )
&& !isset($_GET['f'])
);
$theme_id = ( $iphone ) ? 'iphone' : $theme;
$smarty = load_theme($theme_id);
$smarty->assign('theme', $theme_id);
$smarty->assign('greyhound_version', GREY_VERSION);
$smarty->assign('tried', $tried);
$smarty->assign('success', $success);
$smarty->display('login.tpl');
}
function greyhound_logout($httpd, $socket)
{
// destroy the session
if ( isset($_COOKIE['grey_session']) )
{
load_session_data();
global $session_data;
unset($session_data[$_COOKIE['grey_session']]);
session_commit_db();
}
$httpd->setcookie('grey_session', '', time() - 864000);
$httpd->header('HTTP/1.1 307 Temporary Redirect');
$httpd->header('Location: /');
}
/**
* Check to see if we're logged in
*/
function session_check()
{
global $use_auth, $auth_data;
if ( !$use_auth )
return true;
if ( isset($_COOKIE['grey_session']) )
{
load_session_data();
global $session_data;
if ( isset($session_data[$_COOKIE['grey_session']]) )
{
// has a cookie with a valid session ID, check credentials
$session =& $session_data[$_COOKIE['grey_session']];
if ( isset($auth_data[$session['user']]) )
{
$password =& $auth_data[$session['user']];
if ( $session['hash'] === hmac_md5($password, $session['salt']) )
{
// session is valid, logged in
return $session['user'];
}
}
}
}
return ( $use_auth ) ? false : true;
}
function login($username, $password)
{
global $use_auth, $auth_data;
if ( !$use_auth )
return false;
if ( isset($auth_data[$username]) )
{
if ( $auth_data[$username] === $password )
{
return create_session($username, $password);
}
}
return false;
}
function create_session($username, $password)
{
load_session_data();
global $session_data;
$sessid = md5(sha1(microtime() . mt_rand()));
$salt = md5(sha1(md5(mt_rand() . microtime() . microtime() . mt_rand())));
$session_data[$sessid] = array(
'user' => $username,
'hash' => hmac_md5($password, $salt),
'salt' => $salt
);
session_commit_db();
return $sessid;
}
function var_export_string($arr)
{
ob_start();
var_export($arr);
$r = ob_get_contents();
ob_end_clean();
return $r;
}
function session_commit_db()
{
global $session_data;
$d = var_export_string($session_data);
$fp = @fopen('./session_db.php', 'w');
if ( !$fp )
{
warning('Could not open the session database for writing. Logins may not work.');
return false;
}
$d = <<<EOF
<?php
// Automatically generated session database for Greyhound. Do not edit this file!
\$GLOBALS['session_data'] = $d;
EOF;
fwrite($fp, $d);
fclose($fp);
return true;
}
function load_session_data()
{
if ( file_exists('./session_db.php') )
{
require('./session_db.php');
}
else
{
$GLOBALS['session_data'] = array();
}
}
$session_data = array();
/*
* All this HMAC stuff is ported (ok, copied and pasted) from Enano.
* Hey, I own the copyright on it.
*/
function hmac_core($message, $key, $hashfunc)
{
if ( strlen($key) % 2 == 1 )
$key .= '0';
if ( strlen($key) > 128 )
$key = $hashfunc($key);
while ( strlen($key) < 128 )
{
$key .= '00';
}
$opad = hmac_hexbytearray($key);
$ipad = $opad;
for ( $i = 0; $i < count($ipad); $i++ )
{
$opad[$i] = $opad[$i] ^ 0x5c;
$ipad[$i] = $ipad[$i] ^ 0x36;
}
$opad = hmac_bytearraytostring($opad);
$ipad = hmac_bytearraytostring($ipad);
return $hashfunc($opad . hexdecode($hashfunc($ipad . $message)));
}
function hmac_hexbytearray($val)
{
$val = hexdecode($val);
return hmac_bytearray($val);
}
function hmac_bytearray($val)
{
$val = str_split($val, 1);
foreach ( $val as &$char )
{
$char = ord($char);
}
return $val;
}
function hmac_bytearraytostring($val)
{
foreach ( $val as &$char )
{
$char = chr($char);
}
return implode('', $val);
}
function hmac_md5($message, $key)
{
return hmac_core($message, $key, 'md5');
}
?>