From 4e84166db5c5538e3984d9d2d6bb1f9902e65ee0 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Tue, 04 Nov 2014 17:38:17 -0500 Subject: [PATCH] Merged #217 "Exclude SSLv3 from Gitblit GO https protocols" --- src/main/java/com/gitblit/manager/AuthenticationManager.java | 131 ++++++++++++++++++++++++++++++++++++------- 1 files changed, 109 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 4f3e652..29221e6 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -27,14 +27,15 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; -import org.apache.wicket.RequestCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.Constants; import com.gitblit.Constants.AccountType; import com.gitblit.Constants.AuthenticationType; +import com.gitblit.Constants.Role; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.auth.AuthenticationProvider; @@ -47,11 +48,13 @@ import com.gitblit.auth.WindowsAuthProvider; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; +import com.gitblit.transport.ssh.SshKey; import com.gitblit.utils.Base64; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.StringUtils; import com.gitblit.utils.X509Utils.X509Metadata; -import com.gitblit.wicket.GitBlitWebSession; +import com.google.inject.Inject; +import com.google.inject.Singleton; /** * The authentication manager handles user login & logout. @@ -59,6 +62,7 @@ * @author James Moger * */ +@Singleton public class AuthenticationManager implements IAuthenticationManager { private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -75,6 +79,7 @@ private final Map<String, String> legacyRedirects; + @Inject public AuthenticationManager( IRuntimeManager runtimeManager, IUserManager userManager) { @@ -159,7 +164,7 @@ } return this; } - + public void addAuthenticationProvider(AuthenticationProvider prov) { authenticationProviders.add(prov); } @@ -199,7 +204,7 @@ UserModel user = userManager.getUserModel(username); if (user != null) { // existing user - flagWicketSession(AuthenticationType.CONTAINER); + flagSession(httpRequest, AuthenticationType.CONTAINER); logger.debug(MessageFormat.format("{0} authenticated by servlet container principal from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CONTAINER); @@ -211,7 +216,7 @@ user.password = Constants.EXTERNAL_ACCOUNT; user.accountType = AccountType.CONTAINER; userManager.updateUserModel(user); - flagWicketSession(AuthenticationType.CONTAINER); + flagSession(httpRequest, AuthenticationType.CONTAINER); logger.debug(MessageFormat.format("{0} authenticated and created by servlet container principal from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CONTAINER); @@ -232,7 +237,7 @@ UserModel user = userManager.getUserModel(model.username); X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest); if (user != null) { - flagWicketSession(AuthenticationType.CERTIFICATE); + flagSession(httpRequest, AuthenticationType.CERTIFICATE); logger.debug(MessageFormat.format("{0} authenticated by client certificate {1} from {2}", user.username, metadata.serialNumber, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CERTIFICATE); @@ -254,7 +259,7 @@ if (!StringUtils.isEmpty(cookie)) { user = userManager.getUserModel(cookie.toCharArray()); if (user != null) { - flagWicketSession(AuthenticationType.COOKIE); + flagSession(httpRequest, AuthenticationType.COOKIE); logger.debug(MessageFormat.format("{0} authenticated by cookie from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.COOKIE); @@ -276,7 +281,7 @@ char[] password = values[1].toCharArray(); user = authenticate(username, password); if (user != null) { - flagWicketSession(AuthenticationType.CREDENTIALS); + flagSession(httpRequest, AuthenticationType.CREDENTIALS); logger.debug(MessageFormat.format("{0} authenticated by BASIC request header from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CREDENTIALS); @@ -288,6 +293,37 @@ } return null; } + + /** + * Authenticate a user based on a public key. + * + * 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(String username, SshKey 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 {1} public key", + user.username, key.getAlgorithm())); + return validateAuthentication(user, AuthenticationType.PUBLIC_KEY); + } + logger.warn(MessageFormat.format("Failed to find UserModel for {0} during public key authentication", + username)); + } + } else { + logger.warn("Empty user passed to AuthenticationManager.authenticate!"); + } + return null; + } + /** * This method allows the authentication manager to reject authentication @@ -310,13 +346,8 @@ return user; } - protected void flagWicketSession(AuthenticationType authenticationType) { - RequestCycle requestCycle = RequestCycle.get(); - if (requestCycle != null) { - // flag the Wicket session, if this is a Wicket request - GitBlitWebSession session = GitBlitWebSession.get(); - session.authenticationType = authenticationType; - } + protected void flagSession(HttpServletRequest httpRequest, AuthenticationType authenticationType) { + httpRequest.getSession().setAttribute(Constants.AUTHENTICATION_TYPE, authenticationType); } /** @@ -359,14 +390,14 @@ } } } - + // could not authenticate locally or with a provider return null; } - + /** * Returns a UserModel if local authentication succeeds. - * + * * @param user * @param password * @return a UserModel if local authentication succeeds, null otherwise @@ -422,10 +453,24 @@ * @param user */ @Override + @Deprecated public void setCookie(HttpServletResponse response, UserModel user) { + setCookie(null, response, user); + } + + /** + * Sets a cookie for the specified user. + * + * @param request + * @param response + * @param user + */ + @Override + public void setCookie(HttpServletRequest request, HttpServletResponse response, UserModel user) { if (settings.getBoolean(Keys.web.allowCookieAuthentication, true)) { - GitBlitWebSession session = GitBlitWebSession.get(); - boolean standardLogin = session.authenticationType.isStandard(); + HttpSession session = request.getSession(); + AuthenticationType authenticationType = (AuthenticationType) session.getAttribute(Constants.AUTHENTICATION_TYPE); + boolean standardLogin = authenticationType.isStandard(); if (standardLogin) { Cookie userCookie; @@ -445,7 +490,13 @@ userCookie.setMaxAge((int) TimeUnit.DAYS.toSeconds(7)); } } - userCookie.setPath("/"); + String path = "/"; + if (request != null) { + if (!StringUtils.isEmpty(request.getContextPath())) { + path = request.getContextPath(); + } + } + userCookie.setPath(path); response.addCookie(userCookie); } } @@ -454,11 +505,25 @@ /** * Logout a user. * + * @param response * @param user */ @Override + @Deprecated public void logout(HttpServletResponse response, UserModel user) { - setCookie(response, null); + setCookie(null, response, null); + } + + /** + * Logout a user. + * + * @param request + * @param response + * @param user + */ + @Override + public void logout(HttpServletRequest request, HttpServletResponse response, UserModel user) { + setCookie(request, response, null); } /** @@ -516,6 +581,28 @@ return (team != null && team.isLocalTeam()) || findProvider(team).supportsTeamMembershipChanges(); } + /** + * Returns true if the user's role can be changed. + * + * @param user + * @return true if the user's role can be changed + */ + @Override + public boolean supportsRoleChanges(UserModel user, Role role) { + return (user != null && user.isLocalAccount()) || findProvider(user).supportsRoleChanges(user, role); + } + + /** + * Returns true if the team's role can be changed. + * + * @param user + * @return true if the team's role can be changed + */ + @Override + public boolean supportsRoleChanges(TeamModel team, Role role) { + return (team != null && team.isLocalTeam()) || findProvider(team).supportsRoleChanges(team, role); + } + protected AuthenticationProvider findProvider(UserModel user) { for (AuthenticationProvider provider : authenticationProviders) { if (provider.getAccountType().equals(user.accountType)) { -- Gitblit v1.9.1