Ejemplo n.º 1
0
            def after_data_prep_send(ack = None):
                allData = self.data_buffer.read()
                self._close_data_buffer()

                msg = P2PMessage.P2PDataMessage(self.version)
                if self.version == P2P.Version.V1:
                    msg.Header.Flags = P2P.Flags.Data
                    msg.Header.AckSessionId = random.randint(50, sys.maxint)
                else:
                    msg.Header.TFCombination = P2P.TFCombination.MsnObject | P2P.TFCombination.First
                    msg.Header.PackageNumber = packNum

                msg.InnerBody = allData

                if self.version == P2P.Version.V1:
                    log.info("Sending data message for (V1) %r", self)
                    self.SendMessage(msg, success = lambda ack: self.OnTransferFinished())
                else:
                    log.info("Sending data message for (V2) %r", self)

                    def after_data_send(ack = None):
                        rak = P2PMessage.P2PMessage(self.version)
                        rak.SetRAK()
                        log.info("Sending RAK message for (V2). rak = %r, app = %r", rak, self)
                        self.SendMessage(rak, success = lambda ack: self.OnTransferFinished())

                    self.SendMessage(msg, success = after_data_send)
Ejemplo n.º 2
0
    def Start(self):
        if not super(P2PActivity, self).Start():
            return False

        if not self.sending:
            return

        if not self.ActivityData:
            return

        self.ActivityData += u'\0'
        urlLength = len(self.ActivityData.encode('utf-16-le'))

        prepData = P2PMessage.P2PDataMessage(self.version)
        if self.version == P2P.Version.V1:
            header = '\x80\0\0\0'
        else:
            header = '\x80\x3f\x14\x05'

        data = ''+header
        data += struct.pack('<H', 8)
        data += struct.pack('<I', urlLength)
        data += self.ActivityData.encode('utf-16-le')

        prepData.InnerBody = urlData

        if self.version == P2P.Version.V2:
            prepData.Header.TFCombination = P2P.TFCombination.First

        self.SendMessage(prepData)
Ejemplo n.º 3
0
    def WrapSLPMessage(self, slp):
        message = P2PMessage.P2PMessage(self.Version)
        message.InnerMessage = slp

        if message.Version == P2P.Version.V2:
            message.Header.TFCombination = P2P.TFCombination.First
            message.Header.PackageNumber = self.Bridge.IncrementPackageNumber()
        else:
            message.Header.Flags = P2P.Flags.MSNSLPInfo

        return message
Ejemplo n.º 4
0
    def VerifyHandshake(self, data):
        authVersion = P2P.Version.V1
        ret = None
        version1 = False
        version2 = False

        if len(data) == 48:
            authVersion = P2P.Version.V1
            version1 = True
        elif len(data) == 16:
            authVersion = P2P.Version.V2
            version2 = True
        else:
            return None

        if authVersion != self.Version:
            return None

        incomingHandshake = P2PMessage.P2PDCHandshakeMessage(self.Version)
        incomingHandshake.ParseBytes(data)

        incomingGuid = incomingHandshake.Guid
        if version1 and ((incomingHandshake.VHeader.Flags & P2P.Flags.DCHS) !=
                         P2P.Flags.DCHS):
            return None

        compareGuid = incomingGuid
        if self.needHash:
            compareGuid = MSNU.HashNonce(compareGuid)

        if self.Nonce == compareGuid or not self.StrictNonce:
            if self.Nonce != compareGuid:
                log.warning("nonces don't match! continuing anyway.")

            ret = P2PMessage.P2PDCHandshakeMessage(self.Version)
            ret.ParseBytes(data)
            ret.Guid = compareGuid
            ret.Header.Identifier = 0
            return ret

        return None
Ejemplo n.º 5
0
    def Start(self):
        if not super(ObjectTransfer, self).Start():
            return False

#        if self.Remote.DirectBridge is None:
#            log.error("Don't have a direct bridge (MSNObject)")
#            return False

        if self.sending:
            log.info("Starting send for %r", self)
            self.P2PSession.Bridge.packageNumber += 1
            packNum = self.P2PSession.Bridge.packageNumber
            prepData = P2PMessage.P2PDataMessage(self.version)
            prepData.WritePreparationBytes()

            if self.version == P2P.Version.V2:
                prepData.Header.TFCombination = P2P.TFCombination.First

            def after_data_prep_send(ack = None):
                allData = self.data_buffer.read()
                self._close_data_buffer()

                msg = P2PMessage.P2PDataMessage(self.version)
                if self.version == P2P.Version.V1:
                    msg.Header.Flags = P2P.Flags.Data
                    msg.Header.AckSessionId = random.randint(50, sys.maxint)
                else:
                    msg.Header.TFCombination = P2P.TFCombination.MsnObject | P2P.TFCombination.First
                    msg.Header.PackageNumber = packNum

                msg.InnerBody = allData

                if self.version == P2P.Version.V1:
                    log.info("Sending data message for (V1) %r", self)
                    self.SendMessage(msg, success = lambda ack: self.OnTransferFinished())
                else:
                    log.info("Sending data message for (V2) %r", self)

                    def after_data_send(ack = None):
                        rak = P2PMessage.P2PMessage(self.version)
                        rak.SetRAK()
                        log.info("Sending RAK message for (V2). rak = %r, app = %r", rak, self)
                        self.SendMessage(rak, success = lambda ack: self.OnTransferFinished())

                    self.SendMessage(msg, success = after_data_send)

            log.info("Sending data prep message for %r", self)

            self.SendMessage(prepData, after_send = after_data_prep_send)

        else:
            log.info("Starting receive for %r", self)
            self.data_buffer = io.BytesIO()
