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

@@ -35,6 +35,8 @@ import com.google.inject.servlet.RequestScoped;
import org.eclipse.jgit.http.server.GitSmartHttpTools; import org.eclipse.jgit.http.server.GitSmartHttpTools;
import java.util.EnumSet;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -66,7 +68,7 @@ public final class CacheBasedWebSession implements WebSession {
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final Provider<AnonymousUser> anonymousProvider; private final Provider<AnonymousUser> anonymousProvider;
private final IdentifiedUser.RequestFactory identified; private final IdentifiedUser.RequestFactory identified;
private AccessPath accessPath; private final EnumSet<AccessPath> okPaths = EnumSet.of(AccessPath.UNKNOWN);
private Cookie outCookie; private Cookie outCookie;
private Key key; private Key key;
@@ -85,36 +87,31 @@ public final class CacheBasedWebSession implements WebSession {
this.anonymousProvider = anonymousProvider; this.anonymousProvider = anonymousProvider;
this.identified = identified; this.identified = identified;
String cookie = request.getHeader("Authorization"); if (!GitSmartHttpTools.isGitClient(request)) {
if (cookie != null && cookie.startsWith("Bearer ")) { String cookie = readCookie();
cookie = cookie.substring("Bearer ".length()); String token = request.getHeader("Authorization");
accessPath = AccessPath.REST_API; if (token != null && token.startsWith("Bearer ")) {
} else if (cookie != null && GitSmartHttpTools.isGitClient(request)) { token = token.substring("Bearer ".length());
accessPath = AccessPath.GIT; okPaths.add(AccessPath.REST_API);
} else { } else {
cookie = readCookie(); token = cookie;
accessPath = AccessPath.WEB_BROWSER;
} }
if (cookie != null) { if (token != null) {
key = new Key(cookie); key = new Key(token);
val = manager.get(key); val = manager.get(key);
} else {
key = null;
val = null;
}
if (isSignedIn() && val.needsCookieRefresh()) { if (isSignedIn() && val.needsCookieRefresh()) {
// Cookie is more than half old. Send the cookie again to the // Cookie is more than half old. Send the cookie again to the
// client with an updated expiration date. We don't dare to // client with an updated expiration date.
// change the key token here because there may be other RPCs
// queued up in the browser whose xsrfKey would not get updated
// with the new token, causing them to fail.
//
val = manager.createVal(key, val); val = manager.createVal(key, val);
if (cookie != null) {
saveCookie(); saveCookie();
} }
} }
}
}
}
private String readCookie() { private String readCookie() {
final Cookie[] all = request.getCookies(); final Cookie[] all = request.getCookies();
@@ -129,10 +126,12 @@ public final class CacheBasedWebSession implements WebSession {
return null; return null;
} }
@Override
public boolean isSignedIn() { public boolean isSignedIn() {
return val != null; return val != null;
} }
@Override
public String getAuthorization() { public String getAuthorization() {
return isSignedIn() ? "Bearer " + key.getToken() : null; return isSignedIn() ? "Bearer " + key.getToken() : null;
} }
@@ -142,17 +141,34 @@ public final class CacheBasedWebSession implements WebSession {
return keyIn.equals(getAuthorization()); return keyIn.equals(getAuthorization());
} }
@Override
public boolean isAccessPathOk(AccessPath path) {
return okPaths.contains(path);
}
@Override
public void setAccessPathOk(AccessPath path, boolean ok) {
if (ok) {
okPaths.add(path);
} else {
okPaths.remove(path);
}
}
@Override
public AccountExternalId.Key getLastLoginExternalId() { public AccountExternalId.Key getLastLoginExternalId() {
return val != null ? val.getExternalId() : null; return val != null ? val.getExternalId() : null;
} }
@Override
public CurrentUser getCurrentUser() { public CurrentUser getCurrentUser() {
if (isSignedIn()) { if (isSignedIn()) {
return identified.create(accessPath, val.getAccountId()); return identified.create(val.getAccountId());
} }
return anonymousProvider.get(); return anonymousProvider.get();
} }
@Override
public void login(final AuthResult res, final boolean rememberMe) { public void login(final AuthResult res, final boolean rememberMe) {
final Account.Id id = res.getAccountId(); final Account.Id id = res.getAccountId();
final AccountExternalId.Key identity = res.getExternalId(); final AccountExternalId.Key identity = res.getExternalId();
@@ -167,11 +183,13 @@ public final class CacheBasedWebSession implements WebSession {
} }
/** Set the user account for this current request only. */ /** Set the user account for this current request only. */
@Override
public void setUserAccountId(Account.Id id) { public void setUserAccountId(Account.Id id) {
key = new Key("id:" + id); key = new Key("id:" + id);
val = new Val(id, 0, false, null, 0, null); val = new Val(id, 0, false, null, 0, null);
} }
@Override
public void logout() { public void logout() {
if (val != null) { if (val != null) {
manager.destroy(key); manager.destroy(key);

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.httpd;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
@@ -99,7 +100,10 @@ class ContainerAuthFilter implements Filter {
rsp.sendError(SC_UNAUTHORIZED); rsp.sendError(SC_UNAUTHORIZED);
return false; return false;
} }
session.get().setUserAccountId(who.getAccount().getId()); WebSession ws = session.get();
ws.setUserAccountId(who.getAccount().getId());
ws.setAccessPathOk(AccessPath.GIT, true);
ws.setAccessPathOk(AccessPath.REST_API, true);
return true; return true;
} }
} }

