コード例 #1
0
 def _reply(self, code):
   """Send an appropriately encoded reply to the client"""
   self.reply_func(Basic.write_byte(1) + Basic.write_byte(code))
   if code == RESPONSE_CODES["SUCCESS"]:
     log_msg("Account %s created for %s" % (self.username, self.ipAddress))
   else:
     log_msg("Account creation attempt failed with code = %s" % (code))
コード例 #2
0
ファイル: Proxy.py プロジェクト: wallydz/BitBlinder
 def _send_remote_peer_request(self, infohash, callback):
     #make sure we have a circuit to send it out on:
     if self.circ and self.circ.is_done():
         self.circ = None
     if not self.circ:
         self.circ = self.app.find_or_build_best_circuit(force=True,
                                                         protocol="DHT")
         if self.circ == None:
             log_msg("Could not build circuit for DHT remote peer request",
                     0, "dht")
             return
     #generate the message:  (version, infohash, peerList)
     msg = ""
     #header:
     msg += Basic.write_byte(Node.VERSION)
     #infohash:
     msg += infohash
     #peers:
     for host, port in self.knownNodes:
         #is this an IP address?
         if isIPAddress(host):
             msg += Basic.write_byte(0)
             msg += struct.pack("!4sH", socket.inet_aton(host), port)
         #otherwise, it's a URL that has to be resolved remotely
         else:
             msg += Basic.write_byte(1)
             msg += Basic.write_lenstr(host)
             msg += Basic.write_short(port)
     self.circ.send_dht_request(msg, self.make_callback_wrapper(callback))
コード例 #3
0
ファイル: BankDisplay.py プロジェクト: clawplach/BitBlinder
  def start_payment_loop(self):
    coin = Bank.get().get_acoins(1)
    if not coin:
      log_msg("No ACoins left!")
      return
    coin = coin[0]
    #generate ACoin request
    request = BankMessages.make_acoin_request(Bank.get(), Bank.get().currentACoinInterval, 1)
    #make the message:
    bankMsg = Basic.write_byte(1)
    bankMsg += coin.write_binary() + request.msg
    key = EncryptedDatagram.ClientSymKey(Bank.get().PUBLIC_KEY)
    bankMsg = Basic.write_byte(1) + key.encrypt(Basic.write_byte(3) + bankMsg)
    payment = UDPPayment.UDPPayment(Bank.get(), bankMsg)
    paymentDeferred = payment.get_deferred()
    def success(result, request=request):
      log_msg("success")
      self.payments += 1
#      self.start_payment_loop()
      #validate the ACoin
      code, sig = Basic.read_byte(result)
      coin = BankMessages.parse_acoin_response(Bank.get(), sig, request, False)
      if not coin:
        log_msg("Invalid ACoin sent for payment!")
      else:
        Bank.get().on_earned_coin(coin)
    paymentDeferred.addCallback(success)
    def failure(error):
      self.start_payment_loop()
      log_ex(error, "Failure during test?")
      self.failures += 1
    paymentDeferred.addErrback(failure)
コード例 #4
0
ファイル: Proxy.py プロジェクト: clawplach/BitBlinder
 def _send_remote_peer_request(self, infohash, callback):
   #make sure we have a circuit to send it out on:
   if self.circ and self.circ.is_done():
     self.circ = None
   if not self.circ:
     self.circ = self.app.find_or_build_best_circuit(force=True, protocol="DHT")
     if self.circ == None:
       log_msg("Could not build circuit for DHT remote peer request", 0, "dht")
       return
   #generate the message:  (version, infohash, peerList)
   msg = ""
   #header:
   msg += Basic.write_byte(Node.VERSION)
   #infohash:
   msg += infohash
   #peers:
   for host, port in self.knownNodes:
     #is this an IP address?
     if isIPAddress(host):
       msg += Basic.write_byte(0)
       msg += struct.pack("!4sH", socket.inet_aton(host), port)
     #otherwise, it's a URL that has to be resolved remotely
     else:
       msg += Basic.write_byte(1)
       msg += Basic.write_lenstr(host)
       msg += Basic.write_short(port)
   self.circ.send_dht_request(msg, self.make_callback_wrapper(callback))
コード例 #5
0
 def _reply(self, code):
     """Send an appropriately encoded reply to the client"""
     self.reply_func(Basic.write_byte(1) + Basic.write_byte(code))
     if code == RESPONSE_CODES["SUCCESS"]:
         log_msg("Account %s created for %s" %
                 (self.username, self.ipAddress))
     else:
         log_msg("Account creation attempt failed with code = %s" % (code))
