lwm2m - upDate lwm2mServer

This commit is contained in:
nickAS21 2021-11-11 15:09:34 +02:00
parent 0344b61ed3
commit 781ef66f0b
12 changed files with 175 additions and 140 deletions

View File

@ -17,17 +17,19 @@ package org.thingsboard.server.common.data.device.profile;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServersConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration;
import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration;
import java.util.List;
@Data @Data
public class Lwm2mDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration { public class Lwm2mDeviceProfileTransportConfiguration implements DeviceProfileTransportConfiguration {
private static final long serialVersionUID = 6257277825459600068L; private static final long serialVersionUID = 6257277825459600068L;
private TelemetryMappingConfiguration observeAttr; private TelemetryMappingConfiguration observeAttr;
private LwM2MBootstrapServersConfiguration bootstrap; private List<LwM2MBootstrapServerCredential> bootstrap;
private OtherConfiguration clientLwM2mSettings; private OtherConfiguration clientLwM2mSettings;
@Override @Override

View File

@ -22,6 +22,6 @@ import java.util.List;
@Data @Data
public class LwM2MBootstrapServersConfiguration { public class LwM2MBootstrapServersConfiguration {
List<LwM2MBootstrapServerCredential> serverConfiguration; List<LwM2MBootstrapServerCredential> bootstrap;
} }

View File

@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.elements.util.SslContextUtil;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig; import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager; import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer; import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
@ -26,8 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.config.ssl.SslCredentials; import org.thingsboard.server.common.transport.config.ssl.SslCredentials;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore; import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MBootstrapSecurityStore;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore; import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MInMemoryBootstrapConfigStore;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager; import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
@ -35,10 +34,6 @@ import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2mTransportServic
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig; import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig;

View File

@ -16,23 +16,27 @@
package org.thingsboard.server.transport.lwm2m.bootstrap.secure; package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.request.BindingMode; import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.util.Hex; import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig; import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.thingsboard.server.common.data.device.credentials.lwm2m.AbstractLwM2MBootstrapClientCredentialWithKeys;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredential;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
import java.io.Serializable; import java.io.Serializable;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Data @Data
@AllArgsConstructor
public class LwM2MBootstrapConfig implements Serializable { public class LwM2MBootstrapConfig implements Serializable {
List<LwM2MBootstrapServerCredential> serverConfiguration; List<LwM2MBootstrapServerCredential> serverConfiguration;
@ -75,52 +79,68 @@ public class LwM2MBootstrapConfig implements Serializable {
@Setter @Setter
private LwM2MBootstrapClientCredential lwm2mServer; private LwM2MBootstrapClientCredential lwm2mServer;
public LwM2MBootstrapConfig(List<LwM2MBootstrapServerCredential> serverConfiguration, LwM2MBootstrapClientCredential bootstrapClientCredential) { public LwM2MBootstrapConfig(){};
public LwM2MBootstrapConfig(List<LwM2MBootstrapServerCredential> serverConfiguration, LwM2MBootstrapClientCredential bootstrapClientServer, LwM2MBootstrapClientCredential lwm2mClientServer) {
this.serverConfiguration = serverConfiguration; this.serverConfiguration = serverConfiguration;
this.bootstrapServer = bootstrapClientServer;
this.lwm2mServer = lwm2mClientServer;
} }
@JsonIgnore @JsonIgnore
public BootstrapConfig getLwM2MBootstrapConfig() { public BootstrapConfig getLwM2MBootstrapConfig() {
BootstrapConfig configBs = new BootstrapConfig(); BootstrapConfig configBs = new BootstrapConfig();
/* Delete old security objects */ AtomicInteger index = new AtomicInteger();
/** Delete old security/config objects in LwM2mDefaultBootstrapSessionManager -> initTasks */
configBs.toDelete.add("/0"); configBs.toDelete.add("/0");
configBs.toDelete.add("/1"); configBs.toDelete.add("/1");
/* Server Configuration (object 1) as defined in LWM2M 1.0.x TS. */ serverConfiguration.forEach(serverCredential -> {
BootstrapConfig.ServerConfig server0 = new BootstrapConfig.ServerConfig(); BootstrapConfig.ServerConfig serverConfig = new BootstrapConfig.ServerConfig();
// server0.shortId = servers.getShortId(); serverConfig.shortId = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getShortServerId();
// server0.lifetime = servers.getLifetime(); serverConfig.lifetime = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getLifetime();
// server0.defaultMinPeriod = servers.getDefaultMinPeriod(); serverConfig.defaultMinPeriod = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getDefaultMinPeriod();
// server0.notifIfDisabled = servers.isNotifIfDisabled(); serverConfig.notifIfDisabled = ((AbstractLwM2MBootstrapServerCredential)serverCredential).isNotifIfDisabled();
// server0.binding = BindingMode.parse(servers.getBinding()); serverConfig.binding = BindingMode.parse(((AbstractLwM2MBootstrapServerCredential)serverCredential).getBinding());
configBs.servers.put(0, server0); int k = index.get();
/* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */ configBs.servers.put(k, serverConfig);
// this.bootstrapServer.setBootstrapServerIs(true); BootstrapConfig.ServerSecurity serverSecurity = setServerSecurity((AbstractLwM2MBootstrapServerCredential)serverCredential, serverCredential.getSecurityMode());
// configBs.security.put(0, setServerSecurity(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.getSecurityHost(), this.lwm2mServer.getSecurityPort(), this.bootstrapServer.isBootstrapServerIs(), this.bootstrapServer.getSecurityMode(), this.bootstrapServer.getClientPublicKeyOrId(), this.bootstrapServer.getServerPublicKey(), this.bootstrapServer.getClientSecretKey(), this.bootstrapServer.getServerId())); configBs.security.put(k, serverSecurity);
// /* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */ index.getAndIncrement();
// configBs.security.put(1, setServerSecurity(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.getSecurityHost(), this.lwm2mServer.getSecurityPort(), this.lwm2mServer.isBootstrapServerIs(), this.lwm2mServer.getSecurityMode(), this.lwm2mServer.getClientPublicKeyOrId(), this.lwm2mServer.getServerPublicKey(), this.lwm2mServer.getClientSecretKey(), this.lwm2mServer.getServerId()));
});
return configBs; return configBs;
} }
private BootstrapConfig.ServerSecurity setServerSecurity(String host, Integer port, String securityHost, Integer securityPort, boolean bootstrapServer, SecurityMode securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) { private BootstrapConfig.ServerSecurity setServerSecurity(AbstractLwM2MBootstrapServerCredential serverCredential, LwM2MSecurityMode securityMode) {
BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity(); BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity();
if (securityMode.equals(SecurityMode.NO_SEC)) { String serverUri = "coap://";
serverSecurity.uri = "coap://" + host + ":" + Integer.toString(port); byte[] publicKeyOrId = new byte[]{};;
} else { byte[] secretKey = new byte[]{};;
serverSecurity.uri = "coaps://" + securityHost + ":" + Integer.toString(securityPort); serverSecurity.serverId = serverCredential.getShortServerId();
serverSecurity.securityMode = SecurityMode.valueOf(securityMode.name());
serverSecurity.bootstrapServer = serverCredential.isBootstrapServerIs();
if (!LwM2MSecurityMode.NO_SEC.equals(securityMode)) {
serverUri = "coaps://";
if (serverSecurity.bootstrapServer) {
publicKeyOrId = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.bootstrapServer).getDecodedClientPublicKeyOrId();
secretKey = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.bootstrapServer).getDecodedClientSecretKey();
} else {
publicKeyOrId = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.lwm2mServer).getDecodedClientPublicKeyOrId();
secretKey = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.lwm2mServer).getDecodedClientSecretKey();
}
} }
serverSecurity.bootstrapServer = bootstrapServer; serverUri += (((serverCredential.getHost().equals("0.0.0.0") ? "localhost" : serverCredential.getHost()) + ":" + serverCredential.getPort()));
serverSecurity.securityMode = securityMode; log.info("serverSecurity.uri = [{}]", serverUri);
serverSecurity.publicKeyOrId = setPublicKeyOrId(clientPublicKey, securityMode); log.info("publicKeyOrId [{}]", Hex.encodeHexString(publicKeyOrId));
serverSecurity.serverPublicKey = (serverPublicKey != null && !serverPublicKey.isEmpty()) ? Hex.decodeHex(serverPublicKey.toCharArray()) : new byte[]{}; log.info("secretKey [{}]", Hex.encodeHexString(secretKey));
serverSecurity.secretKey = (secretKey != null && !secretKey.isEmpty()) ? Hex.decodeHex(secretKey.toCharArray()) : new byte[]{}; log.info("server [{}]", Hex.encodeHexString(serverCredential.getDecodedCServerPublicKey()));
serverSecurity.serverId = serverId; serverSecurity.uri = serverUri;
serverSecurity.publicKeyOrId = publicKeyOrId;
serverSecurity.secretKey = secretKey;
serverSecurity.serverPublicKey = serverCredential.getDecodedCServerPublicKey();
return serverSecurity; return serverSecurity;
} }
private byte[] setPublicKeyOrId(String publicKeyOrIdStr, SecurityMode securityMode) {
return (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
SecurityMode.PSK.equals(securityMode) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
Hex.decodeHex(publicKeyOrIdStr.toCharArray());
}
} }

