def import_config(self, file_path: str, username: str, password: str) -> bool: updated = False imported = False if self.remove_legacy_files(): self.logger.info("Removed legacy files") if not os.path.isfile(file_path): self.logger.error("Configuration file '%s' does not exist.", file_path) return None # remove all old connections and any auto-connect, until a better import routine is added if self.remove_active_connections(): updated = True if networkmanager.remove_autoconnect(): updated = True dns_list = self.settings.get_custom_dns_servers() connection_name = os.path.splitext(os.path.basename(file_path))[0] if networkmanager.import_connection(file_path, connection_name, username, password, dns_list): updated = True imported = True self.active_servers[IMPORTED_SERVER_KEY] = { 'name': connection_name, 'domain': '<' + connection_name + '>', 'score': -1, 'load': -1, 'latency': -1, } self.save_active_servers(self.active_servers, paths.ACTIVE_SERVERS) if updated: networkmanager.reload_connections() return imported
def run(self, credentials, settings, update, sync, purge, auto_connect, kill_switch): self.setup() if credentials: self.credentials.save_new_credentials() if settings: self.settings.save_new_settings() if update: self.get_configs() if sync: if self.sync_servers(): networkmanager.reload_connections() elif purge: networkmanager.remove_autoconnect() networkmanager.remove_killswitch(paths.KILLSWITCH) self.purge_active_connections() if auto_connect: self.enable_auto_connect(auto_connect[0], auto_connect[1], auto_connect[2]) if kill_switch: networkmanager.set_killswitch(paths.KILLSWITCH)
def sync(self, update_config=True, preserve_vpn=False, slow_mode=False): if self.remove_legacy_files(): self.logger.info("Removed legacy files") if update_config: self.get_configs() if self.sync_servers(preserve_vpn, slow_mode): networkmanager.reload_connections()
def __init__(self): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title="commands", help="Each command has its own help page, which can be accessed via nordnm <COMMAND> --help", metavar='') # Kill-switch and auto-connect are repeated, to allow their use with or without the sync command. # TODO: Find out if there's a way to re-use the attributes so they don't need to be manually repeated parser.add_argument("-v", "--version", help="Display the package version.", action="store_true") parser.add_argument("-k", "--kill-switch", help="Sets a network kill-switch, to disable the active network interface when an active VPN connection disconnects.", action="store_true") parser.add_argument("-a", "--auto-connect", nargs=3, metavar=("[COUNTRY_CODE]", "[VPN_CATEGORY]", "[PROTOCOL]"), help="Configure NetworkManager to auto-connect to the chosen server type. Takes country code, category and protocol.") remove_parser = subparsers.add_parser("remove", aliases=['r'], help="Remove active connections, auto-connect, kill-switch, data, mac settings or all.") remove_parser.add_argument("--all", dest="remove_all", help="Remove all connections, enabled features and local data.", action="store_true") remove_parser.add_argument("-c", "--connections", dest="remove_c", help="Remove all active connections and auto-connect.", action="store_true") remove_parser.add_argument("-a", "--auto-connect", dest="remove_ac", help="Remove the active auto-connect feature.", action="store_true") remove_parser.add_argument("-k", "--kill-switch", dest="remove_ks", help="Remove the active kill-switch feature.", action="store_true") remove_parser.add_argument("-d", "--data", dest="remove_d", help="Remove existing local data (VPN Configs, Credentials & Settings).", action="store_true") remove_parser.add_argument("-m", "--mac-settings", dest="remove_m", help="Remove existing MAC Address settings configured by nordnm.", action="store_true") remove_parser.set_defaults(remove=True) update_parser = subparsers.add_parser('update', aliases=['u'], help='Update a specified setting.') update_parser.add_argument('-c', '--credentials', help='Update your existing saved credentials.', action='store_true') update_parser.add_argument('-s', '--settings', help='Update your existing saved settings.', action='store_true') update_parser.set_defaults(update=True) list_parser = subparsers.add_parser('list', aliases=['l'], help="List the specified information.") list_parser.add_argument('--active-servers', help='Display a list of the active servers currently synchronised.', action='store_true', default=False) list_parser.add_argument('--countries', help='Display a list of the available NordVPN countries.', action='store_true', default=False) list_parser.add_argument('--categories', help='Display a list of the available NordVPN categories..', action='store_true', default=False) list_parser.set_defaults(list=True) sync_parser = subparsers.add_parser('sync', aliases=['s'], help="Synchronise the optimal servers (based on load and latency) to NetworkManager.") sync_parser.add_argument('-s', '--slow-mode', help="Run benchmarking in 'slow mode'. May increase benchmarking success by pinging servers at a slower rate.", action='store_true') sync_parser.add_argument('-p', '--preserve-vpn', help="When provided, synchronising will preserve any active VPN instead of disabling it for more accurate benchmarking.", action='store_true') sync_parser.add_argument('-n', '--no-update', help='Do not download the latest OpenVPN configurations from NordVPN.', action='store_true', default=False) sync_parser.add_argument("-k", "--kill-switch", help="Sets a network kill-switch, to disable the active network interface when an active VPN connection disconnects.", action="store_true") sync_parser.add_argument('-a', '--auto-connect', nargs=3, metavar=('[COUNTRY_CODE]', '[VPN_CATEGORY]', '[PROTOCOL]'), help='Configure NetworkManager to auto-connect to the chosen server type. Takes country code, category and protocol.') sync_parser.set_defaults(sync=True) import_parser = subparsers.add_parser('import', aliases=['i'], help="Import an OpenVPN config file to NetworkManager.") import_parser.add_argument("config_file", metavar='CONFIG_FILE', help="The OpenVPN config file to be imported.") import_parser.add_argument("-k", "--kill-switch", help="Sets a network kill-switch, to disable the active network interface when an active VPN connection disconnects.", action="store_true") import_parser.add_argument('-a', '--auto-connect', help='Configure NetworkManager to auto-connect to the the imported config.', action="store_true", dest="auto_connect_imported", default=False) import_parser.add_argument('-u', '--username', required=True, help="Specify the username used for the OpenVPN config.", metavar="USERNAME") import_parser.add_argument('-p', '--password', required=True, help="Specify the password used for the OpenVPN config.", metavar="PASSWORD") import_parser.set_defaults(import_config=True) # For reference: https://blogs.gnome.org/thaller/category/networkmanager/ mac_parser = subparsers.add_parser('mac', aliases=['m'], help="Global NetworkManager MAC address preferences. This command will affect ALL NetworkManager connections permanently.") mac_parser.add_argument('-r', '--random', help="A randomised MAC addresss will be generated on each connect.", action='store_true') mac_parser.add_argument('-s', '--stable', help="Use a stable, hashed MAC address on connect.", action='store_true') mac_parser.add_argument('-e', '--explicit', help="Specify a MAC address to use on connect.", nargs=1, metavar='"MAC_ADDRESS"') mac_parser.add_argument('--preserve', help="Don't change the current MAC address upon connection.", action='store_true') mac_parser.add_argument('--permanent', help="Use the permanent MAC address of the device on connect.", action='store_true') mac_parser.set_defaults(mac=True) self.logger = logging.getLogger(__name__) self.active_servers = {} try: args = parser.parse_args() except Exception: parser.print_help() sys.exit(1) # Count the number of arguments provided arg_count = 0 for arg in vars(args): if getattr(args, arg): arg_count += 1 if arg_count == 0: parser.print_help() sys.exit(1) if "version" in args and args.version: print(__version__) sys.exit(1) self.print_splash() # Check for commands that should be run on their own if "remove" in args and args.remove: removed = False if not args.remove_c and not args.remove_d and not args.remove_ac and not args.remove_ks and not args.remove_m and not args.remove_all: remove_parser.print_help() sys.exit(1) if args.remove_all: # Removing all, so set all args to True args.remove_ks = True args.remove_ac = True args.remove_c = True args.remove_d = True args.remove_m = True elif args.remove_c: # We need to remove the auto-connect if we are removing all connections args.remove_ac = True if args.remove_ks: if networkmanager.remove_killswitch(): removed = True if args.remove_ac: if networkmanager.remove_autoconnect(): removed = True if args.remove_c: # Get the active servers, since self.setup() hasn't run if os.path.isfile(paths.ACTIVE_SERVERS): self.active_servers = self.load_active_servers(paths.ACTIVE_SERVERS) if self.remove_active_connections(): removed = True if args.remove_d: if self.remove_data(): removed = True if args.remove_m: if networkmanager.remove_global_mac_address(): removed = True if removed: networkmanager.reload_connections() else: self.logger.info("Nothing to remove.") sys.exit(0) elif "list" in args and args.list: if not args.countries and not args.categories and not args.active_servers: list_parser.print_help() sys.exit(1) if args.categories: self.print_categories() if args.countries: self.print_countries() if args.active_servers: self.print_active_servers() sys.exit(0) elif "mac" in args and args.mac: value = None if args.random: value = "random" elif args.stable: value = "stable" elif args.explicit: value = args.explicit[0] elif args.preserve: value = "preserve" elif args.permanent: value = "permanent" if value: if networkmanager.set_global_mac_address(value): networkmanager.restart() else: mac_parser.print_help() # Now that arguments that don't need to be disturbed by setup() are over, do setup() self.setup() if "update" in args and args.update: if not args.credentials and not args.settings: update_parser.print_help() sys.exit(1) if args.credentials: self.credentials.save_new_credentials() if args.settings: self.settings.save_new_settings() sys.exit(0) # Now check for commands that can be chained... if "sync" in args and args.sync: # Take the inverse of no_update arg as update parameter self.sync(not args.no_update, args.preserve_vpn, args.slow_mode) if "import_config" in args and args.import_config: if not self.import_config(args.config_file, args.username, args.password): sys.exit(1) if args.auto_connect_imported: self.enable_auto_connect(*IMPORTED_SERVER_KEY) if args.kill_switch: networkmanager.set_killswitch() if args.auto_connect: country_code = args.auto_connect[0] category = args.auto_connect[1] protocol = args.auto_connect[2] self.enable_auto_connect(country_code, category, protocol) sys.exit(0)
def sync(self, preserve_vpn=False): # remove legacy files if self.sync_servers(preserve_vpn): networkmanager.reload_connections()