def SendDirectInvite(self): if not common.pref('msn.p2p.allow_direct', type = bool, default = True): return False if self.Remote.DirectBridge is not None and self.Remote.DirectBridge.IsOpen: return False self.ResetDCTimer() connType, netId = self.ConnectionType(self.protocol) remote = self.Remote ver = self.Version message = P2PMessage.P2PMessage(ver) slp = MSNSLP.SLPRequestMessage(self.RemoteContactId, MSNSLP.RequestMethod.INVITE) slp.Source = self.LocalContactId slp.CSeq = 0 slp.CallId = self.Invitation.CallId slp.MaxForwards = 0 slp.ContentType = 'application/x-msnmsgr-transreqbody' slp.BodyValues['Bridges'] = 'TCPv1 SBBridge' slp.BodyValues['Capabilities-Flags'] = '1' slp.BodyValues['NetID'] = str(netId) slp.BodyValues['Conn-Type'] = connType slp.BodyValues['TCP-Conn-Type'] = connType slp.BodyValues['UPnPNat'] = 'false' slp.BodyValues['ICF'] = 'true' if connType == 'Firewall' else 'false' slp.BodyValues['Nat-Trav-Msg-Type'] = 'WLX-Nat-Trav-Msg-Direct-Connect-Req' remote.GenerateNewDCKeys() slp.BodyValues['Hashed-Nonce'] = '{%s}' % str(remote.dcLocalHashedNonce).upper() message.InnerMessage = slp if ver == P2P.Version.V2: message.Header.TFCombination = P2P.TFCombination.First else: message.Header.Flags = P2P.Flags.MSNSLPInfo Bridge = self.protocol.ns.SDGBridge Bridge.StopSending(self) self.ResetDCTimer() log.info("Sending direct invite") Bridge.Send(None, remote, self.RemoteContactEPID, message) return True
def LocalInit(self, app): self.App = app self.Version = app.Version self.LocalContact = app.Local self.RemoteContact = app.Remote self.LocalContactEPID = app.client.get_machine_guid() self.RemoteContactEPID = app.Remote.SelectRandomEPID() self.protocol = getattr(app.Local.client, 'ns', app.Local.client).protocol self.SessionId = randid() invite = self.Invitation = MSNSLP.SLPRequestMessage(self.RemoteContactId, MSNSLP.RequestMethod.INVITE) invite.Target = self.RemoteContactId invite.Source = self.LocalContactId invite.ContentType = 'application/x-msnmsgr-sessionreqbody' invite.BodyValues['SessionID'] = str(self.SessionId) app.SetupInviteMessage(invite) app.P2PSession = self self.RemoteContact.bind('DirectBridgeEstablished', self.RemoteDirectBridgeEstablished) self.Status = P2PSessionStatus.WaitingForRemote
def ProcessDCRespInvite(message, ns, session): body = message.BodyValues if body.get('Bridge', None) == 'TCPv1' and body.get('Listening', 'false').lower() == 'true': remote = ns.contact_list.GetContact(message.FromEmailAccount, MSNAB.IMAddressInfoType.WindowsLive) remoteGuid = message.FromEndPoint dcNonceType, remoteNonce = ParseDCNonce(body) hashed = dcNonceType == DCNonceType.Sha1 replyGuid = remote.dcPlainKey if hashed else remoteNonce selectedPoints = SelectIPEndPoints(body, ns) log.info("SelectedPoints = %r", selectedPoints) if selectedPoints is None or len(selectedPoints) == 0: if session is not None: session.DirectNegotiationFailed() return if uuid.UUID(int = 0) in (message.FromEndPoint, message.ToEndPoint): version1 = True ver = P2P.Version.V1 else: version2 = True ver = P2P.Version.V2 remote.DirectBridge = CreateDirectConnection(remote, remoteGuid, ver, selectedPoints, replyGuid, remoteNonce, hashed, ns, session) needConnectingEndpointInfo = body.get('NeedConnectingEndpointInfo', 'false') == 'true' if needConnectingEndpointInfo: ipep = remote.DirectBridge.LocalEndPoint # Host, port if ipep is not None: port = ipep[-1] else: log.info("Not sending my address info to other client") return ips = map(util.ip_from_bytes, util.myips()) # if ns.protocol.ip not in ips: # ips.append(ns.protocol.ip) hkey = 'IPv4InternalAddrsAndPorts'[::-1] hval = ' '.join(('%s:%s' % (ip, port) for ip in ips))[::-1] slp = MSNSLP.SLPRequestMessage(message.Source, MSNSLP.RequestMethod.ACK) slp.Source = message.Target slp.Via = message.Via slp.CSeq = 0 slp.CallId = str(uuid.UUID(int=0)) slp.MaxForards = 9 slp.ContentType = 'application/x-msnmsgr-transdestaddrupdate' slp.BodyValues[hkey] = hval slp.BodyValues['Nat-Trav-Msg-Type'] = "WLX-Nat-Trav-Msg-Updated-Connecting-Port" msg = P2PMessage.P2PMessage(ver) msg.InnerMessage = slp Bridge = ns.SDGBridge Bridge.Send(None, remote, remoteGuid, msg) else: log.info("Sending transrespbody through transreqbody handler...") return ProcessDCReqInvite(message, ns, session)
def ProcessP2PMessage(self, bridge, message, slp): #log.info("Got message for %r: %r", self, message) self.ResetTimeoutTimer() self.RemoteIdentifier = message.Header.Identifier if self.Version == P2P.Version.V2: self.RemoteIdentifier += message.Header.MessageSize if self.Status in (P2PSessionStatus.Closed, P2PSessionStatus.Error): log.info("Session is closed / error'd. Not handling message %r", message) return False if slp is not None: if hasattr(slp, 'Method'): # Request if slp.ContentType == 'application/x-msnmsgr-sessionclosebody' and slp.Method == 'BYE': log.info("Got BYE message from %r", self.Remote.account) if message.Version == P2P.Version.V1: byeAck = message.CreateAck() byeAck.Header.Flags = P2P.Flags.CloseSession self.Send(byeAck) else: slpMessage = MSNSLP.SLPRequestMessage(self.RemoteContactId, 'BYE') slpMessage.Target = self.RemoteContactId slpMessage.Source = self.LocalContactId slpMessage.Branch = self.Invitation.Branch slpMessage.CallId = self.Invitation.CallId slpMessage.ContentType = 'application/x-msnmsgr-sessionclosebody' slpMessage.BodyValues['SessionID'] = str(self.SessionId) log.info("Sending my own BYE message") self.Send(self.WrapSLPMessage(slpMessage)) self.OnClosed(self.Remote) return True elif (slp.ContentType == 'application/x-msnmsgr-sessionreqbody') and (slp.Method == 'INVITE'): slpMessage = MSNSLP.SLPStatusMessage(self.RemoteContactId, 500, 'Internal Error') slpMessage.Target = self.RemoteContactId slpMessage.Source = self.LocalContactId slpMessage.Branch = self.Invitation.Branch slpMessage.CallId = self.Invitation.CallId slpMessage.ContentType = 'application/x-msnmsgr-sessionreqbody' slpMessage.BodyValues['SessionID'] = str(self.SessionId) errorMessage = self.WrapSLPMessage(slpMessage) bridge.Send(None, self.Remote, self.RemoteContactEPID, errorMessage) return True elif slp.ContentType in ('application/x-msnmsgr-transreqbody', 'application/x-msnmsgr-transrespbody', 'application/x-msnmsgr-transdestaddrupdate'): ProcessDirectInvite(slp, self.protocol, self) return True else: if slp.Code == 200: if slp.ContentType == 'application-x-msnmsgr-transrespbody': ProcessDirectInvite(slp, self.protocol, self) else: log.info("Got 200 OK for invite. Starting app = %r", self.App) self.OnActive() self.App.Start() return True elif slp.Code == 603: self.OnClosed(self.Remote) return True elif slp.Code == 500: return True if self.App is None: log.error("No app set up. Ignoring message = %r", message) return False if message.Header.MessageSize > 0 and message.Header.SessionId > 0: reset = False appData = io.BytesIO() if message.Header.MessageSize == 4 and message.InnerBody == ('\0'*4): reset = True else: appData.write(message.InnerBody) if message.Version == P2P.Version.V2 and P2P.TFCombination.First == (message.Header.TFCombination & P2P.TFCombination.First): reset = True return self.App.ProcessData(bridge, appData, reset) log.error("Nothing to do for message = %r", message) return False
def _MakeSLPRequestMessage(self, for_who, method): slpMessage = MSNSLP.SLPRequestMessage(for_who, method) self._PrepSLPMessage(slpMessage) return slpMessage