lwm2m - Bootstrap auto

This commit is contained in:
nickAS21 2021-11-15 19:11:53 +02:00
parent 6892074646
commit fbc785a471
6 changed files with 313 additions and 111 deletions

View File

@ -23,12 +23,15 @@ import lombok.Data;
@Data
public class LwM2MServerSecurityConfig {
@ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance.\nThis identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.\n" +
"This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. \n" +
@ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " +
"This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. " +
"The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", readOnly = true)
protected Integer shortServerId = 123;
/** Security -> ObjectId = 0 'LWM2M Security' */
@ApiModelProperty(position = 2, value = "Is Bootstrap Server or Lwm2m Server", example = "true or false", readOnly = true)
@ApiModelProperty(position = 2, value = "Is Bootstrap Server or Lwm2m Server. " +
"The LwM2M Client MAY be configured to use one or more LwM2M Server Account(s). " +
"The LwM2M Client MUST have at most one LwM2M Bootstrap-Server Account. " +
"(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", readOnly = true)
protected boolean bootstrapServerIs = false;
@ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", readOnly = true)
protected String host;
@ -45,15 +48,15 @@ public class LwM2MServerSecurityConfig {
/** Config -> ObjectId = 1 'LwM2M Server' */
@ApiModelProperty(position = 10, value = "Specify the lifetime of the registration in seconds.", example = "300", readOnly = true)
private Integer lifetime = 300;
@ApiModelProperty(position = 11, value = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation.\n" +
@ApiModelProperty(position = 11, value = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " +
"If this Resource doesnt exist, the default value is 0.", example = "1", readOnly = true)
private Integer defaultMinPeriod = 1;
/** ResourceID=6 'Notification Storing When Disabled or Offline' */
@ApiModelProperty(position = 12, value = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server.\n" +
"If false, the LwM2M Client discards all the “Notify” operations or temporarily disables the Observe function while the LwM2M Server is disabled or the LwM2M Client is offline.\n" +
@ApiModelProperty(position = 12, value = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " +
"If false, the LwM2M Client discards all the “Notify” operations or temporarily disables the Observe function while the LwM2M Server is disabled or the LwM2M Client is offline. " +
"The default value is true.", example = "true", readOnly = true)
private boolean notifIfDisabled = true;
@ApiModelProperty(position = 14, value = "This Resource defines the transport binding configured for the LwM2M Client.\n" +
@ApiModelProperty(position = 14, value = "This Resource defines the transport binding configured for the LwM2M Client. " +
"If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", readOnly = true)
private String binding = "U";
}

View File

@ -40,23 +40,6 @@ import java.util.concurrent.atomic.AtomicInteger;
public class LwM2MBootstrapConfig implements Serializable {
List<LwM2MBootstrapServerCredential> serverConfiguration;
/*
interface BootstrapSecurityConfig
servers: BootstrapServersSecurityConfig,
bootstrapServer: ServerSecurityConfig,
lwm2mServer: ServerSecurityConfig
}
*/
/** -servers
* shortId: number,
* lifetime: number,
* defaultMinPeriod: number,
* notifIfDisabled: boolean,
* binding: string
* */
// @Getter
// @Setter
// private LwM2MBootstrapServers servers;
/** -bootstrapServer, lwm2mServer
* interface ServerSecurityConfig
@ -91,56 +74,70 @@ public class LwM2MBootstrapConfig implements Serializable {
@JsonIgnore
public BootstrapConfig getLwM2MBootstrapConfig() {
BootstrapConfig configBs = new BootstrapConfig();
AtomicInteger index = new AtomicInteger();
/** Delete old security/config objects in LwM2mDefaultBootstrapSessionManager -> initTasks */
configBs.toDelete.add("/0");
configBs.toDelete.add("/1");
serverConfiguration.forEach(serverCredential -> {
BootstrapConfig.ServerConfig serverConfig = new BootstrapConfig.ServerConfig();
serverConfig.shortId = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getShortServerId();
serverConfig.lifetime = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getLifetime();
serverConfig.defaultMinPeriod = ((AbstractLwM2MBootstrapServerCredential)serverCredential).getDefaultMinPeriod();
serverConfig.notifIfDisabled = ((AbstractLwM2MBootstrapServerCredential)serverCredential).isNotifIfDisabled();
serverConfig.binding = BindingMode.parse(((AbstractLwM2MBootstrapServerCredential)serverCredential).getBinding());
int k = index.get();
configBs.servers.put(k, serverConfig);
BootstrapConfig.ServerSecurity serverSecurity = setServerSecurity((AbstractLwM2MBootstrapServerCredential)serverCredential, serverCredential.getSecurityMode());
configBs.security.put(k, serverSecurity);
index.getAndIncrement();
configBs.autoIdForSecurityObject = true;
int id = 0;
for (LwM2MBootstrapServerCredential serverCredential : serverConfiguration) {
BootstrapConfig.ServerConfig serverConfig = setServerConfig((AbstractLwM2MBootstrapServerCredential) serverCredential);
configBs.servers.put(id, serverConfig);
BootstrapConfig.ServerSecurity serverSecurity = setServerSecurity((AbstractLwM2MBootstrapServerCredential) serverCredential, serverCredential.getSecurityMode());
configBs.security.put(id, serverSecurity);
id++;
}
/** in LwM2mDefaultBootstrapSessionManager -> initTasks
* Delete all security/config objects if update bootstrap server and lwm2m server
* if other: del or update only instances */
});
return configBs;
}
private BootstrapConfig.ServerSecurity setServerSecurity(AbstractLwM2MBootstrapServerCredential serverCredential, LwM2MSecurityMode securityMode) {
BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity();
String serverUri = "coap://";
byte[] publicKeyOrId = new byte[]{};;
byte[] secretKey = new byte[]{};;
byte[] publicKeyOrId = new byte[]{};
byte[] secretKey = new byte[]{};
byte[] serverPublicKey = new byte[]{};
serverSecurity.serverId = serverCredential.getShortServerId();
log.info("serverId = [{}]", serverSecurity.serverId);
serverSecurity.securityMode = SecurityMode.valueOf(securityMode.name());
serverSecurity.bootstrapServer = serverCredential.isBootstrapServerIs();
if (!LwM2MSecurityMode.NO_SEC.equals(securityMode)) {
serverUri = "coaps://";
AbstractLwM2MBootstrapClientCredentialWithKeys server;
if (serverSecurity.bootstrapServer) {
publicKeyOrId = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.bootstrapServer).getDecodedClientPublicKeyOrId();
secretKey = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.bootstrapServer).getDecodedClientSecretKey();
server = (AbstractLwM2MBootstrapClientCredentialWithKeys) this.bootstrapServer;
} else {
publicKeyOrId = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.lwm2mServer).getDecodedClientPublicKeyOrId();
secretKey = ((AbstractLwM2MBootstrapClientCredentialWithKeys)this.lwm2mServer).getDecodedClientSecretKey();
server = (AbstractLwM2MBootstrapClientCredentialWithKeys) this.lwm2mServer;
}
serverUri = "coaps://";
if (LwM2MSecurityMode.PSK.equals(securityMode)) {
publicKeyOrId = server.getClientPublicKeyOrId().getBytes();
secretKey = Hex.decodeHex(server.getClientSecretKey().toCharArray());
log.info("publicKeyOrId [{}]", new String(publicKeyOrId, StandardCharsets.UTF_8));
} else {
publicKeyOrId = server.getDecodedClientPublicKeyOrId();
secretKey = server.getDecodedClientSecretKey();
log.info("publicKeyOrId [{}]", Hex.encodeHexString(publicKeyOrId));
}
serverPublicKey = serverCredential.getDecodedCServerPublicKey();
}
log.info("secretKey [{}]", Hex.encodeHexString(secretKey));
serverUri += (((serverCredential.getHost().equals("0.0.0.0") ? "localhost" : serverCredential.getHost()) + ":" + serverCredential.getPort()));
log.info("serverSecurity.uri = [{}]", serverUri);
log.info("publicKeyOrId [{}]", Hex.encodeHexString(publicKeyOrId));
log.info("secretKey [{}]", Hex.encodeHexString(secretKey));
log.info("server [{}]", Hex.encodeHexString(serverCredential.getDecodedCServerPublicKey()));
serverSecurity.uri = serverUri;
serverSecurity.publicKeyOrId = publicKeyOrId;
serverSecurity.secretKey = secretKey;
serverSecurity.serverPublicKey = serverCredential.getDecodedCServerPublicKey();
serverSecurity.serverPublicKey = serverPublicKey;
log.info("server [{}]", Hex.encodeHexString(serverSecurity.serverPublicKey));
return serverSecurity;
}
private BootstrapConfig.ServerConfig setServerConfig (AbstractLwM2MBootstrapServerCredential serverCredential) {
BootstrapConfig.ServerConfig serverConfig = new BootstrapConfig.ServerConfig();
serverConfig.shortId = serverCredential.getShortServerId();
serverConfig.lifetime = serverCredential.getLifetime();
serverConfig.defaultMinPeriod = serverCredential.getDefaultMinPeriod();
serverConfig.notifIfDisabled = serverCredential.isNotifIfDisabled();
serverConfig.binding = BindingMode.parse(serverCredential.getBinding());
return serverConfig;
}
}

