Merge branch 'develop'

This commit is contained in:
Stefan Kalscheuer 2018-11-20 10:52:57 +01:00
commit c8aeb1396d
111 changed files with 1473 additions and 354 deletions

33
.drone.yml Normal file
View File

@ -0,0 +1,33 @@
kind: pipeline
name: java8
clone:
disable: true
steps:
- name: clone
image: plugins/git
settings:
depth: 10
skip_verify: true
- name: test-online
image: maven:3.5-jdk-8-alpine
commands:
- export VAULT_VERSION=0.11.5
- wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
- wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_${VAULT_VERSION}_linux_amd64.zip
- rm vault_${VAULT_VERSION}_linux_amd64.zip
- mv vault /bin/
- mvn clean test
when:
branch:
- master
- name: test-offline
image: maven:3.5-jdk-8-alpine
commands:
- mvn clean test -Dtest='!HTTPVaultConnectorTest'
when:
branch:
- develop
- feature/*

View File

@ -12,12 +12,12 @@ addons:
token:
secure: "sM9OfX5jW764pn9cb2LSXArnXucKMws+eGeg5NnZxHRcGYt4hpBKLSregBSsBNzUoWVj0zNzPCpnh+UQvgxQzUerOqwEdjTBpy3SNPaxSn7UpoSg+Wz3aUmL9ugmx01b51/wMG4UCHEwTZt2tpgTPVtw8K6uSO78e0dSICCBHDnRcdQwOjMEQHIJJ/qHVRwuy/MzLCAP3W1JPZlsphZg9QsFyhB4hW97dE90joZezfocQIv2xI/r6k+BLz0pY6MxYCul0RiDumaiaej0CPvEJI/uSu//BAQjUdHw+mQgnKUYIbrn2ONOviwNfwdr94JyoZEN2B6zASUmNLjPf4AbIojDeyS+CrpQpm17EVm/Qk/Ds+Xra4PPPIcsZhiWzV0KoDUz9xLfXuRJ526VT5tDPiaeI7oETf0+8l+JIS1b399FyqHi7smzjpvC6GuKflQrbuHK4MuKzDh7WTHiqokGG4SS0wOQIaaHB3dfdwwQzPh6IM24e8CETxh3DjMeqUTU4DWmv5po55jZ934TtxVQvVN78bTG9O0zS9u+JmRY04OZ+OaXuFam6MfMUFQi0EPZzdGul/oWSibGUu3bNfVEBp60CnJwYNM/dKG6U7pJthLHvSwiQFOdKzHZ+l1jZJ4gPaXaIGqpwqVGr28ntqA/El1rytPixr2driE6bYMt5jw="
env:
- PATH=$PATH:.
- PATH=$PATH:. VAULT_VERSION=0.11.5
before_script:
- wget https://releases.hashicorp.com/vault/0.11.4/vault_0.11.4_linux_amd64.zip
- wget -q -O - https://releases.hashicorp.com/vault/0.11.4/vault_0.11.4_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_0.11.4_linux_amd64.zip
- rm vault_0.11.4_linux_amd64.zip
- wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
- wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_${VAULT_VERSION}_linux_amd64.zip
- rm vault_${VAULT_VERSION}_linux_amd64.zip
cache:
directories:
- '$HOME/.m2/repository'

View File

@ -1,71 +1,147 @@
## 0.7.2 [unreleased]
* [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489)
* [improvement] Build environment and tests now compatible with Java 10
## 0.8.0 (unreleased)
### Breaking
* Removed support for `HTTPVaultConnectorFactory#withSslContext()` in favor of `#withTrustedCA()` due to
## 0.7.1 [2018-03-17]
* [improvement] Added automatic module name for JPMS compatibility
* [dependencies] Minor dependency updates
* [test] Tested against Vault 0.9.5
### Improvements
* refactoring of the internal SSL handling (#17)
* `VaultConnector` extends `java.io.Serializable` (#19)
* Added missing flags to `SealResponse` (#20)
* Added replication flags to `HealthResponse` (#21)
* Enforce TLS 1.2 by default with option to override (#22)
* Build environment and tests now compatible with Java 10
* Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489)
### Deprecation
* `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18)
* `AppRoleBuilder#withBoundCidrList(List)` is deprecated in favor of `AppRoleBuilder#withSecretIdBoundCidrs(List)` (#24)
## 0.7.1 (2018-03-17)
### Improvements
* Added automatic module name for JPMS compatibility
* Minor dependency updates
### Test
* Tested against Vault 0.9.5
## 0.7.0 (2017-10-03)
### Features
* Retrieval of health status via `getHealth()` (#15)
### Improvements
* `seal()`, `unseal()` are now `void` and throw Exception on error (#12)
* Adaptation to Vault 0.8 endpoints for `renew` and `revoke`, **breaking** 0.7 compatibility (#11)
### Removed
* Removed deprecated `listAppRoleSecretss()` (use `listAppRoleSecrets()`) (#14)
### Test
* Tested against Vault 0.8.3
## 0.7.0 [2017-10-03]
* [feature] Retrieval of health status via `getHealth()` (#15)
* [improvement] `seal()`, `unseal()` are now `void` and throw Exception on error (#12)
* [compatibility] Adaptation to Vault 0.8 endpoints for `renew` and `revoke`, **breaking** 0.7 compatibility (#11)
* [deletion] Removed deprecated `listAppRoleSecretss()` (use `listAppRoleSecrets()`) (#14)
* [test] Tested against Vault 0.8.3
## 0.6.2 [2017-08-19]
* [fix] Prevent potential NPE on SecretResponse getter
* [fix] Removed stack traces on PUT request and response deserialization (#13)
* [improvement] Fields of InvalidResposneException made final
* [deprecation] `listAppRoleSecretss()` in favor of `listAppRoleSecrets()` (#14)
* [test] Tested against Vault 0.8.1, increased coverage
### Fixes
* Prevent potential NPE on SecretResponse getter
* Removed stack traces on PUT request and response deserialization (#13)
## 0.6.1 [2017-08-02]
* [fix] `TokenModel.getPassword()` returned username instead of password
* [fix] `TokenModel.getUsername()` and `getPassword()` could produce NPE in multithreaded environments
* [fix] `TokenData.getCreatinTtl()` renamed to `getCreationTtl()` (typo fix)
* [test] Tested against Vault 0.7.3
### Improvements
* Fields of InvalidResposneException made final
## 0.6.0 [2017-05-12]
* [feature] Initialization from environment variables using `fromEnv()` in factory (#8)
* [feature] Automatic authentication with `buildAndAuth()`
* [feature] Custom timeout and number of retries (#9)
* [feature] Connector implements `AutoCloseable`
* [fix] `SecretResponse` does not throw NPE on `get(key)` and `getData()`
* [test] Tested against Vault 0.7.2
### Deprecation
* `listAppRoleSecretss()` in favor of `listAppRoleSecrets()` (#14)
### Test
* Tested against Vault 0.8.1, increased coverage
## 0.6.1 (2017-08-02)
### Fixes
* `TokenModel.getPassword()` returned username instead of password
* `TokenModel.getUsername()` and `getPassword()` could produce NPE in multithreaded environments
* `TokenData.getCreatinTtl()` renamed to `getCreationTtl()` (typo fix)
### Test
* Tested against Vault 0.7.3
## 0.6.0 (2017-05-12)
### Features
* Initialization from environment variables using `fromEnv()` in factory (#8)
* Automatic authentication with `buildAndAuth()`
* Custom timeout and number of retries (#9)
* Connector implements `AutoCloseable`
### Fixes
* `SecretResponse` does not throw NPE on `get(key)` and `getData()`
### Test
* Tested against Vault 0.7.2
## 0.5.0 (2017-03-18)
### Features
* Convenience methods for DB credentials (#7)
### Fixes
* Minor bugfix in TokenBuilder
### Deprecation
* `SecretResponse.getValue()` deprecated
### Test
* Tested against Vault 0.7.0
## 0.5.0 [2017-03-18]
* [feature] Convenience methods for DB credentials (#7)
* [fix] Minor bugfix in TokenBuilder
* [deprecation] `SecretResponse.getValue()` deprecated
* [test] Tested against Vault 0.7.0
## 0.4.1 [2016-12-24]
* [fix] Factory Null-tolerant for trusted certificate (#6)
* [test] StackTraces tested for secret leaks
* [test] Tested against Vault 0.6.4
### Fixes
* Factory Null-tolerant for trusted certificate (#6)
## 0.4.0 [2016-11-06]
* [feature] Option to provide a trusted CA certificate (#2)
* [feature] Deletion, revocation and renewal of secrets (#3)
* [feature] Token creation (#4)
* [feature] AppRole auth backend supported (#5)
* [improvement] Support for complex secrets
* [deprecation] App-ID backend marked as deprecated
### Test
* StackTraces tested for secret leaks
* Tested against Vault 0.6.4
## 0.3.0 [2016-10-07]
* [feature] Retrieval of JSON objects (#1)
* [test] Tested against Vault 0.6.2
## 0.2.0 [2016-09-01]
## 0.4.0 (2016-11-06)
### Features
* Option to provide a trusted CA certificate (#2)
* Deletion, revocation and renewal of secrets (#3)
* Token creation (#4)
* AppRole auth backend supported (#5)
### Improvements
* Support for complex secrets
### Deprecation
* App-ID backend marked as deprecated
## 0.3.0 (2016-10-07)
### Features
* Retrieval of JSON objects (#1)
### Test
* Tested against Vault 0.6.2
## 0.2.0 (2016-09-01)
### Improvements
* Dependecies updated and CommonsIO removed
* [fix] Fixed auth backend detection for Vault 0.6.1
* [test] Tested against Vault 0.6.1
## 0.1.1 [2016-06-20]
* [fix] Check for "permission denied" without status code 400 instead of 403
* [test] Tested against Vault 0.6.0
### Fixes
* Fixed auth backend detection for Vault 0.6.1
## 0.1.0 [2016-03-29]
### Test
* Tested against Vault 0.6.1
## 0.1.1 (2016-06-20)
### Fixes
* Check for "permission denied" without status code 400 instead of 403
### Test
* Tested against Vault 0.6.0
## 0.1.0 (2016-03-29)
* First release

View File

@ -31,7 +31,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* Raw secret content or JSON decoding
* SQL secret handling
* Connector Factory with builder pattern
* Tested against Vault 0.11.4
* Tested against Vault 0.11.5
## Maven Artifact
@ -71,13 +71,13 @@ VaultConnector vault = VaultConnectorFactory.httpFactory()
### Authentication
```java
// Authenticate with token
// Authenticate with token.
vault.authToken("01234567-89ab-cdef-0123-456789abcdef");
// Authenticate with username and password
// Authenticate with username and password.
vault.authUserPass("username", "p4ssw0rd");
// Authenticate with AppID (secret - 2nd argument - is optional)
// Authenticate with AppRole (secret - 2nd argument - is optional).
vault.authAppId("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fedc-ba9876543210");
```
@ -87,17 +87,17 @@ vault.authAppId("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fedc
// Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths)
String secret = vault.readSecret("some/secret/key").getValue();
// Complex secret
// Complex secret.
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData();
// Write simple secret
// Write simple secret.
vault.writeSecret("new/secret/key", "secret value");
// Write complex data to arbitraty path
// Write complex data to arbitraty path.
Map<String, Object> map = [...]
vault.write("any/path/to/write", map);
// Delete secret
// Delete secret.
vault.delete("any/path/to/write");
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -2,11 +2,11 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">
<path d="M4,12 l60,104 l60,-104 z" stroke="none" fill="#000000" />
<circle cx="78" cy="24" r="6" stroke="none" fill="#00a9c7" />
<circle cx="78" cy="38" r="6" stroke="none" fill="#00a9c7" />
<circle cx="78" cy="52" r="6" stroke="none" fill="#00a9c7" />
<circle cx="78" cy="66" r="6" stroke="none" fill="#00a9c7" />
<circle cx="72" cy="78" r="6" stroke="none" fill="#00a9c7" />
<circle cx="58" cy="78" r="6" stroke="none" fill="#00a9c7" />
<circle cx="52" cy="66" r="6" stroke="none" fill="#00a9c7" />
<rect x="74" y="20" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="74" y="34" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="74" y="48" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="74" y="62" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="68" y="74" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="54" y="74" width="8" height="8" stroke="none" fill="#00abe0" />
<rect x="48" y="62" width="8" height="8" stroke="none" fill="#00abe0" />
</svg>

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 837 B

73
pom.xml
View File

@ -4,13 +4,14 @@
<groupId>de.stklcode.jvault</groupId>
<artifactId>connector</artifactId>
<version>0.7.2-SNAPSHOT</version>
<version>0.8.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jVaultConnector</name>
<description>Connector artifact for Hashicorp's Vault secret management</description>
<url>https://jvault.stklcode.de</url>
<inceptionYear>2016</inceptionYear>
<licenses>
<license>
@ -24,6 +25,25 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<developers>
<developer>
<name>Stefan Kalscheuer</name>
<email>stefan@stklcode.de</email>
<timezone>+1</timezone>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/stklcode/jvaultconnector.git</connection>
<developerConnection>scm:git:git@github.com:stklcode/jvaultconnector.git</developerConnection>
<url>https://github.com/stklcode/jvaultconnector</url>
</scm>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/stklcode/jvaultconnector/issues</url>
</issueManagement>
<build>
<plugins>
<plugin>
@ -138,4 +158,55 @@
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>sources</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>javadoc</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -29,18 +29,23 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -72,16 +77,19 @@ public class HTTPVaultConnector implements VaultConnector {
private static final String HEADER_VAULT_TOKEN = "X-Vault-Token";
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
private final ObjectMapper jsonMapper;
private final String baseURL; /* Base URL of Vault */
private final SSLContext sslContext; /* Custom SSLSocketFactory */
private final int retries; /* Number of retries on 5xx errors */
private final Integer timeout; /* Timeout in milliseconds */
private final String baseURL; // Base URL of Vault.
private final String tlsVersion; // TLS version (#22).
private final X509Certificate trustedCaCert; // Trusted CA certificate.
private final int retries; // Number of retries on 5xx errors.
private final Integer timeout; // Timeout in milliseconds.
private boolean authorized = false; /* authorization status */
private String token; /* current token */
private long tokenTTL = 0; /* expiration time for current token */
private boolean authorized = false; // Authorization status.
private String token; // Current token.
private long tokenTTL = 0; // Expiration time for current token.
/**
* Create connector using hostname and schema.
@ -122,18 +130,18 @@ public class HTTPVaultConnector implements VaultConnector {
/**
* Create connector using hostname, schema, port, path and trusted certificate.
*
* @param hostname The hostname
* @param useTLS If TRUE, use HTTPS, otherwise HTTP
* @param port The port
* @param prefix HTTP API prefix (default: /v1/)
* @param sslContext Custom SSL Context
* @param hostname The hostname
* @param useTLS If TRUE, use HTTPS, otherwise HTTP
* @param port The port
* @param prefix HTTP API prefix (default: /v1/)
* @param trustedCaCert Trusted CA certificate
*/
public HTTPVaultConnector(final String hostname,
final boolean useTLS,
final Integer port,
final String prefix,
final SSLContext sslContext) {
this(hostname, useTLS, port, prefix, sslContext, 0, null);
final X509Certificate trustedCaCert) {
this(hostname, useTLS, DEFAULT_TLS_VERSION, port, prefix, trustedCaCert, 0, null);
}
/**
@ -141,26 +149,29 @@ public class HTTPVaultConnector implements VaultConnector {
*
* @param hostname The hostname
* @param useTLS If TRUE, use HTTPS, otherwise HTTP
* @param tlsVersion TLS version
* @param port The port
* @param prefix HTTP API prefix (default: /v1/)
* @param sslContext Custom SSL Context
* @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors
* @param timeout Timeout for HTTP requests (milliseconds)
*/
public HTTPVaultConnector(final String hostname,
final boolean useTLS,
final String tlsVersion,
final Integer port,
final String prefix,
final SSLContext sslContext,
final X509Certificate trustedCaCert,
final int numberOfRetries,
final Integer timeout) {
this(((useTLS) ? "https" : "http")
+ "://" + hostname
+ ((port != null) ? ":" + port : "")
+ prefix,
sslContext,
trustedCaCert,
numberOfRetries,
timeout);
timeout,
tlsVersion);
}
/**
@ -175,40 +186,58 @@ public class HTTPVaultConnector implements VaultConnector {
/**
* Create connector using full URL and trusted certificate.
*
* @param baseURL The URL
* @param sslContext Custom SSL Context
* @param baseURL The URL
* @param trustedCaCert Trusted CA certificate
*/
public HTTPVaultConnector(final String baseURL, final SSLContext sslContext) {
this(baseURL, sslContext, 0, null);
public HTTPVaultConnector(final String baseURL, final X509Certificate trustedCaCert) {
this(baseURL, trustedCaCert, 0, null);
}
/**
* Create connector using full URL and trusted certificate.
*
* @param baseURL The URL
* @param sslContext Custom SSL Context
* @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors
*/
public HTTPVaultConnector(final String baseURL, final SSLContext sslContext, final int numberOfRetries) {
this(baseURL, sslContext, numberOfRetries, null);
public HTTPVaultConnector(final String baseURL, final X509Certificate trustedCaCert, final int numberOfRetries) {
this(baseURL, trustedCaCert, numberOfRetries, null);
}
/**
* Create connector using full URL and trusted certificate.
*
* @param baseURL The URL
* @param sslContext Custom SSL Context
* @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors
* @param timeout Timeout for HTTP requests (milliseconds)
*/
public HTTPVaultConnector(final String baseURL,
final SSLContext sslContext,
final X509Certificate trustedCaCert,
final int numberOfRetries,
final Integer timeout) {
this(baseURL, trustedCaCert, numberOfRetries, timeout, DEFAULT_TLS_VERSION);
}
/**
* Create connector using full URL and trusted certificate.
*
* @param baseURL The URL
* @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors
* @param timeout Timeout for HTTP requests (milliseconds)
* @param tlsVersion TLS Version.
*/
public HTTPVaultConnector(final String baseURL,
final X509Certificate trustedCaCert,
final int numberOfRetries,
final Integer timeout,
final String tlsVersion) {
this.baseURL = baseURL;
this.sslContext = sslContext;
this.trustedCaCert = trustedCaCert;
this.retries = numberOfRetries;
this.timeout = timeout;
this.tlsVersion = tlsVersion;
this.jsonMapper = new ObjectMapper();
}
@ -818,8 +847,11 @@ public class HTTPVaultConnector implements VaultConnector {
/* Set JSON Header */
base.addHeader("accept", "application/json");
HttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(sslContext).build()) {
CloseableHttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLSocketFactory(createSSLSocketFactory())
.build()) {
/* Set custom timeout, if defined */
if (this.timeout != null)
base.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setConnectTimeout(timeout).build());
@ -890,7 +922,7 @@ public class HTTPVaultConnector implements VaultConnector {
new InputStreamReader(response.getEntity().getContent()))) {
String responseString = br.lines().collect(Collectors.joining("\n"));
ErrorResponse er = jsonMapper.readValue(responseString, ErrorResponse.class);
/* Check for "permission denied" response */
/* Check for "permission denied" response */
if (!er.getErrors().isEmpty() && er.getErrors().get(0).equals("permission denied"))
throw new PermissionDeniedException();
throw new InvalidResponseException(Error.RESPONSE_CODE,
@ -901,6 +933,39 @@ public class HTTPVaultConnector implements VaultConnector {
}
}
/**
* Create a custom socket factory from trusted CA certificate.
*
* @return The factory.
* @throws TlsException An error occured during initialization of the SSL context.
* @since 0.8.0
*/
private SSLConnectionSocketFactory createSSLSocketFactory() throws TlsException {
try {
// Create Keystore with trusted certificate.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", trustedCaCert);
// Initialize TrustManager.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create context usint this TrustManager.
SSLContext context = SSLContext.getInstance(tlsVersion);
context.init(null, tmf.getTrustManagers(), new SecureRandom());
return new SSLConnectionSocketFactory(
context,
null,
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()
);
} catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException | KeyManagementException e) {
throw new TlsException(Error.INIT_SSL_CONTEXT, e);
}
}
/**
* Inner class to bundle common error messages.
*/
@ -910,6 +975,7 @@ public class HTTPVaultConnector implements VaultConnector {
private static final String UNEXPECTED_RESPONSE = "Received response where none was expected";
private static final String URI_FORMAT = "Invalid URI format";
private static final String RESPONSE_CODE = "Invalid response code";
private static final String INIT_SSL_CONTEXT = "Unable to intialize SSLContext";
/**
* Constructor hidden, this class should not be instantiated.

View File

@ -21,6 +21,7 @@ import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.*;
import de.stklcode.jvault.connector.model.response.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -33,7 +34,7 @@ import java.util.Map;
* @author Stefan Kalscheuer
* @since 0.1
*/
public interface VaultConnector extends AutoCloseable {
public interface VaultConnector extends AutoCloseable, Serializable {
/**
* Default sub-path for Vault secrets.
*/

View File

@ -0,0 +1,298 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Vault Connector Factory implementation for HTTP Vault connectors.
*
* @author Stefan Kalscheuer
* @since 0.8.0
*/
public final class HTTPVaultConnectorBuilder implements VaultConnectorBuilder {
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String tlsVersion;
private String prefix;
private X509Certificate trustedCA;
private int numberOfRetries;
private Integer timeout;
private String token;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
public HTTPVaultConnectorBuilder() {
host = DEFAULT_HOST;
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
tlsVersion = DEFAULT_TLS_VERSION;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
}
/**
* Set hostname (default: 127.0.0.1).
*
* @param host Hostname or IP address
* @return self
*/
public HTTPVaultConnectorBuilder withHost(final String host) {
this.host = host;
return this;
}
/**
* Set port (default: 8200).
*
* @param port Vault TCP port
* @return self
*/
public HTTPVaultConnectorBuilder withPort(final Integer port) {
this.port = port;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS use TLS or not
* @return self
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS) {
this.tls = useTLS;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS Use TLS or not.
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS, final String version) {
this.tls = useTLS;
this.tlsVersion = version;
return this;
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final String version) {
return withTLS(true, version);
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @return self
*/
public HTTPVaultConnectorBuilder withTLS() {
return withTLS(true);
}
/**
* Convenience Method for NOT using TLS.
*
* @return self
*/
public HTTPVaultConnectorBuilder withoutTLS() {
return withTLS(false);
}
/**
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
*
* @param prefix Vault API prefix (default: "/v1/"
* @return self
*/
public HTTPVaultConnectorBuilder withPrefix(final String prefix) {
this.prefix = prefix;
return this;
}
/**
* Add a trusted CA certifiate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @throws VaultConnectorException on error
* @since 0.4.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) {
return withTrustedCA(certificateFromFile(cert));
} else {
this.trustedCA = null;
}
return this;
}
/**
* Add a trusted CA certifiate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final X509Certificate cert) {
this.trustedCA = cert;
return this;
}
/**
* Set token for automatic authentication, using {@link #buildAndAuth()}.
*
* @param token Vault token
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withToken(final String token) {
this.token = token;
return this;
}
/**
* Build connector based on the {@code }VAULT_ADDR} and {@code VAULT_CACERT} (optional) environment variables.
*
* @return self
* @throws VaultConnectorException if Vault address from environment variables is malformed
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
return this;
}
/**
* Define the number of retries to attempt on 5xx errors.
*
* @param numberOfRetries The number of retries to attempt on 5xx errors (default: 0)
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
return this;
}
/**
* Define a custom timeout for the HTTP connection.
*
* @param milliseconds Timeout value in milliseconds.
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withTimeout(final int milliseconds) {
this.timeout = milliseconds;
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, tlsVersion, port, prefix, trustedCA, numberOfRetries, timeout);
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) {
throw new ConnectionException("No vault token provided, unable to authenticate.");
}
HTTPVaultConnector con = build();
con.authToken(token);
return con;
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.VaultConnector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
/**
* Abstract Vault Connector Builder interface.
* Provides builder style for Vault connectors.
*
* @author Stefan Kalscheuer
* @since 0.8.0
*/
public interface VaultConnectorBuilder {
/**
* Get Factory implementation for HTTP Vault Connector.
*
* @return HTTP Connector Factory
*/
static HTTPVaultConnectorBuilder http() {
return new HTTPVaultConnectorBuilder();
}
/**
* Build command, produces connector after initialization.
*
* @return Vault Connector instance.
*/
VaultConnector build();
/**
* Build connector and authenticate with token set in factory or from environment.
*
* @return Authenticated Vault connector instance.
* @throws VaultConnectorException if authentication failed
* @since 0.6.0
*/
VaultConnector buildAndAuth() throws VaultConnectorException;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This package contains the {@link de.stklcode.jvault.connector.builder.VaultConnectorBuilder} to initialize a
* connector instance.
*/
package de.stklcode.jvault.connector.builder;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Some custom exceptions for error handling.
*/
package de.stklcode.jvault.connector.exception;

View File

@ -17,23 +17,11 @@
package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
@ -41,38 +29,19 @@ import java.security.cert.X509Certificate;
*
* @author Stefan Kalscheuer
* @since 0.1
* @deprecated As of 0.8.0 please refer to {@link de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder} with identical API.
*/
@Deprecated
public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String prefix;
private SSLContext sslContext;
private int numberOfRetries;
private Integer timeout;
private String token;
private final HTTPVaultConnectorBuilder delegate;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
public HTTPVaultConnectorFactory() {
host = DEFAULT_HOST;
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
delegate = new HTTPVaultConnectorBuilder();
}
/**
@ -82,7 +51,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self
*/
public HTTPVaultConnectorFactory withHost(final String host) {
this.host = host;
delegate.withHost(host);
return this;
}
@ -93,7 +62,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self
*/
public HTTPVaultConnectorFactory withPort(final Integer port) {
this.port = port;
delegate.withPort(port);
return this;
}
@ -104,7 +73,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self
*/
public HTTPVaultConnectorFactory withTLS(final boolean useTLS) {
this.tls = useTLS;
delegate.withTLS(useTLS);
return this;
}
@ -133,7 +102,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self
*/
public HTTPVaultConnectorFactory withPrefix(final String prefix) {
this.prefix = prefix;
delegate.withPrefix(prefix);
return this;
}
@ -146,8 +115,19 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.4.0
*/
public HTTPVaultConnectorFactory withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null)
return withSslContext(createSslContext(cert));
delegate.withTrustedCA(cert);
return this;
}
/**
* Add a trusted CA certifiate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorFactory withTrustedCA(final X509Certificate cert) {
delegate.withTrustedCA(cert);
return this;
}
@ -158,10 +138,10 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @param sslContext the SSL context
* @return self
* @since 0.4.0
* @deprecated As of 0.8.0 this is no longer supported, please use {@link #withTrustedCA(Path)} or {@link #withTrustedCA(X509Certificate)}.
*/
public HTTPVaultConnectorFactory withSslContext(final SSLContext sslContext) {
this.sslContext = sslContext;
return this;
throw new UnsupportedOperationException("Use of deprecated method, please switch to withTrustedCA()");
}
/**
@ -172,7 +152,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0
*/
public HTTPVaultConnectorFactory withToken(final String token) {
this.token = token;
delegate.withToken(token);
return this;
}
@ -184,34 +164,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0
*/
public HTTPVaultConnectorFactory fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
delegate.fromEnv();
return this;
}
@ -223,7 +176,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0
*/
public HTTPVaultConnectorFactory withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
delegate.withNumberOfRetries(numberOfRetries);
return this;
}
@ -235,78 +188,17 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0
*/
public HTTPVaultConnectorFactory withTimeout(final int milliseconds) {
this.timeout = milliseconds;
delegate.withTimeout(milliseconds);
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, port, prefix, sslContext, numberOfRetries, timeout);
return delegate.build();
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null)
throw new ConnectionException("No vault token provided, unable to authenticate.");
HTTPVaultConnector con = new HTTPVaultConnector(host, tls, port, prefix, sslContext, numberOfRetries, timeout);
con.authToken(token);
return con;
}
/**
* Create SSL Context trusting only provided certificate.
*
* @param trustedCert Path to trusted CA certificate
* @return SSL context
* @throws TlsException on errors
* @since 0.4.0
*/
private SSLContext createSslContext(final Path trustedCert) throws TlsException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, createTrustManager(trustedCert), new SecureRandom());
return context;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new TlsException("Unable to intialize SSLContext", e);
}
}
/**
* Create a custom TrustManager for given CA certificate file.
*
* @param trustedCert Path to trusted CA certificate
* @return TrustManger
* @throws TlsException on error
* @since 0.4.0
*/
private TrustManager[] createTrustManager(final Path trustedCert) throws TlsException {
try {
/* Create Keystore with trusted certificate */
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", certificateFromFile(trustedCert));
/* Initialize TrustManager */
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
return tmf.getTrustManagers();
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
throw new TlsException("Unable to initialize TrustManager", e);
}
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
return delegate.buildAndAuth();
}
}

