From 8d96b960e472433d2b4a5b71df7000bf1fbde648 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 10 Apr 2014 18:58:10 -0400
Subject: [PATCH] Track the SSH public key used for a session and add a `keys which` command

---
 src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java          |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java        |   30 +++++++++++++++
 src/main/java/com/gitblit/transport/ssh/WelcomeShell.java                  |   26 ++++++++-----
 src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java               |   10 +++++
 src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java |    1 
 5 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java b/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java
index eb6f4b6..48e5aa2 100644
--- a/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java
+++ b/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java
@@ -90,6 +90,7 @@
 				UserModel user = authManager.authenticate(username, key);
 				if (user != null) {
 					client.setUser(user);
+					client.setKey(key);
 					return true;
 				}
 			}
diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java b/src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java
index 4d8ea4b..a5d4c3d 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java
+++ b/src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java
@@ -32,6 +32,7 @@
 	private final SocketAddress remoteAddress;
 
 	private volatile UserModel user;
+	private volatile SshKey key;
 	private volatile String repositoryName;
 
 	SshDaemonClient(SocketAddress peer) {
@@ -61,4 +62,13 @@
 	public String getRepositoryName() {
 		return repositoryName;
 	}
+
+	public SshKey getKey() {
+		return key;
+	}
+
+	public void setKey(SshKey key) {
+		this.key = key;
+	}
+
 }
diff --git a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
index a9fe6f0..bcf30c2 100644
--- a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
+++ b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
@@ -134,8 +134,10 @@
 			msg.append(user.getDisplayName());
 			msg.append(", you have successfully connected over SSH.");
 			msg.append(nl);
+			msg.append(" Interactive shells are disabled.");
 			msg.append(nl);
-			msg.append("   client: ");
+			msg.append(nl);
+			msg.append("   client:   ");
 			msg.append(session.getClientVersion());
 			msg.append(nl);
 			msg.append(nl);
@@ -156,17 +158,21 @@
 			msg.append(nl);
 			msg.append(nl);
 
-			msg.append(" You may upload an SSH public key with the following syntax:");
-			msg.append(nl);
-			msg.append(nl);
+			if (client.getKey() == null) {
+				// user has authenticated with a password
+				// display add public key instructions
+				msg.append(" You may upload an SSH public key with the following syntax:");
+				msg.append(nl);
+				msg.append(nl);
 
-			msg.append(String.format("   cat ~/.ssh/id_rsa.pub | ssh -l %s -p %d %s gitblit keys add -", user.username, port, hostname));
-			msg.append(nl);
-			msg.append(nl);
+				msg.append(String.format("   cat ~/.ssh/id_rsa.pub | ssh -l %s -p %d %s gitblit keys add -", user.username, port, hostname));
+				msg.append(nl);
+				msg.append(nl);
 
-			msg.append(b2);
-			msg.append(nl);
-			msg.append(nl);
+				msg.append(b2);
+				msg.append(nl);
+				msg.append(nl);
+			}
 
 			// display the core commands
 			SshCommandFactory cmdFactory = (SshCommandFactory) session.getFactoryManager().getCommandFactory();
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
index d24a716..6662a32 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
@@ -219,7 +219,7 @@
 			msg.write(' ');
 			msg.write(commandName);
 			msg.write('\n');
-			msg.write(' ');
+			msg.write("  ");
 			clp.printSingleLineUsage(msg, null);
 			msg.write("\n\n");
 			msg.write("ARGUMENTS & OPTIONS\n");
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
index 61764c4..b42be17 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
@@ -48,6 +48,7 @@
 		register(user, AddKey.class);
 		register(user, RemoveKey.class);
 		register(user, ListKeys.class);
+		register(user, WhichKey.class);
 	}
 
 	@CommandMetaData(name = "add", description = "Add an SSH public key to your account")
@@ -177,4 +178,33 @@
 			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
 		}
 	}
+
+	@CommandMetaData(name = "which", description = "Display the SSH public key used for this session")
+	public static class WhichKey extends SshCommand {
+
+		@Option(name = "-L", usage = "list complete public key parameters")
+		private boolean showRaw;
+
+		@Override
+		public void run() throws UnloggedFailure {
+			SshKey key = getContext().getClient().getKey();
+			if (key == null) {
+				throw new UnloggedFailure(1,  "You have not authenticated with an SSH public key.");
+			}
+
+			if (showRaw) {
+				stdout.println(key.getRawData());
+			} else {
+				asTable(key);
+			}
+		}
+
+		protected void asTable(SshKey key) {
+			String[] headers = { "Fingerprint", "Comment", "Type" };
+			Object[][] data = new Object[1][];
+			data[0] = new Object[] { key.getFingerprint(), key.getComment(), key.getAlgorithm() };
+
+			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
+		}
+	}
 }

--
Gitblit v1.9.1