Commit bd5b6ba4 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Receive and check IP addres of client connected through CM. JM-1373

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10439 b35dd754-fafc-0310-a699-88a17e54d16e
parent ef99bfef
......@@ -19,6 +19,7 @@ import org.jivesoftware.openfire.session.ConnectionMultiplexerSession;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
......@@ -34,11 +35,15 @@ public class ClientSessionConnection extends VirtualConnection {
private String connectionManagerName;
private String serverName;
private ConnectionMultiplexerManager multiplexerManager;
private String hostName;
private String hostAddress;
public ClientSessionConnection(String connectionManagerName) {
public ClientSessionConnection(String connectionManagerName, String hostName, String hostAddress) {
this.connectionManagerName = connectionManagerName;
multiplexerManager = ConnectionMultiplexerManager.getInstance();
serverName = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
this.hostName = hostName;
this.hostAddress = hostAddress;
}
/**
......@@ -97,11 +102,16 @@ public class ClientSessionConnection extends VirtualConnection {
}
public byte[] getAddress() throws UnknownHostException {
if (hostAddress != null) {
return InetAddress.getByName(hostAddress).getAddress();
}
return null;
}
public String getHostAddress() throws UnknownHostException {
//TODO Future version may return actual IP client address. We would need to pass this info
if (hostAddress != null) {
return hostAddress;
}
// Return IP address of the connection manager that the client used to log in
ConnectionMultiplexerSession multiplexerSession =
multiplexerManager.getMultiplexerSession(connectionManagerName);
......@@ -112,7 +122,9 @@ public class ClientSessionConnection extends VirtualConnection {
}
public String getHostName() throws UnknownHostException {
//TODO Future version may return actual IP client address. We would need to pass this info
if (hostName != null) {
return hostName;
}
// Return IP address of the connection manager that the client used to log in
ConnectionMultiplexerSession multiplexerSession =
multiplexerManager.getMultiplexerSession(connectionManagerName);
......
......@@ -26,6 +26,7 @@ import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.TaskEngine;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
......@@ -123,26 +124,40 @@ public class ConnectionMultiplexerManager implements SessionEventListener {
* @param connectionManagerDomain the connection manager that is handling the connection
* of the session.
* @param streamID the stream ID created by the connection manager for the new session.
* @param hostName the address's hostname of the client or null if using old connection manager.
* @param hostAddress the textual representation of the address of the client or null if using old CM.
* @return true if a session was created or false if the client should disconnect.
*/
public void createClientSession(String connectionManagerDomain, String streamID) {
// TODO Consider that client session may return null when IP address is forbidden
Connection connection = new ClientSessionConnection(connectionManagerDomain);
LocalClientSession session =
SessionManager.getInstance().createClientSession(connection, new BasicStreamID(streamID));
// Register that this streamID belongs to the specified connection manager
streamIDs.put(streamID, connectionManagerDomain);
// Register which sessions are being hosted by the speicifed connection manager
Map<String, LocalClientSession> sessions = sessionsByManager.get(connectionManagerDomain);
if (sessions == null) {
synchronized (connectionManagerDomain.intern()) {
sessions = sessionsByManager.get(connectionManagerDomain);
if (sessions == null) {
sessions = new ConcurrentHashMap<String, LocalClientSession>();
sessionsByManager.put(connectionManagerDomain, sessions);
public boolean createClientSession(String connectionManagerDomain, String streamID, String hostName, String hostAddress) {
Connection connection = new ClientSessionConnection(connectionManagerDomain, hostName, hostAddress);
// Check if client is allowed to connect from the specified IP address. Ignore the checking if connection
// manager is old version and is not passing client's address
byte[] address = null;
try {
address = connection.getAddress();
} catch (UnknownHostException e) {
// Ignore
}
if (address == null || LocalClientSession.isAllowed(connection)) {
LocalClientSession session =
SessionManager.getInstance().createClientSession(connection, new BasicStreamID(streamID));
// Register that this streamID belongs to the specified connection manager
streamIDs.put(streamID, connectionManagerDomain);
// Register which sessions are being hosted by the speicifed connection manager
Map<String, LocalClientSession> sessions = sessionsByManager.get(connectionManagerDomain);
if (sessions == null) {
synchronized (connectionManagerDomain.intern()) {
sessions = sessionsByManager.get(connectionManagerDomain);
if (sessions == null) {
sessions = new ConcurrentHashMap<String, LocalClientSession>();
sessionsByManager.put(connectionManagerDomain, sessions);
}
}
}
sessions.put(streamID, session);
return true;
}
sessions.put(streamID, session);
return false;
}
/**
......
......@@ -73,10 +73,22 @@ public class MultiplexerPacketHandler {
sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
}
else if ("session".equals(child.getName())) {
if (child.element("create") != null) {
Element create = child.element("create");
if (create != null) {
// Get the InetAddress of the client
Element hostElement = create.element("host");
String hostName = hostElement != null ? hostElement.attributeValue("name") : null;
String hostAddress = hostElement != null ? hostElement.attributeValue("address") : null;
// Connection Manager wants to create a Client Session
multiplexerManager.createClientSession(connectionManagerDomain, streamID);
sendResultPacket(iq);
boolean created = multiplexerManager
.createClientSession(connectionManagerDomain, streamID, hostName, hostAddress);
if (created) {
sendResultPacket(iq);
}
else {
// Send error to CM. The CM should close the new-borned connection
sendErrorPacket(iq, PacketError.Condition.not_allowed, null);
}
}
else {
ClientSession session = multiplexerManager
......
......@@ -152,28 +152,15 @@ public class LocalClientSession extends LocalSession implements ClientSession {
}
if (!allowedIPs.isEmpty()) {
boolean forbidAccess = false;
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();
if (!allowedIPs.containsKey(hostAddress)) {
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;
// Do nothing
}
if (forbidAccess) {
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);
......@@ -310,6 +297,32 @@ 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;
}
return !forbidAccess;
}
return true;
}
/**
* 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.
......
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