You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wookie.apache.org by ps...@apache.org on 2012/07/24 17:18:32 UTC

svn commit: r1365117 - in /incubator/wookie/trunk: WebContent/WEB-INF/ src-tests/org/apache/wookie/tests/functional/ src-tests/org/apache/wookie/tests/server/security/ src-tests/testdata/ src-tests/testdata/security-tests/ src/ src/org/apache/wookie/co...

Author: psharples
Date: Tue Jul 24 15:18:31 2012
New Revision: 1365117

URL: http://svn.apache.org/viewvc?rev=1365117&view=rev
Log:
Validate .wgt REST service. See WOOKIE-325.

Added:
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java   (with props)
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java   (with props)
    incubator/wookie/trunk/src-tests/testdata/invalid-xml.wgt   (with props)
    incubator/wookie/trunk/src-tests/testdata/missing-config.wgt   (with props)
    incubator/wookie/trunk/src-tests/testdata/missing-start-page.wgt   (with props)
    incubator/wookie/trunk/src-tests/testdata/security-tests/
    incubator/wookie/trunk/src-tests/testdata/security-tests/README
    incubator/wookie/trunk/src-tests/testdata/security-tests/binary.exe   (with props)
    incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp   (with props)
    incubator/wookie/trunk/src-tests/testdata/security-tests/script.bat
    incubator/wookie/trunk/src-tests/testdata/security-tests/script.sh
    incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-no-manifest.wgt   (with props)
    incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-with-manifest.wgt   (with props)
    incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java   (with props)
    incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java   (with props)
Modified:
    incubator/wookie/trunk/WebContent/WEB-INF/web.xml
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java
    incubator/wookie/trunk/src/org/apache/wookie/controller/Controller.java
    incubator/wookie/trunk/src/widgetserver.properties

Modified: incubator/wookie/trunk/WebContent/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/WebContent/WEB-INF/web.xml?rev=1365117&r1=1365116&r2=1365117&view=diff
==============================================================================
--- incubator/wookie/trunk/WebContent/WEB-INF/web.xml (original)
+++ incubator/wookie/trunk/WebContent/WEB-INF/web.xml Tue Jul 24 15:18:31 2012
@@ -211,6 +211,18 @@
 	
 	<servlet>
 		<description></description>
