diff --git a/pom.xml b/pom.xml
index 74a4c9202..c700fc5be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@ along with DependencyCheck. If not, see .
DependencyCheck
https://github.com/jeremylong/DependencyCheck.git
DependencyCheck is a utility that attempts to detect publically disclosed vulnerabilities contained within project dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.
+ 2012
Jeremy Long
@@ -49,6 +50,10 @@ along with DependencyCheck. If not, see .
https://github.com/jeremylong/DependencyCheck.git
scm:git:git@github.com:jeremylong/DependencyCheck.git
+
+ github
+ https://github.com/jeremylong/DependencyCheck/issues
+
GNU General Public License version 3
@@ -200,10 +205,6 @@ along with DependencyCheck. If not, see .
cve
${project.build.directory}/store/cve
-
- osvdb
- ${project.build.directory}/store/osvdb
-
cpe
${project.build.directory}/store/cpe
@@ -220,7 +221,36 @@ along with DependencyCheck. If not, see .
org.apache.maven.plugins
maven-project-info-reports-plugin
- 2.2
+ 2.5.1
+
+
+
+
+
+ index
+ summary
+ license
+ scm
+ issue-tracking
+ dependencies
+ plugin-management
+ project-team
+
+
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 1.3.1
+
+
+
+ dependency-updates-report
+ plugin-updates-report
+
+
+
org.apache.maven.plugins
@@ -328,25 +358,6 @@ along with DependencyCheck. If not, see .
javadoc
provided
-
- commons-lang
- commons-lang
- 2.6
-
-
- commons-lang
- commons-lang
- 2.6
- javadoc
- provided
-
-
- commons-lang
- commons-lang
- 2.6
- sources
- provided
-
org.apache.commons
commons-io
diff --git a/src/main/java/org/codesecure/dependencycheck/data/LuceneUtils.java b/src/main/java/org/codesecure/dependencycheck/data/LuceneUtils.java
index 25a6a8c7b..93eed5aab 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/LuceneUtils.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/LuceneUtils.java
@@ -67,7 +67,7 @@ public final class LuceneUtils {
case '*':
case '?':
case ':':
- case '\\':
+ case '\\': //it is supposed to fall through here
buf.append('\\');
default:
buf.append(c);
diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java
index 28a5aa544..4acc36e56 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java
@@ -381,7 +381,12 @@ public class CPEQuery {
sb.append("^0.2 ");
}
} else {
- LuceneUtils.appendEscapedLuceneQuery(sb, version);
+ //LuceneUtils.appendEscapedLuceneQuery(sb, version);
+ //if we have a weighting on something else, reduce the weighting on the version a lot
+ for (String v : version.split(" ")) {
+ LuceneUtils.appendEscapedLuceneQuery(sb, v);
+ sb.append("^0.7 ");
+ }
}
sb.append(")");
diff --git a/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java b/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java
index 3e48524f7..19bb138de 100644
--- a/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java
+++ b/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java
@@ -27,6 +27,8 @@ import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
@@ -82,9 +84,7 @@ public class ReportGenerator {
Context context = manager.createContext();
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
config.addDefaultTools();
- config.toolbox("application")
- .tool("esc", "org.apache.velocity.tools.generic.EscapeTool")
- .tool("org.apache.velocity.tools.generic.DateTool");
+ config.toolbox("application").tool("esc", "org.apache.velocity.tools.generic.EscapeTool").tool("org.apache.velocity.tools.generic.DateTool");
manager.configure(config);
@@ -119,12 +119,12 @@ public class ReportGenerator {
try {
writer.close();
} catch (Exception ex) {
- //ignore this error.
+ Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINEST, null, ex);
}
try {
reader.close();
} catch (Exception ex) {
- //ignore this error.
+ Logger.getLogger(ReportGenerator.class.getName()).log(Level.FINEST, null, ex);
}
}
}
diff --git a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
index 55300e2c4..776d1c3e4 100644
--- a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
+++ b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
@@ -145,26 +145,26 @@ public final class CliParser {
@SuppressWarnings("static-access")
private Options createCommandLineOptions() {
Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
- "print this message");
+ "print this message.");
+
+ Option advancedHelp = new Option(ArgumentName.ADVANCED_HELP_SHORT, ArgumentName.ADVANCED_HELP, false,
+ "shows additional help regarding properties file.");
Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
- false, "print the version information and exit");
+ false, "print the version information.");
Option noupdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE,
false, "disables the automatic updating of the CPE data.");
- Option appname = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APPNAME)
- .withDescription("the name of the application being scanned").create(ArgumentName.APPNAME_SHORT);
+ Option appname = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APPNAME).withDescription("the name of the application being scanned.").create(ArgumentName.APPNAME_SHORT);
- Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
- .withDescription("the path to scan - this option can be specified multiple times.")
- .create(ArgumentName.SCAN_SHORT);
+ Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN).withDescription("the path to scan - this option can be specified multiple times.").create(ArgumentName.SCAN_SHORT);
- Option load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE)
- .withDescription("load the CPE xml file").create(ArgumentName.CPE_SHORT);
+ Option load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE).withDescription("load the CPE xml file.").create(ArgumentName.CPE_SHORT);
- Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT)
- .withDescription("the folder to write reports to.").create(ArgumentName.OUT_SHORT);
+ Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP).withDescription("a property file to load.").create(ArgumentName.PROP_SHORT);
+
+ Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT).withDescription("the folder to write reports to.").create(ArgumentName.OUT_SHORT);
//TODO add the ability to load a properties file to override the defaults...
@@ -179,7 +179,8 @@ public final class CliParser {
opts.addOption(version);
opts.addOption(help);
opts.addOption(noupdate);
-
+ opts.addOption(props);
+ opts.addOption(advancedHelp);
return opts;
}
@@ -224,12 +225,28 @@ public final class CliParser {
*/
public void printHelp() {
HelpFormatter formatter = new HelpFormatter();
+ String nl = System.getProperty("line.separator");
+ String advancedHelp = null;
+ if (line.hasOption(ArgumentName.ADVANCED_HELP)) {
+ advancedHelp = nl + nl
+ + "Additionally, the following properties are supported and can be specified either"
+ + "using the -p argument or by passing them in as system properties." + nl
+ + nl + " " + Settings.KEYS.PROXY_URL + "\t\t the proxy URL to use when downloading resources."
+ + nl + " " + Settings.KEYS.PROXY_PORT + "\t\t the proxy port to use when downloading resources."
+ + nl + " " + Settings.KEYS.CONNECTION_TIMEOUT + "\t the cconnection timeout (in milliseconds) to use" + nl + "\t\t\t when downloading resources.";
+ }
+
formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
- "\n" + Settings.getString("application.name", "DependencyCheck")
+ nl + Settings.getString("application.name", "DependencyCheck")
+ " can be used to identify if there are any known CVE vulnerabilities in libraries utillized by an application. "
+ Settings.getString("application.name", "DependencyCheck")
- + " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.\n",
- options, "", true);
+ + " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov." + nl + nl,
+ options,
+ "",
+ true);
+ if (advancedHelp != null) {
+ System.out.println(advancedHelp);
+ }
}
/**
@@ -351,5 +368,21 @@ public final class CliParser {
* The short CLI argument name asking for the version.
*/
public static final String VERSION = "version";
+ /**
+ * The CLI argument name asking for advanced help.
+ */
+ public static final String ADVANCED_HELP_SHORT = "ah";
+ /**
+ * The short CLI argument name asking for advanced help.
+ */
+ public static final String ADVANCED_HELP = "advancedhelp";
+ /**
+ * The short CLI argument name for setting the location of an additional properties file.
+ */
+ public static final String PROP_SHORT = "p";
+ /**
+ * The CLI argument name for setting the location of an additional properties file.
+ */
+ public static final String PROP = "propertyfile";
}
}
diff --git a/src/main/java/org/codesecure/dependencycheck/utils/Settings.java b/src/main/java/org/codesecure/dependencycheck/utils/Settings.java
index c6b3985c2..2c706fb06 100644
--- a/src/main/java/org/codesecure/dependencycheck/utils/Settings.java
+++ b/src/main/java/org/codesecure/dependencycheck/utils/Settings.java
@@ -18,6 +18,8 @@ package org.codesecure.dependencycheck.utils;
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
@@ -52,10 +54,6 @@ public class Settings {
* The properties key for the path where the CCE Lucene Index will be stored.
*/
public static final String CVE_INDEX = "cve";
- /**
- * The properties key for the path where the OSVDB Lucene Index will be stored.
- */
- public static final String OSVDB_INDEX = "osvdb";
/**
* The properties key for the proxy url.
*/
@@ -86,6 +84,44 @@ public class Settings {
}
}
+
+ /**
+ * Sets a property value.
+ * @param key the key for the property.
+ * @param value the value for the property.
+ */
+ public static void setString(String key, String value) {
+ INSTANCE.props.setProperty(key, value);
+ }
+
+ /**
+ * Merges a new properties file into the current properties. This
+ * method allows for the loading of a user provided properties file.
+ * Note: even if using this method - system properties will be loaded before
+ * properties loaded from files.
+ *
+ * @param filePath the path to the properties file to merge.
+ * @throws FileNotFoundException is thrown when the filePath points to a non-existent file.
+ * @throws IOException is thrown when there is an exception loading/merging the properties.
+ */
+ public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
+ FileInputStream fis = new FileInputStream(filePath);
+ mergeProperties(fis);
+ }
+
+ /**
+ * Merges a new properties file into the current properties. This
+ * method allows for the loading of a user provided properties file.
+ * Note: even if using this method - system properties will be loaded before
+ * properties loaded from files.
+ *
+ * @param stream an Input Stream pointing at a properties file to merge.
+ * @throws IOException is thrown when there is an exception loading/merging the properties
+ */
+ public static void mergeProperties(InputStream stream) throws IOException {
+ INSTANCE.props.load(stream);
+ }
+
/**
* Returns a value from the properties file. If the value was specified as a
* system property or passed in via the -Dprop=value argument - this method
@@ -104,15 +140,6 @@ public class Settings {
return str;
}
- /**
- * Sets a property value.
- * @param key the key for the property.
- * @param value the value for the property.
- */
- public static void setString(String key, String value) {
- INSTANCE.props.setProperty(key, value);
- }
-
/**
* Returns a value from the properties file. If the value was specified as a
* system property or passed in via the -Dprop=value argument - this method
@@ -127,7 +154,7 @@ public class Settings {
}
/**
- * Returns a integer value from the properties file. If the value was specified as a
+ * Returns an int value from the properties file. If the value was specified as a
* system property or passed in via the -Dprop=value argument - this method
* will return the value from the system properties before the values in
* the contained configuration file.
@@ -138,6 +165,18 @@ public class Settings {
public static int getInt(String key) {
return Integer.parseInt(Settings.getString(key));
}
+ /**
+ * Returns a long value from the properties file. If the value was specified as a
+ * system property or passed in via the -Dprop=value argument - this method
+ * will return the value from the system properties before the values in
+ * the contained configuration file.
+ *
+ * @param key the key to lookup within the properties file.
+ * @return the property from the properties file.
+ */
+ public static long getLong(String key) {
+ return Long.parseLong(Settings.getString(key));
+ }
/**
* Returns a boolean value from the properties file. If the value was specified as a
diff --git a/src/main/resources/META-INF/dependencycheck.properties b/src/main/resources/META-INF/dependencycheck.properties
index c77202aa4..2076f7d95 100644
--- a/src/main/resources/META-INF/dependencycheck.properties
+++ b/src/main/resources/META-INF/dependencycheck.properties
@@ -5,5 +5,3 @@ cpe=store/cpe
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml.gz
cpe.meta.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.meta
cve=store/cve
-osvdb=store/osvdb
-
diff --git a/src/test/java/org/codesecure/dependencycheck/data/LuceneUtilsTest.java b/src/test/java/org/codesecure/dependencycheck/data/LuceneUtilsTest.java
index f8e4bc3af..ea32fa145 100644
--- a/src/test/java/org/codesecure/dependencycheck/data/LuceneUtilsTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/LuceneUtilsTest.java
@@ -48,7 +48,17 @@ public class LuceneUtilsTest {
LuceneUtils.appendEscapedLuceneQuery(buf, text);
assertEquals(expResult, buf.toString());
}
-
+/**
+ * Test of appendEscapedLuceneQuery method, of class LuceneUtils.
+ */
+ @Test
+ public void testAppendEscapedLuceneQuery_null() {
+ System.out.println("appendEscapedLuceneQuery");
+ StringBuilder buf = new StringBuilder();
+ CharSequence text = null;
+ LuceneUtils.appendEscapedLuceneQuery(buf, text);
+ assertEquals(0, buf.length());
+ }
/**
* Test of escapeLuceneQuery method, of class LuceneUtils.
*/
@@ -60,4 +70,16 @@ public class LuceneUtilsTest {
String result = LuceneUtils.escapeLuceneQuery(text);
assertEquals(expResult, result);
}
+
+ /**
+ * Test of escapeLuceneQuery method, of class LuceneUtils.
+ */
+ @Test
+ public void testEscapeLuceneQuery_null() {
+ System.out.println("escapeLuceneQuery");
+ CharSequence text = null;
+ String expResult = null;
+ String result = LuceneUtils.escapeLuceneQuery(text);
+ assertEquals(expResult, result);
+ }
}
diff --git a/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEQueryTest.java b/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEQueryTest.java
index 620976e46..45bea555c 100644
--- a/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEQueryTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEQueryTest.java
@@ -95,7 +95,7 @@ public class CPEQueryTest extends BaseIndexTestCase {
CPEQuery instance = new CPEQuery();
String queryText = instance.buildSearch(vendor, product, version, null, null);
- String expResult = " product:( struts 2 core ) vendor:( apache software foundation ) version:(2.1.2)";
+ String expResult = " product:( struts 2 core ) vendor:( apache software foundation ) version:(2.1.2^0.7 )";
assertTrue(expResult.equals(queryText));
queryText = instance.buildSearch(vendor, product, version, null, productWeightings);
diff --git a/src/test/java/org/codesecure/dependencycheck/xml/CPEHandlerTest.java b/src/test/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandlerTest.java
similarity index 94%
rename from src/test/java/org/codesecure/dependencycheck/xml/CPEHandlerTest.java
rename to src/test/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandlerTest.java
index e781dcd6b..a35758832 100644
--- a/src/test/java/org/codesecure/dependencycheck/xml/CPEHandlerTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandlerTest.java
@@ -2,7 +2,7 @@
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
-package org.codesecure.dependencycheck.cpe.xml;
+package org.codesecure.dependencycheck.data.cpe.xml;
import java.io.File;
import junit.framework.TestCase;
diff --git a/src/test/java/org/codesecure/dependencycheck/utils/CliParserTest.java b/src/test/java/org/codesecure/dependencycheck/utils/CliParserTest.java
index d2c676765..3fe0d6efb 100644
--- a/src/test/java/org/codesecure/dependencycheck/utils/CliParserTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/utils/CliParserTest.java
@@ -331,6 +331,11 @@ public class CliParserTest extends TestCase {
System.setOut(new PrintStream(baos));
CliParser instance = new CliParser();
+ String[] args = {"-h"};
+ instance.parse(args);
+ instance.printHelp();
+ args[0] = "-ah";
+ instance.parse(args);
instance.printHelp();
try {
baos.flush();
diff --git a/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java b/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
index ba226a6be..4be2b244a 100644
--- a/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
@@ -4,6 +4,10 @@
*/
package org.codesecure.dependencycheck.utils;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
import junit.framework.TestCase;
import org.junit.Test;
@@ -38,4 +42,97 @@ public class SettingsTest extends TestCase {
String result = Settings.getString(key);
assertTrue(result.endsWith(expResult));
}
+
+ /**
+ * Test of mergeProperties method, of class Settings.
+ */
+ @Test
+ public void testMergeProperties_String() throws IOException, URISyntaxException {
+ System.out.println("getString");
+ String key = Settings.KEYS.PROXY_PORT;
+ String expResult = Settings.getString(key);
+ File f = new File(this.getClass().getClassLoader().getResource("test.properties").toURI());
+ //InputStream in = this.getClass().getClassLoader().getResourceAsStream("test.properties");
+ Settings.mergeProperties(f.getAbsolutePath());
+ String result = Settings.getString(key);
+ assertTrue("setting didn't change?", (expResult == null && result != null) || !expResult.equals(result));
+ }
+
+ /**
+ * Test of setString method, of class Settings.
+ */
+ @Test
+ public void testSetString() {
+ System.out.println("setString");
+ String key = "newProperty";
+ String value = "someValue";
+ Settings.setString(key, value);
+ String expResults = Settings.getString(key);
+ assertEquals(expResults, value);
+ }
+
+ /**
+ * Test of getString method, of class Settings.
+ */
+ @Test
+ public void testGetString_String_String() {
+ System.out.println("getString");
+ String key = "key That Doesn't Exist";
+ String defaultValue = "blue bunny";
+ String expResult = "blue bunny";
+ String result = Settings.getString(key);
+ assertTrue(result == null);
+ result = Settings.getString(key, defaultValue);
+ assertEquals(expResult, result);
+ }
+
+ /**
+ * Test of getString method, of class Settings.
+ */
+ @Test
+ public void testGetString_String() {
+ System.out.println("getString");
+ String key = Settings.KEYS.CONNECTION_TIMEOUT;
+ String result = Settings.getString(key);
+ assertTrue(result == null);
+ }
+
+ /**
+ * Test of getInt method, of class Settings.
+ */
+ @Test
+ public void testGetInt() {
+ System.out.println("getInt");
+ String key = "SomeNumber";
+ int expResult = 85;
+ Settings.setString(key, "85");
+ int result = Settings.getInt(key);
+ assertEquals(expResult, result);
+ }
+
+ /**
+ * Test of getLong method, of class Settings.
+ */
+ @Test
+ public void testGetLong() {
+ System.out.println("getLong");
+ String key = "SomeNumber";
+ long expResult = 300L;
+ Settings.setString(key, "300");
+ long result = Settings.getLong(key);
+ assertEquals(expResult, result);
+ }
+
+ /**
+ * Test of getBoolean method, of class Settings.
+ */
+ @Test
+ public void testGetBoolean() {
+ System.out.println("getBoolean");
+ String key = "SomeBoolean";
+ Settings.setString(key, "false");
+ boolean expResult = false;
+ boolean result = Settings.getBoolean(key);
+ assertEquals(expResult, result);
+ }
}
diff --git a/src/test/java/org/codesecure/dependencycheck/xml/CPEEntryTest.java b/src/test/java/org/codesecure/dependencycheck/xml/CPEEntryTest.java
deleted file mode 100644
index 7c47f719b..000000000
--- a/src/test/java/org/codesecure/dependencycheck/xml/CPEEntryTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.codesecure.dependencycheck.cpe.xml;
-
-import org.codesecure.dependencycheck.data.cpe.Entry;
-import junit.framework.TestCase;
-
-/**
- *
- * @author Jeremy Long
- */
-public class CPEEntryTest extends TestCase {
-
- public CPEEntryTest(String testName) {
- super(testName);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /**
- * Test of setName method, of class Entry.
- */
- public void testSetName() throws Exception {
- System.out.println("setName");
- String name = "cpe:/a:apache:struts:1.1:rc2";
-
- Entry instance = new Entry();
- instance.setName(name);
-
- assertEquals(name,instance.getName());
- assertEquals("apache", instance.getVendor());
- assertEquals("struts", instance.getProduct());
- assertEquals("1.1", instance.getVersion());
- assertEquals("rc2", instance.getRevision());
-
- }
-}
diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties
new file mode 100644
index 000000000..dec474f6f
--- /dev/null
+++ b/src/test/resources/test.properties
@@ -0,0 +1 @@
+proxy.port=80
\ No newline at end of file