|
8 | 8 | import asyncio |
9 | 9 | import aiohttp |
10 | 10 | import re |
| 11 | +import tarfile |
| 12 | +import requests |
11 | 13 | import json |
12 | 14 | import tempfile |
13 | 15 | import time |
| 16 | +import os |
14 | 17 | import sys |
15 | 18 | import argparse |
16 | 19 | from colorama import Fore, Style, init |
17 | | -import os |
18 | 20 | import xml.etree.ElementTree as ET |
19 | 21 | from datetime import datetime, timezone |
20 | 22 | from cryptography import x509 |
21 | 23 | from cryptography.hazmat.backends import default_backend |
22 | 24 | from cryptography.hazmat.primitives import hashes, serialization |
23 | 25 | from cryptography.hazmat.primitives.asymmetric import padding, ec |
24 | 26 | init(autoreset=True) |
| 27 | +current_version = "v1.2" |
| 28 | + |
| 29 | +# ==== This code is to check update |
| 30 | + |
| 31 | +# because the "v" is important since it look beautiful |
| 32 | +def parse_version(version): |
| 33 | + return tuple(map(int, (version.lstrip('v').split(".")))) |
| 34 | + |
| 35 | +def get_latest_version(): |
| 36 | + url = f"https://api.github.com/repos/SenyxLois/KeyboxCheckerPython/releases/latest" |
| 37 | + response = requests.get(url) |
| 38 | + if response.status_code == 200: |
| 39 | + latest_release = response.json() |
| 40 | + return latest_release["tag_name"], latest_release["tarball_url"], latest_release["body"] |
| 41 | + else: |
| 42 | + raise Exception(f"Failed to fetch latest release: {response.status_code}") |
| 43 | + |
| 44 | +def download_and_replace_files(tarball_url): |
| 45 | + response = requests.get(tarball_url) |
| 46 | + if response.status_code == 200: |
| 47 | + tar_content = response.content |
| 48 | + with tempfile.TemporaryDirectory() as tmpdirname: |
| 49 | + tar_path = os.path.join(tmpdirname, 'update.tar.gz') |
| 50 | + with open(tar_path, 'wb') as f: |
| 51 | + f.write(tar_content) |
| 52 | + with tarfile.open(tar_path, 'r:gz') as tar_ref: |
| 53 | + def is_within_directory(directory, target): |
| 54 | + abs_directory = os.path.abspath(directory) |
| 55 | + abs_target = os.path.abspath(target) |
| 56 | + prefix = os.path.commonprefix([abs_directory, abs_target]) |
| 57 | + return prefix == abs_directory |
| 58 | + |
| 59 | + def safe_extract(tar, path=".", members=None, *, numeric_owner=False): |
| 60 | + for member in tar.getmembers(): |
| 61 | + member_path = os.path.join(path, member.name) |
| 62 | + if not is_within_directory(path, member_path): |
| 63 | + raise Exception("Attempted Path Traversal in Tar File") |
| 64 | + tar.extractall(path, members, numeric_owner=numeric_owner) |
| 65 | + |
| 66 | + safe_extract(tar_ref, tmpdirname) |
| 67 | + extracted_dir = os.path.join(tmpdirname, os.listdir(tmpdirname)[0]) |
| 68 | + for root, dirs, files in os.walk(extracted_dir): |
| 69 | + for file in files: |
| 70 | + src_path = os.path.join(root, file) |
| 71 | + rel_path = os.path.relpath(src_path, extracted_dir) |
| 72 | + dest_path = os.path.join(os.getcwd(), rel_path) |
| 73 | + os.makedirs(os.path.dirname(dest_path), exist_ok=True) |
| 74 | + os.replace(src_path, dest_path) |
| 75 | + print("Update successful. Please restart the application.") |
| 76 | + else: |
| 77 | + print("Failed to download the update.") |
| 78 | + |
| 79 | +def check_for_update(): |
| 80 | + repo_url = "https://api.github.com/repos/SenyxLois/KeyboxCheckerPython/releases/latest" |
| 81 | + response = requests.get(repo_url) |
| 82 | + if response.status_code == 200: |
| 83 | + release_info = response.json() |
| 84 | + latest_version = release_info['tag_name'] |
| 85 | + changelog = release_info['body'] |
| 86 | + if parse_version(latest_version) > parse_version(current_version): |
| 87 | + print(f"New Version available: {latest_version}") |
| 88 | + print("Changelog :") |
| 89 | + print(changelog) |
| 90 | + update = input("Do you want to update? (y/n): ").strip().lower() |
| 91 | + if update == "y": |
| 92 | + print('Updating...') |
| 93 | + download_and_replace_files(release_info['tarball_url']) |
| 94 | + else: |
| 95 | + print("Update canceled.") |
| 96 | + else: |
| 97 | + time.sleep(0.02) |
| 98 | + else: |
| 99 | + print("Failed to check for updates.") |
| 100 | + |
| 101 | +# ==== very demure lining :3 |
25 | 102 |
|
26 | 103 | async def load_from_url(): |
27 | 104 | url = "https://android.googleapis.com/attestation/status" |
@@ -256,7 +333,7 @@ def get_overrall_status(status, keychain_status, cert_status, google_status): |
256 | 333 |
|
257 | 334 |
|
258 | 335 | if __name__ == "__main__": |
259 | | - # Create an argument parser |
| 336 | + check_for_update() |
260 | 337 | parser = argparse.ArgumentParser(description="Keybox Checker") |
261 | 338 | parser.add_argument( |
262 | 339 | "keybox_path", |
|
0 commit comments