View File

@ -17,6 +17,7 @@
package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.VaultConnector;
import de.stklcode.jvault.connector.builder.VaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
/**
@ -25,30 +26,19 @@ import de.stklcode.jvault.connector.exception.VaultConnectorException;
*
* @author Stefan Kalscheuer
* @since 0.1
* @deprecated As of 0.8.0 please refer to {@link VaultConnectorBuilder} with identical API.
*/
public abstract class VaultConnectorFactory {
@Deprecated
public abstract class VaultConnectorFactory implements VaultConnectorBuilder {
/**
* Get Factory implementation for HTTP Vault Connector.
*
* @return HTTP Connector Factory
* @deprecated As of 0.8.0 please refer to {@link VaultConnectorBuilder#http()}.
*/
@Deprecated
public static HTTPVaultConnectorFactory httpFactory() {
return new HTTPVaultConnectorFactory();
}
/**
* Build command, produces connector after initialization.
*
* @return Vault Connector instance.
*/
public abstract VaultConnector build();
/**
* Build connector and authenticate with token set in factory or from environment.
*
* @return Authenticated Vault connector instance.
* @throws VaultConnectorException if authentication failed
* @since 0.6.0
*/
public abstract VaultConnector buildAndAuth() throws VaultConnectorException;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This package contains the {@link de.stklcode.jvault.connector.factory.VaultConnectorFactory} to initialize a
* connector instance.
*
* @deprecated As of v0.8.0 please refer to {@link de.stklcode.jvault.connector.builder}.
*/
package de.stklcode.jvault.connector.factory;

View File

@ -41,6 +41,8 @@ public final class AppRole {
private List<String> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies;
@JsonProperty("secret_id_num_uses")
@ -73,24 +75,57 @@ public final class AppRole {
/**
* Construct complete {@link AppRole} object.
*
* @param name Role name (required)
* @param id Role ID (optional)
* @param bindSecretId Bind secret ID (optional)
* @param boundCidrList Whitelist of subnets in CIDR notation (optional)
* @param policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional)
* @param period Duration in seconds, if set the token is a periodic token (optional)
* @param name Role name (required)
* @param id Role ID (optional)
* @param bindSecretId Bind secret ID (optional)
* @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional)
* @param policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional)
* @param period Duration in seconds, if set the token is a periodic token (optional)
*/
public AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> boundCidrList,
public AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> secretIdBoundCidrs,
final List<String> policies, final Integer secretIdNumUses, final Integer secretIdTtl,
final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) {
this.name = name;
this.id = id;
this.bindSecretId = bindSecretId;
this.secretIdBoundCidrs = secretIdBoundCidrs;
this.policies = policies;
this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl;
this.tokenTtl = tokenTtl;
this.tokenMaxTtl = tokenMaxTtl;
this.period = period;
}
/**
* Construct complete {@link AppRole} object.
*
* This constructor is used for transition from {@code bound_cidr_list} to {@code secret_id_bound_cidrs} only.
*
* @param name Role name (required)
* @param id Role ID (optional)
* @param bindSecretId Bind secret ID (optional)
* @param boundCidrList Whitelist of subnets in CIDR notation (optional)
* @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional)
* @param policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional)
* @param period Duration in seconds, if set the token is a periodic token (optional)
*/
AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> boundCidrList,
final List<String> secretIdBoundCidrs, final List<String> policies, final Integer secretIdNumUses,
final Integer secretIdTtl, final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) {
this.name = name;
this.id = id;
this.bindSecretId = bindSecretId;
this.boundCidrList = boundCidrList;
this.secretIdBoundCidrs = secretIdBoundCidrs;
this.policies = policies;
this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl;
@ -122,14 +157,18 @@ public final class AppRole {
/**
* @return list of bound CIDR subnets
* @deprecated Use {@link #getSecretIdBoundCidrs()} instead, as this parameter is deprecated in Vault.
*/
@Deprecated
public List<String> getBoundCidrList() {
return boundCidrList;
}
/**
* @param boundCidrList list of subnets in CIDR notation to bind role to
* @deprecated Use {@link #setSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault.
*/
@Deprecated
@JsonSetter("bound_cidr_list")
public void setBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList;
@ -137,7 +176,9 @@ public final class AppRole {
/**
* @return list of subnets in CIDR notation as comma-separated {@link String}
* @deprecated Use {@link #getSecretIdBoundCidrsString()} instead, as this parameter is deprecated in Vault.
*/
@Deprecated
@JsonGetter("bound_cidr_list")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public String getBoundCidrListString() {
@ -146,6 +187,36 @@ public final class AppRole {
return String.join(",", boundCidrList);
}
/**
* @return list of bound CIDR subnets
* @since 0.8 replaces {@link #getBoundCidrList()}
*/
public List<String> getSecretIdBoundCidrs() {
return secretIdBoundCidrs;
}
/**
* @param secretIdBoundCidrs List of subnets in CIDR notation to bind secrets of this role to.
* @since 0.8 replaces {@link #setBoundCidrList(List)}
*/
@JsonSetter("secret_id_bound_cidrs")
public void setSecretIdBoundCidrs(final List<String> secretIdBoundCidrs) {
this.secretIdBoundCidrs = secretIdBoundCidrs;
}
/**
* @return List of subnets in CIDR notation as comma-separated {@link String}
* @since 0.8 replaces {@link #getBoundCidrListString()} ()}
*/
@JsonGetter("secret_id_bound_cidrs")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public String getSecretIdBoundCidrsString() {
if (secretIdBoundCidrs == null || secretIdBoundCidrs.isEmpty()) {
return "";
}
return String.join(",", secretIdBoundCidrs);
}
/**
* @return list of policies
*/

View File

@ -30,6 +30,7 @@ public final class AppRoleBuilder {
private String id;
private Boolean bindSecretId;
private List<String> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies;
private Integer secretIdNumUses;
private Integer secretIdTtl;
@ -93,12 +94,26 @@ public final class AppRoleBuilder {
*
* @param boundCidrList List of CIDR blocks which can perform login
* @return self
* @deprecated Use {@link #withSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault.
*/
@Deprecated
public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList;
return this;
}
/**
* Set bound CIDR blocks.
*
* @param secretIdBoundCidrs List of CIDR blocks which can perform login
* @return self
* @since 0.8 replaces {@link #withBoundCidrList(List)}
*/
public AppRoleBuilder withSecretIdBoundCidrs(final List<String> secretIdBoundCidrs) {
this.secretIdBoundCidrs = secretIdBoundCidrs;
return this;
}
/**
* Add a CIDR block to list of bound blocks.
*
@ -106,9 +121,15 @@ public final class AppRoleBuilder {
* @return self
*/
public AppRoleBuilder withCidrBlock(final String cidrBlock) {
if (boundCidrList == null)
if (boundCidrList == null) {
boundCidrList = new ArrayList<>();
}
boundCidrList.add(cidrBlock);
if (secretIdBoundCidrs == null) {
secretIdBoundCidrs = new ArrayList<>();
}
secretIdBoundCidrs.add(cidrBlock);
return this;
}
@ -204,6 +225,7 @@ public final class AppRoleBuilder {
id,
bindSecretId,
boundCidrList,
secretIdBoundCidrs,
policies,
secretIdNumUses,
secretIdTtl,

View File

@ -0,0 +1,20 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Model classes for communication with the Vault API.
*/
package de.stklcode.jvault.connector.model;

View File

@ -48,6 +48,15 @@ public final class HealthResponse implements VaultResponse {
@JsonProperty("initialized")
private Boolean initialized;
@JsonProperty("replication_perf_mode")
private String replicationPerfMode;
@JsonProperty("replication_dr_mode")
private String replicationDrMode;
@JsonProperty("performance_standby")
private Boolean performanceStandby;
/**
* @return The Cluster ID.
*/
@ -96,4 +105,28 @@ public final class HealthResponse implements VaultResponse {
public Boolean isInitialized() {
return initialized;
}
/**
* @return Replication performance mode of the active node (since Vault 0.9.2).
* @since 0.8 (#21)
*/
public String getReplicationPerfMode() {
return replicationPerfMode;
}
/**
* @return Replication DR mode of the active node (since Vault 0.9.2).
* @since 0.8 (#21)
*/
public String getReplicationDrMode() {
return replicationDrMode;
}
/**
* @return Performance standby status.
* @since 0.8 (#21)
*/
public Boolean isPerformanceStandby() {
return performanceStandby;
}
}

View File

@ -22,14 +22,20 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Vault response for seal status or unseal request.
*
* @author Stefan Kalscheuer
* @since 0.1
* @author Stefan Kalscheuer
* @since 0.1
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class SealResponse implements VaultResponse {
@JsonProperty("type")
private String type;
@JsonProperty("sealed")
private boolean sealed;
@JsonProperty("initialized")
private boolean initialized;
@JsonProperty("t")
private Integer threshold;
@ -39,6 +45,26 @@ public final class SealResponse implements VaultResponse {
@JsonProperty("progress")
private Integer progress;
@JsonProperty("version")
private String version;
@JsonProperty("nonce")
private String nonce;
@JsonProperty("cluster_name")
private String clusterName;
@JsonProperty("cluster_id")
private String clusterId;
/**
* @return Seal type.
* @since 0.8
*/
public String getType() {
return type;
}
/**
* @return Seal status
*/
@ -46,6 +72,14 @@ public final class SealResponse implements VaultResponse {
return sealed;
}
/**
* @return Vault initialization status (since Vault 0.11.2).
* @since 0.8
*/
public boolean isInitialized() {
return initialized;
}
/**
* @return Required threshold of secret shares
*/
@ -66,4 +100,36 @@ public final class SealResponse implements VaultResponse {
public Integer getProgress() {
return progress;
}
/**
* @return Vault version.
* @since 0.8
*/
public String getVersion() {
return version;
}
/**
* @return A random nonce.
* @since 0.8
*/
public String getNonce() {
return nonce;
}
/**
* @return Vault cluster name (only if unsealed).
* @since 0.8
*/
public String getClusterName() {
return clusterName;
}
/**
* @return Vault cluster ID (only if unsealed).
* @since 0.8
*/
public String getClusterId() {
return clusterId;
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Embedded data classes for responses from the Vault API.
*/
package de.stklcode.jvault.connector.model.response.embedded;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Model classes for responses from the Vault API.
*/
package de.stklcode.jvault.connector.model.response;

View File

@ -0,0 +1,21 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Java Vault Connector base package - contains {@link de.stklcode.jvault.connector.VaultConnector} interface and
* default implementation.
*/
package de.stklcode.jvault.connector;

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API Overview</title>
</head>
<body>
<p>Java Vault Connector is a connector library for Vault by Hashicorp written in Java.</p>
<p>The connector allows simple usage of Vault's secret store in own applications.</p>
<p>It features a default implementation for the HTTP(S) interface and supports various authorization methods including
AppRole, token and secret handling.</p>
</body>
</html>

View File

@ -34,10 +34,12 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import static net.bytebuddy.implementation.MethodDelegation.to;
@ -152,7 +154,7 @@ public class HTTPVaultConnectorOfflineTest {
* Test constductors of the {@link HTTPVaultConnector} class.
*/
@Test
public void constructorTest() throws NoSuchAlgorithmException {
public void constructorTest() throws IOException, CertificateException {
final String url = "https://vault.example.net/test/";
final String hostname = "vault.example.com";
final Integer port = 1337;
@ -161,7 +163,11 @@ public class HTTPVaultConnectorOfflineTest {
final String expectedNoTls = "http://" + hostname + "/v1/";
final String expectedCustomPort = "https://" + hostname + ":" + port + "/v1/";
final String expectedCustomPrefix = "https://" + hostname + ":" + port + prefix;
final SSLContext sslContext = SSLContext.getInstance("TLS");
X509Certificate trustedCaCert;
try (InputStream is = getClass().getResourceAsStream("/tls/ca.pem")) {
trustedCaCert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
}
// Most basic constructor expects complete URL.
HTTPVaultConnector connector = new HTTPVaultConnector(url);
@ -178,16 +184,22 @@ public class HTTPVaultConnectorOfflineTest {
// Specify custom prefix.
connector = new HTTPVaultConnector(hostname, true, port, prefix);
assertThat("Unexpected base URL with custom prefix", getPrivate(connector, "baseURL"), is(expectedCustomPrefix));
assertThat("SSL context set, but not specified", getPrivate(connector, "sslContext"), is(nullValue()));
assertThat("Trusted CA cert set, but not specified", getPrivate(connector, "trustedCaCert"), is(nullValue()));
// Provide custom SSL context.
connector = new HTTPVaultConnector(hostname, true, port, prefix, sslContext);
connector = new HTTPVaultConnector(hostname, true, port, prefix, trustedCaCert);
assertThat("Unexpected base URL with custom prefix", getPrivate(connector, "baseURL"), is(expectedCustomPrefix));
assertThat("SSL context not filled correctly", getPrivate(connector, "sslContext"), is(sslContext));
assertThat("Trusted CA cert not filled correctly", getPrivate(connector, "trustedCaCert"), is(trustedCaCert));
// Specify number of retries.
connector = new HTTPVaultConnector(url, sslContext, retries);
connector = new HTTPVaultConnector(url, trustedCaCert, retries);
assertThat("Number of retries not set correctly", getPrivate(connector, "retries"), is(retries));
// Test TLS version (#22).
assertThat("TLS version should be 1.2 if not specified", getPrivate(connector, "tlsVersion"), is("TLSv1.2"));
// Now override.
connector = new HTTPVaultConnector(url, trustedCaCert, retries, null, "TLSv1.1");
assertThat("Overridden TLS version 1.1 not correct", getPrivate(connector, "tlsVersion"), is("TLSv1.1"));
}
/**

View File

@ -56,19 +56,21 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
*/
@EnableRuleMigrationSupport
public class HTTPVaultConnectorTest {
private static final String VAULT_VERISON = "0.11.4"; // the vault version this test is supposed to run against
private static final String KEY = "81011a8061e5c028bd0d9503eeba40bd9054b9af0408d080cb24f57405c27a61";
private static final String TOKEN_ROOT = "d1bd50e2-587b-6e68-d80b-a9a507625cb7";
private static String VAULT_VERSION = "0.11.5"; // the vault version this test is supposed to run against
private static final String KEY1 = "E38bkCm0VhUvpdCKGQpcohhD9XmcHJ/2hreOSY019Lho";
private static final String KEY2 = "O5OHwDleY3IiPdgw61cgHlhsrEm6tVJkrxhF6QAnILd1";
private static final String KEY3 = "mw7Bm3nbt/UWa/juDjjL2EPQ04kiJ0saC5JEXwJvXYsB";
private static final String TOKEN_ROOT = "30ug6wfy2wvlhhe5h7x0pbkx";
private static final String USER_VALID = "validUser";
private static final String PASS_VALID = "validPass";
private static final String APP_ID = "152AEA38-85FB-47A8-9CBD-612D645BFACA";
private static final String USER_ID = "5ADF8218-D7FB-4089-9E38-287465DBF37E";
private static final String APPROLE_ROLE_NAME = "testrole1"; // role with secret ID
private static final String APPROLE_ROLE = "627b6400-90c3-a239-49a9-af65a448ca10";
private static final String APPROLE_SECRET = "5e8b0e99-d906-27f5-f043-ccb9bb53b5e8";
private static final String APPROLE_SECRET_ACCESSOR = "071e2e9d-742a-fc3c-3fd3-1f4004b0420a";
private static final String APPROLE_ROLE = "06eae026-7d4b-e4f8-0ec4-4107eb483975";
private static final String APPROLE_SECRET = "20320293-c1c1-3b22-20f8-e5c960da0b5b";
private static final String APPROLE_SECRET_ACCESSOR = "3b45a7c2-8d1c-abcf-c732-ecf6db16a8e1";
private static final String APPROLE_ROLE2_NAME = "testrole2"; // role with CIDR subnet
private static final String APPROLE_ROLE2 = "35b7bf43-9644-588a-e68f-2e8313bb23b7";
private static final String APPROLE_ROLE2 = "40224890-1563-5193-be4b-0b4f9f573b7f";
private static final String SECRET_PATH = "userstore";
private static final String SECRET_KEY = "foo";
private static final String SECRET_VALUE = "bar";
@ -81,6 +83,15 @@ public class HTTPVaultConnectorTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
@BeforeAll
public static void init() {
// Override vault version if defined in sysenv.
if (System.getenv("VAULT_VERSION") != null) {
VAULT_VERSION = System.getenv("VAULT_VERSION");
System.out.println("Vault version set to " + VAULT_VERSION);
}
}
/**
* Initialize Vault instance with generated configuration and provided file backend.
* Requires "vault" binary to be in current user's executable path. Not using MLock, so no extended rights required.
@ -108,9 +119,13 @@ public class HTTPVaultConnectorTest {
connector = factory.build();
/* Unseal Vault and check result */
SealResponse sealStatus = connector.unseal(KEY);
SealResponse sealStatus = connector.unseal(KEY1);
assumeTrue(sealStatus != null);
assumeTrue(sealStatus.isSealed());
sealStatus = connector.unseal(KEY2);
assumeTrue(sealStatus != null);
assumeFalse(sealStatus.isSealed());
assumeTrue(sealStatus.isInitialized()); // Initialized flag of Vault 0.11.2 (#20).
}
@AfterEach
@ -142,7 +157,9 @@ public class HTTPVaultConnectorTest {
connector.seal();
sealStatus = connector.sealStatus();
assertThat("Vault not sealed", sealStatus.isSealed(), is(true));
sealStatus = connector.unseal(KEY);
sealStatus = connector.unseal(KEY2);
assertThat("Vault unsealed with only 1 key", sealStatus.isSealed(), is(true));
sealStatus = connector.unseal(KEY3);
assertThat("Vault not unsealed", sealStatus.isSealed(), is(false));
} catch (VaultConnectorException e) {
fail("Sealing failed");
@ -161,7 +178,7 @@ public class HTTPVaultConnectorTest {
fail("Retrieving health status failed: " + e.getMessage());
}
assertThat("Health response should be set", res, is(notNullValue()));
assertThat("Unexpected version", res.getVersion(), is(VAULT_VERISON));
assertThat("Unexpected version", res.getVersion(), is(VAULT_VERSION));
assertThat("Unexpected init status", res.isInitialized(), is(true));
assertThat("Unexpected seal status", res.isSealed(), is(false));
assertThat("Unexpected standby status", res.isStandby(), is(false));
@ -861,12 +878,18 @@ public class HTTPVaultConnectorTest {
try {
AuthResponse res = connector.createToken(token);
assertThat("No result given.", res, is(notNullValue()));
assertThat("Token creation returned warnings.", res.getWarnings(), is(nullValue()));
assertThat("Invalid token ID returned.", res.getAuth().getClientToken(), is("test-id"));
assertThat("Invalid number of policies returned.", res.getAuth().getPolicies(), hasSize(1));
assertThat("Root policy not inherited.", res.getAuth().getPolicies(), contains("root"));
assertThat("Metadata unexpected.", res.getAuth().getMetadata(), is(nullValue()));
assertThat("Root token should not be renewable", res.getAuth().isRenewable(), is(false));
// Starting with Vault 1.0 a warning "cusotm ID uses weaker SHA1..." is given.
if (VAULT_VERSION.startsWith("1.")) {
assertThat("Token creation did not return expected warning.", res.getWarnings(), hasSize(1));
} else {
assertThat("Token creation returned warnings.", res.getWarnings(), is(nullValue()));
}
} catch (VaultConnectorException e) {
fail("Secret written to inaccessible path.");
}

View File

@ -0,0 +1,130 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.factory.VaultConnectorFactory;
import org.junit.Rule;
import org.junit.contrib.java.lang.system.EnvironmentVariables;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
import org.junit.rules.TemporaryFolder;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* JUnit test for HTTP Vault connector factory
*
* @author Stefan Kalscheuer
* @since 0.8.0
*/
@EnableRuleMigrationSupport
public class HTTPVaultConnectorBuilderTest {
private static String VAULT_ADDR = "https://localhost:8201";
private static Integer VAULT_MAX_RETRIES = 13;
private static String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
@Rule
public final EnvironmentVariables environment = new EnvironmentVariables();
/**
* Test building from environment variables
*/
@Test
public void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException {
/* Provide address only should be enough */
setenv(VAULT_ADDR, null, null, null);
HTTPVaultConnectorBuilder factory = null;
HTTPVaultConnector connector;
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getPrivate(connector, "retries"), is(0));
/* Provide address and number of retries */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null);
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
/* Provide CA certificate */
String VAULT_CACERT = tmpDir.newFolder().toString() + "/doesnotexist";
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null);
try {
VaultConnectorFactory.httpFactory().fromEnv();
fail("Creation with unknown cert path failed.");
} catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(TlsException.class)));
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
}
/* Automatic authentication */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN);
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(factory, "token"), is(equalTo(VAULT_TOKEN)));
}
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
environment.set("VAULT_ADDR", vault_addr);
environment.set("VAULT_CACERT", vault_cacert);
environment.set("VAULT_MAX_RETRIES", vault_max_retries);
environment.set("VAULT_TOKEN", vault_token);
}
private Object getPrivate(Object target, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field field = target.getClass().getDeclaredField(fieldName);
if (field.isAccessible())
return field.get(target);
field.setAccessible(true);
Object value = field.get(target);
field.setAccessible(false);
return value;
}
}

View File

@ -69,7 +69,7 @@ public class HTTPVaultConnectorFactoryTest {
connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("SSL context set when no cert provided", getPrivate(connector, "sslContext"), is(nullValue()));
assertThat("Trusted CA cert set when no cert provided", getPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getPrivate(connector, "retries"), is(0));
/* Provide address and number of retries */
@ -83,7 +83,7 @@ public class HTTPVaultConnectorFactoryTest {
connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("SSL context set when no cert provided", getPrivate(connector, "sslContext"), is(nullValue()));
assertThat("Trusted CA cert set when no cert provided", getPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
/* Provide CA certificate */
@ -107,7 +107,7 @@ public class HTTPVaultConnectorFactoryTest {
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(factory, "token"), is(equalTo(VAULT_TOKEN)));
assertThat("Token nor set correctly", getPrivate(getPrivate(factory, "delegate"), "token"), is(equalTo(VAULT_TOKEN)));
}
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {

View File

@ -51,8 +51,8 @@ public class AppRoleBuilderTest {
private static final Integer TOKEN_MAX_TTL = 9600;
private static final Integer PERIOD = 1234;
private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}";
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}",
NAME, ID, BIND_SECRET_ID, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD);
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"secret_id_bound_cidrs\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}",
NAME, ID, BIND_SECRET_ID, CIDR_1, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD);
@BeforeAll
public static void init() {
@ -69,6 +69,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue()));
assertThat(role.getBoundCidrList(), is(nullValue()));
assertThat(role.getSecretIdBoundCidrs(), is(nullValue()));
assertThat(role.getPolicies(), is(nullValue()));
assertThat(role.getSecretIdNumUses(), is(nullValue()));
assertThat(role.getSecretIdTtl(), is(nullValue()));
@ -89,6 +90,7 @@ public class AppRoleBuilderTest {
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
.withBoundCidrList(BOUND_CIDR_LIST)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL)
@ -100,6 +102,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(ID));
assertThat(role.getBindSecretId(), is(BIND_SECRET_ID));
assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST));
assertThat(role.getSecretIdBoundCidrs(), is(BOUND_CIDR_LIST));
assertThat(role.getPolicies(), is(POLICIES));
assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES));
assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL));
@ -128,12 +131,16 @@ public class AppRoleBuilderTest {
role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build();
assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(1));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_2));
role = new AppRoleBuilder(NAME)
.withBoundCidrList(BOUND_CIDR_LIST)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withCidrBlock(CIDR_2)
.build();
assertThat(role.getBoundCidrList(), hasSize(2));
assertThat(role.getBoundCidrList(), contains(CIDR_1, CIDR_2));
assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(2));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_1, CIDR_2));
/* Add single policy */
role = new AppRoleBuilder(NAME).withPolicy(POLICY_2).build();

