X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fdiaspora.php;h=2be266e8af34bc7f218b33d953dc6f7d4cbdf0a9;hb=88e7fe67de734035ec35621dd0dc4b29807e8ed6;hp=584be5ef266d3db7879fe9afcd20e61720994128;hpb=c0af6dbb1a5507dcf0fffaf13b42cfd71b0d0c50;p=friendica.git diff --git a/include/diaspora.php b/include/diaspora.php old mode 100644 new mode 100755 index 584be5ef26..2be266e8af --- a/include/diaspora.php +++ b/include/diaspora.php @@ -1060,45 +1060,64 @@ function diaspora_comment($importer,$xml,$msg) { } $parent_item = $r[0]; - $author_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; - $author_signature = base64_decode($author_signature); + /* How Diaspora performs comment signature checking: - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); - - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_comment: unable to find author details'); - return; - } - } + - If an item has been sent by the comment author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner should check + the author_signature, then create a parent_author_signature before relaying the comment on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ - if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) { - logger('diaspora_comment: verification failed.'); - return; - } + $signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; + $key = $msg['key']; if($parent_author_signature) { - $owner_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; + // If a parent_author_signature exists, then we've received the comment + // relayed from the top-level post owner. There's no need to check the + // author_signature if the parent_author_signature is valid $parent_author_signature = base64_decode($parent_author_signature); - $key = $msg['key']; + if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { + logger('diaspora_comment: top-level owner verification failed.'); + return; + } + } + 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 + // should be in $msg['key'] - if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_comment: owner verification failed.'); + $author_signature = base64_decode($author_signature); + + if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) { + logger('diaspora_comment: comment author verification failed.'); return; } } // Phew! Everything checks out. Now create an item. + // Find the original comment author information. + // We need this to make sure we display the comment author + // information (name and avatar) correctly. + if(strcasecmp($diaspora_handle,$msg['author']) == 0) + $person = $contact; + else { + $person = find_diaspora_person_by_handle($diaspora_handle); + + if(! is_array($person)) { + logger('diaspora_comment: unable to find author details'); + return; + } + } + $body = diaspora2bb($text); $message_id = $diaspora_handle . ':' . $guid; @@ -1168,22 +1187,7 @@ function diaspora_comment($importer,$xml,$msg) { ); } - if(($parent_item['origin']) && (! $parent_author_signature)) { if(($parent_item['origin']) && (! $parent_author_signature)) { - q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", - intval($message_id), - dbesc($author_signed_data), - dbesc(base64_encode($author_signature)), - 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. - - proc_run('php','include/notifier.php','comment',$message_id); - } - - + if(($parent_item['origin']) && (! $parent_author_signature)) { q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($message_id), dbesc($author_signed_data), @@ -1620,60 +1624,85 @@ function diaspora_like($importer,$xml,$msg) { logger('diaspora_like: duplicate like: ' . $guid); return; } + // Note: I don't think "Like" objects with positive = "false" are ever actually used + // It looks like "RelayableRetractions" are used for "unlike" instead if($positive === 'false') { - q("UPDATE `item` SET `deleted` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", + logger('diaspora_like: received a like with positive set to "false"...ignoring'); +/* q("UPDATE `item` SET `deleted` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($r[0]['id']), intval($importer['uid']) - ); - // FIXME + );*/ + // FIXME--actually don't unless it turns out that Diaspora does indeed send out "false" likes // send notification via proc_run() return; } } + // Note: I don't think "Like" objects with positive = "false" are ever actually used + // It looks like "RelayableRetractions" are used for "unlike" instead if($positive === 'false') { - logger('diaspora_like: unlike received with no corresponding like'); + logger('diaspora_like: received a like with positive set to "false"'); + logger('diaspora_like: unlike received with no corresponding like...ignoring'); return; } - $author_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; - $author_signature = base64_decode($author_signature); + /* How Diaspora performs "like" signature checking: - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_like: unable to find author details'); - return; - } - } + - If an item has been sent by the like author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner should check + the author_signature, then create a parent_author_signature before relaying the like on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ - if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) { - logger('diaspora_like: verification failed.'); - return; - } + $signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; + $key = $msg['key']; if($parent_author_signature) { - - $owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; + // If a parent_author_signature exists, then we've received the like + // relayed from the top-level post owner. There's no need to check the + // author_signature if the parent_author_signature is valid $parent_author_signature = base64_decode($parent_author_signature); - $key = $msg['key']; + if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { + logger('diaspora_like: top-level owner verification failed.'); + return; + } + } + 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 + // should be in $msg['key'] + + $author_signature = base64_decode($author_signature); - if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_like: owner verification failed.'); + if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) { + logger('diaspora_like: like creator verification failed.'); return; } } // Phew! Everything checks out. Now create an item. + // Find the original comment author information. + // We need this to make sure we display the comment author + // information (name and avatar) correctly. + if(strcasecmp($diaspora_handle,$msg['author']) == 0) + $person = $contact; + else { + $person = find_diaspora_person_by_handle($diaspora_handle); + + if(! is_array($person)) { + logger('diaspora_like: unable to find author details'); + return; + } + } + $uri = $diaspora_handle . ':' . $guid; $activity = ACTIVITY_LIKE; @@ -1811,42 +1840,41 @@ function diaspora_signed_retraction($importer,$xml,$msg) { $signed_data = $guid . ';' . $type ; + $key = $msg['key']; - $sig_decode = base64_decode($sig); + /* How Diaspora performs relayable_retraction signature checking: - if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - $person = $contact; - $key = $msg['key']; - } - else { - $person = find_diaspora_person_by_handle($diaspora_handle); + - If an item has been sent by the item author to the top-level post owner to relay on + to the rest of the contacts on the top-level post, the top-level post owner checks + the author_signature, then creates a parent_author_signature before relaying the item on + - If an item has been relayed on by the top-level post owner, the contacts who receive it + check only the parent_author_signature. Basically, they trust that the top-level post + owner has already verified the authenticity of anything he/she sends out + - In either case, the signature that get checked is the signature created by the person + who sent the salmon + */ - if(is_array($person) && x($person,'pubkey')) - $key = $person['pubkey']; - else { - logger('diaspora_signed_retraction: unable to find author details'); + if($parent_author_signature) { + + $parent_author_signature = base64_decode($parent_author_signature); + + if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { + logger('diaspora_signed_retraction: top-level post owner verification failed'); return; } - } - if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) { - logger('diaspora_signed_retraction: retraction-owner verification failed.' . print_r($msg,true)); - return; } + else { - if($parent_author_signature) { - $parent_author_signature = base64_decode($parent_author_signature); - - $key = $msg['key']; + $sig_decode = base64_decode($sig); - if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { - logger('diaspora_signed_retraction: failed to verify person relaying the retraction (e.g. owner of a post relaying a retracted comment'); + if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) { + logger('diaspora_signed_retraction: retraction owner verification failed.' . print_r($msg,true)); return; } - } - if($type === 'StatusMessage' || $type === 'Comment') { + if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') { $r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1", dbesc($guid), intval($importer['uid']) @@ -1854,6 +1882,7 @@ function diaspora_signed_retraction($importer,$xml,$msg) { if(count($r)) { if(link_compare($r[0]['author-link'],$contact['url'])) { q("update item set `deleted` = 1, `edited` = '%s', `changed` = '%s', `body` = '' , `title` = '' where `id` = %d limit 1", + dbesc(datetime_convert()), dbesc(datetime_convert()), intval($r[0]['id']) ); @@ -2139,7 +2168,11 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { $tpl = get_markup_template('diaspora_like.tpl'); $like = true; $target_type = 'Post'; - $positive = (($item['deleted']) ? 'false' : 'true'); +// $positive = (($item['deleted']) ? 'false' : 'true'); + $positive = 'true'; + + if(($item['deleted'])) + logger('diaspora_send_followup: received deleted "like". Those should go to diaspora_send_retraction'); } else { $tpl = get_markup_template('diaspora_comment.tpl'); @@ -2176,24 +2209,6 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { -// I think the first comment or like on a post whose home is our Friendica server is saved as an item -// as the top-level post owner's contact for writer of the comment or post. Thus, the "uid" -// on the item is `user`.`id` of the top-level post owner. That user is passed to this function -// as "$owner." -// -// I'm assuming for now that "$owner" will be the user of the top-level post for retractions too. Be -// aware that another reasonable possibility is that it's the "$owner" of the deleted comment. - -// TODO -// CHECK 1. If we receive a retraction from Diaspora to be relayed by us, we need to insert the signature -// into the DB and call notifier.php -// CHECK 2. diaspora_send_retraction() needs to be modified to send -// Diaspora a retraction for it to relay when appropriate -// CHECK 3. notifier.php (and delivery.php?) need to be modified to call the right functions for the right -// retraction situation -// 4. If possible, modify notifier.php (and delivery.php?) to remove the relayable retraction's signature -// from the DB after finishing with relaying retractions - $a = get_app(); @@ -2216,20 +2231,21 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $like = false; $relay_retract = false; $sql_sign_id = 'iid'; - if($item['verb'] === ACTIVITY_LIKE) { + if( $item['deleted']) { + $tpl = get_markup_template('diaspora_relayable_retraction.tpl'); + $relay_retract = true; + $sql_sign_id = 'retract_iid'; + $target_type = ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); + } + elseif($item['verb'] === ACTIVITY_LIKE) { $tpl = get_markup_template('diaspora_like_relay.tpl'); $like = true; $target_type = 'Post'; - $positive = (($item['deleted']) ? 'false' : 'true'); - } - elseif(! $item['deleted']) { - $tpl = get_markup_template('diaspora_comment_relay.tpl'); +// $positive = (($item['deleted']) ? 'false' : 'true'); + $positive = 'true'; } else { - $tpl = get_markup_template('diaspora_relayable_retraction.tpl'); - $relay_retract = true; - $sql_sign_id = 'retract_iid'; - $target_type = 'Comment'; + $tpl = get_markup_template('diaspora_comment_relay.tpl'); } $body = $item['body']; @@ -2237,16 +2253,8 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $text = html_entity_decode(bb2diaspora($body)); - // fetch the original signature if somebody sent the post to us to relay - // - // If we are relaying for a reply originating on our own account, there wasn't a 'send to relay' - // action. It wasn't needed. In that case create the original signature and the - // owner (parent author) signature - // Note that mod/item.php seems to take care of creating a signature for Diaspora for replies - // created on our own account - // - // comments from other networks will be relayed under our name, with a brief - // preamble to describe what's happening and noting the real author + // fetch the original signature if the relayable was created by a Diaspora + // or DFRN user. Relayables for other networks are not supported. $r = q("select * from sign where " . $sql_sign_id . " = %d limit 1", intval($item['id']) @@ -2259,6 +2267,12 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { } else { + // Author signature information (for likes, comments, and retractions of likes or comments, + // whether from Diaspora or Friendica) must be placed in the `sign` table before this + // function is called + logger('diaspora_send_relay: original author signature not found, cannot send relayable'); + return; +/* $itemcontact = q("select * from contact where `id` = %d limit 1", intval($item['contact-id']) ); @@ -2297,6 +2311,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { dbesc($handle) ); } +*/ } // sign it with the top-level owner's signature @@ -2330,11 +2345,11 @@ function diaspora_send_retraction($item,$owner,$contact,$public_batch = false) { $a = get_app(); $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - // Check if the retraction is for a top-level post, or whether it's for a comment - if( $item['id'] !== $item['parent'] ) { + // Check whether the retraction is for a top-level post or whether it's a relayable + if( $item['uri'] !== $item['parent-uri'] ) { $tpl = get_markup_template('diaspora_relay_retraction.tpl'); - $target_type = 'Comment'; + $target_type = (($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); } else { @@ -2472,3 +2487,5 @@ function diaspora_transmit($owner,$contact,$slap,$public_batch) { return(($return_code) ? $return_code : (-1)); } + +