MD-SAL netconf northbound now relies on AAA for authentication 36/26736/3
authorTomas Cere <tcere@cisco.com>
Wed, 9 Sep 2015 14:43:48 +0000 (16:43 +0200)
committerTomas Cere <tcere@cisco.com>
Thu, 10 Sep 2015 07:17:57 +0000 (09:17 +0200)
Change-Id: I58ff18fbcc230c7391617c435897673169052aa9
Signed-off-by: Tomas Cere <tcere@cisco.com>
12 files changed:
opendaylight/netconf/netconf-auth/src/main/java/org/opendaylight/netconf/auth/AuthConstants.java [deleted file]
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-mdsal-config/src/main/resources/initial/08-netconf-mdsal.xml
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/ssh/NetconfNorthboundSshModule.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/netconf/ssh/SshProxyServer.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/netconf/ssh/SshProxyServerConfiguration.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/netconf/ssh/SshProxyServerConfigurationBuilder.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/netconf/ssh/osgi/AuthProviderTracker.java
opendaylight/netconf/netconf-ssh/src/main/yang/netconf-northbound-ssh.yang
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/netconf/netty/SSHTest.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/netconf/ssh/authentication/SSHServerTest.java
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java

diff --git a/opendaylight/netconf/netconf-auth/src/main/java/org/opendaylight/netconf/auth/AuthConstants.java b/opendaylight/netconf/netconf-auth/src/main/java/org/opendaylight/netconf/auth/AuthConstants.java
deleted file mode 100644 (file)
index a5340de..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.auth;
-
-public class AuthConstants {
-
-    /**
-     * This property should be set for every implementation of AuthService published to OSGi.
-     * Netconf SSH will pick the service with highest preference in case of multiple services present in OSGi.
-     */
-    public static final String SERVICE_PREFERENCE_KEY = "preference";
-}
index 33312e7e95c229722bc231d307003478696f04e3..d39f2e5de4900c2a5bb4554a2ecc97b21756f065 100644 (file)
@@ -35,9 +35,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -53,14 +51,14 @@ import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.netconf.ssh.SshProxyServer;
-import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
 import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.ssh.SshProxyServer;
+import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
+import org.opendaylight.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -90,13 +88,13 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
                 new SshProxyServerConfigurationBuilder()
                         .setBindingAddress(TLS_ADDRESS)
                         .setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress())
-                        .setAuthenticator(new PasswordAuthenticator() {
-                            @Override
-                            public boolean authenticate(final String username, final String password, final ServerSession session) {
-                                return true;
-                            }
-                        }
-                    )
+                        .setAuthenticator(new AuthProvider() {
+                                              @Override
+                                              public boolean authenticated(String username, String password) {
+                                                  return true;
+                                              }
+                                          }
+                        )
                         .setKeyPairProvider(new PEMGeneratorHostKeyProvider(Files.createTempFile("prefix", "suffix").toAbsolutePath().toString()))
                         .setIdleTimeout(Integer.MAX_VALUE)
                         .createSshProxyServerConfiguration());
index 72a3dcf3885165aad54083ad4774d62e4fe29f8d..be3bb09ed529af84af8cf526899875f31d1fa4cf 100644 (file)
                   <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-dispatcher</type>
                   <name>netconf-mdsal-server-dispatcher</name>
               </dispatcher>
-
-              <username>admin</username>
-              <password>admin</password>
+              <auth-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">
+                  <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:auth">prefix:netconf-auth-provider</type>
+                  <name>default-auth-provider</name>
+              </auth-provider>
           </module>
 
 
index 8d0afa9738b56bec757049e3af9c3502ae19670f..f212edc2d3f3a4f44aae85d53c1fa06d993d2afa 100644 (file)
@@ -8,9 +8,7 @@ import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.concurrent.Executors;
-import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
 import org.opendaylight.netconf.api.NetconfServerDispatcher;
 import org.opendaylight.netconf.ssh.SshProxyServer;
 import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
@@ -47,7 +45,7 @@ public class NetconfNorthboundSshModule extends org.opendaylight.controller.conf
         final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder = new SshProxyServerConfigurationBuilder();
         sshProxyServerConfigurationBuilder.setBindingAddress(bindingAddress);
         sshProxyServerConfigurationBuilder.setLocalAddress(localAddress);
