Browse Source
* lwm2m: back transport newKey start * lwm2m: back transport newKey start1 * lwm2m: back transport newKey fix bug save * lwm2m: back transport newKey test All security - ok * lwm2m: back transport newKey fix bug updateAttrSharedpull/4291/head
committed by
GitHub
14 changed files with 215 additions and 405 deletions
@ -0,0 +1,23 @@ |
|||
/** |
|||
* 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; |
|||
|
|||
public interface LwM2mConstants { |
|||
|
|||
String LWM2M_SEPARATOR_PATH = "/"; |
|||
String LWM2M_SEPARATOR_KEY = "_"; |
|||
String LWM2M_SEPARATOR_SEARCH_TEXT = ":"; |
|||
} |
|||
@ -1,251 +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.transport.lwm2m.server.store; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.eclipse.leshan.core.util.Hex; |
|||
import org.eclipse.leshan.server.registration.Registration; |
|||
import org.eclipse.leshan.server.security.InMemorySecurityStore; |
|||
import org.eclipse.leshan.server.security.SecurityInfo; |
|||
import org.eclipse.leshan.server.security.SecurityStoreListener; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.thingsboard.server.common.data.DeviceProfile; |
|||
import org.thingsboard.server.gen.transport.TransportProtos; |
|||
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; |
|||
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
|||
import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
|||
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
|||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
|||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
|||
import org.thingsboard.server.transport.lwm2m.utils.TypeServer; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.UUID; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
import java.util.concurrent.locks.Lock; |
|||
import java.util.concurrent.locks.ReadWriteLock; |
|||
import java.util.concurrent.locks.ReentrantReadWriteLock; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; |
|||
|
|||
@Slf4j |
|||
//@Service("LwM2mInMemorySecurityStore")
|
|||
//@TbLwM2mTransportComponent
|
|||
@Deprecated |
|||
public class LwM2mInMemorySecurityStore extends InMemorySecurityStore { |
|||
private static final boolean INFOS_ARE_COMPROMISED = false; |
|||
|
|||
// lock for the two maps
|
|||
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); |
|||
private final Lock readLock = readWriteLock.readLock(); |
|||
private final Lock writeLock = readWriteLock.writeLock(); |
|||
private final Map<String /** registrationId */, LwM2mClient> sessions = new ConcurrentHashMap<>(); |
|||
private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); |
|||
private SecurityStoreListener listener; |
|||
|
|||
@Autowired |
|||
LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; |
|||
|
|||
/** |
|||
* Start after DefaultAuthorizer or LwM2mPskStore |
|||
* @param endPoint - |
|||
* @return SecurityInfo |
|||
*/ |
|||
@Override |
|||
public SecurityInfo getByEndpoint(String endPoint) { |
|||
readLock.lock(); |
|||
try { |
|||
String registrationId = this.getRegistrationId(endPoint, null); |
|||
return (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ? |
|||
sessions.get(registrationId).getSecurityInfo() : this.addLwM2MClientToSession(endPoint); |
|||
} finally { |
|||
readLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Start after LwM2mPskStore |
|||
* @param identity - |
|||
* @return SecurityInfo |
|||
*/ |
|||
@Override |
|||
public SecurityInfo getByIdentity(String identity) { |
|||
readLock.lock(); |
|||
try { |
|||
String integrationId = this.getRegistrationId(null, identity); |
|||
return (integrationId != null) ? sessions.get(integrationId).getSecurityInfo() : this.addLwM2MClientToSession(identity); |
|||
} finally { |
|||
readLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public Collection<SecurityInfo> getAll() { |
|||
readLock.lock(); |
|||
try { |
|||
return this.sessions.values().stream().map(LwM2mClient::getSecurityInfo).collect(Collectors.toUnmodifiableList()); |
|||
} finally { |
|||
readLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Removed registration Client from sessions and listener |
|||
* @param registrationId if Client |
|||
*/ |
|||
public void delRemoveSessionAndListener(String registrationId) { |
|||
writeLock.lock(); |
|||
try { |
|||
LwM2mClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null; |
|||
if (lwM2MClient != null) { |
|||
if (listener != null) { |
|||
listener.securityInfoRemoved(INFOS_ARE_COMPROMISED, lwM2MClient.getSecurityInfo()); |
|||
} |
|||
sessions.remove(registrationId); |
|||
} |
|||
} finally { |
|||
writeLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void setListener(SecurityStoreListener listener) { |
|||
this.listener = listener; |
|||
} |
|||
|
|||
public LwM2mClient getLwM2MClient(String endPoint, String identity) { |
|||
Map.Entry<String, LwM2mClient> modelClients = endPoint != null ? |
|||
this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) : |
|||
this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null); |
|||
return modelClients != null ? modelClients.getValue() : null; |
|||
} |
|||
|
|||
public LwM2mClient getLwM2MClientWithReg(Registration registration, String registrationId) { |
|||
return registrationId != null ? |
|||
this.sessions.get(registrationId) : |
|||
this.sessions.containsKey(registration.getId()) ? |
|||
this.sessions.get(registration.getId()) : |
|||
this.sessions.get(registration.getEndpoint()); |
|||
} |
|||
|
|||
public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) { |
|||
return this.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue(); |
|||
} |
|||
|
|||
/** |
|||
* Update in sessions (LwM2MClient for key registration_Id) after starting registration LwM2MClient in LwM2MTransportServiceImpl |
|||
* Remove from sessions LwM2MClient with key registration_Endpoint |
|||
* @param registration - |
|||
* @return LwM2MClient after adding it to session |
|||
*/ |
|||
public LwM2mClient updateInSessionsLwM2MClient(Registration registration) { |
|||
writeLock.lock(); |
|||
try { |
|||
if (this.sessions.get(registration.getEndpoint()) == null) { |
|||
this.addLwM2MClientToSession(registration.getEndpoint()); |
|||
} |
|||
LwM2mClient lwM2MClient = this.sessions.get(registration.getEndpoint()); |
|||
lwM2MClient.setRegistration(registration); |
|||
// lwM2MClient.getAttributes().putAll(registration.getAdditionalRegistrationAttributes());
|
|||
this.sessions.remove(registration.getEndpoint()); |
|||
this.sessions.put(registration.getId(), lwM2MClient); |
|||
return lwM2MClient; |
|||
} finally { |
|||
writeLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
private String getRegistrationId(String endPoint, String identity) { |
|||
List<String> registrationIds = (endPoint != null) ? |
|||
this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).map(Map.Entry::getKey).collect(Collectors.toList()) : |
|||
this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(Map.Entry::getKey).collect(Collectors.toList()); |
|||
return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null; |
|||
} |
|||
|
|||
public Registration getByRegistration(String registrationId) { |
|||
return this.sessions.get(registrationId).getRegistration(); |
|||
} |
|||
|
|||
/** |
|||
* Add new LwM2MClient to session |
|||
* @param identity- |
|||
* @return SecurityInfo. If error - SecurityInfoError |
|||
* and log: |
|||
* - FORBIDDEN - if there is no authorization |
|||
* - profileUuid - if the device does not have a profile |
|||
* - device - if the thingsboard does not have a device with a name equal to the identity |
|||
*/ |
|||
private SecurityInfo addLwM2MClientToSession(String identity) { |
|||
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT); |
|||
if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
|||
UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; |
|||
if (store.getSecurityInfo() != null && profileUuid != null) { |
|||
String endpoint = store.getSecurityInfo().getEndpoint(); |
|||
sessions.put(endpoint, new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID())); |
|||
} else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) { |
|||
sessions.put(identity, new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID())); |
|||
} else { |
|||
log.error("Registration failed: FORBIDDEN/profileUuid/device [{}] , endpointId: [{}]", profileUuid, identity); |
|||
/** |
|||
* Return Error securityInfo |
|||
*/ |
|||
byte[] preSharedKey = Hex.decodeHex("0A0B".toCharArray()); |
|||
SecurityInfo infoError = SecurityInfo.newPreSharedKeyInfo("error", "error_identity", preSharedKey); |
|||
return infoError; |
|||
} |
|||
} |
|||
return store.getSecurityInfo(); |
|||
} |
|||
|
|||
public Map<String, LwM2mClient> getSession(UUID sessionUuId) { |
|||
return this.sessions.entrySet().stream() |
|||
.filter(e -> e.getValue().getSessionId().equals(sessionUuId)) |
|||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); |
|||
} |
|||
|
|||
public Map<String, LwM2mClient> getSessions() { |
|||
return this.sessions; |
|||
} |
|||
|
|||
public Map<UUID, LwM2mClientProfile> getProfiles() { |
|||
return this.profiles; |
|||
} |
|||
|
|||
public LwM2mClientProfile getProfile(UUID profileUuId) { |
|||
return this.profiles.get(profileUuId); |
|||
} |
|||
|
|||
public LwM2mClientProfile getProfile(String registrationId) { |
|||
UUID profileUUid = this.getSessions().get(registrationId).getProfileId(); |
|||
return this.getProfiles().get(profileUUid); |
|||
} |
|||
|
|||
public Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles) { |
|||
return this.profiles = profiles; |
|||
} |
|||
|
|||
public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) { |
|||
LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandler.getLwM2MClientProfileFromThingsboard(deviceProfile); |
|||
if (lwM2MClientProfile != null) { |
|||
profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue