diff --git a/boot.php b/boot.php index 2bd7830d7d..9866077d23 100644 --- a/boot.php +++ b/boot.php @@ -104,6 +104,13 @@ define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API define ( 'MAX_LIKERS', 75); +/** + * Communication timeout + */ + +define ( 'ZCURL_TIMEOUT' , (-1)); + + /** * email notification options */ diff --git a/include/Scrape.php b/include/Scrape.php index e0075d44d9..6726d0b151 100644 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -394,7 +394,7 @@ function probe_url($url) { ); $profile = $j->url; $notify = $j->post; - $key = $j->pubkey; + $pubkey = $j->pubkey; $poll = 'N/A'; } } @@ -570,7 +570,7 @@ function probe_url($url) { $result['priority'] = $priority; $result['network'] = $network; $result['alias'] = $alias; - $result['key'] = $key; + $result['pubkey'] = $pubkey; logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG); diff --git a/include/zotfns.php b/include/zotfns.php new file mode 100644 index 0000000000..a95a064cd1 --- /dev/null +++ b/include/zotfns.php @@ -0,0 +1,192 @@ + $v) { + if($argstr) + $argstr .= '&'; + $argstr .= $k . '=' . $v; + } + $s = fetch_url($url . '?' . $argstr); + if($s) { + $j = json_decode($s); + if($j) + return($j); + } + return false; +} + +function zot_post($url,$args) { + $s = post_url($url,$args); + if($s) { + $j = json_decode($s); + if($j) + return($j); + } + return false; +} + + +function zot_prv_encode($s,$prvkey) { + $x = ''; + $res = openssl_private_encrypt($s,$x,$prvkey); + return base64url_encode($y); +} +function zot_pub_encode($s,$pubkey) { + $x = ''; + $res = openssl_public_encrypt($s,$x,$pubkey); + return base64url_encode($x); +} + +function zot_prv_decode($s,$prvkey) { + $s = base64url_decode($s); + $x = ''; + openssl_private_decrypt($s,$x,$prvkey); + return $x; +} + +function zot_pub_decode($s,$pubkey) { + $s = base64url_decode($s); + $x = ''; + openssl_public_decrypt($s,$x,$pubkey); + return $x; +} + + +function zot_getzid($url,$myaddress,$myprvkey) { + $ret = array(); + $j = zot_get($url,array('sender' => $myaddress)); + if($j->zid_encoded) + $ret['zid'] = zot_prv_decode($j->zid_encoded,$myprvkey); + if($j->zkey_encoded) + $ret['zkey'] = zot_prv_decode($j->zkey_encoded,$myprvkey); + return $ret; +} + +function zot_post_init($url,$zid,$myprvkey,$theirpubkey) { + $ret = array(); + + $zinit = random_string(32); + + $j = zot_get($url,array('zid' => $zid,'zinit' => $zinit)); + + $a = get_app(); + if(! $a->get_curl_code()) + return ZCURL_TIMEOUT; + if(! $j->zinit) { + logger('zot_post_init: no zinit returned.'); + return false; + } + if(zot_pub_decode($j->zinit,$thierpubkey) !== $zinit) { + logger('zot_post_init: incorrect zinit returned.'); + return false; + } + + if($j->challenge) { + $s = zot_prv_decode($j->challenge,$myprvkey); + $s1 = substr($s,0,strpos($s,'.')); + if($s1 != $zid) { + logger("zot_post_init: incorrect zid returned"); + return false; + } + $ret['result'] = substr($s,strpos($s,'.') + 1); + $ret['perms'] = $j->perms; + } + return $ret; +} + + +function zot_encrypt_data($data,&$key) { + $key = random_string(); + return aes_encrypt($data,$key); +} + + +// encrypt the data prior to calling this function so it only need be done once per message +// regardless of the number of recipients. + +function zot_post_data($url,$zid,$myprvkey,$theirpubkey,$encrypted_data,$key, $intro = false) { + $i = zot_post_init($url,$zid,$myprvkey,$theirpubkey); + if($i === ZCURL_TIMEOUT) + return ZCURL_TIMEOUT; + + if((! $i) || (! array_key_exists('perms',$i)) || (! array_key_exists('result',$i))) + return false; + if((! stristr($i['perms'],'post')) && ($intro === false)) { + logger("zot_post_data: no permission to post: url=$url zid=$zid"); + return false; + } + $p = array(); + $p['zid'] = $zid; + $p['result'] = zot_pub_encode($i['result'],$theirpubkey); + $p['aes_key'] = zot_prv_encode($key,$myprvkey); + $p['data'] = $encrypted_data; + $s = zot_post($url,$p); + $a = get_app(); + if(! $a->get_curl_code()) + return ZCURL_TIMEOUT; + + if($s) { + $j = json_decode($s); + return $j; + } + return false; +} + +function zot_deliver($recipients,$myprvkey,$data) { + + if(is_array($recipients) && count($recipients)) { + + $key = ''; + $encrypted = zot_encrypt_data($data,$key); + + + foreach($recipients as $r) { + $result = zot_post_data( + $r['post'], + $r['zid'], + $myprvkey, + $r['pubkey'], + $encrypted, + $key + ); + if($result === false) { + // post failed + logger('zot_deliver: failed: ' . print_r($r,true)); + } + elseif($result === ZCURL_TIMEOUT) { + // queue for redelivery + } + elseif($result->error) { + // failed at other end + logger('zot_deliver: remote failure: ' . $result->error . ' ' . print_r($r,true)); + } + elseif($result->success) { + logger('zot_deliver: success ' . print_r($r,true, LOGGER_DEBUG)); + } + else + logger('zot_deliver: unknown failure.'); + } + } +} + + +function zot_new_contact($user,$cc) { + + $zid = random_string(32); + $zkey = random_string(32); + + logger("zot_new_contact: zid=$zid zkey=$zkey uid={$user['uid']} " . print_r($cc,true)); + + $ret = array(); + $ret['zid_encoded'] = zot_pub_encode($zid,$cc['pubkey']); + $ret['zkey_encoded'] = zot_pub_encode($zkey,$cc['pubkey']); + return $ret; + + + + + +} \ No newline at end of file