mirror of
https://github.com/google/nomulus.git
synced 2025-05-16 09:27:16 +02:00
Require SSL certificate hash on login by default
Note that it's possible to set a config option to disable this functionality on a per-environment basis (we're disabling it for sandbox), but in general SSL certificate hashes should be required for increased security. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=225053496
This commit is contained in:
parent
0a44ef0dca
commit
400994237c
9 changed files with 80 additions and 29 deletions
|
@ -573,6 +573,17 @@ public final class RegistryConfig {
|
|||
return beamBucketUrl + "/templates/spec11";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an SSL certificate hash is required to log in via EPP and run flows.
|
||||
*
|
||||
* @see google.registry.flows.TlsCredentials
|
||||
*/
|
||||
@Provides
|
||||
@Config("requireSslCertificates")
|
||||
public static boolean provideRequireSslCertificates(RegistryConfigSettings config) {
|
||||
return config.registryPolicy.requireSslCertificates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default job zone to run Apache Beam (Cloud Dataflow) jobs in.
|
||||
*
|
||||
|
|
|
@ -92,6 +92,7 @@ public class RegistryConfigSettings {
|
|||
public String rdapTos;
|
||||
public String rdapTosStaticUrl;
|
||||
public String spec11EmailBodyTemplate;
|
||||
public boolean requireSslCertificates;
|
||||
}
|
||||
|
||||
/** Configuration for Cloud Datastore. */
|
||||
|
|
|
@ -183,6 +183,11 @@ registryPolicy:
|
|||
If you have any questions regarding this notice, please contact
|
||||
{REPLY_TO_EMAIL}.
|
||||
|
||||
# Whether to require an SSL certificate hash in order to be able to log in
|
||||
# via EPP and run commands. This can be false for testing environments but
|
||||
# should generally be true for production environments, for added security.
|
||||
requireSslCertificates: true
|
||||
|
||||
datastore:
|
||||
# Number of commit log buckets in Datastore. Lowering this after initial
|
||||
# install risks losing up to a days' worth of differential backups.
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.common.net.HostAndPort;
|
|||
import com.google.common.net.InetAddresses;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.flows.EppException.AuthenticationErrorException;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.request.Header;
|
||||
|
@ -54,14 +55,17 @@ public class TlsCredentials implements TransportCredentials {
|
|||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private final boolean requireSslCertificates;
|
||||
private final String clientCertificateHash;
|
||||
private final InetAddress clientInetAddr;
|
||||
|
||||
@Inject
|
||||
@VisibleForTesting
|
||||
public TlsCredentials(
|
||||
@Config("requireSslCertificates") boolean requireSslCertificates,
|
||||
@Header("X-SSL-Certificate") String clientCertificateHash,
|
||||
@Header("X-Forwarded-For") Optional<String> clientAddress) {
|
||||
this.requireSslCertificates = requireSslCertificates;
|
||||
this.clientCertificateHash = clientCertificateHash;
|
||||
this.clientInetAddr = clientAddress.isPresent() ? parseInetAddress(clientAddress.get()) : null;
|
||||
}
|
||||
|
@ -112,13 +116,17 @@ public class TlsCredentials implements TransportCredentials {
|
|||
* @throws MissingRegistrarCertificateException if frontend didn't send certificate hash header
|
||||
* @throws BadRegistrarCertificateException if registrar requires certificate and it didn't match
|
||||
*/
|
||||
private void validateCertificate(Registrar registrar) throws AuthenticationErrorException {
|
||||
@VisibleForTesting
|
||||
void validateCertificate(Registrar registrar) throws AuthenticationErrorException {
|
||||
if (isNullOrEmpty(registrar.getClientCertificateHash())
|
||||
&& isNullOrEmpty(registrar.getFailoverClientCertificateHash())) {
|
||||
logger.atInfo().log(
|
||||
"Skipping SSL certificate check because %s doesn't have any certificate hashes on file",
|
||||
registrar.getClientId());
|
||||
return;
|
||||
if (requireSslCertificates) {
|
||||
throw new RegistrarCertificateNotConfiguredException();
|
||||
} else {
|
||||
// If the environment is configured to allow missing SSL certificate hashes and this hash is
|
||||
// missing, then bypass the certificate hash checks.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isNullOrEmpty(clientCertificateHash)) {
|
||||
logger.atInfo().log("Request did not include X-SSL-Certificate");
|
||||
|
@ -165,6 +173,14 @@ public class TlsCredentials implements TransportCredentials {
|
|||
}
|
||||
}
|
||||
|
||||
/** Registrar certificate is not configured. */
|
||||
public static class RegistrarCertificateNotConfiguredException
|
||||
extends AuthenticationErrorException {
|
||||
public RegistrarCertificateNotConfiguredException() {
|
||||
super("Registrar certificate is not configured");
|
||||
}
|
||||
}
|
||||
|
||||
/** Registrar IP address is not in stored whitelist. */
|
||||
public static class BadRegistrarIpAddressException extends AuthenticationErrorException {
|
||||
public BadRegistrarIpAddressException() {
|
||||
|
|
|
@ -78,7 +78,7 @@ final class ValidateLoginCredentialsCommand implements CommandWithRemoteApi {
|
|||
Registrar registrar =
|
||||
checkArgumentPresent(
|
||||
Registrar.loadByClientId(clientId), "Registrar %s not found", clientId);
|
||||
new TlsCredentials(clientCertificateHash, Optional.of(clientIpAddress))
|
||||
new TlsCredentials(true, clientCertificateHash, Optional.of(clientIpAddress))
|
||||
.validate(registrar, password);
|
||||
checkState(!registrar.getState().equals(Registrar.State.PENDING), "Account pending");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue