Exemple #1
0
    def _on_bank_ready(self, result):
        """Called when the bank has finished starting.  Alerts the applications to any
    startup arguments that were passed in, which will likely cause them to actually start."""
        if result != True:
            log_msg("Bank failed to start correctly!", 0)
            return result

        #handle the starting arguments:
        Startup.handle_args(ProgramState.STARTING_DIR, sys.argv[1:])
        GlobalEvents.throw_event("startup")

        #if this is the first run, save all the settings files:
        if self.bbApp.isFirstRun:
            for app in [self.bbApp, self.btApp, self.torApp, self.ffApp]:
                if app:
                    app.settings.save()
        self.coreSettings.save()

        #schedule update function:
        def do_update():
            BWHistory.update_all()
            return True

        ProgramState.DO_UPDATES = True
        self.updateEvent = Scheduler.schedule_repeat(
            Globals.INTERVAL_BETWEEN_UPDATES, do_update)
        return result
Exemple #2
0
 def set_value(self, val):
   val = unicode(val)
   if not Files.file_exists(val):
     try:
       os.makedirs(val)
     except Exception, error:
       log_msg("Could not make a dir: %s" % (error), 0)
Exemple #3
0
 def connectionMade(self):
   log_msg('Sending login message...', 2)
   signedFingerprint = Globals.PRIVATE_KEY.sign(Globals.FINGERPRINT)
   publicKey = Basic.long_to_bytes(long(Globals.PRIVATE_KEY.n), 128)
   protocol = 1
   msg = struct.pack('!B128s50s50s128s', protocol, signedFingerprint, self.factory.username, self.factory.password, publicKey)
   self.sendString(msg)
Exemple #4
0
 def handle_request(self, host, port, data, protocol, transport):
     log_msg("Got request from %s to send %s to %s" %
             (host, protocol, port))
     #make the reply:
     msg = self.write_reply(host, data)
     #and send it back
     self.send_reply(msg, host, port, protocol, transport)
 def handle_setup_reply(self, msg):
   """Handle a setup reply.  Send it to the appropriate PaymentStream, then check if they are all done"""
   log_msg("circ=%d:  PAR setup done." % (self.circ.id), 3, "par")
   #unpack the messages:
   forwardParVersion, msg = Basic.read_byte(msg)
   if forwardParVersion < self.parVersion:
     self.parVersion = forwardParVersion
   payStream, msg = self.get_payment_stream(msg)
   payStream.handle_setup_reply(forwardParVersion, msg)
   if self.all_setup_done():
     initialTokensDeferred = self.add_start_tokens()
     #this usually happens if the circuit is already closed, if not, an exception will already be logged
     if not initialTokensDeferred:
       self.circ.on_done()
       return
     def initial_tokens_added(result):
       self.circ.initialTokensAdded = True
       self._add_tokens_callback(result, PaymentMessageHandler.START_READ_TOKENS, PaymentMessageHandler.START_WRITE_TOKENS)
       return result
     initialTokensDeferred.addCallback(initial_tokens_added)
     initialTokensDeferred.addErrback(self.generic_error_handler)
     self.setupDone = True
     #send any payment requests that are waiting on the setup:
     reads = self.queuedReadTokens
     writes = self.queuedWriteTokens
     self.queuedReadTokens = 0
     self.queuedWriteTokens = 0
     if self.queuedReadTokens or self.queuedWriteTokens:
       self.send_payment_request(reads, writes)
     self.circ.on_par_ready()
Exemple #6
0
 def _make_bit_twister_display(self):
     if len(self.torrents['torrents']) == 0:
         #no .torrents yet, still display the header
         height = 1
         width = 9
     else:
         height = 2 * len(self.torrents['torrents']) + 1
         width = self.torrents['maxLength'] + 1
     r, c = self._get_screen_size()
     if r > self.moniesDisplay[0] + height + 1 and \
        c > self.serverDisplay[1] + width + 1:
         win = self.stdscr.derwin(height, width, r - height, c - width)
         win.addstr(0, width - 9, 'Torrents', curses.A_BOLD)
         #add the apps to the gui
         row = 2
         rowSep = 2
         for formatedString in self.torrents['torrents']:
             if len(formatedString) < self.torrents['maxLength']:
                 formatedString = ' ' * (self.torrents['maxLength'] - len(
                     formatedString)) + formatedString
             win.addstr(row, 0, formatedString)
             row += rowSep
         win.refresh()
     else:
         log_msg(
             'There was not enough screen space (%s, %s) for the torrents display (%s, %s)'
             % (r, c, height, width), 4)
     return
Exemple #7
0
 def _make_bit_twister_display(self):
   if len(self.torrents['torrents']) == 0:
     #no .torrents yet, still display the header
     height = 1
     width = 9
   else:
     height = 2 * len(self.torrents['torrents']) + 1
     width = self.torrents['maxLength'] + 1
   r, c = self._get_screen_size()
   if r > self.moniesDisplay[0] + height + 1 and \
      c > self.serverDisplay[1] + width + 1:
     win = self.stdscr.derwin(height, width, r - height, c - width)
     win.addstr(0, width - 9, 'Torrents', curses.A_BOLD)
     #add the apps to the gui
     row = 2
     rowSep = 2
     for formatedString in self.torrents['torrents']:
       if len(formatedString) < self.torrents['maxLength']:
         formatedString = ' '*(self.torrents['maxLength'] - len(formatedString)) + formatedString
       win.addstr(row, 0, formatedString)
       row += rowSep
     win.refresh()
   else:
     log_msg('There was not enough screen space (%s, %s) for the torrents display (%s, %s)'%
            (r ,c , height, width), 4)
   return
