Browse Source

Merge pull request #5520 from thingsboard/lwm2m_bootstrap_m4

[3.3.3] Lwm2m bootstrap m4
pull/5578/head
Andrew Shvayka 5 years ago
committed by GitHub
parent
commit
aa8cf92141
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java
  2. 4
      application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MService.java
  3. 12
      application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServiceImpl.java
  4. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsService.java
  5. 3
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/AbstractLwM2MBootstrapServerCredential.java
  6. 27
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerConfig.java
  7. 10
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java
  8. 63
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java
  9. 44
      common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/ServerSecurityConfig.java
  10. 11
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java
  11. 10
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java

20
application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java

@ -30,12 +30,10 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfig;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.lwm2m.LwM2MService;
import org.thingsboard.server.service.lwm2m.LwM2MServiceImpl;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.Map;
@ -63,14 +61,14 @@ public class Lwm2mController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET)
@ResponseBody
public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(
@ApiParam(value = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION)
@PathVariable(IS_BOOTSTRAP_SERVER) boolean bootstrapServer) throws ThingsboardException {
try {
return lwM2MService.getServerSecurityInfo(bootstrapServer);
} catch (Exception e) {
throw handleException(e);
}
public LwM2MServerSecurityConfig getLwm2mBootstrapSecurityInfo(
@ApiParam(value = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION)
@PathVariable(IS_BOOTSTRAP_SERVER) boolean bootstrapServer) throws ThingsboardException {
try {
return lwM2MService.getServerSecurityInfo(bootstrapServer);
} catch (Exception e) {
throw handleException(e);
}
}
@ApiOperation(hidden = true, value = "Save device with credentials (Deprecated)")

4
application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MService.java

@ -15,10 +15,10 @@
*/
package org.thingsboard.server.service.lwm2m;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfig;
public interface LwM2MService {
ServerSecurityConfig getServerSecurityInfo(boolean bootstrapServer);
LwM2MServerSecurityConfig getServerSecurityInfo(boolean bootstrapServer);
}

12
application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServiceImpl.java

@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfig;
import org.thingsboard.server.common.transport.config.ssl.SslCredentials;
import org.thingsboard.server.transport.lwm2m.config.LwM2MSecureServerConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
@ -36,15 +36,15 @@ public class LwM2MServiceImpl implements LwM2MService {
private final LwM2MTransportBootstrapConfig bootstrapConfig;
@Override
public ServerSecurityConfig getServerSecurityInfo(boolean bootstrapServer) {
ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig);
public LwM2MServerSecurityConfig getServerSecurityInfo(boolean bootstrapServer) {
LwM2MServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig);
result.setBootstrapServerIs(bootstrapServer);
return result;
}
private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig) {
ServerSecurityConfig bsServ = new ServerSecurityConfig();
bsServ.setServerId(serverConfig.getId());
private LwM2MServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig) {
LwM2MServerSecurityConfig bsServ = new LwM2MServerSecurityConfig();
bsServ.setShortServerId(serverConfig.getId());
bsServ.setHost(serverConfig.getHost());
bsServ.setPort(serverConfig.getPort());
bsServ.setSecurityHost(serverConfig.getSecureHost());

2
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsService.java

@ -15,10 +15,8 @@
*/
package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.common.data.security.DeviceCredentials;
public interface DeviceCredentialsService {

3
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/AbstractLwM2MBootstrapServerCredential.java

@ -20,11 +20,10 @@ import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
@Getter
@Setter
public abstract class AbstractLwM2MBootstrapServerCredential extends ServerSecurityConfig implements LwM2MBootstrapServerCredential {
public abstract class AbstractLwM2MBootstrapServerCredential extends LwM2MServerSecurityConfig implements LwM2MBootstrapServerCredential {
@JsonIgnore
public byte[] getDecodedCServerPublicKey() {

27
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerConfig.java

@ -1,27 +0,0 @@
/**
* 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.common.data.device.profile.lwm2m.bootstrap;
import lombok.Data;
@Data
public class LwM2MBootstrapServerConfig {
private Integer shortId = 123;
private Integer lifetime = 300;
private Integer defaultMinPeriod = 1;
private boolean notifIfDisabled = true;
private String binding = "U";
}

10
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServersConfiguration.java

@ -17,15 +17,11 @@ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap;
import lombok.Data;
import java.util.List;
@Data
public class LwM2MBootstrapServersConfiguration {
//TODO
// List <LwM2MBootstrapServersConfiguration> LwM2MBootstrapServersConfigurations;
// LwM2MBootstrapServersConfiguration: Integer shortId, LwM2MBootstrapServerConfig serverConfig; LwM2MBootstrapServerCredential serverSecurity.
private LwM2MBootstrapServerConfig servers;
private LwM2MBootstrapServerCredential lwm2mServer;
private LwM2MBootstrapServerCredential bootstrapServer;
List<LwM2MBootstrapServerCredential> serverConfiguration;
}

63
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java

@ -0,0 +1,63 @@
/**
* 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.common.data.device.profile.lwm2m.bootstrap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel
@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" +
"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)
protected boolean bootstrapServerIs = false;
@ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", readOnly = true)
protected String host;
@ApiModelProperty(position = 4, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", readOnly = true)
protected Integer port;
@ApiModelProperty(position = 5, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", readOnly = true)
protected String securityHost;
@ApiModelProperty(position = 6, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", readOnly = true)
protected Integer securityPort;
@ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", readOnly = true)
protected Integer clientHoldOffTime = 1;
@ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" +
"+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", readOnly = true)
protected String serverPublicKey;
@ApiModelProperty(position = 9, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", readOnly = true)
Integer bootstrapServerAccountTimeout = 0;
/** 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" +
"If this Resource doesn’t 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" +
"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" +
"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";
}

44
common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/ServerSecurityConfig.java

@ -1,44 +0,0 @@
/**
* 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.common.data.lwm2m;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel
@Data
public class ServerSecurityConfig {
@ApiModelProperty(position = 1, value = "Is Bootstrap Server or Lwm2m Server", example = "true or false", readOnly = true)
protected boolean bootstrapServerIs = true;
@ApiModelProperty(position = 2, value = "Host for 'No Security' mode", example = "0.0.0.0", readOnly = true)
protected String host;
@ApiModelProperty(position = 3, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", readOnly = true)
protected Integer port;
@ApiModelProperty(position = 4, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", readOnly = true)
protected String securityHost;
@ApiModelProperty(position = 5, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", readOnly = true)
protected Integer securityPort;
@ApiModelProperty(position = 6, value = "Server short Id", example = "111", readOnly = true)
protected Integer serverId = 111;
@ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", readOnly = true)
protected Integer clientHoldOffTime = 1;
@ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" +
"+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", readOnly = true)
protected String serverPublicKey;
@ApiModelProperty(position = 9, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", readOnly = true)
Integer bootstrapServerAccountTimeout = 0;
}

11
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java

@ -23,12 +23,18 @@ import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredential;
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.List;
@Data
public class LwM2MBootstrapConfig implements Serializable {
List<LwM2MBootstrapServerCredential> serversConfiguration;
LwM2MBootstrapClientCredential bootstrapClientCredential;
/*
interface BootstrapSecurityConfig
servers: BootstrapServersSecurityConfig,
@ -68,6 +74,11 @@ public class LwM2MBootstrapConfig implements Serializable {
@Setter
private LwM2MServerBootstrap lwm2mServer;
public LwM2MBootstrapConfig(List<LwM2MBootstrapServerCredential> serversConfiguration, LwM2MBootstrapClientCredential bootstrapClientCredential) {
this.serversConfiguration = serversConfiguration;
this.bootstrapClientCredential = bootstrapClientCredential;
}
@JsonIgnore
public BootstrapConfig getLwM2MBootstrapConfig() {
BootstrapConfig configBs = new BootstrapConfig();

10
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java

@ -419,8 +419,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
}
} else if (transportConfiguration instanceof Lwm2mDeviceProfileTransportConfiguration) {
LwM2MBootstrapServersConfiguration lwM2MBootstrapServersConfiguration = ((Lwm2mDeviceProfileTransportConfiguration) transportConfiguration).getBootstrap();
validateLwm2mServersCredentialOfBootstrapForClient(lwM2MBootstrapServersConfiguration.getBootstrapServer(), "Bootstrap Server");
validateLwm2mServersCredentialOfBootstrapForClient(lwM2MBootstrapServersConfiguration.getLwm2mServer(), "LwM2M Server");
for (LwM2MBootstrapServerCredential bootstrapServerCredential : lwM2MBootstrapServersConfiguration.getServerConfiguration()) {
validateLwm2mServersCredentialOfBootstrapForClient(bootstrapServerCredential);
}
}
List<DeviceProfileAlarm> profileAlarms = deviceProfile.getProfileData().getAlarms();
@ -704,13 +705,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
}
}
private void validateLwm2mServersCredentialOfBootstrapForClient(LwM2MBootstrapServerCredential bootstrapServerConfig, String server) {
private void validateLwm2mServersCredentialOfBootstrapForClient(LwM2MBootstrapServerCredential bootstrapServerConfig) {
String server;
switch (bootstrapServerConfig.getSecurityMode()) {
case NO_SEC:
case PSK:
break;
case RPK:
RPKLwM2MBootstrapServerCredential rpkServerCredentials = (RPKLwM2MBootstrapServerCredential) bootstrapServerConfig;
server = rpkServerCredentials.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server";
if (StringUtils.isEmpty(rpkServerCredentials.getServerPublicKey())) {
throw new DeviceCredentialsValidationException(server + " RPK public key must be specified!");
}
@ -724,6 +727,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
break;
case X509:
X509LwM2MBootstrapServerCredential x509ServerCredentials = (X509LwM2MBootstrapServerCredential) bootstrapServerConfig;
server = x509ServerCredentials.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server";
if (StringUtils.isEmpty(x509ServerCredentials.getServerPublicKey())) {
throw new DeviceCredentialsValidationException(server + " X509 public key must be specified!");
}

Loading…
Cancel
Save