def start(self): if self.protocol is None: query = QueryMessage(versions=self.supported_versions) self.send_message(query.encode()) self.sent_query = True else: pass # never restart the AKE as it creates a security risk which allows man-in-the-middle attacks even after the session was encrypted and verified using SMP
def handle_input(self, content, content_type): # handle fragments if content.startswith(('?OTR|', '?OTR,')): content = self.fragment_handler.process(content, protocol=self.protocol) else: self.fragment_handler.reset() # handle OTR messages if content.startswith('?OTR:'): if self.protocol is None and self.sent_query and content[OTRProtocol.marker_slice] in OTRProtocol.commit_markers: protocol_class = OTRProtocol.with_marker(content[OTRProtocol.marker_slice]) if protocol_class.__version__ in self.supported_versions: self.protocol = protocol_class(self) if self.protocol is not None: return self.protocol.handle_input(content, content_type) elif content.startswith('?OTR'): try: query = QueryMessage.decode(content) except ValueError: pass else: if self.protocol is None: common_versions = self.supported_versions.intersection(query.versions) if common_versions: self.protocol = OTRProtocol.with_version(max(common_versions))(self) self.protocol.start() else: pass # never restart the AKE as it creates a security risk which allows man-in-the-middle attacks even after the session was encrypted and verified using SMP raise IgnoreMessage try: error = ErrorMessage.decode(content) except ValueError: pass else: if self.protocol is not None: raise OTRError(error.error) # handle non-OTR messages if self.encrypted: raise UnencryptedMessage else: if self.protocol is None and content_type.startswith('text/') and TaggedPlaintextMessage.__tag__.prefix in content: query = TaggedPlaintextMessage.decode(content) common_versions = self.supported_versions.intersection(query.versions) if common_versions: self.protocol = OTRProtocol.with_version(max(common_versions))(self) self.protocol.start() return query.message return content