コード例 #6
0
 def get_prefix(self):
   """@returns:  the beginning of the message from this relay"""
   #send back the PAR version first, so that people can deal with the message intelligently
   msg = Basic.write_byte(self.parVersion)
   #send back our hexid, so they know who this is from:
   msg += Basic.write_hexid(Globals.FINGERPRINT)
   return msg
コード例 #7
0
 def get_prefix(self):
     """@returns:  the beginning of the message from this relay"""
     #send back the PAR version first, so that people can deal with the message intelligently
     msg = Basic.write_byte(self.parVersion)
     #send back our hexid, so they know who this is from:
     msg += Basic.write_hexid(Globals.FINGERPRINT)
     return msg
コード例 #8
0
 def send_setup_reply(self):
   """Send a bunch of payment requests to the origin node"""
   msg = self.get_prefix()
   #send back the number of payment tokens that we will send:
   msg += Basic.write_byte(PaymentStream.MAX_MERCHANT_TOKENS)
   #pack each of the payment tokens:
   for i in range(0, PaymentStream.MAX_MERCHANT_TOKENS):
     msg += self.generate_payment_request_message()
   #finally, send the message back to the customer
   self.send_direct_tor_message(msg, "setup_reply", False, 3)
コード例 #9
0
 def send_setup_reply(self):
     """Send a bunch of payment requests to the origin node"""
     msg = self.get_prefix()
     #send back the number of payment tokens that we will send:
     msg += Basic.write_byte(PaymentStream.MAX_MERCHANT_TOKENS)
     #pack each of the payment tokens:
     for i in range(0, PaymentStream.MAX_MERCHANT_TOKENS):
         msg += self.generate_payment_request_message()
     #finally, send the message back to the customer
     self.send_direct_tor_message(msg, "setup_reply", False, 3)
コード例 #10
0
ファイル: Provider.py プロジェクト: wallydz/BitBlinder
 def _send_peers(self, transactionId):
     #don't try to send a response if that circuit was already closed
     if self.baseCircuit.is_closed():
         return
     log_msg("Sending remote DHT response", 4, "dht")
     responseData = self.responses[transactionId]
     #make the message:
     msg = Basic.write_byte(Node.VERSION)
     #just dump all the peers
     msg += responseData
     #and send it off:
     self.send_direct_tor_message(msg, "dht_response", False, 3, True)
コード例 #11
0
ファイル: Provider.py プロジェクト: clawplach/BitBlinder
 def _send_peers(self, transactionId):
   #don't try to send a response if that circuit was already closed
   if self.baseCircuit.is_closed():
     return
   log_msg("Sending remote DHT response", 4, "dht")
   responseData = self.responses[transactionId]
   #make the message:
   msg = Basic.write_byte(Node.VERSION)
   #just dump all the peers
   msg += responseData
   #and send it off:
   self.send_direct_tor_message(msg, "dht_response", False, 3, True)
コード例 #12
0
    def start_payment_loop(self):
        coin = Bank.get().get_acoins(1)
        if not coin:
            log_msg("No ACoins left!")
            return
        coin = coin[0]
        #generate ACoin request
        request = BankMessages.make_acoin_request(
            Bank.get(),
            Bank.get().currentACoinInterval, 1)
        #make the message:
        bankMsg = Basic.write_byte(1)
        bankMsg += coin.write_binary() + request.msg
        key = EncryptedDatagram.ClientSymKey(Bank.get().PUBLIC_KEY)
        bankMsg = Basic.write_byte(1) + key.encrypt(
            Basic.write_byte(3) + bankMsg)
        payment = UDPPayment.UDPPayment(Bank.get(), bankMsg)
        paymentDeferred = payment.get_deferred()

        def success(result, request=request):
            log_msg("success")
            self.payments += 1
            #      self.start_payment_loop()
            #validate the ACoin
            code, sig = Basic.read_byte(result)
            coin = BankMessages.parse_acoin_response(Bank.get(), sig, request,
                                                     False)
            if not coin:
                log_msg("Invalid ACoin sent for payment!")
            else:
                Bank.get().on_earned_coin(coin)

        paymentDeferred.addCallback(success)

        def failure(error):
            self.start_payment_loop()
            log_ex(error, "Failure during test?")
            self.failures += 1

        paymentDeferred.addErrback(failure)
