From e8543f39d58528e20119e42ca19da6f25eb7250e Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Tue, 24 Jan 2023 16:37:05 +0200 Subject: [PATCH] Fix CacheKey toString and validation logs --- .../transport/DefaultTransportApiService.java | 4 +-- common/cluster-api/src/main/proto/queue.proto | 1 + .../server/common/data/DeviceProfile.java | 8 ++--- .../mqtt/MqttSslHandlerProvider.java | 6 ++-- .../transport/mqtt/MqttTransportHandler.java | 2 +- .../dao/device/DeviceProfileCacheKey.java | 8 +++-- .../dao/device/DeviceProfileEvictEvent.java | 1 + .../dao/device/DeviceProfileServiceImpl.java | 31 ++++++++++++++----- .../validator/DeviceProfileDataValidator.java | 13 ++++---- 9 files changed, 46 insertions(+), 28 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 0bf0ff8035..24f6de76d7 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -258,8 +258,7 @@ public class DefaultTransportApiService implements TransportApiService { } DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileByCertificateHash(certificateHash); if (deviceProfile != null) { - String deviceCN = extractDeviceNameFromCNByRegEx(SslUtil.parseCommonName(chain.get(0)), deviceProfile.getCertificateRegexPattern()); - String deviceName = extractDeviceNameFromCNByRegEx(deviceCN, deviceProfile.getCertificateRegexPattern()); + String deviceName = extractDeviceNameFromCNByRegEx(SslUtil.parseCommonName(chain.get(0)), deviceProfile.getCertificateRegexPattern()); Device device = deviceService.findDeviceByTenantIdAndName(deviceProfile.getTenantId(), deviceName); if (device != null) { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId()); @@ -275,7 +274,6 @@ public class DefaultTransportApiService implements TransportApiService { deviceCredentials = updateDeviceCredentials(savedDevice.getTenantId(), deviceCredentials, updateDeviceCertificateValue, updateDeviceCertificateHash, credentialsType); return getDeviceInfo(deviceCredentials); } - } } } catch (CertificateEncodingException e) { diff --git a/common/cluster-api/src/main/proto/queue.proto b/common/cluster-api/src/main/proto/queue.proto index b9741429f7..9f62eca36b 100644 --- a/common/cluster-api/src/main/proto/queue.proto +++ b/common/cluster-api/src/main/proto/queue.proto @@ -422,6 +422,7 @@ message CredentialsDataProto { ValidateDeviceTokenRequestMsg validateDeviceTokenRequestMsg = 1; ValidateDeviceX509CertRequestMsg validateDeviceX509CertRequestMsg = 2; ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 3; + ValidateOrCreateDeviceX509CertRequestMsg validateOrCreateDeviceX509CertRequestMsg = 4; } message ProvisionDeviceRequestMsg { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index b9b1053d99..e226261227 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -66,13 +66,13 @@ public class DeviceProfile extends SearchTextBased implements H private DeviceTransportType transportType; @ApiModelProperty(position = 15, value = "Provisioning strategy.") private DeviceProfileProvisionType provisionType; - @ApiModelProperty(position = 16, value = "CA certificate value. ") + @ApiModelProperty(position = 18, value = "CA certificate value. ") private String certificateValue; - @ApiModelProperty(position = 17, value = "CA certificate hash. ") + @ApiModelProperty(position = 19, value = "CA certificate hash. ") private String certificateHash; - @ApiModelProperty(position = 18, value = "Regex to fetch deviceName from CN. ") + @ApiModelProperty(position = 20, value = "Regex to fetch deviceName from CN. ") private String certificateRegexPattern; - @ApiModelProperty(position = 19, value = "Allow to create new devices by x509 provision strategy. ") + @ApiModelProperty(position = 21, value = "Allow to create new devices by x509 provision strategy. ") private boolean allowCreateNewDevicesByX509Strategy; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index 67b48464c8..3224556e09 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.mqtt; import io.netty.handler.ssl.SslHandler; import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.units.qual.C; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; @@ -161,14 +160,13 @@ public class MqttSslHandlerProvider { @Override public void onError(Throwable e) { - // to fix this error, cuz no one can understand this ... - log.error(e.getMessage(), e); + log.trace("Failed to process certificate chain: {}", certificateChain, e); latch.countDown(); } }); latch.await(10, TimeUnit.SECONDS); if (!clientDeviceCertValue.equals(credentialsBodyHolder[0])) { - throw new CertificateException("Invalid Certificate's chain"); + throw new CertificateException("Invalid Certificate's chain. Cannot find such device credentials."); } } catch (CertificateEncodingException | InterruptedException e) { log.error(e.getMessage(), e); diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 813a6f1ed2..00d318544f 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -877,7 +877,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private X509Certificate getX509Certificate() { try { Certificate[] certChain = sslHandler.engine().getSession().getPeerCertificates(); - if (certChain.length > 1) { + if (certChain.length > 0) { return (X509Certificate) certChain[0]; } } catch (SSLPeerUnverifiedException e) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java index 228720f0e7..fb44092bd4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileCacheKey.java @@ -56,14 +56,18 @@ public class DeviceProfileCacheKey implements Serializable { return new DeviceProfileCacheKey(tenantId, null, null, null, true); } + /** + * IMPORTANT: Method toString() has to return unique value, if you add additional field to this class, please also refactor toString(). + */ @Override public String toString() { if (deviceProfileId != null) { return deviceProfileId.toString(); } else if (defaultProfile) { return tenantId.toString(); - } else { - return tenantId + "_" + name; + } else if (certificateHash != null) { + return certificateHash; } + return tenantId + "_" + name; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileEvictEvent.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileEvictEvent.java index b5b4b27a6b..acd34ff8e5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileEvictEvent.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileEvictEvent.java @@ -27,5 +27,6 @@ public class DeviceProfileEvictEvent { private final String oldName; private final DeviceProfileId deviceProfileId; private final boolean defaultProfile; + private final String certificateHash; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index 8cd08739b3..ffa25d16d6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -98,6 +98,9 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService 1; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java index 0bf618e367..d737a48a9b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java @@ -138,7 +138,7 @@ public class DeviceProfileDataValidator extends AbstractHasOtaPackageValidator rootCa = new HashSet<>(); + boolean getRootCAFromJavaCacerts(String deviceProfileHash) { try { String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar); FileInputStream is = new FileInputStream(filename); @@ -408,12 +407,14 @@ public class DeviceProfileDataValidator extends AbstractHasOtaPackageValidator