From 165254202d2625e7eebf3f649e4068124656a5e6 Mon Sep 17 00:00:00 2001
From: Jason Pyeron <jpyeron@pdinc.us>
Date: Thu, 06 Sep 2012 17:35:20 -0400
Subject: [PATCH] Merged CVE-2007-450 warning logging from Jason Pyeron (issue 126)

---
 src/com/gitblit/GitBlit.java              |    3 +
 src/com/gitblit/utils/ContainerUtils.java |  135 +++++++++++++++++++++++++++++++++++++++++++++
 docs/04_releases.mkd                      |    1 
 3 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd
index 155fc3b..c6fc1b7 100644
--- a/docs/04_releases.mkd
+++ b/docs/04_releases.mkd
@@ -11,6 +11,7 @@
 
 #### changes
 
+- Emit a warning in the log file if running on a Tomcat-based servlet container which is unfriendly to %2F forward-slash url encoding AND Gitblit is configured to mount parameters with %2F forward-slash url encoding (Github/jpyeron, issue 126)
 - LDAP admin attribute setting is now consistent with LDAP teams setting and admin teams list.  
 If *realm.ldap.maintainTeams==true* **AND** *realm.ldap.admins* is not empty, then User.canAdmin() is controlled by LDAP administrative team membership.  Otherwise, User.canAdmin() is controlled by Gitblit.
 
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index f8fbfef..e6effc2 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -88,6 +88,7 @@
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.ByteFormat;
+import com.gitblit.utils.ContainerUtils;
 import com.gitblit.utils.DeepCopier;
 import com.gitblit.utils.FederationUtils;
 import com.gitblit.utils.JGitUtils;
@@ -2214,6 +2215,8 @@
 		} catch (IllegalArgumentException e) {
 			logger.error("Failed to configure JGit parameters!", e);
 		}
+
+		ContainerUtils.CVE_2007_0450.test();
 	}
 	
 	private void logTimezone(String type, TimeZone zone) {
diff --git a/src/com/gitblit/utils/ContainerUtils.java b/src/com/gitblit/utils/ContainerUtils.java
new file mode 100755
index 0000000..39ba6e0
--- /dev/null
+++ b/src/com/gitblit/utils/ContainerUtils.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 PD Inc / gitblit.com.
+ *
+ * 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 com.gitblit.utils;
+
+import java.io.CharConversionException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.GitBlit;
+import com.gitblit.Keys;
+
+/**
+ * This is the support class for all container specific code.
+ * 
+ * @author jpyeron
+ */
+public class ContainerUtils
+{
+    private static Logger LOGGER = LoggerFactory.getLogger(ContainerUtils.class);
+
+    /**
+     * The support class for managing and evaluating the environment with
+     * regards to CVE-2007-0405.
+     * 
+     * @see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0450
+     * @author jpyeron
+     */
+    public static class CVE_2007_0450
+    {
+        /**
+         * This method will test for know issues in certain containers where %2F
+         * is blocked from use in URLs. It will emit a warning to the logger if
+         * the configuration of Tomcat causes the URL processing to fail on %2F.
+         */
+        public static void test()
+        {
+            if (GitBlit.getBoolean(Keys.web.mountParameters, true)
+                    && ((GitBlit.getChar(Keys.web.forwardSlashCharacter, '/')) == '/' || (GitBlit.getChar(
+                            Keys.web.forwardSlashCharacter, '/')) == '\\'))
+            {
+                try
+                {
+                    if (GitBlit.isGO())
+                        ;
+                    else if (logCVE_2007_0450Tomcat())
+                        ;
+                    // else if (logCVE_2007_0450xxx());
+                    else
+                    {
+                        LOGGER.info("Unknown container, cannot check for CVE-2007-0450 aplicability");
+                    }
+                }
+                catch (Throwable t)
+                {
+                    LOGGER.warn("Failure in checking for CVE-2007-0450 aplicability", t);
+                }
+            }
+
+        }
+
+        /**
+         * This method will test for know issues in certain versions of Tomcat,
+         * JBOSS, glassfish, and other embedded uses of Tomcat where %2F is
+         * blocked from use in certain URL s. It will emit a warning to the
+         * logger if the configuration of Tomcat causes the URL processing to
+         * fail on %2F.
+         * 
+         * @return true if it recognizes Tomcat, false if it does not recognize
+         *         Tomcat
+         */
+        private static boolean logCVE_2007_0450Tomcat()
+        {
+            try
+            {
+                byte[] test = "http://server.domain:8080/context/servlet/param%2fparam".getBytes();
+
+                // ByteChunk mb=new ByteChunk();
+                Class<?> cByteChunk = Class.forName("org.apache.tomcat.util.buf.ByteChunk");
+                Object mb = cByteChunk.newInstance();
+
+                // mb.setBytes(test, 0, test.length);
+                Method mByteChunck_setBytes = cByteChunk.getMethod("setBytes", byte[].class, int.class, int.class);
+                mByteChunck_setBytes.invoke(mb, test, (int) 0, test.length);
+
+                // UDecoder ud=new UDecoder();
+                Class<?> cUDecoder = Class.forName("org.apache.tomcat.util.buf.UDecoder");
+                Object ud = cUDecoder.newInstance();
+
+                // ud.convert(mb,false);
+                Method mUDecoder_convert = cUDecoder.getMethod("convert", cByteChunk, boolean.class);
+
+                try
+                {
+                    mUDecoder_convert.invoke(ud, mb, false);
+                }
+                catch (InvocationTargetException e)
+                {
+                    if (e.getTargetException() != null && e.getTargetException() instanceof CharConversionException)
+                    {
+                        LOGGER.warn("You are using a Tomcat based system and the current settings regarding CVE-2007-0450 will prevent certain fetures from working. Please see http://gitblit.com/faq.html and http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0450");
+                        return true;
+                    }
+                    throw e;
+                }
+            }
+            catch (Throwable t)
+            {
+                // The apache url decoder internals are different, this is not a
+                // Tomcat matching the failure pattern for CVE-2007-0450
+                if (t instanceof ClassNotFoundException || t instanceof NoSuchMethodException
+                        || t instanceof IllegalArgumentException)
+                    return false;
+                LOGGER.debug("This is a tomcat, but the test operation failed somehow", t);
+            }
+            return true;
+        }
+    }
+
+}

--
Gitblit v1.9.1