qxmpp-project / qxmpp

Cross-platform C++ XMPP client and server library
411 stars 197 forks source link

Android not connecting over TLS #579

Open timakas opened 1 year ago

timakas commented 1 year ago

I am trying to connect to my Openfire server with a wildcard cert via an Android app I'm building. When I attempt to login, the server log shows that Session Server [10] (SSL) is now secured and produces no errors. However the connection on the client side does not leave the Connecting State, and just hangs until the server times out because of an idle connection and kills it, and no user authentication happens. So the client connected signal is never emitted.

Things I have tried:

  1. I have checked the underlying qsslsocket.isEncrypted and it returns false at the Connecting State.

  2. I have logged into my Openfire server with Pidgin on my Linux machine, using the same settings I set in QXmppConfiguration, and it successfully connects over tls v1.3. So this suggests there isn't anything wrong on the server side.

  3. I have tried connecting on both Android emulator and Android device, same result. So this rules out it just being an issue with the Android emulator. Tested this for API 29.

  4. I have installed the OpenSSL library correctly for both target architectures (arm64-v8a and x86_64). QSslSocket::supportsSsl() returns true. I followed OpenSsl Wiki for building the libraries. https://wiki.openssl.org/index.php/Android.

    • Edit: I was using an older version of Openssl, so I updated to Openssl version 1.1.1u. Same Result.
  5. Previously I have been successfully able to login to the server with plaintext over my local network using Servers IP and port, so there doesn't seem to be an issue with my login process.

  6. I receive no QSslErrors during the login attempt.

  7. DNS A and SRV records are set up mapping to my Servers FQDN.

  8. Port forwarding on Router is fine.

  9. I ran the following terminal command: "openssl s_client -starttls xmpp -connect (Servers FQDN):5222" And I get: "Verify return code: 0 (ok)", protocol is TLSv1.3, and my server cert is successfully retrieved.

  10. In my app I set the following QXmppConfiguration:

    • setHost // Servers FQDN
    • setPort // 5222
    • setUser
    • setPassword
    • setDomain // Servers FQDN
    • setSaslAuthMechanism // SCRAM-SHA-256
    • setStreamSecurityMode(QXmppConfiguration::TLSRequired)
    • setResource // phone
    • setNetworkProxy(QNetworkProxy::NoProxy)
  11. I have added full cert chain to my server with no errors.

  12. I am using QT 5.15.2, with QXmpp 1.5

  13. In my AndroidManifest.xml I set android:usesCleartextTraffic="true" in the tag because I read that newer versions of Android won't connect using openssl unless this option is set.

  14. I have a reverse proxy setup, but I tried changing my Router port forwarding to bypass the proxy and go straight to the Server, and I get the same result, just hangs at Connecting State until timeout.

Any help would be appreciated, I'm not sure where to go from here to solve this issue.

timakas commented 1 year ago

I believe I have found the issue and a temporary solution. This Post outlines the issue. I'm not sure if this issue can be resolved in QXmpp, but apparently a 100ms delay is needed in the TLSv1.3 handshake. For now I am using TLSv1.2 and I get a successful connection.