+ Adds standard logging for all authentication providers + Updates help page to use default GitBlit SSH porttags/v1.7.0
@@ -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; | |||
} | |||
@@ -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 |
@@ -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. |
@@ -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; |
@@ -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)) { |
@@ -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` |
@@ -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); | |||
} | |||
@@ -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 |
@@ -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); | |||
} | |||
@@ -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); | |||
} | |||
@@ -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")); |