Browse Source

Merge pull request #5436 from thingsboard/lwm2m_credentials_update_registration_no_sec_as_psk

[3.3.2]Lwm2m fix bug validate credentials per each update registration
pull/5454/head
Andrew Shvayka 5 years ago
committed by GitHub
parent
commit
f71d9ac2f1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java
  2. 13
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java
  3. 2
      application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java
  4. 8
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java
  5. 13
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbInMemorySecurityStore.java
  6. 9
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java
  7. 12
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java

3
application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java

@ -123,7 +123,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
protected LwM2MTestClient client; protected LwM2MTestClient client;
private final LwM2MBootstrapCredentials defaultBootstrapCredentials; private final LwM2MBootstrapCredentials defaultBootstrapCredentials;
private String[] resources; private String[] resources;
private String endpoint; protected String endpoint;
public AbstractLwM2MIntegrationTest() { public AbstractLwM2MIntegrationTest() {
this.defaultBootstrapCredentials = new LwM2MBootstrapCredentials(); this.defaultBootstrapCredentials = new LwM2MBootstrapCredentials();
@ -238,7 +238,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest
deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials)); deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials));
doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk());
Thread.sleep(1000);
return device; return device;
} }

13
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java

@ -24,6 +24,7 @@ import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate; import java.util.function.Predicate;
import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL; import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL;
@ -52,7 +53,6 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
protected String RPC_TRANSPORT_CONFIGURATION; protected String RPC_TRANSPORT_CONFIGURATION;
protected static final String ENDPOINT_RPC = "deviceEndpointRpc";
protected ScheduledExecutorService executor; protected ScheduledExecutorService executor;
protected TbTestWebSocketClient wsClient; protected TbTestWebSocketClient wsClient;
protected String deviceId; protected String deviceId;
@ -72,19 +72,18 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
protected String objectIdVer_19; protected String objectIdVer_19;
protected String objectIdVer_50 = "/50"; protected String objectIdVer_50 = "/50";
protected String objectIdVer_3303; protected String objectIdVer_3303;
protected static AtomicInteger endpointSequence = new AtomicInteger();
public AbstractRpcLwM2MIntegrationTest(){ public AbstractRpcLwM2MIntegrationTest(){
setResources(resources); setResources(resources);
setEndpoint(ENDPOINT_RPC);
} }
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
setEndpoint("deviceEndpointRpc" + endpointSequence.incrementAndGet());
init(); init();
createNewClient (SECURITY, COAP_CONFIG, true); createNewClient (SECURITY, COAP_CONFIG, true);
Thread.sleep(1000);
expectedObjects = ConcurrentHashMap.newKeySet(); expectedObjects = ConcurrentHashMap.newKeySet();
expectedObjectIdVers = ConcurrentHashMap.newKeySet(); expectedObjectIdVers = ConcurrentHashMap.newKeySet();
expectedInstances = ConcurrentHashMap.newKeySet(); expectedInstances = ConcurrentHashMap.newKeySet();
@ -179,14 +178,10 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
"}"; "}";
createDeviceProfile(RPC_TRANSPORT_CONFIGURATION); createDeviceProfile(RPC_TRANSPORT_CONFIGURATION);
Thread.sleep(1000); NoSecClientCredentials credentials = createNoSecClientCredentials(endpoint);
NoSecClientCredentials credentials = createNoSecClientCredentials(ENDPOINT_RPC);
final Device device = createDevice(credentials); final Device device = createDevice(credentials);
deviceId = device.getId().getId().toString(); deviceId = device.getId().getId().toString();
Thread.sleep(1000);
client.start(); client.start();
} }

2
application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java

@ -121,7 +121,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes
ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class);
assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText());
String actualValues = rpcActualResult.get("error").asText(); String actualValues = rpcActualResult.get("error").asText();
String expected = "Format value is bad. Value for this Multi-Instance Resource must be in Json format!"; String expected = "Value of Multi-Instance Resource must be in Json format!";
assertTrue(actualValues.contains(expected)); assertTrue(actualValues.contains(expected));
} }