-        sshProxyServerConfigurationBuilder.setAuthenticator(new UserAuthenticator(getUsername(), getPassword()));
+        sshProxyServerConfigurationBuilder.setAuthenticator(getAuthProviderDependency());
         sshProxyServerConfigurationBuilder.setIdleTimeout(Integer.MAX_VALUE);
         sshProxyServerConfigurationBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider());
 
@@ -101,22 +99,4 @@ public class NetconfNorthboundSshModule extends org.opendaylight.controller.conf
             }
         }
     }
-
-
-    private static final class UserAuthenticator implements PasswordAuthenticator {
-
-        private final String username;
-        private final String password;
-
-        public UserAuthenticator(final String username, final String password) {
-            this.username = username;
-            this.password = password;
-        }
-
-        @Override
-        public boolean authenticate(final String username, final String password, final ServerSession session) {
-            // FIXME use aaa stuff here instead
-            return this.username.equals(username) && this.password.equals(password);
-        }
-    }
 }
index ccf5744fab0bf1ab465b29dd5817b2e7e93d5475..57c6789f78f6a307c07bcdd354972355ea217bec 100644 (file)
@@ -36,7 +36,9 @@ import org.apache.sshd.common.io.nio2.Nio2Connector;
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
 import org.apache.sshd.common.util.CloseableUtils;
 import org.apache.sshd.server.Command;