+		<display-name>Widget Validator</display-name>
+		<servlet-name>ValidatorController</servlet-name>
+		<servlet-class>org.apache.wookie.controller.ValidatorController</servlet-class>
+		<load-on-startup>2</load-on-startup>
+		</servlet>
+	<servlet-mapping>
+		<servlet-name>ValidatorController</servlet-name>
+		<url-pattern>/validate/*</url-pattern>
+	</servlet-mapping>
+
+	<servlet>
+		<description></description>
 		<display-name>ProxyServlet</display-name>
 		<servlet-name>ProxyServlet</servlet-name>
 		<servlet-class>

Modified: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java?rev=1365117&r1=1365116&r2=1365117&view=diff
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java (original)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java Tue Jul 24 15:18:31 2012
@@ -39,25 +39,28 @@ import org.junit.AfterClass;
  *
  */
 public abstract class AbstractControllerTest extends AbstractWookieTest{
-	protected static final int TEST_SERVER_PORT = 8080;
-	protected static final String TEST_SERVER_HOST = "localhost";	
-	protected static final String TEST_SERVER_ORIGIN = "http://" + TEST_SERVER_HOST + ":" + TEST_SERVER_PORT;
-	protected static final String TEST_SERVER_LOCATION = TEST_SERVER_ORIGIN+"/wookie/";
-	
-	protected static final String TEST_POLICIES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"policies";
-	protected static final String TEST_INSTANCES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"widgetinstances";
-	protected static final String TEST_PROPERTIES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"properties";
-	protected static final String TEST_PARTICIPANTS_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"participants";
-	protected static final String TEST_WIDGETS_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"widgets";
-	protected static final String TEST_SERVICES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"services";
-		
-	protected static final String API_KEY_VALID = "TEST";
-	protected static final String API_KEY_INVALID = "rubbish";
-	protected static final String WIDGET_ID_VALID = "http://www.getwookie.org/widgets/weather";
-	protected static final String WIDGET_ID_INVALID = "http://www.getwookie.org/widgets/nosuchwidget";
-	protected static final String WIDGET_ID_LOCALIZED = "http://www.getwookie.org/widgets/localetest";
-	
-  protected static Collection<String> importedWidgetList = new ArrayList<String>();
+    protected static final int TEST_SERVER_PORT = 8080;
+    protected static final String TEST_SERVER_HOST = "localhost";	
+    protected static final String TEST_SERVER_ORIGIN = "http://" + TEST_SERVER_HOST + ":" + TEST_SERVER_PORT;
+    protected static final String TEST_SERVER_LOCATION = TEST_SERVER_ORIGIN+"/wookie/";
+
+    protected static final String TEST_POLICIES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"policies";
+    protected static final String TEST_INSTANCES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"widgetinstances";
+    protected static final String TEST_PROPERTIES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"properties";
+    protected static final String TEST_PARTICIPANTS_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"participants";
+    protected static final String TEST_WIDGETS_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"widgets";
+    protected static final String TEST_SERVICES_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"services";
+    protected static final String TEST_VALIDATOR_SERVICE_URL_VALID = TEST_SERVER_LOCATION+"validate";
+
+    protected static final String API_KEY_VALID = "TEST";
+    protected static final String API_KEY_INVALID = "rubbish";
+    protected static final String WIDGET_ID_VALID = "http://www.getwookie.org/widgets/weather";
+    protected static final String WIDGET_ID_INVALID = "http://www.getwookie.org/widgets/nosuchwidget";
+    protected static final String WIDGET_ID_LOCALIZED = "http://www.getwookie.org/widgets/localetest";
+
+    protected static Collection<String> importedWidgetList = new ArrayList<String>();
+    
+    protected String TEMPUPLOADFOLDER = System.getProperty("java.io.tmpdir");
 
 	/**
 	 * Set credentials for accessing Wookie admin functions

Added: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java (added)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java Tue Jul 24 15:18:31 2012
@@ -0,0 +1,154 @@
+/*
+ *  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 org.apache.wookie.tests.functional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class ValidatorControllerTest extends AbstractControllerTest {
+  
+  @AfterClass
+  public static void tearDown() throws HttpException, IOException{}
+
+  @Test
+  public void validateOkWidget() throws HttpException, IOException{
+    HttpClient client = new HttpClient();
+    
+    PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+    
+    //
+    // Use upload test widget
+    //
+    File file = new File("src-tests/testdata/upload-test-2.wgt");
+    assertTrue(file.exists());
+    
+    //
+    // Add test wgt file to POST
+    //
+    Part[] parts = { new FilePart(file.getName(), file) };
+    post.setRequestEntity(new MultipartRequestEntity(parts, post
+        .getParams()));
+
+    client.executeMethod(post);   
+    int code = post.getStatusCode();
+    assertEquals(200, code);
+    //System.out.println(post.getResponseBodyAsString());
+    post.releaseConnection();
+    // ensure resources have been removed
+    File tempUploadFolder = new File(TEMPUPLOADFOLDER, "uploadtest_2");
+    assertFalse(tempUploadFolder.exists());
+    File uploadedWgt = new File(TEMPUPLOADFOLDER, "upload-test-2.wgt");
+    assertFalse(uploadedWgt.exists());
+  }
+  
+  @Test
+  public void validateWidgetMissingStartPage() throws HttpException, IOException{
+    HttpClient client = new HttpClient();
+    
+    PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+    
+    File file = new File("src-tests/testdata/missing-start-page.wgt");
+    assertTrue(file.exists());
+    
+    //
+    // Add test wgt file to POST
+    //
+    Part[] parts = { new FilePart(file.getName(), file) };
+    post.setRequestEntity(new MultipartRequestEntity(parts, post
+        .getParams()));
+    
+    client.executeMethod(post);   
+    int code = post.getStatusCode();
+    // should be 400 - bad wgt package
+    assertEquals(400,code);
+    //System.out.println(post.getResponseBodyAsString());
+    post.releaseConnection();
+    // ensure resources have been removed
+    File tempUploadFolder = new File(TEMPUPLOADFOLDER, "invalid-widget-no-start-page");
+    assertFalse(tempUploadFolder.exists());
+    File uploadedWgt = new File(TEMPUPLOADFOLDER, "missing-start-page.wgt");
+    assertFalse(uploadedWgt.exists());
+  }
+  
+  @Test
+  public void validateWidgetMissingConfigDotXml() throws HttpException, IOException{
+    HttpClient client = new HttpClient();
+    
+    PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+    
+    File file = new File("src-tests/testdata/missing-config.wgt");
+    assertTrue(file.exists());
+    
+    //
+    // Add test wgt file to POST
+    //
+    Part[] parts = { new FilePart(file.getName(), file) };
+    post.setRequestEntity(new MultipartRequestEntity(parts, post
+        .getParams()));
+    
+    client.executeMethod(post);   
+    int code = post.getStatusCode();
+    // should be 400 - bad wgt package
+    assertEquals(400,code);
+    //System.out.println(post.getResponseBodyAsString());
+    post.releaseConnection();
+    // ensure resources have been removed
+    // no unpacked folder should have been created this time
+    // remove original wgt upload
+    File uploadedWgt = new File(TEMPUPLOADFOLDER, "missing-config.wgt");
+    assertFalse(uploadedWgt.exists());
+  }
+  
+  @Test
+  public void validateWidgetInvalidXmlMarkup() throws HttpException, IOException{
+    HttpClient client = new HttpClient();
+    
+    PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+    
+    File file = new File("src-tests/testdata/invalid-xml.wgt");
+    assertTrue(file.exists());
+    
+    //
+    // Add test wgt file to POST
+    //
+    Part[] parts = { new FilePart(file.getName(), file) };
+    post.setRequestEntity(new MultipartRequestEntity(parts, post
+        .getParams()));
+    
+    client.executeMethod(post);   
+    int code = post.getStatusCode();
+    // should be 400 - bad wgt package
+    assertEquals(400,code);
+    //System.out.println(post.getResponseBodyAsString());
+    post.releaseConnection();
+    // ensure resources have been removed
+    // no unpacked folder should have been created this time
+    // remove original wgt upload
+    File uploadedWgt = new File(TEMPUPLOADFOLDER, "invalid-xml.wgt");
+    assertFalse(uploadedWgt.exists());
+  }
+}
\ No newline at end of file

Propchange: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ValidatorControllerTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java (added)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java Tue Jul 24 15:18:31 2012
@@ -0,0 +1,224 @@
+/*
+ *  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 org.apache.wookie.tests.server.security;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.wookie.tests.functional.AbstractControllerTest;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+/**
+ * Turning on the validate service in wookie means anyone can upload artifacts
+ * (although they should be uploaded to the java.temp folder), so these tests check
+ * that resources are deleted after the validation has occurred.
+ */
+public class MaliciousContentUploadTest extends AbstractControllerTest {
+    
+    @AfterClass
+    public static void tearDown() throws HttpException, IOException{}
+
+    @Test
+    public void testNoExecutableInUploadFolder() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/binary.exe");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 400 - bad wgt package
+      assertEquals(400, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure no binary.exe in temp folder
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "binary.exe");
+      assertFalse(uploadedWgt.exists());
+    }
+    
+    @Test
+    public void testNoJspInUploadFolder() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/jsp.jsp");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 400 - bad wgt package
+      assertEquals(400, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure no jsp.jsp in temp folder
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "jsp.jsp");
+      assertFalse(uploadedWgt.exists());
+    }
+    
+    @Test
+    public void testNoBatchFileInUploadFolder() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/script.bat");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 400 - bad wgt package
+      assertEquals(400, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure no script.bat in temp folder
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "script.bat");
+      assertFalse(uploadedWgt.exists());
+    }
+    
+    @Test
+    public void testNoScriptFileInUploadFolder() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/script.sh");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 400 - bad wgt package
+      assertEquals(400, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure no script.sh in temp folder
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "script.sh");
+      assertFalse(uploadedWgt.exists());
+    }
+
+    @Test
+    public void testUploadMaliciousWidgetNoManifest() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/widget-with-malicious-code-no-manifest.wgt");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 400 - bad wgt package
+      assertEquals(400, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure resources are removed
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "widget-with-malicious-code-no-manifest.wgt");
+      assertFalse(uploadedWgt.exists());
+    }
+    
+    @Test
+    public void testUploadMaliciousWidgetWithManifest() throws HttpException, IOException{
+      HttpClient client = new HttpClient();
+      
+      PostMethod post = new PostMethod(TEST_VALIDATOR_SERVICE_URL_VALID);
+      
+      //
+      // Use upload test widget
+      //
+      File file = new File("src-tests/testdata/security-tests/widget-with-malicious-code-with-manifest.wgt");
+      assertTrue(file.exists());
+      
+      //
+      // Add test binary file to POST
+      //
+      Part[] parts = { new FilePart(file.getName(), file) };
+      post.setRequestEntity(new MultipartRequestEntity(parts, post
+          .getParams()));
+
+      client.executeMethod(post);   
+      int code = post.getStatusCode();
+      // should be 200
+      assertEquals(200, code);
+      //System.out.println(post.getResponseBodyAsString());
+      post.releaseConnection();
+      // ensure resources are removed
+      File tempUploadFolder = new File(TEMPUPLOADFOLDER, "pretend-malicious-package");
+      assertFalse(tempUploadFolder.exists());
+      File uploadedWgt = new File(TEMPUPLOADFOLDER, "widget-with-malicious-code-with-manifest.wgt");
+      assertFalse(uploadedWgt.exists());
+    }
+}