8
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.secure;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.core.request.UplinkRequest; import org.eclipse.leshan.core.request.UplinkRequest;
import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.registration.Registration;
@ -30,6 +31,8 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore;
import java.util.Arrays;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@TbLwM2mTransportComponent @TbLwM2mTransportComponent
@ -61,6 +64,11 @@ public class TbLwM2MAuthorizer implements Authorizer {
if (securityStore != null) { if (securityStore != null) {
try { try {
expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint());
if (expectedSecurityInfo != null && expectedSecurityInfo.usePSK() && expectedSecurityInfo.getEndpoint().equals(SecurityMode.NO_SEC.toString())
&& expectedSecurityInfo.getIdentity().equals(SecurityMode.NO_SEC.toString())
&& Arrays.equals(SecurityMode.NO_SEC.toString().getBytes(), expectedSecurityInfo.getPreSharedKey())) {
expectedSecurityInfo = null;
}
} catch (LwM2MAuthException e) { } catch (LwM2MAuthException e) {
log.info("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint()); log.info("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint());
return null; return null;

13
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbInMemorySecurityStore.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.transport.lwm2m.server.store; package org.thingsboard.server.transport.lwm2m.server.store;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
@ -48,9 +49,15 @@ public class TbInMemorySecurityStore implements TbEditableSecurityStore {
readLock.lock(); readLock.lock();
try { try {
TbLwM2MSecurityInfo securityInfo = securityByEp.get(endpoint); TbLwM2MSecurityInfo securityInfo = securityByEp.get(endpoint);
if (securityInfo != null) { if (securityInfo != null ) {
return securityInfo.getSecurityInfo(); if (SecurityMode.NO_SEC.equals(securityInfo.getSecurityMode())) {
} else { return SecurityInfo.newPreSharedKeyInfo(SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString(),
SecurityMode.NO_SEC.toString().getBytes());
} else {
return securityInfo.getSecurityInfo();
}
}
else {
return null; return null;
} }
} finally { } finally {

9
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.transport.lwm2m.server.store; package org.thingsboard.server.transport.lwm2m.server.store;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.nustaq.serialization.FSTConfiguration; import org.nustaq.serialization.FSTConfiguration;
@ -49,7 +50,13 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore {
if (data == null || data.length == 0) { if (data == null || data.length == 0) {
return null; return null;
} else { } else {
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo(); if (SecurityMode.NO_SEC.equals(((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityMode())) {
return SecurityInfo.newPreSharedKeyInfo(SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString(),
SecurityMode.NO_SEC.toString().getBytes());
}
else {
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
}
} }
} finally { } finally {
if (lock != null) { if (lock != null) {

12
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java

@ -16,12 +16,14 @@
package org.thingsboard.server.transport.lwm2m.server.store; package org.thingsboard.server.transport.lwm2m.server.store;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
import org.eclipse.leshan.server.security.SecurityInfo; 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 java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -46,11 +48,21 @@ public class TbLwM2mSecurityStore implements TbMainSecurityStore {
return securityStore.getTbLwM2MSecurityInfoByEndpoint(endpoint); return securityStore.getTbLwM2MSecurityInfoByEndpoint(endpoint);
} }
/**
* @param endpoint
* @return : If SecurityMode == NO_SEC:
* return SecurityInfo.newPreSharedKeyInfo(SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString(),
* SecurityMode.NO_SEC.toString().getBytes());
*/
@Override @Override
public SecurityInfo getByEndpoint(String endpoint) { public SecurityInfo getByEndpoint(String endpoint) {
SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint); SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint);
if (securityInfo == null) { if (securityInfo == null) {
securityInfo = fetchAndPutSecurityInfo(endpoint); securityInfo = fetchAndPutSecurityInfo(endpoint);
} else if (securityInfo.usePSK() && securityInfo.getEndpoint().equals(SecurityMode.NO_SEC.toString())
&& securityInfo.getIdentity().equals(SecurityMode.NO_SEC.toString())
&& Arrays.equals(SecurityMode.NO_SEC.toString().getBytes(), securityInfo.getPreSharedKey())) {
return null;
} }
return securityInfo; return securityInfo;
} }

Loading…
Cancel
Save