From 0805ff838562e3b19d31083d80762abcd0ebd106 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Mon, 15 Jun 2015 12:58:10 -0400
Subject: [PATCH] Merged #259 "Allow custom host & port specification for advertised SSH urls"

---
 src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java |   12 ++++-
 src/main/java/com/gitblit/transport/ssh/SshDaemon.java           |   26 ++++++++----
 src/main/distrib/data/defaults.properties                        |   12 ++++++
 src/main/java/com/gitblit/transport/ssh/WelcomeShell.java        |   11 ++++-
 src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java |   16 +++++--
 5 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/src/main/distrib/data/defaults.properties b/src/main/distrib/data/defaults.properties
index cc42d90..60c914b 100644
--- a/src/main/distrib/data/defaults.properties
+++ b/src/main/distrib/data/defaults.properties
@@ -112,6 +112,18 @@
 # RESTART REQUIRED
 git.sshBindInterface = 
 
+# Manually specify the hostname to use in advertised SSH repository urls.
+# This may be useful in complex forwarding setups.
+#
+# SINCE 1.7.0
+git.sshAdvertisedHost = 
+
+# Manually specify the port to use in advertised SSH repository urls.
+# This may be useful in complex forwarding setups.
+#
+# SINCE 1.7.0
+git.sshAdvertisedPort = 
+
 # Specify the SSH key manager to use for retrieving, storing, and removing
 # SSH keys.
 #
diff --git a/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java b/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
index 69c254c..e989ece 100644
--- a/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
+++ b/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
@@ -19,8 +19,6 @@
 import java.net.URL;
 import java.text.MessageFormat;
 
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -34,6 +32,8 @@
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Handles requests for Sparkleshare Invites
@@ -89,6 +89,8 @@
 			response.getWriter().append("SSH is not active on this server!");
 			return;
 		}
+		int sshDisplayPort = settings.getInteger(Keys.git.sshAdvertisedPort, sshPort);
+
 		// extract repo name from request
 		String repoUrl = request.getPathInfo().substring(1);
 
@@ -111,6 +113,10 @@
 		String url = settings.getString(Keys.web.canonicalUrl, "https://localhost:8443");
 		if (!StringUtils.isEmpty(url) && url.indexOf("localhost") == -1) {
 			host = new URL(url).getHost();
+		}
+		String sshDisplayHost = settings.getString(Keys.git.sshAdvertisedHost, "");
+		if(sshDisplayHost.isEmpty()) {
+			sshDisplayHost = host;
 		}
 
 		UserModel user;
@@ -141,7 +147,7 @@
 		StringBuilder sb = new StringBuilder();
 		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
 		sb.append("<sparkleshare><invite>\n");
-		sb.append(MessageFormat.format("<address>ssh://{0}@{1}:{2,number,0}/</address>\n", user.username, host, sshPort));
+		sb.append(MessageFormat.format("<address>ssh://{0}@{1}:{2,number,0}/</address>\n", user.username, sshDisplayHost, sshDisplayPort));
 		sb.append(MessageFormat.format("<remote_path>/{0}</remote_path>\n", model.name));
 		int fanoutPort = settings.getInteger(Keys.fanout.port, 0);
 		if (fanoutPort > 0) {
diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
index 0ff5c28..68a2e90 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
+++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
@@ -35,8 +35,8 @@
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.server.auth.CachingPublicKeyAuthenticator;
 import org.apache.sshd.server.UserAuth;
+import org.apache.sshd.server.auth.CachingPublicKeyAuthenticator;
 import org.apache.sshd.server.auth.UserAuthKeyboardInteractive;
 import org.apache.sshd.server.auth.UserAuthPassword;
 import org.apache.sshd.server.auth.UserAuthPublicKey;
@@ -130,7 +130,7 @@
 		} else {
 			addr = new InetSocketAddress(bindInterface, port);
 		}
-		
+
 		//Will do GSS ?
 		GSSAuthenticator gssAuthenticator = null;
 		if(settings.getBoolean(Keys.git.sshWithKrb5, false)) {
@@ -144,9 +144,9 @@
 					"");
 			if(! servicePrincipalName.isEmpty()) {
 				gssAuthenticator.setServicePrincipalName(servicePrincipalName);
-			}			
+			}
 		}
