Merge "Update jgit to f2e5bace4841758927d47db7d20e4a6f7353ce57" into stable-3.2
diff --git a/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java b/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java
index be975c5..b685011 100644
--- a/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java
+++ b/java/com/google/gerrit/httpd/auth/openid/OpenIdServiceImpl.java
@@ -477,8 +477,9 @@
     final StringBuilder rdr = new StringBuilder();
     rdr.append(urlProvider.get(req));
     String nextToken = Url.decode(token);
-    if (isNew && !token.startsWith(PageLinks.REGISTER + "/")) {
-      rdr.append('#' + PageLinks.REGISTER);
+    String registerUri = PageLinks.REGISTER + "/";
+    if (isNew && !token.startsWith(registerUri)) {
+      rdr.append('#' + registerUri);
       if (nextToken.startsWith("#")) {
         // Need to strip the leading # off the token to fix registration page redirect
         nextToken = nextToken.substring(1);
diff --git a/java/com/google/gerrit/sshd/LogMaxConnectionsPerUserExceeded.java b/java/com/google/gerrit/sshd/LogMaxConnectionsPerUserExceeded.java
new file mode 100644
index 0000000..6f568b1
--- /dev/null
+++ b/java/com/google/gerrit/sshd/LogMaxConnectionsPerUserExceeded.java
@@ -0,0 +1,42 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// 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.google.gerrit.sshd;
+
+import com.google.common.flogger.FluentLogger;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import org.apache.sshd.common.Service;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionDisconnectHandler;
+
+@Singleton
+public class LogMaxConnectionsPerUserExceeded implements SessionDisconnectHandler {
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+  @Override
+  public boolean handleSessionsCountDisconnectReason(
+      Session session,
+      Service service,
+      String username,
+      int currentSessionCount,
+      int maxSessionCount)
+      throws IOException {
+    logger.atWarning().log(
+        "Max connection count for user %s exceeded, rejecting new connection."
+            + " currentSessionCount = %d, maxSessionCount = %d",
+        username, currentSessionCount, maxSessionCount);
+    return false;
+  }
+}
diff --git a/java/com/google/gerrit/sshd/SshDaemon.java b/java/com/google/gerrit/sshd/SshDaemon.java
index c14ebd8..fa3529c 100644
--- a/java/com/google/gerrit/sshd/SshDaemon.java
+++ b/java/com/google/gerrit/sshd/SshDaemon.java
@@ -161,7 +161,8 @@
       SshLog sshLog,
       @SshListenAddresses List<SocketAddress> listen,
       @SshAdvertisedAddresses List<String> advertised,
-      MetricMaker metricMaker) {
+      MetricMaker metricMaker,
+      LogMaxConnectionsPerUserExceeded logMaxConnectionsPerUserExceeded) {
     setPort(IANA_SSH_PORT /* never used */);
 
     this.cfg = cfg;
@@ -241,6 +242,7 @@
     setKeyPairProvider(hostKeyProvider);
     setCommandFactory(commandFactory);
     setShellFactory(noShell);
+    setSessionDisconnectHandler(logMaxConnectionsPerUserExceeded);
 
     final AtomicInteger connected = new AtomicInteger();
     metricMaker.newCallbackMetric(