54041e6602c52adc996b3d06c29f6461b5e7e4b1
[controller.git] / opendaylight / netconf / netconf-util / src / main / java / org / opendaylight / controller / netconf / util / osgi / NetconfConfigUtil.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.util.osgi;
10
11 import static com.google.common.base.Preconditions.checkNotNull;
12 import static com.google.common.base.Preconditions.checkState;
13
14 import java.io.File;
15 import java.io.FileInputStream;
16 import java.io.InputStream;
17 import java.net.InetSocketAddress;
18
19 import javax.net.ssl.KeyManagerFactory;
20 import javax.net.ssl.SSLContext;
21
22 import org.opendaylight.controller.config.stat.ConfigProvider;
23 import org.opendaylight.protocol.util.SSLUtil;
24
25 import com.google.common.base.Optional;
26
27 public class NetconfConfigUtil {
28     private static final String PREFIX_PROP = "netconf.";
29
30     private enum InfixProp {
31         tcp, tls
32     }
33
34     private static final String PORT_SUFFIX_PROP = ".port";
35     private static final String ADDRESS_SUFFIX_PROP = ".address";
36
37     private static final String NETCONF_TLS_KEYSTORE_PROP = PREFIX_PROP + InfixProp.tls + ".keystore";
38     private static final String NETCONF_TLS_KEYSTORE_PASSWORD_PROP = NETCONF_TLS_KEYSTORE_PROP + ".password";
39
40     public static Optional<InetSocketAddress> extractTCPNetconfAddress(ConfigProvider configProvider) {
41         return extractSomeNetconfAddress(configProvider, InfixProp.tcp);
42     }
43
44     public static Optional<TLSConfiguration> extractTLSConfiguration(ConfigProvider configProvider) {
45         Optional<InetSocketAddress> address = extractSomeNetconfAddress(configProvider, InfixProp.tls);
46         if (address.isPresent()) {
47             String keystoreFileName = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PROP);
48             File keystoreFile = new File(keystoreFileName);
49             checkState(keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead(),
50                     "Keystore file %s does not exist or is not readable file", keystoreFileName);
51             keystoreFile = keystoreFile.getAbsoluteFile();
52             String keystorePassword = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
53             checkNotNull(keystoreFileName, "Property %s must be defined for tls netconf server",
54                     NETCONF_TLS_KEYSTORE_PROP);
55             keystorePassword = keystorePassword != null ? keystorePassword : "";
56             return Optional.of(new TLSConfiguration(address.get(), keystoreFile, keystorePassword));
57         } else {
58             return Optional.absent();
59         }
60     }
61
62     public static class TLSConfiguration {
63         private final InetSocketAddress address;
64         private final File keystoreFile;
65         private final String keystorePassword;
66         private final SSLContext sslContext;
67
68         TLSConfiguration(InetSocketAddress address, File keystoreFile, String keystorePassword) {
69             this.address = address;
70             this.keystoreFile = keystoreFile;
71             this.keystorePassword = keystorePassword;
72             try {
73                 try (InputStream keyStoreIS = new FileInputStream(keystoreFile)) {
74                     try (InputStream trustStoreIS = new FileInputStream(keystoreFile)) {
75                         sslContext = SSLUtil.initializeSecureContext("password", keyStoreIS, trustStoreIS, KeyManagerFactory.getDefaultAlgorithm());
76                     }
77                 }
78             } catch (Exception e) {
79                 throw new RuntimeException("Cannot initialize ssl context for netconf file " + keystoreFile, e);
80             }
81         }
82
83         public SSLContext getSslContext() {
84             return sslContext;
85         }
86
87         public InetSocketAddress getAddress() {
88             return address;
89         }
90
91         public File getKeystoreFile() {
92             return keystoreFile;
93         }
94
95         public String getKeystorePassword() {
96             return keystorePassword;
97         }
98     }
99
100     /**
101      * @param configProvider
102      *            from which properties are being read.
103      * @param infixProp
104      *            either tcp or tls
105      * @return absent if address is missing, value if address and port are
106      *         valid.
107      * @throws IllegalStateException
108      *             if address or port are invalid
109      */
110     private static Optional<InetSocketAddress> extractSomeNetconfAddress(ConfigProvider configProvider,
111             InfixProp infixProp) {
112         String address = configProvider.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
113         if (address == null) {
114             return Optional.absent();
115         }
116         String portKey = PREFIX_PROP + infixProp + PORT_SUFFIX_PROP;
117         String portString = configProvider.getProperty(portKey);
118         checkNotNull(portString, "Netconf port must be specified in properties file with " + portKey);
119         try {
120             int port = Integer.valueOf(portString);
121             return Optional.of(new InetSocketAddress(address, port));
122         } catch (RuntimeException e) {
123             throw new IllegalStateException("Cannot create " + infixProp + " netconf address from address:" + address
124                     + " and port:" + portString, e);
125         }
126     }
127 }