View File

@ -34,6 +34,7 @@ import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker; import org.eclipse.leshan.server.security.SecurityChecker;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MBootstrapSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException;
import java.util.ArrayList; import java.util.ArrayList;
@ -118,6 +119,7 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession
session.setModel(modelProvider.getObjectModel(session, tasks.supportedObjects)); session.setModel(modelProvider.getObjectModel(session, tasks.supportedObjects));
// set Requests to Send // set Requests to Send
log.info("tasks.requestsToSend = [{}]", tasks.requestsToSend);
session.setRequests(tasks.requestsToSend); session.setRequests(tasks.requestsToSend);
// prepare list where we will store Responses // prepare list where we will store Responses

View File

@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.transport.lwm2m.bootstrap.secure; package org.thingsboard.server.transport.lwm2m.bootstrap.store;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig; import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore; import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException; import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException;
@ -26,9 +24,10 @@ import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServersConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
@ -42,12 +41,12 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.BOOTSTRAP; import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.BOOTSTRAP;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_ERROR; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_INFO; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_INFO;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_TELEMETRY; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_TELEMETRY;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.getBootstrapParametersFromThingsboard;
@Slf4j @Slf4j
@Service("LwM2MBootstrapSecurityStore") @Service("LwM2MBootstrapSecurityStore")
@ -73,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
public Iterator<SecurityInfo> getAllByEndpoint(String endPoint) { public Iterator<SecurityInfo> getAllByEndpoint(String endPoint) {
// TODO // TODO
TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(endPoint, BOOTSTRAP); TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(endPoint, BOOTSTRAP);
if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) { if (store.getBootstrapCredentialConfig() != null) {
/* add value to store from BootstrapJson */ /* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store); this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfigNew = store.getBootstrapConfig(); BootstrapConfig bsConfigNew = store.getBootstrapConfig();
@ -123,15 +122,15 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store); LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
if (lwM2MBootstrapConfig != null) { if (lwM2MBootstrapConfig != null) {
/* Security info */ /* Security info */
switch (lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode()) { // switch (lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode()) {
/* Use RPK only */ // /* Use RPK only */
case PSK: // case PSK:
// store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndpoint(), // store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndpoint(),
// lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(), // lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),
// Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray()))); // Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray())));
store.setSecurityMode(SecurityMode.PSK); // store.setSecurityMode(SecurityMode.PSK);
break; // break;
case RPK: // case RPK:
// try { // try {
//// store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndpoint(), //// store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndpoint(),
//// SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray())))); //// SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray()))));
@ -140,16 +139,16 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
// } catch (IOException | GeneralSecurityException e) { // } catch (IOException | GeneralSecurityException e) {
// log.error("Unable to decode Client public key for [{}] [{}]", store.getEndpoint(), e.getMessage()); // log.error("Unable to decode Client public key for [{}] [{}]", store.getEndpoint(), e.getMessage());
// } // }
case X509: // case X509:
store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndpoint())); // store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndpoint()));
store.setSecurityMode(SecurityMode.X509); // store.setSecurityMode(SecurityMode.X509);
break; // break;
case NO_SEC: // case NO_SEC:
store.setSecurityMode(SecurityMode.NO_SEC); // store.setSecurityMode(SecurityMode.NO_SEC);
store.setSecurityInfo(null); // store.setSecurityInfo(null);
break; // break;
default: // default:
} // }
BootstrapConfig bootstrapConfig = lwM2MBootstrapConfig.getLwM2MBootstrapConfig(); BootstrapConfig bootstrapConfig = lwM2MBootstrapConfig.getLwM2MBootstrapConfig();
store.setBootstrapConfig(bootstrapConfig); store.setBootstrapConfig(bootstrapConfig);
} }
@ -158,7 +157,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
private LwM2MBootstrapConfig getParametersBootstrap(TbLwM2MSecurityInfo store) { private LwM2MBootstrapConfig getParametersBootstrap(TbLwM2MSecurityInfo store) {
LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig(); LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig();
if (lwM2MBootstrapConfig != null) { if (lwM2MBootstrapConfig != null) {
LwM2MBootstrapServersConfiguration bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile()); // LwM2MBootstrapServersConfiguration bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile());
// lwM2MBootstrapConfig.setServers(JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getServers()), LwM2MBootstrapServers.class)); // lwM2MBootstrapConfig.setServers(JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getServers()), LwM2MBootstrapServers.class));
// LwM2MServerBootstrap bootstrapServerProfile = JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getBootstrapServer()), LwM2MServerBootstrap.class); // LwM2MServerBootstrap bootstrapServerProfile = JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getBootstrapServer()), LwM2MServerBootstrap.class);
// if (SecurityMode.NO_SEC != bootstrapServerProfile.getSecurityMode() && bootstrapServerProfile != null) { // if (SecurityMode.NO_SEC != bootstrapServerProfile.getSecurityMode() && bootstrapServerProfile != null) {
@ -170,23 +169,25 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
// profileLwm2mServer.setSecurityHost(profileLwm2mServer.getHost()); // profileLwm2mServer.setSecurityHost(profileLwm2mServer.getHost());
// profileLwm2mServer.setSecurityPort(profileLwm2mServer.getPort()); // profileLwm2mServer.setSecurityPort(profileLwm2mServer.getPort());
// } // }
// UUID sessionUUiD = UUID.randomUUID();
// TransportProtos.SessionInfoProto sessionInfo = helper.getValidateSessionInfo(store.getMsg(), sessionUUiD.getMostSignificantBits(), sessionUUiD.getLeastSignificantBits());
// bsSessions.put(store.getEndpoint(), sessionInfo); UUID sessionUUiD = UUID.randomUUID();
// context.getTransportService().registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(null, null, null, sessionInfo, context.getTransportService())); TransportProtos.SessionInfoProto sessionInfo = helper.getValidateSessionInfo(store.getMsg(), sessionUUiD.getMostSignificantBits(), sessionUUiD.getLeastSignificantBits());
// if (this.getValidatedSecurityMode(lwM2MBootstrapConfig.getBootstrapServer(), bootstrapServerProfile, lwM2MBootstrapConfig.getLwm2mServer(), profileLwm2mServer)) { bsSessions.put(store.getEndpoint(), sessionInfo);
context.getTransportService().registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(null, null, null, sessionInfo, context.getTransportService()));
if (this.getValidatedSecurityMode(lwM2MBootstrapConfig)) {
// lwM2MBootstrapConfig.setBootstrapServer(new LwM2MServerBootstrap(lwM2MBootstrapConfig.getBootstrapServer(), bootstrapServerProfile)); // lwM2MBootstrapConfig.setBootstrapServer(new LwM2MServerBootstrap(lwM2MBootstrapConfig.getBootstrapServer(), bootstrapServerProfile));
// lwM2MBootstrapConfig.setLwm2mServer(new LwM2MServerBootstrap(lwM2MBootstrapConfig.getLwm2mServer(), profileLwm2mServer)); // lwM2MBootstrapConfig.setLwm2mServer(new LwM2MServerBootstrap(lwM2MBootstrapConfig.getLwm2mServer(), profileLwm2mServer));
// String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LWM2M_INFO, store.getEndpoint()); String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LWM2M_INFO, store.getEndpoint());
// helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), sessionInfo); helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), sessionInfo);
// return lwM2MBootstrapConfig; return lwM2MBootstrapConfig;
// } else { } else {
// log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndpoint()); log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndpoint());
// log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LWM2M_ERROR, store.getEndpoint()); log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LWM2M_ERROR, store.getEndpoint());
// String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LWM2M_ERROR, store.getEndpoint()); String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LWM2M_ERROR, store.getEndpoint());
// helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), sessionInfo); helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), sessionInfo);
// return null; return null;
// } }
} }
log.error("Unable to decode Json or Certificate for [{}]", store.getEndpoint()); log.error("Unable to decode Json or Certificate for [{}]", store.getEndpoint());
return null; return null;
@ -196,15 +197,27 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
* Bootstrap security have to sync between (bootstrapServer in credential and bootstrapServer in profile) * Bootstrap security have to sync between (bootstrapServer in credential and bootstrapServer in profile)
* and (lwm2mServer in credential and lwm2mServer in profile * and (lwm2mServer in credential and lwm2mServer in profile
* *
* @param bootstrapFromCredential - Bootstrap -> Security of bootstrapServer in credential
* @param bootstrapServerProfile - Bootstrap -> Security of bootstrapServer in profile
* @param lwm2mFromCredential - Bootstrap -> Security of lwm2mServer in credential
* @param profileLwm2mServer - Bootstrap -> Security of lwm2mServer in profile
* @return false if not sync between SecurityMode of Bootstrap credential and profile * @return false if not sync between SecurityMode of Bootstrap credential and profile
*/ */
private boolean getValidatedSecurityMode(LwM2MServerBootstrap bootstrapFromCredential, LwM2MServerBootstrap bootstrapServerProfile, LwM2MServerBootstrap lwm2mFromCredential, LwM2MServerBootstrap profileLwm2mServer) { // private boolean getValidatedSecurityMode(LwM2MServerBootstrap bootstrapFromCredential, LwM2MServerBootstrap bootstrapServerProfile, LwM2MServerBootstrap lwm2mFromCredential, LwM2MServerBootstrap profileLwm2mServer) {
return (bootstrapFromCredential.getSecurityMode().equals(bootstrapServerProfile.getSecurityMode()) && private boolean getValidatedSecurityMode(LwM2MBootstrapConfig lwM2MBootstrapConfig) {
lwm2mFromCredential.getSecurityMode().equals(profileLwm2mServer.getSecurityMode())); LwM2MSecurityMode bootstrapServerSecurityMode = lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode();
LwM2MSecurityMode lwm2mServerSecurityMode = lwM2MBootstrapConfig.getLwm2mServer().getSecurityMode();
AtomicBoolean validBs = new AtomicBoolean(true);
AtomicBoolean validLw = new AtomicBoolean(true);
lwM2MBootstrapConfig.getServerConfiguration().forEach(serverCredential -> {
if (((AbstractLwM2MBootstrapServerCredential)serverCredential).isBootstrapServerIs()) {
if (!bootstrapServerSecurityMode.equals(serverCredential.getSecurityMode())) {
validBs.set(false);
}
}
else {
if (!lwm2mServerSecurityMode.equals(serverCredential.getSecurityMode())) {
validLw.set(false);
}
}
});
return validBs.get()&validLw.get();
} }
public TransportProtos.SessionInfoProto getSessionByEndpoint(String endpoint) { public TransportProtos.SessionInfoProto getSessionByEndpoint(String endpoint) {

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.transport.lwm2m.bootstrap.secure; package org.thingsboard.server.transport.lwm2m.bootstrap.store;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.Identity;

View File

@ -24,13 +24,14 @@ import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential;
import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MClientCredentials; import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MClientCredentials;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
@ -68,17 +69,16 @@ public class LwM2mCredentialsSecurityInfoValidator {
@Override @Override
public void onSuccess(ValidateDeviceCredentialsResponse msg) { public void onSuccess(ValidateDeviceCredentialsResponse msg) {
log.trace("Validated credentials: [{}] [{}]", credentialsId, msg); log.trace("Validated credentials: [{}] [{}]", credentialsId, msg);
String credentialsBody = msg.getCredentials(); resultSecurityStore[0] = createSecurityInfo(credentialsId, msg, keyValue);
resultSecurityStore[0] = createSecurityInfo(credentialsId, credentialsBody, keyValue);
resultSecurityStore[0].setMsg(msg);
resultSecurityStore[0].setDeviceProfile(msg.getDeviceProfile());
latch.countDown(); latch.countDown();
} }
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
log.trace("[{}] [{}] Failed to process credentials ", credentialsId, e); log.trace("[{}] [{}] Failed to process credentials ", credentialsId, e);
resultSecurityStore[0] = createSecurityInfo(credentialsId, null, null); TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo();
result.setEndpoint(credentialsId);
resultSecurityStore[0] = result;
latch.countDown(); latch.countDown();
} }
}); });
@ -88,50 +88,47 @@ public class LwM2mCredentialsSecurityInfoValidator {
log.error("Failed to await credentials!", e); log.error("Failed to await credentials!", e);
} }
return resultSecurityStore[0]; TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0];
if ((CLIENT.equals(keyValue) && securityInfo.getSecurityMode() == null)) {
// if ((CLIENT.equals(keyValue) && securityInfo.getSecurityMode() == null) || throw new LwM2MAuthException();
// (BOOTSTRAP.equals(keyValue) && securityInfo.getBootstrapCredentialConfig().getBootstrapServer()==null && securityInfo.getBootstrapCredentialConfig().getLwm2mServer()==null)){ }
// throw new LwM2MAuthException(); return securityInfo;
// }
//
// return securityInfo;
} }
/** /**
* Create new SecurityInfo * Create new SecurityInfo
*
* @return SecurityInfo * @return SecurityInfo
*/ */
private TbLwM2MSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTypeServer keyValue) { private TbLwM2MSecurityInfo createSecurityInfo(String endpoint, ValidateDeviceCredentialsResponse msg, LwM2mTypeServer keyValue) {
TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo(); TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo();
LwM2MClientCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MClientCredentials.class); LwM2MClientCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MClientCredentials.class);
if (credentials != null) { if (credentials != null) {
result.setMsg(msg);
result.setDeviceProfile(msg.getDeviceProfile());
result.setEndpoint(credentials.getClient().getEndpoint());
// if ((keyValue.equals(CLIENT))) {
switch (credentials.getClient().getSecurityConfigClientMode()) {
case NO_SEC:
createClientSecurityInfoNoSec(result);
break;
case PSK:
createClientSecurityInfoPSK(result, endpoint, credentials.getClient());
break;
case RPK:
createClientSecurityInfoRPK(result, endpoint, credentials.getClient());
break;
case X509:
createClientSecurityInfoX509(result, endpoint, credentials.getClient());
break;
default:
break;
}
// } else
if (keyValue.equals(BOOTSTRAP)) { if (keyValue.equals(BOOTSTRAP)) {
result.setBootstrapCredentialConfig(credentials.getBootstrap()); LwM2MBootstrapConfig bootstrapCredentialConfig = new LwM2MBootstrapConfig(((Lwm2mDeviceProfileTransportConfiguration) msg.getDeviceProfile().getProfileData().getTransportConfiguration()).getBootstrap(),
if (LwM2MSecurityMode.PSK.equals(credentials.getClient().getSecurityConfigClientMode())) { credentials.getBootstrap().getBootstrapServer(), credentials.getBootstrap().getLwm2mServer());
PSKClientCredential pskClientConfig = (PSKClientCredential) credentials.getClient(); result.setBootstrapCredentialConfig(bootstrapCredentialConfig);
endpoint = StringUtils.isNotEmpty(pskClientConfig.getEndpoint()) ? pskClientConfig.getEndpoint() : endpoint;
}
result.setEndpoint(endpoint);
// result.setSecurityMode(credentials.getBootstrap().getBootstrapServer().getSecurityMode());
} else {
result.setEndpoint(credentials.getClient().getEndpoint());
switch (credentials.getClient().getSecurityConfigClientMode()) {
case NO_SEC:
createClientSecurityInfoNoSec(result);
break;
case PSK:
createClientSecurityInfoPSK(result, endpoint, credentials.getClient());
break;
case RPK:
createClientSecurityInfoRPK(result, endpoint, credentials.getClient());
break;
case X509:
createClientSecurityInfoX509(result, endpoint, credentials.getClient());
break;
default:
break;
}
} }
} }
return result; return result;

