import os import json import tkinter.messagebox import customtkinter from winotify import Notification, audio import keyboard import subprocess import requests import hashlib import string import random import tkinter import threading class App(customtkinter.CTk): def __init__(self): super().__init__() self.title(f"{app_name} | ロック中") if client_config["testing"] == 1: pass else: self.attributes('-fullscreen', True) self.attributes('-topmost', True) self.frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent') self.frame.grid(row=0, column=0, sticky='nsew') self.block_taskmgr() self.block_key() lock = Lock() def exit(self): self.unlock_taskmgr() self.toast() self.destroy() def block_key(self): block_keys = ['ctrl', 'alt', 'windows', 'shift', 'delete'] for i in block_keys: keyboard.block_key(i) def block_taskmgr(self): block = subprocess.run(['reg', 'add', 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System', '/v', 'DisableTaskMgr', '/t', 'REG_DWORD', '/d', '1']) print(block) def unlock_taskmgr(self): unlock = subprocess.run(['reg', 'delete', 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System', '/v', 'DisableTaskMgr', '/f']) print(unlock) def toast(self): resource_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "resource") success = Notification( app_id='Dislocker', title='ご協力ありがとうございます!', msg='パスワード認証に成功しました。\n現在使われたパスワードは削除されます。', icon=resource_path + r'\success.png' ) success.set_audio(audio.Default, loop=False) success.show() def handler_close(self): pass class Lock(customtkinter.CTkToplevel): def __init__(self): super().__init__() self.title(f'{app_name} | PC番号 {client_config["pc_number"]} | ロックされています') self.geometry('400x200') self.resizable(height=False, width=False) self.attributes('-topmost', True) self.grab_set() self.lift() self.protocol("WM_DELETE_WINDOW", self.handler_close) self.title_font = customtkinter.CTkFont(family="meiryo", size=24, weight="bold") self.general_font = customtkinter.CTkFont(family="meiryo", size=14) self.general_small_font = customtkinter.CTkFont(family="meiryo", size=12) self.msg_title_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent') self.msg_title_frame.grid(row=0, column=0, sticky="nsew") self.msg_title_1 = customtkinter.CTkLabel(self.msg_title_frame, text='ちょっと待って!!', font=self.title_font, anchor=tkinter.W) self.msg_title_1.grid(row=0, column=0, padx=10, pady=10) self.msg_subtitle_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent') self.msg_subtitle_frame.grid(row=1, column=0, sticky="nsew") self.msg_subtitle_1 = customtkinter.CTkLabel(self.msg_subtitle_frame, text='サインインするには、パスワードが必要です。', font=self.general_font, anchor=tkinter.W) self.msg_subtitle_1.grid(row=0, column=0, padx=10, pady=10) self.input_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent') self.input_frame.grid(row=2, column=0, sticky="nsew") self.password_entry = customtkinter.CTkEntry(self.input_frame, placeholder_text='パスワード', width=380, show='*', font=self.general_small_font) self.password_entry.grid(row=0, column=0, padx=10, pady=10) self.button_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent') self.button_frame.grid(row=3, column=0, sticky="nsew") self.signin_button = customtkinter.CTkButton(self.button_frame, text='サインイン', command=self.auth, font=self.general_font) self.signin_button.grid(row=0, column=1, padx=10, pady=10) self.signin_button.pack(padx=10, anchor=tkinter.E) self.keyboard_listener_thread = threading.Thread(target=self.keyboard_listener) self.keyboard_listener_thread.daemon = True self.keyboard_listener_thread.start() def keyboard_listener(self): keyboard.add_hotkey('ctrl+shift+q', self.exit) def hash_genarate(self, source): hashed = hashlib.md5(source.encode()) return hashed.hexdigest() def auth(self): auth_url = client_config["auth_host_url"] + "/verify" auth_json = { "pc_number": int(client_config["pc_number"]), "password": self.hash_genarate(str(self.password_entry.get())) } try: responce = requests.post(auth_url, json=auth_json) except: master_password_hash = self.hash_genarate(str(self.password_entry.get())) if client_config["master_password_hash"] == master_password_hash: self.exit() else: self.msg_subtitle_1.configure(text='サインインするには、パスワードが必要です。\nネットワークエラーが発生しています。\n続行するには、マスターパスワードを入力して下さい。') if responce.status_code == 200: self.exit() else: master_password_hash = self.hash_genarate(str(self.password_entry.get())) if client_config["master_password_hash"] == master_password_hash: self.exit() else: self.msg_subtitle_1.configure(text='サインインするには、パスワードが必要です。\nパスワードが違います!') def handler_close(self): pass def exit(self): self.destroy() app.exit() def master_password_gen(): numbers = string.digits # (1) password = ''.join(random.choice(numbers) for _ in range(10)) # (2) password_hash = hashlib.md5(password.encode()).hexdigest() result = {"password": password, "password_hash": password_hash} return result app_name = "Dislocker" config_dir_path = "./config/" client_config_path = config_dir_path + "client.json" if not os.path.isfile(client_config_path): if not os.path.isdir(config_dir_path): os.mkdir(config_dir_path) client_config = { "initial": 1, "auth_host_url": "http://localhost", "pc_number": 1, "master_password_hash": "", "testing": 0 } with open(client_config_path, "w") as w: json.dump(client_config, w, indent=4) elif os.path.isfile(client_config_path): with open(client_config_path, "r") as r: client_config = json.load(r) if client_config["initial"] == 1: master_password = master_password_gen() msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 初回起動を検出", message=f"初回起動のようです。\nマスターパスワードを記録しておいてください。\nこれ以降二度と表示されることはないでしょう。\n\n{master_password["password"]}\n\nまた、認証先サーバーの接続先を指定してください。ロックを解除できなくなります。") client_config["master_password_hash"] = master_password["password_hash"] client_config["initial"] = 0 with open(client_config_path, "w") as w: json.dump(client_config, w, indent=4) else: if __name__ == '__main__': app = App() app.protocol("WM_DELETE_WINDOW", app.handler_close) app.mainloop()