Skip to content

Commit

Permalink
Merge pull request #136 from scottslewis/sslcontext
Browse files Browse the repository at this point in the history
SslcontextFactory introduced to ECF core and used in JRE httpclient
  • Loading branch information
scottslewis authored Dec 7, 2024
2 parents e355fb4 + 8e0e523 commit 50a9827
Show file tree
Hide file tree
Showing 16 changed files with 791 additions and 90 deletions.
2 changes: 1 addition & 1 deletion framework/bundles/org.eclipse.ecf/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-Name: %plugin.name
Bundle-SymbolicName: org.eclipse.ecf;singleton:=true
Automatic-Module-Name: org.eclipse.ecf
Bundle-Version: 3.11.0.qualifier
Bundle-Version: 3.12.0.qualifier
Bundle-Activator: org.eclipse.ecf.internal.core.ECFPlugin
Bundle-Vendor: %plugin.provider
Bundle-Localization: plugin
Expand Down
2 changes: 1 addition & 1 deletion framework/bundles/org.eclipse.ecf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
</parent>
<groupId>org.eclipse.ecf</groupId>
<artifactId>org.eclipse.ecf</artifactId>
<version>3.11.0-SNAPSHOT</version>
<version>3.12.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/****************************************************************************
* Copyright (c) 2024 Composent, Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors: Composent, Inc. - initial API and implementation
*
* SPDX-License-Identifier: EPL-2.0
*****************************************************************************/
package org.eclipse.ecf.core.security;

import java.security.*;
import java.util.Optional;
import javax.net.ssl.SSLContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.internal.core.identity.Activator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;