+import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.ServerFactoryManager;
+import org.apache.sshd.server.session.ServerSession;
 
 /**
  * Proxy SSH server that just delegates decrypted content to a delegate server within same VM.
@@ -71,7 +73,13 @@ public class SshProxyServer implements AutoCloseable {
                 i.remove();
             }
         }
-        sshServer.setPasswordAuthenticator(sshProxyServerConfiguration.getAuthenticator());
+        sshServer.setPasswordAuthenticator(new PasswordAuthenticator() {
+            @Override
+            public boolean authenticate(final String username, final String password, final ServerSession session) {
+                return sshProxyServerConfiguration.getAuthenticator().authenticated(username, password);
+            }
+        });
+
         sshServer.setKeyPairProvider(sshProxyServerConfiguration.getKeyPairProvider());
 
         sshServer.setIoServiceFactoryFactory(nioServiceWithPoolFactoryFactory);
index 85688c482a6e971579537ccdb6cf73faa92463e5..55b54862d2e2abcea38ba1bc61ba3a00f1e3dfc0 100644 (file)
@@ -12,16 +12,16 @@ import com.google.common.base.Preconditions;
 import io.netty.channel.local.LocalAddress;
 import java.net.InetSocketAddress;
 import org.apache.sshd.common.KeyPairProvider;
-import org.apache.sshd.server.PasswordAuthenticator;
+import org.opendaylight.netconf.auth.AuthProvider;
 
 public final class SshProxyServerConfiguration {
     private final InetSocketAddress bindingAddress;
     private final LocalAddress localAddress;
-    private final PasswordAuthenticator authenticator;
+    private final AuthProvider authenticator;
     private final KeyPairProvider keyPairProvider;
     private final int idleTimeout;
 
-    SshProxyServerConfiguration(final InetSocketAddress bindingAddress, final LocalAddress localAddress, final PasswordAuthenticator authenticator, final KeyPairProvider keyPairProvider, final int idleTimeout) {
+    SshProxyServerConfiguration(final InetSocketAddress bindingAddress, final LocalAddress localAddress, final AuthProvider authenticator, final KeyPairProvider keyPairProvider, final int idleTimeout) {
         this.bindingAddress = Preconditions.checkNotNull(bindingAddress);
         this.localAddress = Preconditions.checkNotNull(localAddress);
         this.authenticator = Preconditions.checkNotNull(authenticator);
@@ -39,7 +39,7 @@ public final class SshProxyServerConfiguration {
         return localAddress;
     }
 
-    public PasswordAuthenticator getAuthenticator() {
+    public AuthProvider getAuthenticator() {
         return authenticator;
     }
 
index 477eea4ff4b816fea8a9d6f99e668eecf1412a02..14b00b462d93c6942f413fc4551f16e7cf832117 100644 (file)
@@ -11,12 +11,12 @@ package org.opendaylight.netconf.ssh;
 import io.netty.channel.local.LocalAddress;
 import java.net.InetSocketAddress;
 import org.apache.sshd.common.KeyPairProvider;
-import org.apache.sshd.server.PasswordAuthenticator;
+import org.opendaylight.netconf.auth.AuthProvider;
 
 public final class SshProxyServerConfigurationBuilder {
     private InetSocketAddress bindingAddress;
     private LocalAddress localAddress;
-    private PasswordAuthenticator authenticator;
+    private AuthProvider authenticator;
     private KeyPairProvider keyPairProvider;
     private int idleTimeout;
 
@@ -30,7 +30,7 @@ public final class SshProxyServerConfigurationBuilder {
         return this;
     }
 
-    public SshProxyServerConfigurationBuilder setAuthenticator(final PasswordAuthenticator authenticator) {
+    public SshProxyServerConfigurationBuilder setAuthenticator(final AuthProvider authenticator) {
         this.authenticator = authenticator;
         return this;
     }
index 7b2d840d2e1578ee44188e43376f427db4cd4b86..51be1bc3eae126e1e1204d2ef626fcb3433366cc 100644 (file)
@@ -8,10 +8,6 @@
 
 package org.opendaylight.netconf.ssh.osgi;
 
-import com.google.common.base.Preconditions;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.netconf.auth.AuthConstants;
 import org.opendaylight.netconf.auth.AuthProvider;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -20,14 +16,13 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class AuthProviderTracker implements ServiceTrackerCustomizer<AuthProvider, AuthProvider>, PasswordAuthenticator {
+final class AuthProviderTracker implements ServiceTrackerCustomizer<AuthProvider, AuthProvider>, AuthProvider {
     private static final Logger LOG = LoggerFactory.getLogger(AuthProviderTracker.class);
 
     private final BundleContext bundleContext;
 
-    private Integer maxPreference;
     private final ServiceTracker<AuthProvider, AuthProvider> listenerTracker;
-    private AuthProvider authProvider;
+    private volatile AuthProvider authProvider;
 
     public AuthProviderTracker(final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
@@ -38,54 +33,32 @@ final class AuthProviderTracker implements ServiceTrackerCustomizer<AuthProvider
     @Override
     public AuthProvider addingService(final ServiceReference<AuthProvider> reference) {
         LOG.trace("Service {} added", reference);
-        final AuthProvider authService = bundleContext.getService(reference);
-        final Integer newServicePreference = getPreference(reference);
-        if(isBetter(newServicePreference)) {
-            maxPreference = newServicePreference;
-            this.authProvider = authService;
-        }
-        return authService;
-    }
-
-    private static Integer getPreference(final ServiceReference<AuthProvider> reference) {
-        final Object preferenceProperty = reference.getProperty(AuthConstants.SERVICE_PREFERENCE_KEY);
-        return preferenceProperty == null ? Integer.MIN_VALUE : Integer.valueOf(preferenceProperty.toString());
-    }
-
-    private boolean isBetter(final Integer newServicePreference) {
-        Preconditions.checkNotNull(newServicePreference);
-        if(maxPreference == null) {
-            return true;
-        }
-
-        return newServicePreference > maxPreference;
+        this.authProvider = bundleContext.getService(reference);
+        return authProvider;
     }
 
     @Override
     public void modifiedService(final ServiceReference<AuthProvider> reference, final AuthProvider service) {
         final AuthProvider authService = bundleContext.getService(reference);
-        final Integer newServicePreference = getPreference(reference);
-        if(isBetter(newServicePreference)) {
-            LOG.trace("Replacing modified service {} in netconf SSH.", reference);
-            this.authProvider = authService;
-        }
+        LOG.trace("Replacing modified service {} in netconf SSH.", reference);
+        this.authProvider = authService;
     }
 
     @Override
     public void removedService(final ServiceReference<AuthProvider> reference, final AuthProvider service) {
         LOG.trace("Removing service {} from netconf SSH. {}", reference,
                 " SSH won't authenticate users until AuthProvider service will be started.");
-        maxPreference = null;
         this.authProvider = null;
     }
 
     public void stop() {
         listenerTracker.close();
+        this.authProvider = null;
         // sshThread should finish normally since sshServer.close stops processing
     }
 
     @Override
-    public boolean authenticate(final String username, final String password, final ServerSession session) {
+    public boolean authenticated(final String username, final String password) {
         if (authProvider == null) {
             LOG.warn("AuthProvider is missing, failing authentication");
             return false;
index 2e9d0b15b4ffad8b7bd16ef958dd68142e522817..4fa945e54cd6a7c3015933d067800ffb3b7dca90 100644 (file)
@@ -9,6 +9,7 @@ module netconf-northbound-ssh {
     import threadpool {prefix th;}
     import netty {prefix netty;}
     import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+    import netconf-auth { prefix na; revision-date 2015-07-15; }
 
     organization "Cisco Systems, Inc.";
 
@@ -76,18 +77,14 @@ module netconf-northbound-ssh {
                 }
             }
 
-            // FIXME use auth provider from aaa instead
-            leaf username {
-                description "Specifies username credential";
-                type string;
-            }
-
-            leaf password {
-                description "Specifies password credential";
-                type string;
+            container auth-provider {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity na:netconf-auth-provider;
+                    }
+                }
             }
 
-
         }
     }
 
index d5aefbb7726286f78b0e6744ca01b018bd7ec093..b7379808cf3d941374abd6b4f025b59c3243771e 100644 (file)
@@ -26,12 +26,11 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.netconf.auth.AuthProvider;
 import org.opendaylight.netconf.netty.EchoClientHandler.State;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
@@ -75,9 +74,9 @@ public class SSHTest {
         final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
         final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec);
         sshProxyServer.bind(
-                new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
+                new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new AuthProvider() {
                     @Override
-                    public boolean authenticate(final String username, final String password, final ServerSession session) {
+                    public boolean authenticated(final String username, final String password) {
                         return true;
                     }
                 }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
index ecef31338766eae588d8e4e6b87e104801dc2b34..f0350247187a925132de8aae7fab374d863bc0ca 100644 (file)
@@ -25,13 +25,12 @@ import org.apache.sshd.ClientSession;
 import org.apache.sshd.SshClient;
 import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.future.ConnectFuture;
-import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.opendaylight.netconf.auth.AuthProvider;
 import org.opendaylight.netconf.ssh.SshProxyServer;
 import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
 import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
@@ -74,9 +73,9 @@ public class SSHServerTest {
         final InetSocketAddress addr = InetSocketAddress.createUnresolved(HOST, PORT);
         server = new SshProxyServer(minaTimerEx, clientGroup, nioExec);
         server.bind(
-                new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
+                new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new AuthProvider() {
                     @Override
-                    public boolean authenticate(final String username, final String password, final ServerSession session) {
+                    public boolean authenticated(final String username, final String password) {
                         return true;
                     }
                 }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
index 7e04430a6979cdcf1cb8fa43774cc3792b67bf49..edf74ca4c6ec02c6e20e9772a898072ab5b90947 100644 (file)
@@ -51,13 +51,12 @@ import java.util.concurrent.ScheduledExecutorService;
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.apache.sshd.common.util.ThreadUtils;
-import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
 import org.opendaylight.controller.config.util.capability.BasicCapability;
 import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.netconf.auth.AuthProvider;
 import org.opendaylight.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.netconf.impl.SessionIdProvider;
@@ -277,9 +276,9 @@ public class NetconfDeviceSimulator implements Closeable {
         return new SshProxyServerConfigurationBuilder()
                 .setBindingAddress(bindingAddress)
                 .setLocalAddress(tcpLocalAddress)
-                .setAuthenticator(new PasswordAuthenticator() {
+                .setAuthenticator(new AuthProvider() {
                     @Override
-                    public boolean authenticate(final String username, final String password, final ServerSession session) {
+                    public boolean authenticated(final String username, final String password) {
                         return true;
                     }
                 })