View File

@ -35,11 +35,14 @@ import static org.junit.jupiter.api.Assertions.fail;
public class HealthResponseTest {
private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228";
private static final String CLUSTER_NAME = "vault-cluster-5515c810";
private static final String VERSION = "0.6.2";
private static final String VERSION = "0.9.2";
private static final Long SERVER_TIME_UTC = 1469555798L;
private static final Boolean STANDBY = false;
private static final Boolean SEALED = false;
private static final Boolean INITIALIZED = true;
private static final Boolean PERF_STANDBY = false;
private static final String REPL_PERF_MODE = "disabled";
private static final String REPL_DR_MODE = "disabled";
private static final String RES_JSON = "{\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
@ -48,7 +51,10 @@ public class HealthResponseTest {
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
" \"standby\": " + STANDBY + ",\n" +
" \"sealed\": " + SEALED + ",\n" +
" \"initialized\": " + INITIALIZED + "\n" +
" \"initialized\": " + INITIALIZED + ",\n" +
" \"replication_perf_mode\": \"" + REPL_PERF_MODE + "\",\n" +
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + "\n" +
"}";
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
@ -65,6 +71,9 @@ public class HealthResponseTest {
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
} catch (IOException e) {
fail("Health deserialization failed: " + e.getMessage());
}

View File

@ -0,0 +1,112 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
/**
* JUnit Test for {@link SealResponse} model.
*
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SealResponseTest {
private static final String TYPE = "shamir";
private static final Integer THRESHOLD = 3;
private static final Integer SHARES = 5;
private static final Integer PROGRESS_SEALED = 2;
private static final Integer PROGRESS_UNSEALED = 0;
private static final String VERSION = "0.11.2";
private static final String CLUSTER_NAME = "vault-cluster-d6ec3c7f";
private static final String CLUSTER_ID = "3e8b3fec-3749-e056-ba41-b62a63b997e8";
private static final String NONCE = "ef05d55d-4d2c-c594-a5e8-55bc88604c24";
private static final String RES_SEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": true,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_SEALED + ",\n" +
" \"nonce\": \"\",\n" +
" \"version\": \"" + VERSION + "\"\n" +
"}";
private static final String RES_UNSEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": false,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"nonce\": \"" + NONCE + "\"\n" +
"}";
/**
* Test creation from JSON value as returned by Vault when sealed (JSON example close to Vault documentation).
*/
@Test
public void jsonRoundtripSealed() {
// First test sealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_SEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(true));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
assertThat("Nonce not empty", res.getNonce(), is(""));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
// And the fields, that should not be filled.
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
// Not test unsealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(false));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
}
}

View File

@ -92,7 +92,7 @@ public class VaultConfiguration {
@Override
public String toString() {
return "backend \"file\" {\n" +
return "storage \"file\" {\n" +
" path = \"" + dataLocation + "\"\n" +
"}\n" +
"listener \"tcp\" {\n" +

View File

@ -1 +0,0 @@
{"Key":"auth/20e9c2e6-5b1f-b9c9-5a99-21667e0a899d/salt","Value":"AAAAAQJUsuXXEpmdNY5aIh5HdzZRTFpOUIgyKLGiw65DBwSXW6yGAYe/zhN/Ow+vyRZxG4temgnTjN7RVGjyzXGG5yLY"}

View File

@ -1 +0,0 @@
{"Key":"auth/20e9c2e6-5b1f-b9c9-5a99-21667e0a899d/struct/map/app-id/19d90b9adcec2bf5088304034622a169a148ff43","Value":"AAAAAQJuuRcCRinyawQ05brruZQY7ypgs1mOsFHI16XLwYB4dzwJob71wW+74RjvK4FVL4qPfgyMPKEtV2uO9+4hr2mC6BrcN///Ksxv+ns8FMVlBOMJpQ=="}

View File

@ -1 +0,0 @@
{"Key":"auth/20e9c2e6-5b1f-b9c9-5a99-21667e0a899d/struct/map/user-id/55a852babe045b5980fc8ac4a13af27021dbbfd4","Value":"AAAAAQICaFIxG2xAq0AuJryVn1XghDulkVdQicXvhEL45K2S48aZcvMEsrDUXm9o427Bp6eMiq0Hw070nosnB9SWSQJEFUfPmM6I7Jhsou6CKmocs/AmocxY3Du4Lg=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQINZKQEssY4IzHI/0k27nBtxSvnC6LkivYrqky6CblcjyAmQIg/4/cKQIBCXzmrWEv/SqMQbLw+4Lp63Xu1niF+U0NbyqDmFaPqnD2yfPs7meXvZr21+P9E/0APZMHQaSR7DIEY46zedHRjQ/pkhR2Axcjuy5gdfzBzC2XvUcNqdyR0pQwcDwGhAIdO0gxJfZCeBuvv8ceYS+aPs4gDHtIlA3szi+5qAQ8HvPBTDKQn1lHVYnzTdNbMS7v3mtzCyG8AeMkaUw=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJiN0bHxM8aNJpY7aHGZ/p3qOhJbd7JIXwFMEI4LtKmO6pP5Oa4P5z+2LK+2qzZhhX/iDeM4u+nR+lxt/GsBPKf"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIZ5rvzLtBcBQvWqwwDoRADwUo6W0ECKgmcvXejbLKiYcbO0hP8fceCqB12J41wxcMViQ8vvWoIgyOX2HwcZS09GGCqQbjvyVfz/w+kyox9dJzr845f26tJjHVYlHX2YFsnxytwe5qCKdCsD5QP9kyz8J0="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJIKXgvJ2Prr92Fn7qZK/WZxb+Q+vJsXyjMo44en/+zqbbnLfs5m7uH7hEUOfDM/MjzTrhfkOWxf6qcrC4MR3ocrFJwtbJ6j+QrNLg61gVIiLBUVBkvh8ErqCFnSjNIqhaIMQhuZXWANsgGF9K2+HBGJerWGe26C1rdWRZV4J0M23HnxLBf8aYDlOfkHe24I30rHUqXIk9/BKEuekcnhETw9Tx4Fk7KxxxEdGmHPbg+4G14c27wVj8IrpWHBpyLmt55Qdb/y24i5RzFYv1FQ2kQZIO6TQiYkwAUxJ5cIdCiAsEDNt+rBJ9zX1MvkEfkVj/WvzC9pxB7ad+j5vYIJgCUD1o09t0w2ChjBojGoOAWDSvNAeY8kr5PDKwYk+gBY5M2JHDI6ELvOVu8gsW+sqk9St9V3VisShTfU3+qln7TOWw/LQ+fUzGvYrAWG6UyPVpIEYeNmN0iGCIM8rzjQYvVC3KcQMG96MwK3ZlSQzgPpvTGxNxFm2omTn3ue7QHn7Ni6+c/K6xVy0bbJ+jS4yyfl2wFBm1tF1l3BITLqw3TiP3LEw=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIUt2iYYy9zOwkx1mtNMHt69RjdHbUmcN8zydVQTMGjhv1kjEW+d4AaBv1qE22rPTs0xL3pJ1AjIvkBXXVBAuc/FE63t5dE81Fa+MvSY4tBeMtl6i09ykkAYyQUeeV2HlbjRpMUwPyq2QIslYw3d4lc73yT0S82s5I3MfjodKmDpheWMOgg5hGes/wstBHN5HEZkKV8gOPRZ/BsTM7tMXH1piM/JT8sNfsDh6TAGD1OEsS+N2QlKvS4yImNzcKrH0EgdkXB4sRZ9e/SmMaEVaagB1n0M5LukC+pyExgC7eK4EU8o2Xye3iij3YMWBaGollDzJBJFP5aSO4E5u+NnRc5/ZbLRCbqgfQj8IY86WF9hya31aJxbc8Pg28Yfez8hbGRJZZws/ojIUgEz+VtH3OyaW2Wohnycop7i4fK8xlJ2gYOGvlw43czOH6Y6joTce+QBZWI7KR6ugB0dI8pnK2eFy14OZeww1NEew7r1u7PgD10Obg8okIJSD8cGkxUHu/oOLxvKKOAJBLSPfKnJfKEiKrqYED7EPkmgP/t7okvo4c95qeuWy1BLtKfxw5lkv0="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKv0Yr+QFSWxYe8o51TBwGz/yAhNYFmkNHPISEK6EbIVGkpEJMHFYvHWxTXUzF7f2/a"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKs2/ICwQPLv6siBGDbBnB52fBVo52BkSKGvm74p4oHrdMEvejJ4cJljOADYyDT2QYa"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIq05o3NmsucipTxPrcRbT1sXpAJ8w2PpiShnof74Kuzf/4kkHj3AZL5AObGFLAkYUvUrv3RRmYBIhw6Jk4FCbgdQyJAjPNVUTwBun/kQVyzP5sQ9hUFgHJwINomtVDiDgPkOc92zk8ydr1hfnMmTAtS71G3xloHDn6CF/1Y9WI1PkHdSkZ8d+yBNxr+qjGyewrV3QVmQvAfpY56uQ6AOztItD9NgiPrtNP+clbCczsieY6Y9Ce2FZawmuKFi9svMcBtnEcMILV/SGt4iCiMgFwkCJ9gQsGEdWPifu6ITPB92LgT4Ccw4gVRO31QVcPl6S+FG6iCeN6lk2yRXYjyhBuU+GklouEZIsA6SoxlIXPZuvauyS1MWwMxtSOQUFVYr3kvtXzCpcpEHDyBOEUdxPaYUZXHNdhGtMr/JuJCN50t0ng5mEAqfhjoJfJ/tBTqAjySj4zmEHuY0RnqYLPmsp203Q="}

View File

@ -1 +0,0 @@
{"Key":"auth/6802ec63-11b0-0ccc-280a-982ad0a90621/user/validuser","Value":"AAAAAQJwFKMpgopAFjJaftTVY/iiawMw4Yj0S3pPDkzMPAfLxxaM3sCjOJt0q/07ozjTharT52wBv+s2ZEurPpr7VKDDzgy4xTMxFJbJs+0VkG3cjxRYEfW3bOIVAHhjLjmxZwYEATh0UUG7bQRNt56+/622bwR99ifWZ6e9zyRDGEwIn74JFN/3dY44qLQZmqfvDUrRQP5RfqDxqVdzbwse61s692Vy/QvlPsRFVRTkZHlNPqxT+OXd"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQK5U1GclNj+Tga7D4bQ5wExYfVu2y+djHlAlhiJ/JHOS1gS0G/kDrjR8gCdg/Aw2UunrObAq/mrKw0HEe1wo2qA"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQLbvc+neI458Mqhl2WUUjY5HMC1Ast0KjZ5pslwW+5TtjVHcqdzls4whrrYHGUWv+nTg6wxJaS46j5+FER+4gsgWVJE1S33ZqvGtmmueCVpac5ZM0biBDXOvE/YFQ=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIK4FkvUHPiWUfHY7l9lGW1qf+sU2mAIWbjlfSvEIecbg94Mu4KAPxY3E2YLwOs7VyPZtWNZrZAZDMJJJzxM/pLux2o/IctJ5oXGtfPPjTjwNRRJ4U62wpRqBnBGX4="}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/salt","Value":"AAAAAQKDLmmb/XlhfVJ45oKGyYwneS9s3tcQUenB8bTcxuDmAMUWnwG8oNNJFs0mSCF9Yv1KOq3Twxj4qPp05viFnP0z"}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/accessor/da42ddc9a483efd8ddeae4ab38428f73d42ad7f6320705f333555fed8593cbe2","Value":"AAAAAQLCu78fbRRgGWG++5XDCfaO/8NTg7LMAJL7aCsrn6c1WHJ5yrAAmWmSs1euhNd7yKUd0lQ0aknCKdPAZFBlAsqgOdnN8JLFe/H9lISaWdU6lRIfgTH9whEXWT0VK25FcS4r5yVe3Qoxg0DfT8FhjuzOa70="}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/accessor/e83aed0dd0b867f09aa1dbc88b965eafba6030458d6555712e82c479cee3d2d7","Value":"AAAAAQL7t56z9Fr92ztubIfZPPkV3X1Aljnn95Y/tDXOxn8vjbjf21Fhyj3UnLwWyzK/9ip/6+x2DJBXikBOvXoCqKLXGegZ4JN9Z9UMiQ88aE9Z978r13E/rNbhIUa/PhT5NGwCbOl6vtK2hL06BHxKb+4+goM="}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/accessor/e96c348451147331101ad48e157e8056ca1b039ee63a6aafd2d66446c94bcad8","Value":"AAAAAQIcvMn5QMtwELRDXZD9nNf7y/8O6z7u0NUZqyJrBb2OYDRvGpSuPS3CIareSxl8y5F4xtadvhyhunCGBUd289H9foMjfGbVVsM1mbM5i6FDTW0sFOPmXX44mQV29PVNMO+fcLuSWb0+qU4erqylpcvdLW8="}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/role/testrole1","Value":"AAAAAQLyV03lH8m3IYxoZKLf+/suZ+2wwKAyIHqrR3QeJZK+68wslLXy0XZ35bPrdc3jzAFhTizqILlgTBHVccdM/pydtTtbsvGHQlWstLaC79GUTM32gS/jwSrbwfa9j0q/Yrdo2LSa9IM5lw2tmYy+xR9c3ZKcm+VADZMZy3+6UmbQ1t0lniZ4uuVmqu2gl3y0732UtdMSxJepPWMjfvVq5+tynhgvEZNGgZCPc9lsV1fcBVFswtBUeATNnSJPmTnxQflXyhitPOpEM+5L+gnEsSNsyinRjv5cSbIHCP5yDzvpiWtwZ5Q0psVRSh/WJppBHcovwbJsTLK/tZ1wtFl1OgU9NLONEpgDJYiDyU0ACeFJ7r+DhjIDrQkr+WITnfBBwI+65wpOPYboqGgd4qZy84PE2s/VhWS5hjpxgpM="}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/role/testrole2","Value":"AAAAAQIA7g8ifdb9dcRQtIagNGpu2Miv6Dy4jBif1J9OZd26AgFDL6eZTrDr3FfmUQQUs/izDlfI9FDB+UJZO6P2B6vkTchwSg0JdOD8lHjtuoCSDKrIPmzallXHFGwnMnzFY80JzNlzUEfbzciExXthpUjlvBoMlHydZPtAn3pL2NkJdwW1dDRARGB9RoWguqYVgCMkOVdpLFYMVSN1nyHvlt2sm3IdwsXxlE9kH1HGiIEKWYX1U0l8uM0NJTZPFo8Km09u9sz/yzS9B+cyIKXaom7h7S53yRyGP7rFZObl3INMloJyJn7+XxpqiZYAiK31tToZ9k4Y3Eez1ZyCj+oujM6MDwnnzlAkOm3nptIySOk9+iEehr6rG5fpt3WTVSEC3f+1Q+4S"}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/role_id/b2b271423a16ba322c3f87616230f8ced5e89bc8d1a32f0ce91c3d3b5f264a8a","Value":"AAAAAQJhm8OnoLuGdSqb3GhF36ALFfIdoRHQ0SMaC1CAuhlfgzuPcyZFMgHr7IL1UepjItfW"}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/role_id/fb5542bdc4127acea06e585384296c607d18d139be530ac52f850b703b22bcb4","Value":"AAAAAQJMBpriwrK36PPIVHKh4hNEU66EXyp5npyEF3JxUD0BTQW/vQC6hrnDnSF9F59Xh1Ut"}

