Enable specific AccessPaths based on authentication

If the authentication method permits an AccessPath, add it to the
WebSession as a permitted path. Downstream from authentication a
CurrentUser can change its access path based on the entry point of
the request, allowing RefControl to make decisions around this as
expected, without running into the race condition of making user
before the real access method can be determined.

This allows authentication systems to decide on their own if the
REST_API was sufficiently protected from a potentially evil script.

Change-Id: Iefbe6745421f5f438bc06e2e4578a7207718b9a5
This commit is contained in:
Shawn O. Pearce
2012-11-14 10:55:26 -08:00
parent f7d96cbb03
commit 0185d428db
18 changed files with 107 additions and 101 deletions

View File

@@ -21,7 +21,6 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.apache.sshd.server.Environment;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -29,7 +28,6 @@ import org.eclipse.jgit.lib.Repository;
import org.kohsuke.args4j.Argument;
import java.io.IOException;
import java.net.SocketAddress;
public abstract class AbstractGitCommand extends BaseCommand {
@Argument(index = 0, metaVar = "PROJECT.git", required = true, usage = "project name")
@@ -84,13 +82,10 @@ public abstract class AbstractGitCommand extends BaseCommand {
}
private SshSession newSession() {
return new SshSession(session, session.getRemoteAddress(), userFactory
.create(AccessPath.GIT, new Provider<SocketAddress>() {
@Override
public SocketAddress get() {
return session.getRemoteAddress();
}
}, user.getAccountId()));
SshSession n = new SshSession(session, session.getRemoteAddress(),
userFactory.create(session.getRemoteAddress(), user.getAccountId()));
n.setAccessPath(AccessPath.GIT);
return n;
}
private void service() throws IOException, Failure {

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.sshd;
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PeerDaemonUser;
@@ -23,7 +22,6 @@ 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.Provider;
import com.google.inject.Singleton;
import org.apache.commons.codec.binary.Base64;
@@ -43,7 +41,6 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.SocketAddress;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.Collection;
@@ -201,13 +198,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
private IdentifiedUser createUser(final SshSession sd,
final SshKeyCacheEntry key) {
return userFactory.create(AccessPath.SSH_COMMAND,
new Provider<SocketAddress>() {
@Override
public SocketAddress get() {
return sd.getRemoteAddress();
}
}, key.getAccount());
return userFactory.create(sd.getRemoteAddress(), key.getAccount());
}
private SshKeyCacheEntry find(final Iterable<SshKeyCacheEntry> keyList,

View File

@@ -73,8 +73,7 @@ class SshScope {
public CurrentUser getCurrentUser() {
final CurrentUser user = session.getCurrentUser();
if (user instanceof IdentifiedUser) {
return userFactory.create(user.getAccessPath(), //
((IdentifiedUser) user).getAccountId());
return userFactory.create(((IdentifiedUser) user).getAccountId());
}
return user;
}

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.sshd;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser;
import org.apache.sshd.common.Session.AttributeKey;
@@ -43,6 +44,7 @@ public class SshSession {
}
SshSession(SshSession parent, SocketAddress peer, CurrentUser user) {
user.setAccessPath(AccessPath.SSH_COMMAND);
this.sessionId = parent.sessionId;
this.remoteAddress = peer;
if (parent.remoteAddress == peer) {
@@ -83,6 +85,10 @@ public class SshSession {
authError = error;
}
void setAccessPath(AccessPath path) {
identity.setAccessPath(path);
}
/** @return {@code true} if the authentication did not succeed. */
boolean isAuthenticationError() {
return authError != null;

View File

@@ -16,7 +16,6 @@ package com.google.gerrit.sshd;
import com.google.common.util.concurrent.Atomics;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PeerDaemonUser;
@@ -116,14 +115,8 @@ public final class SuExec extends BaseCommand {
} else {
peer = peerAddress;
}
return new SshSession(session.get(), peer, userFactory.create(
AccessPath.SSH_COMMAND, new Provider<SocketAddress>() {
@Override
public SocketAddress get() {
return peer;
}
}, accountId));
return new SshSession(session.get(), peer,
userFactory.create(peer, accountId));
}
private static String join(List<String> args) {