/** * Constructor. * * @param Horde_Kolab_FreeBusy_User $user The decorated user. * @param Horde_Controller_Request $request The request. * @param mixed $logger The log handler. The class must * at least provide the notice() * and err() methods. */ public function __construct(Horde_Kolab_FreeBusy_User $user, Horde_Controller_Request $request, $logger) { $this->_user = $user; $this->_logger = $logger; $vars = $request->getServerVars(); $this->_remote = isset($vars['REMOTE_ADDR']) ? $vars['REMOTE_ADDR'] : 'unknown'; }
/** * Extract user name and password from the request. * * @return NULL */ private function _extractUserAndPassword() { $vars = $this->_request->getServerVars(); $this->_user = isset($vars['PHP_AUTH_USER']) ? $vars['PHP_AUTH_USER'] : null; $this->_pass = isset($vars['PHP_AUTH_PW']) ? $vars['PHP_AUTH_PW'] : null; // This part allows you to use the PHP scripts with CGI rather than as // an apache module. This will of course slow down things but on the // other hand it allows you to reduce the memory footprint of the // apache server. The default is to use PHP as a module and the CGI // version requires specific Apache configuration. // // http://www.besthostratings.com/articles/http-auth-php-cgi.html // // The line you need to add to your configuration of the /freebusy // location of your server looks like this: // // RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] // // The complete section will probably look like this then: // // <IfModule mod_rewrite.c> // RewriteEngine On // # FreeBusy list handling // RewriteBase /freebusy // RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] // RewriteRule ^([^/]+)\.ifb freebusy.php?uid=$1 [L] // RewriteRule ^([^/]+)\.vfb freebusy.php?uid=$1 [L] // RewriteRule ^([^/]+)\.xfb freebusy.php?uid=$1&extended=1 [L] // RewriteRule ^trigger/(.+)\.pfb pfb.php?folder=$1&cache=0 [L] // RewriteRule ^(.+)\.pfb pfb.php?folder=$1&cache=1 [L] // RewriteRule ^(.+)\.pxfb pfb.php?folder=$1&cache=1&extended=1 [L] // </IfModule> if (empty($this->_user)) { $remote_user = isset($vars['REDIRECT_REDIRECT_REMOTE_USER']) ? $vars['REDIRECT_REDIRECT_REMOTE_USER'] : null; if (!empty($remote_user)) { $a = base64_decode(substr($remote_user, 6)); if (strlen($a) > 0 && strpos($a, ':') !== false) { list($this->_user, $this->_pass) = explode(':', $a, 2); } } else { $this->_user = ''; } } }
/** * Handle request * * @return text The content type of the response (text/xml). */ public function handle(Horde_Controller_Request $request = null) { $parser = xml_parser_create(); xml_parse_into_struct($parser, $this->_decoder->getStream()->getString(), $values); // Get $_SERVER $server = $request->getServerVars(); // Some broken clients *cough* android *cough* don't send the actual // XML data structure at all, but instead use the email address as // the username in the HTTP_AUTHENTICATION data. There are so many things // wrong with this, but try to work around it if we can. if (empty($values) && !empty($server['HTTP_AUTHORIZATION'])) { $hash = base64_decode(str_replace('Basic ', '', $server['HTTP_AUTHORIZATION'])); if (strpos($hash, ':') !== false) { list($email, $pass) = explode(':', $hash, 2); } } elseif (empty($values)) { throw new Horde_Exception_AuthenticationFailure('No username provided.'); } else { $email = $values[2]['value']; } // Need to override the username since AUTODISCOVER always uses email // address. $credentials = new Horde_ActiveSync_Credentials($this->_activeSync); $credentials->username = $email; if (!$this->_activeSync->authenticate($credentials)) { throw new Horde_Exception_AuthenticationFailure(); } if (!empty($values)) { $params = array('request_schema' => trim($values[0]['attributes']['XMLNS'])); // Response Schema is not in a set place. foreach ($values as $value) { if ($value['tag'] == 'ACCEPTABLERESPONSESCHEMA') { $params['response_schema'] = trim($value['value']); break; } } } else { // Assume broken clients want these schemas. $params = array('request_schema' => 'http://schemas.microsoft.com/exchange/autodiscover/mobilesync/requestschema/2006', 'response_schema' => 'http://schemas.microsoft.com/exchange/autodiscover/mobilesync/responseschema/2006'); } $results = $this->_driver->autoDiscover($params); if (empty($results['raw_xml'])) { $this->_encoder->getStream()->add($this->_buildResponseString($results)); } else { // The backend is taking control of the XML. $this->_encoder->getStream()->add($results['raw_xml']); } return 'text/xml'; }