View File

@ -1 +0,0 @@
{"Key":"auth/ac4e0527-a7b2-1b40-1148-dc0dfaf01990/secret_id/7ec357dbed8f1b49bb2302aff1f08c57c2f03e03b842b7714ed13a5f9fbe970d/941884199542458348fa08c650246e293eb2bf743350861d73b8fc2978ae5c3a","Value":"AAAAAQLESOciqLucvh8+6PvJKIAQV+P4dPm8q8lweJm5KKH5/Ffh7rtp3btSJhUj2ey5SZummV1mF2rABJ7VROSSjOTbb698VpdXPUeK/qDlyAiT3f2vP16dCbsr1K8Pd0XRdRyrw6osnUwuLgNa9L4pBAoprPn5UwflZVAmwNPWMH3B6Ieo5aZrStP3xuDfU+tjvljaEQALwQAqqo0LTBVU2idw96g/TO75VjbcnptiJOeTPqctJKmh/tdaf1F7x2vOyu5IkhBX3PO4Qn+5F4am66q7HQfB773ga8ZSUoSkph7nahF6JtmHKJ+A972iK9NFx/69jOe1ylwwzzlG4aP1bsrYjGgCIk3CNrvUmK7iO0X9AbzOEgz2d27/VbmGh/bb29z8Oc6Tiw2Qo/tiQtNUreamE5q0UN9XTVC/wdUd5ZdG7RftT6Zv3imPIuAwHJ+GTNSI4HCwc5as/HXMA2xrUdYeuj0rdJejYtyEBQ=="}