コード例 #13
0
 def send_receipt_message(self, theirId, numTokens):
     """Send a new payment request after a successful payment
 @param theirId:  the id that the origin has associated with this payment
 @type  theirId:  int
 @param numTokens:  how many payment requests to send back to the origin
 @type  numTokens:  int
 @returns:  deferred (triggered when message is done sending)"""
     msg = self.get_prefix()
     msg += Basic.write_long(theirId)
     msg += Basic.write_byte(numTokens)
     for i in range(0, numTokens):
         msg += self.generate_payment_request_message()
     return self.send_direct_tor_message(msg, "receipt", False, 3)
コード例 #14
0
 def send_receipt_message(self, theirId, numTokens):
   """Send a new payment request after a successful payment
   @param theirId:  the id that the origin has associated with this payment
   @type  theirId:  int
   @param numTokens:  how many payment requests to send back to the origin
   @type  numTokens:  int
   @returns:  deferred (triggered when message is done sending)"""
   msg = self.get_prefix()
   msg += Basic.write_long(theirId)
   msg += Basic.write_byte(numTokens)
   for i in range(0, numTokens):
     msg += self.generate_payment_request_message()
   return self.send_direct_tor_message(msg, "receipt", False, 3)
コード例 #15
0
 def write_request(self, data, protocol, replyPort):
     #write the header:
     msg = self._write_header("request")
     #determine the protocol ID:
     protocolType = None
     for protocolId, protocolName in self.TEST_TYPES.iteritems():
         if protocolName == protocol:
             protocolType = protocolId
             break
     assert protocolType != None, "Specified bad protocol:  %s" % (protocol)
     #write the protocol type:
     msg += Basic.write_byte(protocolType)
     #write the port:
     msg += Basic.write_short(replyPort)
     #finally, add the data:
     msg += data
     return msg
コード例 #16
0
ファイル: EchoMixin.py プロジェクト: clawplach/BitBlinder
 def write_request(self, data, protocol, replyPort):
   #write the header:
   msg = self._write_header("request")
   #determine the protocol ID:
   protocolType = None
   for protocolId, protocolName in self.TEST_TYPES.iteritems():
     if protocolName == protocol:
       protocolType = protocolId
       break
   assert protocolType != None, "Specified bad protocol:  %s" % (protocol)
   #write the protocol type:
   msg += Basic.write_byte(protocolType)
   #write the port:
   msg += Basic.write_short(replyPort)
   #finally, add the data:
   msg += data
   return msg
コード例 #17
0
  def start_bank_process(self, readTokens, writeTokens, paymentId):
    """Create the bank message, and send it to the payment proxy for relaying to the bank.
    @param readTokens:  how many read tokens to pay the merchant for
    @type  readTokens:  int
    @param writeTokens:  how many write tokens to pay the merchant for
    @type  writeTokens:  int
    @param paymentId:  the id for this payment, for tracking when it is completed
    @type  paymentId:  int
    """
    #generate the response message:
    msg  = Basic.write_byte(PAR_VERSION)
    msg += Basic.write_int(readTokens)
    msg += Basic.write_int(writeTokens)
    msg += Basic.write_long(paymentId)
    #figure out how many payments must be made:
    totalTokens = readTokens + writeTokens
    numPayments = totalTokens / Globals.CELLS_PER_PAYMENT
    msg += Basic.write_byte(numPayments)
    bankMsg = Basic.write_byte(numPayments)
    for i in range(0, numPayments):
      #get a token to use for this payment:
      requestId, token = self.paymentTokens.popitem()
      #send it to the bank for signing
      coin = self.parClient.bank.get_acoins(1)
      if not coin:
        paymentDeferred = self.paymentDeferreds[paymentId]
        del self.paymentDeferreds[paymentId]
        paymentDeferred.errback(InsufficientACoins("No ACoins left."))
        return
      coin = coin[0]
      self.parClient.circ.app.coinsSpent += 1
#      log_msg("Srsly, wtf is going on? %s" % (coin.interval), 4)
      bankMsg += coin.write_binary() + token
      msg += Basic.write_byte(COIN_TYPES['A']) + Basic.write_long(requestId)
    key = EncryptedDatagram.ClientSymKey(self.parClient.bank.PUBLIC_KEY)
    bankMsg = Basic.write_byte(1) + key.encrypt(Basic.write_byte(3) + bankMsg)
    msg = Basic.write_byte(PAR_VERSION) + Basic.write_byte(self.hop-1) + Basic.write_lenstr(bankMsg) + Basic.write_lenstr(msg)
    self.parClient.send_direct_tor_message(msg, "bank_relay", True, self.paymentProxyHop)
