Search in sources :

Example 1 with ClientIDException

use of com.biglybt.pif.clientid.ClientIDException in project BiglyBT by BiglySoftware.

the class TRTrackerBTAnnouncerImpl method announceHTTPSupport.

private String announceHTTPSupport(// overwritten if redirected
URL[] tracker_url, URL original_reqUrl, Proxy proxy, boolean first_effort, ByteArrayOutputStream message) throws IOException {
    TRTrackerUtils.checkForBlacklistedURLs(original_reqUrl);
    URL reqUrl = TRTrackerUtils.adjustURLForHosting(original_reqUrl);
    reqUrl = AddressUtils.adjustURL(reqUrl);
    if (reqUrl != original_reqUrl) {
        if (Logger.isEnabled()) {
            Logger.log(new LogEvent(torrent, LOGID, "    HTTP: url adjusted to " + reqUrl));
        }
    }
    String failure_reason = null;
    HttpURLConnection con;
    Properties http_properties = new Properties();
    http_properties.put(ClientIDGenerator.PR_URL, reqUrl);
    if (proxy != null) {
        http_properties.put(ClientIDGenerator.PR_PROXY, proxy);
    }
    if (enable_sni_hack) {
        http_properties.put(ClientIDGenerator.PR_SNI_HACK, true);
    }
    try {
        ClientIDManagerImpl.getSingleton().generateHTTPProperties(torrent_hash.getBytes(), http_properties);
    } catch (ClientIDException e) {
        throw (new IOException(e.getMessage()));
    }
    reqUrl = (URL) http_properties.get(ClientIDGenerator.PR_URL);
    boolean is_https = reqUrl.getProtocol().equalsIgnoreCase("https");
    if (is_https) {
        // see ConfigurationChecker for SSL client defaults
        HttpsURLConnection ssl_con;
        if (proxy == null) {
            ssl_con = (HttpsURLConnection) reqUrl.openConnection();
        } else {
            ssl_con = (HttpsURLConnection) reqUrl.openConnection(proxy);
        }
        if (!internal_error_hack) {
            ssl_con.setHostnameVerifier(new HostnameVerifier() {

                @Override
                public boolean verify(String host, SSLSession session) {
                    return (true);
                }
            });
        }
        if (dh_hack) {
            UrlUtils.DHHackIt(ssl_con);
        }
        if (!first_effort) {
            // meh, some https trackers are just screwed
            TrustManager[] trustAllCerts = SESecurityManager.getAllTrustingTrustManager();
            try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, RandomUtils.SECURE_RANDOM);
                SSLSocketFactory factory = sc.getSocketFactory();
                ssl_con.setSSLSocketFactory(factory);
            } catch (Throwable e) {
            }
        }
        con = ssl_con;
    } else {
        if (proxy == null) {
            con = (HttpURLConnection) reqUrl.openConnection();
        } else {
            con = (HttpURLConnection) reqUrl.openConnection(proxy);
        }
    }
    // we want this true but some plugins (grrr) set the global default not to follow
    // redirects
    con.setInstanceFollowRedirects(true);
    String user_agent = (String) http_properties.get(ClientIDGenerator.PR_USER_AGENT);
    if (user_agent != null) {
        con.setRequestProperty("User-Agent", user_agent);
    }
    con.setRequestProperty("Connection", "close");
    // some trackers support gzip encoding of replies
    con.addRequestProperty("Accept-Encoding", "gzip");
    try {
        try {
            con.connect();
        } catch (AEProxyFactory.UnknownHostException e) {
            throw (new UnknownHostException(e.getMessage()));
        } catch (IOException e) {
            if (is_https) {
                String msg = Debug.getNestedExceptionMessage(e);
                if (msg.contains("unrecognized_name")) {
                    // SNI borkage - used to fix by globally disabling SNI but this screws too many other things
                    enable_sni_hack = true;
                } else if (msg.contains("internal_error") || msg.contains("handshake_failure")) {
                    internal_error_hack = true;
                } else if (msg.contains("DH keypair")) {
                    dh_hack = true;
                }
            }
            throw (e);
        }
        InputStream is = null;
        try {
            is = con.getInputStream();
            String resulting_url_str = con.getURL().toString();
            if (!reqUrl.toString().equals(resulting_url_str)) {
                // some kind of redirect has occurred. Unfortunately we can't get at the underlying
                // redirection reason (temp, perm etc) so we support the use of an explicit indicator
                // in the resulting url
                String marker = "permredirect=1";
                int pos = resulting_url_str.indexOf(marker);
                if (pos != -1) {
                    // include the '&' or '?'
                    pos = pos - 1;
                    try {
                        URL redirect_url = new URL(resulting_url_str.substring(0, pos));
                        tracker_url[0] = redirect_url;
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
            String encoding = con.getHeaderField("content-encoding");
            boolean gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
            if (gzip) {
                is = new GZIPInputStream(is);
            }
            // there are some trackers out there that don't set content length correctly
            // so we can't reliably use it :(
            // con.getContentLength();
            int content_length = -1;
            // System.out.println(length);
            byte[] data = new byte[1024];
            int num_read = 0;
            while (content_length <= 0 || num_read < content_length) {
                try {
                    int len = is.read(data);
                    if (len > 0) {
                        message.write(data, 0, len);
                        num_read += len;
                        if (num_read > 128 * 1024) {
                            // someone's sending us junk, bail out
                            message.reset();
                            throw (new Exception("Tracker response invalid (too large)"));
                        }
                    } else if (len == 0) {
                        Thread.sleep(20);
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    if (Logger.isEnabled()) {
                        Logger.log(new LogEvent(torrent, LOGID, "Exception while Requesting Tracker", e));
                        Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Message Received was : " + message));
                    }
                    failure_reason = exceptionToString(e);
                    break;
                }
            }
            if (Logger.isEnabled())
                Logger.log(new LogEvent(torrent, LOGID, "Tracker Announcer [" + lastUsedUrl + "] has received : " + message));
        } catch (SSLException e) {
            throw (e);
        } catch (Exception e) {
            // e.printStackTrace();
            failure_reason = exceptionToString(e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                }
                is = null;
            }
        }
    } finally {
        con.disconnect();
    }
    return (failure_reason);
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) LogEvent(com.biglybt.core.logging.LogEvent) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AEProxyFactory(com.biglybt.core.proxy.AEProxyFactory)

Example 2 with ClientIDException

use of com.biglybt.pif.clientid.ClientIDException in project BiglyBT by BiglySoftware.

the class PairingManagerImpl method sendRequest.

private Map<String, Object> sendRequest(String command, Map<String, Object> payload) throws PairingException {
    try {
        Map<String, Object> request = new HashMap<>();
        CryptoManager cman = CryptoManagerFactory.getSingleton();
        String azid = Base32.encode(cman.getSecureID());
        payload.put("_azid", azid);
        try {
            String pk = Base32.encode(cman.getECCHandler().getPublicKey("pairing"));
            payload.put("_pk", pk);
        } catch (Throwable e) {
        }
        request.put("req", payload);
        String request_str = Base32.encode(BEncoder.encode(request));
        String sig = null;
        try {
            sig = Base32.encode(cman.getECCHandler().sign(request_str.getBytes("UTF-8"), "pairing"));
        } catch (Throwable e) {
        }
        String other_params = "&ver=" + UrlUtils.encode(Constants.AZUREUS_VERSION) + "&app=" + UrlUtils.encode(SystemProperties.getApplicationName()) + "&locale=" + UrlUtils.encode(MessageText.getCurrentLocale().toString());
        if (sig != null) {
            other_params += "&sig=" + sig;
        }
        URL target = new URL(SERVICE_URL + "/client/" + command + "?request=" + request_str + other_params);
        Properties http_properties = new Properties();
        http_properties.put(ClientIDGenerator.PR_URL, target);
        try {
            ClientIDManagerImpl.getSingleton().generateHTTPProperties(null, http_properties);
        } catch (ClientIDException e) {
            throw (new IOException(e.getMessage()));
        }
        target = (URL) http_properties.get(ClientIDGenerator.PR_URL);
        HttpURLConnection connection = (HttpURLConnection) target.openConnection();
        connection.setConnectTimeout(30 * 1000);
        InputStream is = connection.getInputStream();
        Map<String, Object> response = (Map<String, Object>) BDecoder.decode(new BufferedInputStream(is));
        synchronized (this) {
            Long min_retry = (Long) response.get("min_secs");
            if (min_retry != null) {
                min_update_period = min_retry.intValue() * 1000;
            }
            Long max_retry = (Long) response.get("max_secs");
            if (max_retry != null) {
                max_update_period = max_retry.intValue() * 1000;
            }
        }
        final String message = getString(response, "message");
        if (message != null) {
            if (last_message == null || !last_message.equals(message)) {
                last_message = message;
                try {
                    byte[] message_sig = (byte[]) response.get("message_sig");
                    AEVerifier.verifyData(message, message_sig);
                    new AEThread2("PairMsg", true) {

                        @Override
                        public void run() {
                            UIManager ui_manager = StaticUtilities.getUIManager(120 * 1000);
                            if (ui_manager != null) {
                                ui_manager.showMessageBox("pairing.server.warning.title", "!" + message + "!", UIManagerEvent.MT_OK);
                            }
                        }
                    }.start();
                } catch (Throwable e) {
                }
            }
        }
        String error = getString(response, "error");
        if (error != null) {
            throw (new PairingException(error));
        }
        setLastServerError(null);
        Map<String, Object> reply = (Map<String, Object>) response.get("rep");
        Long qr_v = (Long) reply.get("qr_v");
        if (qr_v != null) {
            if (qr_version != qr_v.longValue()) {
                qr_version = qr_v;
                COConfigurationManager.setParameter("pairing.qr.ver", qr_version);
            }
        }
        return (reply);
    } catch (Throwable e) {
        setLastServerError(Debug.getNestedExceptionMessage(e));
        if (e instanceof PairingException) {
            throw ((PairingException) e);
        }
        throw (new PairingException("invocation failed", e));
    }
}
Also used : BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) UIManager(com.biglybt.pif.ui.UIManager) CryptoManager(com.biglybt.core.security.CryptoManager) IOException(java.io.IOException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) BufferedInputStream(java.io.BufferedInputStream)

Example 3 with ClientIDException

use of com.biglybt.pif.clientid.ClientIDException in project BiglyBT by BiglySoftware.

the class TrackerStatus method scrapeHTTPSupport.

private URL scrapeHTTPSupport(URL reqUrl, byte[] example_hash, Proxy proxy, ByteArrayOutputStream message) throws IOException {
    for (int connect_loop = 0; connect_loop < 3; connect_loop++) {
        URL redirect_url = null;
        TRTrackerUtils.checkForBlacklistedURLs(reqUrl);
        reqUrl = TRTrackerUtils.adjustURLForHosting(reqUrl);
        reqUrl = AddressUtils.adjustURL(reqUrl);
        // System.out.println( "scraping " + reqUrl.toString());
        Properties http_properties = new Properties();
        http_properties.put(ClientIDGenerator.PR_URL, reqUrl);
        if (proxy != null) {
            http_properties.put(ClientIDGenerator.PR_PROXY, proxy);
        }
        if (enable_sni_hack) {
            http_properties.put(ClientIDGenerator.PR_SNI_HACK, true);
        }
        try {
            ClientIDManagerImpl.getSingleton().generateHTTPProperties(example_hash, http_properties);
        } catch (ClientIDException e) {
            throw (new IOException(e.getMessage()));
        }
        reqUrl = (URL) http_properties.get(ClientIDGenerator.PR_URL);
        InputStream is = null;
        try {
            HttpURLConnection con = null;
            if (reqUrl.getProtocol().equalsIgnoreCase("https")) {
                // see ConfigurationChecker for SSL client defaults
                HttpsURLConnection ssl_con;
                if (proxy == null) {
                    ssl_con = (HttpsURLConnection) reqUrl.openConnection();
                } else {
                    ssl_con = (HttpsURLConnection) reqUrl.openConnection(proxy);
                }
                if (!internal_error_hack) {
                    ssl_con.setHostnameVerifier(new HostnameVerifier() {

                        @Override
                        public boolean verify(String host, SSLSession session) {
                            return (true);
                        }
                    });
                }
                if (dh_hack) {
                    UrlUtils.DHHackIt(ssl_con);
                }
                if (connect_loop > 0) {
                    // meh, some https trackers are just screwed
                    TrustManager[] trustAllCerts = SESecurityManager.getAllTrustingTrustManager();
                    try {
                        SSLContext sc = SSLContext.getInstance("SSL");
                        sc.init(null, trustAllCerts, RandomUtils.SECURE_RANDOM);
                        SSLSocketFactory factory = sc.getSocketFactory();
                        ssl_con.setSSLSocketFactory(factory);
                    } catch (Throwable e) {
                    }
                }
                con = ssl_con;
            } else {
                if (proxy == null) {
                    con = (HttpURLConnection) reqUrl.openConnection();
                } else {
                    con = (HttpURLConnection) reqUrl.openConnection(proxy);
                }
            }
            // we want this true but some plugins (grrr) set the global default not to follow
            // redirects
            con.setInstanceFollowRedirects(true);
            String user_agent = (String) http_properties.get(ClientIDGenerator.PR_USER_AGENT);
            if (user_agent != null) {
                con.setRequestProperty("User-Agent", user_agent);
            }
            // some trackers support gzip encoding of replies
            con.addRequestProperty("Accept-Encoding", "gzip");
            con.setRequestProperty("Connection", "close");
            try {
                con.connect();
            } catch (AEProxyFactory.UnknownHostException e) {
                throw (new UnknownHostException(e.getMessage()));
            }
            is = con.getInputStream();
            String resulting_url_str = con.getURL().toString();
            if (!reqUrl.toString().equals(resulting_url_str)) {
                // some kind of redirect has occurred. Unfortunately we can't get at the underlying
                // redirection reason (temp, perm etc) so we support the use of an explicit indicator
                // in the resulting url
                String marker = "permredirect=1";
                int pos = resulting_url_str.indexOf(marker);
                if (pos != -1) {
                    // include the '&' or '?'
                    pos = pos - 1;
                    try {
                        redirect_url = new URL(resulting_url_str.substring(0, pos));
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
            String encoding = con.getHeaderField("content-encoding");
            boolean gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
            if (gzip) {
                is = new GZIPInputStream(is);
            }
            byte[] data = new byte[1024];
            int num_read = 0;
            while (true) {
                try {
                    int len = is.read(data);
                    if (len > 0) {
                        message.write(data, 0, len);
                        num_read += len;
                        if (num_read > 128 * 1024) {
                            // someone's sending us junk, bail out
                            message.reset();
                            throw (new Exception("Tracker response invalid (too large)"));
                        }
                    } else if (len == 0) {
                        Thread.sleep(20);
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    if (Logger.isEnabled())
                        Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Error from scrape interface " + scrapeURL + " : " + Debug.getNestedExceptionMessage(e)));
                    return (null);
                }
            }
        } catch (SSLException e) {
            if (connect_loop < 3) {
                String msg = Debug.getNestedExceptionMessage(e);
                boolean try_again = false;
                if (msg.contains("unrecognized_name")) {
                    if (!enable_sni_hack) {
                        enable_sni_hack = true;
                        try_again = true;
                    }
                } else if (msg.contains("internal_error") || msg.contains("handshake_failure")) {
                    if (!internal_error_hack) {
                        internal_error_hack = true;
                        try_again = true;
                    }
                } else if (msg.contains("DH keypair")) {
                    if (!dh_hack) {
                        dh_hack = true;
                        try_again = true;
                    }
                }
                if (SESecurityManager.installServerCertificates(reqUrl) != null || connect_loop == 0) {
                    // certificate has been installed
                    try_again = true;
                }
                if (try_again) {
                    continue;
                }
            }
            throw (e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e1) {
                }
            }
        }
        return (redirect_url);
    }
    throw (new IOException("Shouldn't get here"));
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) LogEvent(com.biglybt.core.logging.LogEvent) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) PRUDPPacketHandlerException(com.biglybt.net.udp.uc.PRUDPPacketHandlerException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) AEProxyFactory(com.biglybt.core.proxy.AEProxyFactory)

Aggregations

ClientIDException (com.biglybt.pif.clientid.ClientIDException)3 IOException (java.io.IOException)3 InputStream (java.io.InputStream)3 LogEvent (com.biglybt.core.logging.LogEvent)2 AEProxyFactory (com.biglybt.core.proxy.AEProxyFactory)2 GZIPInputStream (java.util.zip.GZIPInputStream)2 CryptoManager (com.biglybt.core.security.CryptoManager)1 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)1 PRUDPPacketHandlerException (com.biglybt.net.udp.uc.PRUDPPacketHandlerException)1 UIManager (com.biglybt.pif.ui.UIManager)1 BufferedInputStream (java.io.BufferedInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1