View File

@ -1 +1 @@
{"Key":"core/audit","Value":"AAAAAQI4CkDWnI49wp9iDaEMhEgTyBBtXOuIcrn7m4qifUOwQ6reTf3BKc5IQXuhxN5h51KVeinMklz3Ld0Qgw=="}
{"Value":"AAAAAQI695zhv1Tv/6m1Fx/L62lITd+ZWCi+xCDHkev2YtCSIDPrZgNzYnrCHG3cUjBePZt6NYUSgzvZTXbxZPN4rK2rPj/BN9xj9v1vH1woOMY6lNPmBR7r"}

View File

@ -1 +1 @@
{"Key":"core/auth","Value":"AAAAAQKy/0yKRpmA5LiZxPlXV+5jBS7lsbsXcACqT/BmXs0nsEP0oHLb4423GWadgYKg1+Vow5qNcLgc6JufLVkEz4dnAcTU1plaCYhRxSGrO/rlAIsKTgwFkKYnV2YRmiSjxKT8hnWw1SHmxappAhZYDMvVVrE9BYGmrCXSmeopjIPLYWgO7UB9/jda7bzMQx9mDVDRUBhRRi4vXUYgo3Dwm1Dznh2yv20ts7O5BVBtpncXB/RovRRhvh2bn/H+RfE0NuZRhQnZ9S6ATF3kGmJX33OiTmBqHBaS8cvPPSZHWmEcXnM8bHEjYxUNZB6+RattgGYVfGtujKWHfwfwJ96VlfIXbQCoZ7bIa1czNa+xhuoOKvaV70crYT4drFnnu4RoV3+HqZl7qsmS8o4MJINoCO6All6GfK7lsRivVzPIZ9M4H6towxfBvEcDvTDHZlL5pOVp7yPP2PSTs0wHM/e9Gg2x9j7nNSDw2KWKTMrxvxHb53dZ3TaaTB388oylLoaNUTG3PlnKAwB4yMp7OpapWH1qX0oo1k3M+XzOX3krHD9UImCTN5DnNZ7jKf8MJ/0aoDi37lNLvQ+0dEXrhsnsRodb2mnCVbp0UhQpPp+Y3yLnB9zBYVAD8Dnt0hOgsxz3WcFOwNX2zeT7OgGnZlTP+NtKKVfXHYjh18JS7mypA7hkh1scBBLqwMyXpzWkKwnBrJYMM1Le1ht2erJvJ4hmLdISidQ8K7ULcS2Gjht+W83ITqC2fO4NIL8QwP9gk6QyIdC8BSHy0mOlZTkT0m5rnVnvl8CV2BbX0lUKTFSmEz6Z0L4nS0/obBRIrWgKgDw3jqnq6vcvmIH4xaOTfRWUeNMQiFnXEsj6tZvRSdpYmAv9jDbdWEBCA2gFkA8wxZ+MSgRIZE8ETUt//5gcvbLncBadS+d7DcqicXUje6jHCQbPg/j9zK38/cKGIszbqVavb89tf0PEQDJB4HOPiPs5kij3T8GtxgFW1DiT23TvtubQF0XsMnv9N3avwTeJoVtBwMTrO1mIam5EHqmvtftnTQycPg9MURmw54fpUevv/Og="}
{"Value":"AAAAAQKHd7fFuNKfj/RnIQoxQEOTorNNl1NfcVtynLwYvtvZGDvhAO34YmOFKJSQVSiT4Js08ik48DWWnZHCZzAyMlK0HqNGYQRzCkuHkzYpH0uLrTcddXLuKyc7j6IiRTl3qYb1pzdlTzDtlwsi4J7s+7orETS146yY/GnGPWM/Tmet7p5qOECRq7m04gBX0pnwZl12iRqWG4aHHY5D4aFp9KjKUBKCIhz2Tb9wcSKV/Aa/ct1d0K0k8pyu1r1OkaJqCQXQeIaJR/WBMECR4omezvg7IGCoBIkMjwFR1urSaB0xNdgk+ByZE0C5zeDfmVRylYlypPAlIBrGL/Q/d6+NWiiOzXdoQoqAa/Pyg7e2gClsKDBFDvSL1QVBdsnBIskDeig2t46Ew5qM00wY58BWlUxqjlCgsNm3nPHtWpc6+XiR4ZkEZ9VeEIQhwC/R+NxS+QCDKeuSfyZM3OqQBwOx22mTL0i86YzlUph0alBmDF1b1FkDbg46MSWTANrkov1LPDnOvvNet7pb0L6exN5Q+HKitmxn36E0KAiqj1hEaHMZF6Pe+IIScLPClgPNeMkZWLeD5kvLv9kfObTYneHVHqj8O9jGtk03T4vOoaUNJY9U0irBGzlV+GkneJUgBL1QBspfK4GvFvUrd0Ds/teayJba8HDxlpCEWr6h062BXsNPg5gUn4H/uvginsFng02M8IyrDA1QOb4XS1zdfrvq"}

View File

@ -1 +1 @@
{"Key":"core/keyring","Value":"AAAAAQKCYFhCtIpVCVfA/MaX9/fCtNJB5z1z+tsi6VQzlDxo9dUxSsZC3ppnZZ9TYwRj6TUeP8QqyNDDhwiXp/i/WhAeoMV9UDKHQq7Ay4BO+AOz3VpHTX1ZYFrF0ZrYELqyFrOkhETpSpNzD6rxcwoJD9NuC+oQhR4TsMEXNzX3AqMKJE+b8iTbEl3tRZRQ5qgjIIy835JDTI3JoSXUxJAxYAbZLxunx2TF6fXs1urpY6GfCrvb/bidzBsfOT37y9Fok8TnOo8a1laqJpsdL6yOQnHj+ZmJVG+Pj5QLETg2L8hBikIMKA=="}
{"Value":"AAAAAQKyaZ3WVPXS+CbQr/JTfSM4yHT5DN21JfJlKh7ALVkue05z4cy703LvXnlfx5ZRqszSbFAe98ZzwELK89SEq26v2GYe2/7tFYeIAp0YvWNe5uahL0N6KUhFArPtC9gMV+9f7ZdjRDS6AKIHmzWRiXVtTsb+j4MnE+RM9NmwmvpDDTRAFgzjxEQ9IT/nGXieacg49U8NhjmZMh9Dt/7db3e5bGRJFDc3IDuF5xgHr5q+NJBbGrU3X1siH0oiCUbHUKsssmbVI0rwf6lkhvFQIIckYRgwL8/70WjrfELZeN+CgBliwQ=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQII71tl2nQI+IFOoGw3z5x+xUwHdaZUXNW2GLNCJaq7tc2Lv3cLz9loi+q9yDVm/tVDhqK8k0D8lA2adOOGXOiaituANawDLAZu8VrwzpX73+mwtoEk"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKKxZ6U5JakeVWOBYonzhPVLF2WNyxMYFqpYnb000GLiTWD0kLJQG5rBFyPadehhAmlQQvy7zDpCf5RCcsZbeCTSIA9yUiGp+G2uBsXAgLYKRocHTw="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJEF2Kc5GCivEaBANB/amJG+W92c2JbCPoQsFfTNcycNMXgy4famQHdKIBQgp+44HNa+OLTfzOoO4gO0c8pk9mvZrLHN4Bb0ot1aC/pmaT7MGn+6ZyrpyHr86oqMc/Dl91bV2bZjsCosUhZAQDhyjXLm2IVgAU51TldHuDvz3+yWvn5rorZiyDAo4bIYhA8QPlCM71heQMVTXWk3/IynsO6gsg25vJpLrJXO2ixDo2gWsVOH1PD0Qu2dPsRyHcdER4HYmCWcPcLS+0kKsspsAEZrqch45OKd0zrWtWrrlf3QLBFhw2N/gWVy4alSNuzYgJHf25k4xotsjO5S2H8qeWJd9qllHKUuci8fa3V8OtE03xlQM2UYkKm4pf++Xjrwc2HZhHXPP8c7Ufo6bJLYmB79GMv0HmsVpBieze/+XqvibVccdoUAw=="}

View File

@ -1 +1 @@
{"Key":"core/master","Value":"AAAAAQK8dxOynwwVLtj8fqeAPBSmo/cbdJBQgQt84CDEuYd3JMLLz3bRiP8G2rQ8mdaP7VVQjJyaWgG5AIFiyjswnYiOWWFIpFn7xPUr5Og1Pd0jTB5mCGEBSdoVLggt21JC4Rp7ceFlO8fNoc1q6h+IZI8ZMn8MPbqpMALNSqKhpOc5xfh6YkgL3XphWnbM5Gzc"}
{"Value":"AAAAAQL1R9YHyyYMvRbw3Q5EU2oYcg77tz5teL6j9/fzZWhU953/pLdeNSLvTThDX9S9/1PX7awbCihQgV3X+buJVpaSZi4Zpo6T/emsgS3U/Hp8Ml+B8xLhbNeTZ7Swi0rL1X//qYEp8BA7znHHbaL5CWbiaTdP1oZAnfS72FvhjZ4kdQge0Vtyoxrmyy+6K18S"}

View File

