Commit ed84841f 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/branches@10440 b35dd754-fafc-0310-a699-88a17e54d16e
parent 2f67cfc1
...@@ -19,6 +19,7 @@ import org.jivesoftware.openfire.session.ConnectionMultiplexerSession; ...@@ -19,6 +19,7 @@ import org.jivesoftware.openfire.session.ConnectionMultiplexerSession;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
/** /**
...@@ -34,11 +35,15 @@ public class ClientSessionConnection extends VirtualConnection { ...@@ -34,11 +35,15 @@ public class ClientSessionConnection extends VirtualConnection {
private String connectionManagerName; private String connectionManagerName;
private String serverName; private String serverName;
private ConnectionMultiplexerManager multiplexerManager; private ConnectionMultiplexerManager multiplexerManager;
private String hostName;
private String hostAddress;
public ClientSessionConnection(String connectionManagerName) { public ClientSessionConnection(String connectionManagerName, String hostName, String hostAddress) {
this.connectionManagerName = connectionManagerName; this.connectionManagerName = connectionManagerName;
multiplexerManager = ConnectionMultiplexerManager.getInstance(); multiplexerManager = ConnectionMultiplexerManager.getInstance();
serverName = XMPPServer.getInstance().getServerInfo().getXMPPDomain(); serverName = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
this.hostName = hostName;
this.hostAddress = hostAddress;
} }
/** /**
...@@ -97,11 +102,16 @@ public class ClientSessionConnection extends VirtualConnection { ...@@ -97,11 +102,16 @@ public class ClientSessionConnection extends VirtualConnection {
} }
public byte[] getAddress() throws UnknownHostException { public byte[] getAddress() throws UnknownHostException {
if (hostAddress != null) {
return InetAddress.getByName(hostAddress).getAddress();
}
return null; return null;
} }
public String getHostAddress() throws UnknownHostException { 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 // Return IP address of the connection manager that the client used to log in
ConnectionMultiplexerSession multiplexerSession = ConnectionMultiplexerSession multiplexerSession =
multiplexerManager.getMultiplexerSession(connectionManagerName); multiplexerManager.getMultiplexerSession(connectionManagerName);
...@@ -112,7 +122,9 @@ public class ClientSessionConnection extends VirtualConnection { ...@@ -112,7 +122,9 @@ public class ClientSessionConnection extends VirtualConnection {
} }
public String getHostName() throws UnknownHostException { 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 // Return IP address of the connection manager that the client used to log in
ConnectionMultiplexerSession multiplexerSession = ConnectionMultiplexerSession multiplexerSession =
multiplexerManager.getMultiplexerSession(connectionManagerName); multiplexerManager.getMultiplexerSession(connectionManagerName);
......
...@@ -26,6 +26,7 @@ import org.jivesoftware.util.JiveGlobals; ...@@ -26,6 +26,7 @@ import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.TaskEngine; import org.jivesoftware.util.TaskEngine;
import java.net.UnknownHostException;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -123,10 +124,21 @@ public class ConnectionMultiplexerManager implements SessionEventListener { ...@@ -123,10 +124,21 @@ public class ConnectionMultiplexerManager implements SessionEventListener {
* @param connectionManagerDomain the connection manager that is handling the connection * @param connectionManagerDomain the connection manager that is handling the connection
* of the session. * of the session.
* @param streamID the stream ID created by the connection manager for the new 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) { public boolean createClientSession(String connectionManagerDomain, String streamID, String hostName, String hostAddress) {
// TODO Consider that client session may return null when IP address is forbidden Connection connection = new ClientSessionConnection(connectionManagerDomain, hostName, hostAddress);
Connection connection = new ClientSessionConnection(connectionManagerDomain); // 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 = LocalClientSession session =
SessionManager.getInstance().createClientSession(connection, new BasicStreamID(streamID)); SessionManager.getInstance().createClientSession(connection, new BasicStreamID(streamID));
// Register that this streamID belongs to the specified connection manager // Register that this streamID belongs to the specified connection manager
...@@ -143,6 +155,9 @@ public class ConnectionMultiplexerManager implements SessionEventListener { ...@@ -143,6 +155,9 @@ public class ConnectionMultiplexerManager implements SessionEventListener {
} }
} }
sessions.put(streamID, session); sessions.put(streamID, session);
return true;
}
return false;
} }
/** /**
......
...@@ -73,11 +73,23 @@ public class MultiplexerPacketHandler { ...@@ -73,11 +73,23 @@ public class MultiplexerPacketHandler {
sendErrorPacket(iq, PacketError.Condition.bad_request, extraError); sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
} }
else if ("session".equals(child.getName())) { 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 // Connection Manager wants to create a Client Session
multiplexerManager.createClientSession(connectionManagerDomain, streamID); boolean created = multiplexerManager
.createClientSession(connectionManagerDomain, streamID, hostName, hostAddress);
if (created) {
sendResultPacket(iq); sendResultPacket(iq);
} }
else {
// Send error to CM. The CM should close the new-borned connection
sendErrorPacket(iq, PacketError.Condition.not_allowed, null);
}
}
else { else {
ClientSession session = multiplexerManager ClientSession session = multiplexerManager
.getClientSession(connectionManagerDomain, streamID); .getClientSession(connectionManagerDomain, streamID);
......
...@@ -152,28 +152,15 @@ public class LocalClientSession extends LocalSession implements ClientSession { ...@@ -152,28 +152,15 @@ public class LocalClientSession extends LocalSession implements ClientSession {
} }
if (!allowedIPs.isEmpty()) { if (!allowedIPs.isEmpty()) {
boolean forbidAccess = false;
String hostAddress = "Unknown"; String hostAddress = "Unknown";
// The server is using a whitelist so check that the IP address of the client // The server is using a whitelist so check that the IP address of the client
// is authorized to connect to the server // is authorized to connect to the server
try { try {
hostAddress = connection.getHostAddress(); 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) { } catch (UnknownHostException e) {
forbidAccess = true; // Do nothing
} }
if (forbidAccess) { if (!isAllowed(connection)) {
// Client cannot connect from this IP address so end the stream and // Client cannot connect from this IP address so end the stream and
// TCP connection // TCP connection
Log.debug("LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress); Log.debug("LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress);
...@@ -310,6 +297,32 @@ public class LocalClientSession extends LocalSession implements ClientSession { ...@@ -310,6 +297,32 @@ public class LocalClientSession extends LocalSession implements ClientSession {
return session; 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 * 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.
......
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