aboutsummaryrefslogtreecommitdiff
path: root/.gitignore
AgeCommit message (Expand)Author
2015-04-23Integrate backtrace test into the automake test suite.cypherpunks
2015-04-23Integrate ntor test into the automake test suite.cypherpunks
2015-04-23Integrate zero_length_keys test into the automake test suite.cypherpunks
2015-04-01Drop support for --digestsNick Mathewson
2015-03-24Merge remote-tracking branch 'dgoulet/bug15377_027_01'Nick Mathewson
2015-03-24Test: add missing libor.a in include.amDavid Goulet
2015-03-22build tor-cov-{resolve,gencert}Sebastian Hahn
2015-03-14add newly generated files to .gitignoreNick Mathewson
2015-01-23Split the slow unit tests into their own binaryNick Mathewson
2015-01-14Rename bench_workqueue -> test_workqueue and make it a unit test.Nick Mathewson
2014-09-25Merge branch 'ed25519_ref10_squashed'Nick Mathewson
2014-09-25Add Ed25519 support, wrappers, and tests.Nick Mathewson
2014-09-25Merge branch 'libscrypt_trunnel_squashed'Nick Mathewson
2014-09-25Use trunnel for crypto_pwbox encoding/decoding.Nick Mathewson
2014-09-16Ignore coverage_html/Arlo Breault
2014-09-10Merge remote-tracking branch 'public/torrc_minimal'Nick Mathewson
2014-09-08Add cscope generated files to .gitignore.Nick Mathewson
2014-09-02Divide torrc.sample into torrc.sample and torrc.minimalNick Mathewson
2014-04-30More .gitignore tweaks; goodbye latex; hello trsNick Mathewson
2014-04-30Update .gitignore for doc, contrib changesNick Mathewson
2014-04-28Deal with the aftermath of sorting contribNick Mathewson
2013-11-18Merge branch 'backtrace_squashed'Nick Mathewson
2013-11-18Tests for backtrace.cNick Mathewson
2013-09-29Don't preprocess torifyguilhem
2013-07-10Coverage support: build with --enable-coverage to have tests run with gcovNick Mathewson
2013-07-10Start work on fancy compiler tricks to expose extra stuff to our testsNick Mathewson
2013-01-16Add a new automake dropping ("test-driver") to .gitignoreNick Mathewson
2013-01-03Add new ntor bits to gitignoreNick Mathewson
2012-08-27Update .gitignore with new autotools droppings from nonrecursive makeNick Mathewson
2012-05-14Add some MSVC stuff to gitignoreNick Mathewson
2011-11-11New src/test/bench.c to allow us to actually _run_ benchmark codeNick Mathewson
2011-07-21Add src/test/test{-child}.exe to gitignore. bug3626Nick Mathewson
2010-11-11Merge remote branch 'origin/maint-0.2.2'Nick Mathewson
2010-11-10Remove everything related to os x expert packageSebastian Hahn
2010-10-10Add a unit test for tor_spawn_backgroundSteven Murdoch
2010-09-30Add more tor-fw-helper files to gitignoreSebastian Hahn
2010-09-30Add 'compile' to .gitignoreNick Mathewson
2010-09-30First implementation of tor-fw-helper.Jacob Appelbaum
2010-02-25add .exe files to gitignoreNick Mathewson
2010-01-31add a2x intermediate files to gitignoreNick Mathewson
2010-01-28Fix building the tarballSebastian Hahn
2010-01-27Convert the Tor manpage to asciidoc.Sebastian Hahn
2010-01-27Convert the tor-resolve manpage to asciidocSebastian Hahn
2010-01-27Convert the torify manpage to asciidocSebastian Hahn
2010-01-27Convert the tor-gencert manpage to asciidocSebastian Hahn
2009-09-23Move testing code into new src/test directory.Nick Mathewson
2009-09-21Build debian's micro-revision into the binaryPeter Palfrader
2009-06-12Update Tor to use Libevent 2.0 APIs when available.Nick Mathewson
2009-05-27Merge commit 'origin/maint-0.2.1'Nick Mathewson
2009-05-27Add *.swp to .gitignore as vim's editor dropping.Nick Mathewson
ral.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/usr/bin/python
# Copyright 2005-2006 Nick Mathewson
# See the LICENSE file in the Tor distribution for licensing information.

# Requires Python 2.2 or later.

