Skip to content

Commit

Permalink
Add Transport Layer abstraction at Bootstrap server side.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Jan 6, 2023
1 parent 9859a33 commit 6091fc3
Show file tree
Hide file tree
Showing 43 changed files with 3,081 additions and 1,080 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,37 @@
import java.io.File;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.cert.Certificate;
import java.util.List;

import org.eclipse.californium.core.config.CoapConfig;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.scandium.config.DtlsConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.leshan.core.californium.PrincipalMdcConnectionListener;
import org.eclipse.leshan.core.demo.cli.ShortErrorMessageHandler;
import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.model.ObjectLoader;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.bootstrap.LeshanBootstrapServerBuilder;
import org.eclipse.leshan.server.bootstrap.demo.cli.LeshanBsServerDemoCLI;
import org.eclipse.leshan.server.bootstrap.demo.servlet.BootstrapServlet;
import org.eclipse.leshan.server.bootstrap.demo.servlet.EventServlet;
import org.eclipse.leshan.server.bootstrap.demo.servlet.ServerServlet;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.BootstrapServerProtocolProvider;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.CaliforniumBootstrapServerEndpointFactory;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.CaliforniumBootstrapServerEndpointsProvider;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.coap.CoapBootstrapServerProtocolProvider;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.coap.CoapOscoreBootstrapServerEndpointFactory;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.coaps.CoapsBootstrapServerEndpointFactory;
import org.eclipse.leshan.server.californium.bootstrap.endpoint.coaps.CoapsBootstrapServerProtocolProvider;
import org.eclipse.leshan.server.core.demo.json.servlet.SecurityServlet;
import org.eclipse.leshan.server.model.VersionedBootstrapModelProvider;
import org.eclipse.leshan.server.security.BootstrapSecurityStoreAdapter;
Expand Down Expand Up @@ -113,37 +123,15 @@ public static LeshanBootstrapServer createBsLeshanServer(LeshanBsServerDemoCLI c
// Prepare LWM2M server
LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder();

// Create CoAP Config
File configFile = new File(CF_CONFIGURATION_FILENAME);
Configuration coapConfig = LeshanBootstrapServerBuilder.createDefaultCoapConfiguration();
// these configuration values are always overwritten by CLI
// therefore set them to transient.
coapConfig.setTransient(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
coapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
if (configFile.isFile()) {
coapConfig.load(configFile);
} else {
coapConfig.store(configFile, CF_CONFIGURATION_HEADER);
}
builder.setCoapConfig(coapConfig);

// ports from CoAP Config if needed
builder.setLocalAddress(cli.main.localAddress,
cli.main.localPort == null ? coapConfig.get(CoapConfig.COAP_PORT) : cli.main.localPort);
builder.setLocalSecureAddress(cli.main.secureLocalAddress,
cli.main.secureLocalPort == null ? coapConfig.get(CoapConfig.COAP_SECURE_PORT)
: cli.main.secureLocalPort);

// Create DTLS Config
DtlsConnectorConfig.Builder dtlsConfig = DtlsConnectorConfig.builder(coapConfig);
dtlsConfig.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, !cli.dtls.supportDeprecatedCiphers);
if (cli.dtls.cid != null) {
dtlsConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, cli.dtls.cid);
}
// Add MDC for connection logs
if (cli.helpsOptions.getVerboseLevel() > 0) {
dtlsConfig.setConnectionListener(new PrincipalMdcConnectionListener());
// Create Models
List<ObjectModel> models = ObjectLoader.loadDefault();
if (cli.main.modelsFolder != null) {
models.addAll(ObjectLoader.loadObjectsFromDir(cli.main.modelsFolder, true));
}
builder.setObjectModelProvider(new VersionedBootstrapModelProvider(models));

builder.setConfigStore(bsConfigStore);
builder.setSecurityStore(new BootstrapSecurityStoreAdapter(securityStore));

if (cli.identity.isx509()) {
// use X.509 mode (+ RPK)
Expand All @@ -159,24 +147,75 @@ public static LeshanBootstrapServer createBsLeshanServer(LeshanBsServerDemoCLI c
builder.setPrivateKey(cli.identity.getPrivateKey());
}

// Set DTLS Config
builder.setDtlsConfig(dtlsConfig);
// Create Californium Endpoints Provider:
// ------------------
// Create Custom CoAPS protocol provider to add MDC logger :
BootstrapServerProtocolProvider coapsProtocolProvider = new CoapsBootstrapServerProtocolProvider() {
@Override
public CaliforniumBootstrapServerEndpointFactory createDefaultEndpointFactory(URI uri) {
return new CoapsBootstrapServerEndpointFactory(uri) {

@Override
protected Builder createDtlsConnectorConfigBuilder(Configuration configuration) {
Builder dtlsConfigBuilder = super.createDtlsConnectorConfigBuilder(configuration);

// Add MDC for connection logs
if (cli.helpsOptions.getVerboseLevel() > 0)
dtlsConfigBuilder.setConnectionListener(new PrincipalMdcConnectionListener());

return dtlsConfigBuilder;
}
};
}
};

// Create Bootstrap Server Endpoints Provider
CaliforniumBootstrapServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder(
new CoapBootstrapServerProtocolProvider(), coapsProtocolProvider);

// Create Californium Configuration
Configuration serverCoapConfig = endpointsBuilder.createDefaultConfiguration();

// Set some DTLS stuff
// These configuration values are always overwritten by CLI therefore set them to transient.
serverCoapConfig.setTransient(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
serverCoapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
serverCoapConfig.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, !cli.dtls.supportDeprecatedCiphers);
if (cli.dtls.cid != null) {
serverCoapConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, cli.dtls.cid);
}

// Create Models
List<ObjectModel> models = ObjectLoader.loadDefault();
if (cli.main.modelsFolder != null) {
models.addAll(ObjectLoader.loadObjectsFromDir(cli.main.modelsFolder, true));
// Persist configuration
File configFile = new File(CF_CONFIGURATION_FILENAME);
if (configFile.isFile()) {
serverCoapConfig.load(configFile);
} else {
serverCoapConfig.store(configFile, CF_CONFIGURATION_HEADER);
}
builder.setObjectModelProvider(new VersionedBootstrapModelProvider(models));

builder.setConfigStore(bsConfigStore);
builder.setSecurityStore(new BootstrapSecurityStoreAdapter(securityStore));
// Set Californium Configuration
endpointsBuilder.setConfiguration(serverCoapConfig);

// TODO OSCORE Temporary cli option to deactivate OSCORE
if (!cli.main.disableOscore) {
builder.setEnableOscore(true);
// Create CoAP endpoint
int coapPort = cli.main.localPort == null ? serverCoapConfig.get(CoapConfig.COAP_PORT) : cli.main.localPort;
InetSocketAddress coapAddr = cli.main.localAddress == null ? new InetSocketAddress(coapPort)
: new InetSocketAddress(cli.main.localAddress, coapPort);
if (cli.main.disableOscore) {
endpointsBuilder.addEndpoint(coapAddr, Protocol.COAP);
} else {
endpointsBuilder.addEndpoint(new CoapOscoreBootstrapServerEndpointFactory(
EndpointUriUtil.createUri(Protocol.COAP.getUriScheme(), coapAddr)));
}

// Create CoAP over DTLS endpoint
int coapsPort = cli.main.secureLocalPort == null ? serverCoapConfig.get(CoapConfig.COAP_SECURE_PORT)
: cli.main.secureLocalPort;
InetSocketAddress coapsAddr = cli.main.secureLocalAddress == null ? new InetSocketAddress(coapsPort)
: new InetSocketAddress(cli.main.secureLocalAddress, coapsPort);
endpointsBuilder.addEndpoint(coapsAddr, Protocol.COAPS);

// Create LWM2M server
builder.setEndpointsProvider(endpointsBuilder.build());
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import org.eclipse.leshan.server.bootstrap.BootstrapFailureCause;
import org.eclipse.leshan.server.bootstrap.BootstrapSession;
import org.eclipse.leshan.server.bootstrap.BootstrapSessionListener;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.bootstrap.LeshanBootstrapServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.server.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.bootstrap.endpoint.LwM2mBootstrapServerEndpoint;
import org.eclipse.leshan.server.core.demo.json.PublicKeySerDes;
import org.eclipse.leshan.server.core.demo.json.X509CertificateSerDes;

Expand Down Expand Up @@ -83,14 +85,23 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
return;
}

// search coap and coaps port
Integer coapPort = null;
Integer coapsPort = null;
for (LwM2mBootstrapServerEndpoint endpoint : server.getEndpoints()) {
if (endpoint.getProtocol().equals(Protocol.COAP)) {
coapPort = endpoint.getURI().getPort();
} else if (endpoint.getProtocol().equals(Protocol.COAPS)) {
coapsPort = endpoint.getURI().getPort();
}
}

if ("endpoint".equals(path[0])) {
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("application/json");
resp.getOutputStream()
.write(String
.format("{ \"securedEndpointPort\":\"%s\", \"unsecuredEndpointPort\":\"%s\"}",
server.getSecuredAddress().getPort(), server.getUnsecuredAddress().getPort())
.getBytes(StandardCharsets.UTF_8));
resp.getOutputStream().write(String
.format("{ \"securedEndpointPort\":\"%s\", \"unsecuredEndpointPort\":\"%s\"}", coapsPort, coapPort)
.getBytes(StandardCharsets.UTF_8));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ public void bootstrapWithDiscoverOnRoot() {
assertEquals(ResponseCode.CONTENT, lastDiscoverAnswer.getCode());
assertEquals(String.format(
"</>;lwm2m=1.0,</0>;ver=1.1,</0/0>;uri=\"coap://%s:%d\",</1>;ver=1.1,</3>;ver=1.1,</3/0>,</21>;ver=2.0",
helper.bootstrapServer.getUnsecuredAddress().getHostString(),
helper.bootstrapServer.getUnsecuredAddress().getPort()),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getHost(),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getPort()),
linkSerializer.serializeCoreLinkFormat(lastDiscoverAnswer.getObjectLinks()));
}

Expand Down Expand Up @@ -269,8 +269,8 @@ public void bootstrapWithDiscoverOnRootThenRebootstrap() throws InvalidRequestEx
assertEquals(ResponseCode.CONTENT, lastDiscoverAnswer.getCode());
assertEquals(String.format(
"</>;lwm2m=1.0,</0>;ver=1.1,</0/0>;uri=\"coap://%s:%d\",</1>;ver=1.1,</3>;ver=1.1,</3/0>,</21>;ver=2.0",
helper.bootstrapServer.getUnsecuredAddress().getHostString(),
helper.bootstrapServer.getUnsecuredAddress().getPort()),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getHost(),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getPort()),
linkSerializer.serializeCoreLinkFormat(lastDiscoverAnswer.getObjectLinks()));

// re-bootstrap
Expand All @@ -292,8 +292,8 @@ public void bootstrapWithDiscoverOnRootThenRebootstrap() throws InvalidRequestEx
assertEquals(ResponseCode.CONTENT, lastDiscoverAnswer.getCode());
assertEquals(String.format(
"</>;lwm2m=1.0,</0>;ver=1.1,</0/0>;uri=\"coap://%s:%d\",</0/1>;ssid=2222;uri=\"coap://%s:%d\",</1>;ver=1.1,</1/0>;ssid=2222,</3>;ver=1.1,</3/0>,</21>;ver=2.0",
helper.bootstrapServer.getUnsecuredAddress().getHostString(),
helper.bootstrapServer.getUnsecuredAddress().getPort(),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getHost(),
helper.bootstrapServer.getEndpoint(Protocol.COAP).getURI().getPort(),
helper.server.getEndpoint(Protocol.COAP).getURI().getHost(),
helper.server.getEndpoint(Protocol.COAP).getURI().getPort()),
linkSerializer.serializeCoreLinkFormat(lastDiscoverAnswer.getObjectLinks()));
Expand Down
Loading

0 comments on commit 6091fc3

Please sign in to comment.