Exemple #1
0
 def test_decode_unsupported_version(self):
     password = b"fooobarr"
     data = b"#bellavita"
     version = len(crypto.pack_versions).to_bytes(1, "big")
     pack = crypto.encode(password, data, b"")
     offset = crypto.PackVersion.hash_len
     pack = pack[:offset] + version + pack[offset + 1 :]
     with self.assertRaises(ValueError):
         crypto.decode(password, pack)
def crypt_file_main():
    parser = argparse.ArgumentParser(
        description='(De)Crypt a file according to a given password')
    parser.add_argument('-d', '--decrypt', action='store_true')
    parser.add_argument('-m', '--metadata', help='metadata input file')
    parser.add_argument('zip_password', help='hexified zip password')
    parser.add_argument('input_file',
                        help='input file',
                        nargs='?',
                        default='-')
    parser.add_argument('output_file',
                        help='output file',
                        nargs='?',
                        default='-')
    args = parser.parse_args()
    input_file = open(args.input_file,
                      'rb') if args.input_file != '-' else sys.stdin.buffer
    metadata_file = open(args.metadata,
                         'rb') if args.metadata is not None else None
    output_file = open(args.output_file,
                       'wb') if args.output_file != '-' else sys.stdout.buffer
    zip_password = bytes.fromhex(args.zip_password)
    input_data = input_file.read()
    if args.decrypt:
        assert validate(input_data)
        output_file.write(decode(zip_password, input_data))
    else:
        metadata_in = metadata_file.read(
        ) if metadata_file is not None else b""
        output_file.write(encode(zip_password, input_data, metadata_in))
Exemple #3
0
 def test_encode_decode(self):
     for version in range(len(crypto.pack_versions)):
         with self.subTest():
             password = b"fooobarr"
             data = b"#bellavita"
             encrypted = crypto.encode(password, data, b"", version=version)
             self.assertEqual(data, crypto.decode(password, encrypted))
Exemple #4
0
def crypt_file_main():
    parser = argparse.ArgumentParser(
        description="(De)Crypt a file according to a given password"
    )
    parser.add_argument("-d", "--decrypt", action="store_true")
    parser.add_argument("-m", "--metadata", help="metadata input file")
    parser.add_argument("zip_password", help="hexified zip password")
    parser.add_argument("input_file", help="input file", nargs="?", default="-")
    parser.add_argument("output_file", help="output file", nargs="?", default="-")
    args = parser.parse_args()
    input_file = (
        open(args.input_file, "rb") if args.input_file != "-" else sys.stdin.buffer
    )
    metadata_file = open(args.metadata, "rb") if args.metadata is not None else None
    output_file = (
        open(args.output_file, "wb") if args.output_file != "-" else sys.stdout.buffer
    )
    zip_password = bytes.fromhex(args.zip_password)
    input_data = input_file.read()
    if args.decrypt:
        assert validate(input_data)
        output_file.write(decode(zip_password, input_data))
    else:
        metadata_in = metadata_file.read() if metadata_file is not None else b""
        output_file.write(encode(zip_password, input_data, metadata_in))