Propchange: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/server/security/MaliciousContentUploadTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/wookie/trunk/src-tests/testdata/invalid-xml.wgt
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/invalid-xml.wgt?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/invalid-xml.wgt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/wookie/trunk/src-tests/testdata/missing-config.wgt
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/missing-config.wgt?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/missing-config.wgt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/wookie/trunk/src-tests/testdata/missing-start-page.wgt
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/missing-start-page.wgt?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/missing-start-page.wgt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/README
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/README?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/testdata/security-tests/README (added)
+++ incubator/wookie/trunk/src-tests/testdata/security-tests/README Tue Jul 24 15:18:31 2012
@@ -0,0 +1,3 @@
+The files found here are all harmless and are only used in unit tests to ensure 
+they are removed and not left over after a widget validation has occurred.
+See src-tests/server/security/MaliciousContentUploadTest
\ No newline at end of file

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/binary.exe
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/binary.exe?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/security-tests/binary.exe
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp (added)
+++ incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp Tue Jul 24 15:18:31 2012
@@ -0,0 +1 @@
+nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program 
 want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset 
 your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nas
 ty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma 
\ No newline at end of file

Propchange: incubator/wookie/trunk/src-tests/testdata/security-tests/jsp.jsp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/script.bat
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/script.bat?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/testdata/security-tests/script.bat (added)
+++ incubator/wookie/trunk/src-tests/testdata/security-tests/script.bat Tue Jul 24 15:18:31 2012
@@ -0,0 +1 @@
+nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program 
 want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset 
 your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nas
 ty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma 
