From b82a0f3d502c0f6861b0910c409f4992f3f32f86 Mon Sep 17 00:00:00 2001
From: Rafael Cavazin <rafaelcavazin@gmail.com>
Date: Thu, 06 Dec 2012 15:08:50 -0500
Subject: [PATCH] translation of lastest properties

---
 src/com/gitblit/utils/HttpUtils.java |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/src/com/gitblit/utils/HttpUtils.java b/src/com/gitblit/utils/HttpUtils.java
index 079d1a6..86f53cf 100644
--- a/src/com/gitblit/utils/HttpUtils.java
+++ b/src/com/gitblit/utils/HttpUtils.java
@@ -15,7 +15,18 @@
  */
 package com.gitblit.utils;
 
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.text.MessageFormat;
+import java.util.Date;
+
 import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.X509Utils.X509Metadata;
 
 /**
  * Collection of utility methods for http requests.
@@ -32,15 +43,162 @@
 	 * @return the host url
 	 */
 	public static String getGitblitURL(HttpServletRequest request) {
+		// default to the request scheme and port
+		String scheme = request.getScheme();
+		int port = request.getServerPort();
+
+		// try to use reverse-proxy server's port
+        String forwardedPort = request.getHeader("X-Forwarded-Port");
+        if (StringUtils.isEmpty(forwardedPort)) {
+        	forwardedPort = request.getHeader("X_Forwarded_Port");
+        }
+        if (!StringUtils.isEmpty(forwardedPort)) {
+        	// reverse-proxy server has supplied the original port
+        	try {
+        		port = Integer.parseInt(forwardedPort);
+        	} catch (Throwable t) {
+        	}
+        }
+        
+		// try to use reverse-proxy server's scheme
+        String forwardedScheme = request.getHeader("X-Forwarded-Proto");
+        if (StringUtils.isEmpty(forwardedScheme)) {
+        	forwardedScheme = request.getHeader("X_Forwarded_Proto");
+        }
+        if (!StringUtils.isEmpty(forwardedScheme)) {
+        	// reverse-proxy server has supplied the original scheme
+        	scheme = forwardedScheme;
+        	
+        	if ("https".equals(scheme) && port == 80) {
+        		// proxy server is https, inside server is 80
+        		// this is likely because the proxy server has not supplied
+        		// x-forwarded-port. since 80 is almost definitely wrong,
+        		// make an educated guess that 443 is correct.
+        		port = 443;
+        	}
+        }
+        
+        String context = request.getContextPath();
+        String forwardedContext = request.getHeader("X-Forwarded-Context");
+        if (forwardedContext != null) {
+        	forwardedContext = request.getHeader("X_Forwarded_Context");
+        }
+        if (!StringUtils.isEmpty(forwardedContext)) {
+        	context = forwardedContext;
+        }
+        
+        // trim any trailing slash
+        if (context.length() > 0 && context.charAt(context.length() - 1) == '/') {
+        	context = context.substring(1);
+        }
+        
 		StringBuilder sb = new StringBuilder();
-		sb.append(request.getScheme());
+		sb.append(scheme);
 		sb.append("://");
 		sb.append(request.getServerName());
-		if ((request.getScheme().equals("http") && request.getServerPort() != 80)
-				|| (request.getScheme().equals("https") && request.getServerPort() != 443)) {
-			sb.append(":" + request.getServerPort());
+		if (("http".equals(scheme) && port != 80)
+				|| ("https".equals(scheme) && port != 443)) {
+			sb.append(":" + port);
 		}
-		sb.append(request.getContextPath());
+		sb.append(context);
 		return sb.toString();
 	}
+	
+	/**
+	 * Returns a user model object built from attributes in the SSL certificate.
+	 * This model is not retrieved from the user service.
+	 *  
+	 * @param httpRequest
+	 * @param checkValidity ensure certificate can be used now
+	 * @param usernameOIDs if unspecified, CN is used as the username
+	 * @return a UserModel, if a valid certificate is in the request, null otherwise
+	 */
+	public static UserModel getUserModelFromCertificate(HttpServletRequest httpRequest, boolean checkValidity, String... usernameOIDs) {
+		if (httpRequest.getAttribute("javax.servlet.request.X509Certificate") != null) {
+			X509Certificate[] certChain = (X509Certificate[]) httpRequest
+					.getAttribute("javax.servlet.request.X509Certificate");
+			if (certChain != null) {
+				X509Certificate cert = certChain[0];
+				// ensure certificate is valid
+				if (checkValidity) {
+					try {
+						cert.checkValidity(new Date());
+					} catch (CertificateNotYetValidException e) {
+						LoggerFactory.getLogger(HttpUtils.class).info(MessageFormat.format("X509 certificate {0} is not yet valid", cert.getSubjectDN().getName()));
+						return null;
+					} catch (CertificateExpiredException e) {
+						LoggerFactory.getLogger(HttpUtils.class).info(MessageFormat.format("X509 certificate {0} has expired", cert.getSubjectDN().getName()));
+						return null;
+					}
+				}
+				return getUserModelFromCertificate(cert, usernameOIDs);
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Creates a UserModel from a certificate
+	 * @param cert
+	 * @param usernameOids if unspecified CN is used as the username
+	 * @return
+	 */
+	public static UserModel getUserModelFromCertificate(X509Certificate cert, String... usernameOIDs) {
+		X509Metadata metadata = X509Utils.getMetadata(cert);
+		
+		UserModel user = new UserModel(metadata.commonName);
+		user.emailAddress = metadata.emailAddress;
+		user.isAuthenticated = false;
+		
+		if (usernameOIDs == null || usernameOIDs.length == 0) {
+			// use default usename<->CN mapping
+			usernameOIDs = new String [] { "CN" };
+		}
+		
+		// determine username from OID fingerprint
+		StringBuilder an = new StringBuilder();
+		for (String oid : usernameOIDs) {
+			String val = metadata.getOID(oid.toUpperCase(), null);
+			if (val != null) {
+				an.append(val).append(' ');
+			}
+		}
+		user.username = an.toString().trim();		
+		return user;
+	}
+	
+	public static X509Metadata getCertificateMetadata(HttpServletRequest httpRequest) {
+		if (httpRequest.getAttribute("javax.servlet.request.X509Certificate") != null) {
+			X509Certificate[] certChain = (X509Certificate[]) httpRequest
+					.getAttribute("javax.servlet.request.X509Certificate");
+			if (certChain != null) {
+				X509Certificate cert = certChain[0];
+				return X509Utils.getMetadata(cert);
+			}
+		}
+		return null;
+	}
+	
+	public static boolean isIpAddress(String address) {
+		if (StringUtils.isEmpty(address)) {
+			return false;
+		}
+		String [] fields = address.split("\\.");
+		if (fields.length == 4) {
+			// IPV4
+			for (String field : fields) {
+				try {
+					int value = Integer.parseInt(field);
+					if (value < 0 || value > 255) {
+						return false;
+					}
+				} catch (Exception e) {
+					return false;
+				}
+			}
+			return true;
+		}
+		// TODO IPV6?
+		return false;
+	}
 }

--
Gitblit v1.9.1