Exemple #8
0
  def cleanup(self):
    """Make sure the reactor, threads, etc have been stopped.  Also removes
    the file that indicates we shutdown cleanly."""
    
    #shutdown Twisted
    if ProgramState.USE_GTK:
      Globals.reactor.stop()
      Globals.reactor.runUntilCurrent()
      
    #ensure that all threads have closed:
    remainingThreads = threading.enumerate()
    for thread in remainingThreads:
      if threading._MainThread != type(thread):
        log_msg("Thread has not finished by the end of the program: %s" % (thread), 1)

    #start the update if necessary:
    if Updater.get().APPLY_UPDATE:
      ClientUtil.apply_update()
      
    #NOTE:  we intentionally leave the log files open so that errors can get written to them...
    log_msg("Thanks for using BitBlinder", 2)
    ErrorReporting.destroy_marker_file()
    
    #NOTE:  this is here so that threads can finish properly.  I was getting errors from leftover threads without it.
    #However, I'm pretty sure that it was just from the IDE
    time.sleep(0.2)
 def connection_lost(self, protocol):
     c = self.connections[protocol]
     log_msg('%s connection closed' % (c.ccount), 3, "btprotocol")
     del self.connections[protocol]
     if c.download:
         c.download.disconnected()
     self.choker.connection_lost(c)
Exemple #10
0
    def start_connections(self, list):
        peers_added = 0
        #add to our current list except duplicates:
        for peer in list:
            if self.to_connect.count(peer) == 0:
                if self.prev_connected.count(peer) == 0:
                    self.never_connected.append(peer)
                    peers_added += 1
                else:
                    self.to_connect.append(peer)
                    peers_added += 1
        log_msg(
            "Added %s to our list of peers, now %s long." %
            (peers_added, len(self.to_connect)), 2, "tracker")

        #without this, the peers would be each get connected to twice on the very first update if they fail
        if self.lastPeerCycleTime == 0:
            self.lastPeerCycleTime = time.time()

        #for testing:  sometimes handy to print out peers so I can make sure we can connect to them later
        #f = open("peer_list.txt", "wb")
        #for x in list:
        #  dns, id, encrypted = x
        #  #log_msg("%s %s (%s)" % (encrypted, dns, id))
        #  f.write("%s:%s\n" % (dns[0], dns[1]))
        #f.close()
        #make sure we're starting connections from that list:
        if not self.startConnectionsEvent:
            self.startConnectionsEvent = Scheduler.schedule_repeat(
                1.0, self._start_connection_from_queue)
            self._start_connection_from_queue()
Exemple #11
0
    def send_partial(self, bytes):
        if self.protocol.closed:
            return 0
        if self.partial_message is None:
            s = self.upload.get_upload_chunk()
            if s is None:
                return 0
            index, begin, piece = s
            self.lastActive = time.time()
            self.partial_message = ''.join((
                            tobinary(len(piece) + 9), PIECE,
                            tobinary(index), tobinary(begin), piece.tostring() ))
            log_msg('%s sending chunk %s %s %s' % (self.ccount,index,begin,begin+len(piece)), 4, "btprotocol")

        if bytes < len(self.partial_message):
            self.protocol.send_message_raw(self.partial_message[:bytes])
            self.partial_message = self.partial_message[bytes:]
            return bytes

        q = [self.partial_message]
        self.partial_message = None
        if self.send_choke_queued:
            self.send_choke_queued = False
            self.outqueue.append(tobinary(1)+CHOKE)
            self.upload.choke_sent()
            self.just_unchoked = 0
        q.extend(self.outqueue)
        self.outqueue = []
        q = ''.join(q)
        self.protocol.send_message_raw(q)
        return len(q)
Exemple #12
0
 def launch_test_upload(self, widget, event=None):    
   test = None
   #get the selected item (either a Stream or Circuit)
   circ = self.getSelected()
   #if there was no selection or the selection was a stream, let BitBlinder pick the circuit
   if not circ or circ.__class__.__name__ != "Circuit" or not circ.is_open():
     log_msg("Cannot upload through that %s" % (circ), 0)
     return
     
   class TestUploader(Int32StringReceiver):
     def connectionMade(self):
       self.bytesLeft = 2 * 1024 * 1024
       self.transport.write(struct.pack("!I", self.bytesLeft))
       self.sendEvent = Scheduler.schedule_repeat(0.1, self.send_more, 1024 * 10)
       
     def send_more(self, numBytes):
       self.transport.write("1"*numBytes)
       self.bytesLeft -= numBytes
       if self.bytesLeft <= 0:
         return False
       else:
         return True
         
     def stringReceived(self,  data):
       log_msg("Upload hopefully done?")
       return
       
   factory = protocol.ClientFactory()
   factory.protocol = TestUploader
   #connect to the bank and send some trash:
   d = BitBlinder.get().launch_external_factory(Bank.get().host, Bank.get().port, factory, circ.handle_stream, "Test Upload")
Exemple #13
0
 def externally_handshaked_connection_made(self, connection, options, already_read, encrypted = None):
     shouldClose = False
     if self.done:
       shouldClose = True
       log_msg("Refusing connection because we are shutting down", 4)
     #TODO:  move this earlier in the connection process, or ideally, get Twisted to listen only from localhost when socks is enabled
     elif self.config['use_socks'] and connection.get_ip() != "127.0.0.1":
       shouldClose = True
       log_msg("Refusing connection from outside peer because they attempted to connect directly!  ip=%s" % (Basic.clean(ip)), 1)
     elif self.paused:
       shouldClose = True
       log_msg("Refusing connection becase we're paused", 4)
     elif len(self.connections) >= self.max_connections:
       shouldClose = True
       log_msg("Refusing connection becase we have too many already", 4)
     elif self.check_ip(connection=connection):
       shouldClose = True
       log_msg("Refusing connection becase check_ip failed", 4)
     #ok, is there any reason to close?
     if shouldClose:
       connection.close()
       return False
     #guess not, add this to the connections:
     self.connect_succeeded(connection)
     connection.externalHandshakeDone(self, encrypted, options)
     #TODO:  make sure the data is getting handled properly?
     ##connection.complete = True
     #if already_read:
     #    #con.data_came_in(con, already_read)
     #    connection.dataReceived(already_read)
     return True
