Search in sources :

Example 1 with MemorizingTrustManager

use of de.duenndns.ssl.MemorizingTrustManager in project Zom-Android by zom.

the class XmppConnection method initConnection.

// Runs in executor thread
private void initConnection(Imps.ProviderSettings.QueryMap providerSettings, String userName) throws InterruptedException, NoSuchAlgorithmException, KeyManagementException, XMPPException, SmackException, IOException {
    // never! // providerSettings.getAllowPlainAuth();
    boolean allowPlainAuth = false;
    // providerSettings.getRequireTls(); //always!
    boolean requireTls = true;
    boolean doDnsSrv = providerSettings.getDoDnsSrv();
    // boolean tlsCertVerify = providerSettings.getTlsCertVerify();
    // boolean useSASL = true;//!allowPlainAuth;
    // boolean useProxy = providerSettings.getUseTor();
    String domain = providerSettings.getDomain();
    mPriority = providerSettings.getXmppResourcePrio();
    int serverPort = providerSettings.getPort();
    String server = providerSettings.getServer();
    if ("".equals(server))
        server = null;
    if (domain.equals("dukgo.com")) {
        doDnsSrv = false;
        server = "dukgo.com";
    }
    debug(TAG, "TLS required? " + requireTls);
    if (// if serverPort is set to 0 then use 5222 as default
    serverPort == 0)
        serverPort = 5222;
    mConfig = XMPPTCPConnectionConfiguration.builder();
    mConfig.setServiceName(JidCreate.domainBareFrom(domain));
    mConfig.setPort(serverPort);
    mConfig.setCompressionEnabled(true);
    mConfig.setConnectTimeout(CONNECT_TIMEOUT);
    mConfig.setXmppDomain(domain);
    mConfig.setHost(domain);
    if (!TextUtils.isEmpty(server))
        mConfig.setHost(server);
    if (!TextUtils.isEmpty(Preferences.getProxyServerHost())) {
        setProxy("SOCKS5", Preferences.getProxyServerHost(), Preferences.getProxyServerPort());
    } else if (Preferences.useAdvancedNetworking()) {
        setProxy("SOCKS5", "127.0.0.1", 31059);
    } else {
        mProxyInfo = null;
        // SRV lookup shouldn't be done through a proxy
        if (doDnsSrv) {
            // java.lang.System.setProperty("java.net.preferIPv4Stack", "true");
            // java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
            debug(TAG, "(DNS SRV) resolving: " + domain);
            List<HostAddress> listHostsFailed = new ArrayList<>();
            List<HostAddress> listHosts = DNSUtil.resolveXMPPServiceDomain(domain, listHostsFailed, ConnectionConfiguration.DnssecMode.disabled);
            if (listHosts.size() > 0) {
                server = listHosts.get(0).getFQDN();
                serverPort = listHosts.get(0).getPort();
                debug(TAG, "(DNS SRV) resolved: " + domain + "=" + server + ":" + serverPort);
                if (!TextUtils.isEmpty(server))
                    mConfig.setHost(server);
                if (serverPort != -1)
                    mConfig.setPort(serverPort);
            }
        }
        if (!TextUtils.isEmpty(server)) {
            try {
                String[] addressParts = server.split("\\.");
                if (Integer.parseInt(addressParts[0]) != -1) {
                    byte[] parts = new byte[addressParts.length];
                    for (int i = 0; i < 4; i++) parts[i] = (byte) Integer.parseInt(addressParts[i]);
                    byte[] ipAddr = new byte[] { parts[0], parts[1], parts[2], parts[3] };
                    InetAddress addr = InetAddress.getByAddress(ipAddr);
                    mConfig.setHostAddress(addr);
                } else {
                    mConfig.setHostAddress(InetAddress.getByName(server));
                }
            } catch (Exception e) {
                debug(TAG, "error parsing server as IP address; using as hostname instead");
                mConfig.setHostAddress(InetAddress.getByName(server));
            }
        }
    }
    mConfig.setProxyInfo(mProxyInfo);
    mConfig.setDebuggerEnabled(Debug.DEBUG_ENABLED);
    SmackConfiguration.DEBUG = Debug.DEBUG_ENABLED;
    SmackConfiguration.setDebuggerFactory(new SmackDebuggerFactory() {

        @Override
        public SmackDebugger create(XMPPConnection xmppConnection, Writer writer, Reader reader) throws IllegalArgumentException {
            return new AndroidDebugger(xmppConnection, writer, reader);
        }
    });
    // mConfig.setSASLAuthenticationEnabled(useSASL);
    // Android has no support for Kerberos or GSSAPI, so disable completely
    SASLAuthentication.unregisterSASLMechanism("KERBEROS_V4");
    SASLAuthentication.unregisterSASLMechanism("GSSAPI");
    if (allowPlainAuth)
        SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
    SASLAuthentication.unBlacklistSASLMechanism("DIGEST-MD5");
    if (mMemTrust == null)
        mMemTrust = new MemorizingTrustManager(mContext);
    if (sslContext == null) {
        sslContext = SSLContext.getInstance(SSLCONTEXT_TYPE);
        secureRandom = new java.security.SecureRandom();
        sslContext.init(null, MemorizingTrustManager.getInstanceList(mContext), secureRandom);
        while (true) {
            try {
                if (Build.VERSION.SDK_INT >= 20) {
                    sslContext.getDefaultSSLParameters().setCipherSuites(XMPPCertPins.SSL_IDEAL_CIPHER_SUITES_API_20);
                } else {
                    sslContext.getDefaultSSLParameters().setCipherSuites(XMPPCertPins.SSL_IDEAL_CIPHER_SUITES);
                }
                break;
            } catch (IllegalStateException e) {
                debug(TAG, "error setting cipher suites; waiting for SSLContext to init...");
                try {
                    Thread.sleep(1000);
                } catch (Exception e2) {
                }
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            mConfig.setKeystoreType("AndroidCAStore");
            mConfig.setKeystorePath(null);
        } else {
            mConfig.setKeystoreType("BKS");
            String path = System.getProperty("javax.net.ssl.trustStore");
            if (path == null)
                path = System.getProperty("java.home") + File.separator + "etc" + File.separator + "security" + File.separator + "cacerts.bks";
            mConfig.setKeystorePath(path);
        }
        // wait a second while the ssl context init's
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }
    }
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= 16) {
        while (true) {
            try {
                mConfig.setEnabledSSLProtocols(new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" });
                sslContext.getDefaultSSLParameters().setProtocols(new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" });
                break;
            } catch (IllegalStateException ise) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
    }
    if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        mConfig.setEnabledSSLCiphers(XMPPCertPins.SSL_IDEAL_CIPHER_SUITES);
    }
    mConfig.setCustomSSLContext(sslContext);
    mConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
    mConfig.setHostnameVerifier(mMemTrust.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
    mConfig.setSendPresence(true);
    XMPPTCPConnection.setUseStreamManagementDefault(true);
    XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
    mConnection = new XMPPTCPConnection(mConfig.build());
    DeliveryReceiptManager.getInstanceFor(mConnection).addReceiptReceivedListener(new ReceiptReceivedListener() {

        @Override
        public void onReceiptReceived(Jid fromJid, Jid toJid, String receiptId, Stanza receipt) {
            ChatSession session = mSessionManager.findSession(fromJid.asBareJid());
            if (session != null)
                session.onMessageReceipt(receiptId);
        }
    });
    mConnection.addSyncStanzaListener(new StanzaListener() {

        @Override
        public void processStanza(Stanza stanza) {
            debug(TAG, "receive message: " + stanza.getFrom() + " to " + stanza.getTo());
            org.jivesoftware.smack.packet.Message smackMessage = (org.jivesoftware.smack.packet.Message) stanza;
            handleMessage(smackMessage, false, true);
            String msg_xml = smackMessage.toXML().toString();
            try {
                handleChatState(smackMessage.getFrom().toString(), msg_xml);
            } catch (RemoteException re) {
            // no worries
            }
        }
    }, new StanzaTypeFilter(org.jivesoftware.smack.packet.Message.class));
    mConnection.addSyncStanzaListener(new StanzaListener() {

        @Override
        public void processStanza(Stanza packet) {
            org.jivesoftware.smack.packet.Presence presence = (org.jivesoftware.smack.packet.Presence) packet;
            qPresence.add(presence);
        }
    }, new StanzaTypeFilter(org.jivesoftware.smack.packet.Presence.class));
    if (mTimerPackets != null)
        mTimerPackets.cancel();
    initPacketProcessor();
    if (mTimerPresence != null)
        mTimerPresence.cancel();
    initPresenceProcessor();
    if (mTimerNewContacts != null)
        mTimerNewContacts.cancel();
    initNewContactProcessor();
    ConnectionListener connectionListener = new ConnectionListener() {

        /**
         * Called from smack when connect() is fully successful
         *
         * This is called on the executor thread while we are in reconnect()
         */
        @Override
        public void reconnectionSuccessful() {
            if (mStreamHandler == null || !mStreamHandler.isResumePending()) {
                debug(TAG, "Reconnection success");
                onReconnectionSuccessful();
                mRoster = Roster.getInstanceFor(mConnection);
                sendPresencePacket();
                mChatGroupManager.reconnectAll();
            } else {
                debug(TAG, "Ignoring reconnection callback due to pending resume");
            }
        }

        @Override
        public void reconnectionFailed(Exception e) {
            debug(TAG, "reconnection failed", e);
            // We are not using the reconnection manager
            // throw new UnsupportedOperationException();
            execute(new Runnable() {

                public void run() {
                    mNeedReconnect = true;
                    setState(LOGGING_IN, new ImErrorInfo(ImErrorInfo.NETWORK_ERROR, "network error"));
                    reconnect();
                }
            });
        }

        @Override
        public void reconnectingIn(int seconds) {
            // // We are not using the reconnection manager
            // throw new UnsupportedOperationException();
            debug(TAG, "reconnecting in " + seconds + " seconds...");
        }

        @Override
        public void connectionClosedOnError(final Exception e) {
            /*
                 * This fires when:
                 * - Packet reader or writer detect an error
                 * - Stream compression failed
                 * - TLS fails but is required
                 * - Network error
                 * - We forced a socket shutdown
                 */
            debug(TAG, "reconnect on error: " + e.getMessage(), e);
            if (e.getMessage().contains("conflict")) {
                execute(new Runnable() {

                    @Override
                    public void run() {
                        // disconnect();
                        disconnected(new ImErrorInfo(ImpsErrorInfo.ALREADY_LOGGED, "logged in from another location"));
                    }
                });
            } else if (!mNeedReconnect) {
                execute(new Runnable() {

                    public void run() {
                        if (getState() == LOGGED_IN) {
                            mNeedReconnect = true;
                            setState(LOGGING_IN, new ImErrorInfo(ImErrorInfo.NETWORK_ERROR, "network error"));
                            reconnect();
                        }
                    }
                });
            }
        }

        @Override
        public void connected(XMPPConnection connection) {
            debug(TAG, "connected");
            try {
                initOmemo((XMPPTCPConnection) connection);
            } catch (Exception e) {
                debug("OMEMO", "There was a problem init'g omemo", e);
            }
        }

        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) {
            debug(TAG, "authenticated: resumed=" + resumed);
            sendPresencePacket();
            mChatGroupManager.reconnectAll();
        }

        @Override
        public void connectionClosed() {
            debug(TAG, "connection closed");
            // if the state is logged in, we should try to reconnect!
            if (getState() == LOGGED_IN) {
                execute(new Runnable() {

                    public void run() {
                        mNeedReconnect = true;
                        setState(LOGGING_IN, new ImErrorInfo(ImErrorInfo.NETWORK_ERROR, "network error"));
                        reconnect();
                    }
                });
            }
        }
    };
    mConnection.addConnectionListener(connectionListener);
    mStreamHandler = new XmppStreamHandler(mConnection, connectionListener);
    Exception xmppConnectException = null;
    AbstractXMPPConnection conn = mConnection.connect();
}
Also used : AndroidDebugger(org.jivesoftware.smackx.debugger.android.AndroidDebugger) XMPPTCPConnection(org.jivesoftware.smack.tcp.XMPPTCPConnection) Message(org.awesomeapp.messenger.model.Message) Reader(java.io.Reader) StanzaListener(org.jivesoftware.smack.StanzaListener) ReceiptReceivedListener(org.jivesoftware.smackx.receipts.ReceiptReceivedListener) AbstractXMPPConnection(org.jivesoftware.smack.AbstractXMPPConnection) XMPPConnection(org.jivesoftware.smack.XMPPConnection) ConnectionListener(org.jivesoftware.smack.ConnectionListener) ChatSession(org.awesomeapp.messenger.model.ChatSession) IChatSession(org.awesomeapp.messenger.service.IChatSession) SecureRandom(java.security.SecureRandom) StanzaTypeFilter(org.jivesoftware.smack.filter.StanzaTypeFilter) SmackDebuggerFactory(org.jivesoftware.smack.debugger.SmackDebuggerFactory) SmackDebugger(org.jivesoftware.smack.debugger.SmackDebugger) Presence(org.awesomeapp.messenger.model.Presence) LinkedList(java.util.LinkedList) ArrayList(java.util.ArrayList) ContactList(org.awesomeapp.messenger.model.ContactList) List(java.util.List) EntityBareJid(org.jxmpp.jid.EntityBareJid) Jid(org.jxmpp.jid.Jid) EntityFullJid(org.jxmpp.jid.EntityFullJid) BareJid(org.jxmpp.jid.BareJid) EntityJid(org.jxmpp.jid.EntityJid) DomainBareJid(org.jxmpp.jid.DomainBareJid) Stanza(org.jivesoftware.smack.packet.Stanza) OmemoFingerprint(org.jivesoftware.smackx.omemo.OmemoFingerprint) KeyStoreException(java.security.KeyStoreException) UndecidedOmemoIdentityException(org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException) XMPPException(org.jivesoftware.smack.XMPPException) RemoteException(android.os.RemoteException) IOException(java.io.IOException) ImException(org.awesomeapp.messenger.model.ImException) KeyManagementException(java.security.KeyManagementException) InvocationTargetException(java.lang.reflect.InvocationTargetException) XmppStringprepException(org.jxmpp.stringprep.XmppStringprepException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SmackException(org.jivesoftware.smack.SmackException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) MultiUserChatException(org.jivesoftware.smackx.muc.MultiUserChatException) CryptoFailedException(org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException) CertificateException(java.security.cert.CertificateException) MemorizingTrustManager(de.duenndns.ssl.MemorizingTrustManager) RemoteException(android.os.RemoteException) InetAddress(java.net.InetAddress) Writer(java.io.Writer) ImErrorInfo(org.awesomeapp.messenger.model.ImErrorInfo) AbstractXMPPConnection(org.jivesoftware.smack.AbstractXMPPConnection)

Example 2 with MemorizingTrustManager

use of de.duenndns.ssl.MemorizingTrustManager in project xabber-android by redsolution.

the class HttpClientWithMTM method getClient.

public static OkHttpClient getClient(AccountJid accountJid) {
    // create ssl verification factory
    SSLSocketFactory sslSocketFactory = null;
    MemorizingTrustManager mtm = CertificateManager.getInstance().getNewFileUploadManager(accountJid);
    final SSLContext sslContext;
    try {
        sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
        sslSocketFactory = sslContext.getSocketFactory();
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        return null;
    }
    // build http client
    final OkHttpClient client = new OkHttpClient().newBuilder().sslSocketFactory(sslSocketFactory).hostnameVerifier(mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier())).writeTimeout(5, TimeUnit.MINUTES).connectTimeout(5, TimeUnit.MINUTES).readTimeout(5, TimeUnit.MINUTES).build();
    return client;
}
Also used : MemorizingTrustManager(de.duenndns.ssl.MemorizingTrustManager) OkHttpClient(okhttp3.OkHttpClient) SSLContext(javax.net.ssl.SSLContext) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) KeyManagementException(java.security.KeyManagementException)

