X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Futil%2Fosgi%2FNetconfConfigUtil.java;h=0993b8ad0c7038e5b86b0fee0e5cb4d30fd701f8;hb=5f076ac845a3dd966860b4398cac9d8854306482;hp=35e17a2a3e4564ffceac32158d00e5f7e6faba39;hpb=b5d0a1c60d3ff26cb4d7ecf45ee5fc0f95636c19;p=controller.git diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index 35e17a2a3e..0993b8ad0c 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -9,127 +9,160 @@ package org.opendaylight.controller.netconf.util.osgi; import com.google.common.base.Optional; -import org.opendaylight.protocol.util.SSLUtil; import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; import java.net.InetSocketAddress; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +public final class NetconfConfigUtil { + private static final Logger logger = LoggerFactory.getLogger(NetconfConfigUtil.class); + + public static final InetSocketAddress DEFAULT_NETCONF_TCP_ADDRESS + = new InetSocketAddress("127.0.0.1", 8383); + public static final InetSocketAddress DEFAULT_NETCONF_SSH_ADDRESS + = new InetSocketAddress("0.0.0.0", 1830); -public class NetconfConfigUtil { private static final String PREFIX_PROP = "netconf."; + private NetconfConfigUtil() { + } + private enum InfixProp { - tcp, tls, ssh + tcp, ssh } private static final String PORT_SUFFIX_PROP = ".port"; private static final String ADDRESS_SUFFIX_PROP = ".address"; + private static final String CLIENT_PROP = ".client"; + private static final String PRIVATE_KEY_PATH_PROP = ".pk.path"; - private static final String NETCONF_TLS_KEYSTORE_PROP = PREFIX_PROP + InfixProp.tls + ".keystore"; - private static final String NETCONF_TLS_KEYSTORE_PASSWORD_PROP = NETCONF_TLS_KEYSTORE_PROP + ".password"; + private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis"; + private static final long DEFAULT_TIMEOUT_MILLIS = 5000; - public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound) { + public static long extractTimeoutMillis(final BundleContext bundleContext) { + final String key = PREFIX_PROP + CONNECTION_TIMEOUT_MILLIS_PROP; + final String timeoutString = bundleContext.getProperty(key); + if (timeoutString == null || timeoutString.length() == 0) { + return DEFAULT_TIMEOUT_MILLIS; + } + try { + return Long.parseLong(timeoutString); + } catch (final NumberFormatException e) { + logger.warn("Cannot parse {} property: {}, using defaults", key, timeoutString, e); + return DEFAULT_TIMEOUT_MILLIS; + } + } - Optional inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp); - if (inetSocketAddressOptional.isPresent() == false) { - throw new IllegalStateException("Netconf tcp address not found." + exceptionMessageIfNotFound); + public static InetSocketAddress extractTCPNetconfServerAddress(final BundleContext context, final InetSocketAddress defaultAddress) { + final Optional extracted = extractNetconfServerAddress(context, InfixProp.tcp); + final InetSocketAddress netconfTcpAddress = getNetconfAddress(defaultAddress, extracted, InfixProp.tcp); + logger.debug("Using {} as netconf tcp address", netconfTcpAddress); + if (netconfTcpAddress.getAddress().isAnyLocalAddress()) { + logger.warn("Unprotected netconf TCP address is configured to ANY local address. This is a security risk. " + + "Consider changing {} to 127.0.0.1", PREFIX_PROP + InfixProp.tcp + ADDRESS_SUFFIX_PROP); } - return inetSocketAddressOptional.get(); + return netconfTcpAddress; } - public static Optional extractSSHNetconfAddress(BundleContext context) { - return extractSomeNetconfAddress(context, InfixProp.ssh); + public static InetSocketAddress extractTCPNetconfClientAddress(final BundleContext context, final InetSocketAddress defaultAddress) { + final Optional extracted = extractNetconfClientAddress(context, InfixProp.tcp); + return getNetconfAddress(defaultAddress, extracted, InfixProp.tcp); } + /** + * Get extracted address or default. + * + * @throws java.lang.IllegalStateException if neither address is present. + */ + private static InetSocketAddress getNetconfAddress(final InetSocketAddress defaultAddress, Optional extractedAddress, InfixProp infix) { + InetSocketAddress inetSocketAddress; - public static Optional extractTLSConfiguration(BundleContext context) { - Optional address = extractSomeNetconfAddress(context, InfixProp.tls); - if (address.isPresent()) { - String keystoreFileName = context.getProperty(NETCONF_TLS_KEYSTORE_PROP); - File keystoreFile = new File(keystoreFileName); - checkState(keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead(), - "Keystore file %s does not exist or is not readable file", keystoreFileName); - keystoreFile = keystoreFile.getAbsoluteFile(); - String keystorePassword = context.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP); - checkNotNull(keystoreFileName, "Property %s must be defined for tls netconf server", - NETCONF_TLS_KEYSTORE_PROP); - keystorePassword = keystorePassword != null ? keystorePassword : ""; - return Optional.of(new TLSConfiguration(address.get(), keystoreFile, keystorePassword)); + if (extractedAddress.isPresent() == false) { + logger.debug("Netconf {} address not found, falling back to default {}", infix, defaultAddress); + + if (defaultAddress == null) { + logger.warn("Netconf {} address not found, default address not provided", infix); + throw new IllegalStateException("Netconf " + infix + " address not found, default address not provided"); + } + inetSocketAddress = defaultAddress; } else { - return Optional.absent(); + inetSocketAddress = extractedAddress.get(); } + + return inetSocketAddress; } - public static class TLSConfiguration { - private final InetSocketAddress address; - private final File keystoreFile; - private final String keystorePassword; - private final SSLContext sslContext; + public static InetSocketAddress extractSSHNetconfAddress(final BundleContext context, final InetSocketAddress defaultAddress) { + Optional extractedAddress = extractNetconfServerAddress(context, InfixProp.ssh); + InetSocketAddress netconfSSHAddress = getNetconfAddress(defaultAddress, extractedAddress, InfixProp.ssh); + logger.debug("Using {} as netconf SSH address", netconfSSHAddress); + return netconfSSHAddress; + } - TLSConfiguration(InetSocketAddress address, File keystoreFile, String keystorePassword) { - this.address = address; - this.keystoreFile = keystoreFile; - this.keystorePassword = keystorePassword; - try { - try (InputStream keyStoreIS = new FileInputStream(keystoreFile)) { - try (InputStream trustStoreIS = new FileInputStream(keystoreFile)) { - sslContext = SSLUtil.initializeSecureContext("password", keyStoreIS, trustStoreIS, KeyManagerFactory.getDefaultAlgorithm()); - } - } - } catch (Exception e) { - throw new RuntimeException("Cannot initialize ssl context for netconf file " + keystoreFile, e); - } - } + public static String getPrivateKeyPath(final BundleContext context) { + return getPropertyValue(context, PREFIX_PROP + InfixProp.ssh + PRIVATE_KEY_PATH_PROP); + } - public SSLContext getSslContext() { - return sslContext; + private static String getPropertyValue(final BundleContext context, final String propertyName) { + final String propertyValue = context.getProperty(propertyName); + if (propertyValue == null) { + throw new IllegalStateException("Cannot find initial property with name '" + propertyName + "'"); } + return propertyValue; + } - public InetSocketAddress getAddress() { - return address; - } + /** + * @param context from which properties are being read. + * @param infixProp either tcp or ssh + * @return value if address and port are present and valid, Optional.absent otherwise. + * @throws IllegalStateException if address or port are invalid, or configuration is missing + */ + private static Optional extractNetconfServerAddress(final BundleContext context, + final InfixProp infixProp) { - public File getKeystoreFile() { - return keystoreFile; - } + final Optional address = getProperty(context, PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP); + final Optional port = getProperty(context, PREFIX_PROP + infixProp + PORT_SUFFIX_PROP); - public String getKeystorePassword() { - return keystorePassword; + if (address.isPresent() && port.isPresent()) { + try { + return Optional.of(parseAddress(address, port)); + } catch (final RuntimeException e) { + logger.warn("Unable to parse {} netconf address from {}:{}, fallback to default", + infixProp, address, port, e); + } } + return Optional.absent(); } - /** - * @param context - * from which properties are being read. - * @param infixProp - * either tcp or tls - * @return absent if address is missing, value if address and port are - * valid. - * @throws IllegalStateException - * if address or port are invalid - */ - private static Optional extractSomeNetconfAddress(BundleContext context, - InfixProp infixProp) { - String address = context.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP); - if (address == null) { - return Optional.absent(); + private static InetSocketAddress parseAddress(final Optional address, final Optional port) { + final int portNumber = Integer.valueOf(port.get()); + return new InetSocketAddress(address.get(), portNumber); + } + + private static Optional extractNetconfClientAddress(final BundleContext context, + final InfixProp infixProp) { + final Optional address = getProperty(context, + PREFIX_PROP + infixProp + CLIENT_PROP + ADDRESS_SUFFIX_PROP); + final Optional port = getProperty(context, + PREFIX_PROP + infixProp + CLIENT_PROP + PORT_SUFFIX_PROP); + + if (address.isPresent() && port.isPresent()) { + try { + return Optional.of(parseAddress(address, port)); + } catch (final RuntimeException e) { + logger.warn("Unable to parse client {} netconf address from {}:{}, fallback to server address", + infixProp, address, port, e); + } } - String portKey = PREFIX_PROP + infixProp + PORT_SUFFIX_PROP; - String portString = context.getProperty(portKey); - checkNotNull(portString, "Netconf port must be specified in properties file with " + portKey); - try { - int port = Integer.valueOf(portString); - return Optional.of(new InetSocketAddress(address, port)); - } catch (RuntimeException e) { - throw new IllegalStateException("Cannot create " + infixProp + " netconf address from address:" + address - + " and port:" + portString, e); + return extractNetconfServerAddress(context, infixProp); + } + + private static Optional getProperty(final BundleContext context, final String propKey) { + String value = context.getProperty(propKey); + if (value != null && value.isEmpty()) { + value = null; } + return Optional.fromNullable(value); } }