def initialize_gui_config(): gui_config = configparser.ConfigParser() gui_config["connections"] = { "display_secure_core": False } gui_config["general_tab"] = { "start_min": False, "start_on_boot": False, "show_notifications": False, } gui_config["tray_tab"] = { TRAY_CFG_DATA_TX: "0", TRAY_CFG_SERVENAME: "0", TRAY_CFG_TIME_CONN: "0", TRAY_CFG_SERVERLOAD: "0", } gui_config["conn_tab"] = { "autoconnect": "dis", "quick_connect": "dis", } try: with open(GUI_CONFIG_FILE, "w") as f: gui_config.write(f) change_file_owner(GUI_CONFIG_FILE) gui_logger.debug("pvpn-gui.cfg initialized.") return True except: gui_logger.debug("Unablt to initialize pvpn-gui.cfg.") return False
def set_split_tunnel(self): """Enable or disable split tunneling""" with open(pvpncli_constants.SPLIT_TUNNEL_FILE, "a") as f: f.write(f'\n{self.split_tunneling_ip_list.text}') if os.path.isfile(pvpncli_constants.SPLIT_TUNNEL_FILE): pvpncli_utils.change_file_owner( pvpncli_constants.SPLIT_TUNNEL_FILE) else: # If no file exists, split tunneling should be disabled again. pvpncli_logger.logger.debug("No split tunneling file existing.") self.set_config_value("USER", "split_tunnel", 0) os.remove(pvpncli_constants.SPLIT_TUNNEL_FILE) # Update OpenVPN template. pvpncli_utils.make_ovpn_template()
def init_config_file(self): """"Initialize configuration file.""" config = ConfigParser() config["USER"] = { "username": "******", "tier": "None", "default_protocol": "None", "initialized": "0", "dns_leak_protection": "1", "custom_dns": "None", "check_update_interval": "3", } config["metadata"] = { "last_api_pull": "0", "last_update_check": str(int(time())), } with open(pvpncli_constants.CONFIG_FILE, "w") as f: config.write(f) pvpncli_utils.change_file_owner(pvpncli_constants.CONFIG_FILE) pvpncli_logger.logger.debug("pvpn-cli.cfg initialized")
def on_login(interface, username_field, password_field, messagedialog_label, user_window, login_window, messagedialog_window): """Function that initializes a user profile. """ server_list_object = interface.get_object("ServerListStore") populate_servers_dict = { "list_object": server_list_object, "servers": False } user_data = prepare_initilizer(username_field, password_field, interface) config = configparser.ConfigParser() config["USER"] = { "username": "******", "tier": "None", "default_protocol": "None", "initialized": "0", "dns_leak_protection": "1", "custom_dns": "None", "check_update_interval": "3", "killswitch": "0", "split_tunnel": "0", "autoconnect": "0" } config["metadata"] = { "last_api_pull": "0", "last_update_check": str(int(time.time())), } with open(CONFIG_FILE, "w") as f: config.write(f) change_file_owner(CONFIG_FILE) gui_logger.debug("pvpn-cli.cfg initialized") change_file_owner(CONFIG_DIR) ovpn_username = user_data['username'] ovpn_password = user_data['password'] user_tier = user_data['protonvpn_plan'] user_protocol = user_data['openvpn_protocol'] pull_server_data(force=True) make_ovpn_template() if user_tier == 4: user_tier = 3 user_tier -= 1 set_config_value("USER", "username", ovpn_username) set_config_value("USER", "tier", user_tier) set_config_value("USER", "default_protocol", user_protocol) set_config_value("USER", "dns_leak_protection", 1) set_config_value("USER", "custom_dns", None) set_config_value("USER", "killswitch", 0) set_config_value("USER", "split_tunnel", 0) set_config_value("USER", "autoconnect", "0") with open(PASSFILE, "w") as f: f.write("{0}\n{1}".format(ovpn_username, ovpn_password)) gui_logger.debug("Passfile created") os.chmod(PASSFILE, 0o600) gui_config = configparser.ConfigParser() gui_config["connections"] = {"display_secure_core": False} gui_config["general_tab"] = { "start_min": False, "start_on_boot": False, "show_notifications": False, } gui_config["tray_tab"] = { TRAY_CFG_DATA_TX: "0", TRAY_CFG_SERVENAME: "0", TRAY_CFG_TIME_CONN: "0", TRAY_CFG_SERVERLOAD: "0", } gui_config["conn_tab"] = { "autoconnect": "dis", "quick_connect": "dis", } with open(GUI_CONFIG_FILE, "w") as f: gui_config.write(f) change_file_owner(GUI_CONFIG_FILE) gui_logger.debug("pvpn-gui.cfg initialized") set_config_value("USER", "initialized", 1) load_on_start({ "interface": interface, "gui_enabled": True, "messagedialog_label": messagedialog_label })
def update_split_tunneling(interface, messagedialog_label, messagedialog_spinner): """Function that updates split tunneling configurations. """ result = "Split tunneling configurations <b>updated</b>!\n" split_tunneling_buffer = interface.get_object( "split_tunneling_textview").get_buffer() # Get text takes a start_iter, end_iter and the buffer itself as last param split_tunneling_content = split_tunneling_buffer.get_text( split_tunneling_buffer.get_start_iter(), split_tunneling_buffer.get_end_iter(), split_tunneling_buffer) # Split IP/CIDR by either ";" and/or "\n" split_tunneling_content = re.split('[;\n]', split_tunneling_content) # Remove empty spaces split_tunneling_content = [ content.strip() for content in split_tunneling_content ] # Remove empty list elements split_tunneling_content = list(filter(None, split_tunneling_content)) for ip in split_tunneling_content: if not is_valid_ip(ip): messagedialog_spinner.hide() messagedialog_label.set_markup( "<b>{0}</b> is not valid!\nNone of the IP's were added, please try again with a different IP." .format(ip)) gui_logger.debug("[!] Invalid IP \"{0}\".".format(ip)) return gui_logger.debug(">>> Running \"set_split_tunnel\".") if len(split_tunneling_content) == 0: set_config_value("USER", "split_tunnel", 0) if os.path.isfile(SPLIT_TUNNEL_FILE): os.remove(SPLIT_TUNNEL_FILE) result = "Split tunneling <b>disabled</b>!\n\n" if int(get_config_value("USER", "killswitch")): set_config_value("USER", "killswitch", 0) result = result + "Split Tunneling <b>can't</b> be used with Kill Switch.\nKill Switch has been <b>disabled</b>!\n\n" time.sleep(1) set_config_value("USER", "split_tunnel", 1) with open(SPLIT_TUNNEL_FILE, "w") as f: for ip in split_tunneling_content: f.write("\n{0}".format(ip)) if os.path.isfile(SPLIT_TUNNEL_FILE): change_file_owner(SPLIT_TUNNEL_FILE) if len(split_tunneling_content) > 0: result = result + "The following servers were added:\n\n{}".format( [ip for ip in split_tunneling_content]) else: # If no no config file exists, # split tunneling should be disabled again gui_logger.debug("No split tunneling file existing.") set_config_value("USER", "split_tunnel", 0) result = "No split tunneling file was found, split tunneling will be <b>disabled</b>!\n\n" messagedialog_label.set_markup(result) messagedialog_spinner.hide() gui_logger.debug(">>> Result: \"{0}\"".format(result)) gui_logger.debug(">>> Ended tasks in \"set_split_tunnel\" thread.")
def initialize_gui(): """Initializes the GUI --- If user has not initialized a profile, the GUI will ask for the following data: - Username - Password - Plan - Protocol sudo protonvpn-gui - Will start the GUI without invoking cli() """ interface = Gtk.Builder() posixPath = pathlib.PurePath(pathlib.Path(__file__).parent.absolute().joinpath("resources/main.glade")) glade_path = '' for path in posixPath.parts: if path == '/': glade_path = glade_path + path else: glade_path = glade_path + path + "/" interface.add_from_file(glade_path[:-1]) css = re.sub("main.glade", "main.css", glade_path) style_provider = Gtk.CssProvider() style_provider.load_from_path(css[:-1]) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) messagedialog_window = interface.get_object("MessageDialog") messagedialog_label = interface.get_object("message_dialog_label") messagedialog_spinner = interface.get_object("message_dialog_spinner") if not find_cli(): messagedialog_spinner.hide() message = """ <b>Could not find protonvpn-cli-ng installed on your system!</b>\t Original protonvpn-cli-ng is needed for the GUI to work. <b>Install via pip:</b> sudo pip3 install protonvpn-cli <b>Install via Github:</b> git clone https://github.com/protonvpn/protonvpn-cli-ng cd protonvpn-cli-ng sudo python3 setup.py install """ message_dialog_close_button = interface.get_object("message_dialog_close_button") message_dialog_close_button.hide() messagedialog_label.set_markup(message) messagedialog_window.show() messagedialog_window.connect("destroy", Gtk.main_quit) else: interface.connect_signals(Handler(interface)) check_root() if not os.path.isdir(GUI_CONFIG_DIR): os.mkdir(GUI_CONFIG_DIR) gui_logger.debug("Config Directory created") change_file_owner(GUI_CONFIG_DIR) gui_logger.debug("\n______________________________________\n\n\tINITIALIZING NEW GUI WINDOW\n______________________________________\n") try: change_file_owner(os.path.join(GUI_CONFIG_DIR, "protonvpn-gui.log")) except: pass if len(get_gui_processes()) > 1: gui_logger.debug("[!] Two processes were found. Displaying MessageDialog to inform user.") messagedialog_label.set_markup("Another GUI process was found, attempting to end it...") messagedialog_spinner.show() messagedialog_window.show() time.sleep(1) response = kill_duplicate_gui_process() if not response['success']: messagedialog_label.set_markup(response['message']) messagedialog_spinner.hide() time.sleep(3) sys.exit(1) messagedialog_label.set_markup(response['message']) messagedialog_spinner.hide() if not os.path.isfile(CONFIG_FILE): gui_logger.debug(">>> Loading LoginWindow") window = interface.get_object("LoginWindow") dashboard = interface.get_object("DashboardWindow") dashboard.connect("destroy", Gtk.main_quit) else: window = interface.get_object("DashboardWindow") gui_logger.debug(">>> Loading DashboardWindow") window.connect("destroy", Gtk.main_quit) messagedialog_window = interface.get_object("MessageDialog") messagedialog_label = interface.get_object("message_dialog_label") interface.get_object("message_dialog_sub_label").hide() messagedialog_spinner = interface.get_object("message_dialog_spinner") messagedialog_label.set_markup("Loading...") messagedialog_spinner.show() messagedialog_window.show() objects = { "interface": interface, "messagedialog_window": messagedialog_window, "messagedialog_label": messagedialog_label, "messagedialog_spinner": messagedialog_spinner, } thread = Thread(target=load_content_on_start, args=[objects]) thread.daemon = True thread.start() window.show() Gtk.main()
def after_init(self, dt): # Determine if profile has already been initialized try: self.is_initialized = (int( pvpncli_utils.get_config_value("USER", "initialized"))) except KeyError: self.is_initialized = None # Get app reference self.app = App.get_running_app() # Set input field references # Username self.username = (self.app.root.ids.vpn_settings_screen.ids.username) # Password self.password = (self.app.root.ids.vpn_settings_screen.ids.password) self.password_show = ( self.app.root.ids.vpn_settings_screen.ids.password_show) self.password_confirm = ( self.app.root.ids.vpn_settings_screen.ids.password_confirm) self.password_confirm_show = ( self.app.root.ids.vpn_settings_screen.ids.password_confirm_show) # Proton VPN Plan self.pvpn_plan = (self.app.root.ids.vpn_settings_screen.ids.pvpn_plan) # Default Protocol self.default_protocol = ( self.app.root.ids.vpn_settings_screen.ids.default_protocol) # DNS Management self.dns_management = ( self.app.root.ids.vpn_settings_screen.ids.dns_management) self.dns_selection = ( self.app.root.ids.vpn_settings_screen.ids.dns_spinner) self.dns_server_list = Dns_Input( hint_text=' Enter DNS IPs (space-separated; max 3)', padding=[0, 15, 0, 0]) self.dns_server_list.name = '_dns_server_list_' self.dns_server_list.background_normal = ( './images/text-input-background-normal-highlight.png') self.dns_server_list.background_active = ( './images/text-input-background-active-highlight.png') # Kill Switch & Split Tunneling self.kill_switch = ( self.app.root.ids.vpn_settings_screen.ids.kill_switch) self.split_tunneling = ( self.app.root.ids.vpn_settings_screen.ids.split_tunneling) self.split_tunneling_spinner = ( self.app.root.ids.vpn_settings_screen.ids.split_tunneling_spinner) self.split_tunneling_ip_list = Dns_Input( hint_text=' Enter IP/CIDR to exclude from VPN', padding=[0, 15, 0, 0], ) self.split_tunneling_ip_list.name = '_split_tunnel_ip_list_' self.split_tunneling_ip_list.background_normal = ( './images/text-input-background-normal-highlight.png') self.split_tunneling_ip_list.background_active = ( './images/text-input-background-active-highlight.png') self.update_button = ( self.app.root.ids.vpn_settings_screen.ids.update_button) # If profile already initialized, load profile values. if self.is_initialized: self.get_current_values() self.set_current_values() else: if self.is_initialized is None: # Create directory if not already there. if not os.path.isdir(pvpncli_constants.CONFIG_DIR): os.mkdir(pvpncli_constants.CONFIG_DIR) pvpncli_logger.logger.debug("Config Directory created") pvpncli_utils.change_file_owner( pvpncli_constants.CONFIG_DIR) # Initialize config file. self.init_config_file() # Create OpenVPN template. pvpncli_utils.make_ovpn_template() # Set values to detect updates self.username_val = self.username.text self.passwd_val = self.password.text self.tier_val = self.pvpn_plan.text self.prot_val = self.default_protocol.text self.dns_val = self.dns_selection.text self.dns_ip_val = self.dns_server_list.text self.kill_switch_val = self.kill_switch.text self.split_tunl_val = self.split_tunneling_spinner.text self.split_tunnel_ips = self.split_tunneling_ip_list.text # Set bindings: self.password.bind(text=self.enable_confirm_password) self.password_confirm.bind(disabled=self.show_password_confirm_disable) self.dns_selection.bind(text=self.configure_dns_servers) self.kill_switch.bind(text=partial(self.split_tunnel_or_kill_switch, self.kill_switch.name)) self.split_tunneling_spinner.bind( text=partial(self.split_tunnel_or_kill_switch, self.split_tunneling_spinner.name)) self.split_tunneling_spinner.bind(text=self.configure_split_tunnel_ip) # Enable Update button upon changes self.username.bind(text=self.update_button_enable) self.password.bind(text=self.update_button_enable) self.pvpn_plan.bind(text=self.update_button_enable) self.dns_selection.bind(text=self.update_button_enable) self.dns_server_list.bind(text=self.update_button_enable) self.default_protocol.bind(text=self.update_button_enable) self.kill_switch.bind(text=self.update_button_enable) self.split_tunneling_spinner.bind(text=self.update_button_enable) self.split_tunneling_ip_list.bind(text=self.update_button_enable)