View File

@ -16,13 +16,14 @@
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.request.BootstrapDiscoverRequest;
import org.eclipse.leshan.core.request.BootstrapDownlinkRequest;
import org.eclipse.leshan.core.request.BootstrapFinishRequest;
import org.eclipse.leshan.core.request.BootstrapRequest;
import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.core.response.BootstrapDiscoverResponse;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.server.bootstrap.BootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.BootstrapConfigStoreTaskProvider;
import org.eclipse.leshan.server.bootstrap.BootstrapFailureCause;
import org.eclipse.leshan.server.bootstrap.BootstrapSession;
import org.eclipse.leshan.server.bootstrap.BootstrapTaskProvider;
@ -34,13 +35,13 @@ import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MBootstrapConfigStoreTaskProvider;
import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MBootstrapSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LOG_LWM2M_INFO;
@Slf4j
@ -59,7 +60,7 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession
* @param bsSecurityStore the {@link BootstrapSecurityStore} used by default {@link SecurityChecker}.
*/
public LwM2mDefaultBootstrapSessionManager(BootstrapSecurityStore bsSecurityStore, BootstrapConfigStore configStore, TransportService transportService) {
this(bsSecurityStore, new SecurityChecker(), new BootstrapConfigStoreTaskProvider(configStore),
this(bsSecurityStore, new SecurityChecker(), new LwM2MBootstrapConfigStoreTaskProvider(configStore),
new StandardBootstrapModelProvider());
this.transportService = transportService;
}
@ -164,14 +165,15 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession
// store response
DefaultBootstrapSession session = (DefaultBootstrapSession) bsSession;
session.getResponses().add(response);
this.sendLogs (bsSession.getEndpoint(),
String.format("%s: %s %s receives success response %s for %s : %s", LOG_LWM2M_INFO,
request.getClass().getSimpleName(), request.getPath().toString(), response.toString(), bsSession.toString(), request.toString()));
String msg = String.format("%s: %s %s receives success response %s for %s : %s", LOG_LWM2M_INFO,
request.getClass().getSimpleName(), request.getPath().toString(), response.toString(), bsSession.toString(), request.toString());
this.sendLogs(bsSession.getEndpoint(), msg);
// on success for NOT bootstrap finish request we send next request
return BootstrapPolicy.continueWith(nextRequest(bsSession));
} else {
// on success for bootstrap finish request we stop the session
this.sendLogs (bsSession.getEndpoint(),
this.sendLogs(bsSession.getEndpoint(),
String.format("%s: %s receives success response for bootstrap finish request and stop the session: %s", LOG_LWM2M_INFO,
request.getClass().getSimpleName(), bsSession.toString()));
return BootstrapPolicy.finished();
@ -194,9 +196,7 @@ public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSession
} else {
// on response error for bootstrap finish request we stop the session
this.sendLogs (bsSession.getEndpoint(),
String.format("%s: %s %s error response %s for request %s bootstrap finish. Stop the session: %s", LOG_LWM2M_INFO,
request.getClass().getSimpleName(),
request.getPath().toString(), response.toString(), request.toString(), bsSession.toString()));
String.format("%s: error response for request bootstrap finish. Stop the session: %s", LOG_LWM2M_ERROR, bsSession.toString()));
return BootstrapPolicy.failed();
}
}