"""
 exitlist -- Given a Tor directory on stdin, lists the Tor servers
 that accept connections to given addreses.

 example usage (Tor 0.2.0.7-alpha and earlier):

    cat ~/.tor/cached-routers* | python exitlist 18.244.0.188:80

 example usage (Tor 0.2.0.8-alpha and later):

    cat ~/.tor/cached-descriptors* | python exitlist 18.244.0.188:80

 You should look at the "FetchUselessDescriptors" config option in the
 man page. For 0.2.0.13-alpha and later, also look at the
 "FetchDirInfoEarly" config option.

 Note that this script won't give you a perfect list of IP addresses
 that might connect to you using Tor, since some Tor servers might exit
 from other addresses than the one they publish. See
 https://check.torproject.org/ for an alternative (more
 accurate!) approach.

"""

#
# Change this to True if you want more verbose output.  By default, we
# only print the IPs of the servers that accept any the listed
# addresses, one per line.
#
VERBOSE = False

#
# Change this to True if you want to reverse the output, and list the
# servers that accept *none* of the listed addresses.
#
INVERSE = False

#
# Change this list to contain all of the target services you are interested
# in.  It must contain one entry per line, each consisting of an IPv4 address,
# a colon, and a port number. This default is only used if we don't learn
# about any addresses from the command-line.
#
ADDRESSES_OF_INTEREST = """
    1.2.3.4:80
"""


#
# YOU DO NOT NEED TO EDIT AFTER THIS POINT.
#

import sys
import re
import getopt
import socket
import struct
import time

assert sys.version_info >= (2,2)


def maskIP(ip,mask):
    return "".join([chr(ord(a) & ord(b)) for a,b in zip(ip,mask)])

def maskFromLong(lng):
    return struct.pack("!L", lng)

def maskByBits(n):
    return maskFromLong(0xffffffffl ^ ((1L<<(32-n))-1))

class Pattern:
    """
    >>> import socket
    >>> ip1 = socket.inet_aton("192.169.64.11")
    >>> ip2 = socket.inet_aton("192.168.64.11")
    >>> ip3 = socket.inet_aton("18.244.0.188")

    >>> print Pattern.parse("18.244.0.188")
    18.244.0.188/255.255.255.255:1-65535
    >>> print Pattern.parse("18.244.0.188/16:*")
    18.244.0.0/255.255.0.0:1-65535
    >>> print Pattern.parse("18.244.0.188/2.2.2.2:80")
    2.0.0.0/2.2.2.2:80-80
    >>> print Pattern.parse("192.168.0.1/255.255.00.0:22-25")
    192.168.0.0/255.255.0.0:22-25
    >>> p1 = Pattern.parse("192.168.0.1/255.255.00.0:22-25")
    >>> import socket
    >>> p1.appliesTo(ip1, 22)
    False
    >>> p1.appliesTo(ip2, 22)
    True
    >>> p1.appliesTo(ip2, 25)
    True
    >>> p1.appliesTo(ip2, 26)
    False
    """
    def __init__(self, ip, mask, portMin, portMax):
        self.ip = maskIP(ip,mask)
        self.mask = mask
        self.portMin = portMin
        self.portMax = portMax

    def __str__(self):
        return "%s/%s:%s-%s"%(socket.inet_ntoa(self.ip),
                              socket.inet_ntoa(self.mask),
                              self.portMin,
                              self.portMax)

    def parse(s):
        if ":" in s:
            addrspec, portspec = s.split(":",1)
        else:
            addrspec, portspec = s, "*"

        if addrspec == '*':
            ip,mask = "\x00\x00\x00\x00","\x00\x00\x00\x00"
        elif '/' not in addrspec:
            ip = socket.inet_aton(addrspec)
            mask = "\xff\xff\xff\xff"
        else:
            ip,mask = addrspec.split("/",1)
            ip = socket.inet_aton(ip)
            if "." in mask:
                mask = socket.inet_aton(mask)
            else:
                mask = maskByBits(int(mask))

        if portspec == '*':
            portMin = 1
            portMax = 65535
        elif '-' not in portspec:
            portMin = portMax = int(portspec)
        else:
            portMin, portMax = map(int,portspec.split("-",1))

        return Pattern(ip,mask,portMin,portMax)

    parse = staticmethod(parse)

    def appliesTo(self, ip, port):
        return ((maskIP(ip,self.mask) == self.ip) and
                (self.portMin <= port <= self.portMax))

