From d768074afd844788e958f0afbd0040cb3243be83 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 21 Jan 2016 13:21:47 +0100 Subject: [PATCH 1/4] Comments from Hubzilla weren't federated properly --- include/diaspora.php | 64 +++++++++++++++++++++++++++++--------------- include/threads.php | 1 + 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 4673cdaf4c..584ec92a49 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -826,6 +826,19 @@ function diaspora_plink($addr, $guid) { return 'https://'.substr($addr,strpos($addr,'@')+1).'/posts/'.$guid; } +function diaspora_repair_signature($signature, $handle = "", $level = 1) { + if (base64_encode(base64_decode(base64_decode($signature))) == base64_decode($signature)) { + $signature = base64_decode($signature); + logger("Repaired double encoded signature from Diaspora/Hubzilla handle ".$handle." - level ".$level, LOGGER_DEBUG); + + // Do a recursive call to be able to fix even multiple levels + if ($level < 10) + $signature = diaspora_repair_signature($signature, $handle, ++$level); + } + + return($signature); +} + function diaspora_post($importer,$xml,$msg) { $a = get_app(); @@ -1475,8 +1488,7 @@ function diaspora_comment($importer,$xml,$msg) { logger('diaspora_comment: top-level owner verification failed.'); return; } - } - else { + } elseif($author_signature) { // If there's no parent_author_signature, then we've received the comment // from the comment creator. In that case, the person is commenting on // our post, so he/she must be a contact of ours and his/her public key @@ -1490,6 +1502,11 @@ function diaspora_comment($importer,$xml,$msg) { } } + if (!$parent_author_signature AND !$author_signature) { + logger("No signature in comment. Comment will be rejected."); + return; + } + // Phew! Everything checks out. Now create an item. // Find the original comment author information. @@ -1565,18 +1582,19 @@ function diaspora_comment($importer,$xml,$msg) { //); //} - if(($parent_item['origin']) && (! $parent_author_signature)) { + // If we are the origin of the parent we store the original signature and notify our followers + if($parent_item['origin']) { + $author_signature_base64 = base64_encode($author_signature); + $author_signature_base64 = diaspora_repair_signature($author_signature_base64, $diaspora_handle); + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($message_id), dbesc($signed_data), - dbesc(base64_encode($author_signature)), + dbesc($author_signature_base64), dbesc($diaspora_handle) ); - // if the message isn't already being relayed, notify others - // the existence of parent_author_signature means the parent_author or owner - // is already relaying. - + // notify others proc_run('php','include/notifier.php','comment-import',$message_id); } @@ -2113,7 +2131,7 @@ function diaspora_like($importer,$xml,$msg) { logger('diaspora_like: top-level owner verification failed.'); return; } - } else { + } elseif($author_signature) { // If there's no parent_author_signature, then we've received the like // from the like creator. In that case, the person is "like"ing // our post, so he/she must be a contact of ours and his/her public key @@ -2129,6 +2147,11 @@ function diaspora_like($importer,$xml,$msg) { } } + if (!$parent_author_signature AND !$author_signature) { + logger("No signature in like. Like will be rejected."); + return; + } + // Phew! Everything checks out. Now create an item. // Find the original comment author information. @@ -2226,21 +2249,21 @@ EOT; // ); //} - if(! $parent_author_signature) { + // If we are the origin of the parent we store the original signature and notify our followers + if($parent_item['origin']) { + $author_signature_base64 = base64_encode($author_signature); + $author_signature_base64 = diaspora_repair_signature($author_signature_base64, $diaspora_handle); + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($message_id), dbesc($signed_data), - dbesc(base64_encode($author_signature)), + dbesc($author_signature_base64), dbesc($diaspora_handle) ); - } - // if the message isn't already being relayed, notify others - // the existence of parent_author_signature means the parent_author or owner - // is already relaying. The parent_item['origin'] indicates the message was created on our system - - if(($parent_item['origin']) && (! $parent_author_signature)) + // notify others proc_run('php','include/notifier.php','comment-import',$message_id); + } return; } @@ -2336,8 +2359,7 @@ function diaspora_signed_retraction($importer,$xml,$msg) { return; } - } - else { + } else { $sig_decode = base64_decode($sig); @@ -2371,7 +2393,7 @@ function diaspora_signed_retraction($importer,$xml,$msg) { intval($r[0]['parent']) ); if(count($p)) { - if(($p[0]['origin']) && (! $parent_author_signature)) { + if($p[0]['origin']) { q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", $r[0]['id'], dbesc($signed_data), @@ -2961,7 +2983,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { '$handle' => xmlify($handle) )); - logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DATA); + logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DEBUG); logger('send guid '.$item['guid'], LOGGER_DEBUG); $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch))); diff --git a/include/threads.php b/include/threads.php index e542295d7b..0320eaa018 100644 --- a/include/threads.php +++ b/include/threads.php @@ -66,6 +66,7 @@ function add_thread($itemid, $onlyshadow = false) { unset($item[0]['id']); $item[0]['uid'] = 0; + $item[0]['origin'] = 0; $item[0]['contact-id'] = get_contact($item[0]['author-link'], 0); $public_shadow = item_store($item[0], false, false, true); From 54f42cb70663b44de10c12b093ac4aedbe2b34bf Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 21 Jan 2016 13:38:30 +0100 Subject: [PATCH 2/4] removed some test code --- include/diaspora.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 584ec92a49..b193dffadb 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -1488,7 +1488,8 @@ function diaspora_comment($importer,$xml,$msg) { logger('diaspora_comment: top-level owner verification failed.'); return; } - } elseif($author_signature) { + } + else { // If there's no parent_author_signature, then we've received the comment // from the comment creator. In that case, the person is commenting on // our post, so he/she must be a contact of ours and his/her public key @@ -1502,11 +1503,6 @@ function diaspora_comment($importer,$xml,$msg) { } } - if (!$parent_author_signature AND !$author_signature) { - logger("No signature in comment. Comment will be rejected."); - return; - } - // Phew! Everything checks out. Now create an item. // Find the original comment author information. @@ -2131,7 +2127,7 @@ function diaspora_like($importer,$xml,$msg) { logger('diaspora_like: top-level owner verification failed.'); return; } - } elseif($author_signature) { + } else { // If there's no parent_author_signature, then we've received the like // from the like creator. In that case, the person is "like"ing // our post, so he/she must be a contact of ours and his/her public key @@ -2147,11 +2143,6 @@ function diaspora_like($importer,$xml,$msg) { } } - if (!$parent_author_signature AND !$author_signature) { - logger("No signature in like. Like will be rejected."); - return; - } - // Phew! Everything checks out. Now create an item. // Find the original comment author information. From e00c091540f8b5cf7e320ca9f0fbfeb357438a43 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 21 Jan 2016 13:57:21 +0100 Subject: [PATCH 3/4] Small fix for empty signatures --- include/diaspora.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/diaspora.php b/include/diaspora.php index b193dffadb..40a126bf06 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -827,6 +827,10 @@ function diaspora_plink($addr, $guid) { } function diaspora_repair_signature($signature, $handle = "", $level = 1) { + + if ($signature == "") + return($signature); + if (base64_encode(base64_decode(base64_decode($signature))) == base64_decode($signature)) { $signature = base64_decode($signature); logger("Repaired double encoded signature from Diaspora/Hubzilla handle ".$handle." - level ".$level, LOGGER_DEBUG); @@ -2974,7 +2978,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { '$handle' => xmlify($handle) )); - logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DEBUG); + logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DATA); logger('send guid '.$item['guid'], LOGGER_DEBUG); $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch))); From e1bc0b4ff820c3d98ba2188ca408cc88ed9ba7eb Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 21 Jan 2016 16:01:46 +0100 Subject: [PATCH 4/4] Likes are now federated again through Diaspora --- include/diaspora.php | 2 +- include/like.php | 30 +++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 40a126bf06..b72239c4ce 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2836,7 +2836,7 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { // sign it if($like) - $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent['guid'] . ';' . $positive . ';' . $myaddr; + $signed_text = $positive . ';' . $item['guid'] . ';' . $target_type . ';' . $parent['guid'] . ';' . $myaddr; else $signed_text = $item['guid'] . ';' . $parent['guid'] . ';' . $text . ';' . $myaddr; diff --git a/include/like.php b/include/like.php index 6aef0cb5b8..646e0727be 100644 --- a/include/like.php +++ b/include/like.php @@ -279,6 +279,9 @@ function store_diaspora_like_retract_sig($activity, $item, $like_item, $contact) $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; + // This code could never had worked (the return values form the queries were used in a wrong way. + // Additionally it is needlessly complicated. Either the contact is owner or not. And we have this data already. +/* // Get contact's private key if he's a user of the local Friendica server $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", dbesc($contact['url']) @@ -289,9 +292,15 @@ function store_diaspora_like_retract_sig($activity, $item, $like_item, $contact) $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", intval($contact_uid) ); +*/ + // Is the contact the owner? Then fetch the private key + if ($contact['self'] AND ($contact['uid'] > 0)) { + $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", + intval($contact['uid']) + ); - if( $r) - $authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256')); + if($r) + $authorsig = base64_encode(rsa_sign($signed_text,$r[0]['prvkey'],'sha256')); } if(! isset($authorsig)) @@ -329,6 +338,10 @@ function store_diaspora_like_sig($activity, $post_type, $contact, $post_id) { $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; + + // This code could never had worked (the return values form the queries were used in a wrong way. + // Additionally it is needlessly complicated. Either the contact is owner or not. And we have this data already. +/* // Get contact's private key if he's a user of the local Friendica server $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", dbesc($contact['url']) @@ -343,6 +356,17 @@ function store_diaspora_like_sig($activity, $post_type, $contact, $post_id) { if( $r) $contact_uprvkey = $r['prvkey']; } +*/ + + // Is the contact the owner? Then fetch the private key + if ($contact['self'] AND ($contact['uid'] > 0)) { + $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", + intval($contact['uid']) + ); + + if($r) + $contact_uprvkey = $r[0]['prvkey']; + } $r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1", intval($post_id) @@ -353,7 +377,7 @@ function store_diaspora_like_sig($activity, $post_type, $contact, $post_id) { intval($r[0]['parent']) ); if( $p) { - $signed_text = $r[0]['guid'] . ';Post;' . $p[0]['guid'] . ';true;' . $diaspora_handle; + $signed_text = 'true;'.$r[0]['guid'].';Post;'.$p[0]['guid'].';'.$diaspora_handle; if(isset($contact_uprvkey)) $authorsig = base64_encode(rsa_sign($signed_text,$contact_uprvkey,'sha256'));