zhanghai / MaterialFiles

Material Design file manager for Android
https://play.google.com/store/apps/details?id=me.zhanghai.android.files
GNU General Public License v3.0
5.83k stars 394 forks source link

Cannot access FTP Server on Local Network (530 Error) #1260

Closed Humorist2601 closed 3 months ago

Humorist2601 commented 3 months ago

Hello

Recently updated to version 1.7.3 but cannot use the FTP Server. When I try to connect it to my second profile it shows Authentication Error 530 while it works in version 1.7.2

Operating system is Graphene OS, Android 14

zhanghai commented 3 months ago

I was able to use my current debug build of 1.7.3 to start the FTP server in main user and connect to it via 127.0.0.1:2121 in work profile. I'm using OnePlus 12 OxygenOS Android 14. I can try the same thing with release build if necessary but I guess it will be the same

In fact, there's no FTP server/client change between 1.7.2 and 1.7.3 - the tile fix is limited to tile related code, so I don't have a good idea why this is happening.

Are you sure that this is related to the app update? Is it fixed if you downgrade to 1.7.2 and reproduced again if you upgrade to 1.7.3 again?

Valdnet commented 3 months ago

I confirm the problem with connecting via FTP version 1.7.3.

Cannot connect to the application server.

After reinstalling to version 1.7.2 it works fine.

App: Android 12 Material Files 1.7.3

zhanghai commented 3 months ago

Somehow I can reproduce this with release build. Looking into it and halting Play release, probably a ProGuard/R8 bug? Thanks for reporting this issue.


CREATED
OPENED
SENT: 220 Service ready for new user.
RECEIVED: USER anonymous
SENT: 331 Guest login okay, send your complete e-mail address as password.
RECEIVED: PASS *****
PASS.execute()
java.lang.ClassCastException
    at e5.a.p(SourceFile:1)
    at S8.f.e(SourceFile:75)
    at M8.q.a(SourceFile:270)
    at U8.a.e(SourceFile:189)
    at b9.b.E(SourceFile:114)
    at b9.c.c(SourceFile:9)
    at Ib.b.H(SourceFile:11)
    at U8.b.E(SourceFile:33)
    at b9.c.c(SourceFile:9)
    at Ib.b.H(SourceFile:11)
    at b9.h.a(SourceFile:103)
    at l9.b.d0(SourceFile:268)
    at m9.a.E(SourceFile:17)
    at b9.c.c(SourceFile:9)
    at Ib.b.H(SourceFile:11)
    at i9.a.a(SourceFile:13)
    at i9.c.E(SourceFile:73)
    at b9.c.c(SourceFile:9)
    at Ib.b.H(SourceFile:11)
    at b9.h.a(SourceFile:103)
    at f9.k.run(SourceFile:1)
    at k9.d.a(SourceFile:37)
    at k9.d.run(SourceFile:169)
    at java.lang.Thread.run(Thread.java:1012)
Login failure - anonymous
SENT: 530 Authentication failed.
CLOSED

Deobfuscated stacktrace:

java.lang.ClassCastException
    at org.apache.ftpserver.impl.FtpIoSession.getClientCertificates(FtpIoSession.java)
    at org.apache.ftpserver.command.impl.PASS.execute(PASS.java)
    at org.apache.ftpserver.impl.DefaultFtpHandler.messageReceived(DefaultFtpHandler.java)
    at org.apache.ftpserver.listener.nio.FtpHandlerAdapter.messageReceived(FtpHandlerAdapter.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java)
    at org.apache.ftpserver.listener.nio.FtpLoggingFilter.messageReceived(FtpLoggingFilter.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java)
    at org.apache.mina.filter.logging.MdcInjectionFilter.filter(MdcInjectionFilter.java)
    at org.apache.mina.filter.util.CommonEventFilter.messageReceived(CommonEventFilter.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java)
    at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java)
    at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java)
    at org.apache.mina.core.session.IoEvent.run(IoEvent.java)
    at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(OrderedThreadPoolExecutor.java)
    at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(OrderedThreadPoolExecutor.java)
    at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThreadPoolExecutor.java)
    at java.lang.Thread.run(Thread.java:1012)

Relevant code in Apache ftpserver-core-1.2.0:

    public Certificate[] getClientCertificates() {
        if (getFilterChain().contains(SslFilter.class)) {
            SslFilter sslFilter = (SslFilter) getFilterChain().get(
                    SslFilter.class);

            SSLSession sslSession = sslFilter.getSslSession(this);

            if (sslSession != null) {
                try {
                    return sslSession.getPeerCertificates();
                } catch (SSLPeerUnverifiedException e) {
                    // ignore, certificate will not be available to the session
                }
            }

        }

        // no certificates available
        return null;

    }

Corresponding decompiled code:

    public final void e() {
        Class<C1272a> cls;
        boolean z7;
        C1384b bVar;
        m mVar = this.f6314a;
        b9.c cVar = (b9.c) mVar.p();
        C0569a aVar = cVar.f9899c;
        while (true) {
            aVar = aVar.f9889b;
            cls = C1272a.class;
            if (aVar != cVar.f9900d) {
                if (cls.isAssignableFrom(aVar.f9891d.getClass())) {
                    break;
                }
            } else {
                aVar = null;
                break;
            }
        }
        if (aVar != null) {
            z7 = true;
        } else {
            z7 = false;
        }
        if (z7) {
            b9.c cVar2 = (b9.c) mVar.p();
            C0569a aVar2 = cVar2.f9899c;
            while (true) {
                aVar2 = aVar2.f9889b;
                if (aVar2 != cVar2.f9900d) {
                    if (cls.isAssignableFrom(aVar2.f9891d.getClass())) {
                        break;
                    }
                } else {
                    aVar2 = null;
                    break;
                }
            }
            if (aVar2 == null) {
                bVar = null;
            } else {
                bVar = aVar2.f9891d;
            }
            C0856a.p(bVar);
            throw null;
        }
    }
zhanghai commented 3 months ago

Confirmed that this is a R8-related issue because turning off R8 full mode fixed it. I've reported this at https://issuetracker.google.com/issues/349872492 and I'll have to wait for a fix before I can publish a v1.7.4.

zhanghai commented 3 months ago

Thank you for your report. I ended up downgrading R8 so that I'm sure there are no other regressions, and I've released v1.7.4 just now.