\ No newline at end of file

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/script.sh
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/script.sh?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/testdata/security-tests/script.sh (added)
+++ incubator/wookie/trunk/src-tests/testdata/security-tests/script.sh Tue Jul 24 15:18:31 2012
@@ -0,0 +1 @@
+nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program 
 want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset 
 your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nas
 ty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma nasty program want to upset your karma 
\ No newline at end of file

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-no-manifest.wgt
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-no-manifest.wgt?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-no-manifest.wgt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-with-manifest.wgt
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-with-manifest.wgt?rev=1365117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/src-tests/testdata/security-tests/widget-with-malicious-code-with-manifest.wgt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: incubator/wookie/trunk/src/org/apache/wookie/controller/Controller.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/controller/Controller.java?rev=1365117&r1=1365116&r2=1365117&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/controller/Controller.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/controller/Controller.java Tue Jul 24 15:18:31 2012
@@ -28,6 +28,8 @@ import org.apache.log4j.Logger;
 import org.apache.wookie.exceptions.InvalidParametersException;
 import org.apache.wookie.exceptions.ResourceDuplicationException;
 import org.apache.wookie.exceptions.ResourceNotFoundException;
+import org.apache.wookie.exceptions.ServiceUnavailableException;
+import org.apache.wookie.exceptions.SystemUnavailableException;
 import org.apache.wookie.exceptions.UnauthorizedAccessException;
 
 /**
@@ -126,7 +128,10 @@ public abstract class Controller extends
 		} catch (UnauthorizedAccessException e){
 		  _logger.error(e.getMessage(), e);
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
-		}
+	    } catch (ServiceUnavailableException e){
+	      _logger.error(e.getMessage(), e);
+	      response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+	    }
 	}
 
 	/* (non-Javadoc)
@@ -174,8 +179,9 @@ public abstract class Controller extends
 	 * @param request
 	 @return true if the resource was successfully created
 	 * @throws ResourceDuplicationException
+	 * @throws SystemUnavailableException 
 	 */
