mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-08 16:18:05 +03:00
Added comment field in HostEntry for end-of-line comments in known_hosts file (#517)
* Added comment field in HostEntry for end-of-line comments in known_hosts file. * Also modified the getLine() method to return the comment, if it exists. * Fixed implementation * Add CODEOWNERS file Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
This commit is contained in:
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
* @hierynomus
|
||||||
|
|
||||||
@@ -199,24 +199,22 @@ public class OpenSSHKnownHosts
|
|||||||
return new CommentEntry(line);
|
return new CommentEntry(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] split = line.split("\\s+");
|
final String trimmed = line.trim();
|
||||||
if(split.length < 3) {
|
int minComponents = 3;
|
||||||
|
if (trimmed.startsWith("@")) {
|
||||||
|
minComponents = 4;
|
||||||
|
}
|
||||||
|
String[] split = trimmed.split("\\s+", minComponents + 1); // Add 1 for optional comments
|
||||||
|
if(split.length < minComponents) {
|
||||||
log.error("Error reading entry `{}`", line);
|
log.error("Error reading entry `{}`", line);
|
||||||
return new BadHostEntry(line);
|
return new BadHostEntry(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (split[i].isEmpty()) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
final Marker marker = Marker.fromString(split[i]);
|
final Marker marker = Marker.fromString(split[i]);
|
||||||
if (marker != null) {
|
if (marker != null) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if(split.length < i + 3) {
|
|
||||||
log.error("Error reading entry `{}`", line);
|
|
||||||
return new BadHostEntry(line);
|
|
||||||
}
|
|
||||||
final String hostnames = split[i++];
|
final String hostnames = split[i++];
|
||||||
final String sType = split[i++];
|
final String sType = split[i++];
|
||||||
|
|
||||||
@@ -234,6 +232,9 @@ public class OpenSSHKnownHosts
|
|||||||
}
|
}
|
||||||
} else if (isBits(sType)) {
|
} else if (isBits(sType)) {
|
||||||
type = KeyType.RSA;
|
type = KeyType.RSA;
|
||||||
|
minComponents += 1;
|
||||||
|
// re-split
|
||||||
|
split = trimmed.split("\\s+", minComponents + 1); // Add 1 for optional comments
|
||||||
// int bits = Integer.valueOf(sType);
|
// int bits = Integer.valueOf(sType);
|
||||||
final BigInteger e = new BigInteger(split[i++]);
|
final BigInteger e = new BigInteger(split[i++]);
|
||||||
final BigInteger n = new BigInteger(split[i++]);
|
final BigInteger n = new BigInteger(split[i++]);
|
||||||
@@ -249,7 +250,13 @@ public class OpenSSHKnownHosts
|
|||||||
return new BadHostEntry(line);
|
return new BadHostEntry(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HostEntry(marker, hostnames, type, key);
|
final String comment;
|
||||||
|
if (i < split.length) {
|
||||||
|
comment = split[i++];
|
||||||
|
} else {
|
||||||
|
comment = null;
|
||||||
|
}
|
||||||
|
return new HostEntry(marker, hostnames, type, key, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBits(String type) {
|
private boolean isBits(String type) {
|
||||||
@@ -330,13 +337,19 @@ public class OpenSSHKnownHosts
|
|||||||
private final String hostPart;
|
private final String hostPart;
|
||||||
protected final KeyType type;
|
protected final KeyType type;
|
||||||
protected final PublicKey key;
|
protected final PublicKey key;
|
||||||
|
private final String comment;
|
||||||
private final KnownHostMatchers.HostMatcher matcher;
|
private final KnownHostMatchers.HostMatcher matcher;
|
||||||
|
|
||||||
public HostEntry(Marker marker, String hostPart, KeyType type, PublicKey key) throws SSHException {
|
public HostEntry(Marker marker, String hostPart, KeyType type, PublicKey key) throws SSHException {
|
||||||
|
this(marker, hostPart, type, key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostEntry(Marker marker, String hostPart, KeyType type, PublicKey key, String comment) throws SSHException {
|
||||||
this.marker = marker;
|
this.marker = marker;
|
||||||
this.hostPart = hostPart;
|
this.hostPart = hostPart;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
this.comment = comment;
|
||||||
this.matcher = KnownHostMatchers.createMatcher(hostPart);
|
this.matcher = KnownHostMatchers.createMatcher(hostPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,6 +386,9 @@ public class OpenSSHKnownHosts
|
|||||||
line.append(getHostPart());
|
line.append(getHostPart());
|
||||||
line.append(" ").append(type.toString());
|
line.append(" ").append(type.toString());
|
||||||
line.append(" ").append(getKeyString(key));
|
line.append(" ").append(getKeyString(key));
|
||||||
|
|
||||||
|
if (!comment.isEmpty()) line.append(" ").append(comment);
|
||||||
|
|
||||||
return line.toString();
|
return line.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,6 +400,10 @@ public class OpenSSHKnownHosts
|
|||||||
protected String getHostPart() {
|
protected String getHostPart() {
|
||||||
return hostPart;
|
return hostPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BadHostEntry implements KnownHostEntry {
|
public static class BadHostEntry implements KnownHostEntry {
|
||||||
|
|||||||
@@ -116,6 +116,36 @@ host1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL
|
|||||||
s << ["\n", "#comment\n"]
|
s << ["\n", "#comment\n"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "should contain comment at end of line"() {
|
||||||
|
given:
|
||||||
|
def f = knownHosts(host)
|
||||||
|
when:
|
||||||
|
OpenSSHKnownHosts knownHosts = new OpenSSHKnownHosts(f)
|
||||||
|
|
||||||
|
then:
|
||||||
|
knownHosts.entries().size() == 1
|
||||||
|
def entry = knownHosts.entries().get(0)
|
||||||
|
entry instanceof OpenSSHKnownHosts.HostEntry
|
||||||
|
entry.comment == comment
|
||||||
|
|
||||||
|
where:
|
||||||
|
host << [
|
||||||
|
"|1|F1E1KeoE/eEWhi10WpGv4OdiO6Y=|3988QV0VE8wmZL7suNrYQLITLCg= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ== this is a comment",
|
||||||
|
"test.com,1.1.1.1 2048 35 22017496617994656680820635966392838863613340434802393112245951008866692373218840197754553998457793202561151141246686162285550121243768846314646395880632789308110750881198697743542374668273149584280424505890648953477691795864456749782348425425954366277600319096366690719901119774784695056100331902394094537054256611668966698242432417382422091372756244612839068092471592121759862971414741954991375710930168229171638843329213652899594987626853020377726482288618521941129157643483558764875338089684351824791983007780922947554898825663693324944982594850256042689880090306493029526546183035567296830604572253312294059766327 single",
|
||||||
|
"schmizz.net,69.163.155.180 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ==",
|
||||||
|
"schmizz.net,69.163.155.180 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ== ",
|
||||||
|
"schmizz.net,69.163.155.180 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ== extra space"
|
||||||
|
]
|
||||||
|
comment << [
|
||||||
|
"this is a comment",
|
||||||
|
"single",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"extra space"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should match any host name from multi-host line"() {
|
def "should match any host name from multi-host line"() {
|
||||||
given:
|
given:
|
||||||
|
|||||||
Reference in New Issue
Block a user