예제 #1
0
    def sendRemote( self, data, flags=const.FLAG_PAYLOAD ):
        """
        Send data to the remote end after a connection was established.

        The given `data' is first encapsulated in protocol messages.  Then, the
        protocol message(s) are sent over the wire.  The argument `flags'
        specifies the protocol message flags with the default flags signalling
        payload.
        """

        log.debug("Processing %d bytes of outgoing data." % len(data))

        # Wrap the application's data in ScrambleSuit protocol messages.
        messages = message.createProtocolMessages(data, flags=flags)

        # Let the packet morpher tell us how much we should pad.
        paddingLen = self.pktMorpher.calcPadding(sum([len(msg) for
                                                 msg in messages]))

        # If padding > header length, a single message will do...
        if paddingLen > const.HDR_LENGTH:
            messages.append(message.new("", paddingLen=paddingLen -
                                                       const.HDR_LENGTH))

        # ...otherwise, we use two padding-only messages.
        else:
            messages.append(message.new("", paddingLen=const.MPU -
                                                       const.HDR_LENGTH))
            messages.append(message.new("", paddingLen=paddingLen))

        blurb = "".join([msg.encryptAndHMAC(self.sendCrypter,
                        self.sendHMAC) for msg in messages])

        # Flush data chunk for chunk to obfuscate inter arrival times.
        if const.USE_IAT_OBFUSCATION:
            if len(self.choppingBuf) == 0:
                self.choppingBuf.write(blurb)
                reactor.callLater(self.iatMorpher.randomSample(),
                                  self.flushPieces)
            else:
                # flushPieces() is still busy processing the chopping buffer.
                self.choppingBuf.write(blurb)
        else:
            self.circuit.downstream.write(blurb)
예제 #2
0
    def getPadding(self, sendCrypter, sendHMAC, dataLen):
        """
        Based on the burst's size, return a ready-to-send padding blurb.
        """

        padLen = self.calcPadding(dataLen)

        assert const.HDR_LENGTH <= padLen < (const.MTU + const.HDR_LENGTH), "Invalid padding length %d." % padLen

        # We have to use two padding messages if the padding is > MTU.
        if padLen > const.MTU:
            padMsgs = [
                message.new("", paddingLen=700 - const.HDR_LENGTH),
                message.new("", paddingLen=padLen - 700 - const.HDR_LENGTH),
            ]
        else:
            padMsgs = [message.new("", paddingLen=padLen - const.HDR_LENGTH)]

        blurbs = [msg.encryptAndHMAC(sendCrypter, sendHMAC) for msg in padMsgs]

        return "".join(blurbs)
예제 #3
0
    def getPadding( self, sendCrypter, sendHMAC, dataLen ):
        """
        Based on the burst's size, return a ready-to-send padding blurb.
        """

        padLen = self.calcPadding(dataLen)

        assert const.HDR_LENGTH <= padLen < (const.MTU + const.HDR_LENGTH), \
               "Invalid padding length %d." % padLen

        # We have to use two padding messages if the padding is > MTU.
        if padLen > const.MTU:
            padMsgs = [message.new("", paddingLen=700 - const.HDR_LENGTH),
                       message.new("", paddingLen=padLen - 700 - \
                                       const.HDR_LENGTH)]
        else:
            padMsgs = [message.new("", paddingLen=padLen - const.HDR_LENGTH)]

        blurbs = [msg.encryptAndHMAC(sendCrypter, sendHMAC) for msg in padMsgs]

        return "".join(blurbs)
예제 #4
0
def send_user(recipient):
    """
    Send a message to a user.
    """
    # TODO: Replace "random_guy" with the sender of the message.
    sender = "random_guy"

    msg_id = message.new(sender, request.json["content"])
    message.send_users(msg_id, [recipient])

    app.logger.info("[PM] %s -> %s" % (sender, recipient))
    return "", 200
예제 #5
0
def send_user(recipient):
    """
    Send a message to a user.
    """
    # TODO: Replace "random_guy" with the sender of the message.
    sender = "random_guy"

    msg_id = message.new(sender, request.json["content"])
    message.send_users(msg_id, [recipient])

    app.logger.info("[PM] %s -> %s" % (sender, recipient))
    return "", 200
예제 #6
0
    def extractMessages( self, data, aes ):
        """
        Unpacks (i.e., decrypts and authenticates) protocol messages.

        The raw `data' coming directly from the wire is decrypted using `aes'
        and authenticated.  The payload (be it a session ticket or actual
        payload) is then returned as unencrypted protocol messages.  In case of
        invalid headers or HMACs, an exception is raised.
        """

        assert aes and (data is not None)

        self.recvBuf += data
        msgs = []

        # Keep trying to unpack as long as there is at least a header.
        while len(self.recvBuf) >= const.HDR_LENGTH:

            # If necessary, extract the header fields.
            if self.totalLen == self.payloadLen == self.flags == None:
                self.totalLen = pack.ntohs(aes.decrypt(self.recvBuf[16:18]))
                self.payloadLen = pack.ntohs(aes.decrypt(self.recvBuf[18:20]))
                self.flags = ord(aes.decrypt(self.recvBuf[20]))

                if not message.isSane(self.totalLen,
                                      self.payloadLen, self.flags):
                    raise base.PluggableTransportError("Invalid header.")

            # Parts of the message are still on the wire; waiting.
            if (len(self.recvBuf) - const.HDR_LENGTH) < self.totalLen:
                break

            rcvdHMAC = self.recvBuf[0:const.HMAC_SHA256_128_LENGTH]
            vrfyHMAC = mycrypto.HMAC_SHA256_128(self.recvHMAC,
                              self.recvBuf[const.HMAC_SHA256_128_LENGTH:
                              (self.totalLen + const.HDR_LENGTH)])

            if rcvdHMAC != vrfyHMAC:
                raise base.PluggableTransportError("Invalid message HMAC.")

            # Decrypt the message and remove it from the input buffer.
            extracted = aes.decrypt(self.recvBuf[const.HDR_LENGTH:
                         (self.totalLen + const.HDR_LENGTH)])[:self.payloadLen]
            msgs.append(message.new(payload=extracted, flags=self.flags))
            self.recvBuf = self.recvBuf[const.HDR_LENGTH + self.totalLen:]

            # Protocol message processed; now reset length fields.
            self.totalLen = self.payloadLen = self.flags = None

        return msgs