Stop allowing password authentication over SSH
For a service like Gerrit Code Review, it just doesn't make much sense to offer password authentication for users. Anyone who sets up an account with us can configure an SSH key and use that for login. Change-Id: I93373e0a69a7d9adf48001d58983dc8233dcf22e Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
dabf1acee4
commit
8840552f5f
@ -1,116 +0,0 @@
|
||||
// Copyright (C) 2010 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.gerrit.reviewdb.AccountExternalId;
|
||||
import com.google.gerrit.server.AccessPath;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountCache;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gerrit.sshd.SshScope.Context;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.apache.mina.core.future.IoFuture;
|
||||
import org.apache.mina.core.future.IoFutureListener;
|
||||
import org.apache.sshd.server.PasswordAuthenticator;
|
||||
import org.apache.sshd.server.session.ServerSession;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* Authenticates by password through {@link AccountExternalId} entities.
|
||||
*/
|
||||
@Singleton
|
||||
class DatabasePasswordAuth implements PasswordAuthenticator {
|
||||
private final AccountCache accountCache;
|
||||
private final SshLog log;
|
||||
private final IdentifiedUser.GenericFactory userFactory;
|
||||
|
||||
@Inject
|
||||
DatabasePasswordAuth(final AccountCache ac, final SshLog l,
|
||||
final IdentifiedUser.GenericFactory uf) {
|
||||
accountCache = ac;
|
||||
log = l;
|
||||
userFactory = uf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(final String username, final String password,
|
||||
final ServerSession session) {
|
||||
final SshSession sd = session.getAttribute(SshSession.KEY);
|
||||
|
||||
AccountState state = accountCache.getByUsername(username);
|
||||
if (state == null) {
|
||||
sd.authenticationError(username, "user-not-found");
|
||||
return false;
|
||||
}
|
||||
|
||||
final String p = state.getPassword(username);
|
||||
if (p == null) {
|
||||
sd.authenticationError(username, "no-password");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p.equals(password)) {
|
||||
sd.authenticationError(username, "incorrect-password");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sd.getCurrentUser() == null) {
|
||||
sd.authenticationSuccess(username, createUser(sd, state));
|
||||
|
||||
// If this is the first time we've authenticated this
|
||||
// session, record a login event in the log and add
|
||||
// a close listener to record a logout event.
|
||||
//
|
||||
Context ctx = new Context(sd, null);
|
||||
Context old = SshScope.set(ctx);
|
||||
try {
|
||||
log.onLogin();
|
||||
} finally {
|
||||
SshScope.set(old);
|
||||
}
|
||||
|
||||
session.getIoSession().getCloseFuture().addListener(
|
||||
new IoFutureListener<IoFuture>() {
|
||||
@Override
|
||||
public void operationComplete(IoFuture future) {
|
||||
final Context ctx = new Context(sd, null);
|
||||
final Context old = SshScope.set(ctx);
|
||||
try {
|
||||
log.onLogout();
|
||||
} finally {
|
||||
SshScope.set(old);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private IdentifiedUser createUser(final SshSession sd,
|
||||
final AccountState state) {
|
||||
return userFactory.create(AccessPath.SSH_COMMAND,
|
||||
new Provider<SocketAddress>() {
|
||||
@Override
|
||||
public SocketAddress get() {
|
||||
return sd.getRemoteAddress();
|
||||
}
|
||||
}, state.getAccount().getId());
|
||||
}
|
||||
}
|
@ -59,10 +59,8 @@ import org.apache.sshd.common.util.SecurityUtils;
|
||||
import org.apache.sshd.server.Command;
|
||||
import org.apache.sshd.server.CommandFactory;
|
||||
import org.apache.sshd.server.ForwardingFilter;
|
||||
import org.apache.sshd.server.PasswordAuthenticator;
|
||||
import org.apache.sshd.server.PublickeyAuthenticator;
|
||||
import org.apache.sshd.server.UserAuth;
|
||||
import org.apache.sshd.server.auth.UserAuthPassword;
|
||||
import org.apache.sshd.server.auth.UserAuthPublicKey;
|
||||
import org.apache.sshd.server.channel.ChannelDirectTcpip;
|
||||
import org.apache.sshd.server.channel.ChannelSession;
|
||||
@ -119,7 +117,6 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
|
||||
|
||||
@Inject
|
||||
SshDaemon(final CommandFactory commandFactory,
|
||||
final PasswordAuthenticator passAuth,
|
||||
final PublickeyAuthenticator userAuth,
|
||||
final KeyPairProvider hostKeyProvider, final IdGenerator idGenerator,
|
||||
@GerritServerConfig final Config cfg, final SshLog sshLog) {
|
||||
@ -141,7 +138,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
|
||||
initForwardingFilter();
|
||||
initSubsystems();
|
||||
initCompression();
|
||||
initUserAuth(passAuth, userAuth);
|
||||
initUserAuth(userAuth);
|
||||
setKeyPairProvider(hostKeyProvider);
|
||||
setCommandFactory(commandFactory);
|
||||
setShellFactory(new NoShell());
|
||||
@ -459,11 +456,9 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void initUserAuth(final PasswordAuthenticator pass,
|
||||
final PublickeyAuthenticator pubkey) {
|
||||
setUserAuthFactories(Arrays.<NamedFactory<UserAuth>> asList(
|
||||
new UserAuthPublicKey.Factory(), new UserAuthPassword.Factory()));
|
||||
setPasswordAuthenticator(pass);
|
||||
private void initUserAuth(final PublickeyAuthenticator pubkey) {
|
||||
setUserAuthFactories(Arrays
|
||||
.<NamedFactory<UserAuth>> asList(new UserAuthPublicKey.Factory()));
|
||||
setPublickeyAuthenticator(pubkey);
|
||||
}
|
||||
|
||||
|
@ -40,14 +40,12 @@ import com.google.gerrit.util.cli.CmdLineParser;
|
||||
import com.google.gerrit.util.cli.OptionHandlerFactory;
|
||||
import com.google.gerrit.util.cli.OptionHandlerUtil;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
import com.google.inject.servlet.RequestScoped;
|
||||
|
||||
import org.apache.sshd.common.KeyPairProvider;
|
||||
import org.apache.sshd.server.CommandFactory;
|
||||
import org.apache.sshd.server.PasswordAuthenticator;
|
||||
import org.apache.sshd.server.PublickeyAuthenticator;
|
||||
import org.kohsuke.args4j.spi.OptionHandler;
|
||||
|
||||
@ -78,7 +76,6 @@ public class SshModule extends FactoryModule {
|
||||
bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON);
|
||||
|
||||
bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
|
||||
bind(PasswordAuthenticator.class).to(DatabasePasswordAuth.class);
|
||||
bind(KeyPairProvider.class).toProvider(HostKeyProvider.class).in(SINGLETON);
|
||||
bind(TransferConfig.class);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user