Как запустить SSHD-сервер Apache-Mina (2.2.0) на Android Pie?

Я пытаюсь запустить сервер Apache MINA SSHD (v. 2.2.0) на устройстве Android Pie (API 28.0). Я нашел различные сообщения о том, что он работает на устройствах Android 4, но ни один из них, похоже, не работает на моем устройстве Android 9. Поэтому я попытался реализовать это сам, но застрял при инициализации сервера с ReflectionException/NoClassDefFoundError.

Когда я пытаюсь настроить сервер с помощью SshServer.setUpDefaultServer(); Я получаю это исключение:

java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/management/ReflectionException;
        at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:730)
        at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:728)
        at org.apache.sshd.common.util.security.SecurityEntityFactory$2.getInstance(SecurityEntityFactory.java:134)
        at org.apache.sshd.common.util.security.SecurityUtils.getMessageDigest(SecurityUtils.java:726)
        at org.apache.sshd.common.digest.DigestUtils.checkSupported(DigestUtils.java:53)
        at org.apache.sshd.common.digest.BuiltinDigests.<init>(BuiltinDigests.java:61)
        at org.apache.sshd.common.digest.BuiltinDigests.<clinit>(BuiltinDigests.java:36)
        at org.apache.sshd.common.cipher.ECCurves.<clinit>(ECCurves.java:61)
        at org.apache.sshd.common.keyprovider.KeyPairProvider.<clinit>(KeyPairProvider.java:63)
        at org.apache.sshd.common.signature.BuiltinSignatures.<clinit>(BuiltinSignatures.java:62)
        at org.apache.sshd.common.BaseBuilder.<clinit>(BaseBuilder.java:133)
        at org.apache.sshd.server.ServerBuilder.builder(ServerBuilder.java:165)
        at org.apache.sshd.server.SshServer.setUpDefaultServer(SshServer.java:429)
        at ch.zhaw.init.sshshell.SshShellService.<init>(SshShellService.java:20)

Из некоторых старых сообщений для Android 4 кажется, что это была известная проблема, и решение заключалось в том, чтобы добавить $useLibrary 'org.apache.http.legacy' в gradle и добавить в manifest.xml. Я сделал это, но исключение все еще происходит.

файл build.gradle:

android {
    compileSdkVersion 28
    useLibrary 'org.apache.http.legacy'
    ...
}
dependencies {
    ...
    implementation 'org.apache.sshd:sshd-core:2.2.0'
    implementation 'org.slf4j:slf4j-simple:1.6.2'
    implementation 'org.apache.mina:mina-core:2.1.2'
    implementation "org.bouncycastle:bcprov-jdk16:1.46"
}

манифест.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="ch.zhaw.init.sshshell">
    <application
            android:networkSecurityConfig="@xml/network_security_config">
        <uses-library android:name="org.apache.http.legacy"
                      android:required="false" />
        <service android:name=".SshShellService">
            <intent-filter>
                <action android:name="StartSshServer"/>
            </intent-filter>
        </service>
    </application>
</manifest>

Мой Java-код:

import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;


private static final int PORT = 8022;
private final SshServer sshd = SshServer.setUpDefaultServer(); // Here I get the error
private final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator();
private final SimplePublicKeyAuthenticator publicKeyAuth = new SimplePublicKeyAuthenticator();
private final SimpleForwardingFilter forwardingFilter = new SimpleForwardingFilter();

Вроде старые версии работали, но я искал несколько дней и не нашел ни одного работающего примера для самой новой версии. У кого-нибудь есть рабочий пример, который запускает последнюю версию Apache Mina SSHD (2.2.0) на Android 9 (без рутирования устройства)?

или, если нет, есть ли альтернативный SSH-сервер (не клиентский - их много) для Android Pie?

Спасибо за любую помощь.


person Me7e0r    schedule 01.05.2019    source источник


Ответы (2)


Для этой конкретной ошибки достаточно создать фиктивный класс ReflectionException (пример). Учитывая, что класс даже не существует, ничто за пределами вашего собственного кода никогда не создаст его экземпляр, поэтому проверка instanceof ReflectionException SSHD никогда не совпадет, и вам не нужно программировать ни одного из его членов.

Вы также можете создать фиктивное исключение MBeanException (пример).

person guest    schedule 21.01.2020

ошибка из-за библиотеки BouncyCastle устарела как android9 (уровень API 28).

вы можете получить подробные советы от aosp: http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#548

https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html

Чтобы решить эту проблему, вы можете выполнить следующие шаги:

  1. удалить BouncyCastleProvider из системы по умолчанию
Security.removeProvider("BC");
  1. установить новый пользовательский провайдер BC
Security.addProvider(new BouncyCastleProvider());
  1. запустите службу mina sshd
 SshServer sshd = SshServer.setUpDefaultServer();
 sshd.setPort(ssdServerPort);
 ....

aosp просто сравните объект, чтобы решить, является ли объект поставщика bc системным поставщиком по умолчанию, поэтому просто замените его новым объектом поставщика bc: http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#341

примечания: вы должны удалить провайдера с помощью :Security.removeProvider("BC") перед установкой провайдера

person virjar    schedule 05.07.2021