Worked with Oscar on this one: Fixed http authentication, domain login, cleaned up code format. Tested with Thunderbird Lightning and direct browser access without browser errors in

events.ics.  Tasks may be an issue to manage separately.  This file now works solely with the sessions class and no longer calls auth->authenticate()
This commit is contained in:
Miles Lott 2007-02-15 16:19:06 +00:00
parent 48c12d2ef9
commit 21287627ea

View File

@ -42,11 +42,11 @@
//-------- basic operation configuration variables ----------
$logdir = false; // set to false for no logging
$logdir = False; // set to false for no logging
#$logdir = '/tmp'; // set to a valid (writable) directory to get log file generation
// set to true for debug logging to errorlog
#$isdebug = True;
//$isdebug = True;
$isdebug = False;
/** Disallow users to import in non owned calendars and infologs
@ -56,117 +56,71 @@ $disable_nonowner_import = false;
// icalsrv variant with session setup modeled after xmlrpc.php
//die(print_r($_COOKIE, true));
$icalsrv = array();
$GLOBALS['egw_info'] = array();
$GLOBALS['egw_info']['flags'] =
array(
$GLOBALS['egw_info']['flags'] = array(
'currentapp' => 'login',
'noheader' => True,
'nonavbar' => True,
'disable_Template_class' => True
);
include('header.inc.php');
// silly for now but who knows...
$GLOBALS['egw_info']['server']['icalsrv'] = true;
/** Control and status of the icalsrv session setup
* @bug icalsrv enabled checking is not yet working...
* @var array $icalsrv
*/
$icalsrv = array();
// Somehow check if icalsrv is enabled none of the 2 ways works yet..
// either via 1:
$icalsrv['enabled'] = isset($GLOBALS['egw_info']['user']['apps']['icalsrv']);
// or via 2: the configdata
$c =& CreateObject('phpgwapi.config','icalsrv');
$c->read_repository();
$config =& $c->config_data;
unset($c);
$icalsrv['enabled'] = $config['icalsrv_enabled'];
// or via 3: force it! Yes this works :-)
$icalsrv['enabled'] = true;
if(!$icalsrv['enabled']) {
fail_exit('IcalSRV not enabled','403');
$ical_login = split('\@',$_SERVER['PHP_AUTH_USER']);
if($ical_login[1])
{
$ical_user = $ical_login[0];
$domain = $ical_login[1];
unset($ical_login);
}
else
{
$ical_user = $_SERVER['PHP_AUTH_USER'];
$domain = get_var('domain',array('COOKIE','GET'));
}
// now check if we have a session there (according to cookie and auth)
// define this function ourselves if not there..
if(!function_exists('getallheaders')) {
function getallheaders(){
settype($headers,'array');
foreach($_SERVER as $h => $v) {
if(ereg('HTTP_(.+)',$h,$hp)){
$headers[$hp[1]] = $v;
}
}
return $headers;
}
}
$headers = getallheaders();
$auth_header = $headers['Authorization']
? $headers['Authorization'] : $headers['authorization'];
if(eregi('Basic *([^ ]*)',$auth_header,$auth)) {
list($sessionid,$kp3) = explode(':',base64_decode($auth[1]));
// echo "auth='$auth[1]', sessionid='$sessionid', kp3='$kp3'\n";
} else {
$sessionid = get_var('sessionid',array('COOKIE','GET'));
$kp3 = get_var('kp3',array('COOKIE','GET'));
$domain = $domain ? $domain : $GLOBALS['egw_info']['server']['default_domain'];
$icalsrv['session_ok'] = $GLOBALS['egw']->session->verify($sessionid,$kp3);
if($icalsrv['session_ok'])
{
$icalsrv['authed'] = True;
}
if($icalsrv['session_ok'] = $GLOBALS['egw']->session->verify($sessionid,$kp3)){
$s_user_id = $GLOBALS['egw_info']['user']['account_id'];
// check if the new user is the one from the session
$a_user_id = $GLOBALS['egw']->accounts->name2id($_SERVER['PHP_AUTH_USER']);
if( !($a_user_id == $s_user_id)){
$icalsrv['session_ok'] = false;
if(!$icalsrv['session_ok'] && isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']))
{
$icalsrv['authed'] = $GLOBALS['egw']->session->create($ical_user . '@' . $domain, $_SERVER['PHP_AUTH_PW'], 'text');
}
} else {
if($isdebug)
error_log('NO OLD SESSION');
}
if (!$icalsrv['session_ok'] and isset($_SERVER['PHP_AUTH_USER'])
and isset($_SERVER['PHP_AUTH_PW'])) {
// $login = $_SERVER['PHP_AUTH_USER'];
// $domain = 'default';
// check for a possible valid login domain present as parameter
if(isset($_GET['domain'])){
$domain = $_GET['domain'];
}else{
$domain = $GLOBALS['egw_info']['server']['default_domain'];
}
if(!array_key_exists($domain, $GLOBALS['egw_domain'])){
error_log('icalsrv.php: login, invalid domain:' .$domain);
} else {
$userlogin = $_SERVER['PHP_AUTH_USER'] . '@' . $domain;
if($isdebug)
error_log('TRY NEW SESSION FOR login:' . $userlogin);
$sess_id = $GLOBALS['egw']->session->create($userlogin, $_SERVER['PHP_AUTH_PW'],
'text');
}
if ($sess_id) {
$icalsrv['session_ok'] = true;
$GLOBALS['egw_info']['user']['account_id'] = $sess_id->account_id;
}
}
if($icalsrv['session_ok']){
$icalsrv['authed'] = $GLOBALS['egw']->auth->authenticate($_SERVER['PHP_AUTH_USER'],
$_SERVER['PHP_AUTH_PW']);
if($icalsrv['authed'])
{
$icalsrv['session_ok'] = True;
// This may not even be necessary:
$GLOBALS['egw_info']['flags']['currentapp'] = 'icalsrv';
}
// bad session or bad authentication so please re-authenticate..
if (!($icalsrv['session_ok'] && $icalsrv['authed'])) {
if(!($icalsrv['session_ok'] && $icalsrv['authed']))
{
if($isdebug)
{
error_log('line ' . __LINE__ . ': Session: '. $icalsrv['session_ok'] . ', Authed: ' . $icalsrv['authed']);
}
header('WWW-Authenticate: Basic realm="ICal Server"');
header('HTTP/1.1 401 Unauthorized');
exit;
}
/* Moved after the auth header send. It is normal to save this check until now, similar to how simple eGroupWare access control works for a browser login. (Milosch) */
if(!@isset($GLOBALS['egw_info']['user']['apps']['icalsrv']))
{
fail_exit('IcalSRV not enabled','403');
}
// oke we have a session!
// Ok! We have a session and access to icalsrv!
// now set the variables that will control the working mode of icalvircal
// the defines are in the egwical_resourcehandler sourcefile
@ -254,17 +208,21 @@ unset($reqvircal_owner);
unset($reqvircal_owner_id);
unset($reqvircal_basename);
if(empty($_SERVER['PATH_INFO'])){
if(empty($_SERVER['PATH_INFO']))
{
// no specific calendar requested, so do default.ics
$reqvircal_pathname = '/default.ics';
// try owner + base for a personal vircal request
} elseif (preg_match('#^/([\w]+)(/[^<^>^?]+)$#', $_SERVER['PATH_INFO'], $matches)){
}
elseif(preg_match('#^/([\w]+)(/[^<^>^?]+)$#', $_SERVER['PATH_INFO'], $matches))
{
$reqvircal_pathname = $matches[0];
$reqvircal_owner = $matches[1];
$reqvircal_basename = $matches[2];
if(!$reqvircal_owner_id = $GLOBALS['egw']->accounts->name2id($reqvircal_owner)){
if(!$reqvircal_owner_id = $GLOBALS['egw']->accounts->name2id($reqvircal_owner))
{
// owner is unknown, so forget about personal calendar
unset($reqvircal_owner);
@ -272,23 +230,28 @@ if(empty($_SERVER['PATH_INFO'])){
}
// check for decent non personal path
} elseif (preg_match('#^(/[^<^>]+)$#', $_SERVER['PATH_INFO'], $matches)){
}
elseif(preg_match('#^(/[^<^>]+)$#', $_SERVER['PATH_INFO'], $matches))
{
$reqvircal_pathname = $matches[0];
// just default to standard path
} else {
}
else
{
$reqvircal_pathname = 'default.ics';
}
if($isdebug)
error_log('http-user-agent:' . $reqagent .
',pathinfo:' . $reqpath . ',rvc_pathname:' . $reqvircal_pathname .
',rvc_owner:' . $reqvircal_owner . ',rvc_owner_id:' . $reqvircal_owner_id .
',rvc_basename:' . $reqvircal_basename);
{
error_log('http-user-agent:' . $reqagent
. ',pathinfo:' . $reqpath . ',rvc_pathname:' . $reqvircal_pathname
. ',rvc_owner:' . $reqvircal_owner . ',rvc_owner_id:' . $reqvircal_owner_id
. ',rvc_basename:' . $reqvircal_basename);
}
// S1A search for the requested calendar in the vircal_ardb's
if(is_numeric($reqvircal_owner_id)){
if(is_numeric($reqvircal_owner_id))
{
// check if the requested personal calender is provided by the owner..
/**
@ -300,27 +263,31 @@ if(is_numeric($reqvircal_owner_id)){
// find personal database of (array stored) virtual calendars
$cnmsg = 'calendar [' . $reqvircal_basename . '] for user [' . $reqvircal_owner . ']';
$vo_personal_vircal_ardb =& CreateObject('icalsrv.personal_vircal_ardb', $reqvircal_owner_id);
if(!(is_object($vo_personal_vircal_ardb))){
if(!(is_object($vo_personal_vircal_ardb)))
{
error_log('icalsrv.php: couldnot create personal vircal_ardb for user:' . $reqvircal_owner);
fail_exit('could not access' . $cnmsg, '403');
}
// check if a /<username>/list.html is requested
if ($reqvircal_basename == '/list.html'){
if($reqvircal_basename == '/list.html')
{
echo $vo_personal_vircal_ardb->listing(1);
$GLOBALS['egw']->common->egw_exit();
}
# error_log('vo_personal_vircal_ardb:' . print_r($vo_personal_vircal_ardb->calendars, true));
error_log('vo_personal_vircal_ardb:' . print_r($vo_personal_vircal_ardb->calendars, true));
// search our calendar in personal vircal database
if(!($vircal_arstore = $vo_personal_vircal_ardb->calendars[$reqvircal_basename])){
if(!($vircal_arstore = $vo_personal_vircal_ardb->calendars[$reqvircal_basename]))
{
error_log('icalsrv.php: ' . $cnmsg . ' not found.');
fail_exit($cnmsg . ' not found.' , '404');
}
// oke we have a valid personal vircal in array_storage format!
} else {
}
else
{
// check if the requested system calender is provided by system
$cnmsg = 'system calendar [' . $reqvircal_pathname . ']';
/**
@ -331,31 +298,37 @@ if(is_numeric($reqvircal_owner_id)){
// find system database of (array stored) virtual calendars
$system_vircal_ardb = CreateObject('icalsrv.system_vircal_ardb');
if(!(is_object($system_vircal_ardb))){
if(!(is_object($system_vircal_ardb)))
{
error_log('icalsrv.php: couldnot create system vircal_ardb');
fail_exit('couldnot access ' . $cnmsg, '403');
}
// check if a /list.html is requested
if ($reqvircal_pathname == '/list.html'){
if($reqvircal_pathname == '/list.html')
{
echo $system_vircal_ardb->listing(1);
$GLOBALS['egw']->common->egw_exit();
}
// search our calendar in system vircal database
if(!($vircal_arstore = $system_vircal_ardb->calendars[$reqvircal_pathname])){
if(!($vircal_arstore = $system_vircal_ardb->calendars[$reqvircal_pathname]))
{
fail_exit($cnmsg . ' not found', '404');
}
// oke we have a valid system vircal in array_storage format!
}
//die(print_r($_COOKIE,true). " in ". __FILE__.", line ".__LINE__);
if($isdebug)
{
error_log('vircal_arstore:' . print_r($vircal_arstore, true));
}
// build a virtual calendar with ical facilities from the found vircal
// array_storage data
$icalvc =& CreateObject('icalsrv.icalvircal');
if(! $icalvc->fromArray($vircal_arstore)){
if(! $icalvc->fromArray($vircal_arstore))
{
error_log('icalsrv.php: ' . $cnmsg . ' couldnot restore from repository.' );
fail_exit($cnmsg . ' internal problem ' , '403');
}
@ -367,10 +340,12 @@ $icalvc->auth = ':basic';
// check if the virtual calendar demands authentication
if(strpos($icalvc->auth,'none') !== false){
if(strpos($icalvc->auth,'none') !== false)
{
// no authentication demanded so continue
} elseif(strpos($icalvc->auth,'basic') !== false){
}
elseif(strpos($icalvc->auth,'basic') !== false)
{
//basic http authentication demanded
//so exit on non authenticated http request
@ -392,15 +367,16 @@ if(strpos($icalvc->auth,'none') !== false){
// $GLOBALS['egw_info']['user']['account_id'] = $user_id;
// error_log(' ACCOUNT SETUP FOR'
// . $GLOBALS['egw_info']['user']['account_id']);
} elseif(strpos($icalvc->auth,'ssl') !== false){
}
elseif(strpos($icalvc->auth,'ssl') !== false)
{
// ssl demanded, check if we are in https authenticated connection
// if not redirect to https
error_log('icalsrv.php:' . $cnmsg . ' demands secure connection');
fail_exit($cnmsg . ' demands secure connection: please use https', '403');
} else {
}
else
{
error_log('*** icalsrv.php:' . $cnmsg . ' requires unknown authentication method:'
. $icalcv->auth);
fail_exit($cnmsg . ' demands unavailable authentication method:'
@ -413,11 +389,13 @@ if(strpos($icalvc->auth,'none') !== false){
* better be incorporated in the ACL checkings. At some time...
*/
// check if an extra password is needed too
if(strpos($icalvc->auth,'passw') !== false){
if(strpos($icalvc->auth,'passw') !== false)
{
//extra parameter password authentication demanded
//so exit if pw parameter is not valid
if((!isset($_GET['password'])) ||
(!$icalvc->pw !== $_GET['password']) ) {
(!$icalvc->pw !== $_GET['password']))
{
error_log('icalsrv.php:' . $cnmsg . ' demands extra password parameter');
fail_exit($cnmsg . ' demands extra password parameter', '403');
}
@ -432,21 +410,27 @@ $icalvc->reimport_missing_elements = $reimport_missing_elements;
$logmsg = "";
// oke now process the actual import or export to/from icalvc..
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
if($_SERVER['REQUEST_METHOD'] == 'PUT')
{
// *** PUT Request so do an Import *************
if($isdebug)
{
error_log('icalsrv.php: importing, by user:' .$GLOBALS['egw_info']['user']['account_id']
. ' for virtual calendar of: ' . $reqvircal_owner_id);
}
// check if importing in not owned calendars is disabled
if($reqvircal_owner_id
&& ($GLOBALS['egw_info']['user']['account_id'] !== $reqvircal_owner_id)){
if($disable_nonowner_import){
&& ($GLOBALS['egw_info']['user']['account_id'] !== $reqvircal_owner_id))
{
if($disable_nonowner_import)
{
error_log('icalsrv.php: importing in non owner calendars currently disabled');
fail_exit('importing in non owner calendars currently disabled', '403');
}
}
if(isset($reqvircal_owner_id) && ($reqvircal_owner_id < 0)){
if(isset($reqvircal_owner_id) && ($reqvircal_owner_id < 0))
{
error_log('icalsrv.php: importing in group calendars not allowed');
fail_exit('importing in groupcalendars is not allowed', '403');
}
@ -455,7 +439,8 @@ if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$logmsg = 'IMPORTING in '. $importMode . ' mode';
$fpput = fopen("php://input", "r");
$vcalstr = "";
while ($data = fread($fpput, 1024)){
while($data = fread($fpput, 1024))
{
$vcalstr .= $data;
}
fclose($fpput);
@ -465,24 +450,30 @@ if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$import_table =& $icalvc->import_vcal($vcalstr);
// count the successes..
if ($import_table === false) {
if($import_table === false)
{
$msg = 'icalsrv.php: importing '. $cnmsg . ' ERRORS';
fail_exit($msg,'403');
} else {
}
else
{
$logmsg .= "\n imported " . $cnmsg . ' : ';
foreach ($import_table as $rsc_class => $vids){
foreach($import_table as $rsc_class => $vids)
{
$logmsg .= "\n resource: " . $rsc_class . ' : ' . count($vids) .' elements OK';
}
}
// DONE importing
if($logdir) log_ical($logmsg,"import",$vcalstr);
if($logdir)
{
log_ical($logmsg,"import",$vcalstr);
}
// handle response ...
$GLOBALS['egw']->common->egw_exit();
} else {
}
else
{
// *** GET (or POST?) Request so do an export
$logmsg = 'EXPORTING';
// derive a ProductType from our http Agent and set it in icalvc
@ -492,10 +483,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$vcalstr = $icalvc->export_vcal();
// handle response
if ($vcalstr === false) {
if($vcalstr === false)
{
$msg = 'icalsrv.php: exporting '. $cnmsg . ' ERRORS';
fail_exit($msg,'403');
} else {
}
else
{
$logmsg .= "\n exported " . $cnmsg ." : OK ";
}
// DONE exporting
@ -503,16 +497,14 @@ if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
if($logdir) log_ical($logmsg,"export",$vcalstr);
// handle response ...
$content_type = egwical_resourcehandler::deviceType2contentType($icalvc->deviceType);
if($content_type){
if($content_type)
{
header($content_type);
}
echo $vcalstr;
$GLOBALS['egw']->common->egw_exit();
}
// // --- SOME UTILITY FUNCTIONS -------
/**
@ -530,9 +522,6 @@ function fail_exit($msg, $errno = '403')
$GLOBALS['egw']->common->egw_exit();
}
/*
* Log info and data to logfiles if logging is set
*
@ -563,8 +552,4 @@ function log_ical($msg,$icalmethod="data",$data)
fputs($fp, $data);
fclose($fp);
}
?>