From d7b56db99680e4397f571bb19447039d0c0a2b15 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 3 May 2017 19:28:51 +0000 Subject: [PATCH 1/3] Diaspora: Better handling for unrelayed comments and likes --- include/diaspora.php | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 8640e2d6a..121357829 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -333,19 +333,20 @@ class Diaspora { return false; } - if (!self::valid_posting($msg, $fields)) { + if (!($postdata = self::valid_posting($msg))) { logger("Invalid posting"); return false; } - // Is it a an action (comment, like, ...) for our own post? - if (isset($fields->parent_guid)) { - $guid = notags(unxmlify($fields->parent_guid)); + $fields = $postdata['fields']; + // Is it a an action (comment, like, ...) for our own post? + if (isset($fields->parent_guid) AND !$postdata["relayed"]) { + $guid = notags(unxmlify($fields->parent_guid)); $importer = self::importer_for_guid($guid); if (is_array($importer)) { logger("delivering to origin: ".$importer["name"]); - $message_id = self::dispatch($importer, $msg); + $message_id = self::dispatch($importer, $msg, $fields); return $message_id; } } @@ -361,14 +362,14 @@ class Diaspora { if (dbm::is_result($r)) { foreach ($r as $rr) { logger("delivering to: ".$rr["username"]); - self::dispatch($rr, $msg); + self::dispatch($rr, $msg, $fields); } } elseif (!Config::get('system', 'relay_subscribe', false)) { - logger("Unwanted message from ".$sender." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG); + logger("Unwanted message from ".$msg["author"]." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG); } else { // Use a dummy importer to import the data for the public copy $importer = array("uid" => 0, "page-flags" => PAGE_FREELOVE); - $message_id = self::dispatch($importer, $msg); + $message_id = self::dispatch($importer, $msg, $fields); } return $message_id; @@ -382,15 +383,19 @@ class Diaspora { * * @return int The message id of the generated message, "true" or "false" if there was an error */ - public static function dispatch($importer, $msg) { + public static function dispatch($importer, $msg, $fields = null) { // The sender is the handle of the contact that sent the message. // This will often be different with relayed messages (for example "like" and "comment") $sender = $msg["author"]; - if (!self::valid_posting($msg, $fields)) { - logger("Invalid posting"); - return false; + // This is only needed for private postings since this is already done for public ones before + if (is_null($fields)) { + if (!($postdata = self::valid_posting($msg))) { + logger("Invalid posting"); + return false; + } + $fields = $postdata['fields']; } $type = $fields->getName(); @@ -456,7 +461,7 @@ class Diaspora { * * @return bool Is the posting valid? */ - private static function valid_posting($msg, &$fields) { + private static function valid_posting($msg) { $data = parse_xml_string($msg["message"], false); @@ -552,7 +557,7 @@ class Diaspora { // Only some message types have signatures. So we quit here for the other types. if (!in_array($type, array("comment", "message", "like"))) - return true; + return array("fields" => $fields, "relayed" => false); // No author_signature? This is a must, so we quit. if (!isset($author_signature)) { @@ -561,12 +566,16 @@ class Diaspora { } if (isset($parent_author_signature)) { + $relayed = true; + $key = self::key($msg["author"]); if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256")) { logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG); return false; } + } else { + $relayed = false; } $key = self::key($fields->author); @@ -575,7 +584,7 @@ class Diaspora { logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG); return false; } else - return true; + return array("fields" => $fields, "relayed" => $relayed); } /** From a9c263a375746056eaff6f320d2917ff90d12c31 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 3 May 2017 19:55:33 +0000 Subject: [PATCH 2/3] Retraction does now work as well --- include/diaspora.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 121357829..7e82ecc79 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2379,11 +2379,16 @@ class Diaspora { return false; } + if (!isset($contact["url"])) { + $contact["url"] = $person["url"]; + } + $r = q("SELECT `id`, `parent`, `parent-uri`, `author-link` FROM `item` WHERE `guid` = '%s' AND `uid` = %d AND NOT `file` LIKE '%%[%%' LIMIT 1", dbesc($target_guid), intval($importer["uid"]) ); if (!$r) { + logger("Target guid ".$target_guid." was not found for user ".$importer["uid"]); return false; } @@ -2429,7 +2434,7 @@ class Diaspora { $target_type = notags(unxmlify($data->target_type)); $contact = self::contact_by_handle($importer["uid"], $sender); - if (!$contact) { + if (!$contact AND (in_array($target_type, array("Contact", "Person")))) { logger("cannot find contact for sender: ".$sender." and user ".$importer["uid"]); return false; } @@ -2442,7 +2447,7 @@ class Diaspora { case "Post": // "Post" will be supported in a future version case "Reshare": case "StatusMessage": - return self::item_retraction($importer, $contact, $data);; + return self::item_retraction($importer, $contact, $data); case "Contact": case "Person": From 65823fe28f93b61ade6011f29c5e68696b77a6e2 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 4 May 2017 05:11:19 +0000 Subject: [PATCH 3/3] Standards and documentation --- include/diaspora.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 7e82ecc79..39d435342 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -380,6 +380,7 @@ class Diaspora { * * @param array $importer Array of the importer user * @param array $msg The post that will be dispatched + * @param object $fields SimpleXML object that contains the message * * @return int The message id of the generated message, "true" or "false" if there was an error */ @@ -457,9 +458,8 @@ class Diaspora { * It also does the conversion between the old and the new diaspora format. * * @param array $msg Array with the XML, the sender handle and the sender signature - * @param object $fields SimpleXML object that contains the posting when it is valid * - * @return bool Is the posting valid? + * @return bool|array If the posting is valid then an array with an SimpleXML object is returned */ private static function valid_posting($msg) { @@ -556,9 +556,9 @@ class Diaspora { } // Only some message types have signatures. So we quit here for the other types. - if (!in_array($type, array("comment", "message", "like"))) + if (!in_array($type, array("comment", "message", "like"))) { return array("fields" => $fields, "relayed" => false); - + } // No author_signature? This is a must, so we quit. if (!isset($author_signature)) { logger("No author signature for type ".$type." - Message: ".$msg["message"], LOGGER_DEBUG); @@ -583,8 +583,9 @@ class Diaspora { if (!rsa_verify($signed_data, $author_signature, $key, "sha256")) { logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG); return false; - } else + } else { return array("fields" => $fields, "relayed" => $relayed); + } } /**