Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class ConnectionWizardPage extends RelinkableWizardPage {
private final ConnectionWizardModel model;
private Text hostNameField;
private Text usernameField;
private Button requireSecureConnectionButton;
private Text portField;
private Text javaCommandField;
private Label javaCommandCaption;
Expand Down Expand Up @@ -408,15 +409,15 @@ private boolean hasServiceUrl() {
private void createHostPortServiceURLComposite(Composite outer) {
// FIXME: Make sure to fix the layout to align for all components, for example commandline, pid and service url (for JDP)
Composite inner = new Composite(outer, SWT.NONE);
GridLayout l = new GridLayout(1, false);
GridLayout l = new GridLayout(2, false);
inner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 2));

l.marginWidth = 0;
l.marginHeight = 0;
inner.setLayout(l);

fieldStack = new Composite(inner, SWT.NONE);
fieldStack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
fieldStack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appearance:
image

fieldStackLayout = new StackLayout();
fieldStack.setLayout(fieldStackLayout);
createHostPortComposite(fieldStack);
Expand All @@ -425,6 +426,10 @@ private void createHostPortServiceURLComposite(Composite outer) {
}

private void createCustomURLButtonComposite(Composite inner) {
requireSecureConnectionButton = new Button(inner, SWT.CHECK);
requireSecureConnectionButton.setText(Messages.ConnectionWizardPage_REQUIRE_SECURE_CONNECTION_LABEL);
requireSecureConnectionButton
.setLayoutData(new GridData(SWT.LEFT, GridData.VERTICAL_ALIGN_BEGINNING, false, false));
CustomURLSelector customURLSelector = new CustomURLSelector();
customUrlButton = new Button(inner, SWT.TOGGLE);
customUrlButton.setText(Messages.ConnectionWizardPage_BUTTON_CUSTOM_JMX_SERVICE_URL_TEXT);
Expand Down Expand Up @@ -487,6 +492,9 @@ private void initializeFields() {
if (server != null) {
currentUrl = server.getConnectionUrl();
name = server.getServerHandle().getServerDescriptor().getDisplayName();
if (server.getServerHandle().getConnectionDescriptor().requireSecureConnection()) {
this.requireSecureConnectionButton.setSelection(true);
}
ICredentials credential = server.getCredentials();
if (credential != null) {
try {
Expand Down Expand Up @@ -670,7 +678,7 @@ void updateModel() {

ServerModelCredentials credentials = new ServerModelCredentials(username, password, storePassword);
IConnectionDescriptor cd = new ConnectionDescriptorBuilder().url(currentUrl).credentials(credentials)
.build();
.requireSecureConnection(isSecureConnectionRequired()).build();

Server newServer;
if (server != null) {
Expand All @@ -694,6 +702,10 @@ void updateModel() {
}
}

private boolean isSecureConnectionRequired() {
return requireSecureConnectionButton.getSelection();
}

private Exception testConnection() {
if (model.createdServer == null) {
updateModel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class Messages extends NLS {
public static String ConnectionWizardPage_PASSWORD_TOOLTIP;
public static String ConnectionWizardPage_PORT_CAPTION;
public static String ConnectionWizardPage_PORT_TOOLTIP;
public static String ConnectionWizardPage_REQUIRE_SECURE_CONNECTION_LABEL;
public static String ConnectionWizardPage_SERVICE_URL_CAPTION;
public static String ConnectionWizardPage_SERVICE_URL_TOOLTIP;
public static String ConnectionWizardPage_STATUS_CAPTION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ ConnectionWizardPage_STATUS_IS_UNTESTED=Untested
ConnectionWizardPage_STATUS_IS_CONNECTED=OK
ConnectionWizardPage_STATUS_IS_NOT_CONNECTED=Unable to connect
ConnectionWizardPage_COULD_NOT_CONNECT_DISABLE_NEXT=Could not connect to {0}. Click Finish to create the connection without connecting.

ConnectionWizardPage_REQUIRE_SECURE_CONNECTION_LABEL=Require secure connection
ServerSelectionWizardPage_NEW_CONNECTION=Create a new connection
ServerConnectWizardPage_SERVER_SELECT_DESCRIPTION=Select a JVM to connect to
ServerConnectWizardPage_TOOL_SELECT_DESCRIPTION=Select a tool to connect to {0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ public void run() {
WorkbenchToolkit.asyncCloseEditor(ConsoleEditor.this);
// FIXME: Show stacktrace? (Need to show our own ExceptionDialog in that case, or maybe create our own DetailsAreaProvider, see WorkbenchStatusDialogManager.setDetailsAreaProvider)
return new Status(IStatus.ERROR, ConsolePlugin.PLUGIN_ID, IStatus.ERROR,
NLS.bind(Messages.ConsoleEditor_COULD_NOT_CONNECT, getEditorInput().getName(), e.getMessage()),
e);
NLS.bind(e.getLocalizedMessage(), getEditorInput().getName(), e.getMessage()), e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2025, Kantega AS. All rights reserved.
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Kantega AS. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class ConnectionDescriptorBuilder {
private String password;
private int port = DEFAULT_PORT;
private ICredentials credentials;
private boolean requireSecureConnection;

/**
* Port number designator meaning that the default port for the selected protocol should be
Expand Down Expand Up @@ -142,6 +143,16 @@ public ConnectionDescriptorBuilder password(String password) {
return this;
}

/**
* @param requireSecureConnection
* force connection to use TLS. Fail if not possible.
* @return the Builder currently being configured.
*/
public ConnectionDescriptorBuilder requireSecureConnection(boolean requireSecureConnection) {
this.requireSecureConnection = requireSecureConnection;
return this;
}

/**
* Builds the {@link IConnectionDescriptor}.
*
Expand Down Expand Up @@ -169,6 +180,6 @@ public IConnectionDescriptor build() throws IllegalStateException {
}
}

return new JMXConnectionDescriptor(url, credentials);
return new JMXConnectionDescriptor(url, credentials, requireSecureConnection);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
*/
public interface IConnectionDescriptor {

// JMX convention. See e.g.
// https://github.com/openjdk/jdk/blob/master/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java
static final String JMX_REMOTE_X_CHECK_STUB = "jmx.remote.x.check.stub"; //$NON-NLS-1$

/**
* Returns a JMX service URL based on the settings in the descriptor. Some implementations may
* want to just return a pre-configured service URL, whilst others may want to resolve the URL
Expand All @@ -70,4 +74,8 @@ public interface IConnectionDescriptor {
* @return the JMX environment. Usually contains credentials and similar.
*/
Map<String, Object> getEnvironment();

default boolean requireSecureConnection() {
return "true".equals(getEnvironment().get(JMX_REMOTE_X_CHECK_STUB));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,26 @@
*/
public final class JMXConnectionDescriptor implements IConnectionDescriptor {

// JMX convention. See e.g.
// https://github.com/openjdk/jdk/blob/master/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java
private static final String JMX_REMOTE_X_CHECK_STUB = "jmx.remote.x.check.stub"; //$NON-NLS-1$

/**
* The JMX service URL.
*/
private final JMXServiceURL url;

private final ICredentials credentials;

private boolean requireSecureConnection;

/**
* Full constructor.
*/
public JMXConnectionDescriptor(JMXServiceURL url, ICredentials credentials) {
public JMXConnectionDescriptor(JMXServiceURL url, ICredentials credentials, boolean requireSecureConnection) {
this.url = url;
this.credentials = credentials;
this.requireSecureConnection = requireSecureConnection;
}

@Override
Expand Down Expand Up @@ -112,6 +119,9 @@ public Map<String, Object> getEnvironment() {
} catch (SecurityException e) {
throw new RuntimeException(e);
}
if (requireSecureConnection) {
env.put(JMX_REMOTE_X_CHECK_STUB, "true"); //$NON-NLS-1$
}
return env;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ public boolean connect() throws ConnectionException {
return true;
} catch (Exception e) {
m_server = null;
throw new WrappedConnectionException(m_serverDescriptor.getDisplayName(), url, e);
throw new WrappedConnectionException(m_serverDescriptor.getDisplayName(), url,
m_connectionDescriptor.requireSecureConnection(), e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,19 @@ public class WrappedConnectionException extends ConnectionException {

private final JMXServiceURL url;
private final String serverName;
private boolean requireSecureConnection;

public WrappedConnectionException(String serverName, JMXServiceURL url, Exception cause) {
super(cause.getMessage());
initCause(cause); // yes, still 1.4 compatible
this.url = url;
this.serverName = serverName;
}

public WrappedConnectionException(String serverName, JMXServiceURL url, boolean requireSecureConnection,
Exception cause) {
this(serverName, url, cause);
this.requireSecureConnection = requireSecureConnection;
}

@Override
Expand Down Expand Up @@ -89,6 +95,10 @@ public String getLocalizedMessage() {
return String.format(Messages.getString(Messages.ConnectionException_MSARMI_CHECK_PASSWORD), serverName,
url);
}
if (rootCause instanceof SecurityException && requireSecureConnection) {
return String.format(Messages.getString(Messages.ConnectionException_COULD_NOT_MAKE_SECURE_CONNECTION),
serverName, rootCause.getLocalizedMessage()); //$NON-NLS-1$
}
if (rootCause instanceof SecurityException || rootCause instanceof GeneralSecurityException) {
return String.format(Messages.getString(Messages.ConnectionException_UNABLE_TO_RESOLVE_CREDENTIALS),
serverName, rootCause.getLocalizedMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class Messages {
public static final String ConnectionException_UNABLE_TO_CREATE_INITIAL_CONTEXT = "ConnectionException_UNABLE_TO_CREATE_INITIAL_CONTEXT"; //$NON-NLS-1$
public static final String ConnectionException_UNABLE_TO_RESOLVE_CREDENTIALS = "ConnectionException_UNABLE_TO_RESOLVE_CREDENTIALS"; //$NON-NLS-1$
public static final String ConnectionException_UNRESOLVED = "ConnectionException_UNRESOLVED"; //$NON-NLS-1$
public static final String ConnectionException_COULD_NOT_MAKE_SECURE_CONNECTION = "ConnectionException_COULD_NOT_MAKE_SECURE_CONNECTION"; //$NON-NLS-1$
public static final String LABEL_NOT_AVAILABLE = "LABEL_NOT_AVAILABLE"; //$NON-NLS-1$
public static final String MBeanOperationsWrapper_DESCRIPTOR = "MBeanOperationsWrapper_DESCRIPTOR"; //$NON-NLS-1$

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ ConnectionException_UNABLE_TO_RESOLVE_CREDENTIALS=Unable to resolve the connecti
ConnectionException_MSARMI_CHECK_PASSWORD=Unable to connect with msarmi protocol for {0}, using Service URL {1}. Verify that you have entered the correct password.
ConnectionException_ATTACH_NOT_SUPPORTED=Attaching to the local JVM {0} is not supported: {1}
ConnectionException_UNRESOLVED=Unresolved
ConnectionException_COULD_NOT_MAKE_SECURE_CONNECTION=Unable to make secure connection to {0} , check that the connection is secure and credentials are correct. Problem was: {1}
LABEL_NOT_AVAILABLE=N/A
MBeanOperationsWrapper_DESCRIPTOR=Descriptor