From 360a1e9a01d0f90ca6f46745825ce6bc14aa0411 Mon Sep 17 00:00:00 2001 From: Doug Kelly Date: Tue, 10 Nov 2015 10:23:21 -0800 Subject: [PATCH] Log agent version over SSH "agent" is a supported capability in the Git wire protocol, so we can log Git user versions. If the parameter is not supplied, it will not be listed as the final output in the sshd_log format. Change-Id: Id953696f1e48a27c9b837e27972337090f8c7e9d --- .../com/google/gerrit/sshd/CommandFactoryProvider.java | 2 +- .../src/main/java/com/google/gerrit/sshd/SshLog.java | 7 ++++++- .../main/java/com/google/gerrit/sshd/SshLogLayout.java | 2 ++ .../src/main/java/com/google/gerrit/sshd/SshSession.java | 9 +++++++++ .../java/com/google/gerrit/sshd/commands/Receive.java | 5 +++++ .../java/com/google/gerrit/sshd/commands/Upload.java | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandFactoryProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandFactoryProvider.java index 6bd9c4c30a..ee4984b79e 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandFactoryProvider.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandFactoryProvider.java @@ -217,7 +217,7 @@ class CommandFactoryProvider implements Provider, private void log(final int rc) { if (logged.compareAndSet(false, true)) { - log.onExecute(cmd, rc); + log.onExecute(cmd, rc, ctx.getSession()); } } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java index 3a8a1f5de1..cec3249d52 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLog.java @@ -47,6 +47,7 @@ class SshLog implements LifecycleListener { private static final String P_WAIT = "queueWaitTime"; private static final String P_EXEC = "executionTime"; private static final String P_STATUS = "status"; + private static final String P_AGENT = "agent"; private final Provider session; private final Provider context; @@ -115,7 +116,7 @@ class SshLog implements LifecycleListener { audit(null, "FAIL", "AUTH"); } - void onExecute(DispatchCommand dcmd, int exitValue) { + void onExecute(DispatchCommand dcmd, int exitValue, SshSession sshSession) { final Context ctx = context.get(); ctx.finished = TimeUtil.nowMs(); @@ -144,6 +145,10 @@ class SshLog implements LifecycleListener { break; } event.setProperty(P_STATUS, status); + String peerAgent = sshSession.getPeerAgent(); + if (peerAgent != null) { + event.setProperty(P_AGENT, peerAgent); + } if (async != null) { async.append(event); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLogLayout.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLogLayout.java index 0c047495c5..2bed29db87 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLogLayout.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshLogLayout.java @@ -31,6 +31,7 @@ public final class SshLogLayout extends Layout { private static final String P_WAIT = "queueWaitTime"; private static final String P_EXEC = "executionTime"; private static final String P_STATUS = "status"; + private static final String P_AGENT = "agent"; private final Calendar calendar; private long lastTimeMillis; @@ -66,6 +67,7 @@ public final class SshLogLayout extends Layout { opt(P_WAIT, buf, event); opt(P_EXEC, buf, event); opt(P_STATUS, buf, event); + opt(P_AGENT, buf, event); buf.append('\n'); return buf.toString(); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java index ff160e0c58..6285b205be 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java @@ -35,6 +35,7 @@ public class SshSession { private volatile CurrentUser identity; private volatile String username; private volatile String authError; + private volatile String peerAgent; SshSession(final int sessionId, SocketAddress peer) { this.sessionId = sessionId; @@ -72,6 +73,14 @@ public class SshSession { return remoteAsString; } + public String getPeerAgent() { + return peerAgent; + } + + public void setPeerAgent(String agent) { + peerAgent = agent; + } + String getUsername() { return username; } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java index 5950f91aad..0b12aa63e5 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java @@ -22,6 +22,7 @@ import com.google.gerrit.server.git.ReceiveCommits; import com.google.gerrit.server.git.VisibleRefFilter; import com.google.gerrit.sshd.AbstractGitCommand; import com.google.gerrit.sshd.CommandMetaData; +import com.google.gerrit.sshd.SshSession; import com.google.inject.Inject; import org.eclipse.jgit.errors.TooLargeObjectInPackException; @@ -55,6 +56,9 @@ final class Receive extends AbstractGitCommand { @Inject private IdentifiedUser.GenericFactory identifiedUserFactory; + @Inject + private SshSession session; + private final Set reviewerId = new HashSet<>(); private final Set ccId = new HashSet<>(); @@ -91,6 +95,7 @@ final class Receive extends AbstractGitCommand { ReceivePack rp = receive.getReceivePack(); try { rp.receive(in, out, err); + session.setPeerAgent(rp.getPeerUserAgent()); } catch (UnpackException badStream) { // In case this was caused by the user pushing an object whose size // is larger than the receive.maxObjectSizeLimit gerrit.config parameter diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Upload.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Upload.java index 34f7107059..9873c04014 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Upload.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Upload.java @@ -78,6 +78,7 @@ final class Upload extends AbstractGitCommand { up.setPreUploadHook(PreUploadHookChain.newChain(allPreUploadHooks)); try { up.upload(in, out, err); + session.setPeerAgent(up.getPeerUserAgent()); } catch (UploadValidationException e) { // UploadValidationException is used by the UploadValidators to // stop the uploadPack. We do not want this exception to go beyond this