Ejemplo n.º 6
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
Ejemplo n.º 7
0
    def OnMessageReceived(self, data):
        #_log.info("%r got data: %r", self, data)
        #_log.info("\tDC state = %r", self.DCState)
        if self.DCState == DCState.Established:
            dcMessage = P2PMessage.P2PDCMessage(self.Version)
            dcMessage.ParseBytes(data)

            #_log.info("Got P2P message! %r", dcMessage)
            self.OnP2PMessageReceived(dcMessage)
        elif self.DCState == DCState.HandshakeReply:
            match = self.VerifyHandshake(data)
            if match is None:
                log.info("Bad handshake. Disconnecting")
                self.Disconnect()
                return
            else:
                log.info("Got valid handshake. Session Established")

            self.DCState = DCState.Established
        elif self.DCState == DCState.Handshake:

            match = self.VerifyHandshake(data)
            if match is None:
                log.info("Handshake didn't verify. Disconnecting...")
                self.Disconnect()
                return

            match.Guid = self.Reply
            if self.Version == P2P.Version.V1:
                match.Header.Identifier = self.startupSession.NextLocalIdentifier(
                    0)

            log.info(
                "Sending matching handshake and changing to 'Established'")
            self.SendSocketData(self.dcSocket, match.GetBytes())
            self.DCState = DCState.Established
        elif self.DCState == DCState.Foo:
            if len(data) == 4 and data == 'foo\0':
                log.info("Got FOO. State is now 'Handshake'")
                self.DCState = DCState.Handshake
            else:
                log.info("Got something besides foo. Disconnecting")
                self.Disconnect()
                return

        else:
            log.info("Don't know what to do with this data: %r", data)
Ejemplo n.º 8
0
    def Decline(self):
        if self.Status != P2PSessionStatus.WaitingForLocal:
            return False

        slpMessage = self._MakeSLPStatusMessage(self.RemoteContactId, 603, 'Decline')

        msg = P2PMessage.P2PMessage(self.Version)
        if self.Version == P2P.Version.V1:
            msg.Header.Flags = P2P.Flags.MSNSLPInfo
        else:
            msg.Header.OperationCode = P2P.OperationCode.RAK
            msg.Header.TFCombination = P2P.TFCombination.First
            msg.Header.PackageNumber = self.Bridge.IncrementPackageNumber()

        msg.InnerMessage = slpMessage

        self.Send(msg, success = lambda ack: self.Close())
Ejemplo n.º 9
0
    def OnConnected(self):
        if (not self.IsListener) and self.DCState == DCState.Closed:
            log.info(
                "Connected! Changing state to Foo, sending Foo, changing state to Handshake, sending handshake, changing state to HandshakeReply"
            )
            self.DCState = DCState.Foo
            self.SendSocketData(self.dcSocket, '\x04\0\0\0foo\0')

            self.DCState = DCState.Handshake
            hm = P2PMessage.P2PDCHandshakeMessage(self.Version)
            hm.Guid = self.Reply
            log.info("Sending handshake reply message: %r", hm)

            if self.Version == P2P.Version.V1:
                hm.Header.Identifier = self.startupSession.NextLocalIdentifier(
                    0)

            self.SendSocketData(self.dcSocket, hm.GetBytes())
            self.DCState = DCState.HandshakeReply
Ejemplo n.º 10
0
    def SendBye(self):
        if self._sent_bye:
            log.info("Already sent bye message. not re-sending")
            return
        self._sent_bye = True
        log.info("Constructing and queueing BYE message for %r", self)
        slpMessage = self._MakeSLPRequestMessage(self.RemoteContactId, 'BYE')
        slpMessage.MaxForwards = 0
        slpMessage.CSeq = 0
        slpMessage.Branch = self.Invitation.Branch
        slpMessage.ContentType = 'application/x-msnmsgr-sessionclosebody'

        msg = P2PMessage.P2PMessage(self.Version)
        if msg.Version == P2P.Version.V1:
            msg.Header.Flags = P2P.Flags.MSNSLPInfo
        else:
            msg.Header.OperationCode = P2P.OperationCode.RAK
            msg.Header.TFCombination = P2P.TFCombination.First
            if self.Bridge is not None:
                msg.Header.PackageNumber = self.Bridge.IncrementPackageNumber()

        msg.InnerMessage = slpMessage
        self.Send(msg, after_send = lambda ack=None: self.OnClosed(self.Local))