class Policy:
    """
    >>> import socket
    >>> ip1 = socket.inet_aton("192.169.64.11")
    >>> ip2 = socket.inet_aton("192.168.64.11")
    >>> ip3 = socket.inet_aton("18.244.0.188")

    >>> pol = Policy.parseLines(["reject *:80","accept 18.244.0.188:*"])
    >>> print str(pol).strip()
    reject 0.0.0.0/0.0.0.0:80-80
    accept 18.244.0.188/255.255.255.255:1-65535
    >>> pol.accepts(ip1,80)
    False
    >>> pol.accepts(ip3,80)
    False
    >>> pol.accepts(ip3,81)
    True
    """

    def __init__(self, lst):
        self.lst = lst

    def parseLines(lines):
        r = []
        for item in lines:
            a,p=item.split(" ",1)
            if a == 'accept':
                a = True
            elif a == 'reject':
                a = False
            else:
                raise ValueError("Unrecognized action %r",a)
            p = Pattern.parse(p)
            r.append((p,a))
        return Policy(r)

    parseLines = staticmethod(parseLines)

    def __str__(self):
        r = []
        for pat, accept in self.lst:
            rule = accept and "accept" or "reject"
            r.append("%s %s\n"%(rule,pat))
        return "".join(r)

    def accepts(self, ip, port):
        for pattern,accept in self.lst:
            if pattern.appliesTo(ip,port):
                return accept
        return True

class Server:
    def __init__(self, name, ip, policy, published, fingerprint):
        self.name = name
        self.ip = ip
        self.policy = policy
        self.published = published
        self.fingerprint = fingerprint

def uniq_sort(lst):
    d = {}
    for item in lst: d[item] = 1
    lst = d.keys()
    lst.sort()
    return lst

def run():
    global VERBOSE
    global INVERSE
    global ADDRESSES_OF_INTEREST

    if len(sys.argv) > 1:
        try:
            opts, pargs = getopt.getopt(sys.argv[1:], "vx")
        except getopt.GetoptError, e:
            print """
usage: cat ~/.tor/cached-routers* | %s [-v] [-x] [host:port [host:port [...]]]
    -v  verbose output
    -x  invert results
""" % sys.argv[0]
            sys.exit(0)

        for o, a in opts:
            if o == "-v":
                VERBOSE = True
            if o == "-x":
                INVERSE = True
        if len(pargs):
            ADDRESSES_OF_INTEREST = "\n".join(pargs)

    servers = []
    policy = []
    name = ip = None
    published = 0
    fp = ""
    for line in sys.stdin.xreadlines():
        if line.startswith('router '):
            if name:
                servers.append(Server(name, ip, Policy.parseLines(policy),
                                      published, fp))
            _, name, ip, rest = line.split(" ", 3)
            policy = []
            published = 0
            fp = ""
        elif line.startswith('fingerprint') or \
                 line.startswith('opt fingerprint'):
            elts = line.strip().split()
            if elts[0] == 'opt': del elts[0]
            assert elts[0] == 'fingerprint'
            del elts[0]
            fp = "".join(elts)
        elif line.startswith('accept ') or line.startswith('reject '):
            policy.append(line.strip())
        elif line.startswith('published '):
            date = time.strptime(line[len('published '):].strip(),
                                 "%Y-%m-%d %H:%M:%S")
            published = time.mktime(date)

    if name:
        servers.append(Server(name, ip, Policy.parseLines(policy), published,
                              fp))

    targets = []
    for line in ADDRESSES_OF_INTEREST.split("\n"):
        line = line.strip()
        if not line: continue
        p = Pattern.parse(line)
        targets.append((p.ip, p.portMin))

    # remove all but the latest server of each IP/Nickname pair.
    latest = {}
    for s in servers:
        if (not latest.has_key((s.fingerprint))
            or s.published > latest[(s.fingerprint)]):
            latest[s.fingerprint] = s
    servers = latest.values()

    accepters, rejecters = {}, {}
    for s in servers:
        for ip,port in targets:
            if s.policy.accepts(ip,port):
                accepters[s.ip] = s
                break
        else:
            rejecters[s.ip] = s

    # If any server at IP foo accepts, the IP does not reject.
    for k in accepters.keys():
        if rejecters.has_key(k):
            del rejecters[k]

    if INVERSE:
        printlist = rejecters.values()
    else:
        printlist = accepters.values()

    ents = []
    if VERBOSE:
        ents = uniq_sort([ "%s\t%s"%(s.ip,s.name) for s in printlist ])
    else:
        ents = uniq_sort([ s.ip for s in printlist ])
    for e in ents:
        print e

def _test():
    import doctest, exitparse
    return doctest.testmod(exitparse)
#_test()

run()