コード例 #18
0
 def _write_header(self, msgName):
     #write the version
     msg = Basic.write_byte(self.VERSION)
     #note that this is a reply:
     msg += Basic.write_byte(self.MESSAGES[msgName])
     return msg
コード例 #19
0
 def send_setup(self):
   """Send the initial setup message
   @returns: Deferred (triggered when message is sent)"""
   return self.parClient.send_direct_tor_message(Basic.write_byte(PAR_VERSION), "setup", True, self.hop)
コード例 #20
0
ファイル: TorMessages.py プロジェクト: kans/BitBlinder
    def send_direct_tor_message(self, msg, msgType, forward=True, numHops=1, sendOverCircuit=False):
        """Tunnel a message through Tor.  There are two ways to send data:
    
    sendOverCircuit=True:  These messages are visible (plain-text) to the hops 
    that they pass through!  Callers are responsible for any necessary secrecy 
    and intergrity.
    
    sendOverCircuit=False:  These messages are encrypted like normal, relayed 
    Tor cells.  They are thus encrypted and authenticated, but messages may not 
    be sent between two relays (only between the origin and relays)
    
    In either case, messages that are too long will be sent in multiple cells.
    
    @param msg:  the message to send
    @type  msg:  str
    @param msgType:  the type of message.  Must be one of MESSAGE_CODES.
    @type  msgType:  str
    @param forward:  whether to send towards the exit (True) or towards the origin (False)
    @type  forward:  bool
    @param numHops:  how many relays to traverse before the message is delivered.
                     MUST NOT BE 0--in that case, call the handler directly yourself.
    @type  numHops:  int
    @param sendOverCircuit:  whether to send over the circuit (True) or simply send over OR connections to adjacent hops (False)
    @type  sendOverCircuit:  bool"""

        if not self.torApp.is_ready():
            raise TorCtl.TorCtlClosed
        if self.isClosed:
            log_msg("Cannot send Tor message, circuit was closed (%s)" % (msgType))
            return
        # if numHops is 0, you should handle the message yourself, not send it
        assert numHops != 0, "cannot send a zero hop message"
        msg = Basic.write_byte(MESSAGE_CODES[msgType]) + msg
        # put the length in front of the message:
        msgLen = len(msg)
        msg = Basic.write_short(msgLen) + msg
        # who to send it to:
        nextHexId = self.nextHexId
        nextCircId = self.nextCircId
        if not forward:
            nextCircId = self.prevCircId
            nextHexId = self.prevHexId
        dList = []
        # different message lengths depending on if sendOverCircuit if True or False:
        if sendOverCircuit:
            # are sent as normal relayed messages, so they should be this long
            WRITABLE_BYTES = 498
        else:
            # since the Tor cell is 512 bytes, but we need 2 for circid, and 1 for the cell command
            WRITABLE_BYTES = 507
        while len(msg) > 0:
            dataToSend = msg[:WRITABLE_BYTES]
            msg = msg[WRITABLE_BYTES:]

            def add_padding(tmp, desiredLen):
                extraChars = desiredLen - len(tmp)
                return tmp + (" " * extraChars)

            dataToSend = add_padding(dataToSend, WRITABLE_BYTES)
            dataToSend = dataToSend.encode("base64")
            dataToSend = dataToSend.replace("\n", "").replace("=", "")
            # convert sendOverCircuit to "1" or "0" for the control connection:
            if sendOverCircuit:
                sendOverCircuitToken = "1"
            else:
                sendOverCircuitToken = "0"
            dataToSend = "SENDPAYMENT %s %s %s %s %s\r\n" % (
                nextHexId,
                nextCircId,
                dataToSend,
                numHops,
                sendOverCircuitToken,
            )
            d = self.torApp.conn.sendAndRecv(dataToSend)
            dList.append(d)
        d = DeferredList(dList)

        def response(result):
            for x in result:
                if not x[0]:
                    raise Exception(str(x))
                if x[1][0][0] != "250":
                    raise Exception(str(result))
            read, write = x[1][0][1].split(" ")
            read = int(read)
            write = int(write)
            return (read, write)

        d.addCallback(response)

        def error(failure):
            # this happens occasionally when the circuit is closed at approximately the same time that we send a payment
            # it can be safely ignored because the circuit is closed and we already learned about it
            if "552 Cannot find circuit with id" in str(failure):
                log_msg("A circuit that we tried to send a payment message to was closed.  Oops.", 4)
                self.close()
                return
            # otherwise, log an error because this is unexpected
            log_ex(failure, "SENDPAYMENT failed for circuit=%s" % (nextCircId), [TorCtl.ErrorReply])

        d.addErrback(error)
        return d
