From 97abbe83f467ea6b008cb6ab70dc125d296acb89 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 22:18:48 +0200 Subject: [PATCH 1/3] Diaspora: Support for reading the /fetch/post/ functionality --- include/diaspora.php | 83 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 18206be8e..f2680b8d7 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -100,6 +100,59 @@ class diaspora { return($signature); } + /** + * @brief verify the envelope and return the verified data + * + * @param string $envelope The magic envelope + * + * @return string verified data + */ + private function verify_magic_envelope($envelope) { + + $basedom = parse_xml_string($envelope, false); + + if (!is_object($basedom)) { + logger("Envelope is no XML file"); + return false; + } + + $children = $basedom->children('http://salmon-protocol.org/ns/magic-env'); + + if (sizeof($children) == 0) { + logger("XML has no children"); + return false; + } + + $handle = ""; + + $data = base64url_decode($children->data); + $type = $children->data->attributes()->type[0]; + + $encoding = $children->encoding; + + $alg = $children->alg; + + $sig = base64url_decode($children->sig); + $key_id = $children->sig->attributes()->key_id[0]; + if ($key_id != "") + $handle = base64url_decode($key_id); + + $b64url_data = base64url_encode($data); + $msg = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); + + $signable_data = $msg.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); + + $key = self::key($handle); + + $verify = rsa_verify($signable_data, $sig, $key); + if (!$verify) { + logger('Message did not verify. Discarding.'); + return false; + } + + return $data; + } + /** * @brief: Decodes incoming Diaspora message * @@ -233,7 +286,6 @@ class diaspora { return array('message' => (string)$inner_decrypted, 'author' => unxmlify($author_link), 'key' => (string)$key); - } @@ -816,11 +868,28 @@ class diaspora { if ($level > 5) return false; - // This will work for Diaspora and newer Friendica servers - $source_url = $server."/p/".$guid.".xml"; - $x = fetch_url($source_url); - if(!$x) - return false; + // This will work for new Diaspora servers and Friendica servers from 3.5 + $source_url = $server."/fetch/post/".$guid; + logger("Fetch post from ".$source_url, LOGGER_DEBUG); + + $envelope = fetch_url($source_url); + if($envelope) { + logger("Envelope was fetched.", LOGGER_DEBUG); + $x = self::verify_magic_envelope($envelope); + if (!$x) { + logger("Envelope could not be verified.", LOGGER_DEBUG); + return false; + } + logger("Envelope was verified.", LOGGER_DEBUG); + } else { + // This will work for older Diaspora and Friendica servers + $source_url = $server."/p/".$guid.".xml"; + logger("Fetch post from ".$source_url, LOGGER_DEBUG); + + $x = fetch_url($source_url); + if(!$x) + return false; + } $source_xml = parse_xml_string($x, false); @@ -2265,7 +2334,7 @@ class diaspora { * @return string The envelope */ - function build_magic_envelope($msg, $user) { + public static function build_magic_envelope($msg, $user) { $b64url_data = base64url_encode($msg); $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); From e5dd67121f7f3a09522b3d1eaab96c0f1751bb7e Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 22:42:46 +0200 Subject: [PATCH 2/3] Some logging added. --- include/diaspora.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/diaspora.php b/include/diaspora.php index f2680b8d7..ebea83803 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -898,9 +898,11 @@ class diaspora { if ($source_xml->post->reshare) { // Reshare of a reshare - old Diaspora version + logger("Message is a reshare", LOGGER_DEBUG); return self::message($source_xml->post->reshare->root_guid, $server, ++$level); } elseif ($source_xml->getName() == "reshare") { // Reshare of a reshare - new Diaspora version + logger("Message is a new reshare", LOGGER_DEBUG); return self::message($source_xml->root_guid, $server, ++$level); } @@ -913,8 +915,10 @@ class diaspora { $author = (string)$source_xml->author; // If this isn't a "status_message" then quit - if (!$author) + if (!$author) { + logger("Message doesn't seem to be a status message", LOGGER_DEBUG); return false; + } $msg = array("message" => $x, "author" => $author); From c1ce7059b6ce83f7f3995c06ea7d3c4fa5dbbef7 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 22:58:56 +0200 Subject: [PATCH 3/3] If it doesn't work with the new method, try the old one --- include/diaspora.php | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index ebea83803..8598ca794 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -876,13 +876,15 @@ class diaspora { if($envelope) { logger("Envelope was fetched.", LOGGER_DEBUG); $x = self::verify_magic_envelope($envelope); - if (!$x) { + if (!$x) logger("Envelope could not be verified.", LOGGER_DEBUG); - return false; - } - logger("Envelope was verified.", LOGGER_DEBUG); - } else { - // This will work for older Diaspora and Friendica servers + else + logger("Envelope was verified.", LOGGER_DEBUG); + } else + $x = false; + + // This will work for older Diaspora and Friendica servers + if (!$x) { $source_url = $server."/p/".$guid.".xml"; logger("Fetch post from ".$source_url, LOGGER_DEBUG); @@ -1985,27 +1987,15 @@ class diaspora { if (!$r) { $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); - logger("1st try: reshared message ".$guid." will be fetched from original server: ".$server); + logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); $item_id = self::store_by_guid($guid, $server); if (!$item_id) { $server = "http://".substr($orig_author, strpos($orig_author, "@") + 1); - logger("2nd try: reshared message ".$guid." will be fetched from original server: ".$server); + logger("2nd try: reshared message ".$guid." will be fetched without SLL from the server ".$server); $item_id = self::store_by_guid($guid, $server); } - // Deactivated by now since there is a risk that someone could manipulate postings through this method -/* if (!$item_id) { - $server = "https://".substr($author, strpos($author, "@") + 1); - logger("3rd try: reshared message ".$guid." will be fetched from sharer's server: ".$server); - $item_id = self::store_by_guid($guid, $server); - } - if (!$item_id) { - $server = "http://".substr($author, strpos($author, "@") + 1); - logger("4th try: reshared message ".$guid." will be fetched from sharer's server: ".$server); - $item_id = self::store_by_guid($guid, $server); - } -*/ if ($item_id) { $r = q("SELECT `body`, `tag`, `app`, `created`, `object-type`, `uri`, `guid`, `author-name`, `author-link`, `author-avatar`