@ -1 +1 @@
{"Key":"core/mounts","Value":"AAAAAQKEEYCeXSTFocHW81rN1uI6MofozgPy2HnyOaonbuLKzaYM90H7UWfCymZ8sJ/3buSfv8/HNGkrjMHXnwyNbwTZrMt1+3LzSySfrNuq8naoLCbZK0Pn3vJElDnJAej44SBoKrmC04RAj7ROjxB5Eiqe4VJmj2KzjX8pnwKo2cFvetgNiW1a1W9zqqDZX4HRxTCfiS4RwLdkWrUjYvwjX4tQB+GYuixUEWWCsUXSAoIhHx/H7AkmJaJVyrHILjHAcSD8fgxCHwFwf7xaMgQhWqj+ofBYwilgtXkPc/vcmT1pZqw8RgHrfMKTl1gGmuXiiL9/tkWeMs4u9H9+nhLFYy6V2EDFDKPc+zvHg/c4lRUvN0AnX1A050ZJKucYDLq8IxRuBQL4ZZ0syyIVxoA2iJYgIy8dZXHg232LQg5Gicc+sqHKMAJxknkEwl2QBPhcAyGobent4UaAx9b+7LGXhg=="}
{"Value":"AAAAAQIOTEuNxtf2ZfGu6k9+65GFonDBiaetJnyLYFk1qfWPrE/VqUunbxuTv/QyK4pgC/q14sqypdxPe4Ygp/5mxzzuY6JXB0VKiDMXe9R5BltTG7++rLmKH/j+G7nEh71LER1/qVktU6x8dmDmTbpTgl5xzAB5DIXLMMKjjWda/7qJ3ivNI0pEOQ3JyT27SkqjqM49Dp1JIgKnjIEVQORqKcsSP+aqIncMjIo2iGXOGlDYAesp5tZ4hln3VCwXaIlrU8z6Mmntgcg7NeK/O2WTl86K644dbJUh6frGFDujrjOh/Pgp9n9u0BI3E9K9GD1Z1S1wEb1MCqzT/e9oHG7I7D8ku8PH11wGWGH6BmYlESYUG/KRVqu0XOQEfroLHZQiLE00yHBdStW/UJ9y5pmGpu1aiQ88Q8fpjF5xmRey99b4c6KUIpHjw5Af0XA9ZKsEJUyjS/dbMKPM6PBOW21LYefXH5b0poXMWgLW6LJV0zLuVMyVZJqANbzCVtheDPSsEjkHHwR/CLa2zs2Z6wJF3j1GDZxUFf4nbnuXQzz3M3kVPPtS6htlb0d8RN0/dkOrqUue+c4UjnXhiacXyVUnQQzUVu0sGak4vrQi0020aBzMXM2ZG7rNgvw+wcYFS4txO90kwJL6aOMXT2BeJiQ3wjjHb7M74/sSd0ffRTUlJSODSDotO7Q7Dfcnc1FLrIhXPRFPavTjFoL5HRy77xuGG7U7jTMoGra+rK54v0sxqKbS5WZi1hADQmAVIO8bPb+jA1qoejRFygW6sLgAdmEFQQJOhCV/BoKP3A=="}

View File

@ -1 +1 @@
{"Key":"core/seal-config","Value":"eyJzZWNyZXRfc2hhcmVzIjoxLCJwZ3Bfa2V5cyI6bnVsbCwic2VjcmV0X3RocmVzaG9sZCI6MSwibm9uY2UiOiIiLCJiYWNrdXAiOmZhbHNlfQ=="}
{"Value":"eyJ0eXBlIjoic2hhbWlyIiwic2VjcmV0X3NoYXJlcyI6Mywic2VjcmV0X3RocmVzaG9sZCI6MiwicGdwX2tleXMiOm51bGwsIm5vbmNlIjoiIiwiYmFja3VwIjpmYWxzZSwic3RvcmVkX3NoYXJlcyI6MH0="}

View File