Exemple #14
0
def create_error_archive(description):
  logs = ["main.out", "errors.out", "stderr.out", "tor.out", "tor_conn.out", "tor_conn.out.old", "log.out.old"]
  zipFile = zipfile.ZipFile(Globals.BUG_REPORT_NAME, "w")
  MAX_SIZE = 2 * 1024L * 1024L
  for log in logs:
    #write the file log with name log
    logName = os.path.join(Globals.LOG_FOLDER, log)
    if Files.file_exists(logName):
      fileSize = os.path.getsize(logName)
      if fileSize > MAX_SIZE:
        log_msg("There were %s bytes, too many to include  :(" % (fileSize), 0)
        f = open(logName, "rb")
        initialData = f.read(MAX_SIZE/2)
        f.seek(-1 * MAX_SIZE/2, 2)
        finalData = f.read(MAX_SIZE/2)
        data = initialData + "\n\n...\n\n" + finalData
        f.close()
        zipFile.writestr(log, data + "\nStopping becaue there were %s bytes, too many to include  :(" % (fileSize))
      else:
        zipFile.write(logName, log)
    else:
      log_msg("Could not find log file:  %s" % (logName), 0)
  description = "%s\n%s\n%s\n%s\nDescription:  %s" % (Logging.dump_system_info(), Logging.make_platform_status(), Logging.make_application_status(), Logging.make_program_status(), description)
  zipFile.writestr("description.out", description)
  zipFile.close()
Exemple #15
0
 def _make_monies_display(self):
   #need to know our width before we can fit
   maxLen = 0
   for key, stat in self.statistics.iteritems():
     #note, this implicitly sets the pretty text 
     statLen = len(stat)
     if statLen > maxLen:
       maxLen = statLen
   totalWidth = maxLen + 15 + 1
   r, c = self._get_screen_size()
   #will it fit in the top right corner (width is variable, though the rows shouldn't change)
   if r > self.moniesDisplay[0]  and \
      c > totalWidth + self.statusDisplay[1] + 1:
     startY = 0
     startX = c - totalWidth - 1
     win = self.stdscr.derwin(self.moniesDisplay[0], totalWidth + 1, startY, startX)
     win.clear()
     #win.border()
     win.addstr(0, 0, "%sCredits"%((totalWidth - 7)*" "), curses.A_BOLD)
     row = 2
     rowSep = 2
     col = 0
     #dump things into the window! (should we sort them first?)
     for key, value in self.statistics.iteritems():
       win.addstr(row, col, value.justify_right(totalWidth))
       row += rowSep
     win.refresh()
   else:
     log_msg('There was not enough screen space (%s, %s) for the credits display (%s, %s)'%
                  (r, c, self.moniesDisplay[0], totalWidth), 4)
   return
 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))
Exemple #17
0
 def read_rangelist(self, file):
     l = []
     f = open(file, 'r')
     while True:
         line = f.readline()
         if not line:
             break
         line = line.strip()
         if not line or line[0] == '#':
             continue
         line = line.split(':')[-1]
         try:
             ip1, ip2 = line.split('-')
         except:
             ip1 = line
             ip2 = line
         try:
             ip1 = to_long_ipv4(ip1)
             ip2 = to_long_ipv4(ip2)
             assert ip1 <= ip2
         except:
             log_msg('*** WARNING *** could not parse IP range: ' + line, 0)
         l.append((ip1, ip2))
     f.close()
     self._import_ipv4(l)
Exemple #18
0
 def on_update(self):
     """Called every INTERVAL_BETWEEN_UPDATES to update the various information"""
     if not self.is_running():
         return
     #TODO:  this is a really arbitrary way of keeping things up to date...
     #keep the list of circuits and streams reasonable:
     #if there are more than 30 streams/circuits, we remove those that have been done for a minute::
     toDelete = []
     if len(self.streams) > 30:
         for streamId, obj in self.streams.iteritems():
             if obj.is_done():
                 age = time.time() - obj.endedAt
                 if age > 60:
                     toDelete.append(streamId)
                     log_msg(
                         "Removing stream=%d from the list because it is old and closed"
                         % (streamId), 4, "circuit")
     for streamId in toDelete:
         del self.streams[streamId]
     toDelete = []
     if len(self.circuits) > 30:
         for obj in self.circuits:
             if obj.is_done():
                 age = time.time() - obj.endedAt
                 if age > 60:
                     toDelete.append(obj)
                     log_msg(
                         "Removing circuit=%d from the list because it is old and closed"
                         % (obj.id), 4, "stream")
     for circ in toDelete:
         self.circuits.remove(circ)
Exemple #19
0
 def unpack_and_mint(self, msg):
   """unpacks the request retreiving the number of coins packed and the total value desired.
   Verification: values must be positive!
   """
   self.number, msg = Basic.read_short(msg)
   value, msg = Basic.read_int(msg)
   log_msg('REQUEST:: %s %s'%(self.number, self.hexId), 0)
   if not BankUtil.is_positive_integer(self.number):
     raise ValueError('number of coins must be greater than 0!')
   if value != ACOIN_VALUE or not BankUtil.is_positive_integer(value):
     raise ValueError('coins must have a positive, integer value')
     
   self.bill = 0
   self.signatures = ""
   for i in range(0, self.number):
     #TODO: move to a worker pool or something
     sig = Globals.ACOIN_KEY.decrypt(msg[:Globals.ACOIN_KEY_BYTES], False)
     self.signatures += struct.pack('!%ss'%(Globals.ACOIN_KEY_BYTES), sig)
     msg = msg[Globals.ACOIN_KEY_BYTES:]
     self.bill += value
     
   #TODO: move this constraint to postgres to get rid of any potential race conditions
   sql = "SELECT balance FROM Accounts WHERE Username = %s"
   inj = (self.user,)
   d = db.read(sql, inj)
   return d
