def get(self, key): # check key first key, hostname, principal = self._parse_key(key) value = self.store.get(key) if value is not None: # TODO: validate certificate self.logger.info("Found cached certificate for %s", principal) return value # found no cached key/cert pair, generate one try: data = self._request_cert(hostname, principal) except AuthorizationError: msg = "Unauthorized request for '{}' ({})".format( hostname, principal) self.logger.info(msg, exc_info=True) raise CSStoreError(msg) except NotFound: msg = "Host '{}' or principal '{}' not found".format( hostname, principal) self.logger.info(msg, exc_info=True) raise CSStoreError(msg) except Exception: msg = "Failed to request cert '{}' ({})".format( hostname, principal) self.logger.error(msg, exc_info=True) raise CSStoreError(msg) self.store.set(key, data, replace=True) return data
def set(self, key, value, replace=False): key = self._mangle_key(key) if not isinstance(value, bytes): value = value.encode('utf-8') with self.ipa as ipa: try: ipa.Command.vault_add( key, ipavaulttype=u"standard", **self._vault_args) except DuplicateEntry as e: self.logger.info("Vault '%s' already exists: %s", key, e) if not replace: raise CSStoreExists(key) except AuthorizationError: msg = "vault_add denied for entry {}".format(key) self.logger.exception(msg) raise CSStoreDenied(msg) except Exception: msg = "Failed to add entry {}".format(key) self.logger.exception(msg) raise CSStoreError(msg) try: ipa.Command.vault_archive( key, data=value, **self._vault_args) except AuthorizationError: msg = "vault_archive denied for entry {}".format(key) self.logger.exception(msg) raise CSStoreDenied(msg) except Exception: msg = "Failed to archive entry {}".format(key) self.logger.exception(msg) raise CSStoreError(msg)
def _parse_key(self, key): if not isinstance(key, six.text_type): key = key.decode('utf-8') parts = key.split(u'/') # XXX why is 'keys' added in in Secrets._db_key()? if len(parts) != 3 or parts[0] != 'keys': raise CSStoreError("Invalid cert request key '{}'".format(key)) service, hostname = parts[1:3] # pylint: disable=unsupported-membership-test if service not in self.allowed_services: raise CSStoreError("Invalid service '{}'".format(key)) principal = krb5_format_service_principal_name(service, hostname, self.ipa.env.realm) # use cert prefix in storage key key = u"cert/{}/{}".format(service, hostname) return key, hostname, principal
def get(self, key): self.logger.debug("Fetching key %s", key) try: result = self.etcd.get(self._absolute_key(key)) except EtcdException: self.logger.exception("Error fetching key %s", key) raise CSStoreError('Error occurred while trying to get key') self.logger.debug("Fetched key %s got result: %r", key, result) return result.value # pylint: disable=no-member
def span(self, key): path = self._absolute_key(key) self.logger.debug("Creating directory %s", path) try: self.etcd.write(path, None, dir=True, prevExist=False) except EtcdAlreadyExist as err: raise CSStoreExists(str(err)) except EtcdException: self.logger.exception("Error storing key %s", key) raise CSStoreError('Error occurred while trying to store key')
def get(self, key): value = super(EncryptedStore, self).get(key) if value is None: return None try: jwe = JWE() jwe.deserialize(value, self.mkey) return jwe.payload.decode('utf-8') except Exception: self.logger.exception("Error parsing key %s", key) raise CSStoreError('Error occurred while trying to parse key')
def get(self, key): value = self.store.get(key) if value is None: return None try: jwe = JWE() jwe.deserialize(value, self.mkey) return jwe.payload.decode('utf-8') except Exception as err: self.logger.error("Error parsing key %s: [%r]" % (key, repr(err))) raise CSStoreError('Error occurred while trying to parse key')
def set(self, key, value, replace=False): self.logger.debug("Setting key %s to value %s (replace=%s)", key, value, replace) path = self._absolute_key(key) try: self.etcd.write(path, value, prevExist=replace) except EtcdAlreadyExist as err: raise CSStoreExists(str(err)) except EtcdException: self.logger.exception("Error storing key %s", key) raise CSStoreError('Error occurred while trying to store key')
def cut(self, key): self.logger.debug("Removing key %s", key) try: self.etcd.delete(self._absolute_key(key)) except EtcdKeyNotFound: self.logger.debug("Key %s not found", key) return False except EtcdException: self.logger.exception("Error removing key %s", key) raise CSStoreError('Error occurred while trying to cut key') self.logger.debug("Key %s removed", key) return True
def __init__(self, config, section): super(SqliteStore, self).__init__(config, section) # Initialize the DB by trying to create the default table try: conn = sqlite3.connect(self.dburi) os.chmod(self.dburi, self.filemode) with conn: c = conn.cursor() self._create(c) except sqlite3.Error: self.logger.exception("Error creating table %s", self.table) raise CSStoreError('Error occurred while trying to init db')
def cut(self, key): key = self._mangle_key(key) with self.ipa as ipa: try: ipa.Command.vault_del(key, **self._vault_args) except NotFound: return False except Exception: msg = "Failed to delete entry {}".format(key) self.logger.exception(msg) raise CSStoreError(msg) else: return True
def __init__(self, config, section): super(EtcdStore, self).__init__(config, section) # Initialize the DB by trying to create the default table try: self.etcd = Client(self.etcd_server, self.etcd_port) self.etcd.write(self.namespace, None, dir=True) except EtcdNotFile: # Already exists pass except EtcdException: self.logger.exception("Error creating namespace %s", self.namespace) raise CSStoreError('Error occurred while trying to init db')
def get(self, key): key = self._mangle_key(key) with self.ipa as ipa: try: result = ipa.Command.vault_retrieve(key, **self._vault_args) except NotFound as e: self.logger.info(str(e)) return None except Exception: msg = "Failed to retrieve entry {}".format(key) self.logger.exception(msg) raise CSStoreError(msg) else: return result[u'result'][u'data']
def get(self, key): value = self.store.get(key) if value is None: return None try: jwe = JWE() jwe.deserialize(value, self.mkey) value = jwe.payload.decode('utf-8') except Exception as err: self.logger.error("Error parsing key %s: [%r]" % (key, repr(err))) raise CSStoreError('Error occurred while trying to parse key') if self.secret_protection == 'encrypt': return value if 'custodia.key' not in jwe.jose_header: if self.secret_protection == 'migrate': self.set(key, value, replace=True) else: raise CSStoreError('Secret Pinning check failed!' + 'Missing custodia.key element') elif jwe.jose_header['custodia.key'] != key: raise CSStoreError( 'Secret Pinning check failed! Expected {} got {}'.format( key, jwe.jose_header['custodia.key'])) return value
def span(self, key): name = key.rstrip('/') self.logger.debug("Creating container %s", name) query = "INSERT into %s VALUES (?, '')" setdata = query % (self.table, ) try: conn = sqlite3.connect(self.dburi) with conn: c = conn.cursor() self._create(c) c.execute(setdata, (name, )) except sqlite3.IntegrityError as err: raise CSStoreExists(str(err)) except sqlite3.Error: self.logger.exception("Error creating key %s", name) raise CSStoreError('Error occurred while trying to span container')
def get(self, key): self.logger.debug("Fetching key %s", key) query = "SELECT value from %s WHERE key=?" % self.table try: conn = sqlite3.connect(self.dburi) c = conn.cursor() r = c.execute(query, (key, )) value = r.fetchall() except sqlite3.Error: self.logger.exception("Error fetching key %s", key) raise CSStoreError('Error occurred while trying to get key') self.logger.debug("Fetched key %s got result: %r", key, value) if len(value) > 0: return value[0][0] else: return None
def cut(self, key): self.logger.debug("Removing key %s", key) query = "DELETE from %s WHERE key=?" % self.table try: conn = sqlite3.connect(self.dburi) with conn: c = conn.cursor() r = c.execute(query, (key, )) except sqlite3.Error: self.logger.error("Error removing key %s", key) raise CSStoreError('Error occurred while trying to cut key') self.logger.debug("Key %s %s", key, "removed" if r.rowcount > 0 else "not found") if r.rowcount > 0: return True return False
def list(self, keyfilter=None): with self.ipa as ipa: try: result = ipa.Command.vault_find(ipavaulttype=u"standard", **self._vault_args) except Exception: msg = "Failed to list entries" self.logger.exception(msg) raise CSStoreError(msg) names = [] for entry in result[u'result']: cn = entry[u'cn'][0] key = cn.replace('__', '/') if keyfilter is not None and not key.startswith(keyfilter): continue names.append(key.rsplit('/', 1)[-1]) return names
def set(self, key, value, replace=False): self.logger.debug("Setting key %s to value %s (replace=%s)", key, value, replace) if key.endswith('/'): raise ValueError('Invalid Key name, cannot end in "/"') if replace: query = "INSERT OR REPLACE into %s VALUES (?, ?)" else: query = "INSERT into %s VALUES (?, ?)" setdata = query % (self.table, ) try: conn = sqlite3.connect(self.dburi) with conn: c = conn.cursor() self._create(c) c.execute(setdata, (key, value)) except sqlite3.IntegrityError as err: raise CSStoreExists(str(err)) except sqlite3.Error as err: self.logger.exception("Error storing key %s", key) raise CSStoreError('Error occurred while trying to store key')
def list(self, keyfilter='/'): path = self._absolute_key(keyfilter) if path != '/': path = path.rstrip('/') self.logger.debug("Listing keys matching %s", path) try: result = self.etcd.read(path, recursive=True) except EtcdKeyNotFound: return None except EtcdException: self.logger.exception("Error listing %s", keyfilter) raise CSStoreError('Error occurred while trying to list keys') self.logger.debug("Searched for %s got result: %r", path, result) value = set() for entry in result.get_subtree(): if entry.key == path: continue name = entry.key[len(path):] if entry.dir and not name.endswith('/'): name += '/' value.add(name.lstrip('/')) return sorted(value)
def list(self, keyfilter=''): path = keyfilter.rstrip('/') self.logger.debug("Listing keys matching %s", path) child_prefix = path if path == '' else path + '/' search = "SELECT key, value FROM %s WHERE key LIKE ?" % self.table key = "%s%%" % (path, ) try: conn = sqlite3.connect(self.dburi) r = conn.execute(search, (key, )) rows = r.fetchall() except sqlite3.Error: self.logger.exception("Error listing %s: [%r]", keyfilter) raise CSStoreError('Error occurred while trying to list keys') self.logger.debug("Searched for %s got result: %r", path, rows) if len(rows) > 0: parent_exists = False result = list() for key, value in rows: if key == path or key == child_prefix: parent_exists = True continue if not key.startswith(child_prefix): continue result_value = key[len(child_prefix):].lstrip('/') if not value: result.append(result_value + '/') else: result.append(result_value) if result: self.logger.debug("Returning sorted values %r", result) return sorted(result) elif parent_exists: self.logger.debug("Returning empty list") return [] elif keyfilter == '': self.logger.debug("Returning empty list") return [] self.logger.debug("Returning 'Not Found'") return None
def span(self, key): raise CSStoreError("span is not implemented")