View File

@ -0,0 +1,242 @@
/**
* 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 lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.Link;
import org.eclipse.leshan.core.node.LwM2mObject;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.request.*;
import org.eclipse.leshan.core.response.BootstrapDiscoverResponse;
import org.eclipse.leshan.core.response.BootstrapReadResponse;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.bootstrap.BootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.BootstrapSession;
import org.eclipse.leshan.server.bootstrap.BootstrapTaskProvider;
import org.eclipse.leshan.server.bootstrap.BootstrapUtil;
import java.net.InetSocketAddress;
import java.util.*;
import static org.eclipse.leshan.server.bootstrap.BootstrapUtil.toWriteRequest;
@Slf4j
public class LwM2MBootstrapConfigStoreTaskProvider implements BootstrapTaskProvider {
private BootstrapConfigStore store;
private Map<Integer, String> supportedObjects;
/**
* Map<serverId, InstanceId>
*/
protected Map<Integer, Integer> securityInstances;
protected Map<Integer, Integer> serverInstances;
public LwM2MBootstrapConfigStoreTaskProvider(BootstrapConfigStore store) {
this.store = store;
}
@Override
public Tasks getTasks(BootstrapSession session, List<LwM2mResponse> previousResponse) {
BootstrapConfig config = store.get(session.getEndpoint(), session.getIdentity(), session);
if (config == null) {
return null;
}
if (previousResponse == null && shouldStartWithDiscover(config)) {
Tasks tasks = new Tasks();
tasks.requestsToSend = new ArrayList<>(1);
tasks.requestsToSend.add(new BootstrapDiscoverRequest());
tasks.last = false;
return tasks;
} else {
Tasks tasks = new Tasks();
if (this.supportedObjects == null) {
initSupportedObjectsDefault();
}
// add supportedObjects
tasks.supportedObjects = this.supportedObjects;
// handle bootstrap discover response
if (previousResponse != null) {
if (previousResponse.get(0) instanceof BootstrapDiscoverResponse) {
BootstrapDiscoverResponse discoverResponse = (BootstrapDiscoverResponse) previousResponse.get(0);
if (discoverResponse.isSuccess()) {
this.initAfterBootstrapDiscover(discoverResponse);
findSecurityInstanceId(discoverResponse.getObjectLinks());
} else {
log.info(
"Bootstrap Discover return error {} : to continue bootstrap session without autoIdForSecurityObject mode. {}",
discoverResponse, session);
}
if (this.securityInstances.get(0) == null) {
log.error(
"Unable to find bootstrap server instance in Security Object (0) in response {}: unable to continue bootstrap session with autoIdForSecurityObject mode. {}",
discoverResponse, session);
return null;
}
tasks.requestsToSend = new ArrayList<>(1);
tasks.requestsToSend.add(new BootstrapReadRequest("/1"));
tasks.last = false;
return tasks;
}
BootstrapReadResponse readResponse = (BootstrapReadResponse) previousResponse.get(0);
findServerInstanceId(readResponse);
// create requests from config
tasks.requestsToSend = this.toRequests(config,
config.contentFormat != null ? config.contentFormat : session.getContentFormat(),
this.securityInstances.get(0));
} else {
// create requests from config
tasks.requestsToSend = BootstrapUtil.toRequests(config,
config.contentFormat != null ? config.contentFormat : session.getContentFormat());
}
return tasks;
}
}
protected boolean shouldStartWithDiscover(BootstrapConfig config) {
return config.autoIdForSecurityObject;
}
protected void findSecurityInstanceId(Link[] objectLinks) {
this.securityInstances = new HashMap<>();
for (Link link : objectLinks) {
if (link.getUrl().startsWith("/0/")) {
try {
LwM2mPath path = new LwM2mPath(link.getUrl());
if (path.isObjectInstance()) {
if (link.getAttributes().containsKey("ssid")) {
int serverId = Integer.valueOf(link.getAttributes().get("ssid"));
if (!this.securityInstances.containsKey(serverId)) {
this.securityInstances.put(serverId, path.getObjectInstanceId());
} else {
log.error(String.format("Invalid lwm2mSecurityInstance by [{}]", path.getObjectInstanceId()));
}
this.securityInstances.put(Integer.valueOf(link.getAttributes().get("ssid")), path.getObjectInstanceId());
} else {
if (!this.securityInstances.containsKey(0)) {
this.securityInstances.put(0, path.getObjectInstanceId());
} else {
log.error(String.format("Invalid bootstrapSecurityInstance by [{}]", path.getObjectInstanceId()));
}
}
}
} catch (Exception e) {
// ignore if this is not a LWM2M path
log.error("Invalid LwM2MPath starting by \"/0/\"");
}
}
}
}
protected void findServerInstanceId(BootstrapReadResponse readResponse) {
serverInstances = new HashMap<>();
((LwM2mObject) readResponse.getContent()).getInstances().values().forEach(instance -> {
serverInstances.put(((Long) instance.getResource(0).getValue()).intValue(), instance.getId());
});
}
public BootstrapConfigStore getStore() {
return this.store;
}
private void initAfterBootstrapDiscover(BootstrapDiscoverResponse response) {
Link[] links = response.getObjectLinks();
Arrays.stream(links).forEach(link -> {
LwM2mPath path = new LwM2mPath(link.getUrl());
if (path != null && !path.isRoot() && path.getObjectId() < 3) {
if (path.isObject()) {
String ver = link.getAttributes().get("ver") != null ? link.getAttributes().get("ver") : "1.0";
this.supportedObjects.put(path.getObjectId(), ver);
}
}
});
}
public List<BootstrapDownlinkRequest<? extends LwM2mResponse>> toRequests(BootstrapConfig bootstrapConfig,
ContentFormat contentFormat, int bootstrapSecurityInstanceId) {
List<BootstrapDownlinkRequest<? extends LwM2mResponse>> requests = new ArrayList<>();
boolean isBsServer = false;
boolean isLwServer = false;
/** Map<serverId, InstanceId> */
Map<Integer, Integer> instances = new HashMap<>();
// handle security
int id = 0;
for (BootstrapConfig.ServerSecurity security : new TreeMap<>(bootstrapConfig.security).values()) {
if (security.bootstrapServer) {
requests.add(toWriteRequest(bootstrapSecurityInstanceId, security, contentFormat));
isBsServer = true;
instances.put(security.serverId, bootstrapSecurityInstanceId);
} else {
if (id == bootstrapSecurityInstanceId) {
id++;
}
requests.add(toWriteRequest(id, security, contentFormat));
instances.put(security.serverId, id);
id++;
}
}
// handle server
for (Map.Entry<Integer, BootstrapConfig.ServerConfig> server : bootstrapConfig.servers.entrySet()) {
int securityInstanceId = instances.get(server.getValue().shortId);
requests.add(toWriteRequest(securityInstanceId, server.getValue(), contentFormat));
if (!isBsServer && this.serverInstances.containsKey(server.getValue().shortId) && securityInstanceId != this.serverInstances.get(server.getValue().shortId)){
requests.add(new BootstrapDeleteRequest("/0/" + securityInstanceId));
requests.add(new BootstrapDeleteRequest("/1/" + this.serverInstances.get(server.getValue().shortId)));
}
isLwServer = true;
}
// handle acl
for (Map.Entry<Integer, BootstrapConfig.ACLConfig> acl : bootstrapConfig.acls.entrySet()) {
requests.add(toWriteRequest(acl.getKey(), acl.getValue(), contentFormat));
}
// handle delete
if (isBsServer & isLwServer) {
requests.add(new BootstrapDeleteRequest("/0"));
requests.add(new BootstrapDeleteRequest("/1"));
}
return (requests);
}
private InetSocketAddress getSocketAddress(String uri) {
// String uri1 = "coap://localhost:5687";
if (uri.contains("coap://")) {
uri = uri.replace("coap://", "");
} else return null;
String[] uris = uri.split(":");
if (uris.length == 2) {
try {
return new InetSocketAddress(uris[0], Integer.parseInt(uris[1]));
} catch (Exception e) {
return null;
}
} else return null;
}
private void initSupportedObjectsDefault() {
this.supportedObjects = new HashMap<>();
this.supportedObjects.put(0, "1.1");
this.supportedObjects.put(1, "1.1");
this.supportedObjects.put(2, "1.0");
}
}