Exemple #20
0
    def send_partial(self, bytes):
        if self.protocol.closed:
            return 0
        if self.partial_message is None:
            s = self.upload.get_upload_chunk()
            if s is None:
                return 0
            index, begin, piece = s
            self.lastActive = time.time()
            self.partial_message = ''.join(
                (tobinary(len(piece) + 9), PIECE, tobinary(index),
                 tobinary(begin), piece.tostring()))
            log_msg(
                '%s sending chunk %s %s %s' %
                (self.ccount, index, begin, begin + len(piece)), 4,
                "btprotocol")

        if bytes < len(self.partial_message):
            self.protocol.send_message_raw(self.partial_message[:bytes])
            self.partial_message = self.partial_message[bytes:]
            return bytes

        q = [self.partial_message]
        self.partial_message = None
        if self.send_choke_queued:
            self.send_choke_queued = False
            self.outqueue.append(tobinary(1) + CHOKE)
            self.upload.choke_sent()
            self.just_unchoked = 0
        q.extend(self.outqueue)
        self.outqueue = []
        q = ''.join(q)
        self.protocol.send_message_raw(q)
        return len(q)
    def handle_setup_reply(self, msg):
        """Handle a setup reply.  Send it to the appropriate PaymentStream, then check if they are all done"""
        log_msg("circ=%d:  PAR setup done." % (self.circ.id), 3, "par")
        #unpack the messages:
        forwardParVersion, msg = Basic.read_byte(msg)
        if forwardParVersion < self.parVersion:
            self.parVersion = forwardParVersion
        payStream, msg = self.get_payment_stream(msg)
        payStream.handle_setup_reply(forwardParVersion, msg)
        if self.all_setup_done():
            initialTokensDeferred = self.add_start_tokens()
            #this usually happens if the circuit is already closed, if not, an exception will already be logged
            if not initialTokensDeferred:
                self.circ.on_done()
                return

            def initial_tokens_added(result):
                self.circ.initialTokensAdded = True
                self._add_tokens_callback(
                    result, PaymentMessageHandler.START_READ_TOKENS,
                    PaymentMessageHandler.START_WRITE_TOKENS)
                return result

            initialTokensDeferred.addCallback(initial_tokens_added)
            initialTokensDeferred.addErrback(self.generic_error_handler)
            self.setupDone = True
            #send any payment requests that are waiting on the setup:
            reads = self.queuedReadTokens
            writes = self.queuedWriteTokens
            self.queuedReadTokens = 0
            self.queuedWriteTokens = 0
            if self.queuedReadTokens or self.queuedWriteTokens:
                self.send_payment_request(reads, writes)
            self.circ.on_par_ready()
Exemple #22
0
 def response(result):
     if result:
         read, write = result
         log_msg(
             "%s paid us %s for exit stream, now %d / %d" %
             (Basic.clean(self.baseCircuit.prevHexId[:4]),
              creditsEarned, read, write), 3, "par")
    def all_receipts_received(self, results, receiptAction, readTokens,
                              writeTokens, event):
        """Called when all receipts have been received by each PaymentStream
    Will add tokens locally and update inflight payments"""
        #this means that we must have timed out:
        if not results:
            log_msg("PAR timed out while waiting for receipts  :(", 0)
            #END_CIRC_REASON_TIMEOUT
            if not self.circ.is_done():
                self.circ.close(10)
            return
        #validate that all results were successful
        for resultTuple in results:
            if not resultTuple[0]:
                log_msg(
                    "One of the receipts had a problem, closing circuit:  %s" %
                    (str(resultTuple)), 0)
                #END_CIRC_REASON_REQUESTED
                if not self.circ.is_done():
                    self.circ.close(3)
                return
        #otherwise, cancel the timeout:
        if event and event.active():
            event.cancel()
        #just add our tokens:
        addTokensDeferred = self.add_tokens(readTokens, writeTokens)
        if not addTokensDeferred:
            return
        #and we're done!  :)
        def response(result):
            if result:
                receiptAction.callback(result)

        addTokensDeferred.addCallback(response)
        addTokensDeferred.addErrback(self.generic_error_handler)
Exemple #24
0
 def read_rangelist(self, file):
     l = []
     f = open(file, 'r')
     while True:
         line = f.readline()
         if not line:
             break
         line = line.strip()
         if not line or line[0] == '#':
             continue
         line = line.split(':')[-1]
         try:
             ip1,ip2 = line.split('-')
         except:
             ip1 = line
             ip2 = line
         try:
             ip1 = to_long_ipv4(ip1)
             ip2 = to_long_ipv4(ip2)
             assert ip1 <= ip2
         except:
             log_msg('*** WARNING *** could not parse IP range: '+line, 0)
         l.append((ip1,ip2))
     f.close()
     self._import_ipv4(l)
 def add_tokens(self, readTokens, writeTokens):
     if self.circ.is_done():
         log_msg("Not adding tokens because circuit (%s) is closed." %
                 (self.circ.id))
         return None
     return PaymentMessageHandler.PaymentMessageHandler.add_tokens(
         self, readTokens, writeTokens)
Exemple #26
0
 def attach(self, stream):
   """Attach a stream to this circuit.  Callers are responsible for handling failure to attach!
   @param:  the Stream to be attached
   @returns: True if it succeeded, False otherwise."""
   if stream.is_done():
     log_msg("Stream (%s) is already done, should not try to attach to Circuit (%s)." % (stream.id, self.id), 0)
     return False
   if self.is_done():
     log_msg("Circuit (%s) is already done, cannot attach Stream (%s)." % (self.id, stream.id), 0)
     return False
   if not self.app.is_tor_ready():
     log_msg("Cannot attach stream (%s) to circuit (%s) if Tor is not running!" % (stream.id, self.id), 0)
     return False
   #streams can only be attached if the circuit is built
   if self.status == "BUILT":
     def failure(error):
       log_ex(error, "Stream (%s) failed to attach to Circuit (%s)" % (stream.id, self.id), [TorCtl.ErrorReply])
       stream.ignoreCircuits.add(self)
     try:
       #try attaching the stream
       d = self.app.torApp.conn.attach_stream(stream.id, self.id)
       d.addErrback(failure)
       #and what streams are attached to us
       self.add_stream(stream)
       #mark this circuit as dirty if it is not already:
       if not self.dirtiedAt:
         self.dirtiedAt = time.time()
       log_msg("Added stream=%d to circ=%d" % (stream.id, self.id), 4, "stream")
     except TorCtl.ErrorReply, e:
       log_msg("Stream (%s) failed to attached to Circuit (%s): %s" % (stream.id, self.id, e), 1, "stream")
       stream.ignoreCircuits.add(self)
       return False
