Netconf SSH bridge has private key stored in distribution.
Path to this file is configured in config.ini.
Change-Id: I517586009c883a537c80fde8205d9040b5fe6052
Signed-off-by: Martin Bobak <mbobak@cisco.com>
netconf.ssh.address=0.0.0.0
netconf.ssh.port=1830
+netconf.ssh.pk.path = ./configuration/RSA.pk
+
netconf.config.persister.active=1,2
# read startup configuration
private void startSSHServer() throws Exception{
logger.info("Creating SSH server");
StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
- AuthProvider ap = new AuthProvider(um);
+ InputStream is = getClass().getResourceAsStream("/RSA.pk");
+ AuthProvider ap = new AuthProvider(um, is);
Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
sshServerThread.setDaemon(true);
sshServerThread.start();
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
package org.opendaylight.controller.netconf.osgi;
import com.google.common.base.Optional;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
EXCEPTION_MESSAGE, true);
if (sshSocketAddressOptional.isPresent()){
- AuthProvider authProvider = new AuthProvider(iUserManager);
+ String path = NetconfConfigUtil.getPrivateKeyPath(context);
+ path = path.replace("\\", "/");
+ if (path.equals("")){
+ throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+ }
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(path);
+ } catch (FileNotFoundException e){
+ throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file.");
+ } catch (SecurityException e){
+ throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file.");
+ }
+ AuthProvider authProvider = null;
+ try {
+ authProvider = new AuthProvider(iUserManager,fis);
+ } catch (Exception e){
+ if (fis!=null){
+ fis.close();
+ }
+ throw (e);
+ }
this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
Thread serverThread = new Thread(server,"netconf SSH server thread");
serverThread.setDaemon(true);
*/
package org.opendaylight.controller.netconf.ssh.authentication;
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.opendaylight.controller.sal.authorization.UserLevel;
import org.opendaylight.controller.usermanager.IUserManager;
import org.opendaylight.controller.usermanager.UserConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AuthProvider implements AuthProviderInterface {
- private static RSAPrivateKey hostkey = null;
private static IUserManager um;
- private static final String DEAFULT_USER = "netconf";
- private static final String DEAFULT_PASSWORD = "netconf";
+ private static final String DEFAULT_USER = "netconf";
+ private static final String DEFAULT_PASSWORD = "netconf";
+ private static InputStream privateKeyFileInputStream;
+ private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class);
- public AuthProvider(IUserManager ium) throws Exception {
+ public AuthProvider(IUserManager ium,InputStream privateKeyFileInputStream) throws Exception {
this.um = ium;
-
if (this.um == null){
throw new Exception("No usermanager service available.");
}
+ this.privateKeyFileInputStream = privateKeyFileInputStream;
+
List<String> roles = new ArrayList<String>(1);
roles.add(UserLevel.SYSTEMADMIN.toString());
- this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+ this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles));
}
@Override
public boolean authenticated(String username, String password) throws Exception {
}
@Override
- public char[] getPEMAsCharArray() {
-
- InputStream is = getClass().getResourceAsStream("/RSA.pk");
- try {
- return IOUtils.toCharArray(is);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
+ public char[] getPEMAsCharArray() throws Exception {
+ char [] PEM = IOUtils.toCharArray(privateKeyFileInputStream);
+ privateKeyFileInputStream.close();
+ return PEM;
}
@Override
public interface AuthProviderInterface {
public boolean authenticated(String username, String password) throws Exception;
- public char[] getPEMAsCharArray();
+ public char[] getPEMAsCharArray() throws Exception;
public void removeUserManagerService();
public void addUserManagerService(IUserManager userManagerService);
}
conn = new ServerConnection(socket);
try {
conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
- } catch (IOException e) {
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.debug("Server authentication setup failed.");
}
conn.setAuthenticationCallback(this);
conn.setServerConnectionCallback(this);
package org.opendaylight.controller.netconf;
import ch.ethz.ssh2.Connection;
+import java.io.InputStream;
import java.net.InetSocketAddress;
import junit.framework.Assert;
import org.junit.Test;
public void startSSHServer() throws Exception{
logger.info("Creating SSH server");
StubUserManager um = new StubUserManager(USER,PASSWORD);
- AuthProvider ap = new AuthProvider(um);
+ InputStream is = getClass().getResourceAsStream("/RSA.pk");
+ AuthProvider ap = new AuthProvider(um, is);
NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
sshServerThread = new Thread(server);
sshServerThread.setDaemon(true);
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
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";
public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) {
return extractSomeNetconfAddress(context, InfixProp.ssh, exceptionMessage, false);
}
+ public static String getPrivateKeyPath(BundleContext context){
+ return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
+ }
+ private static String getPropertyValue(BundleContext context, String propertyName){
+ String propertyValue = context.getProperty(propertyName);
+ if (propertyValue == null){
+ throw new IllegalStateException("Cannot find initial property with name '"+propertyName+"'");
+ }
+ return propertyValue;
+ }
/**
* @param context
* from which properties are being read.