View File

@ -75,6 +75,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
if (store.getBootstrapCredentialConfig() != null) {
/* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
endPoint = store.getEndpoint();
BootstrapConfig bsConfigNew = store.getBootstrapConfig();
if (bsConfigNew != null) {
try {
@ -121,34 +122,6 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
/* BootstrapConfig */
LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
if (lwM2MBootstrapConfig != null) {
/* Security info */
// switch (lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode()) {
// /* Use RPK only */
// case PSK:
// store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndpoint(),
// lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),
// Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray())));
// store.setSecurityMode(SecurityMode.PSK);
// break;
// case RPK:
// try {
//// store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndpoint(),
//// SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray()))));
//// store.setSecurityMode(SecurityMode.RPK);
// break;
// } catch (IOException | GeneralSecurityException e) {
// log.error("Unable to decode Client public key for [{}] [{}]", store.getEndpoint(), e.getMessage());
// }
// case X509:
// store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndpoint()));
// store.setSecurityMode(SecurityMode.X509);
// break;
// case NO_SEC:
// store.setSecurityMode(SecurityMode.NO_SEC);
// store.setSecurityInfo(null);
// break;
// default:
// }
BootstrapConfig bootstrapConfig = lwM2MBootstrapConfig.getLwM2MBootstrapConfig();
store.setBootstrapConfig(bootstrapConfig);
}
@ -157,27 +130,11 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
private LwM2MBootstrapConfig getParametersBootstrap(TbLwM2MSecurityInfo store) {
LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig();
if (lwM2MBootstrapConfig != null) {
// LwM2MBootstrapServersConfiguration bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile());
// lwM2MBootstrapConfig.setServers(JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getServers()), LwM2MBootstrapServers.class));
// LwM2MServerBootstrap bootstrapServerProfile = JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getBootstrapServer()), LwM2MServerBootstrap.class);
// if (SecurityMode.NO_SEC != bootstrapServerProfile.getSecurityMode() && bootstrapServerProfile != null) {
// bootstrapServerProfile.setSecurityHost(bootstrapServerProfile.getHost());
// bootstrapServerProfile.setSecurityPort(bootstrapServerProfile.getPort());
// }
// LwM2MServerBootstrap profileLwm2mServer = JacksonUtil.fromString(JacksonUtil.toString(bootstrapObject.getLwm2mServer()), LwM2MServerBootstrap.class);
// if (SecurityMode.NO_SEC != profileLwm2mServer.getSecurityMode() && profileLwm2mServer != null) {
// profileLwm2mServer.setSecurityHost(profileLwm2mServer.getHost());
// profileLwm2mServer.setSecurityPort(profileLwm2mServer.getPort());
// }
UUID sessionUUiD = UUID.randomUUID();
TransportProtos.SessionInfoProto sessionInfo = helper.getValidateSessionInfo(store.getMsg(), sessionUUiD.getMostSignificantBits(), sessionUUiD.getLeastSignificantBits());
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.setLwm2mServer(new LwM2MServerBootstrap(lwM2MBootstrapConfig.getLwm2mServer(), profileLwm2mServer));
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);
return lwM2MBootstrapConfig;

View File

@ -48,6 +48,9 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateString;
@ -238,7 +241,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
case PSK:
PSKClientCredential pskCredentials = (PSKClientCredential) clientCredentials;
if (StringUtils.isBlank(pskCredentials.getIdentity())) {
throw new DeviceCredentialsValidationException("LwM2M client PSK identity must be specified!");
throw new DeviceCredentialsValidationException("LwM2M client PSK identity must be specified and must be an utf8 string!");
}
// SecurityMode.NO_SEC.toString() == "NO_SEC";
if (pskCredentials.getIdentity().equals(SecurityMode.NO_SEC.toString())) {
@ -295,7 +298,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
case PSK:
PSKBootstrapClientCredential pskCredentials = (PSKBootstrapClientCredential) serverCredentials;
if (StringUtils.isBlank(pskCredentials.getClientPublicKeyOrId())) {
throw new DeviceCredentialsValidationException(server + " client PSK public key or id must be specified!");
throw new DeviceCredentialsValidationException(server + " client PSK public key or id must be specified and must be an utf8 string!");
}
// SecurityMode.NO_SEC.toString() == "NO_SEC";