Exemple #27
0
 def dns_succeeded(address, testAddress=testAddress):
     log_msg(
         "DNS for %s successfully resolved to %s" % (testAddress, address),
         3)
     global _isDNSWorking
     _isDNSWorking = True
     return True
Exemple #28
0
 def start_connections(self, list):
     peers_added = 0
     #add to our current list except duplicates:       
     for peer in list:
         if self.to_connect.count(peer) == 0:
             if self.prev_connected.count(peer) == 0:
                 self.never_connected.append(peer)
                 peers_added += 1
             else:
                 self.to_connect.append(peer)
                 peers_added += 1
     log_msg("Added %s to our list of peers, now %s long." % (peers_added, len(self.to_connect)), 2, "tracker")
     
     #without this, the peers would be each get connected to twice on the very first update if they fail
     if self.lastPeerCycleTime == 0:
       self.lastPeerCycleTime = time.time()
     
     #for testing:  sometimes handy to print out peers so I can make sure we can connect to them later
     #f = open("peer_list.txt", "wb")
     #for x in list:
     #  dns, id, encrypted = x
     #  #log_msg("%s %s (%s)" % (encrypted, dns, id))
     #  f.write("%s:%s\n" % (dns[0], dns[1]))
     #f.close()
     #make sure we're starting connections from that list:
     if not self.startConnectionsEvent:
       self.startConnectionsEvent = Scheduler.schedule_repeat(1.0, self._start_connection_from_queue)
       self._start_connection_from_queue()
Exemple #29
0
 def error(failure):
     if issubclass(type(failure.value), TorCtl.ErrorReply):
         log_msg(
             "Failed to get address from Tor, probably asking too early.  Oh well."
         )
     else:
         log_ex(failure, "Unhandled exception in get_external_ip")
Exemple #30
0
 def read_fieldlist(
         self, file
 ):  # reads a list from a file in the format 'ip/len <whatever>'
     f = open(file, 'r')
     while True:
         line = f.readline()
         if not line:
             break
         line = line.strip().expandtabs()
         if not line or line[0] == '#':
             continue
         try:
             line, garbage = line.split(' ', 1)
         except:
             pass
         try:
             line, garbage = line.split('#', 1)
         except:
             pass
         try:
             ip, depth = line.split('/')
         except:
             ip = line
             depth = None
         try:
             if depth is not None:
                 depth = int(depth)
             self._append(ip, depth)
         except Exception, e:
             log_msg('*** WARNING *** could not parse IP range: ' + line, 0)
Exemple #31
0
 def set_trackers(self, infohash, trackerList):
     if infohash not in self.downloads:
         log_msg(
             "Cannot set trackers for %s--not downloading that torrent" %
             (str(infohash).encode("hex")), 0)
         return
     self.downloads[infohash].rerequest.set_trackers(trackerList)
Exemple #32
0
 def set_start_on_boot(self, newVal):
   """Change the registry key (if necessary) for auto launching BitBlinder at startup on windows, does nothing on *nix.
   Ends up calling a function made with NSIS that will get the necessary permissions to do the modification
   @param newVal:  whether to start on boot or not
   @type  newVal:  bool"""
   if not System.IS_WINDOWS:
     return
   #No need to change if the value is already correct?
   if self.check_start_on_boot() == newVal:
     if self.startOnBootDeferred:
       log_msg("Failed to modify 'start at bootup' value, already editing the registry!", 0)
     return
   if self.startOnBootDeferred:
     return
   def uac_done(result):
     self.startOnBootDeferred = None
     if result != True:
       log_ex(result, "Bad result while running BitBlinderSettingsUpdate.exe")
   #launch the program:
   if newVal:
     args = " --add-startup=" + ClientUtil.get_launch_command()
   else:
     args = " --remove-startup"
     
   encodedExe = System.encode_for_filesystem(os.path.join(Globals.WINDOWS_BIN, "BitBlinderSettingsUpdate.exe"))
   self.startOnBootDeferred = SerialProcessLauncher.get().run_app(encodedExe + "  /S" + args)
   self.startOnBootDeferred.addCallback(uac_done)
   self.startOnBootDeferred.addErrback(uac_done)
Exemple #33
0
 def died(self, hash):
     if hash in self.torrent_cache:
         log_msg(
             'DIED: "' + Basic.clean(self.torrent_cache[hash]['path']) +
             '"', 1)
     else:
         log_msg('DIED: "' + Basic.clean(hash) + '"', 1)
Exemple #34
0
 def _on_bank_ready(self, result):
   """Called when the bank has finished starting.  Alerts the applications to any
   startup arguments that were passed in, which will likely cause them to actually start."""
   if result != True:
     log_msg("Bank failed to start correctly!", 0)
     return result
     
   #handle the starting arguments:
   Startup.handle_args(ProgramState.STARTING_DIR, sys.argv[1:])
   GlobalEvents.throw_event("startup")
   
   #if this is the first run, save all the settings files:
   if self.bbApp.isFirstRun:
     for app in [self.bbApp, self.btApp, self.torApp, self.ffApp]:
       if app:
         app.settings.save()
   self.coreSettings.save()
    
   #schedule update function:
   def do_update():
     BWHistory.update_all()
     return True
   ProgramState.DO_UPDATES = True
   self.updateEvent = Scheduler.schedule_repeat(Globals.INTERVAL_BETWEEN_UPDATES, do_update)
   return result
