Rename whitelist -> allow list (#635)

* Rename whitelist -> allow list

* Merge branch 'master' into allowlist-denylist
This commit is contained in:
Ben McIlwain
2020-06-18 18:36:05 -04:00
committed by GitHub
parent 382c8014de
commit df8ce38796
91 changed files with 448 additions and 453 deletions
@@ -246,28 +246,32 @@ public class DeleteProberDataAction implements Runnable {
}
private void softDeleteDomain(final DomainBase domain) {
tm().transactNew(() -> {
DomainBase deletedDomain = domain
.asBuilder()
.setDeletionTime(tm().getTransactionTime())
.setStatusValues(null)
.build();
HistoryEntry historyEntry = new HistoryEntry.Builder()
.setParent(domain)
.setType(DOMAIN_DELETE)
.setModificationTime(tm().getTransactionTime())
.setBySuperuser(true)
.setReason("Deletion of prober data")
.setClientId(registryAdminClientId)
.build();
// Note that we don't bother handling grace periods, billing events, pending transfers,
// poll messages, or auto-renews because these will all be hard-deleted the next time the
// mapreduce runs anyway.
ofy().save().entities(deletedDomain, historyEntry);
updateForeignKeyIndexDeletionTime(deletedDomain);
dnsQueue.addDomainRefreshTask(deletedDomain.getDomainName());
}
);
tm().transactNew(
() -> {
DomainBase deletedDomain =
domain
.asBuilder()
.setDeletionTime(tm().getTransactionTime())
.setStatusValues(null)
.build();
HistoryEntry historyEntry =
new HistoryEntry.Builder()
.setParent(domain)
.setType(DOMAIN_DELETE)
.setModificationTime(tm().getTransactionTime())
.setBySuperuser(true)
.setReason("Deletion of prober data")
.setClientId(registryAdminClientId)
.build();
// Note that we don't bother handling grace periods, billing events, pending
// transfers,
// poll messages, or auto-renews because these will all be hard-deleted the next
// time the
// mapreduce runs anyway.
ofy().save().entities(deletedDomain, historyEntry);
updateForeignKeyIndexDeletionTime(deletedDomain);
dnsQueue.addDomainRefreshTask(deletedDomain.getDomainName());
});
}
}
}
@@ -215,8 +215,7 @@ public class DnsUpdateWriter extends BaseDnsWriter {
private void addInBailiwickNameServerSet(DomainBase domain, Update update) {
for (String hostName :
intersection(
domain.loadNameserverHostNames(), domain.getSubordinateHosts())) {
intersection(domain.loadNameserverHostNames(), domain.getSubordinateHosts())) {
Optional<HostResource> host = loadByForeignKey(HostResource.class, hostName, clock.nowUtc());
checkState(host.isPresent(), "Host %s cannot be loaded", hostName);
update.add(makeAddressSet(host.get()));
@@ -284,7 +284,7 @@
<description>
Checks if the monthly ICANN reports have been successfully uploaded. If they have not, attempts to upload them again.
Most of the time, this job should not do anything since the uploads are triggered when the reports are staged.
However, in the event that an upload failed for any reason (e.g. ICANN server is down, IP whitelist issues),
However, in the event that an upload failed for any reason (e.g. ICANN server is down, IP allow list issues),
this cron job will continue to retry uploads daily until they succeed.
</description>
<schedule>every day 15:00</schedule>
@@ -84,8 +84,7 @@ class SyncRegistrarsSheet {
public int compare(Registrar left, Registrar right) {
return left.getClientId().compareTo(right.getClientId());
}
}.immutableSortedCopy(Registrar.loadAllCached())
.stream()
}.immutableSortedCopy(Registrar.loadAllCached()).stream()
.filter(
registrar ->
registrar.getType() == Registrar.Type.REAL
@@ -149,7 +148,7 @@ class SyncRegistrarsSheet {
builder.put("allowedTlds", convert(registrar.getAllowedTlds()));
builder.put("whoisServer", convert(registrar.getWhoisServer()));
builder.put("blockPremiumNames", convert(registrar.getBlockPremiumNames()));
builder.put("ipAddressWhitelist", convert(registrar.getIpAddressWhitelist()));
builder.put("ipAddressAllowList", convert(registrar.getIpAddressAllowList()));
builder.put("url", convert(registrar.getUrl()));
builder.put("referralUrl", convert(registrar.getUrl()));
builder.put("icannReferralEmail", convert(registrar.getIcannReferralEmail()));
@@ -37,7 +37,7 @@ import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
/**
* Container and validation for TLS certificate and ip-whitelisting.
* Container and validation for TLS certificate and IP-allow-listing.
*
* <p>Credentials are based on the following headers:
*
@@ -48,7 +48,7 @@ import javax.servlet.http.HttpServletRequest;
* band.
* <dt>X-Forwarded-For
* <dd>This field should contain the host and port of the connecting client. It is validated
* during an EPP login command against an IP whitelist that is transmitted out of band.
* during an EPP login command against an IP allow list that is transmitted out of band.
* </dl>
*/
public class TlsCredentials implements TransportCredentials {
@@ -85,27 +85,28 @@ public class TlsCredentials implements TransportCredentials {
}
/**
* Verifies {@link #clientInetAddr} is in CIDR whitelist associated with {@code registrar}.
* Verifies {@link #clientInetAddr} is in CIDR allow list associated with {@code registrar}.
*
* @throws BadRegistrarIpAddressException If IP address is not in the whitelist provided
* @throws BadRegistrarIpAddressException If IP address is not in the allow list provided
*/
private void validateIp(Registrar registrar) throws AuthenticationErrorException {
ImmutableList<CidrAddressBlock> ipWhitelist = registrar.getIpAddressWhitelist();
if (ipWhitelist.isEmpty()) {
ImmutableList<CidrAddressBlock> ipAddressAllowList = registrar.getIpAddressAllowList();
if (ipAddressAllowList.isEmpty()) {
logger.atInfo().log(
"Skipping IP whitelist check because %s doesn't have an IP whitelist",
"Skipping IP allow list check because %s doesn't have an IP allow list",
registrar.getClientId());
return;
}
for (CidrAddressBlock cidrAddressBlock : ipWhitelist) {
for (CidrAddressBlock cidrAddressBlock : ipAddressAllowList) {
if (cidrAddressBlock.contains(clientInetAddr)) {
// IP address is in whitelist; return early.
// IP address is in allow list; return early.
return;
}
}
logger.atInfo().log(
"Authentication error: IP address %s is not whitelisted for registrar %s; whitelist is: %s",
clientInetAddr, registrar.getClientId(), ipWhitelist);
"Authentication error: IP address %s is not allow-listed for registrar %s; allow list is:"
+ " %s",
clientInetAddr, registrar.getClientId(), ipAddressAllowList);
throw new BadRegistrarIpAddressException();
}
@@ -180,10 +181,10 @@ public class TlsCredentials implements TransportCredentials {
}
}
/** Registrar IP address is not in stored whitelist. */
/** Registrar IP address is not in stored allow list. */
public static class BadRegistrarIpAddressException extends AuthenticationErrorException {
public BadRegistrarIpAddressException() {
super("Registrar IP address is not in stored whitelist");
super("Registrar IP address is not in stored allow list");
}
}
@@ -181,7 +181,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.MissingRegistrantException}
* @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.NameserversNotAllowedForTldException}
* @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverWhitelistException}
* @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverAllowListException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
@@ -338,11 +338,11 @@ public class DomainFlowUtils {
static void validateNameserversCountForTld(String tld, InternetDomainName domainName, int count)
throws EppException {
// For TLDs with a nameserver whitelist, all domains must have at least 1 nameserver.
ImmutableSet<String> tldNameserversWhitelist =
// For TLDs with a nameserver allow list, all domains must have at least 1 nameserver.
ImmutableSet<String> tldNameserversAllowList =
Registry.get(tld).getAllowedFullyQualifiedHostNames();
if (!tldNameserversWhitelist.isEmpty() && count == 0) {
throw new NameserversNotSpecifiedForTldWithNameserverWhitelistException(
if (!tldNameserversAllowList.isEmpty() && count == 0) {
throw new NameserversNotSpecifiedForTldWithNameserverAllowListException(
domainName.toString());
}
if (count > MAX_NAMESERVERS_PER_DOMAIN) {
@@ -398,21 +398,21 @@ public class DomainFlowUtils {
static void validateRegistrantAllowedOnTld(String tld, String registrantContactId)
throws RegistrantNotAllowedException {
ImmutableSet<String> whitelist = Registry.get(tld).getAllowedRegistrantContactIds();
// Empty whitelist or null registrantContactId are ignored.
ImmutableSet<String> allowedRegistrants = Registry.get(tld).getAllowedRegistrantContactIds();
// Empty allow list or null registrantContactId are ignored.
if (registrantContactId != null
&& !whitelist.isEmpty()
&& !whitelist.contains(registrantContactId)) {
&& !allowedRegistrants.isEmpty()
&& !allowedRegistrants.contains(registrantContactId)) {
throw new RegistrantNotAllowedException(registrantContactId);
}
}
static void validateNameserversAllowedOnTld(String tld, Set<String> fullyQualifiedHostNames)
throws EppException {
ImmutableSet<String> whitelist = Registry.get(tld).getAllowedFullyQualifiedHostNames();
ImmutableSet<String> allowedHostNames = Registry.get(tld).getAllowedFullyQualifiedHostNames();
Set<String> hostnames = nullToEmpty(fullyQualifiedHostNames);
if (!whitelist.isEmpty()) { // Empty whitelist is ignored.
Set<String> disallowedNameservers = difference(hostnames, whitelist);
if (!allowedHostNames.isEmpty()) { // Empty allow list is ignored.
Set<String> disallowedNameservers = difference(hostnames, allowedHostNames);
if (!disallowedNameservers.isEmpty()) {
throw new NameserversNotAllowedForTldException(disallowedNameservers);
}
@@ -1383,32 +1383,32 @@ public class DomainFlowUtils {
}
}
/** Registrant is not whitelisted for this TLD. */
/** Registrant is not allow-listed for this TLD. */
public static class RegistrantNotAllowedException extends StatusProhibitsOperationException {
public RegistrantNotAllowedException(String contactId) {
super(String.format("Registrant with id %s is not whitelisted for this TLD", contactId));
super(String.format("Registrant with id %s is not allow-listed for this TLD", contactId));
}
}
/** Nameservers are not whitelisted for this TLD. */
/** Nameservers are not allow-listed for this TLD. */
public static class NameserversNotAllowedForTldException
extends StatusProhibitsOperationException {
public NameserversNotAllowedForTldException(Set<String> fullyQualifiedHostNames) {
super(
String.format(
"Nameservers '%s' are not whitelisted for this TLD",
"Nameservers '%s' are not allow-listed for this TLD",
Joiner.on(',').join(fullyQualifiedHostNames)));
}
}
/** Nameservers not specified for domain on TLD with nameserver whitelist. */
public static class NameserversNotSpecifiedForTldWithNameserverWhitelistException
/** Nameservers not specified for domain on TLD with nameserver allow list. */
public static class NameserversNotSpecifiedForTldWithNameserverAllowListException
extends StatusProhibitsOperationException {
public NameserversNotSpecifiedForTldWithNameserverWhitelistException(String domain) {
public NameserversNotSpecifiedForTldWithNameserverAllowListException(String domain) {
super(
String.format(
"At least one nameserver must be specified for domain %s"
+ " on a TLD with nameserver whitelist",
+ " on a TLD with nameserver allow list",
domain));
}
}
@@ -118,12 +118,9 @@ public final class DomainInfoFlow implements Flow {
infoBuilder
.setStatusValues(domain.getStatusValues())
.setContacts(loadForeignKeyedDesignatedContacts(domain.getContacts()))
.setNameservers(hostsRequest.requestDelegated()
? domain.loadNameserverHostNames()
: null)
.setSubordinateHosts(hostsRequest.requestSubordinate()
? domain.getSubordinateHosts()
: null)
.setNameservers(hostsRequest.requestDelegated() ? domain.loadNameserverHostNames() : null)
.setSubordinateHosts(
hostsRequest.requestSubordinate() ? domain.getSubordinateHosts() : null)
.setCreationClientId(domain.getCreationClientId())
.setCreationTime(domain.getCreationTime())
.setLastEppUpdateClientId(domain.getLastEppUpdateClientId())
@@ -57,6 +57,7 @@ import google.registry.flows.custom.DomainUpdateFlowCustomLogic.AfterValidationP
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.BeforeSaveParameters;
import google.registry.flows.custom.EntityChanges;
import google.registry.flows.domain.DomainFlowUtils.MissingRegistrantException;
import google.registry.flows.domain.DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverAllowListException;
import google.registry.model.ImmutableObject;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
@@ -109,7 +110,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.MissingRegistrantException}
* @error {@link DomainFlowUtils.NameserversNotAllowedForTldException}
* @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverWhitelistException}
* @error {@link NameserversNotSpecifiedForTldWithNameserverAllowListException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.SecDnsAllUsageException}
@@ -90,16 +90,17 @@ public final class HostInfoFlow implements Flow {
.setLastTransferTime(host.getLastTransferTime());
}
return responseBuilder
.setResData(hostInfoDataBuilder
.setFullyQualifiedHostName(host.getHostName())
.setRepoId(host.getRepoId())
.setStatusValues(statusValues.build())
.setInetAddresses(host.getInetAddresses())
.setCreationClientId(host.getCreationClientId())
.setCreationTime(host.getCreationTime())
.setLastEppUpdateClientId(host.getLastEppUpdateClientId())
.setLastEppUpdateTime(host.getLastEppUpdateTime())
.build())
.setResData(
hostInfoDataBuilder
.setFullyQualifiedHostName(host.getHostName())
.setRepoId(host.getRepoId())
.setStatusValues(statusValues.build())
.setInetAddresses(host.getInetAddresses())
.setCreationClientId(host.getCreationClientId())
.setCreationTime(host.getCreationTime())
.setLastEppUpdateClientId(host.getLastEppUpdateClientId())
.setLastEppUpdateTime(host.getLastEppUpdateTime())
.build())
.build();
}
}
@@ -175,19 +175,21 @@ public final class HostUpdateFlow implements TransactionalFlow {
newSuperordinateDomain.isPresent()
? newSuperordinateDomain.get().getCurrentSponsorClientId()
: owningResource.getPersistedCurrentSponsorClientId();
HostResource newHost = existingHost.asBuilder()
.setHostName(newHostName)
.addStatusValues(add.getStatusValues())
.removeStatusValues(remove.getStatusValues())
.addInetAddresses(add.getInetAddresses())
.removeInetAddresses(remove.getInetAddresses())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setSuperordinateDomain(newSuperordinateDomainKey)
.setLastSuperordinateChange(lastSuperordinateChange)
.setLastTransferTime(lastTransferTime)
.setPersistedCurrentSponsorClientId(newPersistedClientId)
.build();
HostResource newHost =
existingHost
.asBuilder()
.setHostName(newHostName)
.addStatusValues(add.getStatusValues())
.removeStatusValues(remove.getStatusValues())
.addInetAddresses(add.getInetAddresses())
.removeInetAddresses(remove.getInetAddresses())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
.setSuperordinateDomain(newSuperordinateDomainKey)
.setLastSuperordinateChange(lastSuperordinateChange)
.setLastTransferTime(lastTransferTime)
.setPersistedCurrentSponsorClientId(newPersistedClientId)
.build();
verifyHasIpsIffIsExternal(command, existingHost, newHost);
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
entitiesToSave.add(newHost);
@@ -57,17 +57,17 @@ import org.joda.time.Duration;
* <p>This includes the TLDs (Registries), Registrars, and the RegistrarContacts that can access the
* web console.
*
* This class is basically a "builder" for the parameters needed to generate the OT&amp;E entities.
* Nothing is created until you call {@link #buildAndPersist}.
* <p>This class is basically a "builder" for the parameters needed to generate the OT&amp;E
* entities. Nothing is created until you call {@link #buildAndPersist}.
*
* Usage example:
* <p>Usage example:
*
* <pre> {@code
* <pre>{@code
* OteAccountBuilder.forClientId("example")
* .addContact("contact@email.com") // OPTIONAL
* .setPassword("password") // OPTIONAL
* .setCertificateHash(certificateHash) // OPTIONAL
* .setIpWhitelist(ImmutableList.of("1.1.1.1", "2.2.2.0/24")) // OPTIONAL
* .setIpAllowList(ImmutableList.of("1.1.1.1", "2.2.2.0/24")) // OPTIONAL
* .buildAndPersist();
* }</pre>
*/
@@ -221,11 +221,11 @@ public final class OteAccountBuilder {
return transformRegistrars(builder -> builder.setClientCertificate(asciiCert, now));
}
/** Sets the IP whitelist to all the OT&amp;E Registrars. */
public OteAccountBuilder setIpWhitelist(Collection<String> ipWhitelist) {
ImmutableList<CidrAddressBlock> ipAddressWhitelist =
ipWhitelist.stream().map(CidrAddressBlock::create).collect(toImmutableList());
return transformRegistrars(builder -> builder.setIpAddressWhitelist(ipAddressWhitelist));
/** Sets the IP allow list to all the OT&amp;E Registrars. */
public OteAccountBuilder setIpAllowList(Collection<String> ipAllowList) {
ImmutableList<CidrAddressBlock> ipAddressAllowList =
ipAllowList.stream().map(CidrAddressBlock::create).collect(toImmutableList());
return transformRegistrars(builder -> builder.setIpAddressAllowList(ipAddressAllowList));
}
/**
@@ -139,7 +139,8 @@ public class DomainBase extends EppResource
*/
// TODO(b/158858642): Rename this to domainName when we are off Datastore
@Column(name = "domainName")
@Index String fullyQualifiedDomainName;
@Index
String fullyQualifiedDomainName;
/** The top level domain this is under, dernormalized from {@link #fullyQualifiedDomainName}. */
@Index
@@ -680,8 +681,7 @@ public class DomainBase extends EppResource
removeStatusValue(StatusValue.INACTIVE);
}
checkArgumentNotNull(
emptyToNull(instance.fullyQualifiedDomainName), "Missing domainName");
checkArgumentNotNull(emptyToNull(instance.fullyQualifiedDomainName), "Missing domainName");
if (instance.getRegistrant() == null
&& instance.allContacts.stream().anyMatch(IS_REGISTRANT)) {
throw new IllegalArgumentException("registrant is null but is in allContacts");
@@ -128,7 +128,7 @@ public enum StatusValue implements EppEnum {
/** Enum to help clearly list which resource types a status value is allowed to be present on. */
private enum AllowedOn {
ALL(ContactResource.class, DomainBase.class, HostBase.class, HostResource.class),
ALL(ContactResource.class, DomainBase.class, HostBase.class, HostResource.class),
NONE,
DOMAINS(DomainBase.class);
@@ -296,7 +296,9 @@ public class Registrar extends ImmutableObject
/** Base64 encoded SHA256 hash of {@link #failoverClientCertificate}. */
String failoverClientCertificateHash;
/** A whitelist of netmasks (in CIDR notation) which the client is allowed to connect from. */
/** An allow list of netmasks (in CIDR notation) which the client is allowed to connect from. */
// TODO: Rename to ipAddressAllowList once Cloud SQL migration is complete.
@Column(name = "ip_address_allow_list")
List<CidrAddressBlock> ipAddressWhitelist;
/** A hashed password for EPP access. The hash is a base64 encoded SHA256 string. */
@@ -553,7 +555,7 @@ public class Registrar extends ImmutableObject
return failoverClientCertificateHash;
}
public ImmutableList<CidrAddressBlock> getIpAddressWhitelist() {
public ImmutableList<CidrAddressBlock> getIpAddressAllowList() {
return nullToEmptyImmutableCopy(ipAddressWhitelist);
}
@@ -674,7 +676,7 @@ public class Registrar extends ImmutableObject
.put("phoneNumber", phoneNumber)
.put("phonePasscode", phonePasscode)
.putListOfStrings("allowedTlds", getAllowedTlds())
.putListOfStrings("ipAddressWhitelist", ipAddressWhitelist)
.putListOfStrings("ipAddressAllowList", getIpAddressAllowList())
.putListOfJsonObjects("contacts", getContacts())
.put("registryLockAllowed", registryLockAllowed)
.build();
@@ -853,8 +855,8 @@ public class Registrar extends ImmutableObject
return this;
}
public Builder setIpAddressWhitelist(Iterable<CidrAddressBlock> ipAddressWhitelist) {
getInstance().ipAddressWhitelist = ImmutableList.copyOf(ipAddressWhitelist);
public Builder setIpAddressAllowList(Iterable<CidrAddressBlock> ipAddressAllowList) {
getInstance().ipAddressWhitelist = ImmutableList.copyOf(ipAddressAllowList);
return this;
}
@@ -431,10 +431,10 @@ public class Registry extends ImmutableObject implements Buildable {
/** The end of the claims period (at or after this time, claims no longer applies). */
DateTime claimsPeriodEnd = END_OF_TIME;
/** A whitelist of clients allowed to be used on domains on this TLD (ignored if empty). */
/** An allow list of clients allowed to be used on domains on this TLD (ignored if empty). */
Set<String> allowedRegistrantContactIds;
/** A whitelist of hosts allowed to be used on domains on this TLD (ignored if empty). */
/** An allow list of hosts allowed to be used on domains on this TLD (ignored if empty). */
Set<String> allowedFullyQualifiedHostNames;
public String getTldStr() {
@@ -424,8 +424,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
// and fetch all domains, to make sure that we can return the first domains in alphabetical
// order.
ImmutableSortedSet.Builder<DomainBase> domainSetBuilder =
ImmutableSortedSet.orderedBy(
Comparator.comparing(DomainBase::getDomainName));
ImmutableSortedSet.orderedBy(Comparator.comparing(DomainBase::getDomainName));
int numHostKeysSearched = 0;
for (List<VKey<HostResource>> chunk : Iterables.partition(hostKeys, 30)) {
numHostKeysSearched += chunk.size();
@@ -444,8 +443,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
Stream<DomainBase> stream = Streams.stream(query).filter(domain -> isAuthorized(domain));
if (cursorString.isPresent()) {
stream =
stream.filter(
domain -> (domain.getDomainName().compareTo(cursorString.get()) > 0));
stream.filter(domain -> (domain.getDomainName().compareTo(cursorString.get()) > 0));
}
stream.forEach(domainSetBuilder::add);
}
@@ -313,9 +313,7 @@ public class RdapJsonFormatter {
// RDAP Technical Implementation Guide 3.2: must have link to the registrar's RDAP URL for this
// domain, with rel=related.
for (String registrarRdapBase : registrar.getRdapBaseUrls()) {
String href =
makeServerRelativeUrl(
registrarRdapBase, "domain", domainBase.getDomainName());
String href = makeServerRelativeUrl(registrarRdapBase, "domain", domainBase.getDomainName());
builder
.linksBuilder()
.add(
@@ -409,9 +407,7 @@ public class RdapJsonFormatter {
*/
RdapNameserver createRdapNameserver(HostResource hostResource, OutputDataType outputDataType) {
RdapNameserver.Builder builder = RdapNameserver.builder();
builder
.linksBuilder()
.add(makeSelfLink("nameserver", hostResource.getHostName()));
builder.linksBuilder().add(makeSelfLink("nameserver", hostResource.getHostName()));
if (outputDataType != OutputDataType.FULL) {
builder.remarksBuilder().add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
}
@@ -269,10 +269,7 @@ public class RdapNameserverSearchAction extends RdapSearchActionBase {
Optional<String> newCursor = Optional.empty();
for (HostResource host : Iterables.limit(hosts, rdapResultSetMaxSize)) {
newCursor =
Optional.of(
(cursorType == CursorType.NAME)
? host.getHostName()
: host.getRepoId());
Optional.of((cursorType == CursorType.NAME) ? host.getHostName() : host.getRepoId());
builder
.nameserverSearchResultsBuilder()
.add(rdapJsonFormatter.createRdapNameserver(host, outputDataType));
@@ -60,7 +60,7 @@ import javax.inject.Inject;
* <p>It is a "login/query/logout" system where you login using the ICANN Reporting credentials, get
* a cookie you then send to get the list and finally logout.
*
* <p>For clarity, this is how one would contact this endpoint "manually", from a whitelisted IP
* <p>For clarity, this is how one would contact this endpoint "manually", from an allow-listed IP
* server:
*
* <p>$ curl [base]/login -I --user [tld]_ry:[password]
@@ -266,15 +266,15 @@ public final class IcannReportingUploadAction implements Runnable {
private static final String ICANN_UPLOAD_PERMANENT_ERROR_MESSAGE =
"A report for that month already exists, the cut-off date already passed";
/** Don't retry when the IP address isn't whitelisted, as retries go through the same IP. */
private static final Pattern ICANN_UPLOAD_WHITELIST_ERROR =
/** Don't retry when the IP address isn't allow-listed, as retries go through the same IP. */
private static final Pattern ICANN_UPLOAD_ALLOW_LIST_ERROR =
Pattern.compile("Your IP address .+ is not allowed to connect");
/** Predicate to retry uploads on IOException, so long as they aren't non-retryable errors. */
private static boolean isUploadFailureRetryable(Throwable e) {
return (e instanceof IOException)
&& !e.getMessage().contains(ICANN_UPLOAD_PERMANENT_ERROR_MESSAGE)
&& !ICANN_UPLOAD_WHITELIST_ERROR.matcher(e.getMessage()).matches();
&& !ICANN_UPLOAD_ALLOW_LIST_ERROR.matcher(e.getMessage()).matches();
}
private void emailUploadResults(ImmutableMap<String, Boolean> reportSummary) {
@@ -59,13 +59,11 @@ public enum Auth {
/**
* Allows anyone access, as long as they use OAuth to authenticate.
*
* Also allows access from App Engine task-queue. Note that OAuth client ID still needs to be
* whitelisted in the config file for OAuth-based authentication to succeed.
* <p>Also allows access from App Engine task-queue. Note that OAuth client ID still needs to be
* allow-listed in the config file for OAuth-based authentication to succeed.
*/
AUTH_PUBLIC_OR_INTERNAL(
ImmutableList.of(AuthMethod.INTERNAL, AuthMethod.API),
AuthLevel.APP,
UserPolicy.PUBLIC),
ImmutableList.of(AuthMethod.INTERNAL, AuthMethod.API), AuthLevel.APP, UserPolicy.PUBLIC),
/**
* Allows only admins or App Engine task-queue access.
@@ -153,9 +153,9 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
Path failoverClientCertificateFilename;
@Parameter(
names = "--ip_whitelist",
description = "Comma-delimited list of IP ranges. An empty string clears the whitelist.")
List<String> ipWhitelist = new ArrayList<>();
names = "--ip_allow_list",
description = "Comma-delimited list of IP ranges. An empty string clears the allow list.")
List<String> ipAllowList = new ArrayList<>();
@Nullable
@Parameter(
@@ -343,16 +343,16 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
}
builder.setAllowedTlds(allowedTldsBuilder.build());
}
if (!ipWhitelist.isEmpty()) {
ImmutableList.Builder<CidrAddressBlock> ipWhitelistBuilder = new ImmutableList.Builder<>();
if (!(ipWhitelist.size() == 1 && ipWhitelist.get(0).contains("null"))) {
for (String ipRange : ipWhitelist) {
if (!ipAllowList.isEmpty()) {
ImmutableList.Builder<CidrAddressBlock> ipAllowListBuilder = new ImmutableList.Builder<>();
if (!(ipAllowList.size() == 1 && ipAllowList.get(0).contains("null"))) {
for (String ipRange : ipAllowList) {
if (!ipRange.isEmpty()) {
ipWhitelistBuilder.add(CidrAddressBlock.create(ipRange));
ipAllowListBuilder.add(CidrAddressBlock.create(ipRange));
}
}
}
builder.setIpAddressWhitelist(ipWhitelistBuilder.build());
builder.setIpAddressAllowList(ipAllowListBuilder.build());
}
if (clientCertificateFilename != null) {
String asciiCert = new String(Files.readAllBytes(clientCertificateFilename), US_ASCII);
@@ -127,9 +127,8 @@ final class GenerateDnsReportCommand implements CommandWithRemoteApi {
.map(InetAddress::getHostAddress)
.sorted()
.collect(toImmutableList());
ImmutableMap<String, ?> map = ImmutableMap.of(
"host", nameserver.getHostName(),
"ips", ipAddresses);
ImmutableMap<String, ?> map =
ImmutableMap.of("host", nameserver.getHostName(), "ips", ipAddresses);
writeJson(map);
}
@@ -46,10 +46,10 @@ final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemo
private String registrar;
@Parameter(
names = {"-w", "--ip_whitelist"},
names = {"-a", "--ip_allow_list"},
description = "Comma-separated list of IP addreses or CIDR ranges.",
required = true)
private List<String> ipWhitelist = new ArrayList<>();
private List<String> ipAllowList = new ArrayList<>();
@Parameter(
names = {"--email"},
@@ -98,7 +98,7 @@ final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemo
OteAccountBuilder.forClientId(registrar)
.addContact(email)
.setPassword(password)
.setIpWhitelist(ipWhitelist)
.setIpAllowList(ipAllowList)
.setReplaceExisting(overwrite);
if (certFile != null) {
@@ -183,8 +183,7 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand {
+ "to make updates, and if so, use the domain_unlock command to enable updates.",
domain);
if (!nameservers.isEmpty()) {
ImmutableSortedSet<String> existingNameservers =
domainBase.loadNameserverHostNames();
ImmutableSortedSet<String> existingNameservers = domainBase.loadNameserverHostNames();
populateAddRemoveLists(
ImmutableSet.copyOf(nameservers),
existingNameservers,
@@ -83,9 +83,7 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
lockedDomains =
jpaTm().transact(() -> getLockedDomainsWithoutLocks(jpaTm().getTransactionTime()));
ImmutableList<String> lockedDomainNames =
lockedDomains.stream()
.map(DomainBase::getDomainName)
.collect(toImmutableList());
lockedDomains.stream().map(DomainBase::getDomainName).collect(toImmutableList());
return String.format(
"Locked domains for which there does not exist a RegistryLock object: %s",
lockedDomainNames);
@@ -112,8 +110,7 @@ public class BackfillRegistryLocksCommand extends ConfirmingCommand
.build());
} catch (Throwable t) {
logger.atSevere().withCause(t).log(
"Error when creating lock object for domain %s.",
domainBase.getDomainName());
"Error when creating lock object for domain %s.", domainBase.getDomainName());
failedDomainsBuilder.add(domainBase);
}
}
@@ -73,10 +73,12 @@ public class RemoveIpAddressCommand extends MutatingEppToolCommand {
// Build and execute the EPP command.
setSoyTemplate(
RemoveIpAddressSoyInfo.getInstance(), RemoveIpAddressSoyInfo.REMOVE_IP_ADDRESS);
addSoyRecord(registrarId, new SoyMapData(
"name", host.getHostName(),
"ipAddresses", ipAddresses,
"requestedByRegistrar", registrarId));
addSoyRecord(
registrarId,
new SoyMapData(
"name", host.getHostName(),
"ipAddresses", ipAddresses,
"requestedByRegistrar", registrarId));
}
}
}
@@ -284,12 +284,13 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
StringBuilder result = new StringBuilder();
String domainLabel = stripTld(domain.getDomainName(), domain.getTld());
for (HostResource nameserver : tm().load(domain.getNameservers())) {
result.append(String.format(
NS_FORMAT,
domainLabel,
dnsDefaultNsTtl.getStandardSeconds(),
// Load the nameservers at the export time in case they've been renamed or deleted.
loadAtPointInTime(nameserver, exportTime).now().getHostName()));
result.append(
String.format(
NS_FORMAT,
domainLabel,
dnsDefaultNsTtl.getStandardSeconds(),
// Load the nameservers at the export time in case they've been renamed or deleted.
loadAtPointInTime(nameserver, exportTime).now().getHostName()));
}
for (DelegationSignerData dsData : domain.getDsData()) {
result.append(
@@ -319,12 +320,13 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
for (InetAddress addr : host.getInetAddresses()) {
// must be either IPv4 or IPv6
String rrSetClass = (addr instanceof Inet4Address) ? "A" : "AAAA";
result.append(String.format(
A_FORMAT,
stripTld(host.getHostName(), tld),
dnsDefaultATtl.getStandardSeconds(),
rrSetClass,
addr.getHostAddress()));
result.append(
String.format(
A_FORMAT,
stripTld(host.getHostName(), tld),
dnsDefaultATtl.getStandardSeconds(),
rrSetClass,
addr.getHostAddress()));
}
return result.toString();
}
@@ -158,8 +158,8 @@ public final class RegistrarFormFields {
FormFields.MIN_TOKEN.asBuilderNamed("url")
.build();
public static final FormField<List<String>, List<CidrAddressBlock>> IP_ADDRESS_WHITELIST_FIELD =
FormField.named("ipAddressWhitelist")
public static final FormField<List<String>, List<CidrAddressBlock>> IP_ADDRESS_ALLOW_LIST_FIELD =
FormField.named("ipAddressAllowList")
.emptyToNull()
.transform(CidrAddressBlock.class, RegistrarFormFields::parseCidr)
.asList()
@@ -302,8 +302,8 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
RegistrarFormFields.L10N_ADDRESS_FIELD.extractUntyped(args).orElse(null));
// Security
builder.setIpAddressWhitelist(
RegistrarFormFields.IP_ADDRESS_WHITELIST_FIELD
builder.setIpAddressAllowList(
RegistrarFormFields.IP_ADDRESS_ALLOW_LIST_FIELD
.extractUntyped(args)
.orElse(ImmutableList.of()));
RegistrarFormFields.CLIENT_CERTIFICATE_FIELD
@@ -88,9 +88,7 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
.findFirst();
return WhoisResponseResults.create(
new DomainEmitter()
.emitField(
"Domain Name",
maybeFormatHostname(domain.getDomainName(), preferUnicode))
.emitField("Domain Name", maybeFormatHostname(domain.getDomainName(), preferUnicode))
.emitField("Registry Domain ID", domain.getRepoId())
.emitField("Registrar WHOIS Server", registrar.getWhoisServer())
.emitField("Registrar URL", registrar.getUrl())
@@ -51,8 +51,7 @@ final class NameserverLookupByIpCommand implements WhoisCommand {
Streams.stream(queryNotDeleted(HostResource.class, now, "inetAddresses", ipAddress))
.filter(
host ->
Registries.findTldForName(
InternetDomainName.from(host.getHostName()))
Registries.findTldForName(InternetDomainName.from(host.getHostName()))
.isPresent())
.collect(toImmutableList());
if (hosts.isEmpty()) {
@@ -56,8 +56,7 @@ final class NameserverWhoisResponse extends WhoisResponseImpl {
Optional<Registrar> registrar = Registrar.loadByClientIdCached(clientId);
checkState(registrar.isPresent(), "Could not load registrar %s", clientId);
emitter
.emitField(
"Server Name", maybeFormatHostname(host.getHostName(), preferUnicode))
.emitField("Server Name", maybeFormatHostname(host.getHostName(), preferUnicode))
.emitSet("IP Address", host.getInetAddresses(), InetAddresses::toAddrString)
.emitField("Registrar", registrar.get().getRegistrarName())
.emitField("Registrar WHOIS Server", registrar.get().getWhoisServer())
@@ -140,7 +140,7 @@ registry.json.Response.prototype.results;
* driveFolderId: string?,
* ianaIdentifier: (number?|undefined),
* icannReferralEmail: string,
* ipAddressWhitelist: !Array<string>,
* ipAddressAllowList: !Array<string>,
* emailAddress: (string?|undefined),
* lastUpdateTime: string,
* url: (string?|undefined),
@@ -64,8 +64,8 @@ registry.registrar.SecuritySettings.prototype.setupEditor =
goog.events.EventType.CLICK,
goog.bind(this.onIpRemove_, this, remBtn));
}, this);
this.typeCounts['reg-ips'] = objArgs.ipAddressWhitelist ?
objArgs.ipAddressWhitelist.length : 0;
this.typeCounts['reg-ips'] = objArgs.ipAddressAllowList ?
objArgs.ipAddressAllowList.length : 0;
goog.events.listen(goog.dom.getRequiredElement('btn-add-ip'),
goog.events.EventType.CLICK,
@@ -82,7 +82,7 @@ registry.registrar.SecuritySettings.prototype.setupEditor =
registry.registrar.SecuritySettings.prototype.onIpAdd_ = function() {
var ipInputElt = goog.dom.getRequiredElement('newIp');
var ipElt = goog.soy.renderAsFragment(registry.soy.registrar.security.ip, {
name: 'ipAddressWhitelist[' + this.typeCounts['reg-ips'] + ']',
name: 'ipAddressAllowList[' + this.typeCounts['reg-ips'] + ']',
ip: ipInputElt.value
});
goog.dom.appendChild(goog.dom.getRequiredElement('ips'), ipElt);
+14 -14
View File
@@ -849,7 +849,7 @@ soy.$$escapeHtml = function(value) {
*
* @param {?} value The string-like value to be escaped. May not be a string,
* but the value will be coerced to a string.
* @param {Array<string>=} opt_safeTags Additional tag names to whitelist.
* @param {Array<string>=} opt_safeTags Additional tag names to allow-list.
* @return {!goog.soy.data.SanitizedHtml} A sanitized and normalized version of
* value.
*/
@@ -858,15 +858,15 @@ soy.$$cleanHtml = function(value, opt_safeTags) {
goog.asserts.assert(value.constructor === goog.soy.data.SanitizedHtml);
return /** @type {!goog.soy.data.SanitizedHtml} */ (value);
}
var tagWhitelist;
var tagAllowList;
if (opt_safeTags) {
tagWhitelist = goog.object.createSet(opt_safeTags);
goog.object.extend(tagWhitelist, soy.esc.$$SAFE_TAG_WHITELIST_);
tagAllowList = goog.object.createSet(opt_safeTags);
goog.object.extend(tagAllowList, soy.esc.$$SAFE_TAG_ALLOW_LIST_);
} else {
tagWhitelist = soy.esc.$$SAFE_TAG_WHITELIST_;
tagAllowList = soy.esc.$$SAFE_TAG_ALLOW_LIST_;
}
return soydata.VERY_UNSAFE.ordainSanitizedHtml(
soy.$$stripHtmlTags(value, tagWhitelist), soydata.getContentDir(value));
soy.$$stripHtmlTags(value, tagAllowList), soydata.getContentDir(value));
};
@@ -925,19 +925,19 @@ soy.$$HTML5_VOID_ELEMENTS_ = new RegExp(
/**
* Removes HTML tags from a string of known safe HTML.
* If opt_tagWhitelist is not specified or is empty, then
* If opt_tagAllowList is not specified or is empty, then
* the result can be used as an attribute value.
*
* @param {*} value The HTML to be escaped. May not be a string, but the
* value will be coerced to a string.
* @param {Object<string, boolean>=} opt_tagWhitelist Has an own property whose
* @param {Object<string, boolean>=} opt_tagAllowList Has an own property whose
* name is a lower-case tag name and whose value is `1` for
* each element that is allowed in the output.
* @return {string} A representation of value without disallowed tags,
* HTML comments, or other non-text content.
*/
soy.$$stripHtmlTags = function(value, opt_tagWhitelist) {
if (!opt_tagWhitelist) {
soy.$$stripHtmlTags = function(value, opt_tagAllowList) {
if (!opt_tagAllowList) {
// If we have no white-list, then use a fast track which elides all tags.
return String(value)
.replace(soy.esc.$$HTML_TAG_REGEX_, '')
@@ -952,7 +952,7 @@ soy.$$stripHtmlTags = function(value, opt_tagWhitelist) {
// have been removed.
var html = String(value).replace(/\[/g, '&#91;');
// Consider all uses of '<' and replace whitelisted tags with markers like
// Consider all uses of '<' and replace allow-listed tags with markers like
// [1] which are indices into a list of approved tag names.
// Replace all other uses of < and > with entities.
var tags = [];
@@ -960,8 +960,8 @@ soy.$$stripHtmlTags = function(value, opt_tagWhitelist) {
html = html.replace(soy.esc.$$HTML_TAG_REGEX_, function(tok, tagName) {
if (tagName) {
tagName = tagName.toLowerCase();
if (opt_tagWhitelist.hasOwnProperty(tagName) &&
opt_tagWhitelist[tagName]) {
if (opt_tagAllowList.hasOwnProperty(tagName) &&
opt_tagAllowList[tagName]) {
var isClose = tok.charAt(1) == '/';
var index = tags.length;
var start = '</';
@@ -2433,7 +2433,7 @@ soy.esc.$$LT_REGEX_ = /</g;
*
* @private {!Object<string, boolean>}
*/
soy.esc.$$SAFE_TAG_WHITELIST_ = {
soy.esc.$$SAFE_TAG_ALLOW_LIST_ = {
'b': true,
'br': true,
'em': true,
@@ -89,7 +89,7 @@
</td>
</table>
Gave <label>{$contactEmail}</label> web-console access to these registrars.
<h1>Don't forget to set the <label>Certificate</label> and <label>IP-whitelist</label> for these Registrars!</h1>
<h1>Don't forget to set the <label>Certificate</label> and <label>IP allow list</label> for these Registrars!</h1>
Links to the security page for your convenience:<br>
{for $clientId in mapKeys($clientIdToTld)}
<a href="/registrar?clientId={$clientId}#security-settings" target="_blank">{$clientId}</a><br>
@@ -132,7 +132,7 @@
<a href="/registrar?clientId={$clientId}#whois-settings" target="_blank">WHOIS page</a>
<li>allowed TLDs on the {sp}
<a href="/registrar?clientId={$clientId}#admin-settings" target="_blank">admin page</a>
<li>certificate, IP whitelist on the {sp}
<li>certificate, IP allow list on the {sp}
<a href="/registrar?clientId={$clientId}#security-settings" target="_blank">security page</a>
</ol>
</span>
@@ -17,7 +17,7 @@
/** Registrar security settings page for view and edit. */
{template .settings}
{@param ipAddressWhitelist: list<string>}
{@param ipAddressAllowList: list<string>}
{@param? phonePasscode: string}
{@param? clientCertificate: string}
{@param? clientCertificateHash: string}
@@ -36,7 +36,7 @@
<tr class="{css('kd-settings-pane-section')}">
<td>
<label class="{css('setting-label')}">IP whitelist</label>
<label class="{css('setting-label')}">IP allow list</label>
<span class="{css('description')}">Restrict access to EPP
production servers to the following IP/IPv6 addresses, or
ranges like 1.1.1.0/24</span>
@@ -44,9 +44,9 @@
<td class="{css('setting')}">
<div class="{css('info')} {css('summary')}">
<div id="ips">
{for $ip in $ipAddressWhitelist}
{for $ip in $ipAddressAllowList}
{call .ip}
{param name: 'ipAddressWhitelist[' + index($ip) + ']' /}
{param name: 'ipAddressAllowList[' + index($ip) + ']' /}
{param ip: $ip /}
{/call}
{/for}