Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PlainSocketFactory and make it a default fallback #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ Any authorization on the server must be configured using the `jmx.remote.accessc
- Applications can also implement the `nl.futureedge.simple.jmx.access.JMXAccessController` interface instead of using the supplied implementations to fully customize their access control.

### Connections (client-side and server-side)
Connections are made via standaard Java sockets. Simple JMX provides two connection provider out of the box:
- Anonymous SSL (allows operation without certificates) ****default***\*
Connections are made via standaard Java sockets. Simple JMX provides three connection provider out of the box:
- Plain sockets (provides no security) ****default***\*
- Anonymous SSL (allows operation without certificates, but note that these cipher suites are often not enabled)
- System SSL (uses the default Java SSL provider)

Any connection configuration (on the client or the server) must be configured using the `jmx.remote.socketfactory` key in the environment; the value should be an object instance that implements the `nl.futureedge.jmx.socket.JMXSocketFactory` interface:

- Plain socket implementation (`nl.futureedge.simple.jmx.socket.PlainSocketFactory`) does not have any configuration.
- The anonymous SSL implementation (`nl.futureedge.simple.jmx.socket.AnonymousSslSocketFactory`) does not have any specific configuration.
- The system SSL implementation (`nl.futureedge.simple.jmx.socket.SystemSslSocketFactory`) uses the system default SSLContext and should be configured using the [system configuration](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html).
- Applications can also implement the `nl.futureedge.simple.jmx.socket.JMXSocketFactory` interface to fully customize their connections.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import nl.futureedge.simple.jmx.authenticator.StaticAuthenticator;
import nl.futureedge.simple.jmx.socket.AnonymousSslSocketFactory;
import nl.futureedge.simple.jmx.socket.JMXSocketFactory;
import nl.futureedge.simple.jmx.socket.PlainSocketFactory;
import nl.futureedge.simple.jmx.socket.SslConfigurationException;

/**
Expand All @@ -33,6 +34,8 @@ private Environment() {

public static final String KEY_THREADPRIORITY = "jmx.remote.threadpriority";

public static final String KEY_ANONYMOUS_CIPHERS = "jmx.remote.anonymousciphers";

public static JMXSocketFactory determineSocketFactory(final Map<String, ?> environment) throws IOException {
// Custom socket factory via the environment
final JMXSocketFactory custom = (JMXSocketFactory) environment.get(KEY_SOCKETFACTORY);
Expand All @@ -41,10 +44,14 @@ public static JMXSocketFactory determineSocketFactory(final Map<String, ?> envir
}

// Default: no authentication
try {
return new AnonymousSslSocketFactory();
} catch (final SslConfigurationException e) {
throw new IOException("Could not create default socket factory", e);
if (environment.containsKey(KEY_ANONYMOUS_CIPHERS)) {
try {
return new AnonymousSslSocketFactory();
} catch (final SslConfigurationException e) {
throw new IOException("Could not create default socket factory", e);
}
} else {
return new PlainSocketFactory();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package nl.futureedge.simple.jmx.socket;

import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Socket factory without any security at all.
*/
public class PlainSocketFactory implements JMXSocketFactory {

private static final int BACKLOG = 50;
private static final Logger LOGGER = Logger.getLogger(PlainSocketFactory.class.getName());

/**
* Create a client socket.
* @param serviceUrl jmx service url
* @return client socket
* @throws IOException if an I/O error occurs when creating the socket
*/
@Override
public Socket createSocket(final JMXServiceURL serviceUrl) throws IOException {
final Socket socket = new Socket(serviceUrl.getHost(), serviceUrl.getPort());
socket.setKeepAlive(true);

LOGGER.log(Level.FINE, "Created client socket");
return socket;
}

/**
* Create a server socket.
* @param serviceUrl jmx service url
* @return server socket
* @throws IOException if an I/O error occurs when creating the socket
*/
@Override
public ServerSocket createServerSocket(final JMXServiceURL serviceUrl) throws IOException {
final InetAddress host = InetAddress.getByName(serviceUrl.getHost());
final ServerSocket serverSocket = new ServerSocket(serviceUrl.getPort(), BACKLOG, host);

LOGGER.log(Level.FINE, "Created server socket");
return serverSocket;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
Expand All @@ -11,7 +12,8 @@
import javax.management.MBeanServer;
import javax.management.remote.JMXServiceURL;
import javax.net.ssl.SSLSocket;
import nl.futureedge.simple.jmx.socket.AnonymousSslSocketFactory;

import nl.futureedge.simple.jmx.socket.PlainSocketFactory;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Assert;
Expand All @@ -38,7 +40,7 @@ public class ServerListenerTest {
public void setup() throws IOException {
mBeanServer = Mockito.mock(MBeanServer.class);
serverConnector = new ServerConnector(new JMXServiceURL("simple", "localhost", 0), null, mBeanServer);
subject = new ServerListener(serverConnector, new AnonymousSslSocketFactory(), null, null, Thread.NORM_PRIORITY);
subject = new ServerListener(serverConnector, new PlainSocketFactory(), null, null, Thread.NORM_PRIORITY);
}

private void start() {
Expand All @@ -61,8 +63,10 @@ public void test() throws IOException, InterruptedException {

start();

final SSLSocket client = (SSLSocket) new AnonymousSslSocketFactory().createSocket(serverConnector.getAddress());
client.startHandshake();
final Socket client = new PlainSocketFactory().createSocket(serverConnector.getAddress());
if (client instanceof SSLSocket) {
((SSLSocket)client).startHandshake();
}
Assert.assertTrue(client.isConnected());
Assert.assertNotNull(client.getOutputStream());
Assert.assertNotNull(client.getInputStream());
Expand Down