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 test_gen_user_password(self): username = "******" secret = b"SEC" file_password = b"PASSWOR" token = crypto.gen_user_password(username, secret, file_password) new_secret, encoded_password = crypto.decode_data( token[len(username) + 1:], len(secret)) self.assertEqual( file_password, crypto.recover_file_password(username, new_secret, encoded_password))
def validate_admin(admin, password): print(Fore.BLUE, "Validating admins...", Fore.RESET) with open(admin) as f: admins = list(csv.DictReader(f, delimiter=";")) for admin in admins: full_sede = admin["full_sede"] print(" %s" % full_sede) token = admin["password"] if full_sede != token.split("-")[0]: raise AssertionError("Token of admin %s does not starts with %s-" % (full_sede, full_sede)) secret, passwd = decode_data(token[len(full_sede) + 1:], SECRET_LEN) if recover_file_password(full_sede, secret, passwd).hex() != password: raise AssertionError("Invalid token for admin %s" % full_sede)
def test_decode_data(self): base32 = "FOOOOOOOBARRRRRR" secret_len = len("FOOOOOOOO") * 5 // 8 secret, password = crypto.decode_data(base32, secret_len) self.assertEqual(secret, base64.b32decode("FOOOOOOO")) self.assertEqual(password, base64.b32decode("BARRRRRR"))