-	protected boolean create(String resourceId, HttpServletRequest request, HttpServletResponse response) throws ResourceDuplicationException, InvalidParametersException, UnauthorizedAccessException{return false;};
+	protected boolean create(String resourceId, HttpServletRequest request, HttpServletResponse response) throws ResourceDuplicationException, InvalidParametersException, UnauthorizedAccessException, ServiceUnavailableException{return false;};
 	
 	/**
 	 * Delete a resource

Added: incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java (added)
+++ incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java Tue Jul 24 15:18:31 2012
@@ -0,0 +1,130 @@
+/*
+ *  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 org.apache.wookie.controller;
+
+import java.io.File;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.wookie.Messages;
+import org.apache.wookie.exceptions.InvalidParametersException;
+import org.apache.wookie.exceptions.ResourceDuplicationException;
+import org.apache.wookie.exceptions.ServiceUnavailableException;
+import org.apache.wookie.feature.Features;
+import org.apache.wookie.helpers.WidgetImportHelper;
+import org.apache.wookie.server.LocaleHandler;
+import org.apache.wookie.util.WidgetFileUtils;
+import org.apache.wookie.util.WidgetJavascriptSyntaxAnalyzer;
+import org.apache.wookie.util.html.StartPageProcessor;
+import org.apache.wookie.w3c.W3CWidget;
+import org.apache.wookie.w3c.W3CWidgetFactory;
+import org.apache.wookie.w3c.exceptions.BadManifestException;
+import org.apache.wookie.w3c.exceptions.BadWidgetZipFileException;
+import org.apache.wookie.w3c.exceptions.InvalidContentTypeException;
+import org.apache.wookie.w3c.exceptions.InvalidStartFileException;
+
+public class ValidatorController  extends Controller {
+
+    private static final long serialVersionUID = -3969001338861831480L;
+
+    /* (non-Javadoc)
+     * @see org.apache.wookie.controller.Controller#create(java.lang.String, javax.servlet.http.HttpServletRequest)
+     */
+    @Override
+    protected boolean create(String resourceId, HttpServletRequest request, HttpServletResponse response)
+        throws ResourceDuplicationException, InvalidParametersException, ServiceUnavailableException{
+        
+        Configuration properties = (Configuration) getServletContext().getAttribute("properties"); //$NON-NLS-1$
+        // check validation is enabled
+        boolean shouldValidate = properties.getBoolean("widget.enable.validator");
+        if(!shouldValidate){
+            throw new ServiceUnavailableException();
+        }
+        //
+        // Get localized messages so we can return errors
+        //
+        Messages localizedMessages = LocaleHandler.localizeMessages(request);
+        String tempUploadFolder = System.getProperty("java.io.tmpdir");
+        //
+        // Try to obtain a zipfile from the request. 
+        //
+        File zipFile;
+        try {
+          zipFile = WidgetFileUtils.upload(tempUploadFolder, request);
+        } catch (Exception ex) {
+          throw new InvalidParametersException(localizedMessages.getString("widgets.invalid-config-xml") + "\n" + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ 
+        }
+        
+        //
+        // No file uploaded
+        //
+        if(zipFile == null || !zipFile.exists()){
+          throw new InvalidParametersException(localizedMessages.getString("widgets.no-widget-file-uploaded")); //$NON-NLS-1$
+        }
+        
+        W3CWidget widgetModel = null;
+        W3CWidgetFactory fac = null;
+        try {
+            //
+            // Parse and validate the zip as a widget
+            //
+            final String[] locales = properties.getStringArray("widget.locales");
+            fac = new W3CWidgetFactory();
+            fac.setLocales(locales);
+            fac.setLocalPath(tempUploadFolder);
+            fac.setOutputDirectory(tempUploadFolder);
+            fac.setFeatures(Features.getFeatureNames());
+            fac.setStartPageProcessor(new StartPageProcessor());
+            widgetModel = fac.parse(zipFile);
+            new WidgetJavascriptSyntaxAnalyzer(fac.getUnzippedWidgetDirectory());
+            returnXml(WidgetImportHelper.createXMLWidgetDocument(widgetModel, new File(fac.getUnzippedWidgetDirectory(), "config.xml"), getWookieServerURL(request, "").toString(), false), response);
+            //send back a 200 ok.
+            return false;
+            //
+            // Catch specific parsing and validation errors and throw exception with error message
+            //
+        } catch (InvalidStartFileException ex) {
+            _logger.error(ex);
+            throw new InvalidParametersException(
+                    localizedMessages.getString("widgets.no-start-file") + "\n" + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$     
+        } catch (BadManifestException ex) {
+            _logger.error(ex);
+            String message = ex.getMessage();
+            if (ex.getMessage() == null || ex.getMessage().equals(""))message = localizedMessages.getString("widgets.invalid-config-xml"); //$NON-NLS-1$
+            if (ex instanceof InvalidContentTypeException)
+                message = localizedMessages.getString("widgets.unsupported-content-type");//$NON-NLS-1$
+            throw new InvalidParametersException(message);
+        } catch (BadWidgetZipFileException ex) {
+            _logger.error(ex);
+            String message = ex.getMessage();
+            if (ex.getMessage() == null || ex.getMessage().equals(""))message = localizedMessages.getString("widgets.bad-zip-file"); //$NON-NLS-1$
+            throw new InvalidParametersException(message);
+        } catch (Exception ex) {
+            _logger.error(ex);
+            throw new InvalidParametersException(
+                    localizedMessages.getString("widgets.cant-parse-config-xml") + "\n" + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        } finally {
+            // ** No matter what always remove all the resources **
+            if(fac.getUnzippedWidgetDirectory() != null){
+                WidgetFileUtils.removeWidgetResources(tempUploadFolder, fac.getUnzippedWidgetDirectory().getName());
+            }
+            // also delete the uploaded wgt file
+            if(zipFile.exists()){
+                zipFile.delete();
+            }
+        }
+    }
+}

Propchange: incubator/wookie/trunk/src/org/apache/wookie/controller/ValidatorController.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java?rev=1365117&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java (added)
+++ incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java Tue Jul 24 15:18:31 2012
@@ -0,0 +1,40 @@
+/*
+ *  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 org.apache.wookie.exceptions;
+
+/**
+ * Exception to be thrown when a particular service is not available when called
+ * - manifest validator service for example which can be switched off in the widgetserver.properties file
+ */
+public class ServiceUnavailableException extends Exception {
+
+    private static final long serialVersionUID = 5319355407875345855L;
+
+    public ServiceUnavailableException() {
+        super();
+    }
+
+    public ServiceUnavailableException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ServiceUnavailableException(String message) {
+        super(message);
+    }
+
+    public ServiceUnavailableException(Throwable cause) {
+        super(cause);
+    }
+
+}

Propchange: incubator/wookie/trunk/src/org/apache/wookie/exceptions/ServiceUnavailableException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/wookie/trunk/src/widgetserver.properties
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/widgetserver.properties?rev=1365117&r1=1365116&r2=1365117&view=diff
==============================================================================
--- incubator/wookie/trunk/src/widgetserver.properties (original)
+++ incubator/wookie/trunk/src/widgetserver.properties Tue Jul 24 15:18:31 2012
@@ -63,4 +63,8 @@ widget.persistence.manager.rootpath=@REP
 widget.persistence.manager.workspace=@REPOSITORY_WORKSPACE@
 # Queue preferences
 widget.preferences.useinstancequeues=true
-widget.shareddata.useinstancequeues=true
\ No newline at end of file
+widget.shareddata.useinstancequeues=true
+# Validator service preferences
+# Allow **anyone** to upload .wgt packages to wookie for validation
+# Note: .wgt resources are removed after validation and are not imported permanently.
+widget.enable.validator=false
\ No newline at end of file