def __import(server_opts: ServerOpts, hub_password: str, vpn_opts: ToolOpts, group: str, certs_file: str, output_opts: OutputOpts): executor = VPNAuthExecutor(vpn_opts, server_opts, hub_password) data = JsonHelper.read(certs_file, strict=False) tmp_dir = FileHelper.tmp_dir('vpn_auth') command_file = FileHelper.touch(tmp_dir.joinpath('vpncmd.txt')) vpn_acc = {} for k, v in data.items(): cert_file = tmp_dir.joinpath(f'{k}.cert') FileHelper.write_file(cert_file, v['cert_key']) commands = [ f'CAAdd /{cert_file}', f'UserCreate {k} /GROUP:{group or "none"} /RealName:none /Note:none', f'UserSignedSet {k} /CN:{v["fqdn"]} /SERIAL:{v["serial_number"]}' ] vpn_acc[k] = { 'vpn_server': server_opts.host, 'vpn_port': server_opts.port, 'vpn_hub': server_opts.hub, 'vpn_account': server_opts.hub, 'vpn_auth_type': 'cert', 'vpn_user': k, 'vpn_cert_key': v['cert_key'], 'vpn_private_key': v['private_key'], } FileHelper.write_file(command_file, '\n'.join(commands) + '\n', append=True) executor.exec_command(f'/IN:{command_file}', log_lvl=logger.INFO) logger.sep(logger.INFO) out = output_opts.make_file( f'{server_opts.hub}-{output_opts.to_file("json")}') logger.info(f'Export VPN accounts to {out}...') JsonHelper.dump(out, vpn_acc) logger.done()
def add(vpn_opts: ClientOpts, server_opts: ServerOpts, auth_opts: AuthOpts, account: str, is_default: bool, dns_prefix: str, no_connect: bool): is_connect = not no_connect executor = VPNClientExecutor(vpn_opts).require_install().probe() hostname = dns_prefix or executor.generate_host_name( server_opts.hub, auth_opts.user, log_lvl=logger.TRACE) acc = AccountInfo(server_opts.hub, account, hostname, is_default) logger.info(f'Setup VPN Client with VPN account [{acc.account}]...') executor.tweak_network_per_account(acc.account, hostname) setup_cmd = { 'AccountCreate': f'{acc.account} /SERVER:{server_opts.server} /HUB:{acc.hub} /USERNAME:{auth_opts.user} /NICNAME:{acc.account}' } setup_cmd = {**setup_cmd, **auth_opts.setup(acc.account)} setup_cmd = setup_cmd if not is_connect else { **setup_cmd, **{ 'AccountConnect': acc.account } } if acc.is_default or is_connect: executor.do_disconnect_current(log_lvl=logger.DEBUG) executor.exec_command(['NicCreate', 'AccountDisconnect', 'AccountDelete'], acc.account, silent=True) executor.exec_command(setup_cmd) executor.storage.create_or_update(acc, _connect=is_connect) if acc.is_default: executor.do_switch_default_acc(acc.account) executor.lease_vpn_service(account=acc.account, is_enable=acc.is_default, is_restart=acc.is_default and is_connect, is_lease_ip=not acc.is_default and is_connect) logger.done()
def install(vpn_opts: ClientOpts, svc_opts: UnixServiceOpts, auto_startup: bool, auto_dnsmasq: bool, dnsmasq: bool, auto_connman_dhcp: bool, force: bool): executor = VPNClientExecutor(vpn_opts).probe(log_lvl=logger.INFO) dns_resolver = executor.device.dns_resolver if not dnsmasq and not dns_resolver.is_connman(): logger.error('Only support dnsmasq as DNS resolver in first version') sys.exit(ErrorCode.NOT_YET_SUPPORTED) if executor.is_installed(silent=True): if force: logger.warn( 'VPN service is already installed. Try to remove then reinstall...' ) executor.do_uninstall(keep_vpn=False, keep_dnsmasq=True) else: logger.error('VPN service is already installed') sys.exit(ErrorCode.VPN_ALREADY_INSTALLED) if dnsmasq and not dns_resolver.is_dnsmasq_available( ) and not dns_resolver.is_connman(): executor.device.install_dnsmasq(auto_dnsmasq) logger.info( f'Installing VPN client into [{vpn_opts.vpn_dir}] and register service[{svc_opts.service_name}]...' ) executor.do_install(svc_opts, auto_startup, auto_connman_dhcp) logger.done()
def delete(vpn_opts: ClientOpts, accounts): logger.info( f'Delete VPN account [{accounts}] and stop/disable VPN service if it\'s a current VPN connection...' ) if accounts is None or len(accounts) == 0: logger.error('Must provide at least account') sys.exit(ErrorCode.INVALID_ARGUMENT) VPNClientExecutor(vpn_opts).require_install().probe( log_lvl=logger.INFO).do_delete(accounts) logger.done()
def add_trust_server(vpn_opts: ClientOpts, account: str, cert_key: str): logger.info("Enable Trust VPN Server on VPN client...") VPNClientExecutor(vpn_opts, adhoc_task=True).require_install().probe().exec_command({ 'AccountServerCertSet': f'{account} /LOADCERT:{cert_key}', 'AccountServerCertEnable': account }) logger.done()
def set_default(vpn_opts: ClientOpts, account: str, is_connect: bool): logger.info(f'Set VPN account [{account}] as startup VPN connection ' + f'{"then connect immediately" if is_connect else ""}...') executor = VPNClientExecutor( vpn_opts, adhoc_task=not is_connect).require_install().probe() executor.do_switch_default_acc(account) if is_connect: executor.do_disconnect_current() executor.lease_vpn_service(is_enable=True, is_restart=is_connect, is_lease_ip=False, account=account) logger.done()
def connect(vpn_opts: ClientOpts, account: str): executor = VPNClientExecutor(vpn_opts).require_install().probe( log_lvl=logger.INFO) def_acc = executor.storage.get_default() if account and def_acc == account: executor.do_disconnect_current(log_lvl=logger.DEBUG) executor.lease_vpn_service(is_enable=True, is_restart=True, is_lease_ip=False) else: cur_acc = executor.storage.get_current() executor.do_disconnect([account, cur_acc] if cur_acc else [account], log_lvl=logger.DEBUG) executor.do_connect(account, log_lvl=logger.INFO) logger.done()
def disconnect(vpn_opts: ClientOpts, accounts: list, _all: bool, disable: bool): executor = VPNClientExecutor(vpn_opts).require_install().probe( log_lvl=logger.INFO) if not accounts and not _all: executor.do_disconnect_current(must_disable_service=disable, silent=False) else: list_acc = [ acc.account for acc in executor.storage.list() if _all or acc.account in accounts ] executor.do_disconnect(list_acc, must_disable_service=disable, log_lvl=logger.INFO) logger.done()
def upgrade(keep_backup: bool, vpn_opts: ClientOpts): def _reconnect_vpn(_executor: VPNClientExecutor, _default_acc: str, _current_acc: str): logger.debug( f'UPGRADE::Reconnect VPN previous state: default[{_default_acc}] - current[{_current_acc}]' ) if not _current_acc and not _default_acc: return if not _current_acc and _default_acc: logger.debug('UPGRADE::Enable VPN service but no connect...') return _executor.lease_vpn_service(is_enable=True, is_restart=False, is_lease_ip=False) if _current_acc == _default_acc: logger.debug('UPGRADE::Enable then restart VPN service...') return _executor.lease_vpn_service(is_enable=True, is_restart=True, is_lease_ip=False) logger.debug( f'UPGRADE::Start VPN service then connect to previous current acc [{_current_acc}]...' ) _executor.device.unix_service.restart(_executor.vpn_service, delay=0) _executor.do_disconnect_current(log_lvl=logger.DEBUG) _executor.do_connect(_current_acc) executor = VPNClientExecutor(vpn_opts).require_install().probe() default_acc, current_acc, svc_opts, backup_dir = executor.backup_config() executor.do_uninstall(keep_vpn=False, keep_dnsmasq=True, service_opts=svc_opts) logger.info(f'Re-install VPN client into [{vpn_opts.vpn_dir}]...') executor.do_install(service_opts=svc_opts, auto_startup=False, auto_connman_dhcp=executor.device.dns_resolver. is_enable_connman_dhcp()) executor.restore_config(backup_dir, keep_backup) _reconnect_vpn(executor, default_acc, current_acc) logger.done()
def uninstall(vpn_opts: ClientOpts, force: bool = False, keep_dnsmasq: bool = True): VPNClientExecutor(vpn_opts).probe().do_uninstall(keep_vpn=not force, keep_dnsmasq=keep_dnsmasq) logger.done()