Ejemplo n.º 11
0
 def after_data_send(ack = None):
     rak = P2PMessage.P2PMessage(self.version)
     rak.SetRAK()
     log.info("Sending RAK message for (V2). rak = %r, app = %r", rak, self)
     self.SendMessage(rak, success = lambda ack: self.OnTransferFinished())
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
def ProcessDCReqInvite(message, ns, session):
    if session is not None and session.Bridge is not None and session.Bridge.BridgeType == 'TCPv1':
        return

    if 'TCPv1' not in message.BodyValues.get('Bridges', message.BodyValues.get('Bridge', '')):
        if session is not None:
            session.DirectNegotiationFailed()
        return

    remoteGuid = message.FromEndPoint
    remote = ns.contact_list.GetContact(message.FromEmailAccount, MSNAB.IMAddressInfoType.WindowsLive)

    dcNonceType, remoteNonce = ParseDCNonce(message.BodyValues)
    if remoteNonce == uuid.UUID(int = 0):
        remoteNonce = remote.dcPlainKey

    hashed = dcNonceType == DCNonceType.Sha1
    nonceFieldName = 'Hashed-Nonce' if hashed else 'Nonce'
    myHashedNonce = remote.dcLocalHashedNonce if hashed else remoteNonce
    myPlainNonce = remote.dcPlainKey

    if dcNonceType == DCNonceType.Sha1:
        remote.dcType = dcNonceType
        remote.dcRemoteHashedNonce = remoteNonce

    else:
        remote.dcType = DCNonceType.Plain
        myPlainNonce = remote.dcPlainKey = remote.dcLocalHashedNonce = remote.dcRemoteHashedNonce = remoteNonce

    ipAddress = util.ip_from_bytes(util.myip())
    port = 0

    if (message.FromEndPoint != uuid.UUID(int=0) and message.ToEndPoint != uuid.UUID(int=0)):
        ver = P2P.Version.V2
    else:
        ver = P2P.Version.V1

    try:
        remote.DirectBridge = ListenForDirectConnection(remote, remoteGuid, ns, ver, session, ipAddress, port, myPlainNonce, remoteNonce, hashed)
    except Exception as e:
        import traceback; traceback.print_exc()
        log.error("Error setting up direct bridge: %r", e)
        port = 0
    else:
        port = remote.DirectBridge.LocalEndPoint[1]

    slp = MSNSLP.SLPStatusMessage(message.Source, 200, 'OK')
    slp.Target = message.Source
    slp.Source = message.Target
    slp.Branch = message.Branch
    slp.CSeq = 1
    slp.CallId = message.CallId
    slp.MaxForwards = 0
    slp.ContentType = 'application/x-msnmsgr-transrespbody'
    slp.BodyValues['Bridge'] = 'TCPv1'

    log.info("port = %r, ipaddress = %r, protocol.ip == %r, other_listening = %r", port, ipAddress, ns.protocol.ip, message.BodyValues.get("Listening", None))
    if port == 0 and message.BodyValues.get("Listening", None) != "false":
        slp.BodyValues['Listening'] = 'false'
        slp.BodyValues[nonceFieldName] = '{%s}' % str(uuid.UUID(int = 0))

    else:
        slp.BodyValues['Listening'] = 'true'
        slp.BodyValues['Capabilities-Flags'] = '1'
        slp.BodyValues['IPv6-global'] = ''
        slp.BodyValues['Nat-Trav-Msg-Type'] = 'WLX-Nat-Trav-Msg-Direct-Connect-Resp'
        slp.BodyValues['UPnPNat'] = 'false'

        slp.BodyValues['NeedConnectingEndpointInfo'] = 'true'
        slp.BodyValues['Conn-Type'] = 'Direct-Connect'
        slp.BodyValues['TCP-Conn-Type'] = 'Direct-Connect'

        slp.BodyValues[nonceFieldName] = '{%s}' % str(myHashedNonce).upper()
        slp.BodyValues['IPv4Internal-Addrs'] = ipAddress
        slp.BodyValues['IPv4Internal-Port'] = str(port)

        if ipAddress != ns.protocol.ip:
            slp.BodyValues['IPv4External-Addrs'] = ns.protocol.ip
            slp.BodyValues['IPv4External-Port'] = str(port)

    p2pmessage = P2PMessage.P2PMessage(ver)
    p2pmessage.InnerMessage = slp

    if ver == P2P.Version.V2:
        p2pmessage.Header.TFCombination = P2P.TFCombination.First
    else:
        p2pmessage.Header.Flags = P2P.Flags.MSNSLPInfo

    if session is not None:
        session.ResetDCTimer()
        session.Bridge.Send(None, session.Remote, session.RemoteContactID, p2pmessage)
        session.Bridge.StopSending(session)
    else:
        ns.SDGBridge.Send(None, remote, remoteGuid, p2pmessage)