Commit a67661c3 authored by Guus der Kinderen's avatar Guus der Kinderen

Merge pull request #460 from guusdk/OF-1007

OF-1007: Supplement existing client-to-server whitelisting with blacklisting
parents 5e0c7e49 16e84b64
......@@ -2444,6 +2444,13 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -2407,6 +2407,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -1399,9 +1399,15 @@ reg.settings.only_registered_login=Only registered users may login.
reg.settings.allowed_ips=Restrict Login
reg.settings.allowed_ips_info=Use the form below to define the IP addresses or IP address ranges \
that are allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
that clients will be able to connect from any IP address (unless a blacklist is in place).
reg.settings.ips_all=Restrict ALL (including anonymous) logins to these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins to these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
# Server db Page
......
......@@ -2465,6 +2465,12 @@ user.properties.isadmin=El usuario tiene privilegios de administrador.
reg.settings.ips_all=Restringir TODOS los ingresos de estas IPs:
reg.settings.ips_anonymous=Restringir ingresos anonimos de estas IPs:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Aceptar certificados auto-firmados. Server dialback sobre TLS esta habilitado.
# Client Connections Settings page
......
......@@ -2020,6 +2020,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -2391,6 +2391,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -2409,6 +2409,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -2378,6 +2378,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -2411,6 +2411,12 @@ user.properties.isadmin=User has administrative privileges.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -1381,6 +1381,12 @@ reg.settings.allowed_ips_info=Utilize o formul\u00e1rio abaixo para definir ende
que os clientes est\u00e3o habilitados a ligar com qualquer IP.
reg.settings.ips_all=Restringir TODAS (incluindo as anonimas) tentativas de acesso destes IP's:
reg.settings.ips_anonymous=Restringir tentativas de acesso anonimas destes IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
# Server db Page
......
......@@ -821,6 +821,12 @@ reg.settings.inband_account_info=\ \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u0
reg.settings.info=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0444\u043E\u0440\u043C\u044B \u043D\u0438\u0436\u0435, \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u044F\u0442\u044C \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u044B\u0435 \u0430\u0441\u043F\u0435\u043A\u0442\u044B \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u0438 \u0432\u0445\u043E\u0434\u0430.
reg.settings.ips_all=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0438\u0442\u044C \u0434\u043E\u0441\u0442\u0443\u043F \u043A\u043E \u0432\u0441\u0435\u043C (\u0432 \u0442\u043E\u043C \u0447\u0438\u0441\u043B\u0435 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u043C) \u043B\u043E\u0433\u0438\u043D\u0430\u043C \u044D\u0442\u0438\u0445 IP's\:
reg.settings.ips_anonymous=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0438\u0442\u044C \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0435 \u043B\u043E\u0433\u0438\u043D\u044B \u044D\u0442\u0438\u0445 IP's\:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
reg.settings.not_auto_create=\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438 \u043D\u0435 \u043C\u043E\u0433\u0443\u0442 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u0441\u043E\u0437\u0434\u0430\u0432\u0430\u0442\u044C \u043D\u043E\u0432\u044B\u0435 \u0443\u0447\u0435\u0442\u043D\u044B\u0435 \u0437\u0430\u043F\u0438\u0441\u0438.
reg.settings.only_registered_login=\u0422\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438 \u043C\u043E\u0433\u0443\u0442 \u0432\u043E\u0439\u0442\u0438.
reg.settings.title=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438
......
......@@ -2247,6 +2247,12 @@ security.audit.viewer.view_url=Nasledovn\u00fd URL odkazuje na prehliada\u010d z
security.audit.viewer.view_url.url=URL
reg.settings.ips_all=Obmedzi\u0165 V\u0160ETKY (vr\u00e1tane anonymn\u00fdch) prihl\u00e1sen\u00ed na tieto IP adresy:
reg.settings.ips_anonymous=Obmedzi\u0165 anonymn\u00e9 prihl\u00e1senia na tieto IP adresy:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Akceptova\u0165 certifik\u00e1ty podp\u00edsan\u00e9 sebou sam\u00fd. Sp\u00e4tn\u00e9 volanie servera prostredn\u00edctvom TLS je teraz dostupn\u00e9.
# Client Connections Settings page
......
......@@ -2303,6 +2303,12 @@ user.create.isadmin=\u662F\u5426\u4E3A\u7BA1\u7406\u5458?
user.create.admin_info=\u6388\u4E88 Openfire \u7BA1\u7406\u6743\u9650
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
reg.settings.allowed_ips_blocked_info=Use the form below to define the IP addresses or IP address ranges \
that are not allowed to login. E.g.: 200.120.90.10, 200.125.80.*. Leaving the form empty means \
that clients will be able to connect from any IP address, unless a whitelist (see below) is in place. \
Note that entries on the 'blocked' list (here) will always take precedence over entries on the 'allowed' \
lists below.
reg.settings.ips_blocked=Do not allow any logins from these IP's:
ssl.settings.client.label_self-signed=Accept self-signed certificates. Server dialback over TLS is now available.
# Client Connections Settings page
......
......@@ -330,26 +330,7 @@ public class IQAuthHandler extends IQHandler implements IQAuthInfo {
IQ response = IQ.createResultIQ(packet);
if (anonymousAllowed) {
// Verify that client can connect from his IP address
boolean forbidAccess = false;
try {
String hostAddress = session.getConnection().getHostAddress();
if (!LocalClientSession.getAllowedAnonymIPs().isEmpty() &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(hostAddress)) {
byte[] address = session.getConnection().getAddress();
String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." +
(address[2] & 0xff) +
".*";
String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*";
String range3 = (address[0] & 0xff) + ".*.*.*";
if (!LocalClientSession.getAllowedAnonymIPs().containsKey(range1) &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(range2) &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(range3)) {
forbidAccess = true;
}
}
} catch (UnknownHostException e) {
forbidAccess = true;
}
boolean forbidAccess = !LocalClientSession.isAllowedAnonymous( session.getConnection() );
if (forbidAccess) {
// Connection forbidden from that IP address
response.setChildElement(packet.getChildElement().createCopy());
......
......@@ -472,26 +472,7 @@ public class SASLAuthentication {
private static Status doAnonymousAuthentication(LocalSession session) {
if (XMPPServer.getInstance().getIQAuthHandler().isAnonymousAllowed()) {
// Verify that client can connect from his IP address
boolean forbidAccess = false;
try {
String hostAddress = session.getConnection().getHostAddress();
if (!LocalClientSession.getAllowedAnonymIPs().isEmpty() &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(hostAddress)) {
byte[] address = session.getConnection().getAddress();
String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." +
(address[2] & 0xff) +
".*";
String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*";
String range3 = (address[0] & 0xff) + ".*.*.*";
if (!LocalClientSession.getAllowedAnonymIPs().containsKey(range1) &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(range2) &&
!LocalClientSession.getAllowedAnonymIPs().containsKey(range3)) {
forbidAccess = true;
}
}
} catch (UnknownHostException e) {
forbidAccess = true;
}
boolean forbidAccess = !LocalClientSession.isAllowedAnonymous( session.getConnection() );
if (forbidAccess) {
authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed;
......
......@@ -19,6 +19,7 @@ public final class ConnectionSettings {
public static final String COMPRESSION_SETTINGS = "xmpp.client.compression.policy";
public static final String LOGIN_ALLOWED = "xmpp.client.login.allowed";
public static final String LOGIN_BLOCKED = "xmpp.client.login.blocked";
public static final String LOGIN_ANONYM_ALLOWED = "xmpp.client.login.allowedAnonym";
public static final String MAX_THREADS = "xmpp.client.processing.threads";
......
......@@ -21,12 +21,7 @@
package org.jivesoftware.openfire.session;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.*;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.SessionManager;
......@@ -36,7 +31,6 @@ import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.privacy.PrivacyList;
import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.spi.ConnectionConfiguration;
......@@ -68,14 +62,20 @@ public class LocalClientSession extends LocalSession implements ClientSession {
private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash";
/**
* Keep the list of IP address that are allowed to connect to the server. If the list is
* empty then anyone is allowed to connect to the server.<p>
* Keep the list of IP address that are allowed to connect to the server.
*
* Note: Key = IP address or IP range; Value = empty string. A hash map is being used for
* performance reasons.
* If the list is empty then anyone is allowed to connect to the server, unless the IP is on the blacklist (which
* always takes precedence over the whitelist).
*
* Note: the values in this list can be hostnames, IP addresses or IP ranges (with wildcards).
*/
private static Set<String> allowedIPs = new HashSet<>();
private static Set<String> allowedAnonymIPs = new HashSet<>();
/**
* Similar to {@link #allowedIPs}, but used for blacklisting rather than whitelisting.
*/
private static Map<String,String> allowedIPs = new HashMap<>();
private static Map<String,String> allowedAnonymIPs = new HashMap<>();
private static Set<String> blockedIPs = new HashSet<>();
private boolean messageCarbonsEnabled;
......@@ -124,14 +124,19 @@ public class LocalClientSession extends LocalSession implements ClientSession {
StringTokenizer tokens = new StringTokenizer(allowed, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
allowedIPs.put(address, "");
allowedIPs.add( address );
}
String allowedAnonym = JiveGlobals.getProperty(ConnectionSettings.Client.LOGIN_ANONYM_ALLOWED, "");
tokens = new StringTokenizer(allowedAnonym, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
allowedAnonymIPs.put(address, "");
allowedAnonymIPs.add(address);
}
String blocked = JiveGlobals.getProperty(ConnectionSettings.Client.LOGIN_BLOCKED, "");
tokens = new StringTokenizer(blocked, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
blockedIPs.add( address );
}
}
......@@ -141,23 +146,73 @@ public class LocalClientSession extends LocalSession implements ClientSession {
* subject to {@link #getAllowedAnonymIPs()}. This list is used for both anonymous and
* non-anonymous users.
*
* Note that the blacklist in {@link #getBlacklistedIPs()} should take precedence!
*
* @return the list of IP address that are allowed to connect to the server.
* @deprecated Use #getWhitelistedIPs instead.
*/
public static Map<String, String> getAllowedIPs() {
return allowedIPs;
@Deprecated
public static Map<String, String> getAllowedIPs()
{
final Map<String, String> result = new HashMap<>();
for ( String item : allowedIPs )
{
result.put( item, null );
}
return result;
}
/**
* Returns the list of IP address that are allowed to connect to the server. If the list is empty then anyone is
* allowed to connect to the server except for anonymous users that are subject to
* {@link #getWhitelistedAnonymousIPs()}. This list is used for both anonymous and non-anonymous users.
*
* Note that the blacklist in {@link #getBlacklistedIPs()} should take precedence!
*
* @return the collection of IP address that are allowed to connect to the server. Never null, possibly empty.
*/
public static Set<String> getWhitelistedIPs() { return allowedIPs; }
/**
* Returns the list of IP address that are allowed to connect to the server for anonymous
* users. If the list is empty then anonymous will be only restricted by {@link #getAllowedIPs()}.
*
* Note that the blacklist in {@link #getBlacklistedIPs()} should take precedence!
*
* @return the list of IP address that are allowed to connect to the server.
* @deprecated Use #getWhitelistedAnonymousIPs instead.
*/
public static Map<String, String> getAllowedAnonymIPs()
{
final Map<String, String> result = new HashMap<>();
for ( String item : allowedAnonymIPs )
{
result.put( item, null );
}
return result;
}
/**
* Returns the list of IP address that are allowed to connect to the server for anonymous users. If the list is
* empty then anonymous will be only restricted by {@link #getWhitelistedIPs()}.
*
* Note that the blacklist in {@link #getBlacklistedIPs()} should take precedence!
*
* @return the collection of IP address that are allowed to connect to the server. Never null, possibly empty.
*/
public static Map<String, String> getAllowedAnonymIPs() {
public static Set<String> getWhitelistedAnonymousIPs() {
return allowedAnonymIPs;
}
/**
* Returns the list of IP address that are disallowed to connect to the server. If the list is empty then anyone is
* allowed to connect to the server, subject to whitelisting. This list is used for both anonymous and
* non-anonymous users.
*
* @return the collection of IP address that are not allowed to connect to the server. Never null, possibly empty.
*/
public static Set<String> getBlacklistedIPs() { return blockedIPs; }
/**
* Returns a newly created session between the server and a client. The session will
* be created and returned only if correct name/prefix (i.e. 'stream' or 'flash')
......@@ -188,26 +243,23 @@ public class LocalClientSession extends LocalSession implements ClientSession {
"admin.error.bad-namespace"));
}
if (!allowedIPs.isEmpty()) {
if (!isAllowed(connection))
{
// Client cannot connect from this IP address so end the stream and TCP connection.
String hostAddress = "Unknown";
// The server is using a whitelist so check that the IP address of the client
// is authorized to connect to the server
try {
hostAddress = connection.getHostAddress();
hostAddress = connection.getHostAddress();
} catch (UnknownHostException e) {
// Do nothing
}
if (!isAllowed(connection)) {
// Client cannot connect from this IP address so end the stream and
// TCP connection
Log.debug("LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress);
// Include the not-authorized error in the response
StreamError error = new StreamError(StreamError.Condition.not_authorized);
connection.deliverRawText(error.toXML());
// Close the underlying connection
connection.close();
return null;
}
Log.debug("LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress);
// Include the not-authorized error in the response
StreamError error = new StreamError(StreamError.Condition.not_authorized);
connection.deliverRawText(error.toXML());
// Close the underlying connection
connection.close();
return null;
}
// Default language is English ("en").
......@@ -333,30 +385,55 @@ public class LocalClientSession extends LocalSession implements ClientSession {
return session;
}
public static boolean isAllowed(Connection connection) {
if (!allowedIPs.isEmpty()) {
// The server is using a whitelist so check that the IP address of the client
// is authorized to connect to the server
boolean forbidAccess = false;
try {
if (!allowedIPs.containsKey(connection.getHostAddress())) {
byte[] address = connection.getAddress();
String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." +
(address[2] & 0xff) +
".*";
String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*";
String range3 = (address[0] & 0xff) + ".*.*.*";
if (!allowedIPs.containsKey(range1) && !allowedIPs.containsKey(range2) &&
!allowedIPs.containsKey(range3)) {
forbidAccess = true;
}
}
} catch (UnknownHostException e) {
forbidAccess = true;
public static boolean isAllowed( Connection connection )
{
try
{
final String hostAddress = connection.getHostAddress();
final byte[] address = connection.getAddress();
// Blacklist takes precedence over whitelist.
if ( blockedIPs.contains( hostAddress ) || isAddressInRange( address, blockedIPs ) ) {
return false;
}
return !forbidAccess;
// When there's a whitelist (not empty), you must be on it to be allowed.
return allowedIPs.isEmpty() || allowedIPs.contains( hostAddress ) || isAddressInRange( address, allowedIPs );
}
return true;
catch ( UnknownHostException e )
{
return false;
}
}
public static boolean isAllowedAnonymous( Connection connection )
{
try
{
final String hostAddress = connection.getHostAddress();
final byte[] address = connection.getAddress();
// Blacklist takes precedence over whitelist.
if ( blockedIPs.contains( hostAddress ) || isAddressInRange( address, blockedIPs ) ) {
return false;
}
// When there's a whitelist (not empty), you must be on it to be allowed.
return allowedAnonymIPs.isEmpty() || allowedAnonymIPs.contains( hostAddress ) || isAddressInRange( address, allowedAnonymIPs );
}
catch ( UnknownHostException e )
{
return false;
}
}
// TODO Add IPv6 support
public static boolean isAddressInRange( byte[] address, Set<String> ranges ) {
final String range0 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." + (address[2] & 0xff) + "." + (address[3] & 0xff);
final String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." + (address[2] & 0xff) + ".*";
final String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*";
final String range3 = (address[0] & 0xff) + ".*.*.*";
return ranges.contains(range0) || ranges.contains(range1) || ranges.contains(range2) || ranges.contains(range3);
}
/**
......@@ -366,8 +443,26 @@ public class LocalClientSession extends LocalSession implements ClientSession {
* non-anonymous users.
*
* @param allowed the list of IP address that are allowed to connect to the server.
* @deprecated Use setWhitelistedIPs instead.
*/
@Deprecated
public static void setAllowedIPs(Map<String, String> allowed) {
setWhitelistedIPs( allowed.keySet() );
}
/**
* Sets the list of IP address that are allowed to connect to the server. If the list is empty then anyone not on
* {@link #getBlacklistedIPs()} is allowed to connect to the server except for anonymous users that are subject to
* {@link #getWhitelistedAnonymousIPs()}. This list is used for both anonymous and non-anonymous users.
*
* Note that blacklisting takes precedence over whitelisting: if an address is matched by both, access is denied.
*
* @param allowed the list of IP address that are allowed to connect to the server. Can be empty, but not null.
*/
public static void setWhitelistedIPs(Set<String> allowed) {
if (allowed == null) {
throw new NullPointerException();
}
allowedIPs = allowed;
if (allowedIPs.isEmpty()) {
JiveGlobals.deleteProperty(ConnectionSettings.Client.LOGIN_ALLOWED);
......@@ -375,7 +470,7 @@ public class LocalClientSession extends LocalSession implements ClientSession {
else {
// Iterate through the elements in the map.
StringBuilder buf = new StringBuilder();
Iterator<String> iter = allowedIPs.keySet().iterator();
Iterator<String> iter = allowedIPs.iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
......@@ -391,8 +486,23 @@ public class LocalClientSession extends LocalSession implements ClientSession {
* users. If the list is empty then anonymous will be only restricted by {@link #getAllowedIPs()}.
*
* @param allowed the list of IP address that are allowed to connect to the server.
* @deprecated use #setWhitelistedAnonymousIPs instead.
*/
@Deprecated
public static void setAllowedAnonymIPs(Map<String, String> allowed) {
setWhitelistedAnonymousIPs( allowed.keySet() );
}
/**
* Sets the list of IP address that are allowed to connect to the server for anonymous users. If the list is empty
* then anonymous will be only restricted by {@link #getBlacklistedIPs()} and {@link #getWhitelistedIPs()}.
*
* @param allowed the list of IP address that are allowed to connect to the server. Can be empty, but not null.
*/
public static void setWhitelistedAnonymousIPs(Set<String> allowed) {
if (allowed == null) {
throw new NullPointerException();
}
allowedAnonymIPs = allowed;
if (allowedAnonymIPs.isEmpty()) {
JiveGlobals.deleteProperty(ConnectionSettings.Client.LOGIN_ANONYM_ALLOWED);
......@@ -400,7 +510,7 @@ public class LocalClientSession extends LocalSession implements ClientSession {
else {
// Iterate through the elements in the map.
StringBuilder buf = new StringBuilder();
Iterator<String> iter = allowedAnonymIPs.keySet().iterator();
Iterator<String> iter = allowedAnonymIPs.iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
......@@ -411,6 +521,34 @@ public class LocalClientSession extends LocalSession implements ClientSession {
}
}
/**
* Sets the list of IP address that are not allowed to connect to the server. This list is used for both anonymous
* and non-anonymous users, and always takes precedence over a whitelist.
*
* @param blocked the list of IP address that are not allowed to connect to the server. Can be empty, but not null.
*/
public static void setBlacklistedIPs(Set<String> blocked) {
if (blocked == null) {
throw new NullPointerException();
}
blockedIPs = blocked;
if (blockedIPs.isEmpty()) {
JiveGlobals.deleteProperty(ConnectionSettings.Client.LOGIN_BLOCKED);
}
else {
// Iterate through the elements in the map.
StringBuilder buf = new StringBuilder();
Iterator<String> iter = blocked.iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
while (iter.hasNext()) {
buf.append(", ").append(iter.next());
}
JiveGlobals.setProperty(ConnectionSettings.Client.LOGIN_BLOCKED, buf.toString());
}
}
/**
* Returns the Privacy list that overrides the default privacy list. This list affects
* only this session and only for the duration of the session.
......
......@@ -24,11 +24,8 @@
org.jivesoftware.util.ParamUtils"
errorPage="error.jsp"
%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.StringTokenizer"%>
<%@ page import="java.util.regex.Pattern" %>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
......@@ -51,6 +48,7 @@
boolean anonLogin = ParamUtils.getBooleanParameter(request, "anonLogin");
String allowedIPs = request.getParameter("allowedIPs");
String allowedAnonymIPs = request.getParameter("allowedAnonymIPs");
String blockedIPs = request.getParameter("blockedIPs");
// Get an IQRegisterHandler:
IQRegisterHandler regHandler = XMPPServer.getInstance().getIQRegisterHandler();
IQAuthHandler authHandler = XMPPServer.getInstance().getIQAuthHandler();
......@@ -64,29 +62,39 @@
Pattern pattern = Pattern.compile("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.)" +
"(?:(?:\\*|25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){2}" +
"(?:\\*|25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
Map<String, String> newMap = new HashMap<String, String>();
Set<String> allowedSet = new HashSet<String>();
StringTokenizer tokens = new StringTokenizer(allowedIPs, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
if (pattern.matcher(address).matches()) {
newMap.put(address, "");
allowedSet.add( address );
}
}
Map<String, String> allowedAnonymMap = new HashMap<String, String>();
Set<String> allowedAnonymousSet = new HashSet<String>();
StringTokenizer tokens1 = new StringTokenizer(allowedAnonymIPs, ", ");
while (tokens1.hasMoreTokens()) {
String address = tokens1.nextToken().trim();
if (pattern.matcher(address).matches()) {
allowedAnonymMap.put(address, "");
allowedAnonymousSet.add( address );
}
}
LocalClientSession.setAllowedIPs(newMap);
LocalClientSession.setAllowedAnonymIPs(allowedAnonymMap);
Set<String> blockedSet = new HashSet<String>();
StringTokenizer tokens2 = new StringTokenizer(blockedIPs, ", ");
while (tokens2.hasMoreTokens()) {
String address = tokens2.nextToken().trim();
if (pattern.matcher(address).matches()) {
blockedSet.add( address );
}
}
LocalClientSession.setWhitelistedIPs( allowedSet );
LocalClientSession.setWhitelistedAnonymousIPs( allowedAnonymousSet );
LocalClientSession.setBlacklistedIPs( blockedSet );
// Log the event
webManager.logEvent("edited registration settings", "inband enabled = "+inbandEnabled+"\ncan change password = "+canChangePassword+"\nanon login = "+anonLogin+"\nallowed ips = "+allowedIPs);
webManager.logEvent("edited registration settings", "inband enabled = "+inbandEnabled+"\ncan change password = "+canChangePassword+"\nanon login = "+anonLogin+"\nallowed ips = "+allowedIPs+"\nblocked ips = "+blockedIPs);
}
// Reset the value of page vars:
......@@ -95,7 +103,7 @@
anonLogin = authHandler.isAnonymousAllowed();
// Encode the allowed IP addresses
StringBuilder buf = new StringBuilder();
Iterator<String> iter = org.jivesoftware.openfire.session.LocalClientSession.getAllowedIPs().keySet().iterator();
Iterator<String> iter = org.jivesoftware.openfire.session.LocalClientSession.getWhitelistedIPs().iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
......@@ -105,7 +113,7 @@
allowedIPs = buf.toString();
StringBuilder buf1 = new StringBuilder();
Iterator<String> iter1 = org.jivesoftware.openfire.session.LocalClientSession.getAllowedAnonymIPs().keySet().iterator();
Iterator<String> iter1 = org.jivesoftware.openfire.session.LocalClientSession.getWhitelistedAnonymousIPs().iterator();
if (iter1.hasNext()) {
buf1.append(iter1.next());
}
......@@ -113,6 +121,17 @@
buf1.append(", ").append(iter1.next());
}
allowedAnonymIPs = buf1.toString();
StringBuilder buf2 = new StringBuilder();
Iterator<String> iter2 = org.jivesoftware.openfire.session.LocalClientSession.getBlacklistedIPs().iterator();
if (iter2.hasNext()) {
buf2.append(iter2.next());
}
while (iter2.hasNext()) {
buf2.append(", ").append(iter2.next());
}
blockedIPs = buf2.toString();
%>
<p>
......@@ -234,6 +253,20 @@
<br>
<h4><fmt:message key="reg.settings.allowed_ips" /></h4>
<p>
<fmt:message key="reg.settings.allowed_ips_blocked_info" />
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td valign='top'><b><fmt:message key="reg.settings.ips_blocked" /></b></td>
<td>
<textarea name="blockedIPs" cols="40" rows="3" wrap="virtual"><%= ((blockedIPs != null) ? blockedIPs : "") %></textarea>
</td>
</tr>
</tbody>
</table>
<p>
<fmt:message key="reg.settings.allowed_ips_info" />
</p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment