From f29f228463d35f574d6d285be0cf337b7d39c541 Mon Sep 17 00:00:00 2001 From: Friendika Date: Sun, 28 Aug 2011 19:22:27 -0700 Subject: [PATCH] bring Diaspora message signing back to the source author - whether they like it or not. --- boot.php | 2 +- include/delivery.php | 5 ++++- include/diaspora.php | 53 ++++++++++++++++++++++---------------------- include/items.php | 48 ++++++++++++++++++++++++++++++++++++--- include/notifier.php | 3 ++- mod/item.php | 29 ++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 33 deletions(-) diff --git a/boot.php b/boot.php index 58d6cc8394..060bd7117f 100644 --- a/boot.php +++ b/boot.php @@ -7,7 +7,7 @@ require_once('include/text.php'); require_once("include/pgettext.php"); -define ( 'FRIENDIKA_VERSION', '2.2.1085' ); +define ( 'FRIENDIKA_VERSION', '2.2.1086' ); define ( 'DFRN_PROTOCOL_VERSION', '2.21' ); define ( 'DB_UPDATE_VERSION', 1083 ); diff --git a/include/delivery.php b/include/delivery.php index be4f3978cc..0df8ea7e47 100644 --- a/include/delivery.php +++ b/include/delivery.php @@ -77,7 +77,10 @@ function delivery_run($argv, $argc){ $uid = $r[0]['uid']; $updated = $r[0]['edited']; - $items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC", + + + $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer` + FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d ORDER BY `id` ASC", intval($parent_id) ); diff --git a/include/diaspora.php b/include/diaspora.php index 10b3422897..6cba0ecec1 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -1063,18 +1063,6 @@ function diaspora_send_relay($item,$owner,$contact) { $body = $item['body']; - $itemcontact = q("select * from contact where `id` = %d limit 1", - intval($item['contact-id']) - ); - if(count($itemcontact)) { - if(! $itemcontact[0]['self']) { - $prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'), - '['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')', - network_to_name($itemcontact['network'])) . "\n"; - $body = $prefix . $body; - } - } - $text = html_entity_decode(bb2diaspora($body)); // fetch the original signature if somebody sent the post to us to relay @@ -1092,23 +1080,34 @@ function diaspora_send_relay($item,$owner,$contact) { } else { - - - - if($like) - $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr; - else - $signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr; - - $authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha')); - - q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", - intval($item['id']), - dbesc($signed_text), - dbesc(base64_encode($authorsig)), - dbesc($myaddr) + $itemcontact = q("select * from contact where `id` = %d limit 1", + intval($item['contact-id']) ); + if(count($itemcontact)) { + if(! $itemcontact[0]['self']) { + $prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'), + '['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')', + network_to_name($itemcontact['network'])) . "\n"; + $body = $prefix . $body; + } + } + else { + if($like) + $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr; + else + $signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr; + + $authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha')); + + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($item['id']), + dbesc($signed_text), + dbesc(base64_encode($authorsig)), + dbesc($myaddr) + ); + + } } // sign it diff --git a/include/items.php b/include/items.php index 150be27070..e9594cff2c 100644 --- a/include/items.php +++ b/include/items.php @@ -112,8 +112,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, - `contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid` + `contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`, + `sign`.`signed_text`, `sign`.`signature`, `sign`.`signer` FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` + LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`parent` != 0 AND `item`.`wall` = 1 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' ) @@ -363,6 +365,18 @@ function get_atom_elements($feed,$item) { $res['app'] = 'OStatus'; } + // base64 encoded json structure representing Diaspora signature + + $dsig = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_signature'); + if($dsig) { + $res['dsprsig'] = unxmlify($dsig[0]['data']); + } + + $dguid = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_guid'); + if($dguid) + $res['guid'] = unxmlify($dguid[0]['data']); + + /** * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ @@ -659,6 +673,15 @@ function encode_rel_links($links) { function item_store($arr,$force_parent = false) { + // If a Diaspora signature structure was passed in, pull it out of the + // item array and set it aside for later storage. + + $dsprsig = null; + if(x($arr,'dsprsig')) { + $dsprsig = json_decode(base64_decode($arr['dsprsig'])); + unset($arr['dsprsig']); + } + if($arr['gravity']) $arr['gravity'] = intval($arr['gravity']); elseif($arr['parent-uri'] == $arr['uri']) @@ -835,6 +858,16 @@ function item_store($arr,$force_parent = false) { intval($current_post) ); + if($dsprsig) { + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($current_post), + dbesc($dsprsig->signed_text), + dbesc($dsprsig->signature), + dbesc($dsprsig->signer) + ); + } + + /** * If this is now the last-child, force all _other_ children of this parent to *not* be last-child */ @@ -1670,10 +1703,19 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { $o .= '1' . "\r\n"; if($item['extid']) - $o .= '' . $item['extid'] . '' . "\r\n"; + $o .= '' . xmlify($item['extid']) . '' . "\r\n"; if($item['app']) - $o .= ''; + $o .= '' . "\r\n"; + + if($item['guid']) + $o .= '' . $item['guid'] . '' . "\r\n"; + + if($item['signed_text']) { + $sign = base64_encode(json_encode(array('signed_text' => $item['signed_text'],'signature' => $item['signature'],'signer' => $item['signer']))); + $o .= '' . xmlify($sign) . '' . "\r\n"; + } + $verb = construct_verb($item); $o .= '' . xmlify($verb) . '' . "\r\n"; $actobj = construct_activity_object($item); diff --git a/include/notifier.php b/include/notifier.php index 1a3b321cfd..b87aa95b15 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -109,7 +109,8 @@ function notifier_run($argv, $argc){ $uid = $r[0]['uid']; $updated = $r[0]['edited']; - $items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC", + $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer` + FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d ORDER BY `id` ASC", intval($parent_id) ); diff --git a/mod/item.php b/mod/item.php index ef0b232d56..dd42014eb4 100644 --- a/mod/item.php +++ b/mod/item.php @@ -15,6 +15,8 @@ * */ +require_once('include/crypto.php'); + function item_post(&$a) { if((! local_user()) && (! remote_user())) @@ -674,6 +676,27 @@ function item_post(&$a) { pop_lang(); } + + // We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key + + if($self) { + require_once('include/bb2diaspora.php'); + $signed_body = html_entity_decode(bb2diaspora($datarray['body'])); + $myaddr = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + if($datarray['verb'] === ACTIVITY_LIKE) + $signed_text = $datarray['guid'] . ';' . 'Post' . ';' . $parent_item['guid'] . ';' . 'true' . ';' . $myaddr; + else + $signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $myaddr; + + $authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha')); + + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($post_id), + dbesc($signed_text), + dbesc(base64_encode($authorsig)), + dbesc($myaddr) + ); + } } else { $parent = $post_id; @@ -799,6 +822,12 @@ function item_post(&$a) { } } + + + + + + logger('post_complete'); // figure out how to return, depending on from whence we came