mirror of
https://github.com/google/nomulus.git
synced 2025-05-01 12:37:52 +02:00
The DS records consist of 4 values: - keyTag: unsigned short (2 bytes) - alg: unsigned byte - digestType: unsigned byte - digest: binary hex NOTE: the current CL doesn't support keyData, neither as the optional field in dsData nor as a replacement for dsData The command tool accepts DS records as a string, where the 4 values are given as one string separated by white-spaces as follows: <keyTag> <alg> <digestType> <digest> e.g. something like: 60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A which is how it's written in Zone files, allowing easy copy-paste from existing values. ommas is confusing when using spaces. The various "numbers" (keyTag, alg, digestType) are only checked that they are positive integers - the rest is left for the server. digest it checked to be an even-lengthed hex string. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=184583068
161 lines
5.2 KiB
Java
161 lines
5.2 KiB
Java
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
|
//
|
|
// 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 google.registry.tools;
|
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
import static com.google.common.collect.ImmutableList.toImmutableList;
|
|
import static google.registry.util.CollectionUtils.findDuplicates;
|
|
|
|
import com.beust.jcommander.IStringConverter;
|
|
import com.beust.jcommander.Parameter;
|
|
import com.google.auto.value.AutoValue;
|
|
import com.google.common.base.Ascii;
|
|
import com.google.common.base.CharMatcher;
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.io.BaseEncoding;
|
|
import com.google.template.soy.data.SoyListData;
|
|
import com.google.template.soy.data.SoyMapData;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
/** Shared base class for commands to create or update a Domain via EPP. */
|
|
abstract class CreateOrUpdateDomainCommand extends MutatingEppToolCommand {
|
|
|
|
@Parameter(
|
|
names = {"-c", "--client"},
|
|
description = "Client identifier of the registrar to execute the command as",
|
|
required = true
|
|
)
|
|
String clientId;
|
|
|
|
@Parameter(description = "Names of the domains", required = true)
|
|
private List<String> mainParameters;
|
|
|
|
@Parameter(
|
|
names = {"-n", "--nameservers"},
|
|
description = "Comma-separated list of nameservers, up to 13."
|
|
)
|
|
List<String> nameservers = new ArrayList<>();
|
|
|
|
@Parameter(
|
|
names = {"-r", "--registrant"},
|
|
description = "Domain registrant."
|
|
)
|
|
String registrant;
|
|
|
|
@Parameter(
|
|
names = {"-a", "--admins"},
|
|
description = "Comma-separated list of admin contacts."
|
|
)
|
|
List<String> admins = new ArrayList<>();
|
|
|
|
@Parameter(
|
|
names = {"-t", "--techs"},
|
|
description = "Comma-separated list of technical contacts."
|
|
)
|
|
List<String> techs = new ArrayList<>();
|
|
|
|
@Parameter(
|
|
names = {"-p", "--password"},
|
|
description = "Password."
|
|
)
|
|
String password;
|
|
|
|
@Parameter(
|
|
names = "--ds_records",
|
|
description =
|
|
"Comma-separated list of DS records. Each DS record is given as "
|
|
+ "<keyTag> <alg> <digestType> <digest>, in order, as it appears in the Zonefile.",
|
|
converter = DsRecordConverter.class
|
|
)
|
|
List<DsRecord> dsRecords = new ArrayList<>();
|
|
|
|
Set<String> domains;
|
|
|
|
@AutoValue
|
|
abstract static class DsRecord {
|
|
private static final Splitter SPLITTER =
|
|
Splitter.on(CharMatcher.whitespace()).omitEmptyStrings();
|
|
|
|
public abstract int keyTag();
|
|
public abstract int alg();
|
|
public abstract int digestType();
|
|
public abstract String digest();
|
|
|
|
private static DsRecord create(int keyTag, int alg, int digestType, String digest) {
|
|
digest = Ascii.toUpperCase(digest);
|
|
checkArgument(
|
|
BaseEncoding.base16().canDecode(digest),
|
|
"digest should be even-lengthed hex, but is %s (length %s)",
|
|
digest,
|
|
digest.length());
|
|
return new AutoValue_CreateOrUpdateDomainCommand_DsRecord(keyTag, alg, digestType, digest);
|
|
}
|
|
|
|
/**
|
|
* Parses a string representation of the DS record.
|
|
*
|
|
* <p>The string format accepted is "[keyTag] [alg] [digestType] [digest]" (i.e., the 4
|
|
* arguments separated by any number of spaces, as it appears in the Zone file)
|
|
*/
|
|
public static DsRecord parse(String dsRecord) {
|
|
List<String> elements = SPLITTER.splitToList(dsRecord);
|
|
checkArgument(
|
|
elements.size() == 4,
|
|
"dsRecord %s should have 4 parts, but has %s",
|
|
dsRecord,
|
|
elements.size());
|
|
return DsRecord.create(
|
|
Integer.parseUnsignedInt(elements.get(0)),
|
|
Integer.parseUnsignedInt(elements.get(1)),
|
|
Integer.parseUnsignedInt(elements.get(2)),
|
|
elements.get(3));
|
|
}
|
|
|
|
public SoyMapData toSoyData() {
|
|
return new SoyMapData(
|
|
"keyTag", keyTag(),
|
|
"alg", alg(),
|
|
"digestType", digestType(),
|
|
"digest", digest());
|
|
}
|
|
|
|
public static SoyListData convertToSoy(List<DsRecord> dsRecords) {
|
|
return new SoyListData(
|
|
dsRecords.stream().map(DsRecord::toSoyData).collect(toImmutableList()));
|
|
}
|
|
}
|
|
|
|
public static class DsRecordConverter implements IStringConverter<DsRecord> {
|
|
@Override
|
|
public DsRecord convert(String dsRecord) {
|
|
return DsRecord.parse(dsRecord);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void initEppToolCommand() throws Exception {
|
|
checkArgument(nameservers.size() <= 13, "There can be at most 13 nameservers.");
|
|
|
|
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
|
|
checkArgument(duplicates.isEmpty(), "Duplicate arguments found: '%s'", duplicates);
|
|
domains = ImmutableSet.copyOf(mainParameters);
|
|
|
|
initMutatingEppToolCommand();
|
|
}
|
|
}
|