}\r
\r
public static enum AuthenticationType {\r
- SSH, CREDENTIALS, COOKIE, CERTIFICATE, CONTAINER;\r
+ PUBLIC_KEY, CREDENTIALS, COOKIE, CERTIFICATE, CONTAINER;\r
\r
public boolean isStandard() {\r
return ordinal() <= COOKIE.ordinal();\r
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
import com.gitblit.transport.git.GitDaemonClient;
-import com.gitblit.transport.ssh.SshSession;
/**
* The upload pack factory creates an upload pack which controls what refs are
public UploadPack create(X req, Repository db)
throws ServiceNotEnabledException, ServiceNotAuthorizedException {
- UserModel user = UserModel.ANONYMOUS;
int timeout = 0;
- if (req instanceof HttpServletRequest) {
- // http/https request may or may not be authenticated
- HttpServletRequest client = (HttpServletRequest) req;
- user = authenticationManager.authenticate(client);
- if (user == null) {
- user = UserModel.ANONYMOUS;
- }
- } else if (req instanceof GitDaemonClient) {
+ if (req instanceof GitDaemonClient) {
// git daemon request is always anonymous
GitDaemonClient client = (GitDaemonClient) req;
// set timeout from Git daemon
timeout = client.getDaemon().getTimeout();
- } else if (req instanceof SshSession) {
- // SSH request is always authenticated
- SshSession client = (SshSession) req;
- user = authenticationManager.authenticate(client);
- if (user == null) {
- throw new ServiceNotAuthorizedException();
- }
}
UploadPack up = new UploadPack(db);
user = UserModel.ANONYMOUS;
}
} else if (req instanceof SshSession) {
+ // ssh is always authenticated
SshSession s = (SshSession) req;
- user = gitblit.authenticate(s);
- if (user == null) {
- throw new IOException(String.format("User %s not found", s.getRemoteUser()));
- }
+ user = gitblit.getUserModel(s.getRemoteUser());
}
if (user.canClone(model)) {
import java.nio.charset.Charset;
import java.security.Principal;
+import java.security.PublicKey;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import com.gitblit.auth.WindowsAuthProvider;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.SshSession;
import com.gitblit.utils.Base64;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.StringUtils;
}
/**
- * Authenticate a user based on SSH session.
+ * Authenticate a user based on a public key.
*
- * @param SshSession
+ * This implementation assumes that the authentication has already take place
+ * (e.g. SSHDaemon) and that this is a validation/verification of the user.
+ *
+ * @param username
+ * @param key
* @return a user object or null
*/
@Override
- public UserModel authenticate(SshSession sshSession) {
- String username = sshSession.getRemoteUser();
+ public UserModel authenticate(String username, PublicKey key) {
if (username != null) {
if (!StringUtils.isEmpty(username)) {
UserModel user = userManager.getUserModel(username);
if (user != null) {
// existing user
- logger.debug(MessageFormat.format("{0} authenticated by SSH key from {1}",
- user.username, sshSession.getRemoteAddress()));
- return validateAuthentication(user, AuthenticationType.SSH);
+ logger.debug(MessageFormat.format("{0} authenticated by {1} public key",
+ user.username, key.getAlgorithm()));
+ return validateAuthentication(user, AuthenticationType.PUBLIC_KEY);
}
- logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted ssh authentication from {1}",
- username, sshSession.getRemoteAddress()));
+ logger.warn(MessageFormat.format("Failed to find UserModel for {0} during public key authentication",
+ username));
}
} else {
- logger.warn("Empty user in SSH session");
+ logger.warn("Empty user passed to AuthenticationManager.authenticate!");
}
return null;
}
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
+import java.security.PublicKey;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.ITicketService;
-import com.gitblit.transport.ssh.SshSession;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.JsonUtils;
}
return user;
}
-
+
@Override
- public UserModel authenticate(SshSession sshSession) {
- return authenticationManager.authenticate(sshSession);
+ public UserModel authenticate(String username, PublicKey key) {
+ return authenticationManager.authenticate(username, key);
}
-
+
@Override
public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) {
UserModel user = authenticationManager.authenticate(httpRequest, requiresCertificate);
*/
package com.gitblit.manager;
+import java.security.PublicKey;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.SshSession;
public interface IAuthenticationManager extends IManager {
*/
UserModel authenticate(HttpServletRequest httpRequest);
- public UserModel authenticate(SshSession sshSession);
+ /**
+ * Authenticate a user based on a public key.
+ *
+ * @param username
+ * @param key
+ * @return a user object or null
+ */
+ UserModel authenticate(String username, PublicKey key);
/**
* Authenticate a user based on HTTP request parameters.
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
*/
public class SshKeyAuthenticator implements PublickeyAuthenticator {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
protected final IKeyManager keyManager;
protected final IAuthenticationManager authManager;
expireAfterAccess(15, TimeUnit.MINUTES).
maximumSize(100)
.build(new CacheLoader<String, List<PublicKey>>() {
+ @Override
public List<PublicKey> load(String username) {
return keyManager.getKeys(username);
}
@Override
public boolean authenticate(String username, final PublicKey suppliedKey,
final ServerSession session) {
- final SshSession sd = session.getAttribute(SshSession.KEY);
+ final SshSession client = session.getAttribute(SshSession.KEY);
+
+ if (client.getRemoteUser() != null) {
+ // TODO why do we re-authenticate?
+ log.info("{} has already authenticated!", username);
+ return true;
+ }
username = username.toLowerCase(Locale.US);
try {
List<PublicKey> keys = sshKeyCache.get(username);
if (keys == null || keys.isEmpty()) {
- sd.authenticationError(username, "no-matching-key");
+ log.info("{} has not added any public keys for ssh authentication", username);
return false;
}
+
for (PublicKey key : keys) {
if (key.equals(suppliedKey)) {
- return validate(username, sd);
+ UserModel user = authManager.authenticate(username, key);
+ if (user != null) {
+ client.authenticationSuccess(username);
+ return true;
+ }
}
}
- return false;
} catch (ExecutionException e) {
- sd.authenticationError(username, "user-not-found");
- return false;
}
- }
- boolean validate(String username, SshSession sd) {
- // now that the key has been validated, check with the authentication
- // manager to ensure that this user exists and can authenticate
- sd.authenticationSuccess(username);
- UserModel user = authManager.authenticate(sd);
- if (user != null) {
- return true;
- }
- sd.authenticationError(username, "user-not-found");
+ log.warn("could not authenticate {} for SSH using the supplied public key", username);
return false;
}
public IKeyManager getKeyManager() {
return keyManager;
}
-
+
public Cache<String, List<PublicKey>> getKeyCache() {
return sshKeyCache;
}
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.session.ServerSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
*/
public class SshPasswordAuthenticator implements PasswordAuthenticator {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
protected final IAuthenticationManager authManager;
public SshPasswordAuthenticator(IAuthenticationManager authManager) {
@Override
public boolean authenticate(String username, String password, ServerSession session) {
+ SshSession client = session.getAttribute(SshSession.KEY);
+ if (client.getRemoteUser() != null) {
+ log.info("{} has already authenticated!", username);
+ return true;
+ }
+
username = username.toLowerCase(Locale.US);
UserModel user = authManager.authenticate(username, password.toCharArray());
if (user != null) {
- SshSession sd = session.getAttribute(SshSession.KEY);
- sd.authenticationSuccess(username);
+ client.authenticationSuccess(username);
return true;
}
+
+ log.warn("could not authenticate {} for SSH using the supplied password", username);
return false;
}
}