X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fcallhome-provider%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fcallhome%2Fmount%2FCallHomeAuthProviderImpl.java;h=840dca1ffdee9baea59490135af263efb92a3541;hb=268bde77fa1196a742565202783d5071afa833bf;hp=83869ad286e7f5f23e0305e00eedc4ace990218b;hpb=d56371158176659f4dfae6b2befec10204a82849;p=netconf.git diff --git a/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeAuthProviderImpl.java b/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeAuthProviderImpl.java index 83869ad286..840dca1ffd 100644 --- a/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeAuthProviderImpl.java +++ b/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeAuthProviderImpl.java @@ -7,25 +7,23 @@ */ package org.opendaylight.netconf.callhome.mount; -import com.google.common.base.Objects; import com.google.common.net.InetAddresses; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; +import java.security.GeneralSecurityException; import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.annotation.Nonnull; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; -import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; -import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; -import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netconf.callhome.protocol.AuthorizedKeysDecoder; import org.opendaylight.netconf.callhome.protocol.CallHomeAuthorization; import org.opendaylight.netconf.callhome.protocol.CallHomeAuthorization.Builder; @@ -46,14 +44,14 @@ public class CallHomeAuthProviderImpl implements CallHomeAuthorizationProvider, private static final InstanceIdentifier GLOBAL_PATH = InstanceIdentifier.create(NetconfCallhomeServer.class).child(Global.class); private static final DataTreeIdentifier GLOBAL = - new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, GLOBAL_PATH); + DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, GLOBAL_PATH); private static final InstanceIdentifier ALLOWED_DEVICES_PATH = InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class).child(Device.class); private static final DataTreeIdentifier ALLOWED_DEVICES = - new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, ALLOWED_DEVICES_PATH); + DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, ALLOWED_DEVICES_PATH); private static final DataTreeIdentifier ALLOWED_OP_DEVICES = - new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, ALLOWED_DEVICES_PATH); + DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, ALLOWED_DEVICES_PATH); private final GlobalConfig globalConfig = new GlobalConfig(); private final DeviceConfig deviceConfig = new DeviceConfig(); @@ -64,7 +62,7 @@ public class CallHomeAuthProviderImpl implements CallHomeAuthorizationProvider, private final CallhomeStatusReporter statusReporter; - CallHomeAuthProviderImpl(DataBroker broker) { + CallHomeAuthProviderImpl(final DataBroker broker) { configReg = broker.registerDataTreeChangeListener(GLOBAL, globalConfig); deviceReg = broker.registerDataTreeChangeListener(ALLOWED_DEVICES, deviceConfig); deviceOpReg = broker.registerDataTreeChangeListener(ALLOWED_OP_DEVICES, deviceOp); @@ -73,7 +71,8 @@ public class CallHomeAuthProviderImpl implements CallHomeAuthorizationProvider, @Nonnull @Override - public CallHomeAuthorization provideAuth(SocketAddress remoteAddress, PublicKey serverKey) { + public CallHomeAuthorization provideAuth(@Nonnull final SocketAddress remoteAddress, + @Nonnull final PublicKey serverKey) { Device deviceSpecific = deviceConfig.get(serverKey); String sessionName; Credentials deviceCred; @@ -113,13 +112,13 @@ public class CallHomeAuthProviderImpl implements CallHomeAuthorizationProvider, } @Override - public void close() throws Exception { + public void close() { configReg.close(); deviceReg.close(); deviceOpReg.close(); } - private String fromRemoteAddress(SocketAddress remoteAddress) { + private static String fromRemoteAddress(final SocketAddress remoteAddress) { if (remoteAddress instanceof InetSocketAddress) { InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress; return InetAddresses.toAddrString(socketAddress.getAddress()) + ":" + socketAddress.getPort(); @@ -127,143 +126,134 @@ public class CallHomeAuthProviderImpl implements CallHomeAuthorizationProvider, return remoteAddress.toString(); } - private class DeviceConfig implements DataTreeChangeListener { - - private final AuthorizedKeysDecoder keyDecoder = new AuthorizedKeysDecoder(); - - private ConcurrentMap byPublicKey = new ConcurrentHashMap(); + private abstract static class AbstractDeviceListener implements DataTreeChangeListener { @Override - public void onDataTreeChanged(Collection> mods) { + public final void onDataTreeChanged(final Collection> mods) { for (DataTreeModification dataTreeModification : mods) { - DataObjectModification rootNode = dataTreeModification.getRootNode(); - process(rootNode); - } - } - - private void process(DataObjectModification deviceMod) { - Device before = deviceMod.getDataBefore(); - Device after = deviceMod.getDataAfter(); - - if (before == null) { - putDevice(after); - } else if (after == null) { - // Delete - removeDevice(before); - } else { - if (!Objects.equal(before.getSshHostKey(), after.getSshHostKey())) { - // key changed // we should remove previous key. - removeDevice(before); + final DataObjectModification deviceMod = dataTreeModification.getRootNode(); + final ModificationType modType = deviceMod.getModificationType(); + switch (modType) { + case DELETE: + deleteDevice(deviceMod.getDataBefore()); + break; + case SUBTREE_MODIFIED: + case WRITE: + deleteDevice(deviceMod.getDataBefore()); + writeDevice(deviceMod.getDataAfter()); + break; + default: + throw new IllegalStateException("Unhandled modification type " + modType); } - putDevice(after); } } - private void putDevice(Device device) { - PublicKey key = publicKey(device); - if (key == null) { - return; + private void deleteDevice(final Device dataBefore) { + if (dataBefore != null) { + final String publicKey = dataBefore.getSshHostKey(); + if (publicKey != null) { + LOG.debug("Removing device {}", dataBefore.getUniqueId()); + removeDevice(publicKey, dataBefore); + } else { + LOG.debug("Ignoring removal of device {}, no host key present", dataBefore.getUniqueId()); + } } - byPublicKey.put(key, device); } - private void removeDevice(Device device) { - PublicKey key = publicKey(device); - if (key == null) { - return; + private void writeDevice(final Device dataAfter) { + final String publicKey = dataAfter.getSshHostKey(); + if (publicKey != null) { + LOG.debug("Adding device {}", dataAfter.getUniqueId()); + addDevice(publicKey, dataAfter); + } else { + LOG.debug("Ignoring addition of device {}, no host key present", dataAfter.getUniqueId()); } - byPublicKey.remove(key); } - private PublicKey publicKey(Device device) { - String hostKey = device.getSshHostKey(); - try { - return keyDecoder.decodePublicKey(hostKey); - } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchProviderException e) { - LOG.error("Unable to decode SSH key for {}. Ignoring update for this device", device.getUniqueId(), e); - return null; - } - } + abstract void addDevice(String publicKey, Device device); - private Device get(PublicKey key) { - return byPublicKey.get(key); - } + abstract void removeDevice(String publicKey, Device device); } - private class DeviceOp implements DataTreeChangeListener { + private static class DeviceConfig extends AbstractDeviceListener { + private final ConcurrentMap byPublicKey = new ConcurrentHashMap<>(); + private final AuthorizedKeysDecoder keyDecoder = new AuthorizedKeysDecoder(); - private ConcurrentMap byPublicKey = new ConcurrentHashMap<>(); + Device get(final PublicKey key) { + return byPublicKey.get(key); + } @Override - public void onDataTreeChanged(Collection> mods) { - for (DataTreeModification dataTreeModification : mods) { - DataObjectModification rootNode = dataTreeModification.getRootNode(); - process(rootNode); + void addDevice(final String publicKey, final Device device) { + final PublicKey key = publicKey(publicKey, device); + if (key != null) { + byPublicKey.put(key, device); } } - private void process(DataObjectModification deviceMod) { - Device before = deviceMod.getDataBefore(); - Device after = deviceMod.getDataAfter(); - - if (before == null) { - putDevice(after); - } else if (after == null) { - // Delete - removeDevice(before); - } else { - if (!Objects.equal(before.getSshHostKey(), after.getSshHostKey())) { - // key changed // we should remove previous key. - removeDevice(before); - } - putDevice(after); + @Override + void removeDevice(final String publicKey, final Device device) { + final PublicKey key = publicKey(publicKey, device); + if (key != null) { + byPublicKey.remove(key); } } - private void putDevice(Device device) { - String key = device.getSshHostKey(); - byPublicKey.put(key, device); - } - - private void removeDevice(Device device) { - String key = device.getSshHostKey(); - byPublicKey.remove(key); + private PublicKey publicKey(final String hostKey, final Device device) { + try { + return keyDecoder.decodePublicKey(hostKey); + } catch (GeneralSecurityException e) { + LOG.error("Unable to decode SSH key for {}. Ignoring update for this device", device.getUniqueId(), e); + return null; + } } + } - Device get(PublicKey serverKey) { - String skey = ""; + private static class DeviceOp extends AbstractDeviceListener { + private final ConcurrentMap byPublicKey = new ConcurrentHashMap<>(); + Device get(final PublicKey serverKey) { + final String skey; try { skey = AuthorizedKeysDecoder.encodePublicKey(serverKey); - return byPublicKey.get(skey); } catch (IOException | IllegalArgumentException e) { - LOG.error("Unable to encode server key: {}", skey, e); + LOG.error("Unable to encode server key: {}", serverKey, e); return null; } + + return byPublicKey.get(skey); } - } - private class GlobalConfig implements DataTreeChangeListener { + @Override + void removeDevice(final String publicKey, final Device device) { + byPublicKey.remove(publicKey); + } + @Override + void addDevice(final String publicKey, final Device device) { + byPublicKey.put(publicKey, device); + } + } + + private static class GlobalConfig implements DataTreeChangeListener { private volatile Global current = null; @Override - public void onDataTreeChanged(Collection> mods) { + public void onDataTreeChanged(@Nonnull final Collection> mods) { for (DataTreeModification dataTreeModification : mods) { current = dataTreeModification.getRootNode().getDataAfter(); } } boolean allowedUnknownKeys() { - if (current == null) { - return false; - } + final Global local = current; // Deal with null values. - return Boolean.TRUE.equals(current.isAcceptAllSshKeys()); + return local != null && Boolean.TRUE.equals(local.isAcceptAllSshKeys()); } Credentials getCredentials() { - return current != null ? current.getCredentials() : null; + final Global local = current; + return local != null ? local.getCredentials() : null; } } }