示例#1
0
    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
示例#2
0
    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
示例#3
0
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)
示例#4
0
    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
示例#5
0
 def _MakeSLPRequestMessage(self, for_who, method):
     slpMessage = MSNSLP.SLPRequestMessage(for_who, method)
     self._PrepSLPMessage(slpMessage)
     return slpMessage