]> git.mxchange.org Git - friendica.git/commitdiff
Diaspora: Accept new Salmon format
authorMichael <heluecht@pirati.ca>
Sun, 7 May 2017 13:11:11 +0000 (13:11 +0000)
committerMichael <heluecht@pirati.ca>
Sun, 7 May 2017 13:11:11 +0000 (13:11 +0000)
include/Probe.php
include/diaspora.php
mod/receive.php

index f67a821f9dc04b3854570b881189ca98aa527ea8..2f924266cc42af6223df57e85d08f98796ba68a6 100644 (file)
@@ -174,6 +174,9 @@ class Probe {
                                return array();
 
                        $host = $parts["host"];
+                       if (isset($parts["port"])) {
+                               $host .= ':'.$parts["port"];
+                       }
 
                        $path_parts = explode("/", trim($parts["path"], "/"));
 
@@ -334,8 +337,10 @@ class Probe {
 
                if (isset($parts["scheme"]) AND isset($parts["host"]) AND isset($parts["path"])) {
 
-                       /// @todo: Ports?
                        $host = $parts["host"];
+                       if (isset($parts["port"])) {
+                               $host .= ':'.$parts["port"];
+                       }
 
                        if ($host == 'twitter.com') {
                                return array("network" => NETWORK_TWITTER);
index 39d4353429694407d2ba0fc86c6466d87c3c00a5..484aa93786f3f636660c76c40876eb3302643275 100644 (file)
@@ -187,7 +187,80 @@ class Diaspora {
        }
 
        /**
-        * @brief: Decodes incoming Diaspora message
+        * @brief: Decodes incoming Diaspora message in the new format
+        *
+        * @param array $importer Array of the importer user
+        * @param string $raw raw post message
+        *
+        * @return array
+        * 'message' -> decoded Diaspora XML message
+        * 'author' -> author diaspora handle
+        * 'key' -> author public key (converted to pkcs#8)
+        */
+       public static function decode_raw($importer, $raw) {
+               $data = json_decode($raw);
+
+               // Is it a private post? Then decrypt the outer Salmon
+               if (is_object($data)) {
+                       $encrypted_aes_key_bundle = base64_decode($data->aes_key);
+                       $ciphertext = base64_decode($data->encrypted_magic_envelope);
+
+                       $outer_key_bundle = '';
+                       @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']);
+                       $j_outer_key_bundle = json_decode($outer_key_bundle);
+
+                       if (!is_object($j_outer_key_bundle)) {
+                               logger('Outer Salmon did not verify. Discarding.');
+                               http_status_exit(400);
+                       }
+
+                       $outer_iv = base64_decode($j_outer_key_bundle->iv);
+                       $outer_key = base64_decode($j_outer_key_bundle->key);
+
+                       $xml = diaspora::aes_decrypt($outer_key, $outer_iv, $ciphertext);
+               } else {
+                       $xml = $raw;
+               }
+
+               $basedom = parse_xml_string($xml);
+
+               if (!is_object($basedom)) {
+                       logger('Received data does not seem to be an XML. Discarding.');
+                       http_status_exit(400);
+               }
+
+               $base = $basedom->children(NAMESPACE_SALMON_ME);
+
+               // Not sure if this cleaning is needed
+               $data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $base->data);
+
+               // Build the signed data
+               $type = $base->data[0]->attributes()->type[0];
+               $encoding = $base->encoding;
+               $alg = $base->alg;
+               $signed_data = $data.'.'.base64url_encode($type).'.'.base64url_encode($encoding).'.'.base64url_encode($alg);
+
+               // This is the signature
+               $signature = base64url_decode($base->sig);
+
+               // Get the senders' public key
+               $key_id = $base->sig[0]->attributes()->key_id[0];
+               $author_addr = base64_decode($key_id);
+               $key = diaspora::key($author_addr);
+
+               $verify = rsa_verify($signed_data, $signature, $key);
+               if (!$verify) {
+                       logger('Message did not verify. Discarding.');
+                       http_status_exit(400);
+               }
+
+               return array('message' => (string)base64url_decode($base->data),
+                               'author' => unxmlify($author_addr),
+                               'key' => (string)$key);
+       }
+
+       /**
+        * @brief: Decodes incoming Diaspora message in the deprecated format
         *
         * @param array $importer Array of the importer user
         * @param string $xml urldecoded Diaspora salmon
@@ -202,9 +275,10 @@ class Diaspora {
                $public = false;
                $basedom = parse_xml_string($xml);
 
-               if (!is_object($basedom))
+               if (!is_object($basedom)) {
+                       logger("XML is not parseable.");
                        return false;
-
+               }
                $children = $basedom->children('https://joindiaspora.com/protocol');
 
                if ($children->header) {
index 3563f2d705a487f23b7a3b3652bdf308957f62bb..15c9f1d412796b1de5e2cd08664bdb36dba59d15 100644 (file)
@@ -11,30 +11,27 @@ require_once('include/diaspora.php');
 
 
 function receive_post(App $a) {
-
-
-       $enabled = intval(get_config('system','diaspora_enabled'));
-       if(! $enabled) {
+       $enabled = intval(get_config('system', 'diaspora_enabled'));
+       if (!$enabled) {
                logger('mod-diaspora: disabled');
                http_status_exit(500);
        }
 
        $public = false;
 
-       if(($a->argc == 2) && ($a->argv[1] === 'public')) {
+       if (($a->argc == 2) && ($a->argv[1] === 'public')) {
                $public = true;
-       }
-       else {
+       } else {
 
-               if($a->argc != 3 || $a->argv[1] !== 'users')
+               if ($a->argc != 3 || $a->argv[1] !== 'users') {
                        http_status_exit(500);
-
+               }
                $guid = $a->argv[2];
 
                $r = q("SELECT * FROM `user` WHERE `guid` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1",
                        dbesc($guid)
                );
-               if (! dbm::is_result($r)) {
+               if (!dbm::is_result($r)) {
                        http_status_exit(500);
                }
 
@@ -47,29 +44,34 @@ function receive_post(App $a) {
 
        $xml = urldecode($_POST['xml']);
 
-       logger('mod-diaspora: new salmon ' . $xml, LOGGER_DATA);
-
-       if(! $xml)
-               http_status_exit(500);
-
-       logger('mod-diaspora: message is okay', LOGGER_DEBUG);
+       if (!$xml) {
+               $postdata = file_get_contents("php://input");
+               if ($postdata == '') {
+                       http_status_exit(500);
+               }
 
-       $msg = Diaspora::decode($importer,$xml);
+               logger('mod-diaspora: message is in the new format', LOGGER_DEBUG);
+               $msg = Diaspora::decode_raw($importer, $postdata);
+       } else {
+               logger('mod-diaspora: message is in the old format', LOGGER_DEBUG);
+               $msg = Diaspora::decode($importer, $xml);
+       }
 
        logger('mod-diaspora: decoded', LOGGER_DEBUG);
 
-       logger('mod-diaspora: decoded msg: ' . print_r($msg,true), LOGGER_DATA);
+       logger('mod-diaspora: decoded msg: ' . print_r($msg, true), LOGGER_DATA);
 
-       if(! is_array($msg))
+       if (!is_array($msg)) {
                http_status_exit(500);
+       }
 
        logger('mod-diaspora: dispatching', LOGGER_DEBUG);
 
        $ret = 0;
-       if($public) {
+       if ($public) {
                Diaspora::dispatch_public($msg);
        } else {
-               $ret = Diaspora::dispatch($importer,$msg);
+               $ret = Diaspora::dispatch($importer, $msg);
        }
 
        http_status_exit(($ret) ? $ret : 200);