def deselect_handler(args): selectors = get_server_setting(selectors_setting) if isinstance(selectors, str): selectors = [selectors] set_server_setting(selectors_setting, selectors) if selectors is None: selectors = [] set_server_setting(selectors_setting, selectors) errors = False for selector in args.selector: try: selectors.remove(selector) except ValueError: sys.stderr.write( 'Selector {} is not currently selected.\n'.format(selector)) errors = True if errors: sys.exit(1) for selector in args.selector: log.info('Removing secret-keeping selector {}', selector) save_server_settings() set_client_setting(selectors_setting, selectors) save_client_settings() print(restart_note)
def disable_handler(args): if not get_server_setting('secret_keeping:enabled'): sys.exit('Secret-keeping is not enabled.') set_server_setting('secret_keeping:enabled', False) save_server_settings() set_client_setting('secret_keeping:enabled', False) save_client_settings() print(restart_note) log.info('Disabled secret-keeping')
def select_handler(args): selectors = get_server_setting(selectors_setting) if isinstance(selectors, str): selectors = [selectors] set_server_setting(selectors_setting, selectors) if selectors is None: selectors = [] set_server_setting(selectors_setting, selectors) errors = False for selector in args.selector: if selector in selectors: sys.stderr.write( 'Selector {} is already added.\n'.format(selector)) errors = True if errors: sys.exit(1) if not args.force: db = get_db() for selector in args.selector: if not db.clients.find_one({selector: { '$exists': True }}, projection=[]): sys.stderr.write( 'Selector {} does not match anything.\n' 'Specify --force to save anyway.\n'.format(selector)) errors = True if errors: sys.exit(1) for selector in args.selector: log.info('Adding secret-keeping selector {}', selector) selectors.extend(args.selector) save_server_settings() set_client_setting(selectors_setting, selectors) save_client_settings() print(restart_note)
def enable_handler(args): if get_server_setting('secret_keeping:enabled'): sys.exit('Secret-keeping is already enabled.') if get_server_setting('secret_keeping:key_id'): if not (args.replace or args.preserve): sys.exit('Must specify --replace or --preserve.') else: args.replace = True args.shares = args.shares or \ get_server_setting('secret_keeping:num_shares') if args.shares < 2: sys.exit('--num-shares must be at least 2.') args.combine_threshold = args.combine_threshold or \ get_server_setting('secret_keeping:combine_threshold') if args.combine_threshold < 2: sys.exit('--combine-threshold must be at least 2.') if args.combine_threshold > args.shares: sys.exit( '--combine-threshold must be less than {}.'.format(args.shares + 1)) if args.replace: key_name = 'penguindome-secret-keeping-' + uuid.uuid4().hex output = gpg_command('--passphrase', '', '--quick-gen-key', key_name, with_trustdb=True, quiet=False) match = re.search(r'key (.*) marked as ultimately trusted', output) key_id = match.group(1) match = re.search(r'/([0-9A-F]+)\.rev', output) key_fingerprint = match.group(1) split_dir = os.path.join(var_dir, key_name) key_file = os.path.join(split_dir, 'private_key.asc') os.makedirs(split_dir) gpg_command('--export-secret-key', '--armor', '-o', key_file, key_id) subprocess.check_output(('gfsplit', '-n', str( args.combine_threshold), '-m', str(args.shares), key_file), stderr=subprocess.STDOUT) try: gpg_command('--delete-secret-keys', key_fingerprint) except subprocess.CalledProcessError as e: sys.exit('Failed to delete secret key:\n{}'.format( e.output.decode('utf8'))) subprocess.check_output(('shred', '-u', key_file), stderr=subprocess.STDOUT) with NamedTemporaryFile() as public_key_file: gpg_command('--export', '-o', public_key_file.name, key_id) set_gpg('client') try: gpg_command('--import', public_key_file.name) finally: set_gpg('server') set_server_setting('secret_keeping:key_name', key_name) set_server_setting('secret_keeping:key_id', key_id) set_server_setting('secret_keeping:key_fingerprint', key_fingerprint) set_client_setting('secret_keeping:key_id', key_id) set_server_setting('secret_keeping:num_shares', args.shares) set_server_setting('secret_keeping:combine_threshold', args.combine_threshold) set_server_setting('secret_keeping:enabled', True) save_server_settings() set_client_setting('secret_keeping:enabled', True) save_client_settings() print( distribute_secrets_note.format(m=args.shares, n=args.combine_threshold, split_dir=split_dir)) print(restart_note) log.info('Enabled secret-keeping')
def configure_client(args): changed = False url = get_client_setting('server_url') if url: url = list(urlparse(url)) else: url = ['', '', '', '', '', ''] if ':' in url[1]: hostname, port = url[1].split(':') port = int(port) else: hostname = url[1] port = 443 if url[0] == 'https' else 80 if args.hostname: if hostname != args.hostname: hostname = args.hostname changed = True if args.port: if port != args.port: port = args.port changed = True if port == 443 and args.ssl is None: args.ssl = True if args.ssl: if url[0] != 'https': url[0] = 'https' changed = True elif args.ssl is False: if url[0] != 'http': url[0] = 'http' changed = True if port == 443 and url[0] != 'https': print("\n" "WARNING: Are you sure you don't want to use SSL on port 443?\n") verbose_port = port or 80 try: server_port_ssl = get_port_setting( verbose_port, 'ssl:enabled', bool(get_port_setting(verbose_port, 'ssl:certificate'))) except: server_port_ssl = False if server_port_ssl and url[0] != 'https': print('\n' 'WARNING: Port {} on the server is using SSL.\n' ' Does the client need to?\n'.format(verbose_port)) elif not server_port_ssl and url[0] != 'http': print('\n' 'WARNING: Port {} on the server is not using SSL.\n' ' Are you sure the client should?\n'.format( verbose_port)) if not hostname: sys.exit('You must specify hostname.') if url[0] not in ('http', 'https'): changed = True url[0] = 'https' if port == 443 else 80 if port and ((url[0] == 'http' and port != 80) or (url[0] == 'https' and port != 443)): loc = '{}:{}'.format(hostname, port) if url[1] != loc: changed = True url[1] = loc else: url[1] = hostname if args.ssl_ca_file is False: if get_client_setting('ssl:ca_path'): set_client_setting('ssl:ca_path', None) changed = True elif args.ssl_ca_file: try: server_port = int(args.ssl_ca_file) except: pass else: args.ssl_ca_file = get_port_setting(server_port, 'ssl:certificate') if not args.ssl_ca_file: sys.exit('Server port {} does not have an SSL certificate.' .format(server_port)) client_file = os.path.join('client', 'cacert.pem') if not os.path.exists(args.ssl_ca_file): sys.exit('The file {} does not exist.'.format(args.ssl_ca_file)) if not (os.path.exists(client_file) and filecmp.cmp(args.ssl_ca_file, client_file)): shutil.copy(args.ssl_ca_file, client_file) changed = True if get_client_setting('ssl:ca_path') != client_file: set_client_setting('ssl:ca_path', client_file) changed = True url = urlunparse(url) url = re.sub(r'/+$', '', url) if changed: set_client_setting('server_url', url) save_client_settings() print('Updated client configuration.') show_configuration(args) print("\n" "WARNING: Don't forget to build a new client release.\n") else: print('Client configuration unchanged.')