Exemple #35
0
 def stringReceived(self, data):
   self.responseReceived = True
   self.factory.gotResponse = True
   data = self.factory.bank.decrypt_message(data)
   log_msg("ACoin DEPOSIT response received.", 4)
   (newBalance, interval, expiresCurrent, expiresNext), returnSlip = Basic.read_message('!IIII', data)
   self.factory.bank.on_new_info(newBalance, interval, expiresCurrent, expiresNext)
   returnSlip = list(struct.unpack('c'*len(self.factory.coins), returnSlip))
   for i in range(0, len(self.factory.coins)):
     coin = self.factory.coins[i]
     status = returnSlip[i]
     gotAcceptableResponse = True
     badACoin = True
     if status == "0":
       badACoin = False
     elif status == "3":
       log_msg("ACoin deposit failed.  Some node must have double-spent.", 1)
     elif status == "2":
       log_msg("ACoin deposit failed.  You apparently already sent this acoin.", 1)
     elif status == "1":
       log_msg("ACoin deposit failed.  ACoin was not valid?  %s" % (repr(coin.write_binary())), 0)
     else:
       log_msg("Bank returned unknown status message:  %s" % (status), 0)
       gotAcceptableResponse = False
     if badACoin:
       #close the circuit, they're trying to cheat us!
       if coin.originCircuit:
         coin.originCircuit.close()
   self.transport.loseConnection()
Exemple #36
0
 def read_fieldlist(self, file):   # reads a list from a file in the format 'ip/len <whatever>'
     f = open(file, 'r')
     while True:
         line = f.readline()
         if not line:
             break
         line = line.strip().expandtabs()
         if not line or line[0] == '#':
             continue
         try:
             line, garbage = line.split(' ',1)
         except:
             pass
         try:
             line, garbage = line.split('#',1)
         except:
             pass
         try:
             ip, depth = line.split('/')
         except:
             ip = line
             depth = None
         try:
             if depth is not None:                
                 depth = int(depth)
             self._append(ip,depth)
         except Exception, e:
             log_msg('*** WARNING *** could not parse IP range: '+line, 0)
 def stringReceived(self, encryptedMsg):
   self.responseReceived = True
   self.transport.loseConnection()
   blob = self.factory.bank.decrypt_message(encryptedMsg)
   log_msg("ACoin REQUEST response received.", 4)
   responseCode, blob = Basic.read_byte(blob)
   #we had enough credits in our account
   if responseCode == 0:
     (newBalance, number), coins = Basic.read_message('!II', blob)
     #update the balance
     self.factory.bank.on_new_balance_from_bank(newBalance)
     acoinStrFormat = "%ss" % (Globals.ACOIN_KEY_BYTES)
     format = '!' + (acoinStrFormat * number)
     sigs = list(struct.unpack(format, coins))
     while len(self.factory.requests) > 0:
       request = self.factory.requests.pop(0)
       sig = sigs.pop(0)
       coin = BankMessages.parse_acoin_response(self.factory.bank, sig, request, ProgramState.DEBUG)
       if coin:
         self.factory.bank.add_acoin(coin)
       else:
         log_msg("Got an invalid ACoin from the bank!?", 3)
   #the bank could not check out the coins because our account doesn't have enough credits!
   else:
     (newBalance,), blob = Basic.read_message('!I', blob)
     self.factory.bank.on_new_balance_from_bank(newBalance)
 def all_receipts_received(self, results, receiptAction, readTokens, writeTokens, event):
   """Called when all receipts have been received by each PaymentStream
   Will add tokens locally and update inflight payments"""
   #this means that we must have timed out:
   if not results:
     log_msg("PAR timed out while waiting for receipts  :(", 0)
     #END_CIRC_REASON_TIMEOUT
     if not self.circ.is_done():
       self.circ.close(10)
     return
   #validate that all results were successful
   for resultTuple in results:
     if not resultTuple[0]:
       log_msg("One of the receipts had a problem, closing circuit:  %s" % (str(resultTuple)), 0)
       #END_CIRC_REASON_REQUESTED
       if not self.circ.is_done():
         self.circ.close(3)
       return
   #otherwise, cancel the timeout:
   if event and event.active():
     event.cancel()
   #just add our tokens:
   addTokensDeferred = self.add_tokens(readTokens, writeTokens)
   if not addTokensDeferred:
     return
   #and we're done!  :)
   def response(result):
     if result:
       receiptAction.callback(result)
   addTokensDeferred.addCallback(response)
   addTokensDeferred.addErrback(self.generic_error_handler)
Exemple #39
0
  def _update_events(self):
    earliestTime = get_current_gmtime()
    curTime = time.time()
    
    for logTypeName, remoteFolder in self.serverList.iteritems():
      try:
        log_msg("Updating logs from %s..." % (logTypeName))
        dataDir = os.path.join(self.baseDataDir, logTypeName)
        if not os.path.exists(dataDir):
          os.makedirs(dataDir)

        #get the changes from the remote server:
        os.system('rsync --append -rtz -e "ssh -i %s" %s/ %s' % (IDENTITY, remoteFolder, dataDir))
        
        #for each file in the folder
        fileNames = glob.glob(dataDir + "/*")
        for fileName in fileNames:
          baseFileName = os.path.split(fileName)[1]
          
          #ignore really old files:
          if self._file_is_old(fileName, curTime):
            self._remove_file(fileName, baseFileName, logTypeName)
            continue
          
          #look up the database row
          results = self._get_file_row(baseFileName, logTypeName)
          
          #if the row existed, figure out if it is old enough to be deleted
          if len(results) > 0:
            assert len(results) == 1, "Why are there two rows for %s and %s?" % (baseFileName, logTypeName)
            numEvents, lastMTimeString = results[0]
            rowExisted = True
            if not self._file_was_modified(fileName, lastMTimeString):
              #don't bother continuing to parse the file if it hasnt been modified
              continue
          #otherwise, just note that we've obviously never parsed any events from this file
          else:
            numEvents = 0
            rowExisted = False
            
          #load all lines
          cur = self.conn.cursor()
          try:
            startTime, newNumEvents = EventLogging.parse_events(cur, fileName, numEvents)
            if startTime < earliestTime:
              earliestTime = startTime
            log_msg("Parsed %s events" % (newNumEvents-numEvents))
          #if any line fails, abort everything and log the failure
          except Exception, error:
            self._log_failure(error, "Failure (%s) while processing line from %s" % (error, fileName))
          #otherwise update the file row in the database to note that we've successfully parsed newNumEvents events
          else:
            newMTimeString = str(os.path.getmtime(fileName))
            if rowExisted:
              self._update_file_row(cur, baseFileName, logTypeName, newNumEvents, newMTimeString)
            else:
              self._insert_file_row(cur, baseFileName, logTypeName, newNumEvents, newMTimeString)
          finally:
            cur.close()
            self.conn.commit()
