diff --git a/Makefile b/Makefile index e946fbb..39289bc 100644 --- a/Makefile +++ b/Makefile @@ -15,23 +15,23 @@ lint:: install:: ${PIP_EXE_MSYS} --python ${PYTHON_EXE_MSYS} install \ + --no-deps \ --target ${PREFIX}/lib/python${PYTHON_MINOR}/site-packages/ \ --upgrade . + sed -i -e "1s@/usr/bin/python${PYTHON_MINOR}@${PYTHON_EXE_MSYS}@" \ + ${PREFIX}/lib/python${PYTHON_MINOR}/site-packages/bin/* rsync:: bash .rsync.sh -install:: - ${PYTHON_EXE_MSYS} -m pip --timeout=30 --disable-pip-version-check --proxy http://127.0.0.1:9128 install --only-binary :none: --progress-bar=off --target /usr/local/lib/python3.11/site-packages --upgrade . - # execute these tests as: make test PASS=password test:: echo src/${MOD}/check_digests.py - TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/check_digests.py + TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/check_digests.py echo src/${MOD}/interpreter.py - TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/interpreter.py + TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/interpreter.py echo src/${MOD}/connection_resolution.py - sudo env TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/connection_resolution.py + sudo env TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/connection_resolution.py # broken because this site fails: http://128.31.0.39:9131/tor/status-vote # ${PYTHON_EXE_MSYS} src/${MOD}/compare_flags.py # cant use from make: waits for the cmdline to to terminate @@ -45,7 +45,7 @@ test:: echo src/${MOD}/outdated_relays.py NOT WORKING? TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/outdated_relays.py echo src/${MOD}/relay_connections.py - TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/relay_connections.py + sudo env TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/relay_connections.py echo src/${MOD}/tor_bootstrap_check.py TOR_CONTROLLER_PASSWORD=${PASS} ${PYTHON_EXE_MSYS} src/${MOD}/tor_bootstrap_check.py diff --git a/pyproject.toml b/pyproject.toml index 2028645..62aaa84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", ] -# dynamic = ["version", "readme", ] # cannot be dynamic ['license'] [project.scripts] diff --git a/setup.cfg b/setup.cfg index 6cb75d2..a90179a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,7 +20,7 @@ classifiers = zip_safe = false python_requires = ~=3.6 include_package_data = - "*" = ["*.txt"] + "*" = ["*.txt", "*.bash" ] install_requires = stem ruamel.yaml diff --git a/src/stem_examples/check_digests.py b/src/stem_examples/check_digests.py index 6da8649..a8b7e4f 100755 --- a/src/stem_examples/check_digests.py +++ b/src/stem_examples/check_digests.py @@ -21,6 +21,8 @@ import stem from stem_examples.tor_controller import set_socks_proxy LOG = logging.getLogger() +sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook +iTIMEOUT = 120 @contextlib.contextmanager def ignoreStdout() -> None: @@ -108,13 +110,13 @@ if __name__ == '__main__': lArgs = sys.argv[1:] LOG.info(f"Getting some {len(lArgs)}") else: - sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook - LOG.info("Getting some FPs from a sKNOWN_ONION") + LOG.info(f"Getting some FPs from the IPs to a sKNOWN_ONION TIMEOUT={iTIMEOUT}") from stem_examples.introduction_points import lMain as lIPMain with ignoreStdout(): - lArgs = lIPMain([sKNOWN_ONION]) + lArgs = lIPMain([sKNOWN_ONION], timeout=iTIMEOUT) LOG.info(f"Got {len(lArgs)} FPs from a sKNOWN_ONION") - + if not lArgs: + sys.exit(1) i = iMain(lArgs) except KeyboardInterrupt as e: i = 0 diff --git a/src/stem_examples/connection_resolution.py b/src/stem_examples/connection_resolution.py old mode 100644 new mode 100755 diff --git a/src/stem_examples/interpreter.py b/src/stem_examples/interpreter.py old mode 100644 new mode 100755 index bd4be2f..17b2233 --- a/src/stem_examples/interpreter.py +++ b/src/stem_examples/interpreter.py @@ -25,7 +25,7 @@ LOG = logging.getLogger() def iMain(lArgs=None): if not lArgs: lArgs = ['GETINFO' 'version'] - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') if os.path.exists('/run/tor/control'): controller = get_controller(password=password, unix='/run/tor/control') else: diff --git a/src/stem_examples/introduction_points.py b/src/stem_examples/introduction_points.py index ac95b18..7c48610 100755 --- a/src/stem_examples/introduction_points.py +++ b/src/stem_examples/introduction_points.py @@ -22,52 +22,93 @@ import sys import os import getpass import logging +import binascii +import stem from stem.control import Controller +from stem import Timeout +from stem.client.datatype import LinkByFingerprint +from stem.descriptor.hidden_service import HiddenServiceDescriptorV3 from stem_examples.tor_controller import get_controller +from stem.descriptor.hidden_service import HiddenServiceDescriptorV3 LOG = logging.getLogger() - +TIMEOUT = 60 lKNOWN_ONIONS = [ 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd', # facebook 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad', # ddg + 'zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad', # keys.openpgp.org + 'libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd', + 'oftcnet6xg6roj6d7id4y4cu6dchysacqj2ldgea73qzdagufflqxrid', ] +def bin_to_hex(raw_id:int, length: int|None = None) -> str: + if length is None: length = len(raw_id) + res = ''.join('{:02x}'.format(raw_id[i]) for i in range(length)) + return res.upper() + def iMain(lArgs=None): lRetval = lMain(lArgs) if lRetval is None: return -1 return 0 -def lMain(lArgs=None, timeout=None): +def lMain(lArgs=None, timeout=TIMEOUT) -> list: lRetval = [] if not lArgs: lArgs = lKNOWN_ONIONS try: - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') if os.path.exists('/run/tor/control'): controller = get_controller(password=password, unix='/run/tor/control') else: controller = get_controller(password=password, port=9051) for elt in lArgs: - desc = controller.get_hidden_service_descriptor(elt, - await_result=True, - timeout=timeout) - LOG.info(f"{desc} get_hidden_service_descriptor\n") - l = desc.introduction_points() + LOG.info(f"onion: {elt}") + try: + desc = controller.get_hidden_service_descriptor(elt, + await_result=True, + timeout=timeout) + except Exception as e: + LOG.warn (f"{elt} EXCEPTION {e}") + continue + if desc.descriptor_id is None or desc.version is None: + # reparse as HSv3 + inner_layer = HiddenServiceDescriptorV3.from_str(str(desc)).decrypt(elt) + if hasattr(inner_layer, 'introduction_points'): + LOG.info (f"{elt} reparsed desc.decrypt len={len(desc.introduction_points())}") + + l = inner_layer.introduction_points + else: + LOG.warn (f"{elt} reparsed desc.decrypt={dir(inner_layer)}") + sys.exit(1) + + #LOG.info(f"version: {desc.version}\n") + #LOG.info(f"lifetime: {desc.lifetime}\n") + else: + LOG.info(f"published: {desc.published}\n") + l = desc.introduction_points() if not l: LOG.warn(f"{elt} NO introduction points {l}\n") continue - LOG.info(f"{elt} introduction points are...\n") + lp = [] for introduction_point in l: - lRetval += [introduction_point] - LOG.info(' %s:%s => %s' % (introduction_point.address, - introduction_point.port, - introduction_point.identifier)) - + for linkspecifier in introduction_point.link_specifiers: + # if isinstance(linkspecifier, LinkByFingerprint): + # LOG.log(40, f"Getting fingerprint for {linkspecifier}") + if hasattr(linkspecifier, 'fingerprint') and \ + len(linkspecifier.value) == 20: + lp += [bin_to_hex(linkspecifier.value)] + elif hasattr(introduction_point, 'address'): + LOG.info('IP: %s:%s => %s' % (introduction_point.address, + introduction_point.port, + introduction_point.identifier)) + else: + pass # LOG.warn(f"{elt} introduction_point type={type(linkspecifier)}") + LOG.info(f"{elt} {len(lp)} introduction points {lp}") except Exception as e: LOG.exception(f"Exception: {e}") finally: @@ -83,7 +124,7 @@ if __name__ == '__main__': vsetup_logging(LOG, log_level) try: l = lMain(sys.argv[1:]) - if l: print(l) + if l: print('IPs: ', l) i = 0 except KeyboardInterrupt as e: LOG.exception(f"Exception {e}") diff --git a/src/stem_examples/list_circuits.py b/src/stem_examples/list_circuits.py index 5585dd0..5bfeb7c 100755 --- a/src/stem_examples/list_circuits.py +++ b/src/stem_examples/list_circuits.py @@ -15,7 +15,7 @@ def iMain(): else: controller = get_controller(port=9051) - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') try: controller.authenticate(password) diff --git a/src/stem_examples/mappaddress.py b/src/stem_examples/mappaddress.py index 28e32fc..0f14549 100755 --- a/src/stem_examples/mappaddress.py +++ b/src/stem_examples/mappaddress.py @@ -29,7 +29,7 @@ LOG = logging.getLogger() def sMapaddressResolv(target, iPort=9051): try: - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') if os.path.exists('/run/tor/control'): controller = get_controller(password=password, unix='/run/tor/control') else: diff --git a/src/stem_examples/outdated_relays.py b/src/stem_examples/outdated_relays.py index 9f68dab..91efb68 100755 --- a/src/stem_examples/outdated_relays.py +++ b/src/stem_examples/outdated_relays.py @@ -35,7 +35,7 @@ def iMain(lArgs=None): with_contact += 1 LOG.info("%i outdated relays found, %i had contact information" % (count, with_contact)) - # http://vt5hknv6sblkgf22.onion/tutorials/examples/outdated_relays.htmlhttp://vt5hknv6sblkgf22.onion/tutorials/examples/outdated_relays.html + # http://vt5hknv6sblkgf22.onion/tutorials/examples/outdated_relays.html return 0 if __name__ == '__main__': diff --git a/src/stem_examples/relay_connections.py b/src/stem_examples/relay_connections.py index 5c2e3b5..506909f 100755 --- a/src/stem_examples/relay_connections.py +++ b/src/stem_examples/relay_connections.py @@ -52,7 +52,7 @@ def iMain(lArgs=None): parser.add_argument("--resolver", help="default: autodetected") args = parser.parse_args(lArgs) - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') control_port = int(args.ctrlport) if args.ctrlport else 'default' if False and os.path.exists('/run/tor/control'): controller = get_controller(password=password, unix='/run/tor/control') diff --git a/src/stem_examples/stem_utils.py b/src/stem_examples/stem_utils.py old mode 100644 new mode 100755 diff --git a/src/stem_examples/tor_bootstrap_check.py b/src/stem_examples/tor_bootstrap_check.py index d54a904..b281a04 100755 --- a/src/stem_examples/tor_bootstrap_check.py +++ b/src/stem_examples/tor_bootstrap_check.py @@ -21,7 +21,7 @@ from stem_examples.tor_controller import get_controller LOG = logging.getLogger() def iMain(lArgs=None): - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') if os.path.exists('/run/tor/control'): controller = get_controller(password=password, unix='/run/tor/control') else: diff --git a/src/stem_examples/tor_controller.py b/src/stem_examples/tor_controller.py index ceede89..14abc89 100755 --- a/src/stem_examples/tor_controller.py +++ b/src/stem_examples/tor_controller.py @@ -39,7 +39,7 @@ def get_controller(password=None, address='127.0.0.1', port=9051, unix='/run/tor if password is None: # print("DBUG: trying TOR_CONTROLLER_PASSWORD") - password = os.environ.get('TOR_CONTROLLER_PASSWORD') + password = os.environ.get('TOR_CONTROLLER_PASSWORD', '') else: # print(f"DBUG: using a password {len(password)}") pass diff --git a/src/stem_examples/torcontactinfo.py b/src/stem_examples/torcontactinfo.py old mode 100644 new mode 100755