Baïkal unter WebFaction mit Basic Authentication

Installation das Baïkal Card-/CalDAV Servers unter [WebFaction Affiliate] mit Basic Authentication

  1. Download der aktuellen Release (flat) unter http://baikal-server.com/#download unter ~/webapps/htdocs
  2. Entpacken unter ~/webapps/htdocs
  3. Umbenennen des Ordners auf baikal
  4. Rechte mit chmod -R 755 baikal setzen
  5. In [WebFaction Affiliate] eine neue Applikation erstellen
    • Name: baikal
    • App Category: Symbolic link
    • App Type: Symbolic link to static/cgi/php53 app
    • Extra info: <Absoluter Pfad des Homeverzeichnisses (zB /home/myuser/)>/webapps/htdocs/baikal
  6. In [WebFaction Affiliate] eine neue Website erstellen
    • Name: <Namen eingeben (zB baikal)>
    • Status: Enabled
    • Security: Encrypted website (https)
    • Domains: <Subdomain eingeben (zB baikal.mydomain.at)>
    • Contents: Add a web app / Reuse an existing Web App
      <Die neu erstellte App auswählen (zB baikal)> / Add app
      Save
  7. Erstellen von ~/webapps/htdocs/baikal/Core/Frameworks/SabreDAV/lib/Sabre/DAV/Auth/Backend/WebfactionBasic.php
    Code:

    <?php
    
    namespace Sabre\DAV\Auth\Backend;
    
    use Sabre\DAV;
    use Sabre\HTTP;
    
    /**
    * HTTP Basic authentication backend class
    *
    * This class can be used by authentication objects wishing to use HTTP Basic
    * Most of the digest logic is handled, implementors just need to worry about
    * the validateUserPass method.
    *
    * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
    * @author James David Low (http://jameslow.com/)
    * @author Evert Pot (http://www.rooftopsolutions.nl/)
    * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
    */
    class WebfactionBasic extends AbstractBasic {
    
        protected $pdo;
    
        public function __construct($pdo) {
            $this->pdo = $pdo;
        }
    
        protected function validateUserPass($username, $password) {
            $logindigest = hash("md5","$username:".BAIKAL_AUTH_REALM.":$password");
            $stmt = $this->pdo->prepare('SELECT username FROM users WHERE username = ? AND digesta1 = ?');
            $stmt->execute(array($username,$logindigest));
            $result = $stmt->fetchAll();
            if ( count($result) === 1 ) {
                return true;
            }
            else {
                return false;
            };
    
        }
    
        /**
        * Authenticates the user based on the current request.
        *
        * If authentication is successful, true must be returned.
        * If authentication fails, an exception must be thrown.
        *
        * @param DAV\Server $server
        * @param string $realm
        * @throws DAV\Exception\NotAuthenticated
        * @return bool
        */
        public function authenticate(\Sabre\DAV\Server $server, $realm) {
    
            $auth = new HTTP\WebfactionBasicAuth();
            $auth->setHTTPRequest($server->httpRequest);
            $auth->setHTTPResponse($server->httpResponse);
            $auth->setRealm($realm);
            $userpass = $auth->getUserPass();
            if (!$userpass) {
                $auth->requireLogin();
                throw new DAV\Exception\NotAuthenticated('No basic authentication headers were found');
            }
    
            // Authenticates the user
            if (!$this->validateUserPass($userpass[0],$userpass[1])) {
                $auth->requireLogin();
                throw new DAV\Exception\NotAuthenticated('Username or password does not match');
            }
            $this->currentUser = $userpass[0];
            return true;
        }
    
    }
  8. Erstellen von
    ~/webapps/htdocs/baikal//Core/Frameworks/SabreDAV/lib/Sabre/HTTP/WebfactionBasicAuth.php
    Code:

    <?php
    
    namespace Sabre\HTTP;
    
    /**
     * HTTP Basic Authentication handler
     *
     * Use this class for easy http authentication setup
     *
     * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
     * @author Evert Pot (http://www.rooftopsolutions.nl/)
     * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
     */
    class WebfactionBasicAuth extends AbstractAuth {
    
        /**
         * Returns the supplied username and password.
         *
         * The returned array has two values:
         *   * 0 - username
         *   * 1 - password
         *
         * If nothing was supplied, 'false' will be returned
         *
         * @return mixed
         */
        public function getUserPass() {
    
            //set http auth headers for Webfaction workaround
            if(isset($_GET['Authorization']) && preg_match('/Basic\s+(.*)$/i', $_GET['Authorization'], $matches))
            {
                list($name, $password) = explode(':', base64_decode($matches[1]));
                $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
                $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
            }
    
            // Apache and mod_php
            if (($user = $this->httpRequest->getRawServerValue('PHP_AUTH_USER')) && ($pass = $this->httpRequest->getRawServerValue('PHP_AUTH_PW'))) {
    
                return array($user,$pass);
    
            }
    
            // Most other webservers
            $auth = $this->httpRequest->getHeader('Authorization');
    
            // Apache could prefix environment variables with REDIRECT_ when urls
            // are passed through mod_rewrite
            if (!$auth) {
                $auth = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
            }
    
            if (!$auth) return false;
    
            if (strpos(strtolower($auth),'basic')!==0) return false;
    
            return explode(':', base64_decode(substr($auth, 6)),2);
    
        }
    
        /**
         * Returns an HTTP 401 header, forcing login
         *
         * This should be called when username and password are incorrect, or not supplied at all
         *
         * @return void
         */
        public function requireLogin() {
    
            $this->httpResponse->setHeader('WWW-Authenticate','Basic realm="' . $this->realm . '"');
            $this->httpResponse->sendStatus(401);
    
        }
    
    }
  9. Erstellen von ~/webapps/htdocs/baikal/.htaccess
    Code:

    # Disabling cache management
    # that could cause problems with DAV requests
    # Useful only for Apache servers, with AllowOverride All
    # (ie, .htaccess files enabled)
    
    # Allow HTTP headers with Apache/FastCGI
    # See http://code.google.com/p/sabredav/wiki/Authentication#Apache_+_(Fast)CGI
    
    <IfModule mod_rewrite.c>
            RewriteEngine On
    # didn't work
    #       RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
    # actually works
            RewriteCond %{HTTP:Authorization} ^Basic.*
            RewriteRule ^(.*) $1?Authorization=%{HTTP:Authorization} [QSA,C]
            RequestHeader unset Authorization
    </IfModule>
    
    <IfModule mod_expires.c>
            ExpiresActive Off
    </IfModule>
    
    # Android
    RedirectPermanent /dav https://dav.niemetz.it/cal.php
    
    # iOS
    RedirectPermanent /.well-known/caldav https://dav.niemetz.it/cal.php
    RedirectPermanent /.well-known/carddav https://dav.niemetz.it/card.php
    
  10. cal.php und card.php anpassen
    Zeile

    $authBackend = new \Sabre\DAV\Auth\Backend\PDO($GLOBALS["DB"]->getPDO());

    in

    $authBackend = new \Sabre\DAV\Auth\Backend\WebfactionBasic($GLOBALS["DB"]->getPDO());

    ändern

Das war’s

3 Responses to “Baïkal unter WebFaction mit Basic Authentication”

  1. Christian S

    Hallo!

    Vielen Dank für den Hinweis – der Workaround funktioniert auch bei anderen Hostern wunderbar. Dank des Moduls funktioniert Baikal 0.26 auch auf meinem verwalteten Webserver.

    Die Pfade in Schritt 7 und 8 haben sich mit Baikal 0.26 geändert – siehe auch hier: http://st-devel.net/blcsb

    Vielen Dank für den Workaround!

    Beste Grüße,
    Christian.

  2. Michael

    Dear Gerd,

    Many thanks for the excellent workaround that worked many years.
    My question: do you know how to “reimplement” using the new Baïkal?

    I cannot get it to work for the heck of my life 🙁

    Many thanks.

    Kind regards

    • Gerd

      Dear Michael,

      i don’t use Baïkal under WebFaction anymore, so i’m sorry for not having any update on this issue for you 🙁

      Best regards,
      Gerd

×

Kommentare sind geschlossen.