comparison sat/plugins/plugin_xep_0234.py @ 3969:8e7d5796fb23

plugin XEP-0391: implement XEP-0391 (Jingle Encrypted Transports) + XEP-0396 (JET-OMEMO): rel 378
author Goffi <goffi@goffi.org>
date Mon, 31 Oct 2022 04:09:34 +0100
parents 3ef988734869
children 524856bd7b19
comparison
equal deleted inserted replaced
3968:0dd79c6cc1d2 3969:8e7d5796fb23
14 # GNU Affero General Public License for more details. 14 # GNU Affero General Public License for more details.
15 15
16 # You should have received a copy of the GNU Affero General Public License 16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 from collections import namedtuple
20 import mimetypes
19 import os.path 21 import os.path
20 import mimetypes 22
21 from collections import namedtuple
22 from zope.interface import implementer
23 from twisted.words.xish import domish
24 from twisted.words.protocols.jabber import jid
25 from twisted.python import failure
26 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
27 from twisted.internet import defer 23 from twisted.internet import defer
28 from twisted.internet import reactor 24 from twisted.internet import reactor
29 from twisted.internet import error as internet_error 25 from twisted.internet import error as internet_error
26 from twisted.python import failure
27 from twisted.words.protocols.jabber import jid
28 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
29 from twisted.words.xish import domish
30 from wokkel import disco, iwokkel 30 from wokkel import disco, iwokkel
31 from sat.core.i18n import _, D_ 31 from zope.interface import implementer
32
33 from sat.core import exceptions
32 from sat.core.constants import Const as C 34 from sat.core.constants import Const as C
35 from sat.core.i18n import D_, _
33 from sat.core.log import getLogger 36 from sat.core.log import getLogger
34 from sat.core import exceptions
35 from sat.tools import utils 37 from sat.tools import utils
36 from sat.tools import stream 38 from sat.tools import stream
37 from sat.tools.common import date_utils 39 from sat.tools.common import date_utils
38 from sat.tools.common import regex 40 from sat.tools.common import regex
39 41
327 progress_id_d = defer.Deferred() 329 progress_id_d = defer.Deferred()
328 if extra is None: 330 if extra is None:
329 extra = {} 331 extra = {}
330 if file_desc is not None: 332 if file_desc is not None:
331 extra["file_desc"] = file_desc 333 extra["file_desc"] = file_desc
334 encrypted = extra.pop("encrypted", False)
332 await self._j.initiate( 335 await self._j.initiate(
333 client, 336 client,
334 peer_jid, 337 peer_jid,
335 [ 338 [
336 { 339 {
342 "extra": extra, 345 "extra": extra,
343 "progress_id_d": progress_id_d, 346 "progress_id_d": progress_id_d,
344 }, 347 },
345 } 348 }
346 ], 349 ],
350 encrypted = encrypted
347 ) 351 )
348 return await progress_id_d 352 return await progress_id_d
349 353
350 def _fileJingleRequest( 354 def _fileJingleRequest(
351 self, peer_jid, filepath, name="", file_hash="", hash_algo="", extra=None, 355 self, peer_jid, filepath, name="", file_hash="", hash_algo="", extra=None,
488 return await self._fileSendingRequestConf( 492 return await self._fileSendingRequestConf(
489 client, session, content_data, content_name, file_data, file_elt 493 client, session, content_data, content_name, file_data, file_elt
490 ) 494 )
491 else: 495 else:
492 # we receive the file 496 # we receive the file
493 return await self._fileReceivingRequestConf( 497 return await self._file_receiving_request_conf(
494 client, session, content_data, content_name, file_data, file_elt 498 client, session, content_data, content_name, file_data, file_elt
495 ) 499 )
496 500
497 async def _fileSendingRequestConf( 501 async def _fileSendingRequestConf(
498 self, client, session, content_data, content_name, file_data, file_elt 502 self, client, session, content_data, content_name, file_data, file_elt
522 return confirmed 526 return confirmed
523 527
524 log.warning(_("File continue is not implemented yet")) 528 log.warning(_("File continue is not implemented yet"))
525 return False 529 return False
526 530
527 async def _fileReceivingRequestConf( 531 async def _file_receiving_request_conf(
528 self, client, session, content_data, content_name, file_data, file_elt 532 self, client, session, content_data, content_name, file_data, file_elt
529 ): 533 ):
530 """parse file_elt, and handle user permission/file opening""" 534 """parse file_elt, and handle user permission/file opening"""
531 await self.parseFileElement(client, file_elt, file_data, given=True) 535 await self.parseFileElement(client, file_elt, file_data, given=True)
532 try: 536 try:
562 finished_d = content_data["finished_d"] = defer.Deferred() 566 finished_d = content_data["finished_d"] = defer.Deferred()
563 confirmed = await self._f.getDestDir( 567 confirmed = await self._f.getDestDir(
564 client, session["peer_jid"], content_data, file_data, stream_object=True 568 client, session["peer_jid"], content_data, file_data, stream_object=True
565 ) 569 )
566 if confirmed: 570 if confirmed:
571 await self.host.trigger.asyncPoint(
572 "XEP-0234_file_receiving_request_conf",
573 client, session, content_data, file_elt
574 )
567 args = [client, session, content_name, content_data] 575 args = [client, session, content_name, content_data]
568 finished_d.addCallbacks( 576 finished_d.addCallbacks(
569 self._finishedCb, self._finishedEb, args, None, args 577 self._finishedCb, self._finishedEb, args, None, args
570 ) 578 )
571 return confirmed 579 return confirmed
572 580
573 @defer.inlineCallbacks 581 async def jingleHandler(self, client, action, session, content_name, desc_elt):
574 def jingleHandler(self, client, action, session, content_name, desc_elt):
575 content_data = session["contents"][content_name] 582 content_data = session["contents"][content_name]
576 application_data = content_data["application_data"] 583 application_data = content_data["application_data"]
577 if action in (self._j.A_ACCEPTED_ACK,): 584 if action in (self._j.A_ACCEPTED_ACK,):
578 pass 585 pass
579 elif action == self._j.A_SESSION_INITIATE: 586 elif action == self._j.A_SESSION_INITIATE:
615 ) 622 )
616 except Exception as e: 623 except Exception as e:
617 self.host.bridge.progressError( 624 self.host.bridge.progressError(
618 progress_id, C.PROGRESS_ERROR_FAILED, client.profile 625 progress_id, C.PROGRESS_ERROR_FAILED, client.profile
619 ) 626 )
620 yield self._j.terminate( 627 await self._j.terminate(
621 client, self._j.REASON_FAILED_APPLICATION, session) 628 client, self._j.REASON_FAILED_APPLICATION, session)
622 raise e 629 raise e
623 else: 630 else:
624 # we are sending the file 631 # we are sending the file
625 size = file_data["size"] 632 size = file_data["size"]
635 data_cb=lambda data: hasher.update(data), 642 data_cb=lambda data: hasher.update(data),
636 ) 643 )
637 finished_d = content_data["finished_d"] = defer.Deferred() 644 finished_d = content_data["finished_d"] = defer.Deferred()
638 args = [client, session, content_name, content_data] 645 args = [client, session, content_name, content_data]
639 finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args) 646 finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args)
647 await self.host.trigger.asyncPoint(
648 "XEP-0234_jingle_handler",
649 client, session, content_data, desc_elt
650 )
640 else: 651 else:
641 log.warning("FIXME: unmanaged action {}".format(action)) 652 log.warning("FIXME: unmanaged action {}".format(action))
642 defer.returnValue(desc_elt) 653 return desc_elt
643 654
644 def jingleSessionInfo(self, client, action, session, content_name, jingle_elt): 655 def jingleSessionInfo(self, client, action, session, content_name, jingle_elt):
645 """Called on session-info action 656 """Called on session-info action
646 657
647 manage checksum, and ignore <received/> element 658 manage checksum, and ignore <received/> element