From 0d7c650b3b59d8a7bbc47135975f040c832e04c0 Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Sun, 25 Oct 2015 12:12:32 -0400
Subject: [PATCH] Log update for Fail2Ban usage

---
 src/main/java/com/gitblit/manager/IAuthenticationManager.java              |    3 
 src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java             |    2 
 src/main/java/com/gitblit/manager/GitblitManager.java                      |    4 
 src/site/setup_fail2ban.mkd                                                |   14 +++-
 src/test/java/com/gitblit/tests/AuthenticationManagerTest.java             |    4 
 src/test/java/com/gitblit/tests/GitBlitTest.java                           |    2 
 src/main/java/com/gitblit/manager/AuthenticationManager.java               |   36 ++++++-----
 src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java            |   48 ++++++++--------
 src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java |    2 
 src/test/java/com/gitblit/tests/LdapAuthenticationTest.java                |   12 ++--
 src/main/java/com/gitblit/wicket/pages/RootPage.java                       |    5 +
 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 51aa221..7e0b07b 100644
--- a/src/main/java/com/gitblit/manager/AuthenticationManager.java
+++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java
@@ -310,15 +310,12 @@
 			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 @@
 	 * @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 @@
 
 		// 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 a34e29d..4a385fc 100644
--- a/src/main/java/com/gitblit/manager/GitblitManager.java
+++ b/src/main/java/com/gitblit/manager/GitblitManager.java
@@ -649,8 +649,8 @@
 	 */
 
 	@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 c81092b..5406a79 100644
--- a/src/main/java/com/gitblit/manager/IAuthenticationManager.java
+++ b/src/main/java/com/gitblit/manager/IAuthenticationManager.java
@@ -65,10 +65,11 @@
 	 * @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 a6d77ec..e9e2d7e 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 @@
 		}
 
 		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 93d44fc..b48f722 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 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 @@
 					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 928f7a8..c735968 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 d6ca89c..f8dc888 100644
--- a/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java
+++ b/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java
@@ -657,11 +657,11 @@
 		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 9eaae7f..e873ced 100644
--- a/src/test/java/com/gitblit/tests/GitBlitTest.java
+++ b/src/test/java/com/gitblit/tests/GitBlitTest.java
@@ -176,7 +176,7 @@
 
 	@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 e2bb764..26a49b2 100644
--- a/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java
+++ b/src/test/java/com/gitblit/tests/HtpasswdAuthenticationTest.java
@@ -200,43 +200,43 @@
     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 @@
     {
         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 7c84ecc..84dd138 100644
--- a/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
+++ b/src/test/java/com/gitblit/tests/LdapAuthenticationTest.java
@@ -240,23 +240,23 @@
 
 	@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 @@
 		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 ad773b7..7136fa7 100644
--- a/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java
+++ b/src/test/java/com/gitblit/tests/RedmineAuthenticationTest.java
@@ -65,7 +65,7 @@
     @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"));

--
Gitblit v1.9.1