From 4117d9c558cc3573972ba7e81b791d58c5c965c2 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 26 Nov 2021 23:08:32 +0200 Subject: [PATCH] lwm2m - includes bootstrap update --- .../store/LwM2MConfigurationChecker.java | 83 +++++++++++++++++++ .../LwM2MInMemoryBootstrapConfigStore.java | 24 +++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MConfigurationChecker.java diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MConfigurationChecker.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MConfigurationChecker.java new file mode 100644 index 0000000000..d27ec707c2 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MConfigurationChecker.java @@ -0,0 +1,83 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.bootstrap.store; + +import org.eclipse.leshan.server.bootstrap.BootstrapConfig; +import org.eclipse.leshan.server.bootstrap.ConfigurationChecker; +import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException; +import java.util.Map; + +public class LwM2MConfigurationChecker extends ConfigurationChecker { + + @Override + public void verify(BootstrapConfig config) throws InvalidConfigurationException { + // check security configurations + for (Map.Entry e : config.security.entrySet()) { + BootstrapConfig.ServerSecurity sec = e.getValue(); + + // checks security config + switch (sec.securityMode) { + case NO_SEC: + checkNoSec(sec); + break; + case PSK: + checkPSK(sec); + break; + case RPK: + checkRPK(sec); + break; + case X509: + checkX509(sec); + break; + case EST: + throw new InvalidConfigurationException("EST is not currently supported.", e); + } + + validateMandatoryField(sec); + } + + // does each server have a corresponding security entry? + validateOneSecurityByServer(config); + } + + protected void validateOneSecurityByServer(BootstrapConfig config) throws InvalidConfigurationException { + for (Map.Entry e : config.servers.entrySet()) { + BootstrapConfig.ServerConfig srvCfg = e.getValue(); + + // shortId checks + if (srvCfg.shortId == 0) { + throw new InvalidConfigurationException("short ID must not be 0"); + } + + // look for security entry + BootstrapConfig.ServerSecurity security = getSecurityEntry(config, srvCfg.shortId); + + if (security == null) { + throw new InvalidConfigurationException("no security entry for server instance: " + e.getKey()); + } + } + } + + protected static BootstrapConfig.ServerSecurity getSecurityEntry(BootstrapConfig config, int shortId) { + for (Map.Entry es : config.security.entrySet()) { + if (es.getValue().serverId == shortId) { + return es.getValue(); + } + } + return null; + } + +} \ No newline at end of file diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MInMemoryBootstrapConfigStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MInMemoryBootstrapConfigStore.java index 2fa470a58e..485a8946f7 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MInMemoryBootstrapConfigStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MInMemoryBootstrapConfigStore.java @@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.bootstrap.BootstrapConfig; import org.eclipse.leshan.server.bootstrap.BootstrapSession; +import org.eclipse.leshan.server.bootstrap.ConfigurationChecker; import org.eclipse.leshan.server.bootstrap.InMemoryBootstrapConfigStore; import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -36,6 +37,7 @@ public class LwM2MInMemoryBootstrapConfigStore extends InMemoryBootstrapConfigSt private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final Lock readLock = readWriteLock.readLock(); private final Lock writeLock = readWriteLock.writeLock(); + protected final ConfigurationChecker configChecker = new LwM2MConfigurationChecker(); @Override public BootstrapConfig get(String endpoint, Identity deviceIdentity, BootstrapSession session) { @@ -73,6 +75,26 @@ public class LwM2MInMemoryBootstrapConfigStore extends InMemoryBootstrapConfigSt } public void addToStore(String endpoint, BootstrapConfig config) throws InvalidConfigurationException { - super.add(endpoint, config); + + configChecker.verify(config); + // Check PSK identity uniqueness for bootstrap server: + PskByServer pskToAdd = getBootstrapPskIdentity(config); + if (pskToAdd != null) { + BootstrapConfig existingConfig = bootstrapByPskId.get(pskToAdd); + if (existingConfig != null) { + // check if this config will be replace by the new one. + BootstrapConfig previousConfig = bootstrapByEndpoint.get(endpoint); + if (previousConfig != existingConfig) { + throw new InvalidConfigurationException( + "Psk identity [%s] already used for this bootstrap server [%s]", pskToAdd.identity, + pskToAdd.serverUrl); + } + } + } + + bootstrapByEndpoint.put(endpoint, config); + if (pskToAdd != null) { + bootstrapByPskId.put(pskToAdd, config); + } } }