Example 3 with MemorizingTrustManager

use of de.duenndns.ssl.MemorizingTrustManager in project xabber-android by redsolution.

the class CertificateManager method getNewMemorizingTrustManager.

@NonNull
MemorizingTrustManager getNewMemorizingTrustManager(@NonNull final AccountJid accountJid) {
    MemorizingTrustManager mtm = new MemorizingTrustManager(Application.getInstance());
    if (currentActivityForBind != null)
        mtm.bindDisplayActivity(currentActivityForBind);
    memorizingTrustManagerMap.put(accountJid, mtm);
    return mtm;
}
Also used : MemorizingTrustManager(de.duenndns.ssl.MemorizingTrustManager) NonNull(androidx.annotation.NonNull)

Example 4 with MemorizingTrustManager

use of de.duenndns.ssl.MemorizingTrustManager in project xabber-android by redsolution.

the class CertificateManager method getNewFileUploadManager.

@NonNull
public MemorizingTrustManager getNewFileUploadManager(@NonNull final AccountJid accountJid) {
    MemorizingTrustManager mtm = new MemorizingTrustManager(Application.getInstance());
    if (currentActivityForBind != null)
        mtm.bindDisplayActivity(currentActivityForBind);
    fileUploadMap.put(accountJid, mtm);
    return mtm;
}
Also used : MemorizingTrustManager(de.duenndns.ssl.MemorizingTrustManager) NonNull(androidx.annotation.NonNull)

