You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/11/23 11:59:56 UTC

mina-sshd git commit: [SSHD-597] Allow the caller to intervene if failed to resolve an authorized key entry

Repository: mina-sshd
Updated Branches:
  refs/heads/master b2c0b47a1 -> 2867cbe67


[SSHD-597] Allow the caller to intervene if failed to resolve an authorized key entry


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/2867cbe6
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/2867cbe6
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/2867cbe6

Branch: refs/heads/master
Commit: 2867cbe674d991a762d54d86ef006652151f3b2e
Parents: b2c0b47
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Nov 23 12:59:44 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Nov 23 12:59:44 2015 +0200

----------------------------------------------------------------------
 .../keys/AbstractPublicKeyEntryDecoder.java     | 11 ++++
 .../sshd/common/config/keys/PublicKeyEntry.java | 57 +++++++++-------
 .../config/keys/PublicKeyEntryDecoder.java      |  2 +-
 .../config/keys/PublicKeyEntryResolver.java     | 69 ++++++++++++++++++++
 .../server/config/keys/AuthorizedKeyEntry.java  | 19 ++++--
 .../keys/AuthorizedKeysAuthenticator.java       |  7 +-
 .../common/config/keys/PublicKeyEntryTest.java  | 59 +++++++++++++++++
 .../config/keys/AuthorizedKeyEntryTest.java     |  9 +--
 .../keys/AuthorizedKeysAuthenticatorTest.java   |  3 +-
 .../config/keys/AuthorizedKeysTestSupport.java  |  2 +
 .../DefaultAuthorizedKeysAuthenticatorTest.java |  3 +-
 11 files changed, 201 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
index 15d7ae0..1fb988b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
@@ -105,6 +105,17 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey, PRV e
         return new KeyPair(pubCloned, prvCloned);
     }
 
