import logging import os import random import string from config import get_settings class Challenge(object): name = __name__ settings = get_settings() port = 0 # Host the checker connects to. Same machine as the published team ports; # override with RECEIVER_HOST if a receiver ever runs off-host. host = os.environ.get("RECEIVER_HOST", "127.0.0.1") def __init__(self, port, host=None): self.port = port if host: self.host = host self.add_logger() def url(self, path=""): """Absolute URL for the challenge service (see xvi/Challenge.py).""" p = "" if path.startswith("/") else "/" return f"http://{self.host}:{self.port}{p}{path}" def add_logger(self): self.logger = logging.getLogger() def random_string(self, length): charset = string.ascii_uppercase + string.ascii_lowercase + string.digits return ''.join(random.choice(charset) for i in range(length)) def distribute(self, flag): raise NotImplementedError def check(self): raise NotImplementedError def credentials(self): pwd = os.environ.get(f'PASSWORD_{self.port}') if not pwd: pwd = getattr(self.settings, f'PASSWORD_{self.port}', '') # SSH login user is PER-CHALLENGE, not per-package: the imported XVII # Dockerfiles also do `echo root:${PASSWORD} | chpasswd`, so reporting # ctfuser here handed participants a login that could never work. # gen_receiver_services.py injects SSH_USER_ from the registry, # which is the single source of truth; the literal is only a fallback. user = os.environ.get(f'SSH_USER_{self.port}', 'ctfuser') return { 'username': user, 'password': pwd, }