]> git.mxchange.org Git - friendica.git/commitdiff
Enable remote authentication with HTTP Signatures
authorMichael <heluecht@pirati.ca>
Tue, 19 Mar 2019 06:44:51 +0000 (06:44 +0000)
committerMichael <heluecht@pirati.ca>
Tue, 19 Mar 2019 06:44:51 +0000 (06:44 +0000)
src/App.php
src/Model/Profile.php
src/Module/Photo.php
src/Util/HTTPSignature.php

index b3eed92a0da3937b7f793eeb9008c0d7c5700f7f..b5ad6832197a536eaaeab998375321c10567e9e1 100644 (file)
@@ -12,7 +12,9 @@ use Friendica\Core\Config\Cache\ConfigCacheLoader;
 use Friendica\Core\Config\Cache\IConfigCache;
 use Friendica\Core\Config\Configuration;
 use Friendica\Database\DBA;
+use Friendica\Model\Profile;
 use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\HTTPSignature;
 use Friendica\Util\Profiler;
 use Psr\Log\LoggerInterface;
 
@@ -1143,6 +1145,13 @@ class App
                        Core\Worker::executeIfIdle();
                }
 
+               if ($this->getMode()->isNormal()) {
+                       $requester = HTTPSignature::getSigner('', $_SERVER);
+                       if (!empty($requester)) {
+                               Profile::addVisitorCookieForHandle($requester);
+                       }
+               }
+
                // ZRL
                if (!empty($_GET['zrl']) && $this->getMode()->isNormal()) {
                        $this->query_string = Model\Profile::stripZrls($this->query_string);
index b10e9848f5893d269fe79dcb1214ceb8beff159b..b856407994d1d73ff948915d40cc37b6f6cf22c8 100644 (file)
@@ -1083,34 +1083,18 @@ class Profile
        }
 
        /**
-        * OpenWebAuth authentication.
-        *
-        * Ported from Hubzilla: https://framagit.org/hubzilla/core/blob/master/include/zid.php
+        * Set the visitor cookies (see remote_user()) for the given handle
         *
-        * @param string $token
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
+        * @param string $handle Visitor handle
+        * @return array Visitor contact array
         */
-       public static function openWebAuthInit($token)
+       public static function addVisitorCookieForHandle($handle)
        {
-               $a = \get_app();
-
-               // Clean old OpenWebAuthToken entries.
-               OpenWebAuthToken::purge('owt', '3 MINUTE');
-
-               // Check if the token we got is the same one
-               // we have stored in the database.
-               $visitor_handle = OpenWebAuthToken::getMeta('owt', 0, $token);
-
-               if($visitor_handle === false) {
-                       return;
-               }
-
                // Try to find the public contact entry of the visitor.
-               $cid = Contact::getIdForURL($visitor_handle);
-               if(!$cid) {
-                       Logger::log('owt: unable to finger ' . $visitor_handle, Logger::DEBUG);
-                       return;
+               $cid = Contact::getIdForURL($handle);
+               if (!$cid) {
+                       Logger::log('unable to finger ' . $handle, Logger::DEBUG);
+                       return [];
                }
 
                $visitor = DBA::selectFirst('contact', [], ['id' => $cid]);
@@ -1133,6 +1117,43 @@ class Profile
 
                        $_SESSION['remote'][] = ['cid' => $contact['id'], 'uid' => $contact['uid'], 'url' => $visitor['url']];
                }
+
+               $a->contact = $visitor;
+
+               Logger::info('Authenticated visitor', ['url' => $visitor['url']]);
+
+               return $visitor;
+       }
+
+       /**
+        * OpenWebAuth authentication.
+        *
+        * Ported from Hubzilla: https://framagit.org/hubzilla/core/blob/master/include/zid.php
+        *
+        * @param string $token
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws \ImagickException
+        */
+       public static function openWebAuthInit($token)
+       {
+               $a = \get_app();
+
+               // Clean old OpenWebAuthToken entries.
+               OpenWebAuthToken::purge('owt', '3 MINUTE');
+
+               // Check if the token we got is the same one
+               // we have stored in the database.
+               $visitor_handle = OpenWebAuthToken::getMeta('owt', 0, $token);
+
+               if ($visitor_handle === false) {
+                       return;
+               }
+
+               $visitor = self::addVisitorCookieForHandle($visitor_handle);
+               if (empty($visitor)) {
+                       return;
+               }
+
                $arr = [
                        'visitor' => $visitor,
                        'url' => $a->query_string
index f5bbf4a77446d73ecdf723073e6d554509a31d36..15ea261fb0cf6ac1093e2f940d6bbd6df36d54c4 100644 (file)
@@ -45,9 +45,6 @@ class Photo extends BaseModule
                        exit;
                }
 
-               /// @todo Add Authentication to enable fetching of non public content
-               // $requester = HTTPSignature::getSigner('', $_SERVER);
-
                $customsize = 0;
                $photo = false;
                switch($a->argc) {
index ba44bcc80b5416786a4e6dea932ea92eedeeb1d3..d5e1732c08635243ca71abd08888dc078ebb593e 100644 (file)
@@ -488,8 +488,10 @@ class HTTPSignature
                        return false;
                }
 
+               $hasGoodSignedContent = false;
+
                // Check the digest when it is part of the signed data
-               if (in_array('digest', $sig_block['headers'])) {
+               if (!empty($content) && in_array('digest', $sig_block['headers'])) {
                        $digest = explode('=', $headers['digest'], 2);
                        if ($digest[0] === 'SHA-256') {
                                $hashalg = 'sha256';
@@ -503,6 +505,8 @@ class HTTPSignature
                        if (!empty($hashalg) && base64_encode(hash($hashalg, $content, true)) != $digest[1]) {
                                return false;
                        }
+
+                       $hasGoodSignedContent = true;
                }
 
                //  Check if the signed date field is in an acceptable range
@@ -512,6 +516,7 @@ class HTTPSignature
                                Logger::log("Header date '" . $headers['date'] . "' is with " . $diff . " seconds out of the 300 second frame. The signature is invalid.");
                                return false;
                        }
+                       $hasGoodSignedContent = true;
                }
 
                // Check the content-length when it is part of the signed data
@@ -521,6 +526,12 @@ class HTTPSignature
                        }
                }
 
+               // Ensure that the authentication had been done with some content
+               // Without this check someone could authenticate with fakeable data
+               if (!$hasGoodSignedContent) {
+                       return false;
+               }
+
                return $key['url'];
        }