@ -1 +1 @@
{"Key":"core/cluster/local/info","Value":"AAAAAQLM3HpjYNukfnGPRBV4yhHkaDqTMag0rk3fDmRcUt5pzDH0yh/2ZRuF7czOYsfV6146nxmUfekMrH457GtCMPIppE4x0WkikQRxiA5fSw9lYT8yeErVL1o7ETNo3AHPib2ldxBdX8ik3jY="}
{"Value":"AAAAAQIQFA5RAIuPqfLne1VrEimWHZjhECkvEmMrJSb2YFxcBI8LCNI7o12Aa918NyEsAMrDhr8nsHF5MEP29+Oh2scwAtKItlx71GqFK6F6wxcdq6PghZCNz0pHcQWsDzaW7TIEt6hZzJlTR48="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQLxxJkuGSq98jK0aFDxmo4puYFVAJVs+yVg1Si4xkJJmEj7WqdxiICrje+8wtQGA8rebHmTGfemFLSmCH3Pmu9jaE8ChBAHQjdMJuAsfebYGNcxSMpaX96FLT5JGwRLv3eC3JI1YcmbQrvX1Hn49JVYCNxIE1bUDYBXfJ3cg0JJX4oH4w2F+XpJbiZYKoJOZz2Lbun2G0jh6c8fa05wPOb+MNX2oYWKkXEVHUxXb5fWbc65aKlJxXSRaKQv9R1vmxdqmXDx824HxtgTHVRGjgs79xj2Cj5wM3H1Wf6M6O5GexUF6GoIp0nYyFLBiE4/dL2vixfrOK3Bh46bBFzbgCuBbqX0SY1UytwOGD2ljrtvuajlIW23dac+r4Ia8logj0u9Ej4wSsYVWyl5BizkYeYZxva9PA0TuK/RB2yJy+CpKdPMMP5mdLlVOPAyWGo3XUgXWRTsln6USUY7KXzujcZn9Vuiuhdu3m20Gl9Qi06MpPLTWd2TLCC2rXnbPkzyGlurWoNYfZjtErT6tjAVP4DZ1D5zkNuNwz6QKgocInHYZWESRiFIeZ53M7fjV8e4cjOkfze/GNe6z0q+sdZQrzhJ/GzdwyCVAPQmm8OsVDM2W0Pawrf7m+tnErvggLGWKMa/tNiyw/qWnWNm+P6LRquTSHxfENbAE0CZ3G/ni9kElD+9Gepe8DGokinXxW+EtTGxwA=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJ50rfAVWvu+ROEQngQ7wUe6SUmopSYa/pSn427pwZJo2AbcyahEKC2n2L95nWRFJbwO2dWRWcdeEBHvx6i1QwVLiKc2tI91GuBnBvy4MNYOshh0B4qeDI91rszdvQ8QRRwrNJfGl3Oh1cuaXMQ7O34qqvzr3ZXCS4nejuBXW0i0YOX0Pf5OpCG8/+HGeLvjhTRpMewT/JYKezhUSYm5f+k4h7sqz37EfPgzFvTEFWXhyxW3LFSwGRQzsggaCulhW51pt5ULTibzisqfVlVilyhxP2aXVbrff2gopLY4/3ug5z2C9U7na2e1ZIyWYaRRgXmNbSBRXl5UMa7iA6rnN3b+HK9oE27tr+BeEfW9tx1s4yQEzAdsUdpkuUlWTFpt1hjOc3v7XbW0vzJLwi36Sv1z7Ln305TStrdVN3Vu5pI4lHf/1ExIpBONjtbHQ+M11hUMCVCqodwD777dZaH"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIaY1WSVhEL7+pmqMEXJUjMjS5DuQgw5erNjrNV0w1/JV/e2ICx/AFEL+C8Bg=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQItpkJ71VVPSorqDC8Lpr4AcWx6vdbkLF0VaC8mRyLlOUi9eq/5eN/fiy9b3k3AcGXkqnPQJy6H0vNSGMGtV9sJiiBUGCtNT725tShAFsJAaSkxq6AYrAxjhb+CL2/x85MERnbZaz/IS3LjuE/eaNxP2b7Dgybbzxy0hrLgj/xaeuvaNJhxMiylQQ+9UE+nbXH5nWROkI2xEPPaDWeaRW/HSb/SANxa3gqlHinusj2o9bF01mLEc0taEktq3FFefkRog/uM4Em5qwBeuf2O9YjqPz+OcbBVhAdPb360wGrgyZzfElo5qUCbD1vGeYBIlR4WeM3NrOHvmECazANZrQK2jaOImbt0MsqBd7wKqZvTGLwbbrGv8DtVJ1pH8qgfkKmyfMub2+7llHybUYKzDvdlq6YyKCYe7ZyosaePRGNNuOxBYYPaS1ikaRedXG9pBxeR5Acn0SOSQogfAAkTmNZEENznVvqsKAJSasfCAm3IHV0EvaUVIUuOs6jN1WwRcPJyaJmYoojIITNg/Seuzv8lL0Q7M/SNbiiSaN2BYs8Y84GBPoWx3GTDyyQat42F5WlKjW7vHG0GH/bqQGFgUzQdnPN03AZg063u52LES8o4r1Rj+je7US0G9w8uOBdcX9o="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQK49lwqHwzXSd580lHYTZUip9BUMkyXzvFWk0iEjNWBPZrI+jdgh/eZNen/QyaLJwXgggaepT/8cvCLOaDH4Sju/jvhevHM446hRY7S2eFelGpb6JvGwzMClbDHarUaMSBZzMKnrBK2f30q+/uILQJde/tUVkFy0iK6v+G6ZbtzvgiRVdl6xrTBmkx7Bb/lV91nxdKdYCLYWyd48rgO/hZEUoVRPoLzxPadfIC/jZIhOhmRiT6En7dTRGR0GRc1OQoQVlEolGnEygoFVov5WewqyGBHsTIMcj5FLUYlzyCpSChBdkSU/XThWJ5A5G0ykNyL6+I/RGnER+OJscr7OYWWW0hE9pOYfGvlRU4yBAUXFl70RsaL7kE0xkuqyqJOsbwz3PybrB8sXt3MV+lV3lof1Nuf5Gmy2PSzxQiNwy7biHNO5yQevReDmzG90GS6WP8XBlyHG8JUJJBhd5uJpNylDf2Od+oBLW6vpt1OphTwS7yzN9ToPqDlcattbXnFHggMiC+UGALJbvj/YtMtpkVExRmZXMLLPQYu+aFATsHbO6nw2JeGtMVm3f1qYRptytfDvKwx/Lsa8WvBM4ldhXLIeoehXIZbVoujEp1ppASZORXNKGnbIl+jsMrfjMnDlX7EOo+3swnpJUox3udQqbPQyuAWEOYkqv3ZJFWt6EwgLiAMSFk1tsYgOuduTn14smfwkGT2aUIXQht9QE5bgW16owJKd7AKFY7Pp2lBHHTj1INixTuQS1zfvbDtrF5RCdlqHzLy+7+79J3smxsdY13hM7rj99l9F2gvjZPb18JnrNLUR/f8HXYurWRTlRC7KqPzNDZs2bCrLa8fWREPWTIBG/w9L3J8nLQSG6vYxwOe5SPuSj77wlJIDkk4Kdm7yvXpC1EjAXgGuEhr5St96ZXAQNJK+T/3ktkapvA9Ar36w8s5WLPr0+tHOBr/BQvkdjiDrlieA9JyVT0+d97oHr0mSiwS4Aa9VCTwqIS2g5pzZXK+/29XD03DYqoXIcBk/w=="}

View File

@ -1 +0,0 @@
{"Key":"logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/complex","Value":"AAAAAQJGyPQ1TFtwJLO5tbYDvnXDxbK0GVxef0qXs4h2ddHTdWFvk+WJWsTw2l+Igr5v5KY5HOQz/apI6Vo2LmwY"}

View File

@ -1 +0,0 @@
{"Key":"logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/foo","Value":"AAAAAQKEvkR4E7cn/rKtmyhFT75qQ/hMRUwoKNmlfFar6/sxK3icAAYGWMVq8brp"}

View File

@ -1 +0,0 @@
{"Key":"logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/json","Value":"AAAAAQIow6Rc/bPZhf5PDQ3jK/diX99iQZM01NA62tkT0BaKE4UfmSYuYDVUCIrWUOKsVyvD48phL3hEHfgNrJzVsVIk296Br/y7/es9z5zOxe9VATSSJy3CI54AtA=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJFvWn7c1UvQSL6jOqglFQ6NE80ecj+WJSkOCc+hQjZ2EsuYw7U+wrInDL5mq0QLHgsLODRPhyJQ2LyHoiI"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQLT/TTr5tURW8v4ZttyGPjdBDVRUS6Rc0NAII3Oo8LyCCmlDD+MbWJt0wFJ"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQJlKloo1Bvrrmtpue0suXcxOKdP8fCUySezcOv0Yp+RlyOZqespH/998BAKKKLqvHOHHLpIY3mB8jJMAuybHZY4qphKC9aT0k3W+VnYoUpOoVBgV+75TSNi6g=="}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKQKKs2Eidd4urvnqrb/uiYFqXCt53vG6O3BQQEqdok8YI0k7jYTBtxBRqkLlZpGblaGdNTu/idDMe3qRXPwQ0vwyoohZRIldoCpX/wYtpWaV7kpcd/Xl5P7bLuWbrjbqJY3QkaVDV8yaODUxDqp0Wh4alJzxWHp/RneE0CzmXm1rST5rNdvGKj9nQt4fEtRNp+6S78PRIMMim9Fzu2NQGR4tLhukjvK/ab3Us41PJ4mtEaQN/o5CvNzafv3LLQ2QXoitxK3COz63gnrOxQCrYF3ZTlaGAFu+rz/fWprOQdXIkh3+/3AMM4XcPWi6iwa7ChyXRnvhZZw9lCJeFTQI0EE6S09ZniJiSKuqbcmGHdlQDizcQqE1CtdjQ9bpWL4Jda0NsagJvRV6xyFBU5ZDdQAiNViK0BdgCM9HTr2elz5bU+Auit+e+CMnN/owSEuulXU38v3sx3xuOIG50R7+HtNrVzYPvLmISuKwgBVcRC53AhLyN7PqMnGC6UtaveWIlu7d4i/QCiYar5aErD73tSsCQirC8rXuKrIk8b220EvIIz22O9Ime3Wx8Rgpl5tbXnmbsK0wDnDokLaJcpntcBiaB9ACaIwAP7MumHTMMzHZ2oSz6urkpl4KKNmg+HG9dsTd4796dL7aiV5He834+40WW7Tb6v2C0ZxUy0FNylpu+q046wmcovByaeV4EALvN5+ZlwvsbyIhMMIIpoil5gLYb3xT6x1HhE7cXeFprEB+FN17W4wWBa2tL3AiBw47jx7lqv7IxkABiC60SHZ3xWuG+5r7oBntbtxh/oVqicq989AeEKGDJifEzxbHrp3U27wvp10MaG2ZyWiGPr6Qh8ZW4Lqr6pCnTEk9imf3d/o8i9TtucTS6NZKG/hD3Clta5mfoVPSjx+dVnTyekFQyU7TvzStp/L5u4W6YPbLNHkRSLc+4LfH4sg6/mK+Iap/pzuuALvK1MWZHORBym9fRDj8e8HnrKeq+6yjRei9oNcEIjRAQSD+B1YFhEGqt4VbOO5YQ8kdj1iIVpd/fqI3xkscU4QLUfe5mCDLlOKgyvI5mwrCToNvhAk7qSjNgfLAAcqpcj0W3Lzibd59SnN/X0vWGMOuqtw1ccMHFz/1Z9ddKM4v9ABztLaQHSY5BsjLzsyWEI160aRhNk6XHoG9oIzJY4HlukgD3f35N7B44talUxDO4HQZMR7xmi8O1cr8dw6uSgMgIlUraHHXLpYpcfcshl4g+d52kQqot7vw7CNU9jJcUTusdGsDTxWCtYt+lyNvkcYvM="}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/299de173bcf8d6ff55f53e9e947006d8c2c88878","Value":"AAAAAQLaQfkPOOnH3B/DFOXThAGuJNNK5uLCkHM0DOI59wkVISOOKtZJ3tK88S9H2Ce1mQbTr4jJaouYB2L5CWhqju1DZxwk7ji0rTnHZHEIGgCr3fbJFD3rjgcearrJGkvnfpKnyLaV+QZLN59fPga/8KJktvZ+frAG0IOmquVN9G1gGnUcEzbWu7vr49hZWeVAK1lVYVtUDpd44OCBa1A5qHf0in+hvP2egFXqyb0nWBElKUS0CEMjiZrrmKxr0nOU/quMAROPyNEArioJGTE0OYIEcJ+J3oMqSfWokCKuRBQ1vMC8oSMfTva0nnxNVQTAKq997SjCH/XooKxehdQjisndlRH/YaRsWpk+iRfFNmiSpYarQNb7vlDOlm9YLqqE/paQAFe7NQHY1RbOMzT6WJZy2lZ2L2PiR67udhJDHQMMmulqaYuquaT6CDDJzdf9XdJcPPjyceCFCbRnJ7PgvpliKd7saai/EDGSEqK9Cb5YNoPh6ISMsRnZcYGGtpbmHCODVfhYqpT5Fh3X6h1gIs/1dgFD6+n0+eq9V8fjLXMIUEEJ+7Q3+igR78bNaJ6hxJnLoxJL+du2cVVTB76o6iwoiuG6XqipSI/bm8QbxYxhLSmynLBWJopPlgI+hXrLIgOLn66CGurCyIulYbn8hFF1k+XDbZ0siFXHl9iibLRjXHb02d+Fe1mRbODilJKYMBfTkpIdC35kfZiBkMSZNzAoxaemrbYGNV74JFniJ6ElGyUAbXN7ODxZ0zU5Vv9zOwp/LDLDva2vhoxNm7YGlVhSIOcKOgUhm1cfUw+bMCfbtYWxVSNt2R2cfbFGjsKTvba/TCrecTywgo9MC/Pwd2ZnrzDz"}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/2e9403fa105622cab037830348fb1dc2c309ac58","Value":"AAAAAQKShT84HucEAfQKWdl99gAflfpJ6L4OUDIpHL8eTaY8aVBBc9Uyp6Ee9kU5Ej9yJ1TEeJh3fhDQrrAs16tXsgM6R9VbEduvuDqSOleNt4254Zo5WVycQw4qRtbE/JStN0nuGP2zmjPMHwfrOrweEfIHiXwP2fLejGFLq9+AbTqgb/InhRBMSqd9rzSzHpl3RAqqTiwjkArh7Hw57PCCSgOZSOYAeBTqxKiTbwcX7sYjs0AsDR3FnYfb55Ok+aryU2i3j27yX+DGqz7ClAyiX53Q2DHoYdaypcQ08rskCE7Z3tS3X27fMNdYTUzWGyJRCKp5qfYf6RsfOUvtBRj28B4bBIYj1gnRPkThuZq5E5TYESSFQ0j/YauXZFzO/MZifnaHfP7VerBKOZQ2Db6Srz8Vz7LfefWCj9L2sDCbtmMSaH/+FNIxQthbK++/rzrX5K2BlkMn7jwYIe6251Ke8eFdOyPwbXhfui2xiiH8mcZvHs8lHAufgUZKk9okT4QqLkEusz7LmfergjIURIwqz8uBfEi/3SSA783hCnuHeRu7WTylbMUoyS5zge8bhwZ5YpP2Byp5Szbf24uvve3CCt7n4/7stW3PHNXuJk6+x1GU4jnz2RIeBatlsDoJtxUkIZGcDOzocgCc5PtEPFl0a4sh+pfG0WfkcWr9/39+A+rqeTj6KpXDtE3T9B48IvPH0UzhcNXFeQE4RBSIZcPrIex+bxuL3zBnkJiURlDsgXqb9wWRHhd5BtEVTF8qzcWLZYZ0TNs8VR8vux0Onegt1s0BcMkyxtjWHV+KJXgmuk6UDyrBehzXoJX4tsTKBPeU/KdZn87KGkLn5hR66Oojk5LRLvbM"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQLP9f0ZgFQob8qn5P0Ti8erdTopALtAOVX3vY/V46TV1wsqG7dE5aPqnJ7Uf5cCrxXFB6tm130/zrWNOJ5HIpivDg6tMTKYfUW8hLx4CS4WJiSOEkXt4XcvBwJ1M4HkC8DWsppR6pZV9kFLRngVQJtRJlUKP8cBTaVYuhbVH/Ar5e3jtdCqtT/OCAgrGoHselzx88qFRQQIDeOoUWg+p64uaaAMQFFBVvrbT0fVeRYmf/qwp1+nFD/3nnK58OZRnL3nfBUgAf5MZ+APg7bkx2mWWq8gaDHM5zugzNLp7E9sOhXPf0Qb+0MfEP29sBFyV8kl9tKV+epaU/SEQqeOET2F5TpSLt/5l5Y6Yh10KcenY4u4HozLJ25XIC54qh7xeR56Rq1uvvOF3QmfnHdi3cTmISPC9eAHQxWpbz2L3T1FIm7FQ+N2DpHZhO/p0drrCw9Izhdvs91RztTeDkSy+cRzEPNwlInN6PS+6B8tx0NGMY6Qg4em7LExx4AQpaGHK5Fn2ogiCwFkBdvdMq6Xx+JFM7dyrQYXVhyHUHnq8Z78zliR0WF1YKGdqJAGT4wQA5z9fKMlZ/YrxpimJGUlTLxSPJNHD19v4oO1Z3mOIechQkrISGmNdKHC6BVGqPR1ZwQTcjEa//1/Zsmyw77/22ii6I2vaQVDlM5p275oN8tzdZGjNI7qBDzlQ1zos4FFisjx/Nv3nciMxxC0iWiGJea4Asn/ceqd9jLTduaOd+MvGBfVTtrteqWQ5R6ng3PL+b8cD+GVP6O/XdPfLpU6cFVI19Frf4vqyxNLUbHu1AWNClsdntSzlqz4lwsc89rxflE7/GkFZ5Fda7ipfkNhFJQBW6ymnrTZ6rignmRHEMY0utn6rnrxYw0nDTJyQYT4udliAHJlrhkHSep4WE+1FqwLDOn0cglbL4WYcDY79EFxJ2EMVhlPj/GRkSwYYu78NYudQrBQWs7RYFOnTWbPD4dZWNrjZv9urF5SdnnJvpmVMIh+WcTep0Exq4BQAetmm6ZlcAT1KmwXYVJ9hlLt58U+6dOv/23nU/rAM6rRzy+4IjJCu57763oIIeuwPYq/m0LebmlLx5sMqSs2RBxDfCOwN4p51cRphLuNNuqHN8aPWRndWwEK2Ov5C0WHS0iLUaBMQN34x1JM0smTX9dIJPIouQOc+S3claKn2MUw9r9BJbkAvPjVBqThptdRPpBFt1da+vDAzTw0HBcLcujSSERW2VXyDZdiDjZ4ygOq09b3HMx0R0Q79j3ohw7Ty5U8HTR1w4Ol6wU="}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/87656f27093d2d77837196faca0e4698c52bbd72","Value":"AAAAAQKiDmFCGjfaOmh1VNoL99Rqf2L5ZG2zI9CweA6G3Ytd/hHDGB9m5wYOIeBvh2oaZmqdGT3/LSpvAcqJ20NQGhF0rQBa+hxI95lQZ0HFI9b0pJgVZtiJfZAcci5PCb/V4mDytXfwH9/+y4rtmFRTqKww1OatW4cKNIEqQDQTiWzRlstDS+wRaiZyDU0yQmhVNzjjqagGeV+02JwIgnHm1bS6YgNrmLKvjEMYwYAFIf0dFEgf1CD0xr8V/lHaD6/EmxijncqqccQC97CU3RlQAho974zwUNITfRrM9ko1lsm4yUpI6d9/SrZGbpBkK76fW1IwqhU4elMYq07jXPseuE5LXH9hoZu5taaWhUGkwIJgpkBa+aZI3fHdBt7NQBC7YAOShixctpnzEdkXV510q+y41g//LupQkY98bDz5e8seIu59mwuH4TFl6UmcVUNtOiAxIE3/ACd60ycY2diksY0k7FZMO/e0LasO6uNi8ZsrmlYPOhoyVljW5ppsJVPemFW0IXcVrHRht81c2xHhmaTydQFVeuJL9snp1DM7sbDMcTHov7uYQP/ocdXDSTo5+DT7KeHmHH5jjDttX5iAGL8afh2vxmnipNR2uvFF6Rfl/q3Lam0MYRIBe8YdKfTuY4q3lJ4xzljYJlDySWat/mcAKLb+hbGnHXUFStYW4Cucz5BBGYn8dUY7kVV+z75RoJH/Oxv+GoOrXBimIA8nfR0hA9N5iGAubKJxw81RZRRbBKrnkuQ6dLWy+CLeoEEj7JmiJI+rdzET21bQpS+NVsIFJsXsqcEq6Lpqd0PL7auYf1OdvYNPXv4KTq8/yTiqzKhSVE/0YodNGiBmmtD6ChKKZmKv"}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/907c609e9d43718c2d983e1b6fbead2d73f9b77b","Value":"AAAAAQIVNhCvqI99YcDltmevVyBRkRw/W5EtkaJNll99ejxuGdyjhMLxytd+QoyTbEFwo09FTmdxfAI8z9qS1FJO7uuDxVyxDMlZYhQ1BVJh/HUP0jNdbvo3ko6NQ/DjYAJ+Z4JAJr/ap3YQg0p/wq1hhJy7m3Ea8slnOAf+RscQtgjW4ucLV20wCMcSEnASvVzbi1OjMMQvS9lyduIuI6R1HnMSBQDLizZVSG0karp7jhWAbLiHmAiE7FWofIKUR3NbTUOMODQsHS4xsN+wDlKsfiY4vM5eKFby1UFymWganzL1W6SUrEMPBc3O5ZI2BE1Z4zYJJl4Sr8deZYMQorb7qCzCI9M6U0B0PsqBGn0eU49hr+1GUCi4gBHZOF6QNxkwWMPMxOML9MX3jWTiD7r97bGQjQQJ1mEZ0UcwlkVJZ3piYaiUnsVkBaKwYCDylolX9k1EgMVeOi8YQvMunW+oNxcdxbNCRx5bXZmRfHWA+/1w0Klk+R/eWODtI86Azv6CscHWw7mjR7kobH8+hNq2X379DgmyFVWLSt+Gyc4G6sKinps19cOEvZP+XmXXPdnysfI/DYg4g98aMKVMlt9HUhoCAnWs+WT2LdG8fQK8G1mE3w2PD665ZQVikpNJCK9nfOOMjwVZGFe9/jWtjfxqJfimK9WjeAJJ5IBcreSrEdGXo+lKgGjcGiTZ6OD11+dvPShntufxCRt5t1XrZN8swAN5695hYa19NPesJRfKf7FFstOxMi1VNdZvdVmZiw8pOpHJWhp68JRXlloDySQ1echJVh3SFMAf7v4zy+Sw2EoHuEV982w6xA5hyNECa2NRT+HvNfaOWSU/HNaaC3rkr86mFQUa"}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/a5ecc2e5630b7e232b9c8744a0be6441ffb43229","Value":"AAAAAQIENn0L1HL6To2REZnua3OsYnV9HdBkhN478rYY/FRhVGcfmyrRA+iy2FwQXbHoEMgaza6cwr4QPM6EiMNZdDubPMO+NHhBi8NgWTR+bwk7nIs5rNab4fdth9ROsjz9W1asbGORJD4l9rcbZ7B0lqh8A8X01YildprPnuDCtOu8wsrSCfE7eJwNaB+qYWNkEYgzEVWuwMqBZ3vfjUXOK9vyQTd933e3OlrIFBZukJ9QXlTyuma5fq+RcCcvQ359IgFB1wMNSMO2yeEK2yInd1ZZyM/+d4px0PlEh+B95D/gH4akJQ1BvGErvKf87F8J2ROdWxA76zHUXkr6BuZdW6p8Y67UuhHUOVM7DZks2VRB3xHzZjszuHeOCvfhM6mXSU01SP95wUE7cSonYM6wGXAFA+CWhpMRs4py4404JHMUo2tUaLiZLrspW6ZuGHBv/szJ94gdQQF998BsnhtqBzWBRrISrdErcUVtKeTj01PxOKbZgzeuvNMfRwzlbwN9APmI+ub8gSWTjs78w7eMnB78Xpabu6+2WMBELWTg+TmoEqayvpoPbl/AYNB9pJc0sGqm9fnNxVp2mLXQYKomaxOpG9lIv5lb7QzcZgqSpzaZ4Wcg568BXrd30pHUtEujA/za9f0/ywEdtw9eON8tj92IGgcrvkcSQ4+3zbHu3hWDUid2kiuSPxA36hrf7F6xuLQQWtO9e5knQ9sfPwAh8blMBdihjqLw3Mi/jwRLtxD6fySMn+qOFUwUvTfFTdJLgYfqgGej2CS8+x3zrs3fewaL06CqA89QsNfPsAH24ZcSZ0GAOOlgpp1P538cu50OAgdJlw++C0k8i4B4HlgVigtz5xGC"}

View File

