From ed3fd4502604322c720debddcb23d88257911b3b Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Thu, 28 Sep 2023 16:56:54 -0400 Subject: [PATCH 01/33] feat: initial implimentation of tls backend --- .../java/org/eclipse/kura/net/IP6Address.java | 2 +- kura/org.eclipse.kura.nm/META-INF/MANIFEST.MF | 2 + .../OSGI-INF/networkConfigurationService.xml | 1 + .../NMConfigurationServiceImpl.java | 97 +++++++++++++++++-- .../nm/configuration/NMSettingsConverter.java | 54 ++++++++--- .../monitor/DhcpServerMonitor.java | 2 +- .../web/client/ui/network/Tab8021xUi.java | 9 +- .../kura/web/client/ui/network/TabIp4Ui.java | 1 - 8 files changed, 133 insertions(+), 35 deletions(-) diff --git a/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java b/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java index f83bf988c4..445968e9bb 100644 --- a/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java +++ b/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java @@ -36,7 +36,7 @@ public class IP6Address extends IPAddress { * @since 2.6 */ public static IP6Address getDefaultAddress() throws UnknownHostException { - return (IP6Address) IPAddress.parseHostAddress("::"); + return (IP6Address) IPAddress.parseHostAddress("::/0"); } /** diff --git a/kura/org.eclipse.kura.nm/META-INF/MANIFEST.MF b/kura/org.eclipse.kura.nm/META-INF/MANIFEST.MF index 775bcf1ddb..260dfed1df 100644 --- a/kura/org.eclipse.kura.nm/META-INF/MANIFEST.MF +++ b/kura/org.eclipse.kura.nm/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Import-Package: org.apache.commons.io;version="2.4.0", org.eclipse.kura.core.net.modem;version="[1.0,2.0)", org.eclipse.kura.core.net.util;version="[1.0,2.0)", org.eclipse.kura.core.util;version="[1.0,2.0)", + org.eclipse.kura.core.keystore.util;version="[1.0,2.0)", org.eclipse.kura.crypto;version="[1.1,2.0)", org.eclipse.kura.executor;version="[1.0,2.0)", org.eclipse.kura.internal.linux.net.dns;version="[1.0,2.0)", @@ -35,6 +36,7 @@ Import-Package: org.apache.commons.io;version="2.4.0", org.eclipse.kura.net.status.vlan;version="[1.0,2.0)", org.eclipse.kura.net.wifi;version="[2.4,3.0]", org.eclipse.kura.usb;version="[1.0,2.0)", + org.eclipse.kura.security.keystore;version="[1.0,2.0)", org.osgi.framework;version="1.5.0", org.osgi.service.component;version="1.2.0", org.osgi.service.event;version="1.3.0", diff --git a/kura/org.eclipse.kura.nm/OSGI-INF/networkConfigurationService.xml b/kura/org.eclipse.kura.nm/OSGI-INF/networkConfigurationService.xml index 83de1761ea..afe926ff28 100644 --- a/kura/org.eclipse.kura.nm/OSGI-INF/networkConfigurationService.xml +++ b/kura/org.eclipse.kura.nm/OSGI-INF/networkConfigurationService.xml @@ -24,4 +24,5 @@ + diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 167856e1af..24aa65b6de 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -13,6 +13,10 @@ package org.eclipse.kura.nm.configuration; import java.net.UnknownHostException; +import java.security.KeyStore.PrivateKeyEntry; +import java.security.KeyStore.TrustedCertificateEntry; +import java.security.PrivateKey; +import java.security.cert.Certificate; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -25,9 +29,10 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; - +import org.eclipse.kura.KuraErrorCode; import org.eclipse.kura.KuraException; import org.eclipse.kura.configuration.ComponentConfiguration; +import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.configuration.Password; import org.eclipse.kura.configuration.SelfConfiguringComponent; import org.eclipse.kura.crypto.CryptoService; @@ -45,6 +50,7 @@ import org.eclipse.kura.nm.configuration.monitor.DnsServerMonitor; import org.eclipse.kura.nm.configuration.writer.DhcpServerConfigWriter; import org.eclipse.kura.nm.configuration.writer.FirewallNatConfigWriter; +import org.eclipse.kura.security.keystore.KeystoreService; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.osgi.service.component.ComponentContext; @@ -61,12 +67,11 @@ public class NMConfigurationServiceImpl implements SelfConfiguringComponent { private static final String MODIFIED_INTERFACE_NAMES = "modified.interface.names"; private static final String MODEM_PORT_REGEX = "^\\d+-\\d+"; private static final Pattern PPP_INTERFACE = Pattern.compile("ppp\\d+"); - - private static final List SUPPORTED_NAT_INTERFACE_TYPES = Arrays.asList( - NetInterfaceType.ETHERNET, NetInterfaceType.WIFI, NetInterfaceType.MODEM, - NetInterfaceType.VLAN); - private static final List SUPPORTED_DHCP_SERVER_INTERFACE_TYPES = Arrays.asList( - NetInterfaceType.ETHERNET, NetInterfaceType.WIFI, NetInterfaceType.VLAN); + + private static final List SUPPORTED_NAT_INTERFACE_TYPES = Arrays.asList(NetInterfaceType.ETHERNET, + NetInterfaceType.WIFI, NetInterfaceType.MODEM, NetInterfaceType.VLAN); + private static final List SUPPORTED_DHCP_SERVER_INTERFACE_TYPES = Arrays + .asList(NetInterfaceType.ETHERNET, NetInterfaceType.WIFI, NetInterfaceType.VLAN); private NetworkService networkService; private DnsServerService dnsServer; @@ -74,6 +79,9 @@ public class NMConfigurationServiceImpl implements SelfConfiguringComponent { private CommandExecutorService commandExecutorService; private CryptoService cryptoService; + private Map keystoreServices = new HashMap<>(); + private KeystoreService keystoreService; + private DhcpServerMonitor dhcpServerMonitor; private DnsServerMonitor dnsServerMonitor; @@ -127,6 +135,16 @@ public void unsetCryptoService(CryptoService cryptoService) { } } + public void setKeystoreService(KeystoreService keystoreService, Map properties) { + this.keystoreServices.put((String) properties.get(ConfigurationService.KURA_SERVICE_PID), keystoreService); + } + + public void unsetKeystoreService(KeystoreService keystoreService, Map properties) { + if (this.keystoreServices.containsValue(keystoreService)) { + this.keystoreServices.remove((String) properties.get(ConfigurationService.KURA_SERVICE_PID)); + } + } + public void setDnsServerService(DnsServerService dnsServer) { this.dnsServer = dnsServer; } @@ -213,12 +231,13 @@ public synchronized void update(Map receivedProperties) { } if (NetInterfaceType.MODEM.equals(interfaceTypeProperty.get())) { setModemPppNumber(modifiedProps, interfaceName); - } + } } mergeNetworkConfigurationProperties(modifiedProps, this.networkProperties.getProperties()); decryptAndConvertPasswordProperties(modifiedProps); + decryptAndConvertCertificatesProperties(modifiedProps); this.networkProperties = new NetworkProperties(discardModifiedNetworkInterfaces(modifiedProps)); writeNetworkConfigurationSettings(modifiedProps); @@ -252,7 +271,7 @@ protected void setModemPppNumber(Map modifiedProps, String inter Integer pppNum = Integer.valueOf(this.networkService.getModemPppInterfaceName(interfaceName).substring(3)); modifiedProps.put(String.format(PREFIX + "%s.config.pppNum", interfaceName), pppNum); } - + protected void setInterfaceType(Map modifiedProps, String interfaceName, NetInterfaceType type) { modifiedProps.put(String.format(PREFIX + "%s.type", interfaceName), type.toString()); } @@ -295,6 +314,66 @@ private void decryptAndConvertPasswordProperties(Map modifiedPro } } + private void decryptAndConvertCertificatesProperties(Map modifiedProps) throws KuraException { + + for (Entry prop : modifiedProps.entrySet()) { + if (prop.getKey().contains("802-1x.keystore.pid")) { + String keystorePid = (String) prop.getValue(); + getKeystore(keystorePid); + } + } + + for (Entry prop : modifiedProps.entrySet()) { + if (prop.getKey().contains("802-1x.client-cert-name") || prop.getKey().contains("802-1x.ca-cert-name")) { + + Object value = prop.getValue(); + try { + modifiedProps.put(prop.getKey(), decryptCertificate((String) value)); + } catch (Exception e) { + logger.error("Enable to decode certificate {} from keystore.", value.toString(), e); + modifiedProps.put(prop.getKey(), value); + } + } else if (prop.getKey().contains("802-1x.private-key-name")) { + Object value = prop.getValue(); + + try { + modifiedProps.put(prop.getKey(), decryptPrivateKey((String) value)); + } catch (Exception e) { + logger.error("Enable to decode private key {} from keystore.", value.toString(), e); + modifiedProps.put(prop.getKey(), value); + } + + } + } + } + + private Certificate decryptCertificate(String certificateName) throws KuraException { + if (keystoreService.getEntry(certificateName) instanceof TrustedCertificateEntry) { + TrustedCertificateEntry cert = (TrustedCertificateEntry) keystoreService.getEntry(certificateName); + return cert.getTrustedCertificate(); + } else if (keystoreService.getEntry(certificateName) instanceof PrivateKeyEntry) { + PrivateKeyEntry cert = (PrivateKeyEntry) keystoreService.getEntry(certificateName); + return cert.getCertificate(); + } else { + throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, + String.format("Certificate %s is not expected key type or not found.", certificateName)); + } + } + + private PrivateKey decryptPrivateKey(String privateKeyName) throws KuraException { + PrivateKeyEntry key = (PrivateKeyEntry) keystoreService.getEntry(privateKeyName); + + return key.getPrivateKey(); + } + + private void getKeystore(String keystoreServicePid) { + if (this.keystoreServices.containsKey(keystoreServicePid)) { + this.keystoreService = this.keystoreServices.get(keystoreServicePid); + } else { + logger.warn("Cannot find keystore service with pid {}", keystoreServicePid); + } + } + @Override @SuppressWarnings("restriction") public synchronized ComponentConfiguration getConfiguration() throws KuraException { diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 719eefd741..4e0803bdf3 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -16,6 +16,8 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -171,15 +173,32 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map String identity = props.get(String.class, "net.interface.%s.config.802-1x.identity", deviceId); settings.put("identity", new Variant<>(identity)); - String clientCert = props.get(String.class, "net.interface.%s.config.802-1x.client-cert", deviceId); - settings.put("client-cert", new Variant<>(clientCert.getBytes(StandardCharsets.UTF_8))); + try { + Certificate clientCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.client-cert-name", + deviceId); + settings.put("client-cert", new Variant<>(clientCert.getEncoded())); + logger.info(identity + " client cert: " + clientCert.getEncoded()); + } catch (Exception e) { + logger.error("Enable to find or decode Client Certificate", e); + } + + try { + PrivateKey privateKey = props.get(PrivateKey.class, "net.interface.%s.config.802-1x.private-key-name", + deviceId); + settings.put("private-key", new Variant<>(privateKey.getEncoded())); + logger.info(identity + " private key: " + privateKey.getEncoded()); + } catch (Exception e) { + logger.error("Enable to find or decode Private Key", e); + } - String privateKey = props.get(String.class, "net.interface.%s.config.802-1x.private-key", deviceId); - settings.put("private-key", new Variant<>(privateKey.getBytes(StandardCharsets.UTF_8))); + Optional privateKeyPassword = props.getOpt(Password.class, + "net.interface.%s.config.802-1x.private-key-password", deviceId); - String privateKeyPassword = props - .get(Password.class, "net.interface.%s.config.802-1x.private-key-password", deviceId).toString(); - settings.put("private-key-password", new Variant<>(privateKeyPassword)); + if (privateKeyPassword.isPresent()) { + settings.put("private-key-password", new Variant<>(privateKeyPassword)); + } + + settings.put("private-key-password-flags", new Variant<>(new UInt32(4))); } @@ -191,9 +210,14 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p settings.put("anonymous-identity", new Variant<>(anonymousIdentity.get())); } - Optional caCert = props.getOpt(String.class, "net.interface.%s.config.802-1x.ca-cert", deviceId); - if (caCert.isPresent()) { - settings.put("ca-cert", new Variant<>(caCert.get().getBytes(StandardCharsets.UTF_8))); + try { + Optional caCert = props.getOpt(Certificate.class, + "net.interface.%s.config.802-1x.ca-cert-name", deviceId); + if (caCert.isPresent()) { + settings.put("ca-cert", new Variant<>(caCert.get().getEncoded())); + } + } catch (Exception e) { + logger.error("Enable to find or decode CA Certificate", e); } Optional caCertPassword = props.getOpt(Password.class, @@ -512,7 +536,7 @@ public static Map> buildPPPSettings(NetworkProperties props, return settings; } - + public static Map> buildVlanSettings(NetworkProperties props, String deviceId) { Map> settings = new HashMap<>(); settings.put("interface-name", new Variant<>(deviceId)); @@ -524,11 +548,9 @@ public static Map> buildVlanSettings(NetworkProperties props, settings.put("flags", new Variant<>(new UInt32(vlanFlags.orElse(1)))); DBusListType listType = new DBusListType(String.class); Optional> ingressMap = props.getOptStringList("net.interface.%s.config.vlan.ingress", deviceId); - settings.put("ingress-priority-map", new Variant<>(ingressMap - .orElse(new ArrayList()), listType)); + settings.put("ingress-priority-map", new Variant<>(ingressMap.orElse(new ArrayList()), listType)); Optional> egressMap = props.getOptStringList("net.interface.%s.config.vlan.egress", deviceId); - settings.put("egress-priority-map", new Variant<>(egressMap - .orElse(new ArrayList()), listType)); + settings.put("egress-priority-map", new Variant<>(egressMap.orElse(new ArrayList()), listType)); return settings; } @@ -552,7 +574,7 @@ public static Map> buildConnectionSettings(Optional> createConnectionSettings(String iface) { Map> connectionMap = new HashMap<>(); diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/monitor/DhcpServerMonitor.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/monitor/DhcpServerMonitor.java index 60c859655d..a60a9fb72d 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/monitor/DhcpServerMonitor.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/monitor/DhcpServerMonitor.java @@ -76,7 +76,7 @@ private void monitor() { stopDhcpServer(interfaceName); } } catch (KuraException e) { - logger.warn("Failed to chech DHCP server status for the interface " + interfaceName, e); + logger.warn("Failed to check DHCP server status for the interface " + interfaceName, e); } }); } diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java index 04889f6e0a..e02750be9d 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java @@ -327,13 +327,8 @@ public void setDirty(boolean dirty) { public void getUpdatedNetInterface(GwtNetInterfaceConfig updatedNetIf) { Gwt8021xConfig updated8021xConfig = new Gwt8021xConfig(); - if (this.username.isEnabled()) { - updated8021xConfig.setIdentity(this.username.getText()); - } - - if (this.password.isEnabled()) { - updated8021xConfig.setPassword(this.password.getText()); - } + updated8021xConfig.setIdentity(this.username.getText()); + updated8021xConfig.setPassword(this.password.getText()); updated8021xConfig.setEap(Gwt8021xEap.valueOf(this.eap.getSelectedValue())); updated8021xConfig.setInnerAuthEnum(Gwt8021xInnerAuth.valueOf(this.innerAuth.getSelectedValue())); diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java index a862abf109..f1a2cec528 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java @@ -776,7 +776,6 @@ private void refreshForm() { || VMSGS.netIPv4StatusUnmanaged().equals(this.status.getSelectedValue())) { this.dns.setEnabled(false); } - this.renew.setEnabled(false); this.configure.setSelectedIndex(this.configure.getItemText(0).equals(IPV4_MODE_DHCP_MESSAGE) ? 0 : 1); } else if (this.selectedNetIfConfig != null && this.selectedNetIfConfig.getHwTypeEnum() == GwtNetIfType.LOOPBACK) { From 6ecf82f820ea27472447dfb14ef93a9fdc8d900f Mon Sep 17 00:00:00 2001 From: G_Ivo Date: Thu, 28 Sep 2023 17:05:53 -0400 Subject: [PATCH 02/33] fix: weird formatter oddity --- .../src/main/java/org/eclipse/kura/net/IP6Address.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java b/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java index 445968e9bb..f83bf988c4 100644 --- a/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java +++ b/kura/org.eclipse.kura.api/src/main/java/org/eclipse/kura/net/IP6Address.java @@ -36,7 +36,7 @@ public class IP6Address extends IPAddress { * @since 2.6 */ public static IP6Address getDefaultAddress() throws UnknownHostException { - return (IP6Address) IPAddress.parseHostAddress("::/0"); + return (IP6Address) IPAddress.parseHostAddress("::"); } /** From d2a8f4edc99f320392a579399fe8a3185e96b832 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Fri, 29 Sep 2023 09:34:43 -0400 Subject: [PATCH 03/33] fix: removed loggers --- .../org/eclipse/kura/nm/configuration/NMSettingsConverter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 4e0803bdf3..4229c3ca54 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -177,7 +177,6 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map Certificate clientCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.client-cert-name", deviceId); settings.put("client-cert", new Variant<>(clientCert.getEncoded())); - logger.info(identity + " client cert: " + clientCert.getEncoded()); } catch (Exception e) { logger.error("Enable to find or decode Client Certificate", e); } @@ -186,7 +185,6 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map PrivateKey privateKey = props.get(PrivateKey.class, "net.interface.%s.config.802-1x.private-key-name", deviceId); settings.put("private-key", new Variant<>(privateKey.getEncoded())); - logger.info(identity + " private key: " + privateKey.getEncoded()); } catch (Exception e) { logger.error("Enable to find or decode Private Key", e); } From 24c1ad6142b993aa7d7f2dfc5fa74222bf72df43 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Fri, 29 Sep 2023 09:42:54 -0400 Subject: [PATCH 04/33] refactor: ifPresent if's changed to lamdas --- .../nm/configuration/NMSettingsConverter.java | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 4229c3ca54..9915dcc5ac 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -192,9 +192,9 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map Optional privateKeyPassword = props.getOpt(Password.class, "net.interface.%s.config.802-1x.private-key-password", deviceId); - if (privateKeyPassword.isPresent()) { - settings.put("private-key-password", new Variant<>(privateKeyPassword)); - } + privateKeyPassword.ifPresent(value -> { + settings.put("private-key-password", new Variant<>(value)); + }); settings.put("private-key-password-flags", new Variant<>(new UInt32(4))); @@ -204,25 +204,28 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p Map> settings) { Optional anonymousIdentity = props.getOpt(String.class, "net.interface.%s.config.802-1x.anonymous-identity", deviceId); - if (anonymousIdentity.isPresent()) { - settings.put("anonymous-identity", new Variant<>(anonymousIdentity.get())); - } - try { - Optional caCert = props.getOpt(Certificate.class, - "net.interface.%s.config.802-1x.ca-cert-name", deviceId); - if (caCert.isPresent()) { - settings.put("ca-cert", new Variant<>(caCert.get().getEncoded())); + anonymousIdentity.ifPresent(value -> { + settings.put("anonymous-identity", new Variant<>(value)); + }); + + Optional caCert = props.getOpt(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", + deviceId); + + caCert.ifPresent(value -> { + try { + settings.put("ca-cert", new Variant<>(value.getEncoded())); + } catch (Exception e) { + logger.error("Enable to find or decode CA Certificate", e); } - } catch (Exception e) { - logger.error("Enable to find or decode CA Certificate", e); - } + }); Optional caCertPassword = props.getOpt(Password.class, "net.interface.%s.config.802-1x.ca-cert-password", deviceId); - if (caCertPassword.isPresent()) { - settings.put("ca-cert-password", new Variant<>(caCertPassword.get().toString())); - } + + caCertPassword.ifPresent(value -> { + settings.put("ca-cert-password", new Variant<>(value.toString())); + }); } private static void create8021xMschapV2(NetworkProperties props, String deviceId, From 0d13fdcf05f0b7c9b8b6e0f6750859344ffe044d Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Fri, 29 Sep 2023 15:21:02 -0400 Subject: [PATCH 05/33] tests: update for new tls changes --- .../nm/configuration/NMSettingsConverter.java | 2 +- .../NMSettingsConverterTest.java | 83 ++++++++++++++----- 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 9915dcc5ac..1cef7db9c0 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -193,7 +193,7 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map "net.interface.%s.config.802-1x.private-key-password", deviceId); privateKeyPassword.ifPresent(value -> { - settings.put("private-key-password", new Variant<>(value)); + settings.put("private-key-password", new Variant<>(value.toString())); }); settings.put("private-key-password-flags", new Variant<>(new UInt32(4))); diff --git a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java index 8f2b4aa050..e5fba8aa39 100644 --- a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java +++ b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java @@ -16,8 +16,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -504,7 +510,8 @@ public void build8021xSettingsShouldWorkWithTtlsAndMschapV2AndOptionalParams() { givenMapWith("net.interface.wlan0.config.802-1x.eap", "Kura8021xEapTtls"); givenMapWith("net.interface.wlan0.config.802-1x.innerAuth", "Kura8021xInnerAuthMschapv2"); givenMapWith("net.interface.wlan0.config.802-1x.anonymous-identity", "anonymous-identity-test-var"); - givenMapWith("net.interface.wlan0.config.802-1x.ca-cert", "binary ca cert"); + givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-name", + buildMockedCertificateWithCert("binary ca cert")); givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-password", new Password("secure-password")); givenMapWith("net.interface.wlan0.config.802-1x.identity", "example-user-name"); givenMapWith("net.interface.wlan0.config.802-1x.password", new Password("secure-test-password-123!@#")); @@ -549,7 +556,8 @@ public void build8021xSettingsShouldWorkWithPeapAndMschapV2() { public void build8021xSettingsShouldWorkWithPeapAndMschapV2AndCertificates() { givenMapWith("net.interface.wlan0.config.802-1x.eap", "Kura8021xEapPeap"); givenMapWith("net.interface.wlan0.config.802-1x.anonymous-identity", "anonymous-identity-test-var"); - givenMapWith("net.interface.wlan0.config.802-1x.ca-cert", "binary ca cert"); + givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-name", + buildMockedCertificateWithCert("binary ca cert")); givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-password", new Password("secure-password")); givenMapWith("net.interface.wlan0.config.802-1x.innerAuth", "Kura8021xInnerAuthMschapv2"); givenMapWith("net.interface.wlan0.config.802-1x.identity", "example-user-name"); @@ -583,9 +591,12 @@ public void build8021xSettingsShouldWorkWithTls() { givenMapWith("net.interface.wlan0.config.802-1x.eap", "Kura8021xEapTls"); givenMapWith("net.interface.wlan0.config.802-1x.innerAuth", "Kura8021xInnerAuthNone"); givenMapWith("net.interface.wlan0.config.802-1x.identity", "username@email.com"); - givenMapWith("net.interface.wlan0.config.802-1x.ca-cert", "binary ca cert"); - givenMapWith("net.interface.wlan0.config.802-1x.client-cert", "binary client cert"); - givenMapWith("net.interface.wlan0.config.802-1x.private-key", "binary private key"); + givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-name", + buildMockedCertificateWithCert("binary ca cert")); + givenMapWith("net.interface.wlan0.config.802-1x.client-cert-name", + buildMockedCertificateWithCert("binary client cert")); + givenMapWith("net.interface.wlan0.config.802-1x.private-key-name", + buildMockedPrivateKeyWithKey("binary private key")); givenMapWith("net.interface.wlan0.config.802-1x.private-key-password", new Password("secure-password")); givenNetworkPropsCreatedWithTheMap(this.internetNetworkPropertiesInstanciationMap); @@ -1099,7 +1110,7 @@ public void buildPPPSettingsShouldThrowWithUnsupportedAuthType() { thenIllegalArgumentExceptionThrown(); } - + @Test public void buildVlanSettingsShouldWorkWithRequiredSettings() { givenMapWith("net.interface.eth0.30.config.vlan.parent", "eth0"); @@ -1115,7 +1126,7 @@ public void buildVlanSettingsShouldWorkWithRequiredSettings() { thenResultingMapContains("ingress-priority-map", new Variant<>(Arrays.asList(), "as").getValue()); thenResultingMapContains("egress-priority-map", new Variant<>(Arrays.asList(), "as").getValue()); } - + @Test public void buildVlanSettingsShouldWorkWithFullSettings() { givenMapWith("net.interface.eth1.40.config.vlan.parent", "eth1"); @@ -1132,29 +1143,27 @@ public void buildVlanSettingsShouldWorkWithFullSettings() { thenResultingMapContains("parent", "eth1"); thenResultingMapContains("id", new UInt32(40)); thenResultingMapContains("flags", new UInt32(3)); - thenResultingMapContains("ingress-priority-map", new Variant<>( - Arrays.asList("0:1", "4:5"), "as").getValue()); - thenResultingMapContains("egress-priority-map", new Variant<>( - Arrays.asList("2:3"), "as").getValue()); + thenResultingMapContains("ingress-priority-map", new Variant<>(Arrays.asList("0:1", "4:5"), "as").getValue()); + thenResultingMapContains("egress-priority-map", new Variant<>(Arrays.asList("2:3"), "as").getValue()); } - + @Test public void buildVlanSettingsShouldThrowWhenMissingParent() { givenMapWith("net.interface.eth0.30.config.vlan.id", 30); givenNetworkPropsCreatedWithTheMap(this.internetNetworkPropertiesInstanciationMap); whenBuildVlanSettingsIsRunWith(this.networkProperties, "eth0.30"); - + thenNoSuchElementExceptionThrown(); } - + @Test public void buildVlanSettingsShouldThrowWhenMissingVlanId() { givenMapWith("net.interface.eth0.30.config.vlan.parent", "eth0"); givenNetworkPropsCreatedWithTheMap(this.internetNetworkPropertiesInstanciationMap); whenBuildVlanSettingsIsRunWith(this.networkProperties, "eth0.30"); - + thenNoSuchElementExceptionThrown(); } @@ -1182,7 +1191,7 @@ public void buildConnectionSettingsShouldWorkWithUnsupported() { thenIllegalArgumentExceptionThrown(); } - + @Test public void buildConnectionSettingsShouldWorkWithVlan() { whenBuildConnectionSettings(Optional.empty(), "eth0.40", NMDeviceType.NM_DEVICE_TYPE_VLAN); @@ -1288,7 +1297,8 @@ public void buildSettingsShouldWorkWith8021x() { givenMapWith("net.interface.wlan0.config.802-1x.eap", "Kura8021xEapTtls"); givenMapWith("net.interface.wlan0.config.802-1x.innerAuth", "Kura8021xInnerAuthMschapv2"); givenMapWith("net.interface.wlan0.config.802-1x.anonymous-identity", "anonymous-identity-test-var"); - givenMapWith("net.interface.wlan0.config.802-1x.ca-cert", "binary ca cert"); + givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-name", + buildMockedCertificateWithCert("binary ca cert")); givenMapWith("net.interface.wlan0.config.802-1x.ca-cert-password", new Password("secure-password")); givenMapWith("net.interface.wlan0.config.802-1x.identity", "example-user-name"); givenMapWith("net.interface.wlan0.config.802-1x.password", new Password("secure-test-password-123!@#")); @@ -1556,7 +1566,7 @@ public void buildSettingsShouldWorkWithExpectedInputsEthernetAndWanIp4() { thenResultingBuildAllMapContains("connection", "interface-name", "eth0"); thenResultingBuildAllMapContains("connection", "type", "802-3-ethernet"); } - + @Test public void buildSettingsShouldWorkWithExpectedInputsVlanAndWanIp4() { givenMapWith("net.interface.myVlan.config.dhcpClient4.enabled", false); @@ -1589,10 +1599,10 @@ public void buildSettingsShouldWorkWithExpectedInputsVlanAndWanIp4() { thenResultingBuildAllMapContains("vlan", "parent", "eth0"); thenResultingBuildAllMapContains("vlan", "id", new UInt32(55)); thenResultingBuildAllMapContains("vlan", "flags", new UInt32(2)); - thenResultingBuildAllMapContains("vlan", "ingress-priority-map", new Variant<>( - Arrays.asList(), "as").getValue()); - thenResultingBuildAllMapContains("vlan", "egress-priority-map", new Variant<>( - Arrays.asList("2:3"), "as").getValue()); + thenResultingBuildAllMapContains("vlan", "ingress-priority-map", + new Variant<>(Arrays.asList(), "as").getValue()); + thenResultingBuildAllMapContains("vlan", "egress-priority-map", + new Variant<>(Arrays.asList("2:3"), "as").getValue()); } @Test @@ -2845,6 +2855,12 @@ public void givenMockConnection() { } + public void givenMockConnectionWithNullSettings() { + this.mockedConnection = Mockito.mock(Connection.class); + Mockito.when(this.mockedConnection.GetSettings()).thenReturn(null); + + } + /* * When */ @@ -2891,10 +2907,13 @@ public void whenBuild8021xSettingsIsRunWith(NetworkProperties props, String ifac try { this.resultMap = NMSettingsConverter.build8021xSettings(props, iface); } catch (NoSuchElementException e) { + e.printStackTrace(); this.hasNoSuchElementExceptionBeenThrown = true; } catch (IllegalArgumentException e) { + e.printStackTrace(); this.hasAnIllegalArgumentExceptionThrown = true; } catch (Exception e) { + e.printStackTrace(); this.hasAGenericExecptionBeenThrown = true; } } @@ -2958,7 +2977,7 @@ private void whenBuildPPPSettingsIsRunWith(NetworkProperties props, String iface this.hasAGenericExecptionBeenThrown = true; } } - + private void whenBuildVlanSettingsIsRunWith(NetworkProperties props, String iface) { try { this.resultMap = NMSettingsConverter.buildVlanSettings(props, iface); @@ -3043,4 +3062,22 @@ public Object buildAddressDataWith(String ipAddr, UInt32 prefix) { return dataVariant.getValue(); } + + public Certificate buildMockedCertificateWithCert(String certBytes) { + Certificate cert = mock(Certificate.class); + try { + when(cert.getEncoded()).thenReturn(certBytes.getBytes()); + } catch (CertificateEncodingException e) { + fail(); + } + + return cert; + } + + public PrivateKey buildMockedPrivateKeyWithKey(String keyBytes) { + PrivateKey key = mock(PrivateKey.class); + when(key.getEncoded()).thenReturn(keyBytes.getBytes()); + + return key; + } } From 0528ef639c59d223666578d17259a5baf734acd0 Mon Sep 17 00:00:00 2001 From: G_Ivo Date: Sun, 1 Oct 2023 16:42:13 -0400 Subject: [PATCH 06/33] fix: revert un-needed change --- .../java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java index f1a2cec528..6f05ef3a84 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/TabIp4Ui.java @@ -776,6 +776,8 @@ private void refreshForm() { || VMSGS.netIPv4StatusUnmanaged().equals(this.status.getSelectedValue())) { this.dns.setEnabled(false); } + this.renew.setEnabled(false); + this.configure.setSelectedIndex(this.configure.getItemText(0).equals(IPV4_MODE_DHCP_MESSAGE) ? 0 : 1); } else if (this.selectedNetIfConfig != null && this.selectedNetIfConfig.getHwTypeEnum() == GwtNetIfType.LOOPBACK) { @@ -866,4 +868,4 @@ private void initModal() { this.multipleWanWarnText.setText(MSGS.netStatusWarning()); this.wanModal.addHideHandler(evt -> this.setDirty(true)); } -} \ No newline at end of file +} From 1ff935b91b6f5fa00c084dbc6c881f88c4d8ff8b Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Mon, 2 Oct 2023 10:01:05 -0400 Subject: [PATCH 07/33] feat: added support for multiple keystores --- .../configuration/NMConfigurationServiceImpl.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 24aa65b6de..840c4649d2 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -320,12 +320,19 @@ private void decryptAndConvertCertificatesProperties(Map modifie if (prop.getKey().contains("802-1x.keystore.pid")) { String keystorePid = (String) prop.getValue(); getKeystore(keystorePid); + + String interfaceName = prop.getKey().split("\\.")[2]; + findAndDecodeCertificatesForInterface(interfaceName, modifiedProps); } } + } + private void findAndDecodeCertificatesForInterface(String interfaceName, Map modifiedProps) { for (Entry prop : modifiedProps.entrySet()) { - if (prop.getKey().contains("802-1x.client-cert-name") || prop.getKey().contains("802-1x.ca-cert-name")) { - + String clientCertString = String.format("%s.802-1x.client-cert-name", interfaceName); + String caCertString = String.format("%s.802-1x.802-1x.ca-cert-name", interfaceName); + String privateKeyString = String.format("%s.802-1x.private-key-name", interfaceName); + if (prop.getKey().contains(clientCertString) || prop.getKey().contains(caCertString)) { Object value = prop.getValue(); try { modifiedProps.put(prop.getKey(), decryptCertificate((String) value)); @@ -333,7 +340,7 @@ private void decryptAndConvertCertificatesProperties(Map modifie logger.error("Enable to decode certificate {} from keystore.", value.toString(), e); modifiedProps.put(prop.getKey(), value); } - } else if (prop.getKey().contains("802-1x.private-key-name")) { + } else if (prop.getKey().contains(privateKeyString)) { Object value = prop.getValue(); try { From d8b1478586493a7fa04fd6ba4aee0694c1f4f92e Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Mon, 2 Oct 2023 11:44:39 -0400 Subject: [PATCH 08/33] tests: removed not needed logging --- .../eclipse/kura/nm/configuration/NMSettingsConverterTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java index e5fba8aa39..237940032c 100644 --- a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java +++ b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java @@ -2907,13 +2907,10 @@ public void whenBuild8021xSettingsIsRunWith(NetworkProperties props, String ifac try { this.resultMap = NMSettingsConverter.build8021xSettings(props, iface); } catch (NoSuchElementException e) { - e.printStackTrace(); this.hasNoSuchElementExceptionBeenThrown = true; } catch (IllegalArgumentException e) { - e.printStackTrace(); this.hasAnIllegalArgumentExceptionThrown = true; } catch (Exception e) { - e.printStackTrace(); this.hasAGenericExecptionBeenThrown = true; } } From e3ea4fb1b9d2c59e77df84e0d24d3e87c63c8688 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Tue, 3 Oct 2023 14:15:57 -0400 Subject: [PATCH 09/33] fix: improved backend stability, and fixed regex --- .../NMConfigurationServiceImpl.java | 6 +++--- .../nm/configuration/NMSettingsConverter.java | 17 +++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 840c4649d2..8f978deb2f 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -329,9 +329,9 @@ private void decryptAndConvertCertificatesProperties(Map modifie private void findAndDecodeCertificatesForInterface(String interfaceName, Map modifiedProps) { for (Entry prop : modifiedProps.entrySet()) { - String clientCertString = String.format("%s.802-1x.client-cert-name", interfaceName); - String caCertString = String.format("%s.802-1x.802-1x.ca-cert-name", interfaceName); - String privateKeyString = String.format("%s.802-1x.private-key-name", interfaceName); + String clientCertString = String.format("%s.config.802-1x.client-cert-name", interfaceName); + String caCertString = String.format("%s.config.802-1x.802-1x.ca-cert-name", interfaceName); + String privateKeyString = String.format("%s.config.802-1x.private-key-name", interfaceName); if (prop.getKey().contains(clientCertString) || prop.getKey().contains(caCertString)) { Object value = prop.getValue(); try { diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 1cef7db9c0..cb65a659f9 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -202,6 +202,7 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties props, String deviceId, Map> settings) { + Optional anonymousIdentity = props.getOpt(String.class, "net.interface.%s.config.802-1x.anonymous-identity", deviceId); @@ -209,16 +210,12 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p settings.put("anonymous-identity", new Variant<>(value)); }); - Optional caCert = props.getOpt(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", - deviceId); - - caCert.ifPresent(value -> { - try { - settings.put("ca-cert", new Variant<>(value.getEncoded())); - } catch (Exception e) { - logger.error("Enable to find or decode CA Certificate", e); - } - }); + try { + Certificate caCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", deviceId); + settings.put("ca-cert", new Variant<>(caCert.getEncoded())); + } catch (Exception e) { + logger.error("Enable to find or decode CA Certificate", e); + } Optional caCertPassword = props.getOpt(Password.class, "net.interface.%s.config.802-1x.ca-cert-password", deviceId); From 66bb8ed386752714a0b83c28ba7ca388b2ef5082 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Tue, 3 Oct 2023 15:48:05 -0400 Subject: [PATCH 10/33] refactor: changed the way the keystore var is passed --- .../NMConfigurationServiceImpl.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 8f978deb2f..aec2b4225f 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -80,7 +80,6 @@ public class NMConfigurationServiceImpl implements SelfConfiguringComponent { private CryptoService cryptoService; private Map keystoreServices = new HashMap<>(); - private KeystoreService keystoreService; private DhcpServerMonitor dhcpServerMonitor; private DnsServerMonitor dnsServerMonitor; @@ -319,15 +318,21 @@ private void decryptAndConvertCertificatesProperties(Map modifie for (Entry prop : modifiedProps.entrySet()) { if (prop.getKey().contains("802-1x.keystore.pid")) { String keystorePid = (String) prop.getValue(); - getKeystore(keystorePid); String interfaceName = prop.getKey().split("\\.")[2]; - findAndDecodeCertificatesForInterface(interfaceName, modifiedProps); + findAndDecodeCertificatesForInterface(interfaceName, modifiedProps, getKeystore(keystorePid)); } } } - private void findAndDecodeCertificatesForInterface(String interfaceName, Map modifiedProps) { + private void findAndDecodeCertificatesForInterface(String interfaceName, Map modifiedProps, + KeystoreService keystoreService) { + + if (keystoreService == null) { + logger.error("Cannot find keystore service for interface {}", interfaceName); + return; + } + for (Entry prop : modifiedProps.entrySet()) { String clientCertString = String.format("%s.config.802-1x.client-cert-name", interfaceName); String caCertString = String.format("%s.config.802-1x.802-1x.ca-cert-name", interfaceName); @@ -335,16 +340,17 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map Date: Tue, 3 Oct 2023 15:48:53 -0400 Subject: [PATCH 11/33] feat: added more type security in webUI --- .../web/client/ui/network/Tab8021xUi.java | 18 ++++++++++--- ...ConfigurationServicePropertiesBuilder.java | 26 ++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java index e02750be9d..49021a5cd7 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/network/Tab8021xUi.java @@ -327,11 +327,21 @@ public void setDirty(boolean dirty) { public void getUpdatedNetInterface(GwtNetInterfaceConfig updatedNetIf) { Gwt8021xConfig updated8021xConfig = new Gwt8021xConfig(); - updated8021xConfig.setIdentity(this.username.getText()); - updated8021xConfig.setPassword(this.password.getText()); + if (!this.username.getText().isEmpty() && this.username.getText() != null) { + updated8021xConfig.setIdentity(this.username.getText()); + } + + if (!this.password.getText().isEmpty() && this.password.getText() != null) { + updated8021xConfig.setPassword(this.password.getText()); + } - updated8021xConfig.setEap(Gwt8021xEap.valueOf(this.eap.getSelectedValue())); - updated8021xConfig.setInnerAuthEnum(Gwt8021xInnerAuth.valueOf(this.innerAuth.getSelectedValue())); + if (!this.eap.getSelectedValue().isEmpty() && this.eap.getSelectedValue() != null) { + updated8021xConfig.setEap(Gwt8021xEap.valueOf(this.eap.getSelectedValue())); + } + + if (!this.innerAuth.getSelectedValue().isEmpty() && this.innerAuth.getSelectedValue() != null) { + updated8021xConfig.setInnerAuthEnum(Gwt8021xInnerAuth.valueOf(this.innerAuth.getSelectedValue())); + } updatedNetIf.setEnterpriseConfig(updated8021xConfig); } diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java index dbf543e78e..45c8172593 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java @@ -248,10 +248,28 @@ private void setWifiMasterProperties() throws GwtKuraException { private void set8021xConfig() { logger.error("setting 802-1x config"); - this.properties.set8021xEap(this.ifname, this.gwtConfig.get8021xConfig().getEap()); - this.properties.set8021xInnerAuth(this.ifname, this.gwtConfig.get8021xConfig().getInnerAuth()); - this.properties.set8021xIdentity(this.ifname, this.gwtConfig.get8021xConfig().getUsername()); - this.properties.set8021xPassword(this.ifname, this.gwtConfig.get8021xConfig().getPassword()); + if (this.gwtConfig.get8021xConfig() == null) { + return; + } + + if (this.gwtConfig.get8021xConfig().getEap() != null && !this.gwtConfig.get8021xConfig().getEap().isEmpty()) { + this.properties.set8021xEap(this.ifname, this.gwtConfig.get8021xConfig().getEap()); + } + + if (this.gwtConfig.get8021xConfig().getInnerAuth() != null + && !this.gwtConfig.get8021xConfig().getInnerAuth().isEmpty()) { + this.properties.set8021xInnerAuth(this.ifname, this.gwtConfig.get8021xConfig().getInnerAuth()); + } + + if (this.gwtConfig.get8021xConfig().getUsername() != null + && !this.gwtConfig.get8021xConfig().getUsername().isEmpty()) { + this.properties.set8021xIdentity(this.ifname, this.gwtConfig.get8021xConfig().getUsername()); + } + + if (this.gwtConfig.get8021xConfig().getPassword() != null + && !this.gwtConfig.get8021xConfig().getPassword().isEmpty()) { + this.properties.set8021xPassword(this.ifname, this.gwtConfig.get8021xConfig().getPassword()); + } } private void setWifiInfraProperties() { From 0081908422200626d5f146ffb0128701cecb3ffb Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 08:12:20 -0400 Subject: [PATCH 12/33] refactor: fix comments enable -> unable --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 4 ++-- .../eclipse/kura/nm/configuration/NMSettingsConverter.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index aec2b4225f..011c1da6fa 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -343,7 +343,7 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map(clientCert.getEncoded())); } catch (Exception e) { - logger.error("Enable to find or decode Client Certificate", e); + logger.error("Unable to find or decode Client Certificate", e); } try { @@ -186,7 +186,7 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map deviceId); settings.put("private-key", new Variant<>(privateKey.getEncoded())); } catch (Exception e) { - logger.error("Enable to find or decode Private Key", e); + logger.error("Unable to find or decode Private Key", e); } Optional privateKeyPassword = props.getOpt(Password.class, @@ -214,7 +214,7 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p Certificate caCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", deviceId); settings.put("ca-cert", new Variant<>(caCert.getEncoded())); } catch (Exception e) { - logger.error("Enable to find or decode CA Certificate", e); + logger.error("Unable to find or decode CA Certificate", e); } Optional caCertPassword = props.getOpt(Password.class, From a38a52f77141d89561ff3b5ee12c412c343ac084 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 08:25:29 -0400 Subject: [PATCH 13/33] refactor: removed to string --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 011c1da6fa..c45b6d3bcc 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -343,7 +343,7 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map Date: Wed, 4 Oct 2023 10:12:10 -0400 Subject: [PATCH 14/33] refactor: certificate replacement method --- .../NMConfigurationServiceImpl.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index c45b6d3bcc..86bbba0968 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -333,33 +333,35 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map prop : modifiedProps.entrySet()) { - String clientCertString = String.format("%s.config.802-1x.client-cert-name", interfaceName); - String caCertString = String.format("%s.config.802-1x.802-1x.ca-cert-name", interfaceName); - String privateKeyString = String.format("%s.config.802-1x.private-key-name", interfaceName); - if (prop.getKey().contains(clientCertString) || prop.getKey().contains(caCertString)) { - Object value = prop.getValue(); - try { - String valueString = (String) prop.getValue(); - modifiedProps.put(prop.getKey(), decryptCertificate(valueString, keystoreService)); - } catch (Exception e) { - logger.error("Unable to decode certificate {} from keystore.", value, e); - modifiedProps.put(prop.getKey(), value); - } - } else if (prop.getKey().contains(privateKeyString)) { - Object value = prop.getValue(); - try { - String valueString = (String) prop.getValue(); - modifiedProps.put(prop.getKey(), decryptPrivateKey(valueString, keystoreService)); - } catch (Exception e) { - logger.error("Unable to decode private key {} from keystore.", value, e); - modifiedProps.put(prop.getKey(), value); - } + final String clientCertString = String.format("net.interface.%s.config.802-1x.client-cert-name", interfaceName); + final String caCertString = String.format("net.interface.%s.config.802-1x.802-1x.ca-cert-name", interfaceName); + final String privateKeyString = String.format("net.interface.%s.config.802-1x.private-key-name", interfaceName); + final List keyCertStrings = Arrays.asList(clientCertString, caCertString, privateKeyString); + for (String key : keyCertStrings) { + if (!modifiedProps.containsKey(key)) { + continue; + } + + Object value = modifiedProps.get(key); + try { + String valueString = value.toString(); + if (isCertificate(key)) { + modifiedProps.put(key, decryptCertificate(valueString, keystoreService)); + } else { + modifiedProps.put(key, decryptPrivateKey(valueString, keystoreService)); + } + } catch (KuraException e) { + logger.error("Unable to decode key/certificate {} from keystore.", key, e); + modifiedProps.put(key, value); } } } + private boolean isCertificate(String key) { + return key.contains("cert"); + } + private Certificate decryptCertificate(String certificateName, KeystoreService keystoreService) throws KuraException { if (keystoreService.getEntry(certificateName) instanceof TrustedCertificateEntry) { From 8d52d363af36ccd37aa9217c239294d1e83db7fc Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 10:15:35 -0400 Subject: [PATCH 15/33] refactor: removed not needed Exception --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 86bbba0968..72cc62d8d6 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -313,7 +313,7 @@ private void decryptAndConvertPasswordProperties(Map modifiedPro } } - private void decryptAndConvertCertificatesProperties(Map modifiedProps) throws KuraException { + private void decryptAndConvertCertificatesProperties(Map modifiedProps) { for (Entry prop : modifiedProps.entrySet()) { if (prop.getKey().contains("802-1x.keystore.pid")) { From e6c53e74b1aff66d1da026f91d48634d0da788d6 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 11:05:11 -0400 Subject: [PATCH 16/33] refactor: decryptAndConvertCertificates method --- .../NMConfigurationServiceImpl.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 72cc62d8d6..3d0cb03d08 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -236,7 +236,7 @@ public synchronized void update(Map receivedProperties) { mergeNetworkConfigurationProperties(modifiedProps, this.networkProperties.getProperties()); decryptAndConvertPasswordProperties(modifiedProps); - decryptAndConvertCertificatesProperties(modifiedProps); + decryptAndConvertCertificatesProperties(modifiedProps, interfaces); this.networkProperties = new NetworkProperties(discardModifiedNetworkInterfaces(modifiedProps)); writeNetworkConfigurationSettings(modifiedProps); @@ -313,16 +313,22 @@ private void decryptAndConvertPasswordProperties(Map modifiedPro } } - private void decryptAndConvertCertificatesProperties(Map modifiedProps) { + private void decryptAndConvertCertificatesProperties(Map modifiedProps, Set interfaces) { - for (Entry prop : modifiedProps.entrySet()) { - if (prop.getKey().contains("802-1x.keystore.pid")) { - String keystorePid = (String) prop.getValue(); + interfaces.forEach(interfaceName -> { + String key = String.format("net.interface.%s.config.802-1x.keystore.pid", interfaceName); + if (modifiedProps.containsKey(key)) { + + Object prop = modifiedProps.get(key); - String interfaceName = prop.getKey().split("\\.")[2]; - findAndDecodeCertificatesForInterface(interfaceName, modifiedProps, getKeystore(keystorePid)); + if (prop instanceof String) { + String keystorePid = (String) prop; + + findAndDecodeCertificatesForInterface(interfaceName, modifiedProps, + this.keystoreServices.get(keystorePid)); + } } - } + }); } private void findAndDecodeCertificatesForInterface(String interfaceName, Map modifiedProps, @@ -382,10 +388,6 @@ private PrivateKey decryptPrivateKey(String privateKeyName, KeystoreService keys return key.getPrivateKey(); } - private KeystoreService getKeystore(String keystoreServicePid) { - return this.keystoreServices.get(keystoreServicePid); - } - @Override @SuppressWarnings("restriction") public synchronized ComponentConfiguration getConfiguration() throws KuraException { From ab1d76c14e03cbfc6ff92247c7ac11d1eac27586 Mon Sep 17 00:00:00 2001 From: G_Ivo Date: Wed, 4 Oct 2023 11:08:05 -0400 Subject: [PATCH 17/33] refactor: removed extra newline Co-authored-by: Mattia Dal Ben --- .../eclipse/kura/nm/configuration/NMSettingsConverterTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java index 237940032c..28e4d4d8db 100644 --- a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java +++ b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMSettingsConverterTest.java @@ -2858,7 +2858,6 @@ public void givenMockConnection() { public void givenMockConnectionWithNullSettings() { this.mockedConnection = Mockito.mock(Connection.class); Mockito.when(this.mockedConnection.GetSettings()).thenReturn(null); - } /* From 6d51d78e69af1cb639895fc06de4b7aed7d35027 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 16:04:40 -0400 Subject: [PATCH 18/33] refactor: error message --- .../org/eclipse/kura/nm/configuration/NMSettingsConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 79ead68525..39e47125ba 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -214,7 +214,7 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p Certificate caCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", deviceId); settings.put("ca-cert", new Variant<>(caCert.getEncoded())); } catch (Exception e) { - logger.error("Unable to find or decode CA Certificate", e); + logger.error(String.format("Unable to find or decode CA Certificate for interface %s", deviceId)); } Optional caCertPassword = props.getOpt(Password.class, From 6e963a226c295b0581e8056c726a19e099d4e83e Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 4 Oct 2023 16:45:54 -0400 Subject: [PATCH 19/33] refactor: added more if checks to improve reliability when applying from webUI --- ...NetworkConfigurationServiceProperties.java | 39 +++++++++---------- ...ConfigurationServicePropertiesBuilder.java | 7 +++- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServiceProperties.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServiceProperties.java index 7ebb2da07d..543b609f0d 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServiceProperties.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServiceProperties.java @@ -195,8 +195,7 @@ public void setIp6AddressGenMode(String ifname, String addrGenMode) { } public Optional getIp6Privacy(String ifname) { - return getNonEmptyStringProperty( - this.properties.get(String.format(NET_INTERFACE_CONFIG_IP6_PRIVACY, ifname))); + return getNonEmptyStringProperty(this.properties.get(String.format(NET_INTERFACE_CONFIG_IP6_PRIVACY, ifname))); } public void setIp6Privacy(String ifname, String privacy) { @@ -363,8 +362,8 @@ public void setWifiMasterDriver(String ifname, String driver) { } public Password getWifiMasterPassphrase(String ifname) { - return getPasswordFromProperty(this.properties - .get(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_PASSPHRASE, ifname))); + return getPasswordFromProperty( + this.properties.get(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_PASSPHRASE, ifname))); } public void setWifiMasterPassphrase(String ifname, String passphrase) { @@ -373,8 +372,7 @@ public void setWifiMasterPassphrase(String ifname, String passphrase) { } public String getWifiMasterSsid(String ifname) { - return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_SSID, ifname), - ""); + return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_SSID, ifname), ""); } public void setWifiMasterSsid(String ifname, String ssid) { @@ -391,8 +389,8 @@ public void setWifiMasterSecurityType(String ifname, String securityType) { } public Optional getWifiMasterMode(String ifname) { - return Optional.ofNullable( - (String) this.properties.get(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_MODE, ifname))); + return Optional + .ofNullable((String) this.properties.get(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_MODE, ifname))); } public void setWifiMasterMode(String ifname, String mode) { @@ -400,9 +398,8 @@ public void setWifiMasterMode(String ifname, String mode) { } public List getWifiMasterChannel(String ifname) { - return channelsAsIntegersList( - (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_CHANNEL, ifname), - "")); + return channelsAsIntegersList((String) this.properties + .getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_MASTER_CHANNEL, ifname), "")); } public void setWifiMasterChannel(String ifname, List channels) { @@ -479,9 +476,8 @@ public void setWifiInfraSsid(String ifname, String ssid) { } public List getWifiInfraChannel(String ifname) { - return channelsAsIntegersList( - (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_INFRA_CHANNEL, ifname), - "")); + return channelsAsIntegersList((String) this.properties + .getOrDefault(String.format(NET_INTERFACE_CONFIG_WIFI_INFRA_CHANNEL, ifname), "")); } public void setWifiInfraChannel(String ifname, List channels) { @@ -499,8 +495,8 @@ public void setWifiInfraBgscan(String ifname, String bgScan) { } public Password getWifiInfraPassphrase(String ifname) { - return getPasswordFromProperty(this.properties - .get(String.format(NET_INTERFACE_CONFIG_WIFI_INFRA_PASSPHRASE, ifname))); + return getPasswordFromProperty( + this.properties.get(String.format(NET_INTERFACE_CONFIG_WIFI_INFRA_PASSPHRASE, ifname))); } public void setWifiInfraPassphrase(String ifname, String passphrase) { @@ -810,7 +806,7 @@ public void setUsbDevicePath(String ifname, String path) { } /** - * Wifi Enterprise / 802-1x Configuration + * Wifi Enterprise / 802-1x Configuration */ private static final String NET_INTERFACE_CONFIG_8021X_EAP = "net.interface.%s.config.802-1x.eap"; @@ -823,7 +819,8 @@ public void set8021xEap(String ifname, String eap) { } public String get8021xEap(String ifname) { - return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_EAP, ifname), ""); + return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_EAP, ifname), + "Kura8021xEapTtls"); } public void set8021xInnerAuth(String ifname, String phase2) { @@ -831,7 +828,8 @@ public void set8021xInnerAuth(String ifname, String phase2) { } public String get8021xInnerAuth(String ifname) { - return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_PHASE2, ifname), ""); + return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_PHASE2, ifname), + "Kura8021xEapNone"); } public void set8021xIdentity(String ifname, String identity) { @@ -839,7 +837,8 @@ public void set8021xIdentity(String ifname, String identity) { } public String get8021xIdentity(String ifname) { - return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_IDENTITY, ifname), ""); + return (String) this.properties.getOrDefault(String.format(NET_INTERFACE_CONFIG_8021X_IDENTITY, ifname), + "changeme"); } public void set8021xPassword(String ifname, String password) { diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java index 45c8172593..90b42c93d4 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/server/net2/configuration/NetworkConfigurationServicePropertiesBuilder.java @@ -247,11 +247,12 @@ private void setWifiMasterProperties() throws GwtKuraException { } private void set8021xConfig() { - logger.error("setting 802-1x config"); - if (this.gwtConfig.get8021xConfig() == null) { + if (this.gwtConfig.get8021xConfig() == null || !(this.gwtConfig instanceof GwtWifiNetInterfaceConfig)) { return; } + logger.info("setting 802-1x config"); + if (this.gwtConfig.get8021xConfig().getEap() != null && !this.gwtConfig.get8021xConfig().getEap().isEmpty()) { this.properties.set8021xEap(this.ifname, this.gwtConfig.get8021xConfig().getEap()); } @@ -270,6 +271,8 @@ private void set8021xConfig() { && !this.gwtConfig.get8021xConfig().getPassword().isEmpty()) { this.properties.set8021xPassword(this.ifname, this.gwtConfig.get8021xConfig().getPassword()); } + + logger.info("DONE - setting 802-1x config"); } private void setWifiInfraProperties() { From 023df59bfddca4ceb6e5cf13de30c770d8fd0f10 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Thu, 5 Oct 2023 12:56:58 -0400 Subject: [PATCH 20/33] refactor: created a hard copy of the modifiedMap so it is not passed to the configuration service and applied --- .../nm/configuration/NMConfigurationServiceImpl.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 3d0cb03d08..884f1cc566 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -235,9 +235,10 @@ public synchronized void update(Map receivedProperties) { mergeNetworkConfigurationProperties(modifiedProps, this.networkProperties.getProperties()); + this.networkProperties = new NetworkProperties(discardModifiedNetworkInterfaces(new HashMap<>(modifiedProps))); + decryptAndConvertPasswordProperties(modifiedProps); decryptAndConvertCertificatesProperties(modifiedProps, interfaces); - this.networkProperties = new NetworkProperties(discardModifiedNetworkInterfaces(modifiedProps)); writeNetworkConfigurationSettings(modifiedProps); writeFirewallNatRules(interfaces, modifiedProps); @@ -353,9 +354,9 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map Date: Tue, 10 Oct 2023 09:37:37 -0400 Subject: [PATCH 21/33] refactor: removed extra 802-1x in String Co-authored-by: Mattia Dal Ben --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 884f1cc566..b7ae677c28 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -341,7 +341,7 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map keyCertStrings = Arrays.asList(clientCertString, caCertString, privateKeyString); From 04280ee9d078e0c1cf04b9a54531b6eae32ff547 Mon Sep 17 00:00:00 2001 From: G_Ivo Date: Tue, 10 Oct 2023 09:38:36 -0400 Subject: [PATCH 22/33] refactor: add specificity to to isCertificate method Co-authored-by: Mattia Dal Ben --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index b7ae677c28..74cbbbffbc 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -366,7 +366,7 @@ private void findAndDecodeCertificatesForInterface(String interfaceName, Map Date: Tue, 10 Oct 2023 09:44:16 -0400 Subject: [PATCH 23/33] refactor: updated String for better readability Co-authored-by: Mattia Dal Ben --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 74cbbbffbc..2eb25e663c 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -379,7 +379,7 @@ private Certificate getTrustedCertificateFromKeystore(String certificateName, Ke return cert.getCertificate(); } else { throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, - String.format("Certificate %s is not expected key type or not found.", certificateName)); + String.format("Certificate \"%s\" is not of the expected key type or not found.", certificateName)); } } From 5150b1edfb23c1911ee1ecfa837f986e24646e9a Mon Sep 17 00:00:00 2001 From: G_Ivo Date: Tue, 10 Oct 2023 09:55:24 -0400 Subject: [PATCH 24/33] refactor: add extra safety checks in getTrustedCertificateFromKeystoreMethod Co-authored-by: Mattia Dal Ben --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 2eb25e663c..ccf4f20a6a 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -384,8 +384,12 @@ private Certificate getTrustedCertificateFromKeystore(String certificateName, Ke } private PrivateKey getTrustedPrivateKeyFromKeystore(String privateKeyName, KeystoreService keystoreService) throws KuraException { + if(!keystoreService.getEntry(privateKeyName) instanceof PrivateKeyEntry) { + throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, + String.format("Private key \"%s\" is not of the expected key type or not found.", privateKeyName)); + } + PrivateKeyEntry key = (PrivateKeyEntry) keystoreService.getEntry(privateKeyName); - return key.getPrivateKey(); } From 820d62726d8d2f6920bf591a6e1a764c2e36a265 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Tue, 10 Oct 2023 10:00:29 -0400 Subject: [PATCH 25/33] lint: fix whitespace issues --- .../kura/nm/configuration/NMConfigurationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index ccf4f20a6a..6950f9a191 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -384,7 +384,7 @@ private Certificate getTrustedCertificateFromKeystore(String certificateName, Ke } private PrivateKey getTrustedPrivateKeyFromKeystore(String privateKeyName, KeystoreService keystoreService) throws KuraException { - if(!keystoreService.getEntry(privateKeyName) instanceof PrivateKeyEntry) { + if (!(keystoreService.getEntry(privateKeyName) instanceof PrivateKeyEntry)) { throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, String.format("Private key \"%s\" is not of the expected key type or not found.", privateKeyName)); } From c95320e1a057809d57733d33c6cb8558a6ab7d84 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 09:40:10 -0400 Subject: [PATCH 26/33] fix: changed 802-1x -> 802.1x --- .../org/eclipse/kura/web/client/messages/Messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties b/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties index 7bcb20fce4..fa78dbda5d 100644 --- a/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties +++ b/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties @@ -620,7 +620,7 @@ netWifiChannelMissingError=The chosen network uses a channel that is not allowed netWifiCountryCode=Country Code netWifiCountryCodeLabel=Country Code -netWifiWireless8021x=802-1x +netWifiWireless8021x=802.1x net8021xEap=Enterprise EAP (Extensible Authentication Protocol) net8021xEapHelp=Extensible Authentication Protocol (EAP), determine what protocol will be used to authenticate the network. net8021xInnerAuth=Inner Authentication (Phase2 Auth) From f97bdcd1d82c007ad686aaca7213f8b4233ce4ea Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 10:44:56 -0400 Subject: [PATCH 27/33] refactor: removed unnecessary cast to String --- .../NMConfigurationServiceImpl.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java index 6950f9a191..97c305f648 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImpl.java @@ -140,7 +140,7 @@ public void setKeystoreService(KeystoreService keystoreService, Map properties) { if (this.keystoreServices.containsValue(keystoreService)) { - this.keystoreServices.remove((String) properties.get(ConfigurationService.KURA_SERVICE_PID)); + this.keystoreServices.remove(properties.get(ConfigurationService.KURA_SERVICE_PID)); } } @@ -235,8 +235,9 @@ public synchronized void update(Map receivedProperties) { mergeNetworkConfigurationProperties(modifiedProps, this.networkProperties.getProperties()); - this.networkProperties = new NetworkProperties(discardModifiedNetworkInterfaces(new HashMap<>(modifiedProps))); - + this.networkProperties = new NetworkProperties( + discardModifiedNetworkInterfaces(new HashMap<>(modifiedProps))); + decryptAndConvertPasswordProperties(modifiedProps); decryptAndConvertCertificatesProperties(modifiedProps, interfaces); @@ -319,12 +320,12 @@ private void decryptAndConvertCertificatesProperties(Map modifie interfaces.forEach(interfaceName -> { String key = String.format("net.interface.%s.config.802-1x.keystore.pid", interfaceName); if (modifiedProps.containsKey(key)) { - + Object prop = modifiedProps.get(key); if (prop instanceof String) { String keystorePid = (String) prop; - + findAndDecodeCertificatesForInterface(interfaceName, modifiedProps, this.keystoreServices.get(keystorePid)); } @@ -383,12 +384,13 @@ private Certificate getTrustedCertificateFromKeystore(String certificateName, Ke } } - private PrivateKey getTrustedPrivateKeyFromKeystore(String privateKeyName, KeystoreService keystoreService) throws KuraException { + private PrivateKey getTrustedPrivateKeyFromKeystore(String privateKeyName, KeystoreService keystoreService) + throws KuraException { if (!(keystoreService.getEntry(privateKeyName) instanceof PrivateKeyEntry)) { - throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, + throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR, String.format("Private key \"%s\" is not of the expected key type or not found.", privateKeyName)); } - + PrivateKeyEntry key = (PrivateKeyEntry) keystoreService.getEntry(privateKeyName); return key.getPrivateKey(); } From 419a67f902ca07495fbbd4218c3abb5a56451202 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 10:16:05 -0400 Subject: [PATCH 28/33] refactor: removed extra curly braces in lamdas --- .../kura/nm/configuration/NMSettingsConverter.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index 39e47125ba..ee8d2d3d71 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -192,9 +192,7 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map Optional privateKeyPassword = props.getOpt(Password.class, "net.interface.%s.config.802-1x.private-key-password", deviceId); - privateKeyPassword.ifPresent(value -> { - settings.put("private-key-password", new Variant<>(value.toString())); - }); + privateKeyPassword.ifPresent(value -> settings.put("private-key-password", new Variant<>(value.toString()))); settings.put("private-key-password-flags", new Variant<>(new UInt32(4))); @@ -206,9 +204,7 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p Optional anonymousIdentity = props.getOpt(String.class, "net.interface.%s.config.802-1x.anonymous-identity", deviceId); - anonymousIdentity.ifPresent(value -> { - settings.put("anonymous-identity", new Variant<>(value)); - }); + anonymousIdentity.ifPresent(value -> settings.put("anonymous-identity", new Variant<>(value))); try { Certificate caCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.ca-cert-name", deviceId); @@ -220,9 +216,7 @@ private static void create8021xOptionalCaCertAndAnonIdentity(NetworkProperties p Optional caCertPassword = props.getOpt(Password.class, "net.interface.%s.config.802-1x.ca-cert-password", deviceId); - caCertPassword.ifPresent(value -> { - settings.put("ca-cert-password", new Variant<>(value.toString())); - }); + caCertPassword.ifPresent(value -> settings.put("ca-cert-password", new Variant<>(value.toString()))); } private static void create8021xMschapV2(NetworkProperties props, String deviceId, From 748d729d54325355819e143f8996df5e8c84ea63 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 10:20:27 -0400 Subject: [PATCH 29/33] refactor: removed type in <> --- .../eclipse/kura/nm/configuration/NMSettingsConverter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index ee8d2d3d71..efcfd2664b 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -540,9 +540,9 @@ public static Map> buildVlanSettings(NetworkProperties props, settings.put("flags", new Variant<>(new UInt32(vlanFlags.orElse(1)))); DBusListType listType = new DBusListType(String.class); Optional> ingressMap = props.getOptStringList("net.interface.%s.config.vlan.ingress", deviceId); - settings.put("ingress-priority-map", new Variant<>(ingressMap.orElse(new ArrayList()), listType)); + settings.put("ingress-priority-map", new Variant<>(ingressMap.orElse(new ArrayList<>()), listType)); Optional> egressMap = props.getOptStringList("net.interface.%s.config.vlan.egress", deviceId); - settings.put("egress-priority-map", new Variant<>(egressMap.orElse(new ArrayList()), listType)); + settings.put("egress-priority-map", new Variant<>(egressMap.orElse(new ArrayList<>()), listType)); return settings; } From 7579211a6b9612ffb30b8a25c79a132dcba86ea1 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 14:57:52 -0400 Subject: [PATCH 30/33] tests: added basic enterprise test coverage --- .../NMConfigurationServiceImplTest.java | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java index 51ef3cf28a..f6dbe3e02a 100644 --- a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java +++ b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java @@ -17,13 +17,19 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.security.PrivateKey; +import java.security.KeyStore.PrivateKeyEntry; +import java.security.KeyStore.TrustedCertificateEntry; +import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -33,6 +39,7 @@ import org.eclipse.kura.KuraException; import org.eclipse.kura.configuration.ComponentConfiguration; +import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.configuration.metatype.AD; import org.eclipse.kura.configuration.metatype.OCD; import org.eclipse.kura.core.linux.executor.LinuxExitStatus; @@ -48,6 +55,7 @@ import org.eclipse.kura.nm.NMDbusConnector; import org.eclipse.kura.nm.NetworkProperties; import org.eclipse.kura.nm.configuration.writer.DhcpServerConfigWriter; +import org.eclipse.kura.security.keystore.KeystoreService; import org.junit.Test; import org.mockito.Mockito; import org.osgi.framework.BundleContext; @@ -67,6 +75,7 @@ public class NMConfigurationServiceImplTest { private AtomicBoolean posted; private Event event; private final Set dhcpConfigWriterInterfaces = new HashSet<>(); + private KeystoreService keystoreService = mock(KeystoreService.class); @Test public void shouldPostEventAfterActivationTest() throws InterruptedException, KuraException { @@ -152,6 +161,17 @@ public void shouldStartConfigWriterIfEthernetInterfaceIsEnabledAndInDhcpServerMo thenDhcpConfigWriterIsCreatedForInterfaces("eno1"); } + @Test + public void shouldStartConfigWriterIfEnterpriseWifi() throws KuraException { + givenNetworkConfigurationService(); + givenFullProperties(); + givenWifiEnterprisePropertiesForInterfaceWlp2s0(); + + whenServiceIsActivated(); + + thenDhcpConfigWriterIsCreatedForInterfaces("wlp2s0"); + } + @Test public void shouldStartConfigWriterIfWifiInterfaceIsEnabledAndInDhcpServerMode() throws KuraException { givenNetworkConfigurationService(); @@ -369,6 +389,92 @@ private void givenFullProperties() { this.properties.put("net.interface.1-4.config.pdpType", "IP"); } + private void givenWifiEnterprisePropertiesForInterfaceWlp2s0() { + this.properties.put("net.interfaces", "enp5s0,lo,eno1,wlp1s0,wlp2s0,1-4"); + + this.properties.put("net.interface.wlp2s0.type", "WIFI"); + this.properties.put("net.interface.wlp2s0.config.ip4.gateway", ""); + this.properties.put("net.interface.wlp2s0.config.wifi.master.driver", "nl80211"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.ssid", "testssid"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.groupCiphers", "CCMP_TKIP"); + this.properties.put("net.interface.wlp2s0.config.wifi.master.bgscan", ""); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.rangeStart", "172.16.1.100"); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.maxLeaseTime", 7200); + this.properties.put("net.interface.wlp2s0.config.wifi.master.pingAccessPoint", false); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.channel", "1"); + this.properties.put("net.interface.wlp2s0.config.wifi.master.passphrase", "qwerty="); + this.properties.put("net.interface.wlp2s0.config.wifi.master.groupCiphers", "CCMP_TKIP"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.bgscan", ""); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.passphrase", ""); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.defaultLeaseTime", 7200); + this.properties.put("net.interface.wlp2s0.config.wifi.master.ssid", "kura_gateway_0"); + this.properties.put("net.interface.wlp2s0.config.wifi.master.securityType", "SECURITY_WPA2"); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.rangeEnd", "172.16.1.110"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.ignoreSSID", false); + this.properties.put("net.interface.wlp2s0.config.wifi.master.mode", "MASTER"); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.prefix", 24); + this.properties.put("net.interface.wlp2s0.config.wifi.mode", "INFRA"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.mode", "INFRA"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.pingAccessPoint", false); + this.properties.put("net.interface.wlp2s0.config.nat.enabled", false); + this.properties.put("net.interface.wlp2s0.config.ip4.status", "netIPv4StatusEnabledWAN"); + this.properties.put("net.interface.wlp2s0.config.ip6.status", "netIPv6StatusDisabled"); + this.properties.put("net.interface.wlp2s0.config.wifi.master.channel", "1"); + this.properties.put("net.interface.wlp2s0.config.wifi.master.radioMode", "RADIO_MODE_80211g"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.driver", "nl80211"); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.enabled", true); + this.properties.put("net.interface.wlp2s0.config.wifi.master.ignoreSSID", false); + this.properties.put("net.interface.wlp2s0.config.ip4.address", "172.16.1.1"); + this.properties.put("net.interface.wlp2s0.config.ip6.dnsServers", ""); + this.properties.put("net.interface.wlp2s0.config.wifi.master.pairwiseCiphers", "CCMP"); + this.properties.put("net.interface.wlp2s0.config.dhcpClient6.enabled", false); + this.properties.put("net.interface.wlp2s0.config.dhcpServer4.passDns", false); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.securityType", "SECURITY_WPA2_WPA3_ENTERPRISE"); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.radioMode", "RADIO_MODE_80211b"); + this.properties.put("net.interface.wlp2s0.config.ip4.dnsServers", ""); + this.properties.put("net.interface.wlp2s0.config.wifi.infra.pairwiseCiphers", "CCMP_TKIP"); + this.properties.put("net.interface.wlp2s0.config.ip4.prefix", 24); + this.properties.put("net.interface.wlp2s0.config.802-1x.eap", "Kura8021xEapTls"); + this.properties.put("net.interface.wlp2s0.config.802-1x.keystore.pid", "WifiKeystore"); + this.properties.put("net.interface.wlp2s0.config.802-1x.ca-cert-name", "caCert"); + this.properties.put("net.interface.wlp2s0.config.802-1x.client-cert-name", "privatekey"); + this.properties.put("net.interface.wlp2s0.config.802-1x.private-key-name", "privatekey"); + } + + private void givenEnterpriseWifiKeystore() { + + try { + TrustedCertificateEntry trustedCertificateEntry = mock(TrustedCertificateEntry.class); + Certificate certificate = mock(Certificate.class); + + PrivateKeyEntry privateKeyEntry = mock(PrivateKeyEntry.class); + Certificate privateKeyCertificate = mock(Certificate.class); + PrivateKey privateKey = mock(PrivateKey.class); + + when(trustedCertificateEntry.getTrustedCertificate()).thenReturn(certificate); + when(privateKeyEntry.getCertificate()).thenReturn(privateKeyCertificate); + when(privateKeyEntry.getPrivateKey()).thenReturn(privateKey); + + when(certificate.getEncoded()).thenReturn("ca-certificate".getBytes()); + when(privateKeyCertificate.getEncoded()).thenReturn("certificate-key".getBytes()); + when(privateKey.getEncoded()).thenReturn("privatekey".getBytes()); + + this.keystoreService = mock(KeystoreService.class); + + when(this.keystoreService.getEntry("caCert")).thenReturn(trustedCertificateEntry); + when(this.keystoreService.getEntry("privatekey")).thenReturn(privateKeyEntry); + + Map propertiesMap = new HashMap<>(); + propertiesMap.put(ConfigurationService.KURA_SERVICE_PID, "WifiKeystore"); + + this.networkConfigurationService.setKeystoreService(keystoreService, propertiesMap); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + + } + private void givenPropertiesWithPppInterfaceNames() { this.properties.clear(); this.properties.put("net.interfaces", "enp5s0,lo,eno1,wlp1s0,ppp3"); @@ -792,6 +898,55 @@ private void thenComponentDefinitionHasCorrectProperties() { assertEquals(40, adsConfigured); } + private void thenComponentDefinitionHasCorrectEnterpriseProperties() { + int adsConfigured = 0; + for (AD ad : this.ads) { + + if ("net.interfaces".equals(ad.getId())) { + assertEquals("net.interfaces", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertTrue(ad.isRequired()); + adsConfigured++; + } + + if ("net.interface.wlp2s0.config.802-1x.eap".equals(ad.getId())) { + assertEquals("net.interface.wlp2s0.config.802-1x.eap", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertFalse(ad.isRequired()); + adsConfigured++; + } + + if ("net.interface.wlp2s0.config.802-1x.keystore.pid".equals(ad.getId())) { + assertEquals("net.interface.wlp2s0.config.802-1x.keystore.pid", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertFalse(ad.isRequired()); + adsConfigured++; + } + + if ("net.interface.wlp2s0.config.802-1x.ca-cert-name".equals(ad.getId())) { + assertEquals("net.interface.wlp2s0.config.802-1x.ca-cert-name", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertFalse(ad.isRequired()); + adsConfigured++; + } + + if ("net.interface.wlp2s0.config.802-1x.client-cert-name".equals(ad.getId())) { + assertEquals("net.interface.wlp2s0.config.802-1x.client-cert-name", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertFalse(ad.isRequired()); + adsConfigured++; + } + + if ("net.interface.wlp2s0.config.802-1x.private-key-name".equals(ad.getId())) { + assertEquals("net.interface.wlp2s0.config.802-1x.private-key-name", ad.getName()); + assertEquals("STRING", ad.getType().name()); + assertFalse(ad.isRequired()); + adsConfigured++; + } + } + assertEquals(5, adsConfigured); + } + private void thenPropertiesNumberIsCorrect() { assertEquals(33, this.event.getPropertyNames().length); } From 3ede2eebfdd5557eaf5fcad11678f2b00c975901 Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Wed, 11 Oct 2023 18:38:20 -0400 Subject: [PATCH 31/33] test: added method for mocking keystore --- .../kura/nm/configuration/NMConfigurationServiceImplTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java index f6dbe3e02a..2a70e3a3b8 100644 --- a/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java +++ b/kura/test/org.eclipse.kura.nm.test/src/test/java/org/eclipse/kura/nm/configuration/NMConfigurationServiceImplTest.java @@ -164,6 +164,7 @@ public void shouldStartConfigWriterIfEthernetInterfaceIsEnabledAndInDhcpServerMo @Test public void shouldStartConfigWriterIfEnterpriseWifi() throws KuraException { givenNetworkConfigurationService(); + givenEnterpriseWifiKeystore(); givenFullProperties(); givenWifiEnterprisePropertiesForInterfaceWlp2s0(); From a9ebe520e33f57457009a5e4b07f071f80b63bdf Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Thu, 12 Oct 2023 09:34:33 -0400 Subject: [PATCH 32/33] fix: added static variable for NM_SECRET_FLAGS_NOT_REQUIRED --- .../eclipse/kura/nm/configuration/NMSettingsConverter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index efcfd2664b..acfe37ba20 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -66,6 +66,8 @@ public class NMSettingsConverter { private static final String KURA_PROPS_KEY_WIFI_MODE = "net.interface.%s.config.wifi.mode"; private static final String KURA_PROPS_KEY_WIFI_SECURITY_TYPE = "net.interface.%s.config.wifi.%s.securityType"; + static final UInt32 NM_SECRET_FLAGS_NOT_REQUIRED = new UInt32(4); + private NMSettingsConverter() { throw new IllegalStateException("Utility class"); } @@ -194,7 +196,7 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map privateKeyPassword.ifPresent(value -> settings.put("private-key-password", new Variant<>(value.toString()))); - settings.put("private-key-password-flags", new Variant<>(new UInt32(4))); + settings.put("private-key-password-flags", new Variant<>(NM_SECRET_FLAGS_NOT_REQUIRED)); } From 2ff3a7f74d782ab53a9a60418a96c573406b3c4b Mon Sep 17 00:00:00 2001 From: Gregory Ivo Date: Thu, 12 Oct 2023 09:45:49 -0400 Subject: [PATCH 33/33] fix: removed generic exception logging, and changed exceptions --- .../nm/configuration/NMSettingsConverter.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java index acfe37ba20..cb23356e34 100644 --- a/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java +++ b/kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/configuration/NMSettingsConverter.java @@ -18,6 +18,7 @@ import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -179,16 +180,17 @@ private static void create8021xTls(NetworkProperties props, String deviceId, Map Certificate clientCert = props.get(Certificate.class, "net.interface.%s.config.802-1x.client-cert-name", deviceId); settings.put("client-cert", new Variant<>(clientCert.getEncoded())); - } catch (Exception e) { - logger.error("Unable to find or decode Client Certificate", e); + } catch (CertificateEncodingException e) { + logger.error("Unable to find or decode Client Certificate"); } - try { - PrivateKey privateKey = props.get(PrivateKey.class, "net.interface.%s.config.802-1x.private-key-name", - deviceId); + PrivateKey privateKey = props.get(PrivateKey.class, "net.interface.%s.config.802-1x.private-key-name", + deviceId); + + if (privateKey.getEncoded() != null) { settings.put("private-key", new Variant<>(privateKey.getEncoded())); - } catch (Exception e) { - logger.error("Unable to find or decode Private Key", e); + } else { + logger.error("Unable to find or decode Private Key"); } Optional privateKeyPassword = props.getOpt(Password.class,