Hubzilla core code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

302 lines
9.0 KiB

  1. <?php
  2. namespace Zotlabs\Zot;
  3. class Receiver {
  4. protected $data;
  5. protected $encrypted;
  6. protected $error;
  7. protected $messagetype;
  8. protected $sender;
  9. protected $validated;
  10. protected $recipients;
  11. protected $response;
  12. protected $handler;
  13. function __construct($data,$prvkey,$handler) {
  14. $this->error = false;
  15. $this->validated = false;
  16. $this->messagetype = '';
  17. $this->response = array('success' => false);
  18. $this->handler = $handler;
  19. if(! is_array($data))
  20. $data = json_decode($data,true);
  21. if($data && is_array($data)) {
  22. $this->encrypted = ((array_key_exists('iv',$data)) ? true : false);
  23. if($this->encrypted) {
  24. $this->data = @json_decode(@crypto_unencapsulate($data,$prvkey),true);
  25. }
  26. if(! $this->data)
  27. $this->data = $data;
  28. if($this->data && is_array($this->data) && array_key_exists('type',$this->data))
  29. $this->messagetype = $this->data['type'];
  30. }
  31. if(! $this->messagetype)
  32. $this->error = true;
  33. if($this->data) {
  34. $this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
  35. $this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
  36. }
  37. if($this->sender)
  38. $this->ValidateSender();
  39. $this->Dispatch();
  40. }
  41. function ValidateSender() {
  42. $hubs = zot_gethub($this->sender,true);
  43. if (! $hubs) {
  44. /* Have never seen this guid or this guid coming from this location. Check it and register it. */
  45. /* (!!) this will validate the sender. */
  46. $result = zot_register_hub($this->sender);
  47. if ((! $result['success']) || (! ($hubs = zot_gethub($this->sender,true)))) {
  48. $this->response['message'] = 'Hub not available.';
  49. json_return_and_die($this->response);
  50. }
  51. }
  52. foreach($hubs as $hub) {
  53. update_hub_connected($hub,((array_key_exists('sitekey',$this->sender)) ? $this->sender['sitekey'] : ''));
  54. }
  55. $this->validated = true;
  56. }
  57. function Dispatch() {
  58. /* Handle tasks which don't require sender validation */
  59. switch($this->messagetype) {
  60. case 'ping':
  61. /* no validation needed */
  62. $this->handler->Ping();
  63. break;
  64. case 'pickup':
  65. /* perform site validation, as opposed to sender validation */
  66. $this->handler->Pickup($this->data);
  67. break;
  68. default:
  69. if(! $this->validated) {
  70. $this->response['message'] = 'Sender not valid';
  71. json_return_and_die($this->response);
  72. }
  73. break;
  74. }
  75. /* Now handle tasks which require sender validation */
  76. switch($this->messagetype) {
  77. case 'auth_check':
  78. $this->handler->AuthCheck($this->data,$this->encrypted);
  79. break;
  80. case 'request':
  81. $this->handler->Request($this->data);
  82. break;
  83. case 'purge':
  84. $this->handler->Purge($this->sender,$this->recipients);
  85. break;
  86. case 'refresh':
  87. case 'force_refresh':
  88. $this->handler->Refresh($this->sender,$this->recipients);
  89. break;
  90. case 'notify':
  91. $this->handler->Notify($this->data);
  92. break;
  93. case 'rekey':
  94. $this->handler->Rekey($this->sender, $this->data);
  95. break;
  96. default:
  97. $this->response['message'] = 'Not implemented';
  98. json_return_and_die($this->response);
  99. break;
  100. }
  101. }
  102. }
  103. /**
  104. * @brief zot communications and messaging.
  105. *
  106. * Sender HTTP posts to this endpoint ($site/post typically) with 'data' parameter set to json zot message packet.
  107. * This packet is optionally encrypted, which we will discover if the json has an 'iv' element.
  108. * $contents => array( 'alg' => 'aes256cbc', 'iv' => initialisation vector, 'key' => decryption key, 'data' => encrypted data);
  109. * $contents->iv and $contents->key are random strings encrypted with this site's RSA public key and then base64url encoded.
  110. *
  111. * Once decrypted, one will find the normal json_encoded zot message packet.
  112. *
  113. * Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup
  114. *
  115. * Standard packet: (used by notify, purge, refresh, force_refresh, and auth_check)
  116. * \code{.json}
  117. * {
  118. * "type": "notify",
  119. * "sender":{
  120. * "guid":"kgVFf_1...",
  121. * "guid_sig":"PT9-TApzp...",
  122. * "url":"http:\/\/podunk.edu",
  123. * "url_sig":"T8Bp7j5...",
  124. * },
  125. * "recipients": { optional recipient array },
  126. * "callback":"\/post",
  127. * "version":"1.2",
  128. * "encryption":["aes256cbc"],
  129. * "secret":"1eaa...",
  130. * "secret_sig": "df89025470fac8..."
  131. * }
  132. * \endcode
  133. *
  134. * Signature fields are all signed with the sender channel private key and base64url encoded.
  135. * Recipients are arrays of guid and guid_sig, which were previously signed with the recipients private
  136. * key and base64url encoded and later obtained via channel discovery. Absence of recipients indicates
  137. * a public message or visible to all potential listeners on this site.
  138. *
  139. * "pickup" packet:
  140. * The pickup packet is sent in response to a notify packet from another site
  141. * \code{.json}
  142. * {
  143. * "type":"pickup",
  144. * "url":"http:\/\/example.com",
  145. * "callback":"http:\/\/example.com\/post",
  146. * "callback_sig":"teE1_fLI...",
  147. * "secret":"1eaa...",
  148. * "secret_sig":"O7nB4_..."
  149. * }
  150. * \endcode
  151. *
  152. * In the pickup packet, the sig fields correspond to the respective data
  153. * element signed with this site's system private key and then base64url encoded.
  154. * The "secret" is the same as the original secret from the notify packet.
  155. *
  156. * If verification is successful, a json structure is returned containing a
  157. * success indicator and an array of type 'pickup'.
  158. * Each pickup element contains the original notify request and a message field
  159. * whose contents are dependent on the message type.
  160. *
  161. * This JSON array is AES encapsulated using the site public key of the site
  162. * that sent the initial zot pickup packet.
  163. * Using the above example, this would be example.com.
  164. *
  165. * \code{.json}
  166. * {
  167. * "success":1,
  168. * "pickup":{
  169. * "notify":{
  170. * "type":"notify",
  171. * "sender":{
  172. * "guid":"kgVFf_...",
  173. * "guid_sig":"PT9-TApz...",
  174. * "url":"http:\/\/z.podunk.edu",
  175. * "url_sig":"T8Bp7j5D..."
  176. * },
  177. * "callback":"\/post",
  178. * "version":1,
  179. * "secret":"1eaa661..."
  180. * },
  181. * "message":{
  182. * "type":"activity",
  183. * "message_id":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
  184. * "message_top":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
  185. * "message_parent":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
  186. * "created":"2012-11-20 04:04:16",
  187. * "edited":"2012-11-20 04:04:16",
  188. * "title":"",
  189. * "body":"Hi Nickordo",
  190. * "app":"",
  191. * "verb":"post",
  192. * "object_type":"",
  193. * "target_type":"",
  194. * "permalink":"",
  195. * "location":"",
  196. * "longlat":"",
  197. * "owner":{
  198. * "name":"Indigo",
  199. * "address":"indigo@podunk.edu",
  200. * "url":"http:\/\/podunk.edu",
  201. * "photo":{
  202. * "mimetype":"image\/jpeg",
  203. * "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
  204. * },
  205. * "guid":"kgVFf_...",
  206. * "guid_sig":"PT9-TAp...",
  207. * },
  208. * "author":{
  209. * "name":"Indigo",
  210. * "address":"indigo@podunk.edu",
  211. * "url":"http:\/\/podunk.edu",
  212. * "photo":{
  213. * "mimetype":"image\/jpeg",
  214. * "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
  215. * },
  216. * "guid":"kgVFf_...",
  217. * "guid_sig":"PT9-TAp..."
  218. * }
  219. * }
  220. * }
  221. * }
  222. * \endcode
  223. *
  224. * Currently defined message types are 'activity', 'mail', 'profile', 'location'
  225. * and 'channel_sync', which each have different content schemas.
  226. *
  227. * Ping packet:
  228. * A ping packet does not require any parameters except the type. It may or may
  229. * not be encrypted.
  230. *
  231. * \code{.json}
  232. * {
  233. * "type": "ping"
  234. * }
  235. * \endcode
  236. *
  237. * On receipt of a ping packet a ping response will be returned:
  238. *
  239. * \code{.json}
  240. * {
  241. * "success" : 1,
  242. * "site" {
  243. * "url": "http:\/\/podunk.edu",
  244. * "url_sig": "T8Bp7j5...",
  245. * "sitekey": "-----BEGIN PUBLIC KEY-----
  246. * MIICIjANBgkqhkiG9w0BAQE..."
  247. * }
  248. * }
  249. * \endcode
  250. *
  251. * The ping packet can be used to verify that a site has not been re-installed, and to
  252. * initiate corrective action if it has. The url_sig is signed with the site private key
  253. * and base64url encoded - and this should verify with the enclosed sitekey. Failure to
  254. * verify indicates the site is corrupt or otherwise unable to communicate using zot.
  255. * This return packet is not otherwise verified, so should be compared with other
  256. * results obtained from this site which were verified prior to taking action. For instance
  257. * if you have one verified result with this signature and key, and other records for this
  258. * url which have different signatures and keys, it indicates that the site was re-installed
  259. * and corrective action may commence (remove or mark invalid any entries with different
  260. * signatures).
  261. * If you have no records which match this url_sig and key - no corrective action should
  262. * be taken as this packet may have been returned by an imposter.
  263. *
  264. * @param[in,out] App &$a
  265. */