@ -1 +0,0 @@
{"Key":"sys/expire/id/auth/userpass/login/validUser/dadddf1d8c65ecfb20c4361929d1e7f6b72e39ae","Value":"AAAAAQLS9Dgic+3ywWAIR7I3J+9PmdEt81fce3eOTNpcT/TRNDkzD5NY3WEQjBLM7UzxGMg7M88IeGi6L7Rd+ZmoKjL0zogptwvKYggG4P0z+fCQW+/WgpIYEB1187wsF7wh7GQtXTXKE9F/dtKFvfi+3KsZ/0//tXcs9fUqPuJFJSUelcMaIeb2emle4p+kjs0pDuSNzovIGvRToLW4f5TbqVy0ve0zo8r/7IwKlrxo7E2uY0xzJX6IjygIACFm7GjRZgy2rkl0v9Be0T31k/zDWsEPINXu2a+vsYqjZTkRWevrK2ZE8IQBlJcFER5bcnsZiA89wm0VTcwBbYlWJ32IM9AJw/75DGMQ1wbdyJ8PUWvdhyl9i9HahtHWKCo9oH8qTiBjbmkrCECCaUeV1TgpqcqyglxBkgn6Qlb5kgNEHeXxCPy8GarT2gHlmPNaWunnxqE71WuVLZ4+PBlCjmksyXQtdqmDIRE1oSHeuohBQ2dA0B/rDmhLwXBssA+/eQDONLm639VrLJR4IRaNo04PEdxz8pec8W5fG5+Ea3Z171nl3FseZO78i3Wj7Y2KvYFA1XWNlrucxWg0jRI1hDlUHXqLh7nqctdudkI8NrkwbAE6W6a9imMUnTd3yIHN05ke9ihlJrVvAaBbgav4ssz3tnYC/s3TmozGic2TdXGxi9ewMKhdfntXi1VQEJ52i2QmWsnDAUoISHFaK+azNFt7sD5tCKmSIdpS4IL9g6RMH/sVAzuB0ZT+83jYY+jP9L4SajQs4ncWkrMQmJ0fxGs62x6lBxk1LtI2qzV1J57+1QZxFoQc6OQINec3VoQ1t7aFpqYYDk9GKEA/hk8vM5vhwc058RPpjYM8l+3PCPOilMh+FgqOs++8HBTarMTp"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQK26ilWp1mHFV/SL6xhGfl83BnJPBRlrgG1IwOC0/j9SiS9i+vMxv61wZ5amlKYUwrVFfwxerOIfWmrMrFKcL7aP5qPgT1XzJr1GlNA8Z5+k4cX/lUhLmt2Mmhe8lFbyhhx1ys9aiUZaXN9YPTDHWvkoY5giUTtfpYAD84g08gIIWr15bbK5aN9QrZkmnFxhY2WxG/gaMDQh4tA7Ic9wOXnEz7mJjtCIdTK6DbQvt+Z1juRrpkDRrRviNdJKIQ0pynuKDaHWZTydGffSfuHrgMMi0+xeHD2asnw65useHb0fOuXFlu2fTtqYR3tHRLH5h1rLv3Z"}

View File

@ -1 +1 @@
{"Key":"sys/policy/default","Value":"AAAAAQLsSCMLrL6OyG1Sqtmatk8G6JI634tmLqR+kai/22iklR6iAGI0xel8Sgo6MuOZPYFqM36J7dlcTduFb1KvNDlYVh77jv1zeqHm1Bv5Jq8S4Ndj1dWm+xTL/Eet9Ay9jccnP2h71V7pP9Fdnjsz9+Dm7mR+9+FRq5YPI/IeFUq8xy8fKsaMprUEBJaTOj0h9PFOxtxUnzAwrdSHixETrRJ5gFvndw0FLoh3kzK7/6RJIzcTQBu5msDKFOhOcp7X5s38JzwICzpnHBDaWFFsAgV6wVysV/GjsTx+E6MtTQsrLMTwd9wKc3kAuP9UwmVaLuhr3D/KEL/ZMTtGR57+tevdpOTxRxvS4ZavR9CJjNingqZKGlkkB3EMtb+3GAbD2ivDKDCmkqpLoekZpYbIkvJ6dW2fugAhWaxzIDrcr2EmGHTXnAJNDr4Kz/G+ghq97U2LBa15JjeyV5mc2li280PeUUZp8g/Qyv/c1CT/0OVn/F3nvlWNVc37kKkrefMX507BCMSYAVULl+NmIWaj+pcOSGpT1CV4O4l4IchzKez5lzJ7fTba74pysGxg19oB4A=="}
{"Value":"AAAAAQLcHIro6JHRSE0zFR5/4+wr8aDsV9k41FOFfETGPZIiOV5O11dJHMN4ZhZ4jvAPGuiF5kFZUMyPAa94eZZ4dzeis9+3FTJOKKoro1+yz/VbPchdwhFZXOzwCGo1X+lncZP/vnSocpZxjEuhjs3cQQ/dxHOX00Lo50PCwaPRWG/9nwv7NhzW4sUj0+cX0Q2b3hBcEIjhHstBAmj9cVDwhDpe28vmEnKrSRyHovWzNniK7y7KgXXmbxYhxTq/e0brKLb9zXdBKiTtrVhkuIyQPaZNJ3AZWiXPe6eKatb3c92VxfRM5YyQB/Ip1z5W73IlgHHwG+cOBmoZLIJ8Wj1duXfRsav1ixyXx2856Q+biymoRx0bUuykWlUludJXljZRdAh2+N9CDqR5/kkfl0hPVssYuoPrEFxrLDEsdBgL22BvPuXahCj1fjf7Z7pHK2pUnD6NleS5pbaRAm+P2S1zGUAoLIHg0lTRxyffvLsQCve3nUz6MejsZvLAuC6vHXoOO9SUOx3ZNP96oBlCyUb+joS/K6f/ehDke0gxvDN2HKlLJFyGyQptKSRj+lLb8w7zlyrwJRnlblz88OQkLYDLpPJmpxSwTZWF8Mi9OrjyBhPY1S67Li6dqWjLEOKL/QXJaswTv56tXueAEw8bYeibBgYvTKBBghxR7ZEt4rrCTfv+CU2DL6BJ8jKjHAI//yuE+wiW7+v1F3PjL6/3UH4vpfpe5ViqHfZi4Mw/T+gcizc/OfxNgUe75F77jfyI0hUfPuRMMJZ1vfwFmKFloCwnXbnNwo8a7XD9Nz11YzePXg2wgqK2aylDgPj3SgxOWryEoCUc1CyWZH2X6uoNiMnY08s/DQNsItBxbwEmjzq6Rsekg8cIJSMa1Be6ewTewJ1IgJYpctfNiUmxbHkAOVhDWSQYxuTeppB97PSg/LpSRZIiPLXW/cWut4K3LZjOW4+njD55b1HAQhOB1/HkWpsQsOdK6igM0icJNUbcGQi5N7w5fDOVvZ3jLfxuIjr+W3s551m5u+7yleN28EVQbaLFnFqQDKMveHBqiXP4mT2xbzh2+APVoP0COPLt946JuSY33rinX8Yh6DXpmDMnE6YIPDfZuQN0DOu/CrwK3uvIXRD89Z9+IRvccNrEl/TOwnjU1RFPsKsTEvlg92MgWSTxkvdcR2WAJb+GLP0UuUrBxBHk3WvTwsKb5IKJKS7mBfsxCBfLgTLW+98MwwdduVKy13lCrxEhqaMU8ig2jJhk9EuJTbDcsdLMAP2/RmPLoZt066cySjWGv+HDd9voaJjFro4pDhMvX3zxKSSr6H8dqJMUs0ryVqVTgLLTsTedYeSHXKVwYIODcsO87kpROHm9IpTvDmRPQpREICPwt7I+1tXFmcNbqNz4Yapk+9+RAYPC/QRImOabH8Ep4lACc4frd19D6Wx5k3iP+JRwsJ2YpfVHQy8QU2KzUynNa+eAEXwKuc2wlzTN3jFOTMFT1E1XWMACriUYc4RZgd9k9T7PxCTLHW3jbU71KmJ7Tmsk574olXaRXGtyL/rhOvHBYvN3QO7HxIrHykV8NY5NeZPprM169wWyqg2AqKeq77q9WB2+R3ldDetNutOsb15N0/hQLHYBNqpbHBhEqj69L91Bl+QwJiDu3cXWjM29541u0nToY0S2ykPz772StNkERs/dosNld7P1Oh/G+/pzYWYGTZpbTLeylDH1HDbIcp9wtVRKMgDDlFnTzCyTl0J5jc1a1rLm5LKk2E7W7xTitDawYHx7Ivnwtvnya3xAJWTGWnvdKdYwP9rk2UZFx54eZNdkcpsuxLpmf+7vu01X1pZkbiHNAoqkHQruGcMOMmWl7jYKip7lf5OFle+UIeZnH/RcfTT2uNzu4EXj8K8ItFTMk0qGmevFlLCNrjnFxKXaEmoOtn9oDwtlA2Q4qT+NFeqFL9wgdAGcHmdp/CXqdlB5iTMr52V1+fdIswUO9TKAGjWHy+sOlMTg8DiDOf6xQZrNUFA7v/fJZEhHCbPJFT+w4pgS06wmxyr+iiVLxWGdFKetWoKahgh0cjRwEJAVrbKE/mbnExrLzQkgWzpa7+AeY4F8wQdfIbvHX+WKV8zsnSSDATyl6rS2Kq/hnfVuJpfVl0pz67Dhp1oKErtf7ozliE/QNs7kPPf6JKh7UNJ898DoVb8dnwRXxBH8NKpV1npaWe+6tVNFRVHPPIPdnrcjcBIhRU27uFe7pcpFtWxvg1WvrG1wzzXLuhzZDVMO56Rizr5ets5f9Rs1sqXF9xpZ6NMaXdoiKpSqMiv5vou2b1XLmTkLFVamHcyDlEVFhiTA7cWkgBLgCBDrgGHSbXi6ocxqRSgeLFRpDCnOFXhrvklaiQI0AMexIdrgrnpQO4pQPEorZFmiWoHlVoj++fiK7p5oFIDZU41a2vXUvdYFQn3jqkt9bcvvf5BaIM+pmzPDOEoD795qJY1qCgEQzMPoIw7SjBAQnNFSLZFewCmhHiX3RZkiv8NKkUf+y2Co6RA5tlZT9twtn24rkx+W2TYuIdHlYfQCStnR7dzpU0tMBV/xt+eQ+ILKORi31dUXj5ZpsigzgM2PIKmxKoSMyioLb3JrYpWVf1K85EZPi9NAQYAOrqvQdLOfDNxHEXalllpt3pQWHIaHnu47e3vF8BGWbXJq+XAs2LUYDMNmTeBgzapCViDda+x19C3RJgiJr06/W95IEL0pSd4Jj6vhZlE0eWzKad4E+3+RQLZfFm9ulcbr0nJlPghjSHr8Mr73hSKQJvYgHElF84kQl7wJX3ux/xsIHBCgzVMNApKctNhrjEFi93wUbHK34gssF071tt0sSSb3uelRi9m7vpHo1o/pT0hLmWzuGSgoAEf56thpkJ1VU9U9gpjofMQSHMwyWCtMQK6sIxa9PCXzVmG034MtAXtfet2okfU102yqCLJTu2szhZWo+OOI8x3IuHOGfeVes20IH1Wo2I1uOgJF455O+pvf/PlUt3pi/W2SoI8AtLaIUnHaWEtrPyNWcdtEYzG0+ykSQlJkLYO+7hu6E55a5Xh7hlkzu6P6BAbOY1HKGQJ86mE6bnjh0yWmqpKWS4cWXcHCu5IMjSmem1JLTuvESzPxEcZAjpJTqtsXCcIkuuG7tfB1fRe9+hvrblcjDZ2LanwsP9RYuDRm16v4S/AWL6AzLdMcNqmaDai0s+ok/DoOfPP5yKNXRQ79TazklXBVf/DQxMBkJqWL7VU0ThlXHwhzOTJ/hd3e0i58jL4ffg=="}

View File

@ -1 +1 @@
{"Key":"sys/policy/response-wrapping","Value":"AAAAAQI0PU/pu6EEHcT4HwfZjzScyW8DLBzmGDanjLuWqGEtlLcKgRLZh7/c/CRWwbRXy2d3GUB1Bo3YVzpUuDDlNY3NaipcORS3zzCHep5uO/DFUJ3DPSlde8j1BrmSpQDHerAsJYXYEManr93puObYs1cEfP9Mt8WdC/IPhgecSw32tVGBz0SSP2qaXGwdJQva6xroMWqmwMVU/lsVi/qcV459xXiTYU/8Kp6Xbqx0p0SRR0yVdM+yNiMtYtnzoxWdptbSYLTG1mhumA=="}
{"Value":"AAAAAQJhvv0FiU7o56Z5VXid2TYQ0wRuqUePfHUTdOfqzmNXN1SXEv7xWH9UXOjXIXOurwig/vn19xelqeL53HID/6i7LWrdg6wU+/GPZMDgKBU2Ols81BGCkr+s6o+mYUYf0HAyjAWexqfEPbfKEdtweYRLz4PFQ0JCSfy9PXERzJp+HXNbKh800S+3Y2elSl0EcdtVZQQ4E+5OGfoSTFAam//KTHskHsmg8t52PpTCWJrSjGxpKILI/K6FqiPxYrdDjDukpfILhAk4t0tgVU3JoAE2soBwt4fKnqvMrgJp0okkogxwDw=="}

View File

@ -1 +1 @@
{"Key":"sys/policy/user","Value":"AAAAAQL2/4QvXwqcImWZ0+3rMWv9w6B4ql33rXMnfzi2v/qA7mQbfdow/lB6j0fy79JPNLOPd9K3n7MOlsdDJTL6RJ1hUFFM7CeMYT3EviwKgFl4enaB/K40a/f8jYiLBkvHqdrhLrit7kjs2NytNw=="}
{"Value":"AAAAAQLCgjqndhozT2JTFStJ8yqLGSlBsqtol6u7Rfl1oX1fIfYevraxwpCFORxRx3v77RDNX0xzXkJ1taJ8LVx/9m4GEp5XPh2AsB0nPy0Sfr0s1jqR4Ev8d+z6X01099F6mNfUAnx3gmGuubXZC28Sp3dLBf9Xy080mD0yd+GqlHp2WXnW0aWQKchWwArkTHRxR1722tkbXmr8E72aRz+5eyHapnWXnKhppznQPkGaOY2y9nxhoOM04FVqHA=="}

View File

@ -1 +1 @@
{"Key":"sys/token/salt","Value":"AAAAAQIHNULiDBunAxcG4lQlnKj21ShIgxm7GNc7Zf8an238P2F4XryORfdzXqPyehkJ/npBnI5rCMmt8xLymOXLFRnB"}
{"Value":"AAAAAQJwWbbayyTIlVnbstZPr/otfBY+N+m0j1+7GL19VJXozOVz5jWHqHG6go7ZJOhH2xopMPx3ON4a8kcXuaKU3sUD"}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/1d9485c11b88512ab6e00f6e038105ddeacc8b61","Value":"AAAAAQLgGEtaqyYVvAdd75Ai904aegVg+D/K6PSw2j1ZF1b9Dqq8iqGm57BlpY7WdFI1pXwX9xWNSr4wa8/LofDfuQdW"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKkCb608if/5XnoIX4mxum4Izo9CeV4A4eNp2OvtZhdm6nT328Kk1cyZgyiFBVdqZCsF2aUB4aBo0tJOO4X7gNschAYtGUVP+EhXXNvfJJVCSre+5f5zm3qTkpi7URFCPB2+WnvG4nLHLCDpr8Agp7ZTGRA8ckXA8WjJbmDEG1uBsKZKg=="}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/575eee1a6b5cea9bfe29e29fecffffcbf8ad4006","Value":"AAAAAQKdywIFtMoadN+LSrck4PggbvSJO3WLExzNGdJMrazlhY20PRUfLI3Wzwlet78eJdzhrJ6yymDYEoPAmBdl2unc"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQKXm5Z2IQ9eoLGQS3ynrXFv/vvoJObJHkzyH7uEOTJUqQSJcACpINCBQVVvubvvWtdj6Z8RaUYyKvcMRKI6p7Woi6x7hfRnelWhFgUAkAKaRzj74GxDWn1zWWjtrojz9p8UyzKx1BNH8H5NTYzAsesqC2Sao8LMfSR73tz8g9LhIYYwRQ=="}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/7ab2fb12cd4d090ef2eca9be98f8e3375d42a8f6","Value":"AAAAAQKi28/4Q2x9KVoknHGdIUtoQu8aqb7iecYaVHjPE/DriZ3zG3kexhzspjH8nUp7LjaY7FHwZrSjsOu5CYIBnOOz"}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/92437f5eab1616023d9d221099c46657e7075387","Value":"AAAAAQKOxe300u7ZzybBdAYi5KtrxicnO/0hK9cWDaoCd6lGD71/g/AIWlWKz+DP4aRI+lJ0YFO9WEv6TmNf9gj3dN9m"}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/d2e5585c0050261f9182adcaa8693b5fc31ff553","Value":"AAAAAQJBaj8iLfbGRFRH90AiJ179KHanpct9ko4VMzsYjbd5vLcQs74x/JtkUoJuxdgS4iQp5+qLKAehDOZDqb5d4sE7"}

View File

@ -0,0 +1 @@
{"Value":"AAAAAQIoY02ysjNHsefuLR5lcKu9rzK1Dwp3ZH8AMfVq+dZln9T+FATKzC80OrKafXJzzs3WE7PLZsrYQiwXXaJVrUw+2LufEdccpR1teoKtgtVsLrOuo+++RAAjJoS70ieht9U2Rn3faES3Tw82ISQCoydi6vtLNce5PP+oOXXGmaMaV3T4MQ=="}

View File

@ -1 +0,0 @@
{"Key":"sys/token/accessor/f36b16467afa41b83f8d2f467ce86b0a848aebbf","Value":"AAAAAQKCq6Zqg/q7n6Oi/FfipknrqzI7vYVD9IB+FUuZR56CWUngRRLOs4kLU78vNboCenbYQ3kDYtnxOvUD4xOjNktUzvXoqV0sF0N1p50Mc+MBsR1kzRbbk3nhxocW6lvOmnwLwnE7TtQdEMiU4sHeCoitFgWXfITl2YVxNnY5SXbq4ZSHAVlF"}

Some files were not shown because too many files have changed in this diff Show More