Exemple #5
0
 def build_pack(metadata):
     asset = os.path.join(os.path.dirname(__file__),
                          "./assets/pack.zip.enc")
     with open(asset, "rb") as f:
         zip = crypto.decode(bytes.fromhex(Utils.ZIP_PASSWORD), f.read())
     password = bytes.fromhex(Utils.ZIP_PASSWORD)
     return crypto.encode(password, zip, metadata.encode())
    def drop_contest(self, admin_token):
        """
        POST /admin/drop_contest
        """
        if not os.path.exists(Config.encrypted_file):
            self.raise_exc(NotFound, "NOT_FOUND", "No packs found")
        Logger.warning("DROP_CONTEST", "Started dropping contest")
        with open(Config.encrypted_file, "rb") as f:
            pack = f.read()

        db_token = Database.get_meta("admin_token")
        # contest has been extracted but the token is wrong
        if db_token is not None and db_token != admin_token:
            self.raise_exc(Forbidden, "FORBIDDEN", "Wrong token")
        # contest has not been extracted
        if db_token is None:
            try:
                password = crypto.recover_file_password_from_token(admin_token)
                crypto.decode(password, pack)
            except nacl.exceptions.CryptoError:
                # pack password is wrong
                self.raise_exc(Forbidden, "FORBIDDEN", "Wrong pack token")

        metadata = ruamel.yaml.safe_load(crypto.metadata(pack).strip(b"\x00"))
        if not metadata.get("deletable"):
            self.raise_exc(Forbidden, "FORBIDDEN", "Contest not deletable")

        shutil.rmtree(Config.storedir, ignore_errors=True)
        shutil.rmtree(Config.statementdir, ignore_errors=True)
        shutil.rmtree(Config.contest_path, ignore_errors=True)
        for f in (Config.encrypted_file, Config.decrypted_file):
            try:
                os.remove(f)
            except FileNotFoundError:
                pass

        Database.disconnect_database()
        for f in glob.glob(Config.db + "*"):
            os.remove(f)
        Database.connect_to_database()
        Logger.warning("DROP_CONTEST", "Contest dropped")
        return {}
    def extract_contest(token):
        """
        Decrypt and extract the contest and store the used admin token in the
        database
        """

        if "-" not in token:
            BaseHandler.raise_exc(Forbidden, "WRONG_PASSWORD",
                                  "The provided password is malformed")

        try:
            username, password = token.split("-", 1)
            secret, scrambled_password = decode_data(password, SECRET_LEN)
            file_password = recover_file_password(username, secret,
                                                  scrambled_password)
        except ValueError:
            BaseHandler.raise_exc(Forbidden, "WRONG_PASSWORD",
                                  "The provided password is malformed")
        try:
            with open(Config.encrypted_file, "rb") as encrypted_file:
                encrypted_data = encrypted_file.read()
                decrypted_data = decode(file_password, encrypted_data)
                with open(Config.decrypted_file, "wb") as decrypted_file:
                    decrypted_file.write(decrypted_data)
        except FileNotFoundError:
            BaseHandler.raise_exc(NotFound, "NOT_FOUND",
                                  "The contest pack was not uploaded yet")
        except nacl.exceptions.CryptoError:
            BaseHandler.raise_exc(Forbidden, "WRONG_PASSWORD",
                                  "The provided password is wrong")
        except OSError as ex:
            BaseHandler.raise_exc(InternalServerError, "FAILED", str(ex))

        zip_abs_path = os.path.realpath(Config.decrypted_file)
        wd = os.getcwd()
        try:
            os.makedirs(Config.contest_path, exist_ok=True)
            os.chdir(Config.contest_path)
            with zipfile.ZipFile(zip_abs_path) as f:
                f.extractall()
            real_yaml = os.path.join("__users__", username + ".yaml")
            if not os.path.exists(real_yaml):
                BaseHandler.raise_exc(Forbidden, "WRONG_PASSWORD",
                                      "Invalid username for the given pack")
            os.symlink(real_yaml, "contest.yaml")
            Logger.info("CONTEST", "Contest extracted")
        except zipfile.BadZipFile as ex:
            BaseHandler.raise_exc(Forbidden, "FAILED", str(ex))
        finally:
            os.chdir(wd)

        Database.set_meta("admin_token", token)
def main(args):
    with open(args.pack, "rb") as pack:
        pack = pack.read()
    if not validate(pack):
        raise AssertionError("Corrupted pack")
    meta = ruamel.yaml.safe_load(metadata(pack).strip(b"\x00"))
    if meta.get("deletable"):
        print(Fore.YELLOW, "WARNING: The pack is marked as deletable",
              Fore.RESET)
    if not meta.get("name"):
        print(Fore.YELLOW,
              "WARNING: The pack metadata does not include 'name'", Fore.RESET)
    if not meta.get("description"):
        print(Fore.YELLOW,
              "WARNING: The pack metadata does not include 'description'",
              Fore.RESET)
    decoded = decode(bytes.fromhex(args.password), pack)

    tasks = args.tasks.split(",")
    if args.solutions:
        solutions = [
            list(map(os.path.abspath, s.split(",")))
            for s in args.solutions.split(";")
        ]
    else:
        solutions = [[]] * len(tasks)

    extract_dir = tempfile.mkdtemp()
    os.chdir(extract_dir)
    print("Working in %s" % extract_dir)

    with open("pack.zip", "wb") as f:
        f.write(decoded)
    with zipfile.ZipFile("pack.zip") as zip_file:
        zip_file.extractall(".")
    if args.sedi:
        validate_sedi(args.sedi)
    if args.admin:
        validate_admin(args.admin, args.password)
    for i, task in enumerate(tasks):
        if not os.path.exists(task):
            raise AssertionError("Task %s not included in the pack" % task)
        sols = solutions[i] if i < len(solutions) else []
        validate_task(task, args.fuzz, args.iterations, sols)

    shutil.rmtree(extract_dir)
Exemple #9
0
 def test_encode_decode(self):
     password = b"fooobarr"
     data = b"#bellavita"
     encrypted = crypto.encode(password, data, b"")
     self.assertEqual(data, crypto.decode(password, encrypted))