def read_tmp_secrets(self, zf_secrets): """Read temporary secrets. Args: zf_secrets (ZipFile): ZipFile instance with secrets and passkeys. Raises: SystemExit: If manager crashes or corrupted data are found. """ for each in zf_secrets.read(self.migrate_tmpfile).split("\n"): line = each.split("\t", self.COLUMNS) if len(line) == 0: continue _, _, host, ipv4, port, user, scheme, name, ptype, passkey = line if ptype not in Passkey.SUPPORTED_TYPES: Log.fatal("Unsupported passkey storage {x}", x=ptype) authority_args = user, host, port, scheme auth = self.manager.build_authority_from_args(*authority_args) if ptype == "privatekey": passkey = zf_secrets.read(passkey) data = { "name": name, "host": host, "auth": auth, "passkey": Passkey.SUPPORTED_TYPES.get(ptype) + passkey } self.manager.get_db().add(**data) Log.warn("Unsupported import for jump server, yet")
def call_read_write_append_option(self, name, host, port, user, auth, scheme, jump_server, **kwargs): """Append secrets to a named authority. Args: name (str): The name of the authority to lookup. host (str): Hostname to attach to authority. port (int): Port number to attach to authority. user (str): Username to attach to authority. auth (str): Authentification method. scheme (str): Scheme of the connection. jump_server (str): Name or signature of another authority. Raises: Exception: If named authority already exists. Outputs: stdout: Confirm message with human-readable authority details. """ Log.debug("Incoming append request...") if name is None: name = self.build_random_name() Log.warn("Named authority is known as: {n}", n=name) elif len(name) < self.MIN_NAME_LEN: error = "Possible lookup collision: entry name is too short " \ "(name must be at least {size} characters)" Log.fatal(error, size=self.MIN_NAME_LEN) elif len(name) > self.MAX_NAME_LEN: error = "Possible bad naming: entry name is too long " \ "(name must be at most {size} characters)" Log.fatal(error, size=self.MAX_NAME_LEN) elif self.get_db().exists(name): error = "Another entry with the same name exists: {name} " \ "(name must be unique)" Log.fatal(error, name=name) data = { "name": name, "host": host, "auth": self.build_authority_from_args(user, host, port, scheme), } if jump_server is not None: data.update({ "jump_auth": self.build_authority_from_signature(jump_server) }) Log.debug("Preparing to add {args}", args=data) self.get_db().add(passkey=Passkey.resolve(auth), **data) Log.debug("New named authority is saved...") Display.show_append(data.get("auth"))
def remove(self, key): """Remove key from keychain. Args: key (str): Key to remove. Returns: str: Raw "as is" removed value for given key. """ value = self.get(key) if value is None: Log.warn("Keychain can not remove an unset key") else: del self.keychain[key] return value
def set_host(self, host): """Authority host setter. Args: host (str): Hostname or IP address to store. Raises: Exception: if an invalid hostname is provided. """ if not isinstance(host, (str, unicode)): Log.fatal("Invalid host: expected string, got {x}", x=type(host)) try: self.ip_addr = unicode(gethostbyname(host)) except Exception as e: Log.warn("Cannot resolve hostname {h}: {e}", e=str(e), h=host) try: self.host = int(ip_address(self.ip_addr)) except Exception as e: Log.fatal("Invalid host: {e}", e=str(e))
def recover(cls, authority): """Reconstruct an authority instance from a string representation. Args: authority (str): A string representation of a stored authority. Raises: Exception: If required fields are invalid. Returns: Authority: An authority instance. """ if authority.count(cls.DELIMITER) != cls.COMPONENTS: Log.fatal("Cannot recover from an invalid authority") host, port, user, srv = authority.split(cls.DELIMITER, cls.COMPONENTS) try: # fix for non-linux platforms host = str(IPv4Address(int(host, 10))) except ValueError as e: Log.warn("Cannot convert to IP4: {e}", e=str(e)) except AddressValueError as e: Log.fatal("Invalid host address: {e}", e=str(e)) return cls.new(host, port, user, srv)