summaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service/src
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@oath.com>2017-11-02 12:58:49 +0100
committerValerij Fredriksen <valerijf@oath.com>2017-11-02 12:58:49 +0100
commit52f764682095c08f654e59d3041a704b9ac9551c (patch)
tree2125813562b8d7ea2249fb12ebf8631d7a60be7e /athenz-identity-provider-service/src
parent8a96eb2f6c55f15b69cb103fe44eb524023fb2ba (diff)
Validate identity same as in services.xml
Diffstat (limited to 'athenz-identity-provider-service/src')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java12
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/InstanceValidator.java50
2 files changed, 57 insertions, 5 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java
index e66130332ac..c417675f16d 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.athenz.instanceproviderservice;
import com.google.inject.Inject;
import com.yahoo.component.AbstractComponent;
+import com.yahoo.config.model.api.SuperModelProvider;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.log.LogLevel;
@@ -47,14 +48,16 @@ public class AthenzInstanceProviderService extends AbstractComponent {
private final Server jetty;
@Inject
- public AthenzInstanceProviderService(AthenzProviderServiceConfig config, NodeRepository nodeRepository, Zone zone) {
+ public AthenzInstanceProviderService(AthenzProviderServiceConfig config, SuperModelProvider superModelProvider,
+ NodeRepository nodeRepository, Zone zone) {
this(config, new FileBackedKeyProvider(config.keyPathPrefix()), Executors.newSingleThreadScheduledExecutor(),
- nodeRepository, zone, new AthenzCertificateClient(config));
+ superModelProvider, nodeRepository, zone, new AthenzCertificateClient(config));
}
AthenzInstanceProviderService(AthenzProviderServiceConfig config,
KeyProvider keyProvider,
ScheduledExecutorService scheduler,
+ SuperModelProvider superModelProvider,
NodeRepository nodeRepository,
Zone zone,
CertificateClient certificateClient) {
@@ -63,7 +66,7 @@ public class AthenzInstanceProviderService extends AbstractComponent {
this.scheduler = scheduler;
SslContextFactory sslContextFactory = createSslContextFactory();
this.jetty = createJettyServer(
- config, keyProvider, sslContextFactory, nodeRepository, zone);
+ config, keyProvider, sslContextFactory, superModelProvider, nodeRepository, zone);
AthenzCertificateUpdater reloader =
new AthenzCertificateUpdater(certificateClient, sslContextFactory, keyProvider, config);
// TODO Configurable update frequency
@@ -82,6 +85,7 @@ public class AthenzInstanceProviderService extends AbstractComponent {
private static Server createJettyServer(AthenzProviderServiceConfig config,
KeyProvider keyProvider,
SslContextFactory sslContextFactory,
+ SuperModelProvider superModelProvider,
NodeRepository nodeRepository,
Zone zone) {
Server server = new Server();
@@ -91,7 +95,7 @@ public class AthenzInstanceProviderService extends AbstractComponent {
ServletHandler handler = new ServletHandler();
InstanceConfirmationServlet instanceConfirmationServlet =
- new InstanceConfirmationServlet(new InstanceValidator(keyProvider));
+ new InstanceConfirmationServlet(new InstanceValidator(keyProvider, superModelProvider));
handler.addServletWithMapping(new ServletHolder(instanceConfirmationServlet), config.apiPath() + "/instance");
IdentityDocumentServlet identityDocumentServlet =
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/InstanceValidator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/InstanceValidator.java
index 8d76300c2bb..d738b34041a 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/InstanceValidator.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/InstanceValidator.java
@@ -1,6 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl;
+import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.model.api.SuperModelProvider;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.log.LogLevel;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.model.InstanceConfirmation;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.model.ProviderUniqueId;
@@ -12,6 +16,7 @@ import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Base64;
+import java.util.Optional;
import java.util.logging.Logger;
/**
@@ -24,14 +29,23 @@ public class InstanceValidator {
private static final Logger log = Logger.getLogger(InstanceValidator.class.getName());
private final KeyProvider keyProvider;
+ private final SuperModelProvider superModelProvider;
- public InstanceValidator(KeyProvider keyProvider) {
+ public InstanceValidator(KeyProvider keyProvider, SuperModelProvider superModelProvider) {
this.keyProvider = keyProvider;
+ this.superModelProvider = superModelProvider;
}
public boolean isValidInstance(InstanceConfirmation instanceConfirmation) {
SignedIdentityDocument signedIdentityDocument = instanceConfirmation.signedIdentityDocument;
ProviderUniqueId providerUniqueId = signedIdentityDocument.identityDocument.providerUniqueId;
+ ApplicationId applicationId = ApplicationId.from(
+ providerUniqueId.tenant, providerUniqueId.application, providerUniqueId.instance);
+
+ if (! isSameIdentityAsInServicesXml(applicationId, instanceConfirmation.domain, instanceConfirmation.service)) {
+ return false;
+ }
+
log.log(LogLevel.INFO, () -> String.format("Validating instance %s.", providerUniqueId));
PublicKey publicKey = keyProvider.getPublicKey(signedIdentityDocument.signingKeyVersion);
if (isSignatureValid(publicKey, signedIdentityDocument.rawIdentityDocument, signedIdentityDocument.signature)) {
@@ -52,4 +66,38 @@ public class InstanceValidator {
throw new RuntimeException(e);
}
}
+
+ // If/when we dont care about logging exactly whats wrong, this can be simplified
+ private boolean isSameIdentityAsInServicesXml(ApplicationId applicationId, String domain, String service) {
+ Optional<ApplicationInfo> applicationInfo = superModelProvider.getSuperModel().getApplicationInfo(applicationId);
+
+ if (!applicationInfo.isPresent()) {
+ log.info(String.format("Could not find application info for %s", applicationId.serializedForm()));
+ return false;
+ }
+
+ Optional<ServiceInfo> matchingServiceInfo = applicationInfo.get()
+ .getModel()
+ .getHosts()
+ .stream()
+ .flatMap(hostInfo -> hostInfo.getServices().stream())
+ .filter(serviceInfo -> serviceInfo.getProperty("identity.domain").isPresent())
+ .filter(serviceInfo -> serviceInfo.getProperty("identity.service").isPresent())
+ .findFirst();
+
+ if (!matchingServiceInfo.isPresent()) {
+ log.info(String.format("Application %s has not specified domain/service", applicationId.serializedForm()));
+ return false;
+ }
+
+ String domainInConfig = matchingServiceInfo.get().getProperty("identity.domain").get();
+ String serviceInConfig = matchingServiceInfo.get().getProperty("identity.service").get();
+ if (domainInConfig.equals(domain) && serviceInConfig.equals(service)) {
+ return true;
+ } else {
+ log.info(String.format("domain '%s' or service '%s' does not match the one in config for application %s",
+ domain, service, applicationId.serializedForm()));
+ return false;
+ }
+ }
}