Example 5 with MemorizingTrustManager

use of de.duenndns.ssl.MemorizingTrustManager in project xabber-android by redsolution.

the class ConnectionThread method onReady.

private void onReady(XMPPTCPConnectionConfiguration.Builder builder) {
    builder.setSecurityMode(tlsMode.getSecurityMode());
    builder.setCompressionEnabled(compression);
    builder.setSendPresence(false);
    try {
        if (SettingsManager.securityCheckCertificate()) {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            MemorizingTrustManager mtm = new MemorizingTrustManager(Application.getInstance());
            sslContext.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
            builder.setCustomSSLContext(sslContext);
            builder.setHostnameVerifier(mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
        } else {
            TLSUtils.acceptAllCertificates(builder);
            TLSUtils.disableHostnameVerificationForTlsCertificicates(builder);
        }
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
    }
    setUpSASL();
    xmppConnection = new XMPPTCPConnection(builder.build());
    xmppConnection.addAsyncStanzaListener(this, ACCEPT_ALL);
    xmppConnection.addConnectionListener(this);
    // by default Smack disconnects in case of parsing errors
    xmppConnection.setParsingExceptionCallback(new ExceptionLoggingCallback());
    AccountRosterListener rosterListener = new AccountRosterListener(((AccountItem) connectionItem).getAccount());
    final Roster roster = Roster.getInstanceFor(xmppConnection);
    roster.addRosterListener(rosterListener);
    roster.addRosterLoadedListener(rosterListener);
    roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
    org.jivesoftware.smackx.ping.PingManager.getInstanceFor(xmppConnection).registerPingFailedListener(this);
    connectionItem.onSRVResolved(this);
    final String password = OAuthManager.getInstance().getPassword(protocol, token);
    if (password != null) {
        runOnConnectionThread(new Runnable() {

            @Override
            public void run() {
                connect(password);
            }
        });
    } else {
        runOnConnectionThread(new Runnable() {

            @Override
            public void run() {
                passwordRequest();
            }
        });
    }
}
Also used : XMPPTCPConnection(org.jivesoftware.smack.tcp.XMPPTCPConnection) SSLContext(javax.net.ssl.SSLContext) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) KeyManagementException(java.security.KeyManagementException) MemorizingTrustManager(de.duenndns.ssl.MemorizingTrustManager) AccountRosterListener(com.xabber.android.data.roster.AccountRosterListener) Roster(org.jivesoftware.smack.roster.Roster) ExceptionLoggingCallback(org.jivesoftware.smack.parsing.ExceptionLoggingCallback)

Aggregations

MemorizingTrustManager (de.duenndns.ssl.MemorizingTrustManager)10 SSLContext (javax.net.ssl.SSLContext)6 KeyManagementException (java.security.KeyManagementException)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 NonNull (androidx.annotation.NonNull)3 SSLSocketFactory (javax.net.ssl.SSLSocketFactory)3 IOException (java.io.IOException)2 KeyStoreException (java.security.KeyStoreException)2 OkHttpClient (okhttp3.OkHttpClient)2 SmackException (org.jivesoftware.smack.SmackException)2 StanzaListener (org.jivesoftware.smack.StanzaListener)2 XMPPException (org.jivesoftware.smack.XMPPException)2 Stanza (org.jivesoftware.smack.packet.Stanza)2 XMPPTCPConnection (org.jivesoftware.smack.tcp.XMPPTCPConnection)2 Handler (android.os.Handler)1 RemoteException (android.os.RemoteException)1 AccountItem (com.xabber.android.data.account.AccountItem)1 AccountJid (com.xabber.android.data.entity.AccountJid)1 UserJid (com.xabber.android.data.entity.UserJid)1 AccountRosterListener (com.xabber.android.data.roster.AccountRosterListener)1