- File privateKeyFile = new File(path);
- String privateKeyPEMString = null;
- if (privateKeyFile.exists() == false) {
- try {
- privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
- } catch (Exception e) {
- logger.error("Exception occurred while generating PEM string {}",e);
- }
- } else {
- // read from file
- try (FileInputStream fis = new FileInputStream(path)) {
- privateKeyPEMString = IOUtils.toString(fis);
- } catch (IOException e) {
- logger.error("Error reading RSA key from file '{}'", path);
- throw new IllegalStateException("Error reading RSA key from file " + path);
+ private static NetconfSSHServer startSSHServer(final BundleContext bundleContext) throws IOException {
+ final Optional<InetSocketAddress> maybeSshSocketAddress = NetconfConfigUtil.extractNetconfServerAddress(bundleContext,
+ InfixProp.ssh);
+
+ if (maybeSshSocketAddress.isPresent() == false) {
+ logger.trace("SSH bridge not configured");
+ return null;
+ }
+
+ final InetSocketAddress sshSocketAddress = maybeSshSocketAddress.get();
+ logger.trace("Starting netconf SSH bridge at {}", sshSocketAddress);
+
+ final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
+
+ final String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(bundleContext));
+ checkState(!Strings.isNullOrEmpty(path), "Path to ssh private key is blank. Reconfigure %s", NetconfConfigUtil.getPrivateKeyKey());
+ final String privateKeyPEMString = PEMGenerator.readOrGeneratePK(new File(path));
+
+ final EventLoopGroup bossGroup = new NioEventLoopGroup();
+ final NetconfSSHServer server = NetconfSSHServer.start(sshSocketAddress.getPort(), localAddress, bossGroup, privateKeyPEMString.toCharArray());
+
+ authProviderTracker = new AuthProviderTracker(bundleContext, server);
+
+ return server;
+ }
+
+ private static Thread runNetconfSshThread(final NetconfSSHServer server) {
+ final Thread serverThread = new Thread(server, "netconf SSH server thread");
+ serverThread.setDaemon(true);
+ serverThread.start();
+ logger.trace("Netconf SSH bridge up and running.");
+ return serverThread;
+ }
+
+ private static class AuthProviderTracker implements ServiceTrackerCustomizer<AuthProvider, AuthProvider> {
+ private final BundleContext bundleContext;
+ private final NetconfSSHServer server;
+
+ private Integer maxPreference;
+ private Thread sshThread;
+ private final ServiceTracker<AuthProvider, AuthProvider> listenerTracker;
+
+ public AuthProviderTracker(final BundleContext bundleContext, final NetconfSSHServer server) {
+ this.bundleContext = bundleContext;
+ this.server = server;
+ listenerTracker = new ServiceTracker<>(bundleContext, AuthProvider.class, this);
+ listenerTracker.open();
+ }
+
+ @Override
+ public AuthProvider addingService(final ServiceReference<AuthProvider> reference) {
+ logger.trace("Service {} added", reference);
+ final AuthProvider authService = bundleContext.getService(reference);
+ final Integer newServicePreference = getPreference(reference);
+ if(isBetter(newServicePreference)) {
+ maxPreference = newServicePreference;
+ server.setAuthProvider(authService);
+ if(sshThread == null) {
+ sshThread = runNetconfSshThread(server);