use of org.eclipse.leshan.server.californium.impl.LeshanServer in project leshan by eclipse.
the class LeshanServerDemo method createAndStartServer.
public static void createAndStartServer(int webPort, String localAddress, int localPort, String secureLocalAddress, int secureLocalPort, String modelsFolderPath, String redisUrl, String keyStorePath, String keyStoreType, String keyStorePass, String keyStoreAlias, String keyStoreAliasPass, Boolean publishDNSSdServices) throws Exception {
// Prepare LWM2M server
LeshanServerBuilder builder = new LeshanServerBuilder();
builder.setLocalAddress(localAddress, localPort);
builder.setLocalSecureAddress(secureLocalAddress, secureLocalPort);
builder.setEncoder(new DefaultLwM2mNodeEncoder());
LwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder();
builder.setDecoder(decoder);
// Create CoAP Config
NetworkConfig coapConfig;
File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME);
if (configFile.isFile()) {
coapConfig = new NetworkConfig();
coapConfig.load(configFile);
} else {
coapConfig = LeshanServerBuilder.createDefaultNetworkConfig();
coapConfig.store(configFile);
}
builder.setCoapConfig(coapConfig);
// connect to redis if needed
Pool<Jedis> jedis = null;
if (redisUrl != null) {
// TODO: support sentinel pool and make pool configurable
jedis = new JedisPool(new URI(redisUrl));
}
PublicKey publicKey = null;
// Set up X.509 mode
if (keyStorePath != null) {
try {
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
try (FileInputStream fis = new FileInputStream(keyStorePath)) {
keyStore.load(fis, keyStorePass == null ? null : keyStorePass.toCharArray());
List<Certificate> trustedCertificates = new ArrayList<>();
for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements(); ) {
String alias = aliases.nextElement();
if (keyStore.isCertificateEntry(alias)) {
trustedCertificates.add(keyStore.getCertificate(alias));
} else if (keyStore.isKeyEntry(alias) && alias.equals(keyStoreAlias)) {
List<X509Certificate> x509CertificateChain = new ArrayList<>();
Certificate[] certificateChain = keyStore.getCertificateChain(alias);
if (certificateChain == null || certificateChain.length == 0) {
LOG.error("Keystore alias must have a non-empty chain of X509Certificates.");
System.exit(-1);
}
for (Certificate certificate : certificateChain) {
if (!(certificate instanceof X509Certificate)) {
LOG.error("Non-X.509 certificate in alias chain is not supported: {}", certificate);
System.exit(-1);
}
x509CertificateChain.add((X509Certificate) certificate);
}
Key key = keyStore.getKey(alias, keyStoreAliasPass == null ? new char[0] : keyStoreAliasPass.toCharArray());
if (!(key instanceof PrivateKey)) {
LOG.error("Keystore alias must have a PrivateKey entry, was {}", key == null ? null : key.getClass().getName());
System.exit(-1);
}
builder.setPrivateKey((PrivateKey) key);
publicKey = keyStore.getCertificate(alias).getPublicKey();
builder.setCertificateChain(x509CertificateChain.toArray(new X509Certificate[x509CertificateChain.size()]));
}
}
builder.setTrustedCertificates(trustedCertificates.toArray(new Certificate[trustedCertificates.size()]));
}
} catch (KeyStoreException | IOException e) {
LOG.error("Unable to initialize X.509.", e);
System.exit(-1);
}
} else // Otherwise, set up RPK mode
{
try {
// Get point values
byte[] publicX = Hex.decodeHex("fcc28728c123b155be410fc1c0651da374fc6ebe7f96606e90d927d188894a73".toCharArray());
byte[] publicY = Hex.decodeHex("d2ffaa73957d76984633fc1cc54d0b763ca0559a9dff9706e9f4557dacc3f52a".toCharArray());
byte[] privateS = Hex.decodeHex("1dae121ba406802ef07c193c1ee4df91115aabd79c1ed7f4c0ef7ef6a5449400".toCharArray());
// Get Elliptic Curve Parameter spec for secp256r1
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
// Create key specs
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), parameterSpec);
KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec);
// Get keys
publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
PrivateKey privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
builder.setPublicKey(publicKey);
builder.setPrivateKey(privateKey);
} catch (InvalidKeySpecException | NoSuchAlgorithmException | InvalidParameterSpecException e) {
LOG.error("Unable to initialize RPK.", e);
System.exit(-1);
}
}
// Define model provider
List<ObjectModel> models = ObjectLoader.loadDefault();
models.addAll(ObjectLoader.loadDdfResources("/models/", modelPaths));
if (modelsFolderPath != null) {
models.addAll(ObjectLoader.loadObjectsFromDir(new File(modelsFolderPath)));
}
LwM2mModelProvider modelProvider = new StaticModelProvider(models);
builder.setObjectModelProvider(modelProvider);
// Set securityStore & registrationStore
EditableSecurityStore securityStore;
if (jedis == null) {
// use file persistence
securityStore = new FileSecurityStore();
} else {
// use Redis Store
securityStore = new RedisSecurityStore(jedis);
builder.setRegistrationStore(new RedisRegistrationStore(jedis));
}
builder.setSecurityStore(securityStore);
// Create and start LWM2M server
LeshanServer lwServer = builder.build();
// Now prepare Jetty
Server server = new Server(webPort);
WebAppContext root = new WebAppContext();
root.setContextPath("/");
root.setResourceBase(LeshanServerDemo.class.getClassLoader().getResource("webapp").toExternalForm());
root.setParentLoaderPriority(true);
server.setHandler(root);
// Create Servlet
EventServlet eventServlet = new EventServlet(lwServer, lwServer.getSecuredAddress().getPort());
ServletHolder eventServletHolder = new ServletHolder(eventServlet);
root.addServlet(eventServletHolder, "/event/*");
ServletHolder clientServletHolder = new ServletHolder(new ClientServlet(lwServer, lwServer.getSecuredAddress().getPort()));
root.addServlet(clientServletHolder, "/api/clients/*");
ServletHolder securityServletHolder = new ServletHolder(new SecurityServlet(securityStore, publicKey));
root.addServlet(securityServletHolder, "/api/security/*");
ServletHolder objectSpecServletHolder = new ServletHolder(new ObjectSpecServlet(lwServer.getModelProvider()));
root.addServlet(objectSpecServletHolder, "/api/objectspecs/*");
// Register a service to DNS-SD
if (publishDNSSdServices) {
// Create a JmDNS instance
JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost());
// Publish Leshan HTTP Service
ServiceInfo httpServiceInfo = ServiceInfo.create("_http._tcp.local.", "leshan", webPort, "");
jmdns.registerService(httpServiceInfo);
// Publish Leshan CoAP Service
ServiceInfo coapServiceInfo = ServiceInfo.create("_coap._udp.local.", "leshan", localPort, "");
jmdns.registerService(coapServiceInfo);
// Publish Leshan Secure CoAP Service
ServiceInfo coapSecureServiceInfo = ServiceInfo.create("_coaps._udp.local.", "leshan", secureLocalPort, "");
jmdns.registerService(coapSecureServiceInfo);
}
// Start Jetty & Leshan
lwServer.start();
server.start();
LOG.info("Web server started at {}.", server.getURI());
}
use of org.eclipse.leshan.server.californium.impl.LeshanServer in project leshan by eclipse.
the class LeshanClusterServer method createAndStartServer.
public static void createAndStartServer(String clusterInstanceId, String localAddress, int localPort, String secureLocalAddress, int secureLocalPort, String modelsFolderPath, String redisUrl) throws Exception {
// Create Redis connector.
// TODO: support sentinel pool and make pool configurable
Pool<Jedis> jedis = new JedisPool(new URI(redisUrl));
// Prepare LWM2M server.
LeshanServerBuilder builder = new LeshanServerBuilder();
builder.setLocalAddress(localAddress, localPort);
builder.setLocalSecureAddress(secureLocalAddress, secureLocalPort);
DefaultLwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder();
builder.setDecoder(decoder);
builder.setCoapConfig(NetworkConfig.getStandard());
List<ObjectModel> models = ObjectLoader.loadDefault();
if (modelsFolderPath != null) {
models.addAll(ObjectLoader.loadObjectsFromDir(new File(modelsFolderPath)));
}
LwM2mModelProvider modelProvider = new StaticModelProvider(models);
builder.setObjectModelProvider(modelProvider);
RedisRegistrationStore registrationStore = new RedisRegistrationStore(jedis);
builder.setRegistrationStore(registrationStore);
// TODO add support of public and private server key
builder.setSecurityStore(new RedisSecurityStore(jedis));
// Create and start LWM2M server
LeshanServer lwServer = builder.build();
// Create Clustering support
RedisTokenHandler tokenHandler = new RedisTokenHandler(jedis, clusterInstanceId);
new RedisRequestResponseHandler(jedis, lwServer, lwServer.getRegistrationService(), tokenHandler, lwServer.getObservationService());
lwServer.getRegistrationService().addListener(tokenHandler);
lwServer.getRegistrationService().addListener(new RedisRegistrationEventPublisher(jedis));
// Start Jetty & Leshan
lwServer.start();
}
use of org.eclipse.leshan.server.californium.impl.LeshanServer in project leshan by eclipse.
the class LeshanServerBuilder method build.
public LeshanServer build() {
if (localAddress == null)
localAddress = new InetSocketAddress(LwM2m.DEFAULT_COAP_PORT);
if (registrationStore == null)
registrationStore = new InMemoryRegistrationStore();
if (authorizer == null)
authorizer = new DefaultAuthorizer(securityStore);
if (modelProvider == null)
modelProvider = new StandardModelProvider();
if (encoder == null)
encoder = new DefaultLwM2mNodeEncoder();
if (decoder == null)
decoder = new DefaultLwM2mNodeDecoder();
if (coapConfig == null)
coapConfig = createDefaultNetworkConfig();
if (awakeTimeProvider == null)
awakeTimeProvider = new StaticClientAwakeTimeProvider();
// handle dtlsConfig
DtlsConnectorConfig dtlsConfig = null;
if (!noSecuredEndpoint) {
if (dtlsConfigBuilder == null) {
dtlsConfigBuilder = new DtlsConnectorConfig.Builder();
}
// set default DTLS setting for Leshan unless user change it.
DtlsConnectorConfig incompleteConfig = dtlsConfigBuilder.getIncompleteConfig();
// Handle PSK Store
if (incompleteConfig.getPskStore() == null && securityStore != null) {
dtlsConfigBuilder.setPskStore(new LwM2mPskStore(this.securityStore, registrationStore));
} else {
LOG.warn("PskStore should be automatically set by Leshan. Using a custom implementation is not advised.");
}
// Handle secure address
if (incompleteConfig.getAddress() == null) {
if (localSecureAddress == null) {
localSecureAddress = new InetSocketAddress(LwM2m.DEFAULT_COAP_SECURE_PORT);
}
dtlsConfigBuilder.setAddress(localSecureAddress);
} else if (localSecureAddress != null && !localSecureAddress.equals(incompleteConfig.getAddress())) {
throw new IllegalStateException(String.format("Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for secure address: %s != %s", localSecureAddress, incompleteConfig.getAddress()));
}
// Handle active peers
if (incompleteConfig.getMaxConnections() == null)
dtlsConfigBuilder.setMaxConnections(coapConfig.getInt(Keys.MAX_ACTIVE_PEERS));
if (incompleteConfig.getStaleConnectionThreshold() == null)
dtlsConfigBuilder.setStaleConnectionThreshold(coapConfig.getLong(Keys.MAX_PEER_INACTIVITY_PERIOD));
// handle trusted certificates
if (trustedCertificates != null) {
if (incompleteConfig.getTrustStore() == null) {
dtlsConfigBuilder.setTrustStore(trustedCertificates);
} else if (!Arrays.equals(trustedCertificates, incompleteConfig.getTrustStore())) {
throw new IllegalStateException(String.format("Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for trusted Certificates (trustStore) : \n%s != \n%s", Arrays.toString(trustedCertificates), Arrays.toString(incompleteConfig.getTrustStore())));
}
}
// check conflict for private key
if (privateKey != null) {
if (incompleteConfig.getPrivateKey() != null && !incompleteConfig.getPrivateKey().equals(privateKey)) {
throw new IllegalStateException(String.format("Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for private key: %s != %s", privateKey, incompleteConfig.getPrivateKey()));
}
// if in raw key mode and not in X.509 set the raw keys
if (certificateChain == null && publicKey != null) {
if (incompleteConfig.getPublicKey() != null && !incompleteConfig.getPublicKey().equals(publicKey)) {
throw new IllegalStateException(String.format("Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for public key: %s != %s", publicKey, incompleteConfig.getPublicKey()));
}
dtlsConfigBuilder.setIdentity(privateKey, publicKey);
}
// if in X.509 mode set the private key, certificate chain, public key is extracted from the certificate
if (certificateChain != null && certificateChain.length > 0) {
if (incompleteConfig.getCertificateChain() != null && !Arrays.equals(incompleteConfig.getCertificateChain(), certificateChain)) {
throw new IllegalStateException(String.format("Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for certificate chain: %s != %s", Arrays.toString(certificateChain), Arrays.toString(incompleteConfig.getCertificateChain())));
}
dtlsConfigBuilder.setIdentity(privateKey, certificateChain, false);
}
}
// we try to build the dtlsConfig, if it fail we will just not create the secured endpoint
try {
dtlsConfig = dtlsConfigBuilder.build();
} catch (IllegalStateException e) {
}
}
// create endpoints
CoapEndpoint unsecuredEndpoint = null;
if (!noUnsecuredEndpoint) {
if (endpointFactory != null) {
unsecuredEndpoint = endpointFactory.createUnsecuredEndpoint(localAddress, coapConfig, registrationStore);
} else {
CoapEndpoint.CoapEndpointBuilder builder = new CoapEndpoint.CoapEndpointBuilder();
builder.setInetSocketAddress(localAddress);
builder.setNetworkConfig(coapConfig);
builder.setObservationStore(registrationStore);
unsecuredEndpoint = builder.build();
}
}
CoapEndpoint securedEndpoint = null;
if (!noSecuredEndpoint && dtlsConfig != null) {
if (endpointFactory != null) {
securedEndpoint = endpointFactory.createSecuredEndpoint(dtlsConfig, coapConfig, registrationStore);
} else {
CoapEndpoint.CoapEndpointBuilder builder = new CoapEndpoint.CoapEndpointBuilder();
builder.setConnector(new DTLSConnector(dtlsConfig));
builder.setNetworkConfig(coapConfig);
builder.setObservationStore(registrationStore);
builder.setEndpointContextMatcher(new Lwm2mEndpointContextMatcher());
securedEndpoint = builder.build();
}
}
if (securedEndpoint == null && unsecuredEndpoint == null) {
throw new IllegalStateException("All CoAP enpoints are deactivated, at least one endpoint should be activated");
}
return new LeshanServer(unsecuredEndpoint, securedEndpoint, registrationStore, securityStore, authorizer, modelProvider, encoder, decoder, coapConfig, noQueueMode, awakeTimeProvider);
}
Aggregations