コード例 #21
0
ファイル: EchoMixin.py プロジェクト: clawplach/BitBlinder
 def _write_header(self, msgName):
   #write the version
   msg = Basic.write_byte(self.VERSION)
   #note that this is a reply:
   msg += Basic.write_byte(self.MESSAGES[msgName])
   return msg
コード例 #22
0
ファイル: TorMessages.py プロジェクト: wallydz/BitBlinder
 def send_direct_tor_message(self, msg, msgType, forward=True, numHops=1, sendOverCircuit=False):
   """Tunnel a message through Tor.  There are two ways to send data:
   
   sendOverCircuit=True:  These messages are visible (plain-text) to the hops 
   that they pass through!  Callers are responsible for any necessary secrecy 
   and intergrity.
   
   sendOverCircuit=False:  These messages are encrypted like normal, relayed 
   Tor cells.  They are thus encrypted and authenticated, but messages may not 
   be sent between two relays (only between the origin and relays)
   
   In either case, messages that are too long will be sent in multiple cells.
   
   @param msg:  the message to send
   @type  msg:  str
   @param msgType:  the type of message.  Must be one of MESSAGE_CODES.
   @type  msgType:  str
   @param forward:  whether to send towards the exit (True) or towards the origin (False)
   @type  forward:  bool
   @param numHops:  how many relays to traverse before the message is delivered.
                    MUST NOT BE 0--in that case, call the handler directly yourself.
   @type  numHops:  int
   @param sendOverCircuit:  whether to send over the circuit (True) or simply send over OR connections to adjacent hops (False)
   @type  sendOverCircuit:  bool"""
   
   if not self.torApp.is_ready():
     raise TorCtl.TorCtlClosed
   if self.isClosed:
     log_msg("Cannot send Tor message, circuit was closed (%s)" % (msgType))
     return
   #if numHops is 0, you should handle the message yourself, not send it
   assert numHops != 0, "cannot send a zero hop message"
   msg = Basic.write_byte(MESSAGE_CODES[msgType]) + msg
   #put the length in front of the message:
   msgLen = len(msg)
   msg = Basic.write_short(msgLen) + msg
   #who to send it to:
   nextHexId = self.nextHexId
   nextCircId = self.nextCircId
   if not forward:
     nextCircId = self.prevCircId
     nextHexId = self.prevHexId
   dList = []
   #different message lengths depending on if sendOverCircuit if True or False:
   if sendOverCircuit:
     #are sent as normal relayed messages, so they should be this long
     WRITABLE_BYTES = 498
   else:
     #since the Tor cell is 512 bytes, but we need 2 for circid, and 1 for the cell command
     WRITABLE_BYTES = 507
   while len(msg) > 0:
     dataToSend = msg[:WRITABLE_BYTES]
     msg = msg[WRITABLE_BYTES:]
     def add_padding(tmp, desiredLen):
       extraChars = desiredLen - len(tmp)
       return tmp + (" " * extraChars)
     dataToSend = add_padding(dataToSend, WRITABLE_BYTES)
     dataToSend = dataToSend.encode("base64")
     dataToSend = dataToSend.replace('\n', '').replace('=', '')
     #convert sendOverCircuit to "1" or "0" for the control connection:
     if sendOverCircuit:
       sendOverCircuitToken = "1"
     else:
       sendOverCircuitToken = "0"
     dataToSend = "SENDPAYMENT %s %s %s %s %s\r\n" % (nextHexId, nextCircId, dataToSend, numHops, sendOverCircuitToken)
     d = self.torApp.conn.sendAndRecv(dataToSend)
     dList.append(d)
   d = DeferredList(dList)
   def response(result):
     for x in result:
       if not x[0]:
         raise Exception(str(x))
       if x[1][0][0] != '250':
         raise Exception(str(result))
     read, write = x[1][0][1].split(" ")
     read = int(read)
     write = int(write)
     return (read, write)
   d.addCallback(response)
   def error(failure):
     #this happens occasionally when the circuit is closed at approximately the same time that we send a payment
     #it can be safely ignored because the circuit is closed and we already learned about it
     if "552 Cannot find circuit with id" in str(failure):
       log_msg("A circuit that we tried to send a payment message to was closed.  Oops.", 4)
       self.close()
       return
     #otherwise, log an error because this is unexpected
     log_ex(failure, "SENDPAYMENT failed for circuit=%s" % (nextCircId), [TorCtl.ErrorReply])
   d.addErrback(error)
   return d