From: Martin Bobak Date: Thu, 10 Apr 2014 09:10:35 +0000 (+0200) Subject: Default auth parameters in config.ini. X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~160^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=892e5047abfe83a7b2b92d6fe956b9a64af40adb Default auth parameters in config.ini. Hardcoded default username and password for ssh authenticaton moved from AuthProvider.java to config.ini IUSerManager in AuthProvider.java is not static anymore. Change-Id: Ia4fd2cddf42d17842869d599d645881b77d2afbd Signed-off-by: Martin Bobak --- diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index 9d0d6c1888..234e0feb45 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -22,6 +22,8 @@ netconf.tcp.client.port=8383 netconf.ssh.address=0.0.0.0 netconf.ssh.port=1830 netconf.ssh.pk.path = ./configuration/RSA.pk +netconf.ssh.default.user = netconf +netconf.ssh.default.password = netconf netconf.config.persister.active=1,2 diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 857cc3e2e5..b77d92e7cb 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -13,6 +13,20 @@ import ch.ethz.ssh2.Session; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import io.netty.channel.ChannelFuture; +import java.io.IOException; +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; import junit.framework.Assert; import org.apache.commons.io.IOUtils; import org.junit.After; @@ -52,22 +66,6 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; - -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - import static java.util.Collections.emptyList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -411,7 +409,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { try { c = sess.getStdout().read(bytes); } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + throw new IllegalStateException("IO exception while reading data on ssh bridge."); } logger.info("got data:" + bytes); if (c == 0) { diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index 6ddc8ebb55..2e9a0b9d8b 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -7,42 +7,26 @@ */ package org.opendaylight.controller.netconf.ssh.authentication; +import java.io.IOException; import org.opendaylight.controller.sal.authorization.AuthResultEnum; -import org.opendaylight.controller.sal.authorization.UserLevel; import org.opendaylight.controller.usermanager.IUserManager; -import org.opendaylight.controller.usermanager.UserConfig; - -import java.util.ArrayList; -import java.util.List; - import static com.google.common.base.Preconditions.checkNotNull; public class AuthProvider implements AuthProviderInterface { - private static IUserManager um; //FIXME static mutable state, no locks - private static final String DEFAULT_USER = "netconf"; - private static final String DEFAULT_PASSWORD = "netconf"; + private IUserManager um; private final String pem; - public AuthProvider(IUserManager ium, String pemCertificate) throws Exception { + public AuthProvider(IUserManager ium, String pemCertificate) throws IllegalArgumentException, IOException { checkNotNull(pemCertificate, "Parameter 'pemCertificate' is null"); - AuthProvider.um = ium; - if (AuthProvider.um == null) { - throw new Exception("No usermanager service available."); - } - - List roles = new ArrayList(1); - roles.add(UserLevel.SYSTEMADMIN.toString()); - AuthProvider.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); //FIXME hardcoded auth + checkNotNull(ium, "No user manager service available."); + this.um = ium; pem = pemCertificate; } @Override public boolean authenticated(String username, String password) { - if (AuthProvider.um == null) { - throw new IllegalStateException("No usermanager service available."); - } - AuthResultEnum authResult = AuthProvider.um.authenticate(username, password); + AuthResultEnum authResult = this.um.authenticate(username, password); return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC); } @@ -53,11 +37,11 @@ public class AuthProvider implements AuthProviderInterface { @Override public void removeUserManagerService() { - AuthProvider.um = null; + this.um = null; } @Override public void addUserManagerService(IUserManager userManagerService) { - AuthProvider.um = userManagerService; + this.um = userManagerService; } } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java index 5b8803001c..ca0c9454d4 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java @@ -8,12 +8,21 @@ package org.opendaylight.controller.netconf.ssh.osgi; import com.google.common.base.Optional; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator; import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; +import org.opendaylight.controller.sal.authorization.UserLevel; import org.opendaylight.controller.usermanager.IUserManager; +import org.opendaylight.controller.usermanager.UserConfig; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -21,16 +30,12 @@ import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.InetSocketAddress; +import static com.google.common.base.Preconditions.checkNotNull; /** * Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator * starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket - * and listen for client connections. Each client connection creation is handled in separate + * and listens for client connections. Each client connection creation is handled in separate * {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread. * This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread} * forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream. @@ -44,6 +49,8 @@ public class NetconfSSHActivator implements BundleActivator{ private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available."; private IUserManager iUserManager; private BundleContext context = null; + private Optional defaultPassword; + private Optional defaultUser; private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ @Override @@ -79,20 +86,23 @@ public class NetconfSSHActivator implements BundleActivator{ @Override public void stop(BundleContext context) throws IOException { + if (this.defaultUser.isPresent()){ + this.iUserManager.removeLocalUser(this.defaultUser.get()); + } if (server != null){ server.stop(); logger.trace("Netconf SSH bridge is down ..."); } } private void startSSHServer() throws IllegalStateException, IOException { + checkNotNull(this.iUserManager, "No user manager service available."); logger.trace("Starting netconf SSH bridge."); Optional sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE); InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context, EXCEPTION_MESSAGE, true); if (sshSocketAddressOptional.isPresent()){ - String path = NetconfConfigUtil.getPrivateKeyPath(context); - path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator? + String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context)); if (path.equals("")){ throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file."); } @@ -100,11 +110,10 @@ public class NetconfSSHActivator implements BundleActivator{ File privateKeyFile = new File(path); String privateKeyPEMString = null; if (privateKeyFile.exists() == false) { - // generate & save to file try { privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); } catch (Exception e) { - logger.error("Exception occured while generating PEM string {}",e); + logger.error("Exception occurred while generating PEM string {}",e); } } else { // read from file @@ -117,6 +126,17 @@ public class NetconfSSHActivator implements BundleActivator{ } AuthProvider authProvider = null; try { + this.defaultPassword = NetconfConfigUtil.getSSHDefaultPassword(context); + this.defaultUser = NetconfConfigUtil.getSSHDefaultUser(context); + // Since there is no user data store yet (ldap, ...) this adds default user/password to UserManager + // if these parameters are set in netconf configuration file. + if (defaultUser.isPresent() && + defaultPassword.isPresent()){ + logger.trace(String.format("Default username and password for netconf ssh bridge found. Adding user %s to user manager.",defaultUser.get())); + List roles = new ArrayList(1); + roles.add(UserLevel.SYSTEMADMIN.toString()); + iUserManager.addLocalUser(new UserConfig(defaultUser.get(), defaultPassword.get(), roles)); + } authProvider = new AuthProvider(iUserManager, privateKeyPEMString); } catch (Exception e) { logger.error("Error instantiating AuthProvider {}",e); 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 b23a2d6697..f89df2ac7c 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,12 +9,11 @@ package org.opendaylight.controller.netconf.util.osgi; import com.google.common.base.Optional; +import com.google.common.base.Strings; +import java.net.InetSocketAddress; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.net.InetSocketAddress; - import static com.google.common.base.Preconditions.checkNotNull; public final class NetconfConfigUtil { @@ -32,6 +31,8 @@ public final class NetconfConfigUtil { 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 SSH_DEFAULT_USER = ".default.user"; + private static final String SSH_DEFAULT_PASSWORD = ".default.password"; private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis"; private static final long DEFAULT_TIMEOUT_MILLIS = 5000; @@ -72,6 +73,13 @@ public final class NetconfConfigUtil { public static String getPrivateKeyPath(BundleContext context){ return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP); } + public static Optional getSSHDefaultUser(BundleContext context){ + return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER); + } + public static Optional getSSHDefaultPassword(BundleContext context){ + return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_PASSWORD); + } + private static String getPropertyValue(BundleContext context, String propertyName){ String propertyValue = context.getProperty(propertyName); if (propertyValue == null){ @@ -79,6 +87,13 @@ public final class NetconfConfigUtil { } return propertyValue; } + private static Optional getOptionalPropertyValue(BundleContext context, String propertyName){ + String propertyValue = context.getProperty(propertyName); + if (Strings.isNullOrEmpty(propertyValue)){ + return Optional.absent(); + } + return Optional.fromNullable(propertyValue); + } /** * @param context * from which properties are being read.