streams/Zotlabs/Zot6/Receiver.php

182 lines
4.2 KiB
PHP
Raw Normal View History

2018-04-23 01:51:46 +00:00
<?php
namespace Zotlabs\Zot6;
use Zotlabs\Lib\Config;
2018-06-01 02:42:13 +00:00
use Zotlabs\Lib\Libzot;
2018-05-30 06:52:08 +00:00
use Zotlabs\Web\HTTPSig;
2018-04-23 01:51:46 +00:00
class Receiver {
protected $data;
protected $encrypted;
protected $error;
protected $messagetype;
protected $sender;
protected $validated;
protected $recipients;
protected $response;
protected $handler;
protected $prvkey;
2018-05-30 04:08:52 +00:00
protected $rawdata;
2018-04-23 01:51:46 +00:00
function __construct($handler) {
$this->error = false;
$this->validated = false;
$this->messagetype = '';
$this->response = [ 'success' => false ];
$this->handler = $handler;
$this->data = null;
2018-05-30 04:08:52 +00:00
$this->rawdata = null;
2018-04-23 01:51:46 +00:00
$this->prvkey = Config::get('system','prvkey');
2018-05-30 04:08:52 +00:00
$this->rawdata = file_get_contents('php://input');
2018-04-23 01:51:46 +00:00
2018-05-30 06:52:08 +00:00
// All access to the zot endpoint must use http signatures
if (! $this->Valid_Httpsig()) {
2018-05-30 04:08:52 +00:00
logger('signature failed');
http_status_exit(400);
}
2018-05-30 06:52:08 +00:00
if ($this->rawdata) {
2018-05-30 04:08:52 +00:00
$this->data = json_decode($this->rawdata,true);
2018-04-23 01:51:46 +00:00
}
else {
$this->error = true;
$this->response['message'] = 'no data';
}
2018-05-31 03:32:59 +00:00
logger('received: ' . print_r($this->data,true), LOGGER_DATA);
2018-05-29 02:42:40 +00:00
2018-05-30 06:52:08 +00:00
if ($this->data && is_array($this->data)) {
$this->encrypted = ((array_key_exists('encrypted',$this->data) && intval($this->data['encrypted'])) ? true : false);
2018-04-23 01:51:46 +00:00
2018-05-30 06:52:08 +00:00
if ($this->encrypted && $this->prvkey) {
2018-05-29 02:42:40 +00:00
$uncrypted = crypto_unencapsulate($this->data,$this->prvkey);
2018-05-30 06:52:08 +00:00
if ($uncrypted) {
2018-04-23 01:51:46 +00:00
$this->data = json_decode($uncrypted,true);
}
else {
$this->error = true;
$this->response['message'] = 'no data';
}
}
}
}
function run() {
2018-05-30 06:52:08 +00:00
if ($this->error) {
2018-04-23 01:51:46 +00:00
// make timing attacks on the decryption engine a bit more difficult
usleep(mt_rand(10000,100000));
json_return_and_die($this->response);
}
2018-05-30 06:52:08 +00:00
if ($this->data) {
if (array_key_exists('type',$this->data))
2018-04-23 01:51:46 +00:00
$this->messagetype = $this->data['type'];
2018-05-30 06:52:08 +00:00
if (! $this->messagetype) {
2018-04-23 01:51:46 +00:00
$this->error = true;
$this->response['message'] = 'no datatype';
}
$this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
$this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
}
2018-05-30 06:52:08 +00:00
if ($this->sender) {
2018-04-23 01:51:46 +00:00
$this->ValidateSender();
2018-05-30 06:52:08 +00:00
}
2018-05-30 04:08:52 +00:00
2018-04-23 01:51:46 +00:00
$this->Dispatch();
}
function ValidateSender() {
2018-05-30 04:08:52 +00:00
2018-06-01 02:42:13 +00:00
$hubs = Libzot::gethub($this->sender,true);
2018-05-29 02:42:40 +00:00
2018-04-23 01:51:46 +00:00
if (! $hubs) {
/* Have never seen this guid or this guid coming from this location. Check it and register it. */
/* (!!) this will validate the sender. */
2018-06-01 02:42:13 +00:00
$result = Libzot::register_hub($this->sender);
2018-04-23 01:51:46 +00:00
if ((! $result['success']) || (! ($hubs = zot_gethub($this->sender,true)))) {
$this->response['message'] = 'Hub not available.';
json_return_and_die($this->response);
}
}
2018-05-30 06:52:08 +00:00
foreach ($hubs as $hub) {
2018-06-01 02:42:13 +00:00
Libzot::update_hub_connected($hub,((array_key_exists('sitekey',$this->sender)) ? $this->sender['sitekey'] : ''));
2018-04-23 01:51:46 +00:00
}
$this->validated = true;
2018-05-29 02:42:40 +00:00
$this->hubs = $hubs;
2018-04-23 01:51:46 +00:00
}
2018-05-30 04:08:52 +00:00
function Valid_Httpsig() {
2018-05-30 06:52:08 +00:00
$result = false;
2018-05-30 04:08:52 +00:00
2018-05-30 06:52:08 +00:00
$verified = HTTPSig::verify($this->rawdata);
2018-05-30 04:08:52 +00:00
if($verified && $verified['header_signed'] && $verified['header_valid']) {
2018-05-30 06:52:08 +00:00
$result = true;
// It is OK to not have signed content - not all messages provide content.
// But if it is signed, it has to be valid
if (($verified['content_signed']) && (! $verified['content_valid'])) {
$result = false;
2018-05-30 04:08:52 +00:00
}
}
2018-05-30 06:52:08 +00:00
return $result;
2018-05-30 04:08:52 +00:00
}
2018-04-23 01:51:46 +00:00
function Dispatch() {
2018-05-30 06:52:08 +00:00
/* These tasks require sender validation */
if (! $this->validated) {
2018-04-23 01:51:46 +00:00
$this->response['message'] = 'Sender not valid';
json_return_and_die($this->response);
}
2018-05-30 06:52:08 +00:00
switch ($this->messagetype) {
2018-04-23 01:51:46 +00:00
case 'request':
2018-05-29 02:42:40 +00:00
$this->handler->Request($this->data,$this->hubs);
2018-04-23 01:51:46 +00:00
break;
case 'purge':
2018-05-29 02:42:40 +00:00
$this->handler->Purge($this->sender,$this->recipients,$this->hubs);
2018-04-23 01:51:46 +00:00
break;
case 'refresh':
2018-05-29 02:42:40 +00:00
$this->handler->Refresh($this->sender,$this->recipients,$this->hubs);
2018-04-23 01:51:46 +00:00
break;
case 'notify':
2018-05-29 02:42:40 +00:00
$this->handler->Notify($this->data,$this->hubs);
2018-04-23 01:51:46 +00:00
break;
case 'rekey':
2018-05-29 02:42:40 +00:00
$this->handler->Rekey($this->sender, $this->data,$this->hubs);
2018-04-23 01:51:46 +00:00
break;
default:
$this->response['message'] = 'Not implemented';
json_return_and_die($this->response);
break;
}
}
}