View File

@ -28,12 +28,13 @@ import java.io.Serializable;
@Data @Data
public class TbLwM2MSecurityInfo implements Serializable { public class TbLwM2MSecurityInfo implements Serializable {
private ValidateDeviceCredentialsResponse msg; private ValidateDeviceCredentialsResponse msg;
private DeviceProfile deviceProfile;
private String endpoint;
private SecurityInfo securityInfo; private SecurityInfo securityInfo;
private SecurityMode securityMode; private SecurityMode securityMode;
private DeviceProfile deviceProfile;
/** bootstrap */ /** bootstrap */
private LwM2MBootstrapConfig bootstrapCredentialConfig; private LwM2MBootstrapConfig bootstrapCredentialConfig;
private String endpoint;
private BootstrapConfig bootstrapConfig; private BootstrapConfig bootstrapConfig;
} }

View File

@ -22,6 +22,7 @@ import org.eclipse.leshan.server.security.SecurityInfo;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -71,7 +72,12 @@ public class TbLwM2mSecurityStore implements TbMainSecurityStore {
public SecurityInfo getByIdentity(String pskIdentity) { public SecurityInfo getByIdentity(String pskIdentity) {
SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity); SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity);
if (securityInfo == null) { if (securityInfo == null) {
securityInfo = fetchAndPutSecurityInfo(pskIdentity); try {
securityInfo = fetchAndPutSecurityInfo(pskIdentity);
} catch (LwM2MAuthException e) {
log.info("Registration failed: FORBIDDEN, endpointId: [{}]", pskIdentity);
securityInfo = SecurityInfo.newPreSharedKeyInfo(pskIdentity, pskIdentity, new byte[]{0x00});
}
} }
return securityInfo; return securityInfo;
} }

