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: 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=" 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: env:
- PATH=$PATH:. - PATH=$PATH:. VAULT_VERSION=0.11.5
before_script: before_script:
- wget https://releases.hashicorp.com/vault/0.11.4/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/0.11.4/vault_0.11.4_SHA256SUMS | grep linux_amd64 | sha256sum -c - wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_0.11.4_linux_amd64.zip - unzip vault_${VAULT_VERSION}_linux_amd64.zip
- rm vault_0.11.4_linux_amd64.zip - rm vault_${VAULT_VERSION}_linux_amd64.zip
cache: cache:
directories: directories:
- '$HOME/.m2/repository' - '$HOME/.m2/repository'

View File

@ -1,71 +1,147 @@
## 0.7.2 [unreleased] ## 0.8.0 (unreleased)
* [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489) ### Breaking
* [improvement] Build environment and tests now compatible with Java 10 * Removed support for `HTTPVaultConnectorFactory#withSslContext()` in favor of `#withTrustedCA()` due to
## 0.7.1 [2018-03-17] ### Improvements
* [improvement] Added automatic module name for JPMS compatibility * refactoring of the internal SSL handling (#17)
* [dependencies] Minor dependency updates * `VaultConnector` extends `java.io.Serializable` (#19)
* [test] Tested against Vault 0.9.5 * 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] ## 0.6.2 [2017-08-19]
* [fix] Prevent potential NPE on SecretResponse getter ### Fixes
* [fix] Removed stack traces on PUT request and response deserialization (#13) * Prevent potential NPE on SecretResponse getter
* [improvement] Fields of InvalidResposneException made final * Removed stack traces on PUT request and response deserialization (#13)
* [deprecation] `listAppRoleSecretss()` in favor of `listAppRoleSecrets()` (#14)
* [test] Tested against Vault 0.8.1, increased coverage
## 0.6.1 [2017-08-02] ### Improvements
* [fix] `TokenModel.getPassword()` returned username instead of password * Fields of InvalidResposneException made final
* [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
## 0.6.0 [2017-05-12] ### Deprecation
* [feature] Initialization from environment variables using `fromEnv()` in factory (#8) * `listAppRoleSecretss()` in favor of `listAppRoleSecrets()` (#14)
* [feature] Automatic authentication with `buildAndAuth()`
* [feature] Custom timeout and number of retries (#9) ### Test
* [feature] Connector implements `AutoCloseable` * Tested against Vault 0.8.1, increased coverage
* [fix] `SecretResponse` does not throw NPE on `get(key)` and `getData()`
* [test] Tested against Vault 0.7.2
## 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] ## 0.4.1 [2016-12-24]
* [fix] Factory Null-tolerant for trusted certificate (#6) ### Fixes
* [test] StackTraces tested for secret leaks * Factory Null-tolerant for trusted certificate (#6)
* [test] Tested against Vault 0.6.4
## 0.4.0 [2016-11-06] ### Test
* [feature] Option to provide a trusted CA certificate (#2) * StackTraces tested for secret leaks
* [feature] Deletion, revocation and renewal of secrets (#3) * Tested against Vault 0.6.4
* [feature] Token creation (#4)
* [feature] AppRole auth backend supported (#5)
* [improvement] Support for complex secrets
* [deprecation] App-ID backend marked as deprecated
## 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 * 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] ### Fixes
* [fix] Check for "permission denied" without status code 400 instead of 403 * Fixed auth backend detection for Vault 0.6.1
* [test] Tested against Vault 0.6.0
## 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 * 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 * Raw secret content or JSON decoding
* SQL secret handling * SQL secret handling
* Connector Factory with builder pattern * Connector Factory with builder pattern
* Tested against Vault 0.11.4 * Tested against Vault 0.11.5
## Maven Artifact ## Maven Artifact
@ -71,13 +71,13 @@ VaultConnector vault = VaultConnectorFactory.httpFactory()
### Authentication ### Authentication
```java ```java
// Authenticate with token // Authenticate with token.
vault.authToken("01234567-89ab-cdef-0123-456789abcdef"); vault.authToken("01234567-89ab-cdef-0123-456789abcdef");
// Authenticate with username and password // Authenticate with username and password.
vault.authUserPass("username", "p4ssw0rd"); 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"); 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) // Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths)
String secret = vault.readSecret("some/secret/key").getValue(); String secret = vault.readSecret("some/secret/key").getValue();
// Complex secret // Complex secret.
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData(); Map<String, Object> secretData = vault.readSecret("another/secret/key").getData();
// Write simple secret // Write simple secret.
vault.writeSecret("new/secret/key", "secret value"); vault.writeSecret("new/secret/key", "secret value");
// Write complex data to arbitraty path // Write complex data to arbitraty path.
Map<String, Object> map = [...] Map<String, Object> map = [...]
vault.write("any/path/to/write", map); vault.write("any/path/to/write", map);
// Delete secret // Delete secret.
vault.delete("any/path/to/write"); 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"> <!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"> <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" /> <path d="M4,12 l60,104 l60,-104 z" stroke="none" fill="#000000" />
<circle cx="78" cy="24" r="6" stroke="none" fill="#00a9c7" /> <rect x="74" y="20" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="78" cy="38" r="6" stroke="none" fill="#00a9c7" /> <rect x="74" y="34" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="78" cy="52" r="6" stroke="none" fill="#00a9c7" /> <rect x="74" y="48" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="78" cy="66" r="6" stroke="none" fill="#00a9c7" /> <rect x="74" y="62" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="72" cy="78" r="6" stroke="none" fill="#00a9c7" /> <rect x="68" y="74" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="58" cy="78" r="6" stroke="none" fill="#00a9c7" /> <rect x="54" y="74" width="8" height="8" stroke="none" fill="#00abe0" />
<circle cx="52" cy="66" r="6" stroke="none" fill="#00a9c7" /> <rect x="48" y="62" width="8" height="8" stroke="none" fill="#00abe0" />
</svg> </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> <groupId>de.stklcode.jvault</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>0.7.2-SNAPSHOT</version> <version>0.8.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>jVaultConnector</name> <name>jVaultConnector</name>
<description>Connector artifact for Hashicorp's Vault secret management</description> <description>Connector artifact for Hashicorp's Vault secret management</description>
<url>https://jvault.stklcode.de</url> <url>https://jvault.stklcode.de</url>
<inceptionYear>2016</inceptionYear>
<licenses> <licenses>
<license> <license>
@ -24,6 +25,25 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </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> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -138,4 +158,55 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </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> </project>

View File

@ -29,18 +29,23 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*; import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets; 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.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -72,16 +77,19 @@ public class HTTPVaultConnector implements VaultConnector {
private static final String HEADER_VAULT_TOKEN = "X-Vault-Token"; 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 ObjectMapper jsonMapper;
private final String baseURL; /* Base URL of Vault */ private final String baseURL; // Base URL of Vault.
private final SSLContext sslContext; /* Custom SSLSocketFactory */ private final String tlsVersion; // TLS version (#22).
private final int retries; /* Number of retries on 5xx errors */ private final X509Certificate trustedCaCert; // Trusted CA certificate.
private final Integer timeout; /* Timeout in milliseconds */ private final int retries; // Number of retries on 5xx errors.
private final Integer timeout; // Timeout in milliseconds.
private boolean authorized = false; /* authorization status */ private boolean authorized = false; // Authorization status.
private String token; /* current token */ private String token; // Current token.
private long tokenTTL = 0; /* expiration time for current token */ private long tokenTTL = 0; // Expiration time for current token.
/** /**
* Create connector using hostname and schema. * 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. * Create connector using hostname, schema, port, path and trusted certificate.
* *
* @param hostname The hostname * @param hostname The hostname
* @param useTLS If TRUE, use HTTPS, otherwise HTTP * @param useTLS If TRUE, use HTTPS, otherwise HTTP
* @param port The port * @param port The port
* @param prefix HTTP API prefix (default: /v1/) * @param prefix HTTP API prefix (default: /v1/)
* @param sslContext Custom SSL Context * @param trustedCaCert Trusted CA certificate
*/ */
public HTTPVaultConnector(final String hostname, public HTTPVaultConnector(final String hostname,
final boolean useTLS, final boolean useTLS,
final Integer port, final Integer port,
final String prefix, final String prefix,
final SSLContext sslContext) { final X509Certificate trustedCaCert) {
this(hostname, useTLS, port, prefix, sslContext, 0, null); 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 hostname The hostname
* @param useTLS If TRUE, use HTTPS, otherwise HTTP * @param useTLS If TRUE, use HTTPS, otherwise HTTP
* @param tlsVersion TLS version
* @param port The port * @param port The port
* @param prefix HTTP API prefix (default: /v1/) * @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 numberOfRetries Number of retries on 5xx errors
* @param timeout Timeout for HTTP requests (milliseconds) * @param timeout Timeout for HTTP requests (milliseconds)
*/ */
public HTTPVaultConnector(final String hostname, public HTTPVaultConnector(final String hostname,
final boolean useTLS, final boolean useTLS,
final String tlsVersion,
final Integer port, final Integer port,
final String prefix, final String prefix,
final SSLContext sslContext, final X509Certificate trustedCaCert,
final int numberOfRetries, final int numberOfRetries,
final Integer timeout) { final Integer timeout) {
this(((useTLS) ? "https" : "http") this(((useTLS) ? "https" : "http")
+ "://" + hostname + "://" + hostname
+ ((port != null) ? ":" + port : "") + ((port != null) ? ":" + port : "")
+ prefix, + prefix,
sslContext, trustedCaCert,
numberOfRetries, numberOfRetries,
timeout); timeout,
tlsVersion);
} }
/** /**
@ -175,40 +186,58 @@ public class HTTPVaultConnector implements VaultConnector {
/** /**
* Create connector using full URL and trusted certificate. * Create connector using full URL and trusted certificate.
* *
* @param baseURL The URL * @param baseURL The URL
* @param sslContext Custom SSL Context * @param trustedCaCert Trusted CA certificate
*/ */
public HTTPVaultConnector(final String baseURL, final SSLContext sslContext) { public HTTPVaultConnector(final String baseURL, final X509Certificate trustedCaCert) {
this(baseURL, sslContext, 0, null); this(baseURL, trustedCaCert, 0, null);
} }
/** /**
* Create connector using full URL and trusted certificate. * Create connector using full URL and trusted certificate.
* *
* @param baseURL The URL * @param baseURL The URL
* @param sslContext Custom SSL Context * @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors * @param numberOfRetries Number of retries on 5xx errors
*/ */
public HTTPVaultConnector(final String baseURL, final SSLContext sslContext, final int numberOfRetries) { public HTTPVaultConnector(final String baseURL, final X509Certificate trustedCaCert, final int numberOfRetries) {
this(baseURL, sslContext, numberOfRetries, null); this(baseURL, trustedCaCert, numberOfRetries, null);
} }
/** /**
* Create connector using full URL and trusted certificate. * Create connector using full URL and trusted certificate.
* *
* @param baseURL The URL * @param baseURL The URL
* @param sslContext Custom SSL Context * @param trustedCaCert Trusted CA certificate
* @param numberOfRetries Number of retries on 5xx errors * @param numberOfRetries Number of retries on 5xx errors
* @param timeout Timeout for HTTP requests (milliseconds) * @param timeout Timeout for HTTP requests (milliseconds)
*/ */
public HTTPVaultConnector(final String baseURL, public HTTPVaultConnector(final String baseURL,
final SSLContext sslContext, final X509Certificate trustedCaCert,
final int numberOfRetries, final int numberOfRetries,
final Integer timeout) { 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.baseURL = baseURL;
this.sslContext = sslContext; this.trustedCaCert = trustedCaCert;
this.retries = numberOfRetries; this.retries = numberOfRetries;
this.timeout = timeout; this.timeout = timeout;
this.tlsVersion = tlsVersion;
this.jsonMapper = new ObjectMapper(); this.jsonMapper = new ObjectMapper();
} }
@ -818,8 +847,11 @@ public class HTTPVaultConnector implements VaultConnector {
/* Set JSON Header */ /* Set JSON Header */
base.addHeader("accept", "application/json"); base.addHeader("accept", "application/json");
HttpResponse response = null; CloseableHttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(sslContext).build()) {
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLSocketFactory(createSSLSocketFactory())
.build()) {
/* Set custom timeout, if defined */ /* Set custom timeout, if defined */
if (this.timeout != null) if (this.timeout != null)
base.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setConnectTimeout(timeout).build()); base.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setConnectTimeout(timeout).build());
@ -890,7 +922,7 @@ public class HTTPVaultConnector implements VaultConnector {
new InputStreamReader(response.getEntity().getContent()))) { new InputStreamReader(response.getEntity().getContent()))) {
String responseString = br.lines().collect(Collectors.joining("\n")); String responseString = br.lines().collect(Collectors.joining("\n"));
ErrorResponse er = jsonMapper.readValue(responseString, ErrorResponse.class); 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")) if (!er.getErrors().isEmpty() && er.getErrors().get(0).equals("permission denied"))
throw new PermissionDeniedException(); throw new PermissionDeniedException();
throw new InvalidResponseException(Error.RESPONSE_CODE, 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. * 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 UNEXPECTED_RESPONSE = "Received response where none was expected";
private static final String URI_FORMAT = "Invalid URI format"; private static final String URI_FORMAT = "Invalid URI format";
private static final String RESPONSE_CODE = "Invalid response code"; 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. * 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.*;
import de.stklcode.jvault.connector.model.response.*; import de.stklcode.jvault.connector.model.response.*;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -33,7 +34,7 @@ import java.util.Map;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
*/ */
public interface VaultConnector extends AutoCloseable { public interface VaultConnector extends AutoCloseable, Serializable {
/** /**
* Default sub-path for Vault secrets. * 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; package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.HTTPVaultConnector; import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.ConnectionException; import de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.exception.VaultConnectorException;
import javax.net.ssl.SSLContext; 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.Path;
import java.nio.file.Paths;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
@ -41,38 +29,19 @@ import java.security.cert.X509Certificate;
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @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 { 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"; private final HTTPVaultConnectorBuilder delegate;
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;
/** /**
* Default empty constructor. * Default empty constructor.
* Initializes factory with default values. * Initializes factory with default values.
*/ */
public HTTPVaultConnectorFactory() { public HTTPVaultConnectorFactory() {
host = DEFAULT_HOST; delegate = new HTTPVaultConnectorBuilder();
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
} }
/** /**
@ -82,7 +51,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self * @return self
*/ */
public HTTPVaultConnectorFactory withHost(final String host) { public HTTPVaultConnectorFactory withHost(final String host) {
this.host = host; delegate.withHost(host);
return this; return this;
} }
@ -93,7 +62,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self * @return self
*/ */
public HTTPVaultConnectorFactory withPort(final Integer port) { public HTTPVaultConnectorFactory withPort(final Integer port) {
this.port = port; delegate.withPort(port);
return this; return this;
} }
@ -104,7 +73,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self * @return self
*/ */
public HTTPVaultConnectorFactory withTLS(final boolean useTLS) { public HTTPVaultConnectorFactory withTLS(final boolean useTLS) {
this.tls = useTLS; delegate.withTLS(useTLS);
return this; return this;
} }
@ -133,7 +102,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @return self * @return self
*/ */
public HTTPVaultConnectorFactory withPrefix(final String prefix) { public HTTPVaultConnectorFactory withPrefix(final String prefix) {
this.prefix = prefix; delegate.withPrefix(prefix);
return this; return this;
} }
@ -146,8 +115,19 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.4.0 * @since 0.4.0
*/ */
public HTTPVaultConnectorFactory withTrustedCA(final Path cert) throws VaultConnectorException { public HTTPVaultConnectorFactory withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) delegate.withTrustedCA(cert);
return withSslContext(createSslContext(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; return this;
} }
@ -158,10 +138,10 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @param sslContext the SSL context * @param sslContext the SSL context
* @return self * @return self
* @since 0.4.0 * @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) { public HTTPVaultConnectorFactory withSslContext(final SSLContext sslContext) {
this.sslContext = sslContext; throw new UnsupportedOperationException("Use of deprecated method, please switch to withTrustedCA()");
return this;
} }
/** /**
@ -172,7 +152,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0 * @since 0.6.0
*/ */
public HTTPVaultConnectorFactory withToken(final String token) { public HTTPVaultConnectorFactory withToken(final String token) {
this.token = token; delegate.withToken(token);
return this; return this;
} }
@ -184,34 +164,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0 * @since 0.6.0
*/ */
public HTTPVaultConnectorFactory fromEnv() throws VaultConnectorException { public HTTPVaultConnectorFactory fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */ delegate.fromEnv();
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; return this;
} }
@ -223,7 +176,7 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0 * @since 0.6.0
*/ */
public HTTPVaultConnectorFactory withNumberOfRetries(final int numberOfRetries) { public HTTPVaultConnectorFactory withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries; delegate.withNumberOfRetries(numberOfRetries);
return this; return this;
} }
@ -235,78 +188,17 @@ public final class HTTPVaultConnectorFactory extends VaultConnectorFactory {
* @since 0.6.0 * @since 0.6.0
*/ */
public HTTPVaultConnectorFactory withTimeout(final int milliseconds) { public HTTPVaultConnectorFactory withTimeout(final int milliseconds) {
this.timeout = milliseconds; delegate.withTimeout(milliseconds);
return this; return this;
} }
@Override @Override
public HTTPVaultConnector build() { public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, port, prefix, sslContext, numberOfRetries, timeout); return delegate.build();
} }
@Override @Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException { public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) return delegate.buildAndAuth();
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);
}
} }
} }

View File

@ -17,6 +17,7 @@
package de.stklcode.jvault.connector.factory; package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.VaultConnector; import de.stklcode.jvault.connector.VaultConnector;
import de.stklcode.jvault.connector.builder.VaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.exception.VaultConnectorException;
/** /**
@ -25,30 +26,19 @@ import de.stklcode.jvault.connector.exception.VaultConnectorException;
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @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. * Get Factory implementation for HTTP Vault Connector.
* *
* @return HTTP Connector Factory * @return HTTP Connector Factory
* @deprecated As of 0.8.0 please refer to {@link VaultConnectorBuilder#http()}.
*/ */
@Deprecated
public static HTTPVaultConnectorFactory httpFactory() { public static HTTPVaultConnectorFactory httpFactory() {
return new HTTPVaultConnectorFactory(); 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> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies; private List<String> policies;
@JsonProperty("secret_id_num_uses") @JsonProperty("secret_id_num_uses")
@ -73,24 +75,57 @@ public final class AppRole {
/** /**
* Construct complete {@link AppRole} object. * Construct complete {@link AppRole} object.
* *
* @param name Role name (required) * @param name Role name (required)
* @param id Role ID (optional) * @param id Role ID (optional)
* @param bindSecretId Bind secret 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 policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional) * @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional) * @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional) * @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (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 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 List<String> policies, final Integer secretIdNumUses, final Integer secretIdTtl,
final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) { final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) {
this.name = name; this.name = name;
this.id = id; this.id = id;
this.bindSecretId = bindSecretId; 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.boundCidrList = boundCidrList;
this.secretIdBoundCidrs = secretIdBoundCidrs;
this.policies = policies; this.policies = policies;
this.secretIdNumUses = secretIdNumUses; this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl; this.secretIdTtl = secretIdTtl;
@ -122,14 +157,18 @@ public final class AppRole {
/** /**
* @return list of bound CIDR subnets * @return list of bound CIDR subnets
* @deprecated Use {@link #getSecretIdBoundCidrs()} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
public List<String> getBoundCidrList() { public List<String> getBoundCidrList() {
return boundCidrList; return boundCidrList;
} }
/** /**
* @param boundCidrList list of subnets in CIDR notation to bind role to * @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") @JsonSetter("bound_cidr_list")
public void setBoundCidrList(final List<String> boundCidrList) { public void setBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList; this.boundCidrList = boundCidrList;
@ -137,7 +176,9 @@ public final class AppRole {
/** /**
* @return list of subnets in CIDR notation as comma-separated {@link String} * @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") @JsonGetter("bound_cidr_list")
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
public String getBoundCidrListString() { public String getBoundCidrListString() {
@ -146,6 +187,36 @@ public final class AppRole {
return String.join(",", boundCidrList); 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 * @return list of policies
*/ */

View File

@ -30,6 +30,7 @@ public final class AppRoleBuilder {
private String id; private String id;
private Boolean bindSecretId; private Boolean bindSecretId;
private List<String> boundCidrList; private List<String> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies; private List<String> policies;
private Integer secretIdNumUses; private Integer secretIdNumUses;
private Integer secretIdTtl; private Integer secretIdTtl;
@ -93,12 +94,26 @@ public final class AppRoleBuilder {
* *
* @param boundCidrList List of CIDR blocks which can perform login * @param boundCidrList List of CIDR blocks which can perform login
* @return self * @return self
* @deprecated Use {@link #withSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) { public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList; this.boundCidrList = boundCidrList;
return this; 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. * Add a CIDR block to list of bound blocks.
* *
@ -106,9 +121,15 @@ public final class AppRoleBuilder {
* @return self * @return self
*/ */
public AppRoleBuilder withCidrBlock(final String cidrBlock) { public AppRoleBuilder withCidrBlock(final String cidrBlock) {
if (boundCidrList == null) if (boundCidrList == null) {
boundCidrList = new ArrayList<>(); boundCidrList = new ArrayList<>();
}
boundCidrList.add(cidrBlock); boundCidrList.add(cidrBlock);
if (secretIdBoundCidrs == null) {
secretIdBoundCidrs = new ArrayList<>();
}
secretIdBoundCidrs.add(cidrBlock);
return this; return this;
} }
@ -204,6 +225,7 @@ public final class AppRoleBuilder {
id, id,
bindSecretId, bindSecretId,
boundCidrList, boundCidrList,
secretIdBoundCidrs,
policies, policies,
secretIdNumUses, secretIdNumUses,
secretIdTtl, 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") @JsonProperty("initialized")
private Boolean 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. * @return The Cluster ID.
*/ */
@ -96,4 +105,28 @@ public final class HealthResponse implements VaultResponse {
public Boolean isInitialized() { public Boolean isInitialized() {
return initialized; 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. * Vault response for seal status or unseal request.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class SealResponse implements VaultResponse { public final class SealResponse implements VaultResponse {
@JsonProperty("type")
private String type;
@JsonProperty("sealed") @JsonProperty("sealed")
private boolean sealed; private boolean sealed;
@JsonProperty("initialized")
private boolean initialized;
@JsonProperty("t") @JsonProperty("t")
private Integer threshold; private Integer threshold;
@ -39,6 +45,26 @@ public final class SealResponse implements VaultResponse {
@JsonProperty("progress") @JsonProperty("progress")
private Integer 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 * @return Seal status
*/ */
@ -46,6 +72,14 @@ public final class SealResponse implements VaultResponse {
return sealed; 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 * @return Required threshold of secret shares
*/ */
@ -66,4 +100,36 @@ public final class SealResponse implements VaultResponse {
public Integer getProgress() { public Integer getProgress() {
return progress; 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.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import javax.net.ssl.SSLContext;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field; 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 java.util.Collections;
import static net.bytebuddy.implementation.MethodDelegation.to; import static net.bytebuddy.implementation.MethodDelegation.to;
@ -152,7 +154,7 @@ public class HTTPVaultConnectorOfflineTest {
* Test constductors of the {@link HTTPVaultConnector} class. * Test constductors of the {@link HTTPVaultConnector} class.
*/ */
@Test @Test
public void constructorTest() throws NoSuchAlgorithmException { public void constructorTest() throws IOException, CertificateException {
final String url = "https://vault.example.net/test/"; final String url = "https://vault.example.net/test/";
final String hostname = "vault.example.com"; final String hostname = "vault.example.com";
final Integer port = 1337; final Integer port = 1337;
@ -161,7 +163,11 @@ public class HTTPVaultConnectorOfflineTest {
final String expectedNoTls = "http://" + hostname + "/v1/"; final String expectedNoTls = "http://" + hostname + "/v1/";
final String expectedCustomPort = "https://" + hostname + ":" + port + "/v1/"; final String expectedCustomPort = "https://" + hostname + ":" + port + "/v1/";
final String expectedCustomPrefix = "https://" + hostname + ":" + port + prefix; 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. // Most basic constructor expects complete URL.
HTTPVaultConnector connector = new HTTPVaultConnector(url); HTTPVaultConnector connector = new HTTPVaultConnector(url);
@ -178,16 +184,22 @@ public class HTTPVaultConnectorOfflineTest {
// Specify custom prefix. // Specify custom prefix.
connector = new HTTPVaultConnector(hostname, true, port, prefix); connector = new HTTPVaultConnector(hostname, true, port, prefix);
assertThat("Unexpected base URL with custom prefix", getPrivate(connector, "baseURL"), is(expectedCustomPrefix)); 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. // 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("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. // 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)); 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 @EnableRuleMigrationSupport
public class HTTPVaultConnectorTest { public class HTTPVaultConnectorTest {
private static final String VAULT_VERISON = "0.11.4"; // the vault version this test is supposed to run against private static String VAULT_VERSION = "0.11.5"; // the vault version this test is supposed to run against
private static final String KEY = "81011a8061e5c028bd0d9503eeba40bd9054b9af0408d080cb24f57405c27a61"; private static final String KEY1 = "E38bkCm0VhUvpdCKGQpcohhD9XmcHJ/2hreOSY019Lho";
private static final String TOKEN_ROOT = "d1bd50e2-587b-6e68-d80b-a9a507625cb7"; 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 USER_VALID = "validUser";
private static final String PASS_VALID = "validPass"; private static final String PASS_VALID = "validPass";
private static final String APP_ID = "152AEA38-85FB-47A8-9CBD-612D645BFACA"; 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 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_NAME = "testrole1"; // role with secret ID
private static final String APPROLE_ROLE = "627b6400-90c3-a239-49a9-af65a448ca10"; private static final String APPROLE_ROLE = "06eae026-7d4b-e4f8-0ec4-4107eb483975";
private static final String APPROLE_SECRET = "5e8b0e99-d906-27f5-f043-ccb9bb53b5e8"; private static final String APPROLE_SECRET = "20320293-c1c1-3b22-20f8-e5c960da0b5b";
private static final String APPROLE_SECRET_ACCESSOR = "071e2e9d-742a-fc3c-3fd3-1f4004b0420a"; 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_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_PATH = "userstore";
private static final String SECRET_KEY = "foo"; private static final String SECRET_KEY = "foo";
private static final String SECRET_VALUE = "bar"; private static final String SECRET_VALUE = "bar";
@ -81,6 +83,15 @@ public class HTTPVaultConnectorTest {
@Rule @Rule
public TemporaryFolder tmpDir = new TemporaryFolder(); 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. * 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. * 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(); connector = factory.build();
/* Unseal Vault and check result */ /* 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); assumeTrue(sealStatus != null);
assumeFalse(sealStatus.isSealed()); assumeFalse(sealStatus.isSealed());
assumeTrue(sealStatus.isInitialized()); // Initialized flag of Vault 0.11.2 (#20).
} }
@AfterEach @AfterEach
@ -142,7 +157,9 @@ public class HTTPVaultConnectorTest {
connector.seal(); connector.seal();
sealStatus = connector.sealStatus(); sealStatus = connector.sealStatus();
assertThat("Vault not sealed", sealStatus.isSealed(), is(true)); 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)); assertThat("Vault not unsealed", sealStatus.isSealed(), is(false));
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
fail("Sealing failed"); fail("Sealing failed");
@ -161,7 +178,7 @@ public class HTTPVaultConnectorTest {
fail("Retrieving health status failed: " + e.getMessage()); fail("Retrieving health status failed: " + e.getMessage());
} }
assertThat("Health response should be set", res, is(notNullValue())); 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 init status", res.isInitialized(), is(true));
assertThat("Unexpected seal status", res.isSealed(), is(false)); assertThat("Unexpected seal status", res.isSealed(), is(false));
assertThat("Unexpected standby status", res.isStandby(), is(false)); assertThat("Unexpected standby status", res.isStandby(), is(false));
@ -861,12 +878,18 @@ public class HTTPVaultConnectorTest {
try { try {
AuthResponse res = connector.createToken(token); AuthResponse res = connector.createToken(token);
assertThat("No result given.", res, is(notNullValue())); 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 token ID returned.", res.getAuth().getClientToken(), is("test-id"));
assertThat("Invalid number of policies returned.", res.getAuth().getPolicies(), hasSize(1)); assertThat("Invalid number of policies returned.", res.getAuth().getPolicies(), hasSize(1));
assertThat("Root policy not inherited.", res.getAuth().getPolicies(), contains("root")); assertThat("Root policy not inherited.", res.getAuth().getPolicies(), contains("root"));
assertThat("Metadata unexpected.", res.getAuth().getMetadata(), is(nullValue())); assertThat("Metadata unexpected.", res.getAuth().getMetadata(), is(nullValue()));
assertThat("Root token should not be renewable", res.getAuth().isRenewable(), is(false)); 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) { } catch (VaultConnectorException e) {
fail("Secret written to inaccessible path."); 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(); connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); 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)); assertThat("Non-default number of retries, when none set", getPrivate(connector, "retries"), is(0));
/* Provide address and number of retries */ /* Provide address and number of retries */
@ -83,7 +83,7 @@ public class HTTPVaultConnectorFactoryTest {
connector = factory.build(); connector = factory.build();
assertThat("URL nor set correctly", getPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); 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)); assertThat("Number of retries not set correctly", getPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
/* Provide CA certificate */ /* Provide CA certificate */
@ -107,7 +107,7 @@ public class HTTPVaultConnectorFactoryTest {
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed"); 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) { 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 TOKEN_MAX_TTL = 9600;
private static final Integer PERIOD = 1234; private static final Integer PERIOD = 1234;
private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}"; 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}", 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, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD); NAME, ID, BIND_SECRET_ID, CIDR_1, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD);
@BeforeAll @BeforeAll
public static void init() { public static void init() {
@ -69,6 +69,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
assertThat(role.getBoundCidrList(), is(nullValue())); assertThat(role.getBoundCidrList(), is(nullValue()));
assertThat(role.getSecretIdBoundCidrs(), is(nullValue()));
assertThat(role.getPolicies(), is(nullValue())); assertThat(role.getPolicies(), is(nullValue()));
assertThat(role.getSecretIdNumUses(), is(nullValue())); assertThat(role.getSecretIdNumUses(), is(nullValue()));
assertThat(role.getSecretIdTtl(), is(nullValue())); assertThat(role.getSecretIdTtl(), is(nullValue()));
@ -89,6 +90,7 @@ public class AppRoleBuilderTest {
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
.withBoundCidrList(BOUND_CIDR_LIST) .withBoundCidrList(BOUND_CIDR_LIST)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withPolicies(POLICIES) .withPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES) .withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL) .withSecretIdTtl(SECRET_ID_TTL)
@ -100,6 +102,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(ID)); assertThat(role.getId(), is(ID));
assertThat(role.getBindSecretId(), is(BIND_SECRET_ID)); assertThat(role.getBindSecretId(), is(BIND_SECRET_ID));
assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST)); assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST));
assertThat(role.getSecretIdBoundCidrs(), is(BOUND_CIDR_LIST));
assertThat(role.getPolicies(), is(POLICIES)); assertThat(role.getPolicies(), is(POLICIES));
assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES)); assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES));
assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL)); assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL));
@ -128,12 +131,16 @@ public class AppRoleBuilderTest {
role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build(); role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build();
assertThat(role.getBoundCidrList(), hasSize(1)); assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_2)); assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(1));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_2));
role = new AppRoleBuilder(NAME) role = new AppRoleBuilder(NAME)
.withBoundCidrList(BOUND_CIDR_LIST) .withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withCidrBlock(CIDR_2) .withCidrBlock(CIDR_2)
.build(); .build();
assertThat(role.getBoundCidrList(), hasSize(2)); assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_1, CIDR_2)); assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(2));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_1, CIDR_2));
/* Add single policy */ /* Add single policy */
role = new AppRoleBuilder(NAME).withPolicy(POLICY_2).build(); 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 { public class HealthResponseTest {
private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228"; private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228";
private static final String CLUSTER_NAME = "vault-cluster-5515c810"; 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 Long SERVER_TIME_UTC = 1469555798L;
private static final Boolean STANDBY = false; private static final Boolean STANDBY = false;
private static final Boolean SEALED = false; private static final Boolean SEALED = false;
private static final Boolean INITIALIZED = true; 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" + private static final String RES_JSON = "{\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" + " \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
@ -48,7 +51,10 @@ public class HealthResponseTest {
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" + " \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
" \"standby\": " + STANDBY + ",\n" + " \"standby\": " + STANDBY + ",\n" +
" \"sealed\": " + SEALED + ",\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). * 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 standby state", res.isStandby(), is(STANDBY));
assertThat("Incorrect seal state", res.isSealed(), is(SEALED)); assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED)); 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) { } catch (IOException e) {
fail("Health deserialization failed: " + e.getMessage()); 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 @Override
public String toString() { public String toString() {
return "backend \"file\" {\n" + return "storage \"file\" {\n" +
" path = \"" + dataLocation + "\"\n" + " path = \"" + dataLocation + "\"\n" +
"}\n" + "}\n" +
"listener \"tcp\" {\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