def refresh_screen(screen, selection, main_win=None): """Refreshes the GUI elements of the main screen""" y, x = screen.getmaxyx() main_x = x - (x / 4) main_y = len(conf.get('vaults')) + 5 if y < main_y or x < main_x: problems("screen too small") screen.border() screen.bkgd(ord(' '), curses.color_pair(1)) middle_y, middle_x = middle_yx(screen) if not main_win: main_win = curses.newwin(main_y, main_x, int(round(middle_y - (main_y/2))), int(round(middle_x - (main_x/2)))) else: main_win.erase() main_win.bkgd(ord(' '), curses.color_pair(1)) main_win.border() string_at(main_win, 1, 0, conf.get("title", "Vault Friends"), curses.color_pair(1), 'center') refresh_status(main_win, selection) screen.nooutrefresh() main_win.nooutrefresh() curses.doupdate() return main_win
def rekey_start(server, keys): """Start the rekeying process. This will result in new unseal keys being generated once quorum has been achieved.""" client = server['client'] required = conf.get('required') backup = conf.get('backup', False) client.start_rekey(secret_shares=len(keys), secret_threshold=required, backup=backup, pgp_keys=keys)
def update_servers(): """Kicks off the update process for our Vault servers""" servers = [] for server in conf.get('vaults'): servers.append(get_server(server['name'])) return servers
def grok_keys(): """Returns a list of all extracted keys""" keys = [] for key in conf.get('keys'): keys.append(grok_key(key)) return keys
def cli_seal_all(): """Seals every accessible Vault instance""" for name in [x['name'] for x in conf.get('vaults')]: if not seal(get_server(name)): sys.exit(1) sys.exit(0)
def focus_loop(screen, index): """Main interaction loop when an actual Vault instance is selected and we are looking at the detailed view.""" done = False screen.erase() while not done: server = get_server(conf.get('vaults')[index]['name']) refresh_focused(screen, server) if focus_input(screen, server): screen.erase() return
def cli_root_import(name): """Imports a plaintext root token and will encrypt according to the propriecle configuration.""" server = get_server(name) root_token = getpass('Root Token: ', stream=sys.stderr) if not root_token: problems("Must specify a token") root_key = conf.get('root_key') key_id = cryptorito.key_from_keybase(root_key[8:])['fingerprint'] encrypted = cryptorito.portable_b64encode( cryptorito.encrypt_var(root_token, [key_id])) do_write(encrypted, root_file_name(server))
def init(server): """Initialize a fresh Vault server. It will do this based on the settings as defined in the proprieclerc file""" obj = { "root_token_pgp_key": grok_key(conf.get('root_key')), "secret_shares": len(conf.get('keys')), "secret_threshold": conf.get('required'), "pgp_keys": grok_keys() } client = server['client'] resp = client.write('sys/init', **obj) if 'root_token' not in resp or \ 'keys_base64' not in resp: return False do_write(resp['root_token'], root_file_name(server)) index = 0 for key in resp['keys_base64']: do_write(key, unseal_file_name(server, index + 1)) index = index + 1 return True
def cli_unseal_import(name, s_slot): """Imports a unseal key at a spcified slot and will encrypt accordign to the propriecle configuration.""" slot = int(s_slot) server = get_server(name) unseal_key = getpass('Unseal Key: ', stream=sys.stderr) if not unseal_key: problems("Must specify a unseal key") a_key = conf.get('keys')[slot - 1] key_id = cryptorito.key_from_keybase(a_key[8:])['fingerprint'] encrypted = cryptorito.portable_b64encode( cryptorito.encrypt_var(unseal_key, [key_id])) do_write(encrypted, unseal_file_name(server, slot))
def main_loop(screen): """Main interaction loop.""" done = False selection = 0 main_win = None while not done: main_win = refresh_screen(screen, selection, main_win) screen.timeout(500) ch = screen.getch() if ch == 27: screen.erase() screen.refresh() popup(screen, "Thank you for playing") curses.endwin() return elif ch == curses.KEY_DOWN: if selection < len(conf.get('vaults')) - 1: selection = selection + 1 elif ch == curses.KEY_UP: if selection > 0: selection = selection - 1 elif ch == 10: focus_loop(screen, selection)
def list_keys(server): """Retuns a list of all unseal keys which are available""" keys = [] index = 0 for key in conf.get('keys'): key_obj = {'index': index, 'name': key, 'key': None} key_file = unseal_file_name(server, index + 1) if os.path.exists(key_file): key_obj['key'] = do_decrypt(key_file) else: for a_server in server.get('cluster_members', []): a_filename = unseal_file_name(a_server, index + 1) if os.path.exists(a_filename): key_obj['key'] = do_decrypt(a_filename) break if key_obj['key'] and key_obj['key'] != '': keys.append(key_obj) index = index + 1 return keys
def get_keys(screen, server): """Generates a list of keys for the user to select from. Options also include manually entering a key or using any valid key""" client = server['client'] keys = list_keys(server) middle_y, middle_x = middle_yx(screen) my_x = 30 my_y = len(keys) + 6 win_x = middle_x - (my_x/2) win_y = middle_y - 10 win = curses.newwin(my_y, my_x, win_y, win_x) status = client.seal_status done = False selection = 0 return_keys = [] while not done: win.border() win.bkgd(ord(' '), curses.color_pair(1)) win.addstr(1, 1, "Select Key (%s of %s complete)" % (status['progress'], status['t']), curses.color_pair(2)) win.addstr(my_y - 2, 1, "[m]anual [a]ny", curses.color_pair(1)) for key_obj in keys: name = key_obj['name'] i = key_obj['index'] color = curses.color_pair(2) if not key_obj['key']: color = curses.color_pair(4) if selection == i: color = curses.color_pair(6) if name.startswith('keybase:'): name = name[8:] win.addstr(i + 2, 1, "[%s] %s" % (i + 1, name), color) win.refresh() screen.timeout(500) ch = screen.getch() if ch == 27: del win screen.refresh() return elif ch == curses.KEY_DOWN: down_done = False while not down_done: if selection < len(keys) - 1 and \ keys[selection + 1]['key']: selection = selection + 1 down_done = True elif selection == len(keys) - 1: down_done = True else: selection = selection + 1 elif ch == curses.KEY_UP: up_done = False while not up_done: if selection > 0 and \ keys[selection - 1]['key']: selection = selection - 1 up_done = True elif selection == 0: up_done = True else: selection = selection - 1 elif ch == ord('m') or ch == ord('M'): return ask_for(screen, "Key") elif ch == ord('a') or ch == ord('A'): return_keys = [k for k in keys if k['key']][0:conf.get('required')] done = True elif ch == 10: if keys[selection]['key']: done = True win.erase() win.refresh() del win if len(return_keys) == 0: return_keys = [k for k in keys if k['index'] == selection] return return_keys
def do_rekey(server): """Invoke the GUI action of rekeying unseal keys""" if not conf.get('keys') or not conf.get('required'): problems('keys and required missing from config') rekey_start(server, grok_keys())
def regenerate_start(server): """Begin the process for regenerating the root token""" client = server['client'] obj = {"pgp_key": grok_key(conf.get('root_key'))} client.write('sys/generate-root/attempt', **obj)
def cli_unseal_all(): """Attempts to submit every available unseal key for each Vault instance in order""" for name in [x['name'] for x in conf.get('vaults')]: cli_unseal(name)