View File

@ -39,7 +39,7 @@ import org.eclipse.leshan.server.registration.Registration;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServersConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.ota.OtaPackageKey; import org.thingsboard.server.common.data.ota.OtaPackageKey;
@ -181,7 +181,7 @@ public class LwM2MTransportUtil {
} }
} }
public static LwM2MBootstrapServersConfiguration getBootstrapParametersFromThingsboard(DeviceProfile deviceProfile) { public static List<LwM2MBootstrapServerCredential> getBootstrapParametersFromThingsboard(DeviceProfile deviceProfile) {
return toLwM2MClientProfile(deviceProfile).getBootstrap(); return toLwM2MClientProfile(deviceProfile).getBootstrap();
} }

View File

@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackage;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServersConfiguration;
import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration;
import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration;
@ -418,8 +417,8 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
} }
} }
} else if (transportConfiguration instanceof Lwm2mDeviceProfileTransportConfiguration) { } else if (transportConfiguration instanceof Lwm2mDeviceProfileTransportConfiguration) {
LwM2MBootstrapServersConfiguration lwM2MBootstrapServersConfiguration = ((Lwm2mDeviceProfileTransportConfiguration) transportConfiguration).getBootstrap(); List<LwM2MBootstrapServerCredential> lwM2MBootstrapServersConfigurations = ((Lwm2mDeviceProfileTransportConfiguration) transportConfiguration).getBootstrap();
for (LwM2MBootstrapServerCredential bootstrapServerCredential : lwM2MBootstrapServersConfiguration.getServerConfiguration()) { for (LwM2MBootstrapServerCredential bootstrapServerCredential : lwM2MBootstrapServersConfigurations) {
validateLwm2mServersCredentialOfBootstrapForClient(bootstrapServerCredential); validateLwm2mServersCredentialOfBootstrapForClient(bootstrapServerCredential);
} }
} }