/**
* @since 3.12
*/
public class ECFSSLContextFactory implements SSLContextFactory {

private final ServiceTracker<Provider, Provider> providerTracker;
private final String defaultProtocol;
private final String defaultProviderName;

public ECFSSLContextFactory(BundleContext context, String defaultProtocol) {
this(context, defaultProtocol, null);
}

public ECFSSLContextFactory(BundleContext context, String defaultProtocol, String defaultProviderName) {
this.defaultProtocol = defaultProtocol;
this.defaultProviderName = defaultProviderName;
this.providerTracker = new ServiceTracker<Provider, Provider>(context, Provider.class, null);
this.providerTracker.open();
}

@Override
public SSLContext getDefault() throws NoSuchAlgorithmException, NoSuchProviderException {
return getInstance0(this.defaultProtocol, this.defaultProviderName);
}

protected SSLContext getInstance0(String protocol, String providerName) throws NoSuchAlgorithmException, NoSuchProviderException {
if (protocol == null) {
return SSLContext.getDefault();
}
Provider provider = findProvider(providerName);
if (provider == null)
throw new NoSuchProviderException("No provider registered named '" + providerName + "'"); //$NON-NLS-1$ //$NON-NLS-2$
return SSLContext.getInstance(protocol, provider);
}

@Override
public SSLContext getInstance(String protocol) throws NoSuchAlgorithmException, NoSuchProviderException {
return getInstance0(protocol, this.defaultProviderName);
}

public void close() {
this.providerTracker.close();
}

protected Provider findProvider(String providerName) {
if (providerName == null) {
return this.providerTracker.getService();
}
Optional<Provider> optResult = this.providerTracker.getTracked().values().stream().filter(p ->
// test that providerName is equal to Provider.getName()
providerName.equals(p.getName())).findFirst();
// If there are matching Providers, use first (highest priority from sorted map) and use to create SSLContext.
// If none, then throw
if (optResult.isPresent()) {
return optResult.get();
}
// If providerName is same as current default SSLContext then use it
try {
SSLContext defaultContext = SSLContext.getDefault();
if (providerName.equals(defaultContext.getProvider().getName())) {
return defaultContext.getProvider();
}
} catch (NoSuchAlgorithmException e) {
Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not get SSLContext.getDefault()", e)); //$NON-NLS-1$
}
return null;
}

@Override
public SSLContext getInstance(String protocol, String providerName) throws NoSuchAlgorithmException, NoSuchProviderException {
return getInstance0(protocol, providerName);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/****************************************************************************
* Copyright (c) 2024 Composent, Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors: Composent, Inc. - initial API and implementation
*
* SPDX-License-Identifier: EPL-2.0
*****************************************************************************/
package org.eclipse.ecf.core.security;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.net.ssl.SSLContext;

/**
* @since 3.12
*/
public interface SSLContextFactory {

SSLContext getDefault() throws NoSuchAlgorithmException, NoSuchProviderException;

SSLContext getInstance(String protocol) throws NoSuchAlgorithmException, NoSuchProviderException;

SSLContext getInstance(String protocol, String providerName) throws NoSuchAlgorithmException, NoSuchProviderException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
package org.eclipse.ecf.internal.core;

import java.util.*;
import javax.net.ssl.SSLContext;
import org.eclipse.core.runtime.*;
import org.eclipse.ecf.core.*;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.provider.IContainerInstantiator;
import org.eclipse.ecf.core.security.ECFSSLContextFactory;
import org.eclipse.ecf.core.security.SSLContextFactory;
import org.eclipse.ecf.core.start.ECFStartJob;
import org.eclipse.ecf.core.start.IECFStart;
import org.eclipse.ecf.core.util.*;
Expand Down Expand Up @@ -92,6 +95,10 @@ public class ECFPlugin implements BundleActivator {

private BundleActivator ecfTrustManager;

private ServiceRegistration sslContextFactoryRegistration;

private ECFSSLContextFactory ecfSSLContextFactory;

/**
* Returns the shared instance.
* @return ECFPlugin
Expand Down Expand Up @@ -221,6 +228,11 @@ public void ungetService(Bundle bundle, ServiceRegistration registration, Object
containerFactoryServiceRegistration = ctxt.registerService(IContainerFactory.class.getName(), sf, null);
containerManagerServiceRegistration = ctxt.registerService(IContainerManager.class.getName(), sf, null);

// Register SSLContextFactory
SSLContext defaultContext = SSLContext.getDefault();
ecfSSLContextFactory = new ECFSSLContextFactory(ctxt, defaultContext.getProtocol(), defaultContext.getProvider().getName());
sslContextFactoryRegistration = ctxt.registerService(SSLContextFactory.class, ecfSSLContextFactory, null);

SafeRunner.run(new ExtensionRegistryRunnable(this.context) {
protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
if (registry != null) {
Expand Down Expand Up @@ -317,6 +329,14 @@ protected void runWithRegistry(IExtensionRegistry registry) throws Exception {
containerManagerServiceRegistration.unregister();
containerManagerServiceRegistration = null;
}
if (sslContextFactoryRegistration != null) {
sslContextFactoryRegistration.unregister();
sslContextFactoryRegistration = null;
if (ecfSSLContextFactory != null) {
ecfSSLContextFactory.close();
ecfSSLContextFactory = null;
}
}
if (adapterManagerTracker != null) {
adapterManagerTracker.close();
adapterManagerTracker = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin.name
Bundle-SymbolicName: org.eclipse.ecf.provider.filetransfer.httpclientjava;singleton:=true
Bundle-Version: 2.0.300.qualifier
Bundle-Version: 2.0.0.qualifier
Bundle-Vendor: %plugin.provider
Bundle-Localization: plugin
Automatic-Module-Name: org.eclipse.ecf.provider.filetransfer.httpclientjava
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.eclipse.equinox.common;bundle-version="3.13.0",
org.eclipse.ecf;bundle-version="3.9.101",
org.eclipse.ecf;bundle-version="3.12.0",
org.eclipse.core.jobs;bundle-version="3.10.800"
Import-Package: javax.net.ssl,
org.eclipse.ecf.filetransfer;version="5.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<relativePath>../../../</relativePath>
</parent>
<artifactId>org.eclipse.ecf.provider.filetransfer.httpclientjava</artifactId>
<version>2.0.300-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLSocketFactory;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.security.SSLContextFactory;
import org.eclipse.ecf.core.util.ECFRuntimeException;
import org.eclipse.ecf.core.util.LogHelper;
import org.eclipse.ecf.core.util.Trace;
Expand Down Expand Up @@ -118,7 +117,7 @@ public void removedService(ServiceReference<HttpClient> reference, HttpClient se

private ServiceTracker<LogService, LogService> logServiceTracker = null;

private ServiceTracker<SSLSocketFactory, SSLSocketFactory> sslSocketFactoryTracker;
private ServiceTracker<SSLContextFactory, SSLContextFactory> sslContextFactoryTracker;

private ServiceTracker<INTLMProxyHandler, INTLMProxyHandler> ntlmProxyHandlerTracker;

Expand Down Expand Up @@ -181,8 +180,8 @@ private void applyDebugOptions(BundleContext ctxt) {

@Override
public synchronized void stop(BundleContext ctxt) throws Exception {
if (sslSocketFactoryTracker != null) {
sslSocketFactoryTracker.close();
if (sslContextFactoryTracker != null) {
sslContextFactoryTracker.close();
}

if (logServiceTracker != null) {
Expand Down Expand Up @@ -247,12 +246,15 @@ public void log(IStatus status) {
}
}

public synchronized SSLSocketFactory getSSLSocketFactory() {
if (sslSocketFactoryTracker == null) {
sslSocketFactoryTracker = new ServiceTracker<SSLSocketFactory, SSLSocketFactory>(this.context, SSLSocketFactory.class, null);
sslSocketFactoryTracker.open();
/**
* @since 2.0
*/
public synchronized SSLContextFactory getSSLContextFactory() {
if (sslContextFactoryTracker == null) {
sslContextFactoryTracker = new ServiceTracker<SSLContextFactory, SSLContextFactory>(this.context, SSLContextFactory.class, null);
sslContextFactoryTracker.open();
}
SSLSocketFactory service = sslSocketFactoryTracker.getService();
SSLContextFactory service = sslContextFactoryTracker.getService();
return service;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
import java.net.http.HttpClient;
import java.net.http.HttpClient.Redirect;
import java.net.http.HttpRequest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.internal.provider.filetransfer.DebugOptions;
import org.eclipse.ecf.provider.filetransfer.httpclientjava.HttpClientOptions;
Expand All @@ -48,6 +52,11 @@ public class ECFHttpClientFactory implements IHttpClientFactory {
public HttpClient.Builder newClient() {

HttpClient.Builder builder = HttpClient.newBuilder().followRedirects(Redirect.NORMAL);
try {
builder.sslContext(Activator.getDefault().getSSLContextFactory().getDefault());
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
Activator.getDefault().log(new Status(IStatus.ERROR,Activator.PLUGIN_ID,"Could not set SSLContext when creating jre HttpClient", e));
}
builder = Activator.getDefault().runModifiers(builder, new ModifierRunner<HttpClient.Builder>() {
@Override
public HttpClient.Builder run(IHttpClientModifier modifier, HttpClient.Builder value) {
Expand Down
4 changes: 2 additions & 2 deletions releng/features/org.eclipse.ecf.xmpp.feature/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<feature
id="org.eclipse.ecf.xmpp.feature"
label="ECF XMPP Provider"
version="1.0.500.qualifier"
version="1.0.600.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
Expand Down Expand Up @@ -45,6 +45,6 @@ https://wiki.eclipse.org/ECF#OSGi_Remote_Services

<plugin
id="org.xbill.dns"
version="3.6.1"/>
version="0.0.0"/>

</feature>
2 changes: 1 addition & 1 deletion releng/features/org.eclipse.ecf.xmpp.feature/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
<relativePath>../../../</relativePath>
</parent>
<artifactId>org.eclipse.ecf.xmpp.feature</artifactId>
<version>1.0.500-SNAPSHOT</version>
<version>1.0.600-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
</project>
13 changes: 11 additions & 2 deletions releng/org.eclipse.ecf.releng.target/ecf-2024-06.target
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,22 @@
<unit id="org.osgi.util.xml" version="0.0.0"/>
<unit id="org.sat4j.pb" version="0.0.0"/>
<unit id="org.tukaani.xz" version="0.0.0"/>
<unit id="org.xbill.dns" version="0.0.0"/>
<repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/milestone/latest"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.equinox.core.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
<repository location="https://download.eclipse.org/eclipse/updates/4.32/R-4.32-202406010610"/>
</location>
<location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="generate" type="Maven">
<dependencies>
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>3.6.2</version>
<type>jar</type>
</dependency>
</dependencies>
</location>
</locations>
</target>
</target>
Loading

0 comments on commit 50a9827

Please sign in to comment.