导航菜单

页面标题

页面副标题

95爱播免登录版 v3.1.9 - Socks5BytestreamManager.java 源代码

正在查看: 95爱播免登录版 v3.1.9 应用的 Socks5BytestreamManager.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package org.jivesoftware.smackx.bytestreams.socks5;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.SyncPacketSend;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.bytestreams.BytestreamListener;
import org.jivesoftware.smackx.bytestreams.BytestreamManager;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smackx.packet.DiscoverItems;

public final class Socks5BytestreamManager implements BytestreamManager {
    public static final String NAMESPACE = "http://jabber.org/protocol/bytestreams";
    private static final String SESSION_ID_PREFIX = "js5_";
    private static final Map<Connection, Socks5BytestreamManager> managers;
    private static final Random randomGenerator;
    private final Connection connection;
    private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap();
    private final List<BytestreamListener> allRequestListeners = Collections.synchronizedList(new LinkedList());
    private int targetResponseTimeout = 10000;
    private int proxyConnectionTimeout = 10000;
    private final List<String> proxyBlacklist = Collections.synchronizedList(new LinkedList());
    private String lastWorkingProxy = null;
    private boolean proxyPrioritizationEnabled = true;
    private List<String> ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList());
    private final InitiationListener initiationListener = new InitiationListener(this);

    static {
        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
            @Override
            public void connectionCreated(final Connection connection) {
                final Socks5BytestreamManager bytestreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
                connection.addConnectionListener(new AbstractConnectionListener() {
                    @Override
                    public void connectionClosed() {
                        bytestreamManager.disableService();
                    }

                    @Override
                    public void connectionClosedOnError(Exception exc) {
                        bytestreamManager.disableService();
                    }

                    @Override
                    public void reconnectionSuccessful() {
                        Socks5BytestreamManager.managers.put(connection, bytestreamManager);
                    }
                });
            }
        });
        randomGenerator = new Random();
        managers = new WeakHashMap();
    }

    private Socks5BytestreamManager(Connection connection) {
        this.connection = connection;
    }

    private void activate() {
        Connection connection = this.connection;
        InitiationListener initiationListener = this.initiationListener;
        connection.addPacketListener(initiationListener, initiationListener.getFilter());
        enableService();
    }

    private Bytestream createBytestreamInitiation(String str, String str2, List<Bytestream.StreamHost> list) {
        Bytestream bytestream = new Bytestream(str);
        Iterator<Bytestream.StreamHost> it = list.iterator();
        while (it.hasNext()) {
            bytestream.addStreamHost(it.next());
        }
        bytestream.setType(IQ.Type.SET);
        bytestream.setTo(str2);
        return bytestream;
    }

    private Bytestream createStreamHostRequest(String str) {
        Bytestream bytestream = new Bytestream();
        bytestream.setType(IQ.Type.GET);
        bytestream.setTo(str);
        return bytestream;
    }

    private List<String> determineProxies() throws XMPPException {
        ServiceDiscoveryManager instanceFor = ServiceDiscoveryManager.getInstanceFor(this.connection);
        ArrayList arrayList = new ArrayList();
        Iterator items = instanceFor.discoverItems(this.connection.getServiceName()).getItems();
        while (items.hasNext()) {
            DiscoverItems.Item item = (DiscoverItems.Item) items.next();
            if (!this.proxyBlacklist.contains(item.getEntityID())) {
                try {
                    Iterator identities = instanceFor.discoverInfo(item.getEntityID()).getIdentities();
                    while (true) {
                        if (!identities.hasNext()) {
                            break;
                        }
                        DiscoverInfo.Identity identity = (DiscoverInfo.Identity) identities.next();
                        if ("proxy".equalsIgnoreCase(identity.getCategory()) && "bytestreams".equalsIgnoreCase(identity.getType())) {
                            arrayList.add(item.getEntityID());
                            break;
                        }
                        this.proxyBlacklist.add(item.getEntityID());
                    }
                } catch (XMPPException unused) {
                    this.proxyBlacklist.add(item.getEntityID());
                }
            }
        }
        return arrayList;
    }

    private List<Bytestream.StreamHost> determineStreamHostInfos(List<String> list) {
        ArrayList arrayList = new ArrayList();
        List<Bytestream.StreamHost> localStreamHost = getLocalStreamHost();
        if (localStreamHost != null) {
            arrayList.addAll(localStreamHost);
        }
        for (String str : list) {
            try {
                arrayList.addAll(((Bytestream) SyncPacketSend.getReply(this.connection, createStreamHostRequest(str))).getStreamHosts());
            } catch (XMPPException unused) {
                this.proxyBlacklist.add(str);
            }
        }
        return arrayList;
    }

    private void enableService() {
        ServiceDiscoveryManager instanceFor = ServiceDiscoveryManager.getInstanceFor(this.connection);
        if (instanceFor.includesFeature(NAMESPACE)) {
            return;
        }
        instanceFor.addFeature(NAMESPACE);
    }

    public static synchronized Socks5BytestreamManager getBytestreamManager(Connection connection) {
        synchronized (Socks5BytestreamManager.class) {
            if (connection == null) {
                return null;
            }
            Map<Connection, Socks5BytestreamManager> map = managers;
            Socks5BytestreamManager socks5BytestreamManager = map.get(connection);
            if (socks5BytestreamManager == null) {
                socks5BytestreamManager = new Socks5BytestreamManager(connection);
                map.put(connection, socks5BytestreamManager);
                socks5BytestreamManager.activate();
            }
            return socks5BytestreamManager;
        }
    }

    private List<Bytestream.StreamHost> getLocalStreamHost() {
        Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
        if (!socks5Proxy.isRunning()) {
            return null;
        }
        List<String> localAddresses = socks5Proxy.getLocalAddresses();
        int port = socks5Proxy.getPort();
        if (localAddresses.size() < 1) {
            return null;
        }
        ArrayList arrayList = new ArrayList();
        Iterator<String> it = localAddresses.iterator();
        while (it.hasNext()) {
            Bytestream.StreamHost streamHost = new Bytestream.StreamHost(this.connection.getUser(), it.next());
            streamHost.setPort(port);
            arrayList.add(streamHost);
        }
        return arrayList;
    }

    private String getNextSessionID() {
        return SESSION_ID_PREFIX + Math.abs(randomGenerator.nextLong());
    }

    private boolean supportsSocks5(String str) throws XMPPException {
        return ServiceDiscoveryManager.getInstanceFor(this.connection).discoverInfo(str).containsFeature(NAMESPACE);
    }

    @Override
    public void addIncomingBytestreamListener(BytestreamListener bytestreamListener) {
        this.allRequestListeners.add(bytestreamListener);
    }

    public synchronized void disableService() {
        this.connection.removePacketListener(this.initiationListener);
        this.initiationListener.shutdown();
        this.allRequestListeners.clear();
        this.userListeners.clear();
        this.lastWorkingProxy = null;
        this.proxyBlacklist.clear();
        this.ignoredBytestreamRequests.clear();
        Map<Connection, Socks5BytestreamManager> map = managers;
        map.remove(this.connection);
        if (map.size() == 0) {
            Socks5Proxy.getSocks5Proxy().stop();
        }
        ServiceDiscoveryManager instanceFor = ServiceDiscoveryManager.getInstanceFor(this.connection);
        if (instanceFor != null) {
            instanceFor.removeFeature(NAMESPACE);
        }
    }

    protected List<BytestreamListener> getAllRequestListeners() {
        return this.allRequestListeners;
    }

    protected Connection getConnection() {
        return this.connection;
    }

    protected List<String> getIgnoredBytestreamRequests() {
        return this.ignoredBytestreamRequests;
    }

    public int getProxyConnectionTimeout() {
        if (this.proxyConnectionTimeout <= 0) {
            this.proxyConnectionTimeout = 10000;
        }
        return this.proxyConnectionTimeout;
    }

    public int getTargetResponseTimeout() {
        if (this.targetResponseTimeout <= 0) {
            this.targetResponseTimeout = 10000;
        }
        return this.targetResponseTimeout;
    }

    protected BytestreamListener getUserListener(String str) {
        return this.userListeners.get(str);
    }

    public void ignoreBytestreamRequestOnce(String str) {
        this.ignoredBytestreamRequests.add(str);
    }

    public boolean isProxyPrioritizationEnabled() {
        return this.proxyPrioritizationEnabled;
    }

    @Override
    public void removeIncomingBytestreamListener(BytestreamListener bytestreamListener) {
        this.allRequestListeners.remove(bytestreamListener);
    }

    protected void replyRejectPacket(IQ iq) {
        this.connection.sendPacket(IQ.createErrorResponse(iq, new XMPPError(XMPPError.Condition.no_acceptable)));
    }

    public void setProxyConnectionTimeout(int i2) {
        this.proxyConnectionTimeout = i2;
    }

    public void setProxyPrioritizationEnabled(boolean z) {
        this.proxyPrioritizationEnabled = z;
    }

    public void setTargetResponseTimeout(int i2) {
        this.targetResponseTimeout = i2;
    }

    @Override
    public void addIncomingBytestreamListener(BytestreamListener bytestreamListener, String str) {
        this.userListeners.put(str, bytestreamListener);
    }

    @Override
    public void removeIncomingBytestreamListener(String str) {
        this.userListeners.remove(str);
    }

    @Override
    public Socks5BytestreamSession establishSession(String str) throws XMPPException, IOException, InterruptedException {
        return establishSession(str, getNextSessionID());
    }

    @Override
    public Socks5BytestreamSession establishSession(String str, String str2) throws XMPPException, IOException, InterruptedException {
        if (supportsSocks5(str)) {
            ArrayList arrayList = new ArrayList();
            Bytestream.StreamHost streamHost = null;
            try {
                arrayList.addAll(determineProxies());
                e = null;
            } catch (XMPPException e2) {
                e = e2;
            }
            List<Bytestream.StreamHost> determineStreamHostInfos = determineStreamHostInfos(arrayList);
            if (determineStreamHostInfos.isEmpty()) {
                if (e != null) {
                    throw e;
                }
                throw new XMPPException("no SOCKS5 proxies available");
            }
            String createDigest = Socks5Utils.createDigest(str2, this.connection.getUser(), str);
            if (this.proxyPrioritizationEnabled && this.lastWorkingProxy != null) {
                Iterator<Bytestream.StreamHost> it = determineStreamHostInfos.iterator();
                while (true) {
                    if (!it.hasNext()) {
                        break;
                    }
                    Bytestream.StreamHost next = it.next();
                    if (next.getJID().equals(this.lastWorkingProxy)) {
                        streamHost = next;
                        break;
                    }
                }
                if (streamHost != null) {
                    determineStreamHostInfos.remove(streamHost);
                    determineStreamHostInfos.add(0, streamHost);
                }
            }
            Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
            try {
                try {
                    socks5Proxy.addTransfer(createDigest);
                    Bytestream createBytestreamInitiation = createBytestreamInitiation(str2, str, determineStreamHostInfos);
                    Bytestream.StreamHost streamHost2 = createBytestreamInitiation.getStreamHost(((Bytestream) SyncPacketSend.getReply(this.connection, createBytestreamInitiation, getTargetResponseTimeout())).getUsedHost().getJID());
                    if (streamHost2 != null) {
                        Socket socket = new Socks5ClientForInitiator(streamHost2, createDigest, this.connection, str2, str).getSocket(getProxyConnectionTimeout());
                        this.lastWorkingProxy = streamHost2.getJID();
                        return new Socks5BytestreamSession(socket, streamHost2.getJID().equals(this.connection.getUser()));
                    }
                    throw new XMPPException("Remote user responded with unknown host");
                } catch (TimeoutException unused) {
                    throw new IOException("Timeout while connecting to SOCKS5 proxy");
                }
            } finally {
                socks5Proxy.removeTransfer(createDigest);
            }
        }
        throw new XMPPException(String.valueOf(str) + " doesn't support SOCKS5 Bytestream");
    }
}