commit e7f93e1a6a0a761d4d02295daf622f9e446dcd93
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Fri May 3 15:32:13 2013 +0200
Restrict valid keyword characters to [A-Za-z0-9-]+.
Fixes #8798.
---
.../descriptor/impl/ExtraInfoDescriptorImpl.java | 1 +
.../torproject/descriptor/impl/ParseHelper.java | 11 ++++++
.../descriptor/impl/ServerDescriptorImpl.java | 1 +
.../impl/ExtraInfoDescriptorImplTest.java | 34 ++++++++++++++++++
.../descriptor/impl/ServerDescriptorImplTest.java | 37 ++++++++++++++++++++
5 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index 9bd9a9b..f5bf8ed 100644
--- a/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -183,6 +183,7 @@ public class ExtraInfoDescriptorImpl extends DescriptorImpl
} else if (line.startsWith("-----END")) {
skipCrypto = false;
} else if (!skipCrypto) {
+ ParseHelper.parseKeyword(line, partsNoOpt[0]);
if (this.failUnrecognizedDescriptorLines) {
throw new DescriptorParseException("Unrecognized line '"
+ line + "' in extra-info descriptor.");
diff --git a/src/org/torproject/descriptor/impl/ParseHelper.java b/src/org/torproject/descriptor/impl/ParseHelper.java
index 1b7eff2..4fd776e 100644
--- a/src/org/torproject/descriptor/impl/ParseHelper.java
+++ b/src/org/torproject/descriptor/impl/ParseHelper.java
@@ -17,6 +17,17 @@ import org.apache.commons.codec.binary.Hex;
public class ParseHelper {
+ private static Pattern keywordPattern =
+ Pattern.compile("^[A-Za-z0-9-]+$");
+ public static String parseKeyword(String line, String keyword)
+ throws DescriptorParseException {
+ if (!keywordPattern.matcher(keyword).matches()) {
+ throw new DescriptorParseException("Unrecognized character in "
+ + "keyword '" + keyword + "' in line '" + line + "'.");
+ }
+ return keyword;
+ }
+
private static Pattern ipv4Pattern =
Pattern.compile("^[0-9\\.]{7,15}$");
public static String parseIpv4Address(String line, String address)
diff --git a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index 1fb39f5..baf4456 100644
--- a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -152,6 +152,7 @@ public class ServerDescriptorImpl extends DescriptorImpl
} else if (crypto != null) {
crypto.append(line + "\n");
} else {
+ ParseHelper.parseKeyword(line, partsNoOpt[0]);
if (this.failUnrecognizedDescriptorLines) {
throw new DescriptorParseException("Unrecognized line '"
+ line + "' in server descriptor.");
diff --git a/test/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java b/test/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
index 569ce06..11b07b2 100644
--- a/test/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
+++ b/test/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
@@ -7,6 +7,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -142,6 +144,15 @@ public class ExtraInfoDescriptorImplTest {
return new ExtraInfoDescriptorImpl(db.buildDescriptor(),
failUnrecognizedDescriptorLines);
}
+ private byte[] nonAsciiLineBytes = null;
+ private static ExtraInfoDescriptor createWithNonAsciiLineBytes(
+ byte[] lineBytes, boolean failUnrecognizedDescriptorLines)
+ throws DescriptorParseException {
+ DescriptorBuilder db = new DescriptorBuilder();
+ db.nonAsciiLineBytes = lineBytes;
+ return new ExtraInfoDescriptorImpl(db.buildDescriptor(),
+ failUnrecognizedDescriptorLines);
+ }
private String routerSignatureLines = "router-signature\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "o4j+kH8UQfjBwepUnr99v0ebN8RpzHJ/lqYsTojXHy9kMr1RNI9IDeSzA7PSqT"
@@ -204,6 +215,20 @@ public class ExtraInfoDescriptorImplTest {
if (this.unrecognizedLine != null) {
sb.append(this.unrecognizedLine + "\n");
}
+ if (this.nonAsciiLineBytes != null) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ baos.write(sb.toString().getBytes());
+ baos.write(this.nonAsciiLineBytes);
+ baos.write("\n".getBytes());
+ if (this.routerSignatureLines != null) {
+ baos.write(this.routerSignatureLines.getBytes());
+ }
+ return baos.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
if (this.routerSignatureLines != null) {
sb.append(this.routerSignatureLines + "\n");
}
@@ -1304,6 +1329,15 @@ public class ExtraInfoDescriptorImplTest {
}
@Test(expected = DescriptorParseException.class)
+ public void testBridgeIpsNonAsciiKeyword()
+ throws DescriptorParseException {
+ DescriptorBuilder.createWithNonAsciiLineBytes(new byte[] {
+ 0x14, (byte) 0xfe, 0x18, // non-ascii chars
+ 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2d, // "bridge-"
+ 0x69, 0x70, 0x73 }, false); // "ips" (no newline)
+ }
+
+ @Test(expected = DescriptorParseException.class)
public void testBridgeIpVersionsDouble()
throws DescriptorParseException {
BridgeStatsBuilder.createWithBridgeIpVersionsLine(
diff --git a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
index 5bd73af..9eb38ae 100644
--- a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
+++ b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
@@ -8,6 +8,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -216,6 +218,15 @@ public class ServerDescriptorImplTest {
return new ServerDescriptorImpl(db.buildDescriptor(),
failUnrecognizedDescriptorLines);
}
+ private byte[] nonAsciiLineBytes = null;
+ private static ServerDescriptor createWithNonAsciiLineBytes(
+ byte[] lineBytes, boolean failUnrecognizedDescriptorLines)
+ throws DescriptorParseException {
+ DescriptorBuilder db = new DescriptorBuilder();
+ db.nonAsciiLineBytes = lineBytes;
+ return new ServerDescriptorImpl(db.buildDescriptor(),
+ failUnrecognizedDescriptorLines);
+ }
private byte[] buildDescriptor() {
StringBuilder sb = new StringBuilder();
if (this.routerLine != null) {
@@ -287,6 +298,20 @@ public class ServerDescriptorImplTest {
if (this.unrecognizedLine != null) {
sb.append(this.unrecognizedLine + "\n");
}
+ if (this.nonAsciiLineBytes != null) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ baos.write(sb.toString().getBytes());
+ baos.write(this.nonAsciiLineBytes);
+ baos.write("\n".getBytes());
+ if (this.routerSignatureLines != null) {
+ baos.write(this.routerSignatureLines.getBytes());
+ }
+ return baos.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
if (this.routerSignatureLines != null) {
sb.append(this.routerSignatureLines + "\n");
}
@@ -1159,6 +1184,18 @@ public class ServerDescriptorImplTest {
"allow-single-hop-exits true");
}
+ @Test(expected = DescriptorParseException.class)
+ public void testAllowSingleHopExitsNonAsciiKeyword()
+ throws DescriptorParseException {
+ DescriptorBuilder.createWithNonAsciiLineBytes(new byte[] {
+ 0x14, (byte) 0xfe, 0x18, // non-ascii chars
+ 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x2d, // "allow-"
+ 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x2d, // "single-"
+ 0x68, 0x6f, 0x70, 0x2d, // "hop-"
+ 0x65, 0x78, 0x69, 0x74, 0x73 }, // "exits" (no newline)
+ false);
+ }
+
@Test()
public void testIpv6PolicyLine() throws DescriptorParseException {
ServerDescriptor descriptor = DescriptorBuilder.