-		
+
 		//Sort the authenticators for sshd
 		List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
 		String sshAuthenticatorsOrderString = settings.getString(Keys.git.sshAuthenticatorsOrder,
@@ -156,7 +156,7 @@
 			switch (authenticatorName) {
 			case "gssapi-with-mic":
 				if(gssAuthenticator != null) {
-					userAuthFactories.add(new UserAuthGSS.Factory());					
+					userAuthFactories.add(new UserAuthGSS.Factory());
 				}
 				break;
 			case "publickey":
@@ -172,7 +172,7 @@
 				log.error("Unknown ssh authenticator: '{}'", authenticatorName);
 			}
 		}
-		
+
 		// Create the SSH server
 		sshd = SshServer.setUpDefaultServer();
 		sshd.setPort(addr.getPort());
@@ -200,14 +200,22 @@
 	}
 
 	public String formatUrl(String gituser, String servername, String repository) {
-		if (sshd.getPort() == DEFAULT_PORT) {
+		IStoredSettings settings = gitblit.getSettings();
+
+		int port = sshd.getPort();
+		int displayPort = settings.getInteger(Keys.git.sshAdvertisedPort, port);
+		String displayServername = settings.getString(Keys.git.sshAdvertisedHost, "");
+		if(displayServername.isEmpty()) {
+			displayServername = servername;
+		}
+		if (displayPort == DEFAULT_PORT) {
 			// standard port
-			return MessageFormat.format("ssh://{0}@{1}/{2}", gituser, servername,
+			return MessageFormat.format("ssh://{0}@{1}/{2}", gituser, displayServername,
 					repository);
 		} else {
 			// non-standard port
 			return MessageFormat.format("ssh://{0}@{1}:{2,number,0}/{3}",
-					gituser, servername, sshd.getPort(), repository);
+					gituser, displayServername, displayPort, repository);
 		}
 	}
 
diff --git a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
index 852756a..ec6f729 100644
--- a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
+++ b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
@@ -200,13 +200,18 @@
 		}
 
 		private String formatUrl(String hostname, int port, String username) {
-			if (port == 22) {
+			int displayPort = settings.getInteger(Keys.git.sshAdvertisedPort, port);
+			String displayHostname = settings.getString(Keys.git.sshAdvertisedHost, "");
+			if(displayHostname.isEmpty()) {
+				displayHostname = hostname;
+			}
+			if (displayPort == 22) {
 				// standard port
-				return MessageFormat.format("{0}@{1}/REPOSITORY.git", username, hostname);
+				return MessageFormat.format("{0}@{1}/REPOSITORY.git", username, displayHostname);
 			} else {
 				// non-standard port
 				return MessageFormat.format("ssh://{0}@{1}:{2,number,0}/REPOSITORY.git",
-						username, hostname, port);
+						username, displayHostname, displayPort);
 			}
 		}
 	}
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java
index f18b99b..02764db 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java
@@ -27,6 +27,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.manager.IGitblit;
 import com.gitblit.utils.StringUtils;
@@ -73,15 +74,20 @@
 
 	protected String getRepositoryUrl(String repository) {
 		String username = getContext().getClient().getUsername();
-		String hostname = getHostname();
-		int port = getContext().getGitblit().getSettings().getInteger(Keys.git.sshPort, 0);
-		if (port == 22) {
+		IStoredSettings settings = getContext().getGitblit().getSettings();
+		String displayHostname = settings.getString(Keys.git.sshAdvertisedHost, "");
+		if(displayHostname.isEmpty()) {
+			displayHostname = getHostname();
+		}
+		int port = settings.getInteger(Keys.git.sshPort, 0);
+		int displayPort = settings.getInteger(Keys.git.sshAdvertisedPort, port);
+		if (displayPort == 22) {
 			// standard port
-			return MessageFormat.format("{0}@{1}/{2}.git", username, hostname, repository);
+			return MessageFormat.format("{0}@{1}/{2}.git", username, displayHostname, repository);
 		} else {
 			// non-standard port
 			return MessageFormat.format("ssh://{0}@{1}:{2,number,0}/{3}",
-					username, hostname, port, repository);
+					username, displayHostname, displayPort, repository);
 		}
 	}
 

--
Gitblit v1.9.1