commit 895992549b2dd4de3cf7914c00544094b66a6670 Author: Karsten Loesing karsten.loesing@gmx.net Date: Sun Dec 30 19:54:06 2012 +0100
Parse ipv6-policy lines in server descriptors.
Spotted by atager in related ticket #7826. --- .../torproject/descriptor/ServerDescriptor.java | 8 +++ .../descriptor/impl/ServerDescriptorImpl.java | 38 +++++++++++++++- .../descriptor/impl/ServerDescriptorImplTest.java | 49 ++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletions(-)
diff --git a/src/org/torproject/descriptor/ServerDescriptor.java b/src/org/torproject/descriptor/ServerDescriptor.java index 0875eeb..01c3672 100644 --- a/src/org/torproject/descriptor/ServerDescriptor.java +++ b/src/org/torproject/descriptor/ServerDescriptor.java @@ -135,5 +135,13 @@ public interface ServerDescriptor extends Descriptor { /* Return whether this relay allows single-hop circuits to make exit * connections. */ public boolean getAllowSingleHopExits(); + + /* Return the default policy of the IPv6 port summary or null if the + * server descriptor didn't contain an IPv6 port summary line. */ + public String getIpv6DefaultPolicy(); + + /* Return the port list of the IPv6 port summary or null if the server + * descriptor didn't contain an IPv6 port summary line. */ + public String getIpv6PortList(); }
diff --git a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java index 4443284..b25d17a 100644 --- a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java +++ b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java @@ -48,7 +48,7 @@ public class ServerDescriptorImpl extends DescriptorImpl "platform,fingerprint,hibernating,uptime,contact,family," + "read-history,write-history,eventdns,caches-extra-info," + "extra-info-digest,hidden-service-dir,protocols," - + "allow-single-hop-exits,onion-key,signing-key," + + "allow-single-hop-exits,onion-key,signing-key,ipv6-policy," + "router-signature").split(","))); this.checkAtMostOnceKeywords(atMostOnceKeywords); this.checkFirstKeyword("router"); @@ -127,6 +127,8 @@ public class ServerDescriptorImpl extends DescriptorImpl this.parseDircacheportLine(line, lineNoOpt, partsNoOpt); } else if (keyword.equals("router-digest")) { this.parseRouterDigestLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("ipv6-policy")) { + this.parseIpv6PolicyLine(line, lineNoOpt, partsNoOpt); } else if (line.startsWith("-----BEGIN")) { crypto = new StringBuilder(); crypto.append(line + "\n"); @@ -474,6 +476,30 @@ public class ServerDescriptorImpl extends DescriptorImpl line, partsNoOpt[1]); }
+ private void parseIpv6PolicyLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + boolean isValid = true; + if (partsNoOpt.length != 3) { + isValid = false; + } else if (!partsNoOpt[1].equals("accept") && + !partsNoOpt[1].equals("reject")) { + isValid = false; + } else { + this.ipv6DefaultPolicy = partsNoOpt[1]; + this.ipv6PortList = partsNoOpt[2]; + String[] ports = partsNoOpt[2].split(",", -1); + for (int i = 0; i < ports.length; i++) { + if (ports[i].length() < 1) { + isValid = false; + break; + } + } + } + if (!isValid) { + throw new DescriptorParseException("Illegal line '" + line + "'."); + } + } + private void calculateDigest() throws DescriptorParseException { if (this.serverDescriptorDigest != null) { /* We already learned the descriptor digest of this bridge @@ -654,5 +680,15 @@ public class ServerDescriptorImpl extends DescriptorImpl public boolean getAllowSingleHopExits() { return this.allowSingleHopExits; } + + private String ipv6DefaultPolicy; + public String getIpv6DefaultPolicy() { + return this.ipv6DefaultPolicy; + } + + private String ipv6PortList; + public String getIpv6PortList() { + return this.ipv6PortList; + } }
diff --git a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java index ece15fb..a5a7d84 100644 --- a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java +++ b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java @@ -181,6 +181,13 @@ public class ServerDescriptorImplTest { db.allowSingleHopExitsLine = line; return new ServerDescriptorImpl(db.buildDescriptor(), true); } + private String ipv6PolicyLine = null; + private static ServerDescriptor createWithIpv6PolicyLine( + String line) throws DescriptorParseException { + DescriptorBuilder db = new DescriptorBuilder(); + db.ipv6PolicyLine = line; + return new ServerDescriptorImpl(db.buildDescriptor(), true); + } private String routerSignatureLines = "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "o4j+kH8UQfjBwepUnr99v0ebN8RpzHJ/lqYsTojXHy9kMr1RNI9IDeSzA7PSqT" @@ -264,6 +271,9 @@ public class ServerDescriptorImplTest { if (this.allowSingleHopExitsLine != null) { sb.append(this.allowSingleHopExitsLine + "\n"); } + if (this.ipv6PolicyLine != null) { + sb.append(this.ipv6PolicyLine + "\n"); + } if (this.unrecognizedLine != null) { sb.append(this.unrecognizedLine + "\n"); } @@ -1139,6 +1149,45 @@ public class ServerDescriptorImplTest { "allow-single-hop-exits true"); }
+ @Test() + public void testIpv6PolicyLine() throws DescriptorParseException { + ServerDescriptor descriptor = DescriptorBuilder. + createWithIpv6PolicyLine("ipv6-policy accept 80,1194,1220,1293"); + assertEquals("accept", descriptor.getIpv6DefaultPolicy()); + assertEquals("80,1194,1220,1293", descriptor.getIpv6PortList()); + } + + @Test(expected = DescriptorParseException.class) + public void testIpv6PolicyLineNoPolicy() + throws DescriptorParseException { + DescriptorBuilder.createWithIpv6PolicyLine("ipv6-policy 80"); + } + + @Test(expected = DescriptorParseException.class) + public void testIpv6PolicyLineNoPorts() + throws DescriptorParseException { + DescriptorBuilder.createWithIpv6PolicyLine("ipv6-policy accept"); + } + + @Test(expected = DescriptorParseException.class) + public void testIpv6PolicyLineNoPolicyNoPorts() + throws DescriptorParseException { + DescriptorBuilder.createWithIpv6PolicyLine("ipv6-policy "); + } + + @Test(expected = DescriptorParseException.class) + public void testIpv6PolicyLineProject() + throws DescriptorParseException { + DescriptorBuilder.createWithIpv6PolicyLine("ipv6-policy project 80"); + } + + @Test(expected = DescriptorParseException.class) + public void testTwoIpv6PolicyLines() throws DescriptorParseException { + DescriptorBuilder.createWithIpv6PolicyLine( + "ipv6-policy accept 80,1194,1220,1293\n" + + "ipv6-policy accept 80,1194,1220,1293"); + } + @Test(expected = DescriptorParseException.class) public void testUnrecognizedLineFail() throws DescriptorParseException {