Exemple #1
0
 def test_datetime_to_unix(self):
     self.assertEqual(
         1344251971.0,
         datetime_to_unix(datetime.datetime(2012, 8, 6, 11, 19, 31)))
     self.assertEqual(
         1515894416.0,
         datetime_to_unix(datetime.datetime(2018, 1, 14, 1, 46, 56)))
     self.assertTrue(
         (time.time() - datetime_to_unix(datetime.datetime.utcnow())) < 2)
Exemple #2
0
    def pack(self, link_protocol):
        payload = bytearray()
        payload += Size.LONG.pack(int(datetime_to_unix(self.timestamp)))
        payload += self.receiver_address.pack()
        payload += Size.CHAR.pack(len(self.sender_addresses))

        for addr in self.sender_addresses:
            payload += addr.pack()

        return NetinfoCell._pack(link_protocol, bytes(payload))
Exemple #3
0
    def pack(self,
             link_protocol: 'stem.client.datatype.LinkProtocol') -> bytes:
        payload = bytearray()
        payload += Size.LONG.pack(int(datetime_to_unix(self.timestamp)))
        payload += self.receiver_address.pack()
        payload += Size.CHAR.pack(len(self.sender_addresses))

        for addr in self.sender_addresses:
            payload += addr.pack()

        return NetinfoCell._pack(link_protocol, bytes(payload), self.unused)
Exemple #4
0
    def line(fingerprint, line_type):
      address, port, nickname, locale = '0.0.0.0', 0, None, None
      consensus_tracker = nyx.tracker.get_consensus_tracker()

      if fingerprint is not None:
        address, port = consensus_tracker.get_relay_address(fingerprint, ('192.168.0.1', 0))
        nickname = consensus_tracker.get_relay_nickname(fingerprint)
        locale = tor_controller().get_info('ip-to-country/%s' % address, None)

      connection = nyx.tracker.Connection(datetime_to_unix(self._circuit.created), False, '127.0.0.1', 0, address, port, 'tcp', False)
      return Line(self, line_type, connection, self._circuit, fingerprint, nickname, locale)
Exemple #5
0
    def line(fingerprint, line_type):
      address, port, nickname = '0.0.0.0', 0, None
      consensus_tracker = nyx.tracker.get_consensus_tracker()

      if fingerprint is not None:
        address, port = consensus_tracker.get_relay_address(fingerprint, ('192.168.0.1', 0))
        nickname = consensus_tracker.get_relay_nickname(fingerprint)

      locale = tor_controller().get_info('ip-to-country/%s' % address, None)
      connection = nyx.tracker.Connection(datetime_to_unix(self._circuit.created), False, '127.0.0.1', 0, address, port, 'tcp', False)
      return Line(self, line_type, connection, self._circuit, fingerprint, nickname, locale)
Exemple #6
0
 def test_datetime_to_unix(self):
   self.assertEqual(1344251971.0, datetime_to_unix(datetime.datetime(2012, 8, 6, 11, 19, 31)))
   self.assertTrue((time.time() - datetime_to_unix(datetime.datetime.utcnow())) < 2)
Exemple #7
0
def main():
    last_notified_config = conf.get_config('last_notified')
    last_notified_path = util.get_path('data',
                                       'fingerprint_change_last_notified.cfg')

    if os.path.exists(last_notified_path):
        last_notified_config.load(last_notified_path)
    else:
        last_notified_config._path = last_notified_path

    fingerprint_changes = load_fingerprint_changes()
    downloader = DescriptorDownloader(timeout=15)
    alarm_for = {}

    for relay in downloader.get_consensus():
        prior_fingerprints = fingerprint_changes.setdefault(
            (relay.address, relay.or_port), {})

        if relay.fingerprint not in prior_fingerprints:
            log.debug("Registering a new fingerprint for %s:%s (%s)" %
                      (relay.address, relay.or_port, relay.fingerprint))
            prior_fingerprints[relay.fingerprint] = datetime_to_unix(
                relay.published)

            # drop fingerprint changes that are over thirty days old

            old_fingerprints = [
                fp for fp in prior_fingerprints
                if (time.time() - prior_fingerprints[fp] > TEN_DAYS)
            ]

            for fp in old_fingerprints:
                log.debug(
                    "Removing fingerprint for %s:%s (%s) which was published %i days ago"
                    % (relay.address, relay.or_port, fp,
                       prior_fingerprints[fp] / 60 / 60 / 24))
                del prior_fingerprints[fp]

            # if we've changed more than ten times in the last ten days then alarm

            if len(prior_fingerprints) >= 10:
                alarm_for['%s:%s' %
                          (relay.address, relay.or_port)] = (relay.address,
                                                             relay.or_port,
                                                             relay.fingerprint)

    if alarm_for and not is_notification_suppressed(alarm_for.values()):
        log.debug("Sending a notification for %i relays..." % len(alarm_for))
        body = EMAIL_BODY

        for address, or_port, fingerprint in alarm_for.values():
            try:
                desc = downloader.get_server_descriptors(fingerprint).run()[0]
            except:
                desc = None  # might not be available, just used for extra info

            fp_changes = fingerprint_changes[(address, or_port)]
            log.debug("* %s:%s has had %i fingerprints: %s" %
                      (address, or_port, len(fp_changes), ', '.join(
                          fp_changes.keys())))

            if desc:
                body += "* %s:%s (platform: %s, contact: %s)\n" % (
                    address, or_port, desc.platform.decode(
                        'utf-8', 'replace'), desc.contact)
            else:
                body += "* %s:%s\n" % (address, or_port)

            count = 0

            for fingerprint in sorted(fp_changes,
                                      reverse=True,
                                      key=lambda k: fp_changes[k]):
                body += "  %s at %s\n" % (
                    fingerprint,
                    datetime.datetime.fromtimestamp(
                        fp_changes[fingerprint]).strftime('%Y-%m-%d %H:%M:%S'))
                count += 1

                # Relays frequently cycling their fringerprint can have thousands of
                # entries. Enumerating them all is unimportant, so if too long then
                # just give the count.

                if count > 8:
                    oldest_timestamp = sorted(fp_changes.values())[0]
                    body += "  ... and %i more since %s\n" % (
                        len(fp_changes) - 8,
                        datetime.datetime.fromtimestamp(
                            oldest_timestamp).strftime('%Y-%m-%d %H:%M:%S'))
                    break

            body += "\n"

        subject = EMAIL_SUBJECT

        if len(alarm_for) == 1:
            subject += ' (%s:%s)' % alarm_for.values()[0][:2]

        util.send(subject,
                  body=body,
                  to=[
                      '*****@*****.**',
                      '*****@*****.**'
                  ])

        # register that we've notified for these

        current_time = str(int(time.time()))

        for address, or_port, _ in alarm_for.values():
            last_notified_config.set('%s:%s' % (address, or_port),
                                     current_time)

        last_notified_config.save()

    save_fingerprint_changes(fingerprint_changes)