+    @Override   // TODO make this a default method in Java-8
+    public PublicKey resolve(String keyType, byte[] keyData) throws IOException, GeneralSecurityException {
+        ValidateUtils.checkNotNullAndNotEmpty(keyType, "No key type provided");
+        Collection<String> supported = getSupportedTypeNames();
+        if ((GenericUtils.size(supported) > 0) && supported.contains(keyType)) {
+            return decodePublicKey(keyData);
+        }
+
+        throw new InvalidKeySpecException("resolve(" + keyType + ") not in listed supported types: " + supported);
+    }
+
     @Override
     public Collection<String> getSupportedTypeNames() {
         return names;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
index b533823..d2388ea 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 import java.io.StreamCorruptedException;
 import java.nio.file.Path;
 import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
 import java.security.PublicKey;
 import java.security.spec.InvalidKeySpecException;
 import java.util.Arrays;
@@ -33,7 +32,6 @@ import java.util.Objects;
 
 import org.apache.sshd.common.util.Base64;
 import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.buffer.BufferUtils;
 
 /**
  * <P>Represents a {@link PublicKey} whose data is formatted according to
@@ -89,45 +87,49 @@ public class PublicKeyEntry implements Serializable {
     }
 
     /**
-     * @return The resolved {@link PublicKey} - never {@code null}.
-     * <B>Note:</B> may be called only after key type and data bytes have
-     * been set or exception(s) may be thrown
+     * @param fallbackResolver The {@link PublicKeyEntryResolver} to consult if
+     * none of the built-in ones can be used. If {@code null} and no built-in
+     * resolver can be used then an {@link InvalidKeySpecException} is thrown.
+     * @return The resolved {@link PublicKey} - or {@code null} if could not be
+     * resolved. <B>Note:</B> may be called only after key type and data bytes
+     * have been set or exception(s) may be thrown
      * @throws IOException              If failed to decode the key
      * @throws GeneralSecurityException If failed to generate the key
      */
-    public PublicKey resolvePublicKey() throws IOException, GeneralSecurityException {
+    public PublicKey resolvePublicKey(PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException {
         String kt = getKeyType();
-        PublicKeyEntryDecoder<?, ?> decoder = KeyUtils.getPublicKeyEntryDecoder(kt);
+        PublicKeyEntryResolver decoder = KeyUtils.getPublicKeyEntryDecoder(kt);
         if (decoder == null) {
-            throw new InvalidKeySpecException("No decoder registered for key type=" + kt);
+            decoder = fallbackResolver;
         }
-
-        byte[] data = getKeyData();
-        PublicKey key = decoder.decodePublicKey(data);
-        if (key == null) {
-            throw new InvalidKeyException("No key of type=" + kt + " decoded for data=" + BufferUtils.printHex(':', data));
+        if (decoder == null) {
+            throw new InvalidKeySpecException("No decoder available for key type=" + kt);
         }
 
-        return key;
+        return decoder.resolve(kt, getKeyData());
     }
 
     /**
      * @param sb The {@link Appendable} instance to encode the data into
-     * @return The {@link PublicKey}
+     * @param fallbackResolver The {@link PublicKeyEntryResolver} to consult if
+     * none of the built-in ones can be used. If {@code null} and no built-in
+     * resolver can be used then an {@link InvalidKeySpecException} is thrown.
+     * @return The {@link PublicKey} or {@code null} if could not resolve it
      * @throws IOException              If failed to decode/encode the key
      * @throws GeneralSecurityException If failed to generate the key
-     * @see #resolvePublicKey()
+     * @see #resolvePublicKey(PublicKeyEntryResolver)
      */
-    public PublicKey appendPublicKey(Appendable sb) throws IOException, GeneralSecurityException {
-        PublicKey key = resolvePublicKey();
-        appendPublicKeyEntry(sb, key);
+    public PublicKey appendPublicKey(Appendable sb, PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException {
+        PublicKey key = resolvePublicKey(fallbackResolver);
+        if (key != null) {
+            appendPublicKeyEntry(sb, key);
+        }
         return key;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(getKeyType())
-                + Arrays.hashCode(getKeyData());
+        return Objects.hashCode(getKeyType()) + Arrays.hashCode(getKeyData());
     }
 
     /*
@@ -139,7 +141,7 @@ public class PublicKeyEntry implements Serializable {
             return true;
         }
         return Objects.equals(getKeyType(), e.getKeyType())
-                && Arrays.equals(getKeyData(), e.getKeyData());
+            && Arrays.equals(getKeyData(), e.getKeyData());
     }
 
     @Override
@@ -232,15 +234,20 @@ public class PublicKeyEntry implements Serializable {
      *
      * @param <A> The generic appendable class
      * @param sb  The {@link Appendable} instance to encode the data into
-     * @param key The {@link PublicKey}
+     * @param key The {@link PublicKey} - ignored if {@code null}
      * @return The updated appendable instance
      * @throws IOException If failed to append the data
      */
     public static <A extends Appendable> A appendPublicKeyEntry(A sb, PublicKey key) throws IOException {
+        if (key == null) {
+            return sb;
+        }
+
         @SuppressWarnings("unchecked")
-        PublicKeyEntryDecoder<PublicKey, ?> decoder = (PublicKeyEntryDecoder<PublicKey, ?>) KeyUtils.getPublicKeyEntryDecoder(key);
+        PublicKeyEntryDecoder<PublicKey, ?> decoder =
+            (PublicKeyEntryDecoder<PublicKey, ?>) KeyUtils.getPublicKeyEntryDecoder(key);
         if (decoder == null) {
-            throw new StreamCorruptedException("Cannot retrived decoder for key=" + key.getAlgorithm());
+            throw new StreamCorruptedException("Cannot retrieve decoder for key=" + key.getAlgorithm());
         }
 
         try (ByteArrayOutputStream s = new ByteArrayOutputStream(Byte.MAX_VALUE)) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryDecoder.java
index ed8c8a4..53b35dd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryDecoder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryDecoder.java
@@ -37,7 +37,7 @@ import java.util.Collection;
  * @param <PRV> Type of {@link PrivateKey}
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface PublicKeyEntryDecoder<PUB extends PublicKey, PRV extends PrivateKey> {
+public interface PublicKeyEntryDecoder<PUB extends PublicKey, PRV extends PrivateKey> extends PublicKeyEntryResolver {
     /**
      * @return The {@link Class} of the {@link PublicKey} that is the result
      * of decoding

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryResolver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryResolver.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryResolver.java
new file mode 100644
index 0000000..6fd9b14
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntryResolver.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.config.keys;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface PublicKeyEntryResolver {
+    /**
+     * A resolver that ignores all input
+     */
+    PublicKeyEntryResolver IGNORING = new PublicKeyEntryResolver() {
+        @Override
+        public PublicKey resolve(String keyType, byte[] keyData) throws IOException, GeneralSecurityException {
+            return null;
+        }
+
+        @Override
+        public String toString() {
+            return "IGNORING";
+        }
+    };
+
+    /**
+     * A resolver that fails on all input
+     */
+    PublicKeyEntryResolver FAILING = new PublicKeyEntryResolver() {
+        @Override
+        public PublicKey resolve(String keyType, byte[] keyData) throws IOException, GeneralSecurityException {
+            throw new InvalidKeySpecException("Failing resolver on key type=" + keyType);
+        }
+
+        @Override
+        public String toString() {
+            return "FAILING";
+        }
+    };
+
+    /**
+     * @param keyType The {@code OpenSSH} reported key type
+     * @param keyData The {@code OpenSSH} encoded key data
+     * @return The extracted {@link PublicKey} - ignored if {@code null}
+     * @throws IOException If failed to parse the key data
+     * @throws GeneralSecurityException If failed to generate the key
+     */
+    PublicKey resolve(String keyType, byte[] keyData) throws IOException, GeneralSecurityException;
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntry.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntry.java b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntry.java
index 142dd5b..c57cde5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntry.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntry.java
@@ -44,6 +44,7 @@ import java.util.TreeMap;
 import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.config.keys.PublicKeyEntry;
 import org.apache.sshd.common.config.keys.PublicKeyEntryDecoder;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.common.util.io.NoCloseInputStream;
@@ -102,7 +103,7 @@ public class AuthorizedKeyEntry extends PublicKeyEntry {
     }
 
     @Override
-    public PublicKey appendPublicKey(Appendable sb) throws IOException, GeneralSecurityException {
+    public PublicKey appendPublicKey(Appendable sb, PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException {
         Map<String, String> options = getLoginOptions();
         if (!GenericUtils.isEmpty(options)) {
             int index = 0;
@@ -126,7 +127,7 @@ public class AuthorizedKeyEntry extends PublicKeyEntry {
             }
         }
 
-        PublicKey key = super.appendPublicKey(sb);
+        PublicKey key = super.appendPublicKey(sb, fallbackResolver);
         String kc = getComment();
         if (!GenericUtils.isEmpty(kc)) {
             sb.append(' ').append(kc);
@@ -145,8 +146,9 @@ public class AuthorizedKeyEntry extends PublicKeyEntry {
                 + (GenericUtils.isEmpty(kc) ? "" : " " + kc);
     }
 
-    public static PublickeyAuthenticator fromAuthorizedEntries(Collection<? extends AuthorizedKeyEntry> entries) throws IOException, GeneralSecurityException {
-        Collection<PublicKey> keys = resolveAuthorizedKeys(entries);
+    public static PublickeyAuthenticator fromAuthorizedEntries(PublicKeyEntryResolver fallbackResolver, Collection<? extends AuthorizedKeyEntry> entries)
+            throws IOException, GeneralSecurityException {
+        Collection<PublicKey> keys = resolveAuthorizedKeys(fallbackResolver, entries);
         if (GenericUtils.isEmpty(keys)) {
             return RejectAllPublickeyAuthenticator.INSTANCE;
         } else {
@@ -154,15 +156,18 @@ public class AuthorizedKeyEntry extends PublicKeyEntry {
         }
     }
 
-    public static List<PublicKey> resolveAuthorizedKeys(Collection<? extends AuthorizedKeyEntry> entries) throws IOException, GeneralSecurityException {
+    public static List<PublicKey> resolveAuthorizedKeys(PublicKeyEntryResolver fallbackResolver, Collection<? extends AuthorizedKeyEntry> entries)
+            throws IOException, GeneralSecurityException {
         if (GenericUtils.isEmpty(entries)) {
             return Collections.emptyList();
         }
 
         List<PublicKey> keys = new ArrayList<PublicKey>(entries.size());
         for (AuthorizedKeyEntry e : entries) {
-            PublicKey k = e.resolvePublicKey();
-            keys.add(k);
+            PublicKey k = e.resolvePublicKey(fallbackResolver);
+            if (k != null) {
+                keys.add(k);
+            }
         }
 
         return keys;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
index 91faae1..da09c66 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
@@ -28,6 +28,7 @@ import java.security.PublicKey;
 import java.util.Collection;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.IoUtils;
@@ -106,7 +107,7 @@ public class AuthorizedKeysAuthenticator extends ModifiableFileWatcher implement
             if (exists()) {
                 Collection<AuthorizedKeyEntry> entries = reloadAuthorizedKeys(path, username, session);
                 if (GenericUtils.size(entries) > 0) {
-                    delegateHolder.set(AuthorizedKeyEntry.fromAuthorizedEntries(entries));
+                    delegateHolder.set(AuthorizedKeyEntry.fromAuthorizedEntries(getFallbackPublicKeyEntryResolver(), entries));
                 }
             } else {
                 log.info("resolvePublickeyAuthenticator(" + username + ")[" + session + "] no authorized keys file at " + path);
@@ -116,6 +117,10 @@ public class AuthorizedKeysAuthenticator extends ModifiableFileWatcher implement
         return delegateHolder.get();
     }
 
+    protected PublicKeyEntryResolver getFallbackPublicKeyEntryResolver() {
+        return PublicKeyEntryResolver.IGNORING;
+    }
+
     protected Collection<AuthorizedKeyEntry> reloadAuthorizedKeys(Path path, String username, ServerSession session) throws IOException {
         Collection<AuthorizedKeyEntry> entries = AuthorizedKeyEntry.readAuthorizedKeys(path);
         log.info("reloadAuthorizedKeys(" + username + ")[" + session + "] loaded " + GenericUtils.size(entries) + " keys from " + path);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/test/java/org/apache/sshd/common/config/keys/PublicKeyEntryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/config/keys/PublicKeyEntryTest.java b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/PublicKeyEntryTest.java
new file mode 100644
index 0000000..b6f0448
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/PublicKeyEntryTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.config.keys;
+
+import java.security.GeneralSecurityException;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.util.test.BaseTestSupport;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PublicKeyEntryTest extends BaseTestSupport {
+    public PublicKeyEntryTest() {
+        super();
+    }
+
+    @Test
+    public void testFallbackResolver() throws Exception {
+        PublicKeyEntry entry =  // TODO use some
+                PublicKeyEntry.parsePublicKeyEntry(
+                        GenericUtils.join(
+                                Arrays.asList(getCurrentTestName(), "AAAA", getClass().getSimpleName()), ' '));
+        for (PublicKeyEntryResolver resolver : new PublicKeyEntryResolver[]{
+                null, PublicKeyEntryResolver.FAILING, PublicKeyEntryResolver.IGNORING}) {
+            try {
+                PublicKey key = entry.resolvePublicKey(resolver);
+                assertSame("Mismatched successful resolver", PublicKeyEntryResolver.IGNORING, resolver);
+                assertNull("Unexpected success for resolver=" + resolver + ": " + KeyUtils.getFingerPrint(key), key);
+            } catch(GeneralSecurityException e) {
+                assertObjectInstanceOf("Mismatched thrown exception for resolver=" + resolver, InvalidKeySpecException.class, e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntryTest.java b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntryTest.java
index 1ecfe76..674812f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntryTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeyEntryTest.java
@@ -27,6 +27,7 @@ import java.util.Collection;
 import java.util.List;
 
 import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.IoUtils;
@@ -70,7 +71,7 @@ public class AuthorizedKeyEntryTest extends AuthorizedKeysTestSupport {
                 sb.setLength(0);
             }
 
-            PublicKey key = entry.appendPublicKey(sb);
+            PublicKey key = entry.appendPublicKey(sb, PublicKeyEntryResolver.FAILING);
             assertNotNull("No key for line=" + line, key);
 
             String encoded = sb.toString();
@@ -106,7 +107,7 @@ public class AuthorizedKeyEntryTest extends AuthorizedKeysTestSupport {
         Exception err = null;
         for (AuthorizedKeyEntry entry : entries) {
             try {
-                ValidateUtils.checkNotNull(entry.resolvePublicKey(), "No public key resolved from %s", entry);
+                ValidateUtils.checkNotNull(entry.resolvePublicKey(PublicKeyEntryResolver.FAILING), "No public key resolved from %s", entry);
             } catch (Exception e) {
                 System.err.append("Failed (").append(e.getClass().getSimpleName()).append(')')
                         .append(" to resolve key of entry=").append(entry.toString())
@@ -123,8 +124,8 @@ public class AuthorizedKeyEntryTest extends AuthorizedKeysTestSupport {
     }
 
     private PublickeyAuthenticator testAuthorizedKeysAuth(Collection<AuthorizedKeyEntry> entries) throws Exception {
-        Collection<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(entries);
-        PublickeyAuthenticator auth = AuthorizedKeyEntry.fromAuthorizedEntries(entries);
+        Collection<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(PublicKeyEntryResolver.FAILING, entries);
+        PublickeyAuthenticator auth = AuthorizedKeyEntry.fromAuthorizedEntries(PublicKeyEntryResolver.FAILING, entries);
         for (PublicKey key : keySet) {
             assertTrue("Failed to authenticate with key=" + key.getAlgorithm(), auth.authenticate(getCurrentTestName(), key, null));
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticatorTest.java b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticatorTest.java
index c1e89c2..3ec0e35 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticatorTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticatorTest.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.sshd.common.config.keys.PublicKeyEntry;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
@@ -83,7 +84,7 @@ public class AuthorizedKeysAuthenticatorTest extends AuthorizedKeysTestSupport {
             List<AuthorizedKeyEntry> entries = AuthorizedKeyEntry.readAuthorizedKeys(file);
             assertEquals("Mismatched number of loaded entries", keyLines.size(), entries.size());
 
-            List<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(entries);
+            List<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(PublicKeyEntryResolver.FAILING, entries);
             assertEquals("Mismatched number of loaded keys", entries.size(), keySet.size());
 
             reloadCount.set(0);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysTestSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysTestSupport.java b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysTestSupport.java
index 659195c..3b6d0d5 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysTestSupport.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/AuthorizedKeysTestSupport.java
@@ -57,6 +57,8 @@ public abstract class AuthorizedKeysTestSupport extends BaseTestSupport {
             Files.delete(file);
         }
 
+        assertHierarchyTargetFolderExists(file.getParent());
+
         try (Writer w = Files.newBufferedWriter(file, StandardCharsets.UTF_8, options)) {
             w.append(PublicKeyEntry.COMMENT_CHAR)
              .append(' ').append(getCurrentTestName())

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2867cbe6/sshd-core/src/test/java/org/apache/sshd/server/config/keys/DefaultAuthorizedKeysAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/DefaultAuthorizedKeysAuthenticatorTest.java b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/DefaultAuthorizedKeysAuthenticatorTest.java
index 68782c6..cd6809c 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/config/keys/DefaultAuthorizedKeysAuthenticatorTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/config/keys/DefaultAuthorizedKeysAuthenticatorTest.java
@@ -23,6 +23,7 @@ import java.nio.file.Path;
 import java.security.PublicKey;
 import java.util.Collection;
 
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
 import org.junit.FixMethodOrder;
@@ -44,7 +45,7 @@ public class DefaultAuthorizedKeysAuthenticatorTest extends AuthorizedKeysTestSu
         writeDefaultSupportedKeys(file);
 
         Collection<AuthorizedKeyEntry> entries = AuthorizedKeyEntry.readAuthorizedKeys(file);
-        Collection<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(entries);
+        Collection<PublicKey> keySet = AuthorizedKeyEntry.resolveAuthorizedKeys(PublicKeyEntryResolver.FAILING, entries);
         PublickeyAuthenticator auth = new DefaultAuthorizedKeysAuthenticator(file, false);
         String thisUser = OsUtils.getCurrentUser();
         for (String username : new String[]{null, "", thisUser, getClass().getName() + "#" + getCurrentTestName()}) {