Commit a92017da authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Added login restriction to certain IP addresses or ranges. JM-154


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1636 b35dd754-fafc-0310-a699-88a17e54d16e
parent b5221a1e
......@@ -19,15 +19,21 @@ import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.net.SocketConnection;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
import org.xmpp.packet.StreamError;
import org.dom4j.io.XPPPacketReader;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParser;
import java.io.Writer;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
/**
* Represents a session between the server and a client.
......@@ -46,6 +52,15 @@ public class ClientSession extends Session {
private static final int MAJOR_VERSION = 0;
private static final int MINOR_VERSION = 0;
/**
* 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>
*
* Note: Key = IP address or IP range; Value = empty string. A hash map is being used for
* performance reasons.
*/
private static Map<String,String> allowedIPs = new HashMap<String,String>();
/**
* The authentication token for this session.
*/
......@@ -60,6 +75,16 @@ public class ClientSession extends Session {
private int conflictCount = 0;
static {
// Fill out the allowedIPs with the system property
String allowed = JiveGlobals.getProperty("xmpp.client.login.allowed", "");
StringTokenizer tokens = new StringTokenizer(allowed, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
allowedIPs.put(address, "");
}
}
/**
* 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')
......@@ -93,6 +118,32 @@ public class ClientSession extends Session {
"admin.error.bad-namespace"));
}
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
if (!allowedIPs.containsKey(connection.getInetAddress().getHostAddress())) {
byte[] address = connection.getInetAddress().getAddress();
String range1 = address[0] + "." + address[1] + "." + address[2] + ".*";
String range2 = address[0] + "." + address[1] + ".*.*";
String range3 = address[0] + ".*.*.*";
if (!allowedIPs.containsKey(range1) && !allowedIPs.containsKey(range2) &&
!allowedIPs.containsKey(range3)) {
// Client cannot connect from this IP address so end the stream and
// TCP connection
Log.debug("Closed connection to client attempting to connect from: " +
connection.getInetAddress().getHostAddress());
// Include the not-authorized error in the response
StreamError error = new StreamError(StreamError.Condition.not_authorized);
StringBuilder sb = new StringBuilder();
sb.append(error.toXML());
connection.deliverRawText(sb.toString());
// Close the underlying connection
connection.close();
return null;
}
}
}
// Default language is English ("en").
String language = "en";
// Default to a version of "0.0". Clients written before the XMPP 1.0 spec may
......@@ -211,6 +262,41 @@ public class ClientSession extends Session {
return session;
}
/**
* 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.
*
* @return the list of IP address that are allowed to connect to the server.
*/
public static Map<String, String> getAllowedIPs() {
return allowedIPs;
}
/**
* 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.
*
* @param allowed the list of IP address that are allowed to connect to the server.
*/
public static void setAllowedIPs(Map<String, String> allowed) {
allowedIPs = allowed;
if (allowedIPs.isEmpty()) {
JiveGlobals.deleteProperty("xmpp.client.login.allowed");
}
else {
// Iterate through the elements in the map.
StringBuilder buf = new StringBuilder();
Iterator<String> iter = allowedIPs.keySet().iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
while (iter.hasNext()) {
buf.append(", ").append((String)iter.next());
}
JiveGlobals.setProperty("xmpp.client.login.allowed", buf.toString());
}
}
/**
* Creates a session with an underlying connection and permission protection.
*
......
......@@ -9,11 +9,12 @@
- a copy of which is included in this distribution.
--%>
<%@ page import="org.jivesoftware.util.ParamUtils,
org.jivesoftware.messenger.handler.IQRegisterHandler,
<%@ page import="org.jivesoftware.messenger.handler.IQRegisterHandler,
org.jivesoftware.messenger.handler.IQAuthHandler,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.util.LocaleUtils"
java.util.*,
org.jivesoftware.messenger.ClientSession,
org.jivesoftware.util.*"
errorPage="error.jsp"
%>
......@@ -39,6 +40,7 @@
boolean inbandEnabled = ParamUtils.getBooleanParameter(request,"inbandEnabled");
boolean canChangePassword = ParamUtils.getBooleanParameter(request,"canChangePassword");
boolean anonLogin = ParamUtils.getBooleanParameter(request,"anonLogin");
String allowedIPs = request.getParameter("allowedIPs");
// Get an IQRegisterHandler:
IQRegisterHandler regHandler = new IQRegisterHandler();
......@@ -48,12 +50,31 @@
regHandler.setInbandRegEnabled(inbandEnabled);
regHandler.setCanChangePassword(canChangePassword);
authHandler.setAllowAnonymous(anonLogin);
// Build a Map with the allowed IP addresses
Map<String,String> newMap = new HashMap<String,String>();
StringTokenizer tokens = new StringTokenizer(allowedIPs, ", ");
while (tokens.hasMoreTokens()) {
String address = tokens.nextToken().trim();
newMap.put(address, "");
}
ClientSession.setAllowedIPs(newMap);
}
// Reset the value of page vars:
inbandEnabled = regHandler.isInbandRegEnabled();
canChangePassword = regHandler.canChangePassword();
anonLogin = authHandler.isAllowAnonymous();
// Encode the allowed IP addresses
StringBuilder buf = new StringBuilder();
Iterator<String> iter = ClientSession.getAllowedIPs().keySet().iterator();
if (iter.hasNext()) {
buf.append(iter.next());
}
while (iter.hasNext()) {
buf.append(", ").append((String)iter.next());
}
allowedIPs = buf.toString();
%>
<p>
......@@ -175,6 +196,26 @@
</div>
</fieldset>
<br>
<fieldset>
<legend><fmt:message key="reg.settings.allowed_ips" /></legend>
<div>
<p>
<fmt:message key="reg.settings.allowed_ips_info" />
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td>
<textarea name="allowedIPs" cols="40" rows="3" wrap="virtual"><%= ((allowedIPs != null) ? allowedIPs : "") %></textarea>
</td>
</tr>
</tbody>
</table>
</div>
</fieldset>
<br><br>
<input type="submit" name="save" value="<fmt:message key="global.save_settings" />">
......
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