Commit 6b109ac1 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added support to restrict login access for anonymous users by IP address. JM-1389

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10510 b35dd754-fafc-0310-a699-88a17e54d16e
parent 701d2523
......@@ -2394,4 +2394,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2380,4 +2380,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -443,7 +443,8 @@
## Added key: 'clearspace.status.connected.table.label.received'
## Added key: 'clearspace.status.connected.table.label.hostname'
## Added key: 'clearspace.status.connected.adminbutton'
## Added key: 'reg.settings.ips_all'
## Added key: 'reg.settings.ips_anonymous'
# Openfire
......@@ -1325,6 +1326,8 @@ 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:
# Server db Page
......
......@@ -2431,4 +2431,6 @@ setup.clearspace.service.certificate.verify.identity_help=Primer certificado de
setup.clearspace.service.certificate.verify.root=Verificar certificado raiz
setup.clearspace.service.certificate.verify.root_help=Ultimo certificado en la cadena fue emitido por CA conocido
setup.clearspace.service.certificate.verify.validity=Verificar certificado no expirado
setup.clearspace.service.certificate.verify.validity_help=Certificado sea valido en el tiempo actual
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificado sea valido en el tiempo actual
reg.settings.ips_all=Restringir TODOS los ingresos de estas IPs:
reg.settings.ips_anonymous=Restringir ingresos anonimos de estas IPs:
\ No newline at end of file
......@@ -2002,4 +2002,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2527,4 +2527,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2391,4 +2391,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2360,4 +2360,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2394,4 +2394,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2509,4 +2509,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -2172,4 +2172,6 @@ setup.clearspace.service.certificate.verify.identity_help=First certificate in t
setup.clearspace.service.certificate.verify.root=Verify root certificate
setup.clearspace.service.certificate.verify.root_help=Last certificate in the chain was issued by a trusted CA
setup.clearspace.service.certificate.verify.validity=Verify certificate is not expired
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
\ No newline at end of file
setup.clearspace.service.certificate.verify.validity_help=Certificate is valid at the current time.
reg.settings.ips_all=Restrict ALL (including anonymous) logins by these IP's:
reg.settings.ips_anonymous=Restrict anonymous logins by these IP's:
\ No newline at end of file
......@@ -36,6 +36,7 @@ import org.xmpp.packet.StreamError;
import java.util.ArrayList;
import java.util.List;
import java.net.UnknownHostException;
/**
* Implements the TYPE_IQ jabber:iq:auth protocol (plain only). Clients
......@@ -276,12 +277,42 @@ public class IQAuthHandler extends IQHandler implements IQAuthInfo {
private IQ anonymousLogin(LocalClientSession session, IQ packet) {
IQ response = IQ.createResultIQ(packet);
if (anonymousAllowed) {
session.setAnonymousAuth();
response.setTo(session.getAddress());
Element auth = response.setChildElement("query", "jabber:iq:auth");
auth.addElement("resource").setText(session.getAddress().getResource());
// 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;
}
if (forbidAccess) {
// Connection forbidden from that IP address
response.setChildElement(packet.getChildElement().createCopy());
response.setError(PacketError.Condition.forbidden);
}
else {
// Anonymous authentication allowed
session.setAnonymousAuth();
response.setTo(session.getAddress());
Element auth = response.setChildElement("query", "jabber:iq:auth");
auth.addElement("resource").setText(session.getAddress().getResource());
}
}
else {
// Anonymous authentication is not allowed
response.setChildElement(packet.getChildElement().createCopy());
response.setError(PacketError.Condition.forbidden);
}
......
......@@ -38,6 +38,7 @@ import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.*;
import java.net.UnknownHostException;
/**
* SASLAuthentication is responsible for returning the available SASL mechanisms to use and for
......@@ -396,6 +397,31 @@ 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;
}
if (forbidAccess) {
authenticationFailed(session);
return Status.failed;
}
// Just accept the authentication :)
authenticationSuccessful(session, null, null);
return Status.authenticated;
......
......@@ -61,6 +61,7 @@ public class LocalClientSession extends LocalSession implements ClientSession {
* performance reasons.
*/
private static Map<String,String> allowedIPs = new HashMap<String,String>();
private static Map<String,String> allowedAnonymIPs = new HashMap<String,String>();
/**
* The authentication token for this session.
......@@ -109,11 +110,20 @@ public class LocalClientSession extends LocalSession implements ClientSession {
String address = tokens.nextToken().trim();
allowedIPs.put(address, "");
}
String allowedAnonym = JiveGlobals.getProperty("xmpp.client.login.allowedAnonym", "");
tokens = new StringTokenizer(allowedAnonym, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
allowedAnonymIPs.put(address, "");
}
}
/**
* 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.
* empty then anyone is allowed to connect to the server except for anonymous users that are
* subject to {@link #getAllowedAnonymIPs()}. This list is used for both anonymous and
* non-anonymous users.
*
* @return the list of IP address that are allowed to connect to the server.
*/
......@@ -121,6 +131,17 @@ public class LocalClientSession extends LocalSession implements ClientSession {
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()}.
*
* @return the list of IP address that are allowed to connect to the server.
*/
public static Map<String, String> getAllowedAnonymIPs() {
return allowedAnonymIPs;
}
/**
* 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')
......@@ -325,7 +346,9 @@ public class LocalClientSession extends LocalSession implements ClientSession {
/**
* Sets 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.
* empty then anyone is allowed to connect to the server except for anonymous users that are
* subject to {@link #getAllowedAnonymIPs()}. This list is used for both anonymous and
* non-anonymous users.
*
* @param allowed the list of IP address that are allowed to connect to the server.
*/
......@@ -348,6 +371,31 @@ public class LocalClientSession extends LocalSession implements ClientSession {
}
}
/**
* 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 #getAllowedIPs()}.
*
* @param allowed the list of IP address that are allowed to connect to the server.
*/
public static void setAllowedAnonymIPs(Map<String, String> allowed) {
allowedAnonymIPs = allowed;
if (allowedAnonymIPs.isEmpty()) {
JiveGlobals.deleteProperty("xmpp.client.login.allowedAnonym");
}
else {
// Iterate through the elements in the map.
StringBuilder buf = new StringBuilder();
Iterator<String> iter = allowedAnonymIPs.keySet().iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
while (iter.hasNext()) {
buf.append(", ").append(iter.next());
}
JiveGlobals.setProperty("xmpp.client.login.allowedAnonym", buf.toString());
}
}
/**
* Returns whether TLS is mandatory, optional or is disabled for clients. When TLS is
* mandatory clients are required to secure their connections or otherwise their connections
......
......@@ -42,7 +42,7 @@
boolean canChangePassword = ParamUtils.getBooleanParameter(request, "canChangePassword");
boolean anonLogin = ParamUtils.getBooleanParameter(request, "anonLogin");
String allowedIPs = request.getParameter("allowedIPs");
String allowedAnonymIPs = request.getParameter("allowedAnonymIPs");
// Get an IQRegisterHandler:
IQRegisterHandler regHandler = XMPPServer.getInstance().getIQRegisterHandler();
IQAuthHandler authHandler = XMPPServer.getInstance().getIQAuthHandler();
......@@ -64,7 +64,18 @@
newMap.put(address, "");
}
}
Map<String, String> allowedAnonymMap = new HashMap<String, String>();
StringTokenizer tokens1 = new StringTokenizer(allowedAnonymIPs, ", ");
while (tokens1.hasMoreTokens()) {
String address = tokens1.nextToken().trim();
if (pattern.matcher(address).matches()) {
allowedAnonymMap.put(address, "");
}
}
LocalClientSession.setAllowedIPs(newMap);
LocalClientSession.setAllowedAnonymIPs(allowedAnonymMap);
// Log the event
webManager.logEvent("edited registration settings", "inband enabled = "+inbandEnabled+"\ncan change password = "+canChangePassword+"\nanon login = "+anonLogin+"\nallowed ips = "+allowedIPs);
......@@ -84,6 +95,16 @@
buf.append(", ").append(iter.next());
}
allowedIPs = buf.toString();
StringBuilder buf1 = new StringBuilder();
Iterator<String> iter1 = org.jivesoftware.openfire.session.LocalClientSession.getAllowedAnonymIPs().keySet().iterator();
if (iter1.hasNext()) {
buf1.append(iter1.next());
}
while (iter1.hasNext()) {
buf1.append(", ").append(iter1.next());
}
allowedAnonymIPs = buf1.toString();
%>
<p>
......@@ -211,10 +232,17 @@
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td valign='top'><b><fmt:message key="reg.settings.ips_all" /></b></td>
<td>
<textarea name="allowedIPs" cols="40" rows="3" wrap="virtual"><%= ((allowedIPs != null) ? allowedIPs : "") %></textarea>
</td>
</tr>
<tr>
<td valign='top'><b><fmt:message key="reg.settings.ips_anonymous" /></b></td>
<td>
<textarea name="allowedAnonymIPs" cols="40" rows="3" wrap="virtual"><%= ((allowedAnonymIPs != null) ? allowedAnonymIPs : "") %></textarea>
</td>
</tr>
</tbody>
</table>
......@@ -226,4 +254,5 @@
</body>
</html>
\ No newline at end of file
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