figENC.py (36683B)
1 import sys, json, getpass 2 import tkinter as tk 3 from tkinter import filedialog 4 from random import choice 5 import key, check 6 from encrypt import enc_manager 7 from decrypt import dec_manager 8 import version_check as vc 9 from path import find_path 10 11 12 class App(): 13 14 def __init__(self, root): 15 """Create and hide the main window then open the launcher window 16 17 Keyword arguments: 18 root -- the Tk() frame for the main window 19 """ 20 self.crypto_mode = "" 21 self.show_pass = False 22 self.crypto_filepaths = () 23 self.key_dir = "" 24 25 self.settings_file = find_path("settings.json") 26 self.tips_file = find_path("tips.json") 27 with open(self.settings_file) as settings_file: 28 settings = json.load(settings_file) 29 root.withdraw() 30 31 self.launcher(settings) 32 root.mainloop() 33 34 def main_app(self, root, settings): 35 """Create the main app widgets in the passed root variable, and then 36 minimize the root window. 37 38 Keyword arguments: 39 root -- the main app window 40 settings -- a dictionary of settings used to build the widget 41 """ 42 root.wm_title("figENC") 43 self.canvas = tk.Canvas( 44 root, 45 height=settings["win_height"], 46 width=settings["win_width"] 47 ) 48 self.canvas.pack(fill="both", expand=True, side=tk.LEFT) 49 self.frame = tk.Frame(self.canvas, bg="#1A181C") 50 self.frame.place(relwidth=1, relheight=1) 51 self.header = tk.Label( 52 self.frame, 53 text="figENC", 54 justify=tk.CENTER, 55 font=("Arial", settings["font_size"] + 6), 56 bg="#643181", 57 fg="#F2DAFF", 58 pady=2 59 ) 60 self.subheader = tk.Label( 61 self.frame, 62 text="Industry leading encryption by FIGBERT", 63 justify=tk.CENTER, 64 font=("Arial", settings["font_size"]), 65 bg="#643181", 66 fg="#F2DAFF", 67 pady=2 68 ) 69 self.header.pack(fill="x", side=tk.TOP) 70 self.subheader.pack(fill="x", side=tk.TOP) 71 self.action = tk.Frame(self.frame, bg="#1A181C", pady=5) 72 self.action.pack(fill="both") 73 self.action_label = tk.Label( 74 self.action, 75 text="Action:", 76 justify=tk.LEFT, 77 font=("Arial", settings["font_size"]), 78 bg="#1A181C", 79 fg="#F2DAFF", 80 ) 81 self.action_label.pack() 82 self.action_list = tk.Listbox( 83 self.action, 84 justify=tk.CENTER, 85 font=("Arial", settings["font_size"] - 2), 86 bg="#1A181C", 87 fg="#ACA0B2", 88 selectbackground="#643181", 89 selectmode=tk.SINGLE, 90 relief=tk.SUNKEN, 91 height=7 92 ) 93 self.action_list.insert( 94 1, 95 "Encrypt with fresh keys (password locked)" 96 ) 97 self.action_list.insert(2, "Encrypt with fresh keys (no password)") 98 self.action_list.insert(3, "Encrypt with generated keys") 99 self.action_list.insert( 100 4, 101 "Decrypt with generated keys (password locked)" 102 ) 103 self.action_list.insert( 104 5, 105 "Decrypt with generated keys (no password)" 106 ) 107 self.action_list.insert(6, "Only create fresh keys (password locked)") 108 self.action_list.insert(7, "Only create fresh keys (no password)") 109 self.action_list.pack(fill="both", pady=10) 110 if sys.platform == "darwin": 111 self.submit_action = tk.Button( 112 self.action, 113 text="Begin Process", 114 font=("Arial", settings["font_size"] - 2), 115 fg="#643181", 116 highlightthickness=0, 117 highlightbackground="#1A181C", 118 command=lambda: self.setup(self.action_list.curselection()) 119 ) 120 else: 121 self.submit_action = tk.Button( 122 self.action, 123 text="Begin Process", 124 font=("Arial", settings["font_size"] - 2), 125 bg="#8A8A8A", 126 fg="#643181", 127 command=lambda: self.setup(self.action_list.curselection()) 128 ) 129 self.submit_action.pack() 130 self.step_two = tk.Frame(self.frame, bg="#1A181C") 131 self.step_two.pack(fill="both") 132 self.file_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8) 133 self.file_label = tk.Label( 134 self.file_frame, 135 text="If you see this, the app broke", 136 font=("Arial", settings["font_size"]), 137 bg="#1A181C", 138 fg="#F2DAFF" 139 ) 140 if sys.platform == "darwin": 141 self.file_input = tk.Button( 142 self.file_frame, 143 text="Select File/s", 144 font=("Arial", settings["font_size"] - 2), 145 fg="#643181", 146 highlightthickness=0, 147 highlightbackground="#1A181C", 148 command=self.select_filepaths 149 ) 150 else: 151 self.file_input = tk.Button( 152 self.file_frame, 153 text="Select File/s", 154 font=("Arial", settings["font_size"] - 2), 155 bg="#8A8A8A", 156 fg="#643181", 157 command=self.select_filepaths 158 ) 159 self.passcode_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8) 160 self.passcode_label = tk.Label( 161 self.passcode_frame, 162 text="If you see this, the app broke", 163 font=("Arial", settings["font_size"]), 164 bg="#1A181C", 165 fg="#F2DAFF" 166 ) 167 self.passcode_instructions = tk.Label( 168 self.passcode_frame, 169 text="If you see this, the app broke", 170 font=("Arial", settings["font_size"] - 2), 171 bg="#1A181C", 172 fg="#B494C7" 173 ) 174 self.passcode_input = tk.Entry( 175 self.passcode_frame, 176 font=("Arial", settings["font_size"] - 2), 177 justify=tk.CENTER, 178 textvariable=tk.StringVar, 179 show="*", 180 bg="#1A181C", 181 fg="#F2DAFF", 182 highlightthickness=0, 183 insertbackground="#F2DAFF" 184 ) 185 self.passcode_input.bind("<Button-2>", self.toggle_pass) 186 self.confirm_label = tk.Label( 187 self.passcode_frame, 188 text="Confirm passkey", 189 font=("Arial", settings["font_size"]), 190 bg="#1A181C", 191 fg="#F2DAFF" 192 ) 193 self.confirm_instructions = tk.Label( 194 self.passcode_frame, 195 text="Re-enter the provided passkey", 196 font=("Arial", settings["font_size"] - 2), 197 bg="#1A181C", 198 fg="#B494C7" 199 ) 200 self.confirm_input = tk.Entry( 201 self.passcode_frame, 202 font=("Arial", settings["font_size"] - 2), 203 justify=tk.CENTER, 204 textvariable=tk.StringVar, 205 show="*", 206 bg="#1A181C", 207 fg="#F2DAFF", 208 highlightthickness=0, 209 insertbackground="#F2DAFF" 210 ) 211 self.confirm_input.bind("<Button-2>", self.toggle_pass) 212 self.save = tk.Frame(self.step_two, bg="#1A181C", pady=8) 213 self.save_label = tk.Label( 214 self.save, 215 text="Save location for keys", 216 font=("Arial", settings["font_size"]), 217 bg="#1A181C", 218 fg="#F2DAFF" 219 ) 220 self.save_instructions = tk.Label( 221 self.save, 222 text="If you see this, the app broke", 223 font=("Arial", settings["font_size"] - 2), 224 bg="#1A181C", 225 fg="#B494C7" 226 ) 227 if sys.platform == "darwin": 228 self.save_input = tk.Button( 229 self.save, 230 text="Select Directory", 231 font=("Arial", settings["font_size"] - 2), 232 fg="#643181", 233 highlightthickness=0, 234 highlightbackground="#1A181C", 235 command=self.select_key_dir 236 ) 237 else: 238 self.save_input = tk.Button( 239 self.save, 240 text="Select Directory", 241 font=("Arial", settings["font_size"] - 2), 242 bg="#8A8A8A", 243 fg="#643181", 244 command=self.select_key_dir 245 ) 246 self.type_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8) 247 self.type_label = tk.Label( 248 self.type_frame, 249 text="Type of keys to generate", 250 font=("Arial", settings["font_size"]), 251 bg="#1A181C", 252 fg="#F2DAFF" 253 ) 254 self.type_instructions = tk.Label( 255 self.type_frame, 256 text=("Selecting RSA will generate a public and private key,\nbut" 257 " selecting Mixed will also generate a symmetric key." 258 ), 259 font=("Arial", settings["font_size"] - 2), 260 bg="#1A181C", 261 fg="#B494C7" 262 ) 263 self.type_button_frame = tk.Frame(self.type_frame, bg="#1A181C") 264 self.type_control = tk.IntVar() 265 self.rsa_radiobutton = tk.Radiobutton( 266 self.type_button_frame, 267 text="RSA", 268 bg="#1A181C", 269 fg="#F2DAFF" if sys.platform == "darwin" else "#B494C7", 270 variable=self.type_control, 271 value=0 272 ) 273 self.mixed_radiobutton = tk.Radiobutton( 274 self.type_button_frame, 275 text="Mixed", 276 bg="#1A181C", 277 fg="#F2DAFF" if sys.platform == "darwin" else "#B494C7", 278 variable=self.type_control, 279 value=1 280 ) 281 if sys.platform == "darwin": 282 self.submit = tk.Button( 283 self.step_two, 284 text="If you see this, the app broke", 285 font=("Arial", settings["font_size"] - 2), 286 fg="#643181", 287 highlightbackground="#1A181C", 288 highlightthickness=0, 289 command=lambda: self.go( 290 mode=self.crypto_mode, 291 key_dir=self.key_paths, 292 target_files=self.crypto_filepaths, 293 passkey=self.passcode_input.get(), 294 passcheck=self.confirm_input.get() 295 ) 296 ) 297 else: 298 self.submit = tk.Button( 299 self.step_two, 300 text="If you see this, the app broke", 301 font=("Arial", settings["font_size"] - 2), 302 bg="#8A8A8A", 303 fg="#643181", 304 command=lambda: self.go( 305 mode=self.crypto_mode, 306 key_dir=self.key_paths, 307 target_files=self.crypto_filepaths, 308 passkey=self.passcode_input.get(), 309 passcheck=self.confirm_input.get() 310 ) 311 ) 312 313 def open_settings(self, root): 314 """Open the settings window and temporarily minimize the root window 315 316 Keyword arguments: 317 root -- the window to be minimized 318 """ 319 root.withdraw() 320 with open(self.settings_file) as settings_file: 321 self.settings = json.load(settings_file) 322 self.settings_window = tk.Toplevel( 323 height=self.settings["win_height"], 324 width=self.settings["win_width"], 325 bg="#1A181C" 326 ) 327 self.settings_window.wm_title("figENC - Settings") 328 self.canvas = tk.Canvas( 329 self.settings_window, 330 height=self.settings["win_height"], 331 width=self.settings["win_width"] 332 ) 333 self.canvas.pack(fill=tk.BOTH, expand=True, side=tk.LEFT) 334 self.frame = tk.Frame(self.canvas, bg="#1A181C") 335 self.frame.place(relwidth=1, relheight=1) 336 self.header = tk.Label( 337 self.frame, 338 text="Settings", 339 justify=tk.CENTER, 340 font=("Arial", str(self.settings["font_size"] + 4)), 341 bg="#643181", 342 fg="#F2DAFF", 343 pady=6 344 ) 345 self.header.pack(fill=tk.X) 346 self.font_frame = tk.Frame(self.frame, bg="#1A181C") 347 self.font_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10) 348 self.font_label = tk.Label( 349 self.font_frame, 350 text="Font Size: ", 351 justify=tk.LEFT, 352 font=("Arial", str(self.settings["font_size"])), 353 bg="#1A181C", 354 fg="#F2DAFF", 355 pady=2 356 ) 357 self.font_label.pack(side=tk.LEFT) 358 self.font_options = [12, 14, 16, 18, 20, 24, 32] 359 self.font_dropdown = tk.StringVar() 360 self.font_dropdown.set(self.settings["font_size"]) 361 self.font_menu = tk.OptionMenu( 362 self.font_frame, 363 self.font_dropdown, 364 *self.font_options, 365 command=self.modify_font 366 ) 367 if sys.platform == "darwin": 368 self.font_menu.config(bg="#1A181C", fg="#643181") 369 else: 370 self.font_menu.config( 371 bg="#1A181C", 372 fg="#643181", 373 highlightbackground="#643181", 374 activebackground="#F2DAFF", 375 activeforeground="#1A181C" 376 ) 377 self.font_menu["menu"].config( 378 bg="#1A181C", 379 fg="#643181", 380 activebackground="#643181", 381 activeforeground="#F2DAFF" 382 ) 383 self.font_menu.pack(side=tk.LEFT) 384 self.dim_frame = tk.Frame(self.frame, bg="#1A181C") 385 self.dim_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10) 386 self.dim_label = tk.Label( 387 self.dim_frame, 388 text="Default window dimension: ", 389 justify=tk.LEFT, 390 font=("Arial", str(self.settings["font_size"])), 391 bg="#1A181C", 392 fg="#F2DAFF", 393 pady=2 394 ) 395 self.dim_label.pack(side=tk.LEFT) 396 self.dim_options = [ 397 "Small", 398 "Medium (Default)", 399 "Large", 400 "Extra Large" 401 ] 402 if self.settings["win_width"] == 500: 403 self.dim_start_value = "Small" 404 elif self.settings["win_width"] == 1000: 405 self.dim_start_value = "Large" 406 elif self.settings["win_width"] == 1200: 407 self.dim_start_value = "Extra Large" 408 else: 409 self.dim_start_value = "Medium (Default)" 410 self.dim_dropdown = tk.StringVar() 411 self.dim_dropdown.set(self.dim_start_value) 412 self.dim_menu = tk.OptionMenu( 413 self.dim_frame, 414 self.dim_dropdown, 415 *self.dim_options, 416 command=self.modify_dim 417 ) 418 if sys.platform == "darwin": 419 self.dim_menu.config(bg="#1A181C", fg="#643181") 420 else: 421 self.dim_menu.config( 422 bg="#1A181C", 423 fg="#643181", 424 highlightbackground="#643181", 425 activebackground="#F2DAFF", 426 activeforeground="#1A181C" 427 ) 428 self.dim_menu["menu"].config( 429 bg="#1A181C", 430 fg="#643181", 431 activebackground="#643181", 432 activeforeground="#F2DAFF" 433 ) 434 self.dim_menu.pack(side=tk.LEFT) 435 self.update_frame = tk.Frame(self.frame, bg="#1A181C") 436 self.update_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10) 437 self.update_label = tk.Label( 438 self.update_frame, 439 text="Update Status: ", 440 justify=tk.LEFT, 441 font=("Arial", str(self.settings["font_size"])), 442 bg="#1A181C", 443 fg="#F2DAFF", 444 pady=2 445 ) 446 self.update_label.pack(side=tk.LEFT) 447 self.update_bool = vc.update_available() 448 if self.update_bool == "available": 449 self.update_text = "Available" 450 self.update_color = "#84D373" 451 elif self.update_bool == "updated": 452 self.update_text = "Up to date!" 453 self.update_color = "#B1A5B8" 454 elif self.update_bool == "dev": 455 self.update_text = "Hello FIGBERT" 456 self.update_color = "#643181" 457 else: 458 self.update_text = "Connection failed" 459 self.update_color = "#FC142F" 460 self.update_status = tk.Label( 461 self.update_frame, 462 text=self.update_text, 463 justify=tk.LEFT, 464 font=("Arial", str(self.settings["font_size"])), 465 bg="#1A181C", 466 fg=self.update_color, 467 pady=2 468 ) 469 self.update_status.pack(side=tk.LEFT) 470 self.save_frame = tk.Frame(self.frame, bg="#1A181C", pady=5, padx=5) 471 self.save_frame.pack(side=tk.BOTTOM, fill=tk.BOTH) 472 if sys.platform == "darwin": 473 self.save_button = tk.Button( 474 self.save_frame, 475 fg="#643181", 476 text="Save", 477 font=("Arial", self.settings["font_size"] - 2), 478 highlightthickness=5, 479 highlightbackground="#1A181C", 480 padx=10, 481 pady=2, 482 command=lambda: self.close_settings(self.settings_window) 483 ) 484 else: 485 self.save_button = tk.Button( 486 self.save_frame, 487 fg="#643181", 488 bg="#8A8A8A", 489 text="Save", 490 font=("Arial", self.settings["font_size"] - 2), 491 padx=10, 492 pady=2, 493 command=lambda: self.close_settings(self.settings_window) 494 ) 495 self.save_button.pack(side=tk.LEFT) 496 self.settings_window.protocol( 497 "WM_DELETE_WINDOW", 498 lambda: self.close_settings(self.settings_window) 499 ) 500 self.settings_window.mainloop() 501 502 def launcher(self, settings): 503 self.launcher_window = tk.Toplevel() 504 self.launcher_window.wm_title("figENC") 505 self.canvas = tk.Canvas( 506 self.launcher_window, 507 height=settings["win_height"]/6, 508 width=settings["win_width"]/1.5 509 ) 510 self.canvas.pack(fill=tk.BOTH, expand=True) 511 self.frame = tk.Frame(self.canvas, bg="#1A181C") 512 self.frame.place(relwidth=1, relheight=1) 513 self.header = tk.Label( 514 self.frame, 515 text="Loading application...", 516 font=("Arial", ( 517 settings["font_size"]-2 if settings["font_size"]-2 > 0 else 2 518 ) 519 ), 520 bg="#1A181C", 521 fg="#F2DAFF", 522 pady=5 523 ) 524 self.header.pack(side=tk.TOP) 525 self.subheader = tk.Label( 526 self.frame, 527 text=self.pick_tip(), 528 font=("Arial", settings["font_size"]-4), 529 bg="#1A181C", 530 fg="#B494C7" 531 ) 532 self.subheader.pack(side=tk.TOP) 533 self.button_frame = tk.Frame(self.frame, bg="#1A181C", pady=5) 534 self.button_frame.pack(side=tk.TOP) 535 if sys.platform == "darwin": 536 self.launch_button = tk.Button( 537 self.button_frame, 538 fg="#643181", 539 text="Launch App", 540 font=("Arial", settings["font_size"]-6), 541 highlightthickness=5, 542 highlightbackground="#1A181C", 543 command=lambda: self.launch_app(root) 544 ) 545 self.settings_button = tk.Button( 546 self.button_frame, 547 fg="#643181", 548 text="Settings", 549 font=("Arial", settings["font_size"]-6), 550 highlightbackground="#1A181C", 551 highlightthickness=5, 552 command=lambda: self.open_settings(self.launcher_window) 553 ) 554 else: 555 self.launch_button = tk.Button( 556 self.button_frame, 557 fg="#643181", 558 bg="#8A8A8A", 559 text="Launch App", 560 font=("Arial", settings["font_size"]-6), 561 command=lambda: self.launch_app(root) 562 ) 563 self.settings_button = tk.Button( 564 self.button_frame, 565 fg="#643181", 566 bg="#8A8A8A", 567 text="Settings", 568 font=("Arial", settings["font_size"]-6), 569 command=lambda: self.open_settings(self.launcher_window) 570 ) 571 self.launch_button.pack(side=tk.LEFT) 572 self.settings_button.pack(side=tk.RIGHT) 573 self.launcher_window.protocol( 574 "WM_DELETE_WINDOW", 575 lambda: self.full_shutdown(self.launcher_window, root) 576 ) 577 578 def launch_app(self, root): 579 """Deiconify the passed root window, destroy the launcher 580 window and update the frame 581 582 Keyword arguments: 583 root -- the main app window 584 """ 585 with open(self.settings_file) as settings_file: 586 settings = json.load(settings_file) 587 self.main_app(root, settings) 588 root.deiconify() 589 self.launcher_window.destroy() 590 591 592 def reset(self): 593 """Hide all elements of the main app GUI and reset the entered text""" 594 self.file_frame.pack_forget() 595 self.file_label.pack_forget() 596 self.file_input.pack_forget() 597 self.passcode_frame.pack_forget() 598 self.passcode_label.pack_forget() 599 self.passcode_instructions.pack_forget() 600 self.reset_text(self.passcode_input) 601 self.passcode_input.pack_forget() 602 self.confirm_label.pack_forget() 603 self.confirm_instructions.pack_forget() 604 self.reset_text(self.confirm_input) 605 self.confirm_input.pack_forget() 606 self.save.pack_forget() 607 self.save_label.pack_forget() 608 self.save_instructions.pack_forget() 609 self.save_input.pack_forget() 610 self.type_frame.pack_forget() 611 self.type_label.pack_forget() 612 self.type_instructions.pack_forget() 613 self.type_button_frame.pack_forget() 614 self.rsa_radiobutton.pack_forget() 615 self.mixed_radiobutton.pack_forget() 616 self.submit.pack_forget() 617 618 def reset_text(self, entry_widget): 619 """Reset the string value of a tk.Entry object to an empty string 620 621 Keyword arguments: 622 entry_widget -- a tk.Entry object 623 """ 624 entry_widget.delete(0,tk.END) 625 entry_widget.insert(0,"") 626 627 def setup(self, mode): 628 """"Change the GUI to match the app mode, 629 based on the user's action_list selection. 630 631 Keyword arguments: 632 mode -- an int (0-6) corresponding with the action_list selection 633 """ 634 mode = mode[0] 635 if mode == 0: #Encrypt with fresh keys (password locked) 636 self.reset() 637 self.file_frame.pack(fill="both") 638 self.file_label.config(text="Filepath/s to the file/s to encrypt") 639 self.file_label.pack() 640 self.file_input.pack(fill="x") 641 self.passcode_frame.pack(fill="both") 642 self.passcode_label.config(text="Set private key passcode") 643 self.passcode_label.pack() 644 self.passcode_instructions.config( 645 text=( 646 "CRITICAL: DO NOT FORGET YOUR" 647 "PASSCODE.\nWITHOUT IT, " 648 "YOUR DATA WILL BE LOST." 649 ) 650 ) 651 self.passcode_instructions.pack() 652 self.passcode_input.pack(fill="x") 653 self.confirm_label.pack() 654 self.confirm_instructions.pack() 655 self.confirm_input.pack(fill="x") 656 self.save.pack(fill="both") 657 self.save_label.config(text="Save location for keys") 658 self.save_label.pack() 659 self.save_instructions.config( 660 text=( 661 "Save the keys to an empty folder, " 662 "and store them somewhere secure\n" 663 "If other key files exist in the same" 664 "folder, they will be overwritten" 665 ) 666 ) 667 self.save_instructions.pack() 668 self.save_input.pack(fill="x") 669 self.submit.config(text="Encrypt file/s") 670 self.submit.pack(pady=10) 671 self.crypto_mode = "key_enc" 672 self.frame.update() 673 elif mode == 1: #Encrypt with fresh keys (no password) 674 self.reset() 675 self.file_frame.pack(fill="both") 676 self.file_label.config(text="Filepath/s to the file/s to encrypt") 677 self.file_label.pack() 678 self.file_input.pack(fill="x") 679 self.save.pack(fill="both") 680 self.save_label.config(text="Save location for keys") 681 self.save_label.pack() 682 self.save_instructions.config( 683 text=( 684 "Save the keys to an empty folder, " 685 "and store them somewhere secure\n" 686 "If other key files exist in the same" 687 "folder, they will be overwritten" 688 ) 689 ) 690 self.save_instructions.pack() 691 self.save_input.pack(fill="x") 692 self.submit.config(text="Encrypt file/s") 693 self.submit.pack(pady=10) 694 self.crypto_mode = "weak_key_enc" 695 self.frame.update() 696 elif mode == 2: #Encrypt with generated keys 697 self.reset() 698 self.file_frame.pack(fill="both") 699 self.file_label.config(text="Filepath/s to the file/s to encrypt") 700 self.file_label.pack() 701 self.file_input.pack(fill="x") 702 self.save.pack(fill="both") 703 self.save_label.config(text="Key location") 704 self.save_label.pack() 705 self.save_instructions.config( 706 text="Filepath to matching key trio" 707 ) 708 self.save_instructions.pack() 709 self.save_input.pack(fill="x") 710 self.submit.config(text="Encrypt file/s") 711 self.submit.pack(pady=10) 712 self.crypto_mode = "enc" 713 self.frame.update() 714 elif mode == 3: #Decrypt with generated keys (password locked) 715 self.reset() 716 self.file_frame.pack(fill="both") 717 self.file_label.config(text="Filepath/s to the file/s to decrypt") 718 self.file_label.pack() 719 self.file_input.pack(fill="x") 720 self.passcode_frame.pack(fill="both") 721 self.passcode_label.config(text="Private key passcode") 722 self.passcode_label.pack() 723 self.passcode_instructions.config( 724 text=( 725 "Passcode must be the same " 726 "passcode used when the keys were created" 727 ) 728 ) 729 self.passcode_instructions.pack() 730 self.passcode_input.pack(fill="x") 731 self.confirm_label.pack() 732 self.confirm_instructions.pack() 733 self.confirm_input.pack(fill="x") 734 self.save.pack(fill="both") 735 self.save_label.config(text="Key location") 736 self.save_label.pack() 737 self.save_instructions.config( 738 text="Filepath to matching key trio" 739 ) 740 self.save_instructions.pack() 741 self.save_input.pack(fill="x") 742 self.submit.config(text="Decrypt file/s") 743 self.submit.pack(pady=10) 744 self.crypto_mode = "dec" 745 self.frame.update() 746 elif mode == 4: #Decrypt with generated keys (no password) 747 self.reset() 748 self.file_frame.pack(fill="both") 749 self.file_label.config(text="Filepath/s to the file/s to decrypt") 750 self.file_label.pack() 751 self.file_input.pack(fill="x") 752 self.save.pack(fill="both") 753 self.save_label.config(text="Key location") 754 self.save_label.pack() 755 self.save_instructions.config( 756 text="Filepath to matching key trio" 757 ) 758 self.save_instructions.pack() 759 self.save_input.pack(fill="x") 760 self.submit.config(text="Decrypt file/s") 761 self.submit.pack(pady=10) 762 self.crypto_mode = "weak_dec" 763 self.frame.update() 764 elif mode == 5: #Only create fresh keys (password locked) 765 self.reset() 766 self.passcode_frame.pack(fill="both") 767 self.passcode_label.config(text="Set private key passcode") 768 self.passcode_label.pack() 769 self.passcode_instructions.config( 770 text=( 771 "CRITICAL: DO NOT FORGET YOUR PASSCODE.\nWITHOUT IT, " 772 "YOUR DATA WILL BE LOST." 773 ) 774 ) 775 self.passcode_instructions.pack() 776 self.passcode_input.pack(fill="x") 777 self.confirm_label.pack() 778 self.confirm_instructions.pack() 779 self.confirm_input.pack(fill="x") 780 self.save.pack(fill="both") 781 self.save_label.config(text="Save location for keys") 782 self.save_label.pack() 783 self.save_instructions.config( 784 text=( 785 "Save the keys to an empty folder, " 786 "and store them somewhere secure\n" 787 "If other key files exist in the same" 788 "folder, they will be overwritten" 789 ) 790 ) 791 self.save_instructions.pack() 792 self.save_input.pack(fill="x") 793 self.type_frame.pack() 794 self.type_label.pack() 795 self.type_instructions.pack() 796 self.type_button_frame.pack() 797 self.rsa_radiobutton.pack(side=tk.LEFT) 798 self.mixed_radiobutton.pack(side=tk.LEFT) 799 self.submit.config(text="Create keys") 800 self.submit.pack(pady=10) 801 self.crypto_mode = "just_key" 802 self.frame.update() 803 elif mode == 6: #Only create fresh keys (no password) 804 self.reset() 805 self.save.pack(fill="both") 806 self.save_label.config(text="Save location for keys") 807 self.save_label.pack() 808 self.save_instructions.config( 809 text=( 810 "Save the keys to an empty folder, " 811 "and store them somewhere secure\n" 812 "If other key files exist in the same" 813 "folder, they will be overwritten" 814 ) 815 ) 816 self.save_instructions.pack() 817 self.save_input.pack(fill="x") 818 self.type_frame.pack() 819 self.type_label.pack() 820 self.type_instructions.pack() 821 self.type_button_frame.pack() 822 self.rsa_radiobutton.pack(side=tk.LEFT) 823 self.mixed_radiobutton.pack(side=tk.LEFT) 824 self.submit.config(text="Create keys") 825 self.submit.pack(pady=10) 826 self.crypto_mode = "weak_key" 827 self.frame.update() 828 829 def go( 830 self, 831 mode, 832 key_dir=None, 833 target_files=None, 834 passkey=None, 835 passcheck=None 836 ): 837 """Perform the action corresponding to the mode, 838 using the input data from the user, after checking the validity 839 of the filepaths. 840 841 Keyword arguments: 842 mode -- the mode defined by setup() from action_list 843 save_folder -- the folder where the keys are or will be stored 844 target_file -- the file to encrypt or decrypt 845 passkey - the access code to the RSA keys that have them 846 passcheck - the access code to the RSA keys that have them confirmed, 847 to prevent spelling errors. 848 """ 849 if mode == "key_enc" and check.key_enc( 850 target_files, 851 passkey, 852 passcheck, 853 key_dir 854 ): 855 key.key_manager(target_files, key_dir, passkey) 856 enc_manager(target_files, key_dir) 857 elif mode == "weak_key_enc" and check.weak_key_enc( 858 target_files, 859 key_dir 860 ): 861 key.key_manager(target_files, key_dir, passkey) 862 enc_manager(target_files, key_dir) 863 elif mode == "enc" and check.enc(target_files, key_dir): 864 enc_manager(target_files, key_dir) 865 elif mode == "dec" and check.dec( 866 target_files, 867 passkey, 868 passcheck, 869 key_dir 870 ): 871 dec_manager(target_files, key_dir, passkey) 872 elif mode == "weak_dec" and check.weak_dec(target_files, key_dir): 873 dec_manager(target_files, key_dir, passkey) 874 elif mode == "just_key" and check.key(key_dir, passkey, passcheck): 875 key.just_key_manager(self.type_control.get(), key_dir, passkey) 876 elif mode == "weak_key" and check.weak_key(key_dir): 877 key.just_key_manager(self.type_control.get(), key_dir, passkey) 878 879 def pick_tip(self): 880 """Return a random string from the tips.json file""" 881 with open(self.tips_file) as source: 882 self.tips = json.load(source) 883 self.tip = "Tip: " + choice(self.tips) 884 return self.tip 885 886 def close_settings(self, settings_window): 887 """Destroy the settings toplevel and deiconify the root window 888 889 Keyword arguments: 890 settings_window -- the window of the app to destroy 891 root -- the window of the app to deiconify() 892 """ 893 settings_window.destroy() 894 with open(self.settings_file) as settings_file: 895 settings = json.load(settings_file) 896 self.launcher(settings) 897 898 def full_shutdown(self, launcher_window, root): 899 """Destroy the launcher window and the root window 900 901 Keyword arguments: 902 launcher_window -- the window of the app to destroy 903 root -- another app to destroy 904 """ 905 launcher_window.destroy() 906 root.destroy() 907 908 def modify_font(self, value): 909 """Change the value of the font_size key in the self.settings variable 910 and export settings to file. 911 912 Keyword arguments: 913 value -- the int to which the self.settings variable will change 914 """ 915 self.settings["font_size"] = value 916 with open(self.settings_file, "w") as fl: 917 json.dump(self.settings, fl, indent=4, sort_keys=True) 918 919 def modify_dim(self, value): 920 """Change the value of the win_width key in the self.settings 921 variable and export settings to file. 922 923 Keyword arguments: 924 value -- an int represeting the new width of the window 925 """ 926 if value == "Small": 927 dim = 500 928 elif value == "Large": 929 dim = 1000 930 elif value == "Extra Large": 931 dim = 1200 932 else: 933 dim = 700 934 self.settings["win_width"] = dim 935 self.settings["win_height"] = dim 936 with open(self.settings_file, "w") as fl: 937 json.dump(self.settings, fl, indent=4, sort_keys=True) 938 939 def toggle_pass(self, *args): 940 """Toogle the password fields between showing the characters and 941 hiding them. 942 """ 943 if self.show_pass: 944 self.passcode_input.config(show="") 945 self.confirm_input.config(show="") 946 self.show_pass = not self.show_pass 947 else: 948 self.passcode_input.config(show="*") 949 self.confirm_input.config(show="*") 950 self.show_pass = not self.show_pass 951 952 def select_filepaths(self): 953 """Set the cryptofilepath variable to the tuple result of a 954 tkinter filenames filedialog 955 """ 956 self.crypto_filepaths = filedialog.askopenfilenames() 957 self.file_input.config( 958 text=self.crypto_filepaths[0] if len(self.crypto_filepaths) == 1 else self.crypto_filepaths[0] + "..." 959 ) 960 961 def select_key_dir(self): 962 """Set the key_paths variable to the string result of a tkinter 963 askdirectory filedialog. If on MacOS, the start directory will 964 be home folder of the current user. 965 """ 966 if sys.platform == "darwin": 967 self.key_paths = filedialog.askdirectory(initialdir="/Users/%s"%getpass.getuser()) 968 else: 969 self.key_paths = filedialog.askdirectory() 970 self.save_input.config(text=self.key_paths) 971 972 973 if __name__ == "__main__": 974 root = tk.Tk() 975 App(root) 976 if sys.platform == "darwin": 977 icon_path = find_path('icon-windowed.icns') 978 else: 979 icon_path = find_path('icon-windowed.ico') 980 root.iconbitmap(icon_path) 981 root.mainloop()