Exemple #40
0
 def datagramReceived(self, datagram, address):
     if self.finished:
         return
     try:
         self.read_reply(datagram, address[0])
     except EchoMixin.BadEchoMessageFormat, e:
         log_msg("Got a bad UDP message (%s) while testing ports:  %s" % (e, repr(datagram)), 4)
Exemple #41
0
 def set_value(self, val):
     val = unicode(val)
     if not Files.file_exists(val):
         try:
             os.makedirs(val)
         except Exception, error:
             log_msg("Could not make a dir: %s" % (error), 0)
Exemple #42
0
 def connection_lost(self, protocol):
     c = self.connections[protocol]
     log_msg('%s connection closed' % (c.ccount), 3, "btprotocol")
     del self.connections[protocol]
     if c.download:
         c.download.disconnected()
     self.choker.connection_lost(c)
Exemple #43
0
 def message_arrived(self, msg):
     """Called when a payment message is received via the controller.
 Is responsible for piecing it back together into the actual message.
 @param msg:  the data received from Tor
 @type  msg:  str"""
     self.buffer += msg
     # is the whole message here?
     msgLen, msgData = Basic.read_short(self.buffer)
     if len(msgData) >= msgLen:
         msgData = msgData[:msgLen]
         # we just discard the rest of the cell, two messages are never packed in the same cell currently
         self.buffer = ""
         # what type of message is this?
         msgType, msgData = Basic.read_byte(msgData)
         # ok, now handle that message:
         for msgName in MESSAGE_CODES.keys():
             if msgType == MESSAGE_CODES[msgName]:
                 # if we don't know how to handle this message, just close the circuit
                 if msgName not in self.messageHandlers:
                     log_msg("Remote request for %s, which we do not know how to handle" % (msgName), 1)
                     self.close()
                     return
                 # get the handler:
                 handler = self.messageHandlers[msgName]
                 # get the handler function:
                 funcName = "handle_%s" % (msgName)
                 if not hasattr(handler, funcName):
                     raise Exception("%s cannot handle %s payment message?" % (handler, msgName))
                 f = getattr(handler, funcName)
                 f(msgData)
                 return
         # uhh, not sure how to handle this message:
         raise Exception("Unknown message type for payment message:  %s" % (msgType))
Exemple #44
0
 def _make_monies_display(self):
     #need to know our width before we can fit
     maxLen = 0
     for key, stat in self.statistics.iteritems():
         #note, this implicitly sets the pretty text
         statLen = len(stat)
         if statLen > maxLen:
             maxLen = statLen
     totalWidth = maxLen + 15 + 1
     r, c = self._get_screen_size()
     #will it fit in the top right corner (width is variable, though the rows shouldn't change)
     if r > self.moniesDisplay[0]  and \
        c > totalWidth + self.statusDisplay[1] + 1:
         startY = 0
         startX = c - totalWidth - 1
         win = self.stdscr.derwin(self.moniesDisplay[0], totalWidth + 1,
                                  startY, startX)
         win.clear()
         #win.border()
         win.addstr(0, 0, "%sCredits" % ((totalWidth - 7) * " "),
                    curses.A_BOLD)
         row = 2
         rowSep = 2
         col = 0
         #dump things into the window! (should we sort them first?)
         for key, value in self.statistics.iteritems():
             win.addstr(row, col, value.justify_right(totalWidth))
             row += rowSep
         win.refresh()
     else:
         log_msg(
             'There was not enough screen space (%s, %s) for the credits display (%s, %s)'
             % (r, c, self.moniesDisplay[0], totalWidth), 4)
     return
Exemple #45
0
 def find_and_bind(self,
                   minport,
                   maxport,
                   bind='',
                   reuse=False,
                   ipv6_socket_style=1,
                   upnp=0,
                   randomizer=False):
     self.factory = IncomingBTFactory()
     e = 'maxport less than minport - no ports to check'
     if maxport - minport < 50 or not randomizer:
         portrange = range(minport, maxport + 1)
         if randomizer:
             shuffle(portrange)
             portrange = portrange[:20]  # check a maximum of 20 ports
     else:
         portrange = []
         while len(portrange) < 20:
             listen_port = randrange(minport, maxport + 1)
             if not listen_port in portrange:
                 portrange.append(listen_port)
     for listen_port in portrange:
         try:
             self.bind(listen_port,
                       bind,
                       ipv6_socket_style=ipv6_socket_style,
                       upnp=upnp)
             return listen_port
         except CannotListenError, e:
             log_msg(
                 "Could not bind %s to listen for BT server" %
                 (listen_port), 3)
             pass
Exemple #46
0
 def failure(error):
     if error and hasattr(error, "value") and issubclass(
             type(error.value), TimeoutError):
         #TODO:  this indicates that the bank is down, or something is wrong with their network?
         log_msg("Relayed payment timed out  :(", 0, "par")
     else:
         log_ex(error, "Relaying payment message failed!")
Exemple #47
0
 def deposit_cb(self, widget, event=None):
     """Attempts to deposit all coins- for debugging only"""
     coins = Bank.get().get_acoins(Bank.get().get_wallet_balance())
     if not coins:
         log_msg("No ACoins left!")
         return
     Bank.get().deposit_acoins(coins)
Exemple #48
0
 def on_update(self):
   """Called every INTERVAL_BETWEEN_UPDATES to update the various information"""
   if not self.is_running():
     return
   #TODO:  this is a really arbitrary way of keeping things up to date...
   #keep the list of circuits and streams reasonable:
   #if there are more than 30 streams/circuits, we remove those that have been done for a minute::
   toDelete = []
   if len(self.streams) > 30:
     for streamId, obj in self.streams.iteritems():
       if obj.is_done():
         age = time.time() - obj.endedAt
         if age > 60:
           toDelete.append(streamId)
           log_msg("Removing stream=%d from the list because it is old and closed" % (streamId), 4, "circuit")
   for streamId in toDelete:
     del self.streams[streamId]
   toDelete = []
   if len(self.circuits) > 30:
     for obj in self.circuits:
       if obj.is_done():
         age = time.time() - obj.endedAt
         if age > 60:
           toDelete.append(obj)
           log_msg("Removing circuit=%d from the list because it is old and closed" % (obj.id), 4, "stream")
   for circ in toDelete:
     self.circuits.remove(circ)
