diff options
11 files changed, 72 insertions, 60 deletions
diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 51aa2213..7e0b07be 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -310,15 +310,12 @@ public class AuthenticationManager implements IAuthenticationManager { if (values.length == 2) { String username = values[0]; char[] password = values[1].toCharArray(); - user = authenticate(username, password); + user = authenticate(username, password, httpRequest.getRemoteAddr()); if (user != null) { flagRequest(httpRequest, AuthenticationType.CREDENTIALS, user.username); logger.debug(MessageFormat.format("{0} authenticated by BASIC request header from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CREDENTIALS); - } else { - logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", - username, httpRequest.getRemoteAddr())); } } } @@ -445,7 +442,7 @@ public class AuthenticationManager implements IAuthenticationManager { * @return a user object or null */ @Override - public UserModel authenticate(String username, char[] password) { + public UserModel authenticate(String username, char[] password, String remoteIP) { if (StringUtils.isEmpty(username)) { // can not authenticate empty username return null; @@ -462,22 +459,29 @@ public class AuthenticationManager implements IAuthenticationManager { // try local authentication if (user != null && user.isLocalAccount()) { - return authenticateLocal(user, password); - } - - // try registered external authentication providers - for (AuthenticationProvider provider : authenticationProviders) { - if (provider instanceof UsernamePasswordAuthenticationProvider) { - UserModel returnedUser = provider.authenticate(usernameDecoded, password); - if (returnedUser != null) { - // user authenticated - returnedUser.accountType = provider.getAccountType(); - return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + UserModel returnedUser = authenticateLocal(user, password); + if (returnedUser != null) { + // user authenticated + return returnedUser; + } + } else { + // try registered external authentication providers + for (AuthenticationProvider provider : authenticationProviders) { + if (provider instanceof UsernamePasswordAuthenticationProvider) { + UserModel returnedUser = provider.authenticate(usernameDecoded, password); + if (returnedUser != null) { + // user authenticated + returnedUser.accountType = provider.getAccountType(); + return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + } } } } // could not authenticate locally or with a provider + logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", username, + remoteIP != null ? remoteIP : "unknown")); + return null; } diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index a34e29d7..4a385fc1 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -649,8 +649,8 @@ public class GitblitManager implements IGitblit { */ @Override - public UserModel authenticate(String username, char[] password) { - return authenticationManager.authenticate(username, password); + public UserModel authenticate(String username, char[] password, String remoteIP) { + return authenticationManager.authenticate(username, password, remoteIP); } @Override diff --git a/src/main/java/com/gitblit/manager/IAuthenticationManager.java b/src/main/java/com/gitblit/manager/IAuthenticationManager.java index c81092b9..5406a794 100644 --- a/src/main/java/com/gitblit/manager/IAuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/IAuthenticationManager.java @@ -65,10 +65,11 @@ public interface IAuthenticationManager extends IManager { * @see IUserService.authenticate(String, char[]) * @param username * @param password + * @param remoteIP * @return a user object or null * @since 1.4.0 */ - UserModel authenticate(String username, char[] password); + UserModel authenticate(String username, char[] password, String remoteIP); /** * Return the UserModel for already authenticated user. diff --git a/src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java b/src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java index a6d77ec4..e9e2d7e1 100644 --- a/src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java +++ b/src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java @@ -51,7 +51,7 @@ public class UsernamePasswordAuthenticator implements PasswordAuthenticator { } username = username.toLowerCase(Locale.US); - UserModel user = authManager.authenticate(username, password.toCharArray()); + UserModel user = authManager.authenticate(username, password.toCharArray(), null); if (user != null) { client.setUser(user); return true; diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java index 93d44fc7..b48f7224 100644 --- a/src/main/java/com/gitblit/wicket/pages/RootPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java @@ -36,6 +36,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.wicket.MarkupContainer; import org.apache.wicket.PageParameters; +import org.apache.wicket.RequestCycle; import org.apache.wicket.behavior.HeaderContributor; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.IHeaderResponse; @@ -566,7 +567,9 @@ public abstract class RootPage extends BasePage { String username = RootPage.this.username.getObject(); char[] password = RootPage.this.password.getObject().toCharArray(); - UserModel user = app().authentication().authenticate(username, password); + HttpServletRequest request = ((WebRequest)RequestCycle.get().getRequest()).getHttpServletRequest(); + + UserModel user = app().authentication().authenticate(username, password, request.getRemoteAddr()); if (user == null) { error(getString("gb.invalidUsernameOrPassword")); } else if (user.username.equals(Constants.FEDERATION_USER)) { diff --git a/src/site/setup_fail2ban.mkd b/src/site/setup_fail2ban.mkd index 928f7a84..c735968d 100644 --- a/src/site/setup_fail2ban.mkd +++ b/src/site/setup_fail2ban.mkd @@ -1,20 +1,24 @@ ## Configure fail2ban for Gitblit-SSH -This procedure is based on a Debian installation of [fail2ban](http://www.fail2ban.org/), but it should works in any installation. +This procedure uses [fail2ban](http://www.fail2ban.org/). -First, create a new filter file `gitblit.conf` in filter directory (Debian: `/etc/fail2ban/filter.d/`) or into `filter.conf` file. Here an example: +First, create a new filter file `gitblit.conf` in filter directory (Debian/CentOS: `/etc/fail2ban/filter.d/`) or into `filter.conf` file. Here is an example: [Definition] - failregex = could not authenticate .*? \(/<HOST>:[0-9]*\) for SSH using the supplied password$ + failregex = Failed login attempt for .+, invalid credentials from <HOST>\s*$ + could not authenticate .*? \(/<HOST>:[0-9]*\) for SSH using the supplied password$ ignoreregex = Then edit `jail.conf` to add "gitblit" service (Debian: `/etc/fail2ban/jail.conf`). For example: [gitblit] enabled = true - port = 22 + port = 443,29418 protocol = tcp filter = gitblit logpath = /var/log/gitblit.log -Restart fail2ban to apply (Debian: `/etc/init.d/fail2ban restart`). + +Reload fail2ban config to apply (`fail2ban-client reload`). + +Check the status of the gitblit fail2ban jail with `fail2ban-client status gitblit` diff --git a/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java b/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java index d6ca89c6..f8dc8885 100644 --- a/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java +++ b/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java @@ -657,11 +657,11 @@ public class AuthenticationManagerTest extends GitblitUnitTest { user.password = "password"; users.updateUserModel(user); - assertNotNull(auth.authenticate(user.username, user.password.toCharArray())); + assertNotNull(auth.authenticate(user.username, user.password.toCharArray(), null)); user.disabled = true; users.updateUserModel(user); - assertNull(auth.authenticate(user.username, user.password.toCharArray())); + assertNull(auth.authenticate(user.username, user.password.toCharArray(), null)); users.deleteUserModel(user); } diff --git a/src/test/java/com/gitblit/tests/GitBlitTest.java b/src/test/java/com/gitblit/tests/GitBlitTest.java index 9eaae7f8..e873ced2 100644 --- a/src/test/java/com/gitblit/tests/GitBlitTest.java +++ b/src/test/java/com/gitblit/tests/GitBlitTest.java @@ -176,7 +176,7 @@ public class GitBlitTest extends GitblitUnitTest { @Test
public void testAuthentication() throws Exception {
- assertTrue(authentication().authenticate("admin", "admin".toCharArray()) != null);
+ assertTrue(authentication().authenticate("admin", "admin".toCharArray(), null) != null);
}
@Test
diff --git a/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java b/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java index e2bb764e..26a49b24 100644 --- a/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java +++ b/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java @@ -200,43 +200,43 @@ public class HtpasswdAuthenticationTest extends GitblitUnitTest { public void testAuthenticationManager() { MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - UserModel user = auth.authenticate("user1", "pass1".toCharArray()); + UserModel user = auth.authenticate("user1", "pass1".toCharArray(), null); assertNotNull(user); assertEquals("user1", user.username); - user = auth.authenticate("user2", "pass2".toCharArray()); + user = auth.authenticate("user2", "pass2".toCharArray(), null); assertNotNull(user); assertEquals("user2", user.username); // Test different encryptions - user = auth.authenticate("plain", "passWord".toCharArray()); + user = auth.authenticate("plain", "passWord".toCharArray(), null); assertNotNull(user); assertEquals("plain", user.username); MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - user = auth.authenticate("crypt", "password".toCharArray()); + user = auth.authenticate("crypt", "password".toCharArray(), null); assertNotNull(user); assertEquals("crypt", user.username); - user = auth.authenticate("md5", "password".toCharArray()); + user = auth.authenticate("md5", "password".toCharArray(), null); assertNotNull(user); assertEquals("md5", user.username); - user = auth.authenticate("sha", "password".toCharArray()); + user = auth.authenticate("sha", "password".toCharArray(), null); assertNotNull(user); assertEquals("sha", user.username); // Test leading and trailing whitespace - user = auth.authenticate("trailing", "whitespace".toCharArray()); + user = auth.authenticate("trailing", "whitespace".toCharArray(), null); assertNotNull(user); assertEquals("trailing", user.username); - user = auth.authenticate("tabbed", "frontAndBack".toCharArray()); + user = auth.authenticate("tabbed", "frontAndBack".toCharArray(), null); assertNotNull(user); assertEquals("tabbed", user.username); - user = auth.authenticate("leading", "whitespace".toCharArray()); + user = auth.authenticate("leading", "whitespace".toCharArray(), null); assertNotNull(user); assertEquals("leading", user.username); } @@ -323,55 +323,55 @@ public class HtpasswdAuthenticationTest extends GitblitUnitTest { { UserModel user = null; MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "true"); - user = auth.authenticate("user1", "".toCharArray()); + user = auth.authenticate("user1", "".toCharArray(), null); assertNull("User 'user1' falsely authenticated.", user); - user = auth.authenticate("user1", "pass2".toCharArray()); + user = auth.authenticate("user1", "pass2".toCharArray(), null); assertNull("User 'user1' falsely authenticated.", user); - user = auth.authenticate("user2", "lalala".toCharArray()); + user = auth.authenticate("user2", "lalala".toCharArray(), null); assertNull("User 'user2' falsely authenticated.", user); - user = auth.authenticate("user3", "disabled".toCharArray()); + user = auth.authenticate("user3", "disabled".toCharArray(), null); assertNull("User 'user3' falsely authenticated.", user); - user = auth.authenticate("user4", "disabled".toCharArray()); + user = auth.authenticate("user4", "disabled".toCharArray(), null); assertNull("User 'user4' falsely authenticated.", user); - user = auth.authenticate("plain", "text".toCharArray()); + user = auth.authenticate("plain", "text".toCharArray(), null); assertNull("User 'plain' falsely authenticated.", user); - user = auth.authenticate("plain", "password".toCharArray()); + user = auth.authenticate("plain", "password".toCharArray(), null); assertNull("User 'plain' falsely authenticated.", user); MS.put(KEY_SUPPORT_PLAINTEXT_PWD, "false"); - user = auth.authenticate("crypt", "".toCharArray()); + user = auth.authenticate("crypt", "".toCharArray(), null); assertNull("User 'cyrpt' falsely authenticated.", user); - user = auth.authenticate("crypt", "passwd".toCharArray()); + user = auth.authenticate("crypt", "passwd".toCharArray(), null); assertNull("User 'crypt' falsely authenticated.", user); - user = auth.authenticate("md5", "".toCharArray()); + user = auth.authenticate("md5", "".toCharArray(), null); assertNull("User 'md5' falsely authenticated.", user); - user = auth.authenticate("md5", "pwd".toCharArray()); + user = auth.authenticate("md5", "pwd".toCharArray(), null); assertNull("User 'md5' falsely authenticated.", user); - user = auth.authenticate("sha", "".toCharArray()); + user = auth.authenticate("sha", "".toCharArray(), null); assertNull("User 'sha' falsely authenticated.", user); - user = auth.authenticate("sha", "letmein".toCharArray()); + user = auth.authenticate("sha", "letmein".toCharArray(), null); assertNull("User 'sha' falsely authenticated.", user); - user = auth.authenticate(" tabbed", "frontAndBack".toCharArray()); + user = auth.authenticate(" tabbed", "frontAndBack".toCharArray(), null); assertNull("User 'tabbed' falsely authenticated.", user); - user = auth.authenticate(" leading", "whitespace".toCharArray()); + user = auth.authenticate(" leading", "whitespace".toCharArray(), null); assertNull("User 'leading' falsely authenticated.", user); } diff --git a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java index 7c84ecc2..84dd138d 100644 --- a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java +++ b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java @@ -240,23 +240,23 @@ public class LdapAuthenticationTest extends GitblitUnitTest { @Test public void testAuthenticationManager() { - UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray()); + UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray(), null); assertNotNull(userOneModel); assertNotNull(userOneModel.getTeam("git_admins")); assertNotNull(userOneModel.getTeam("git_users")); assertTrue(userOneModel.canAdmin); - UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray()); + UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray(), null); assertNull(userOneModelFailedAuth); - UserModel userTwoModel = auth.authenticate("UserTwo", "userTwoPassword".toCharArray()); + UserModel userTwoModel = auth.authenticate("UserTwo", "userTwoPassword".toCharArray(), null); assertNotNull(userTwoModel); assertNotNull(userTwoModel.getTeam("git_users")); assertNull(userTwoModel.getTeam("git_admins")); assertNotNull(userTwoModel.getTeam("git admins")); assertTrue(userTwoModel.canAdmin); - UserModel userThreeModel = auth.authenticate("UserThree", "userThreePassword".toCharArray()); + UserModel userThreeModel = auth.authenticate("UserThree", "userThreePassword".toCharArray(), null); assertNotNull(userThreeModel); assertNotNull(userThreeModel.getTeam("git_users")); assertNull(userThreeModel.getTeam("git_admins")); @@ -269,10 +269,10 @@ public class LdapAuthenticationTest extends GitblitUnitTest { settings.put(Keys.realm.ldap.username, ""); settings.put(Keys.realm.ldap.password, ""); - UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray()); + UserModel userOneModel = auth.authenticate("UserOne", "userOnePassword".toCharArray(), null); assertNotNull(userOneModel); - UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray()); + UserModel userOneModelFailedAuth = auth.authenticate("UserOne", "userTwoPassword".toCharArray(), null); assertNull(userOneModelFailedAuth); } diff --git a/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java b/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java index ad773b7a..7136fa79 100644 --- a/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java +++ b/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java @@ -65,7 +65,7 @@ public class RedmineAuthenticationTest extends GitblitUnitTest { @Test public void testAuthenticationManager() throws Exception { AuthenticationManager auth = newAuthenticationManager(); - UserModel userModel = auth.authenticate("RedmineAdminId", "RedmineAPIKey".toCharArray()); + UserModel userModel = auth.authenticate("RedmineAdminId", "RedmineAPIKey".toCharArray(), null); assertThat(userModel.getName(), is("redmineadminid")); assertThat(userModel.getDisplayName(), is("baz foo")); assertThat(userModel.emailAddress, is("baz@example.com")); |