mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-990: Enabled/disable auth failure tracking via implementations of a common interface.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.apache.guacamole.auth.ban;
|
||||
|
||||
import org.apache.guacamole.auth.ban.status.AuthenticationFailureTracker;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
||||
import org.apache.guacamole.net.event.AuthenticationFailureEvent;
|
||||
|
@@ -19,8 +19,11 @@
|
||||
|
||||
package org.apache.guacamole.auth.ban;
|
||||
|
||||
import org.apache.guacamole.auth.ban.status.InMemoryAuthenticationFailureTracker;
|
||||
import org.apache.guacamole.auth.ban.status.AuthenticationFailureTracker;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleServerException;
|
||||
import org.apache.guacamole.auth.ban.status.NullAuthenticationFailureTracker;
|
||||
import org.apache.guacamole.environment.Environment;
|
||||
import org.apache.guacamole.environment.LocalEnvironment;
|
||||
import org.apache.guacamole.net.auth.AbstractAuthenticationProvider;
|
||||
@@ -29,6 +32,8 @@ import org.apache.guacamole.net.auth.Credentials;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.properties.IntegerGuacamoleProperty;
|
||||
import org.apache.guacamole.properties.LongGuacamoleProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* AuthenticationProvider implementation that blocks further authentication
|
||||
@@ -37,6 +42,11 @@ import org.apache.guacamole.properties.LongGuacamoleProperty;
|
||||
*/
|
||||
public class BanningAuthenticationProvider extends AbstractAuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(BanningAuthenticationProvider.class);
|
||||
|
||||
/**
|
||||
* The maximum number of failed authentication attempts allowed before an
|
||||
* address is temporarily banned.
|
||||
@@ -126,7 +136,29 @@ public class BanningAuthenticationProvider extends AbstractAuthenticationProvide
|
||||
+ "\"" + MAX_ADDRESSES.getName() + "\" property, must be "
|
||||
+ "greater than zero.");
|
||||
|
||||
tracker = new AuthenticationFailureTracker(maxAttempts, banDuration, maxAddresses);
|
||||
// Configure auth failure tracking behavior and inform administrator of
|
||||
// ultimate result
|
||||
if (maxAttempts <= 0) {
|
||||
this.tracker = new NullAuthenticationFailureTracker();
|
||||
logger.info("Maximum failed authentication attempts has been set "
|
||||
+ "to {}. Automatic banning of brute-force authentication "
|
||||
+ "attempts will be disabled.", maxAttempts);
|
||||
}
|
||||
else if (banDuration <= 0) {
|
||||
this.tracker = new NullAuthenticationFailureTracker();
|
||||
logger.info("Ban duration for addresses that repeatedly fail "
|
||||
+ "authentication has been set to {}. Automatic banning "
|
||||
+ "of brute-force authentication attempts will be "
|
||||
+ "disabled.", banDuration);
|
||||
}
|
||||
else {
|
||||
this.tracker = new InMemoryAuthenticationFailureTracker(maxAttempts, banDuration, maxAddresses);
|
||||
logger.info("Addresses will be automatically banned for {} "
|
||||
+ "seconds after {} failed authentication attempts. Up "
|
||||
+ "to {} unique addresses will be tracked/banned at any "
|
||||
+ "given time.", banDuration, maxAttempts, maxAddresses);
|
||||
}
|
||||
|
||||
BanningAuthenticationListener.setAuthenticationFailureTracker(tracker);
|
||||
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.ban;
|
||||
package org.apache.guacamole.auth.ban.status;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.ban.status;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
|
||||
/**
|
||||
* Tracks past authentication results, automatically blocking the IP addresses
|
||||
* of machines that repeatedly fail to authenticate.
|
||||
*/
|
||||
public interface AuthenticationFailureTracker {
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received, but it is
|
||||
* either not yet known whether the request has succeeded or failed. If the
|
||||
* associated address is currently being blocked, an exception will be
|
||||
* thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the authentication request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
void notifyAuthenticationRequestReceived(Credentials credentials)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received and has
|
||||
* succeeded. If the associated address is currently being blocked, an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the successful authentication
|
||||
* request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
void notifyAuthenticationSuccess(Credentials credentials)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received and has
|
||||
* failed. If the associated address is currently being blocked, an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the failed authentication request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
void notifyAuthenticationFailed(Credentials credentials)
|
||||
throws GuacamoleException;
|
||||
|
||||
}
|
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.ban;
|
||||
package org.apache.guacamole.auth.ban.status;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
@@ -30,15 +30,16 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Provides automated tracking and blocking of IP addresses that repeatedly
|
||||
* fail authentication.
|
||||
* AuthenticationFailureTracker implementation that tracks the failure status
|
||||
* of each IP address in memory. The maximum amount of memory consumed is
|
||||
* bounded by the configured maximum number of addresses tracked.
|
||||
*/
|
||||
public class AuthenticationFailureTracker {
|
||||
public class InMemoryAuthenticationFailureTracker implements AuthenticationFailureTracker {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthenticationFailureTracker.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(InMemoryAuthenticationFailureTracker.class);
|
||||
|
||||
/**
|
||||
* All authentication failures currently being tracked, stored by the
|
||||
@@ -74,38 +75,17 @@ public class AuthenticationFailureTracker {
|
||||
* The maximum number of unique IP addresses that should be tracked
|
||||
* before discarding older tracked failures.
|
||||
*/
|
||||
public AuthenticationFailureTracker(int maxAttempts, int banDuration,
|
||||
public InMemoryAuthenticationFailureTracker(int maxAttempts, int banDuration,
|
||||
long maxAddresses) {
|
||||
|
||||
this.maxAttempts = maxAttempts;
|
||||
this.banDuration = banDuration;
|
||||
|
||||
// Inform administrator of configured behavior
|
||||
if (maxAttempts <= 0) {
|
||||
logger.info("Maximum failed authentication attempts has been set "
|
||||
+ "to {}. Automatic banning of brute-force authentication "
|
||||
+ "attempts will be disabled.", maxAttempts);
|
||||
}
|
||||
else if (banDuration <= 0) {
|
||||
logger.info("Ban duration for addresses that repeatedly fail "
|
||||
+ "authentication has been set to {}. Automatic banning "
|
||||
+ "of brute-force authentication attempts will be "
|
||||
+ "disabled.", banDuration);
|
||||
}
|
||||
else {
|
||||
logger.info("Addresses will be automatically banned for {} "
|
||||
+ "seconds after {} failed authentication attempts.",
|
||||
banDuration, maxAttempts);
|
||||
}
|
||||
|
||||
// Limit maximum number of tracked addresses to configured upper bound
|
||||
this.failures = Caffeine.newBuilder()
|
||||
.maximumSize(maxAddresses)
|
||||
.build();
|
||||
|
||||
logger.info("Up to {} unique addresses will be tracked/banned at any "
|
||||
+ " given time.", maxAddresses);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,10 +167,6 @@ public class AuthenticationFailureTracker {
|
||||
private void notifyAuthenticationStatus(Credentials credentials,
|
||||
boolean failed) throws GuacamoleException {
|
||||
|
||||
// Do not track/ban if tracking or banning are disabled
|
||||
if (maxAttempts <= 0 || banDuration <= 0)
|
||||
return;
|
||||
|
||||
// Ignore requests that do not contain explicit parameters of any kind
|
||||
if (isEmpty(credentials))
|
||||
return;
|
||||
@@ -234,54 +210,19 @@ public class AuthenticationFailureTracker {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received, but it is
|
||||
* either not yet known whether the request has succeeded or failed. If the
|
||||
* associated address is currently being blocked, an exception will be
|
||||
* thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the authentication request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
@Override
|
||||
public void notifyAuthenticationRequestReceived(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
notifyAuthenticationStatus(credentials, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received and has
|
||||
* succeeded. If the associated address is currently being blocked, an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the successful authentication
|
||||
* request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
@Override
|
||||
public void notifyAuthenticationSuccess(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
notifyAuthenticationStatus(credentials, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that an authentication request has been received and has
|
||||
* failed. If the associated address is currently being blocked, an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials associated with the failed authentication request.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the authentication request is being blocked due to brute force
|
||||
* prevention rules.
|
||||
*/
|
||||
@Override
|
||||
public void notifyAuthenticationFailed(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
notifyAuthenticationStatus(credentials, true);
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.ban.status;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
|
||||
/**
|
||||
* AuthenticationFailureTracker implementation that does nothing. All requests
|
||||
* are ignored, regardless of status, and no tracking is performed.
|
||||
*/
|
||||
public class NullAuthenticationFailureTracker implements AuthenticationFailureTracker {
|
||||
|
||||
@Override
|
||||
public void notifyAuthenticationRequestReceived(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAuthenticationSuccess(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAuthenticationFailed(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user