Exemple #49
0
 def create_circuit(self, path, ignoreLogin=False):
     """Create a new Circuit for this Application that will travel over path.
 @param path:  the path that the circuit will follow when fully constructed
 @type path:   a list of Routers
 @return:  the newly created circuit, or None if we cannot create a Circuit right now."""
     #can only create circuits if we are logged in:
     if not self.bankApp.is_ready() and not ignoreLogin:
         log_msg("Not creating the circuit because we arent logged in yet!",
                 1, "circuit")
         return None
     if not self.torApp.is_running(
     ) or not self.torApp.conn or self.torApp.conn._closed:
         log_msg("Not creating the circuit because Tor is not ready", 0,
                 "circuit")
         return None
     #create the new circuit
     ids = []
     circ = None
     for relay in path:
         ids.append(relay.desc.idhex)
     circ = Circuit.Circuit(None, self, -1, path)
     #add to list of circuits
     self.circuits.add(circ)
     #add to list of live circuits:
     self.liveCircuits.add(circ)
     #tell tor to make the circuit
     torDeferred = self.torApp.conn.extend_circuit(0, ids)
     torDeferred.addCallback(self._on_circuit_creation_success, circ)
     torDeferred.addErrback(self._on_circuit_creation_failure, circ)
     return circ
Exemple #50
0
def get_default_gateway():
    #TODO:  execing route print is probably a better idea here
    try:
        strComputer = "."
        objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        objSWbemServices = objWMIService.ConnectServer(strComputer,
                                                       "root\cimv2")
        colItems = objSWbemServices.ExecQuery(
            "Select * from Win32_NetworkAdapterConfiguration")
        gateways = []
        for objItem in colItems:
            z = objItem.DefaultIPGateway
            if z:
                for x in z:
                    gateways.append(x)
        if len(gateways) > 1:
            log_msg(
                "Why are there multiple gateways?  :(  %s" %
                (Basic.clean(gateways)), 2)
        elif len(gateways) == 0:
            return None
        return gateways.pop(0)
    except Exception, e:
        log_ex(e, "Failed to get default gateway")
        return "192.168.1.1"
Exemple #51
0
 def on_response(self, dialog, response_id):
     if (response_id == gtk.RESPONSE_YES):
         self.cb(self.newVersion)
     else:
         log_msg("User elected not to update.", 4)
     GUIController.get().updateDialog = None
     self.dia.destroy()
Exemple #52
0
 def error(failure):
   if not self.is_done():
     if Basic.exception_is_a(failure, [TorCtl.TorCtlClosed, TorCtl.ErrorReply]):
       log_msg("Failed to create PAR client, closing", 1, "circuit")
     else:
       log_ex(failure, "Unexpected failure while starting circuit")
     self.on_done()
Exemple #53
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)
Exemple #54
0
 def _load_private_key(self):
     """Load (and generate if necessary) the Tor public and private keys"""
     log_msg("Loading private key...", 3)
     try:
         torKey = os.path.join(Globals.USER_DATA_DIR, "tor_data", "keys",
                               "secret_id_key")
         if not Files.file_exists(torKey):
             #have to create it ourselves.  First make the folders if necessary:
             keyFolder = os.path.join(Globals.USER_DATA_DIR, "tor_data",
                                      "keys")
             if not Files.file_exists(keyFolder):
                 os.makedirs(keyFolder)
             #then generate the key
             Globals.PRIVATE_KEY = PrivateKey.PrivateKey(1024)
             #and save it in the appropriate format
             if not Globals.PRIVATE_KEY.key.save_key(torKey, cipher=None):
                 raise Exception("Failed to save key as PEM!")
         else:
             Globals.PRIVATE_KEY = PrivateKey.PrivateKey(torKey)
         Globals.PUBLIC_KEY = Globals.PRIVATE_KEY.publickey()
         Globals.FINGERPRINT = TorUtils.fingerprint(Globals.PRIVATE_KEY.n,
                                                    Globals.PRIVATE_KEY.e)
         log_msg("Globals.FINGERPRINT = %s" % (Globals.FINGERPRINT), 3)
     except Exception, error:
         log_ex(error, "Failed while loading private key data")
Exemple #55
0
 def deposit_cb(self, widget, event=None):
   """Attempts to deposit all coins- for debugging only"""
   coins = Bank.get().get_acoins(Bank.get().get_wallet_balance())
   if not coins:
     log_msg("No ACoins left!")
     return
   Bank.get().deposit_acoins(coins)
Exemple #56
0
    def cleanup(self):
        """Make sure the reactor, threads, etc have been stopped.  Also removes
    the file that indicates we shutdown cleanly."""

        #shutdown Twisted
        if ProgramState.USE_GTK:
            Globals.reactor.stop()
            Globals.reactor.runUntilCurrent()

        #ensure that all threads have closed:
        remainingThreads = threading.enumerate()
        for thread in remainingThreads:
            if threading._MainThread != type(thread):
                log_msg(
                    "Thread has not finished by the end of the program: %s" %
                    (thread), 1)

        #start the update if necessary:
        if Updater.get().APPLY_UPDATE:
            ClientUtil.apply_update()

        #NOTE:  we intentionally leave the log files open so that errors can get written to them...
        log_msg("Thanks for using BitBlinder", 2)
        ErrorReporting.destroy_marker_file()

        #NOTE:  this is here so that threads can finish properly.  I was getting errors from leftover threads without it.
        #However, I'm pretty sure that it was just from the IDE
        time.sleep(0.2)
Exemple #57
0
 def reply(self, msg):
   """returns string msg to client"""
   msg = str(msg)
   self.sendString(msg)
   log_msg('msg returned to client',  3)
   self.drop_connection()
   return