View File

@@ -18,7 +18,9 @@ import com.google.common.cache.Cache;
import com.google.gerrit.common.data.Capable; import com.google.gerrit.common.data.Capable;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser; import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.cache.CacheModule; import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.git.AsyncReceiveCommits; import com.google.gerrit.server.git.AsyncReceiveCommits;
@@ -157,8 +159,12 @@ public class GitOverHttpServlet extends GitServlet {
} catch (NoSuchProjectException err) { } catch (NoSuchProjectException err) {
throw new RepositoryNotFoundException(projectName); throw new RepositoryNotFoundException(projectName);
} }
CurrentUser user = pc.getCurrentUser();
user.setAccessPath(AccessPath.GIT);
if (!pc.isVisible()) { if (!pc.isVisible()) {
if (pc.getCurrentUser() instanceof AnonymousUser) { if (user instanceof AnonymousUser) {
throw new ServiceNotAuthorizedException(); throw new ServiceNotAuthorizedException();
} else { } else {
throw new ServiceNotEnabledException(); throw new ServiceNotEnabledException();

View File

@@ -18,6 +18,7 @@ import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountException; import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager; import com.google.gerrit.server.account.AccountManager;
@@ -103,10 +104,9 @@ class ProjectBasicAuthFilter implements Filter {
private boolean verify(HttpServletRequest req, Response rsp) private boolean verify(HttpServletRequest req, Response rsp)
throws IOException { throws IOException {
final String hdr = req.getHeader(AUTHORIZATION); final String hdr = req.getHeader(AUTHORIZATION);
if (hdr == null) { if (hdr == null || !hdr.startsWith(LIT_BASIC)) {
// Allow an anonymous connection through, or it might be using a // Allow an anonymous connection through, or it might be using a
// session cookie instead of basic authentication. // session cookie instead of basic authentication.
//
return true; return true;
} }
@@ -142,7 +142,10 @@ class ProjectBasicAuthFilter implements Filter {
try { try {
AuthResult whoAuthResult = accountManager.authenticate(whoAuth); AuthResult whoAuthResult = accountManager.authenticate(whoAuth);
session.get().setUserAccountId(whoAuthResult.getAccountId()); WebSession ws = session.get();
ws.setUserAccountId(whoAuthResult.getAccountId());
ws.setAccessPathOk(AccessPath.GIT, true);
ws.setAccessPathOk(AccessPath.REST_API, true);
return true; return true;
} catch (AccountException e) { } catch (AccountException e) {
log.warn("Authentication failed for " + username, e); log.warn("Authentication failed for " + username, e);

View File

@@ -20,6 +20,7 @@ import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.CanonicalWebUrl;
@@ -109,10 +110,9 @@ class ProjectDigestFilter implements Filter {
private boolean verify(HttpServletRequest req, Response rsp) private boolean verify(HttpServletRequest req, Response rsp)
throws IOException { throws IOException {
final String hdr = req.getHeader(AUTHORIZATION); final String hdr = req.getHeader(AUTHORIZATION);
if (hdr == null) { if (hdr == null || !hdr.startsWith("Digest ")) {
// Allow an anonymous connection through, or it might be using a // Allow an anonymous connection through, or it might be using a
// session cookie instead of digest authentication. // session cookie instead of digest authentication.
//
return true; return true;
} }
@@ -164,7 +164,10 @@ class ProjectDigestFilter implements Filter {
if (expect.equals(response)) { if (expect.equals(response)) {
try { try {
if (tokens.checkToken(nonce, "") != null) { if (tokens.checkToken(nonce, "") != null) {
session.get().setUserAccountId(who.getAccount().getId()); WebSession ws = session.get();
ws.setUserAccountId(who.getAccount().getId());
ws.setAccessPathOk(AccessPath.GIT, true);
ws.setAccessPathOk(AccessPath.REST_API, true);
return true; return true;
} else { } else {
@@ -229,12 +232,6 @@ class ProjectDigestFilter implements Filter {
} }
private Map<String, String> parseAuthorization(String auth) { private Map<String, String> parseAuthorization(String auth) {
if (!auth.startsWith("Digest ")) {
// We only support Digest authentication scheme, deny the rest.
//
return Collections.emptyMap();
}
Map<String, String> p = new HashMap<String, String>(); Map<String, String> p = new HashMap<String, String>();
int next = "Digest ".length(); int next = "Digest ".length();
while (next < auth.length()) { while (next < auth.length()) {

View File

@@ -16,26 +16,23 @@ package com.google.gerrit.httpd;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountExternalId; import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AuthResult; import com.google.gerrit.server.account.AuthResult;
public interface WebSession { public interface WebSession {
public boolean isSignedIn(); public boolean isSignedIn();
public String getAuthorization(); public String getAuthorization();
public boolean isValidAuthorization(String keyIn); public boolean isValidAuthorization(String keyIn);
public AccountExternalId.Key getLastLoginExternalId(); public AccountExternalId.Key getLastLoginExternalId();
public CurrentUser getCurrentUser(); public CurrentUser getCurrentUser();
public void login(AuthResult res, boolean rememberMe); public void login(AuthResult res, boolean rememberMe);
/** Set the user account for this current request only. */ /** Set the user account for this current request only. */
public void setUserAccountId(Account.Id id); public void setUserAccountId(Account.Id id);
public boolean isAccessPathOk(AccessPath path);
public void setAccessPathOk(AccessPath path, boolean ok);
public void logout(); public void logout();
public String getSessionId(); public String getSessionId();
} }

View File

@@ -30,7 +30,7 @@ import java.util.Set;
public class AnonymousUser extends CurrentUser { public class AnonymousUser extends CurrentUser {
@Inject @Inject
AnonymousUser(CapabilityControl.Factory capabilityControlFactory) { AnonymousUser(CapabilityControl.Factory capabilityControlFactory) {
super(capabilityControlFactory, AccessPath.UNKNOWN); super(capabilityControlFactory);
} }
@Override @Override

View File

@@ -33,15 +33,12 @@ import java.util.Set;
*/ */
public abstract class CurrentUser { public abstract class CurrentUser {
private final CapabilityControl.Factory capabilityControlFactory; private final CapabilityControl.Factory capabilityControlFactory;
private final AccessPath accessPath; private AccessPath accessPath = AccessPath.UNKNOWN;
private CapabilityControl capabilities; private CapabilityControl capabilities;
protected CurrentUser( protected CurrentUser(CapabilityControl.Factory capabilityControlFactory) {
CapabilityControl.Factory capabilityControlFactory,
AccessPath accessPath) {
this.capabilityControlFactory = capabilityControlFactory; this.capabilityControlFactory = capabilityControlFactory;
this.accessPath = accessPath;
} }
/** How this user is accessing the Gerrit Code Review application. */ /** How this user is accessing the Gerrit Code Review application. */
@@ -49,6 +46,10 @@ public abstract class CurrentUser {
return accessPath; return accessPath;
} }
public void setAccessPath(AccessPath path) {
accessPath = path;
}
/** /**
* Get the set of groups the user is currently a member of. * Get the set of groups the user is currently a member of.
* <p> * <p>

View File

@@ -38,6 +38,7 @@ import com.google.inject.Inject;
import com.google.inject.OutOfScopeException; import com.google.inject.OutOfScopeException;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.google.inject.util.Providers;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.SystemReader;
@@ -90,20 +91,19 @@ public class IdentifiedUser extends CurrentUser {
} }
public IdentifiedUser create(final Account.Id id) { public IdentifiedUser create(final Account.Id id) {
return create(AccessPath.UNKNOWN, null, id); return create((SocketAddress) null, id);
} }
public IdentifiedUser create(Provider<ReviewDb> db, Account.Id id) { public IdentifiedUser create(Provider<ReviewDb> db, Account.Id id) {
return new IdentifiedUser(capabilityControlFactory, AccessPath.UNKNOWN, return new IdentifiedUser(capabilityControlFactory,
authConfig, anonymousCowardName, canonicalUrl, realm, accountCache, authConfig, anonymousCowardName, canonicalUrl, realm, accountCache,
groupBackend, null, db, id); groupBackend, null, db, id);
} }
public IdentifiedUser create(AccessPath accessPath, public IdentifiedUser create(SocketAddress remotePeer, Account.Id id) {
Provider<SocketAddress> remotePeerProvider, Account.Id id) { return new IdentifiedUser(capabilityControlFactory,
return new IdentifiedUser(capabilityControlFactory, accessPath,
authConfig, anonymousCowardName, canonicalUrl, realm, accountCache, authConfig, anonymousCowardName, canonicalUrl, realm, accountCache,
groupBackend, remotePeerProvider, null, id); groupBackend, Providers.of(remotePeer), null, id);
} }
} }
@@ -149,9 +149,8 @@ public class IdentifiedUser extends CurrentUser {
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
} }
public IdentifiedUser create(final AccessPath accessPath, public IdentifiedUser create(Account.Id id) {
final Account.Id id) { return new IdentifiedUser(capabilityControlFactory,
return new IdentifiedUser(capabilityControlFactory, accessPath,
authConfig, anonymousCowardName, canonicalUrl, realm, accountCache, authConfig, anonymousCowardName, canonicalUrl, realm, accountCache,
groupBackend, remotePeerProvider, dbProvider, id); groupBackend, remotePeerProvider, dbProvider, id);
} }
@@ -187,7 +186,6 @@ public class IdentifiedUser extends CurrentUser {
private IdentifiedUser( private IdentifiedUser(
CapabilityControl.Factory capabilityControlFactory, CapabilityControl.Factory capabilityControlFactory,
final AccessPath accessPath,
final AuthConfig authConfig, final AuthConfig authConfig,
final String anonymousCowardName, final String anonymousCowardName,
final Provider<String> canonicalUrl, final Provider<String> canonicalUrl,
@@ -195,7 +193,7 @@ public class IdentifiedUser extends CurrentUser {
final GroupBackend groupBackend, final GroupBackend groupBackend,
@Nullable final Provider<SocketAddress> remotePeerProvider, @Nullable final Provider<SocketAddress> remotePeerProvider,
@Nullable final Provider<ReviewDb> dbProvider, final Account.Id id) { @Nullable final Provider<ReviewDb> dbProvider, final Account.Id id) {
super(capabilityControlFactory, accessPath); super(capabilityControlFactory);
this.canonicalUrl = canonicalUrl; this.canonicalUrl = canonicalUrl;
this.accountCache = accountCache; this.accountCache = accountCache;
this.groupBackend = groupBackend; this.groupBackend = groupBackend;

View File

@@ -39,7 +39,7 @@ public class InternalUser extends CurrentUser {
@Inject @Inject
protected InternalUser(CapabilityControl.Factory capabilityControlFactory) { protected InternalUser(CapabilityControl.Factory capabilityControlFactory) {
super(capabilityControlFactory, AccessPath.UNKNOWN); super(capabilityControlFactory);
} }
@Override @Override

View File

@@ -40,7 +40,7 @@ public class PeerDaemonUser extends CurrentUser {
@Inject @Inject
protected PeerDaemonUser(CapabilityControl.Factory capabilityControlFactory, protected PeerDaemonUser(CapabilityControl.Factory capabilityControlFactory,
@Assisted SocketAddress peer) { @Assisted SocketAddress peer) {
super(capabilityControlFactory, AccessPath.SSH_COMMAND); super(capabilityControlFactory);
this.peer = peer; this.peer = peer;
} }

View File

@@ -17,7 +17,6 @@ package com.google.gerrit.server.query.change;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountProjectWatch; import com.google.gerrit.reviewdb.client.AccountProjectWatch;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl; import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
@@ -37,7 +36,7 @@ public final class SingleGroupUser extends CurrentUser {
public SingleGroupUser(CapabilityControl.Factory capabilityControlFactory, public SingleGroupUser(CapabilityControl.Factory capabilityControlFactory,
Set<AccountGroup.UUID> groups) { Set<AccountGroup.UUID> groups) {
super(capabilityControlFactory, AccessPath.UNKNOWN); super(capabilityControlFactory);
this.groups = new ListGroupMembership(groups); this.groups = new ListGroupMembership(groups);
} }

View File

@@ -33,7 +33,6 @@ import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.rules.PrologEnvironment; import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.RulesCache; import com.google.gerrit.rules.RulesCache;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl; import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
@@ -415,7 +414,7 @@ public class RefControlTest extends TestCase {
private final GroupMembership groups; private final GroupMembership groups;
MockUser(String name, AccountGroup.UUID[] groupId) { MockUser(String name, AccountGroup.UUID[] groupId) {
super(RefControlTest.this.capabilityControlFactory, AccessPath.UNKNOWN); super(RefControlTest.this.capabilityControlFactory);
username = name; username = name;
ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId); ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId);
groupIds.add(registered); groupIds.add(registered);

View File

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

View File

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

View File

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

View File

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

View File

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