+++ /dev/null
-/*
- * 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";
-}
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;
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;
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());
<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>
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;
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());
}
}
}
-
-
- 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);
- }
- }
}
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.
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);
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);
return localAddress;
}
- public PasswordAuthenticator getAuthenticator() {
+ public AuthProvider getAuthenticator() {
return authenticator;
}
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;
return this;
}
- public SshProxyServerConfigurationBuilder setAuthenticator(final PasswordAuthenticator authenticator) {
+ public SshProxyServerConfigurationBuilder setAuthenticator(final AuthProvider authenticator) {
this.authenticator = authenticator;
return this;
}
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;
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;
@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;
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.";
}
}
- // 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;
+ }
+ }
}
-
}
}
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;
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());
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;
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());
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;
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;
}
})