Refactor success and createUser into SshUtil

To permit other forms of authentication to be performed,
having the generic set-up of the user and verification in a
common class allows this implementation to be called via
alternative authentication methods.

These changes have been migrated from DatabasePubKeyAuth into
SshUtil, with the only changes being from the required signatures
and a modification which doesn't require a key for the authentication
or success stage.

Change-Id: I59835e772d1f467ce5a49e8583064368cc3276b8
This commit is contained in:
Alex Blewitt
2013-04-01 11:47:50 -04:00
parent 2d9df5ddd1
commit e035784cd2
2 changed files with 54 additions and 47 deletions

View File

@@ -15,18 +15,14 @@
package com.google.gerrit.sshd;
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PeerDaemonUser;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.commons.codec.binary.Base64;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.Buffer;
@@ -104,7 +100,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
if (myHostKeys.contains(suppliedKey)
|| getPeerKeys().contains(suppliedKey)) {
PeerDaemonUser user = peerFactory.create(sd.getRemoteAddress());
return success(username, session, sd, user);
return SshUtil.success(username, session, sshScope, sshLog, sd, user);
} else {
sd.authenticationError(username, "no-matching-key");
@@ -144,12 +140,14 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
}
}
if (!createUser(sd, key).getAccount().isActive()) {
if (!SshUtil.createUser(sd, userFactory, key.getAccount())
.getAccount().isActive()) {
sd.authenticationError(username, "inactive-account");
return false;
}
return success(username, session, sd, createUser(sd, key));
return SshUtil.success(username, session, sshScope, sshLog, sd,
SshUtil.createUser(sd, userFactory, key.getAccount()));
}
private Set<PublicKey> getPeerKeys() {
@@ -161,46 +159,6 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
return p.keys;
}
private boolean success(final String username, final ServerSession session,
final SshSession sd, final CurrentUser user) {
if (sd.getCurrentUser() == null) {
sd.authenticationSuccess(username, user);
// 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 = sshScope.newContext(null, sd, null);
Context old = sshScope.set(ctx);
try {
sshLog.onLogin();
} finally {
sshScope.set(old);
}
session.getIoSession().getCloseFuture().addListener(
new IoFutureListener<IoFuture>() {
@Override
public void operationComplete(IoFuture future) {
final Context ctx = sshScope.newContext(null, sd, null);
final Context old = sshScope.set(ctx);
try {
sshLog.onLogout();
} finally {
sshScope.set(old);
}
}
});
}
return true;
}
private IdentifiedUser createUser(final SshSession sd,
final SshKeyCacheEntry key) {
return userFactory.create(sd.getRemoteAddress(), key.getAccount());
}
private SshKeyCacheEntry find(final Iterable<SshKeyCacheEntry> keyList,
final PublicKey suppliedKey) {
for (final SshKeyCacheEntry k : keyList) {

View File

@@ -14,12 +14,19 @@
package com.google.gerrit.sshd;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.sshd.SshScope.Context;
import org.apache.commons.codec.binary.Base64;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.Buffer;
import org.apache.sshd.server.session.ServerSession;
import org.eclipse.jgit.lib.Constants;
import java.io.BufferedReader;
@@ -112,4 +119,46 @@ public class SshUtil {
return keyStr;
}
}
public static boolean success(final String username, final ServerSession session,
final SshScope sshScope, final SshLog sshLog,
final SshSession sd, final CurrentUser user) {
if (sd.getCurrentUser() == null) {
sd.authenticationSuccess(username, user);
// 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 = sshScope.newContext(null, sd, null);
Context old = sshScope.set(ctx);
try {
sshLog.onLogin();
} finally {
sshScope.set(old);
}
session.getIoSession().getCloseFuture().addListener(
new IoFutureListener<IoFuture>() {
@Override
public void operationComplete(IoFuture future) {
final Context ctx = sshScope.newContext(null, sd, null);
final Context old = sshScope.set(ctx);
try {
sshLog.onLogout();
} finally {
sshScope.set(old);
}
}
});
}
return true;
}
public static IdentifiedUser createUser(final SshSession sd,
final IdentifiedUser.GenericFactory userFactory,
final Account.Id account) {
return userFactory.create(sd.getRemoteAddress(), account);
}
}