Revert "SSHD: Prevent double authentication for the same public key"

This reverts commit a5959d2216.

This revert is necessary because of downgrade to the SSHD 0.9.0.

Change-Id: Ia41ad2d9a713ddd515bc383923844227b676070f
This commit is contained in:
Saša Živkov
2014-12-05 13:55:51 +01:00
parent 074fd761bf
commit c7dedf989c
3 changed files with 11 additions and 83 deletions

View File

@@ -1,72 +0,0 @@
// Copyright (C) 2014 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.inject.Inject;
import com.google.inject.Singleton;
import org.apache.sshd.common.Session;
import org.apache.sshd.common.SessionListener;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Singleton
public class CachingPublicKeyAuthenticator implements PublickeyAuthenticator,
SessionListener {
private final PublickeyAuthenticator authenticator;
private final Map<ServerSession, Map<PublicKey, Boolean>> sessionCache;
@Inject
public CachingPublicKeyAuthenticator(DatabasePubKeyAuth authenticator) {
this.authenticator = authenticator;
this.sessionCache = new ConcurrentHashMap<>();
}
@Override
public boolean authenticate(String username, PublicKey key,
ServerSession session) {
Map<PublicKey, Boolean> m = sessionCache.get(session);
if (m == null) {
m = new HashMap<>();
sessionCache.put(session, m);
session.addListener(this);
}
if (m.containsKey(key)) {
return m.get(key);
}
boolean r = authenticator.authenticate(username, key, session);
m.put(key, r);
return r;
}
@Override
public void sessionCreated(Session session) {
}
@Override
public void sessionEvent(Session sesssion, Event event) {
}
@Override
public void sessionClosed(Session session) {
sessionCache.remove(session);
}
}

View File

@@ -14,13 +14,13 @@
package com.google.gerrit.sshd; package com.google.gerrit.sshd;
import com.google.common.base.Preconditions;
import com.google.gerrit.reviewdb.client.AccountSshKey; import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PeerDaemonUser; import com.google.gerrit.server.PeerDaemonUser;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.KeyPairProvider;
@@ -48,6 +48,7 @@ import java.util.Set;
/** /**
* Authenticates by public key through {@link AccountSshKey} entities. * Authenticates by public key through {@link AccountSshKey} entities.
*/ */
@Singleton
class DatabasePubKeyAuth implements PublickeyAuthenticator { class DatabasePubKeyAuth implements PublickeyAuthenticator {
private static final Logger log = private static final Logger log =
LoggerFactory.getLogger(DatabasePubKeyAuth.class); LoggerFactory.getLogger(DatabasePubKeyAuth.class);
@@ -91,11 +92,10 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
} }
} }
@Override public boolean authenticate(String username,
public boolean authenticate(String username, PublicKey suppliedKey, final PublicKey suppliedKey, final ServerSession session) {
ServerSession session) { final SshSession sd = session.getAttribute(SshSession.KEY);
SshSession sd = session.getAttribute(SshSession.KEY);
Preconditions.checkState(sd.getCurrentUser() == null);
if (PeerDaemonUser.USER_NAME.equals(username)) { if (PeerDaemonUser.USER_NAME.equals(username)) {
if (myHostKeys.contains(suppliedKey) if (myHostKeys.contains(suppliedKey)
|| getPeerKeys().contains(suppliedKey)) { || getPeerKeys().contains(suppliedKey)) {
@@ -112,10 +112,10 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
username = username.toLowerCase(Locale.US); username = username.toLowerCase(Locale.US);
} }
Iterable<SshKeyCacheEntry> keyList = sshKeyCache.get(username); final Iterable<SshKeyCacheEntry> keyList = sshKeyCache.get(username);
SshKeyCacheEntry key = find(keyList, suppliedKey); final SshKeyCacheEntry key = find(keyList, suppliedKey);
if (key == null) { if (key == null) {
String err; final String err;
if (keyList == SshKeyCacheImpl.NO_SUCH_USER) { if (keyList == SshKeyCacheImpl.NO_SUCH_USER) {
err = "user-not-found"; err = "user-not-found";
} else if (keyList == SshKeyCacheImpl.NO_KEYS) { } else if (keyList == SshKeyCacheImpl.NO_KEYS) {
@@ -133,7 +133,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
// security check to ensure there aren't two users sharing the same // security check to ensure there aren't two users sharing the same
// user name on the server. // user name on the server.
// //
for (SshKeyCacheEntry otherKey : keyList) { for (final SshKeyCacheEntry otherKey : keyList) {
if (!key.getAccount().equals(otherKey.getAccount())) { if (!key.getAccount().equals(otherKey.getAccount())) {
sd.authenticationError(username, "keys-cross-accounts"); sd.authenticationError(username, "keys-cross-accounts");
return false; return false;

View File

@@ -81,7 +81,7 @@ public class SshModule extends LifecycleModule {
bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON); bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON);
bind(GSSAuthenticator.class).to(GerritGSSAuthenticator.class); bind(GSSAuthenticator.class).to(GerritGSSAuthenticator.class);
bind(PublickeyAuthenticator.class).to(CachingPublicKeyAuthenticator.class); bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
bind(ModuleGenerator.class).to(SshAutoRegisterModuleGenerator.class); bind(ModuleGenerator.class).to(SshAutoRegisterModuleGenerator.class);
bind(SshPluginStarterCallback.class); bind(SshPluginStarterCallback.class);