Search in sources :

Example 1 with NetworkAdminPropertyChangeListener

use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.

the class CoreImpl method start.

@Override
public void start() throws CoreException {
    if (!canStart()) {
        throw (new CoreException("Core: already started (alternative process)"));
    }
    AEThread2.setOurThread();
    try {
        this_mon.enter();
        if (started) {
            throw (new CoreException("Core: already started"));
        }
        if (stopped) {
            throw (new CoreException("Core: already stopped"));
        }
        started = true;
    } finally {
        this_mon.exit();
    }
    // If a user sets this property, it is an alias for the following settings.
    if ("1".equals(System.getProperty(SystemProperties.SYSPROP_SAFEMODE))) {
        if (Logger.isEnabled())
            Logger.log(new LogEvent(LOGID, "Safe mode enabled"));
        Constants.isSafeMode = true;
        System.setProperty(SystemProperties.SYSPROP_LOADPLUGINS, "0");
        System.setProperty(SystemProperties.SYSPROP_DISABLEDOWNLOADS, "1");
        System.setProperty(SystemProperties.SYSPROP_SKIP_SWTCHECK, "1");
        // Not using localised text - not sure it's safe to this early.
        Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogEvent.LT_WARNING, "You are running " + Constants.APP_NAME + " in safe mode - you " + "can change your configuration, but any downloads added will " + "not be remembered when you close " + Constants.APP_NAME + "."));
    }
    /**
     * test to see if UI plays nicely with a really slow initialization
     */
    String sDelayCore = System.getProperty("delay.core", null);
    if (sDelayCore != null) {
        try {
            long delayCore = Long.parseLong(sDelayCore);
            Thread.sleep(delayCore);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // run plugin loading in parallel to the global manager loading
    AEThread2 pluginload = new AEThread2("PluginLoader", true) {

        @Override
        public void run() {
            if (Logger.isEnabled())
                Logger.log(new LogEvent(LOGID, "Loading of Plugins starts"));
            pi.loadPlugins(CoreImpl.this, false, !"0".equals(System.getProperty(SystemProperties.SYSPROP_LOADPLUGINS)), true, true);
            if (Logger.isEnabled())
                Logger.log(new LogEvent(LOGID, "Loading of Plugins complete"));
        }
    };
    if (LOAD_PLUGINS_IN_OTHER_THREAD) {
        pluginload.start();
    } else {
        pluginload.run();
    }
    // Disable async loading of existing torrents, because there are many things
    // (like hosting) that require all the torrents to be loaded.  While we
    // can write code for each of these cases to wait until the torrents are
    // loaded, it's a pretty big job to find them all and fix all their quirks.
    // Too big of a job for this late in the release stage.
    // Other example is the tracker plugin that is coded in a way where it must
    // always publish a complete rss feed
    global_manager = GlobalManagerFactory.create(this, null, 0);
    if (stopped) {
        System.err.println("Core stopped while starting");
        return;
    }
    // wait until plugin loading is done
    if (LOAD_PLUGINS_IN_OTHER_THREAD) {
        pluginload.join();
    }
    if (stopped) {
        System.err.println("Core stopped while starting");
        return;
    }
    VuzeFileHandler.getSingleton().addProcessor(new VuzeFileProcessor() {

        @Override
        public void process(VuzeFile[] files, int expected_types) {
            for (int i = 0; i < files.length; i++) {
                VuzeFile vf = files[i];
                VuzeFileComponent[] comps = vf.getComponents();
                for (int j = 0; j < comps.length; j++) {
                    VuzeFileComponent comp = comps[j];
                    int comp_type = comp.getType();
                    if (comp_type == VuzeFileComponent.COMP_TYPE_ADD_TORRENT) {
                        PluginInterface default_pi = getPluginManager().getDefaultPluginInterface();
                        Map map = comp.getContent();
                        try {
                            Torrent torrent;
                            String url = MapUtils.getMapString(map, "torrent_url", null);
                            if (url != null) {
                                TorrentDownloader dl = default_pi.getTorrentManager().getURLDownloader(new URL(url));
                                torrent = dl.download();
                            } else {
                                String tf = MapUtils.getMapString(map, "torrent_file", null);
                                if (tf != null) {
                                    File file = new File(tf);
                                    if (!file.canRead() || file.isDirectory()) {
                                        throw (new Exception("torrent_file '" + tf + "' is invalid"));
                                    }
                                    torrent = default_pi.getTorrentManager().createFromBEncodedFile(file);
                                } else {
                                    throw (new Exception("torrent_url or torrent_file must be specified"));
                                }
                            }
                            File dest = null;
                            String save_folder = MapUtils.getMapString(map, "save_folder", null);
                            if (save_folder != null) {
                                dest = new File(save_folder, torrent.getName());
                            } else {
                                String save_file = MapUtils.getMapString(map, "save_file", null);
                                if (save_file != null) {
                                    dest = new File(save_file);
                                }
                            }
                            if (dest != null) {
                                dest.getParentFile().mkdirs();
                            }
                            default_pi.getDownloadManager().addDownload(torrent, null, dest);
                        } catch (Throwable e) {
                            Debug.out(e);
                        }
                        comp.setProcessed();
                    }
                }
            }
        }
    });
    triggerLifeCycleComponentCreated(global_manager);
    pi.initialisePlugins();
    if (stopped) {
        System.err.println("Core stopped while starting");
        return;
    }
    if (Logger.isEnabled())
        Logger.log(new LogEvent(LOGID, "Initializing Plugins complete"));
    try {
        PluginInterface dht_pi = getPluginManager().getPluginInterfaceByClass(DHTPlugin.class);
        if (dht_pi != null) {
            dht_pi.addEventListener(new PluginEventListener() {

                private boolean first_dht = true;

                @Override
                public void handleEvent(PluginEvent ev) {
                    if (ev.getType() == DHTPlugin.EVENT_DHT_AVAILABLE) {
                        if (first_dht) {
                            first_dht = false;
                            DHT dht = (DHT) ev.getValue();
                            dht.addListener(new DHTListener() {

                                @Override
                                public void speedTesterAvailable(DHTSpeedTester tester) {
                                    if (speed_manager != null) {
                                        speed_manager.setSpeedTester(tester);
                                    }
                                }
                            });
                            global_manager.addListener(new GlobalManagerAdapter() {

                                @Override
                                public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
                                    checkConfig();
                                }
                            });
                            COConfigurationManager.addAndFireParameterListeners(new String[] { TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY, TransferSpeedValidator.AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY }, new ParameterListener() {

                                @Override
                                public void parameterChanged(String parameterName) {
                                    checkConfig();
                                }
                            });
                        }
                    }
                }

                protected void checkConfig() {
                    if (speed_manager != null) {
                        speed_manager.setEnabled(TransferSpeedValidator.isAutoSpeedActive(global_manager));
                    }
                }
            });
        }
    } catch (Throwable e) {
    }
    if (COConfigurationManager.getBooleanParameter("Resume Downloads On Start")) {
        global_manager.resumeDownloads();
    }
    VersionCheckClient.getSingleton().initialise();
    instance_manager.initialize();
    NetworkManager.getSingleton().initialize(this);
    SpeedLimitHandler.getSingleton(this);
    Runtime.getRuntime().addShutdownHook(new AEThread("Shutdown Hook") {

        @Override
        public void runSupport() {
            Logger.log(new LogEvent(LOGID, "Shutdown hook triggered"));
            CoreImpl.this.stop();
        }
    });
    DelayedTask delayed_task = UtilitiesImpl.addDelayedTask("Core", new Runnable() {

        @Override
        public void run() {
            new AEThread2("core:delayTask", true) {

                @Override
                public void run() {
                    AEDiagnostics.checkDumpsAndNatives();
                    COConfigurationManager.setParameter("diags.enable.pending.writes", true);
                    AEDiagnostics.flushPendingLogs();
                    NetworkAdmin na = NetworkAdmin.getSingleton();
                    na.runInitialChecks(CoreImpl.this);
                    na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {

                        private String last_as;

                        @Override
                        public void propertyChanged(String property) {
                            NetworkAdmin na = NetworkAdmin.getSingleton();
                            if (property.equals(NetworkAdmin.PR_NETWORK_INTERFACES)) {
                                boolean found_usable = false;
                                NetworkAdminNetworkInterface[] intf = na.getInterfaces();
                                for (int i = 0; i < intf.length; i++) {
                                    NetworkAdminNetworkInterfaceAddress[] addresses = intf[i].getAddresses();
                                    for (int j = 0; j < addresses.length; j++) {
                                        if (!addresses[j].isLoopback()) {
                                            found_usable = true;
                                        }
                                    }
                                }
                                if (!found_usable) {
                                    return;
                                }
                                Logger.log(new LogEvent(LOGID, "Network interfaces have changed (new=" + na.getNetworkInterfacesAsString() + ")"));
                                announceAll(false);
                            } else if (property.equals(NetworkAdmin.PR_AS)) {
                                String as = na.getCurrentASN().getAS();
                                if (last_as == null) {
                                    last_as = as;
                                } else if (!as.equals(last_as)) {
                                    Logger.log(new LogEvent(LOGID, "AS has changed (new=" + as + ")"));
                                    last_as = as;
                                    announceAll(false);
                                }
                            }
                        }
                    });
                    setupSleepAndCloseActions();
                }
            }.start();
        }
    });
    delayed_task.queue();
    if (stopped) {
        System.err.println("Core stopped while starting");
        return;
    }
    PairingManagerFactory.getSingleton();
    CoreRunningListener[] runningListeners;
    mon_coreRunningListeners.enter();
    try {
        if (coreRunningListeners == null) {
            runningListeners = new CoreRunningListener[0];
        } else {
            runningListeners = coreRunningListeners.toArray(new CoreRunningListener[0]);
            coreRunningListeners = null;
        }
    } finally {
        mon_coreRunningListeners.exit();
    }
    // Trigger Listeners now that core is started
    new AEThread2("Plugin Init Complete", false) {

        @Override
        public void run() {
            try {
                PlatformManagerFactory.getPlatformManager().startup(CoreImpl.this);
            } catch (Throwable e) {
                Debug.out("PlatformManager: init failed", e);
            }
            Iterator it = lifecycle_listeners.iterator();
            while (it.hasNext()) {
                try {
                    CoreLifecycleListener listener = (CoreLifecycleListener) it.next();
                    if (!listener.requiresPluginInitCompleteBeforeStartedEvent()) {
                        listener.started(CoreImpl.this);
                    }
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
            }
            pi.initialisationComplete();
            it = lifecycle_listeners.iterator();
            while (it.hasNext()) {
                try {
                    CoreLifecycleListener listener = (CoreLifecycleListener) it.next();
                    if (listener.requiresPluginInitCompleteBeforeStartedEvent()) {
                        listener.started(CoreImpl.this);
                    }
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
            }
        }
    }.start();
    // Typically there are many runningListeners, most with quick execution, and
    // a few longer ones.  Let 3 run at a time, queue the rest.  Without
    // a ThreadPool, the slow ones would delay the startup processes that run
    // after this start() method
    ThreadPool tp = new ThreadPool("Trigger CoreRunning Listeners", 3);
    for (final CoreRunningListener l : runningListeners) {
        try {
            tp.run(new AERunnable() {

                @Override
                public void runSupport() {
                    l.coreRunning(CoreImpl.this);
                }
            });
        } catch (Throwable t) {
            Debug.out(t);
        }
    }
// Debug.out("Core Start Complete");
}
Also used : Torrent(com.biglybt.pif.torrent.Torrent) TOTorrent(com.biglybt.core.torrent.TOTorrent) DHTSpeedTester(com.biglybt.core.dht.speed.DHTSpeedTester) VuzeFileComponent(com.biglybt.core.vuzefile.VuzeFileComponent) URL(java.net.URL) DHT(com.biglybt.core.dht.DHT) NetworkAdmin(com.biglybt.core.networkmanager.admin.NetworkAdmin) DHTListener(com.biglybt.core.dht.DHTListener) VuzeFile(com.biglybt.core.vuzefile.VuzeFile) DelayedTask(com.biglybt.pif.utils.DelayedTask) LogEvent(com.biglybt.core.logging.LogEvent) LogAlert(com.biglybt.core.logging.LogAlert) VuzeFileProcessor(com.biglybt.core.vuzefile.VuzeFileProcessor) NetworkAdminPropertyChangeListener(com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener) GlobalManagerAdapter(com.biglybt.core.global.GlobalManagerAdapter) ParameterListener(com.biglybt.core.config.ParameterListener) TorrentDownloader(com.biglybt.pif.torrent.TorrentDownloader) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) VuzeFile(com.biglybt.core.vuzefile.VuzeFile)

Example 2 with NetworkAdminPropertyChangeListener

use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.

the class WebPlugin method setupServer.

protected void setupServer() {
    try {
        if (!plugin_enabled) {
            if (tracker_context != null) {
                tracker_context.destroy();
                tracker_context = null;
            }
            return;
        }
        final int port = param_port.getValue();
        String protocol_str = param_protocol.getValue().trim();
        String bind_str = param_bind.getValue().trim();
        InetAddress bind_ip = null;
        if (bind_str.length() > 0) {
            try {
                bind_ip = InetAddress.getByName(bind_str);
            } catch (Throwable e) {
            }
            if (bind_ip == null) {
                // might be an interface name, see if we can resolve it
                final NetworkAdmin na = NetworkAdmin.getSingleton();
                InetAddress[] addresses = na.resolveBindAddresses(bind_str);
                if (addresses.length > 0) {
                    bind_ip = addresses[0];
                    if (!na_intf_listener_added) {
                        na_intf_listener_added = true;
                        na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {

                            @Override
                            public void propertyChanged(String property) {
                                if (unloaded) {
                                    na.removePropertyChangeListener(this);
                                } else {
                                    if (property == NetworkAdmin.PR_NETWORK_INTERFACES) {
                                        new AEThread2("setupserver") {

                                            @Override
                                            public void run() {
                                                setupServer();
                                            }
                                        }.start();
                                    }
                                }
                            }
                        });
                    }
                }
            }
            if (bind_ip == null) {
                log.log(LoggerChannel.LT_ERROR, "Bind IP parameter '" + bind_str + "' is invalid");
            }
        }
        if (tracker_context != null) {
            URL url = tracker_context.getURLs()[0];
            String existing_protocol = url.getProtocol();
            int existing_port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
            InetAddress existing_bind_ip = tracker_context.getBindIP();
            if (existing_port == port && existing_protocol.equalsIgnoreCase(protocol_str) && sameAddress(bind_ip, existing_bind_ip)) {
                return;
            }
            tracker_context.destroy();
            tracker_context = null;
        }
        int protocol = protocol_str.equalsIgnoreCase("HTTP") ? Tracker.PR_HTTP : Tracker.PR_HTTPS;
        Map<String, Object> tc_properties = new HashMap<>();
        Boolean prop_non_blocking = (Boolean) properties.get(PR_NON_BLOCKING);
        if (prop_non_blocking != null && prop_non_blocking) {
            tc_properties.put(Tracker.PR_NON_BLOCKING, true);
        }
        log.log(LoggerChannel.LT_INFORMATION, "Server initialisation: port=" + port + (bind_ip == null ? "" : (", bind=" + bind_str + "->" + bind_ip + ")")) + ", protocol=" + protocol_str + (root_dir.length() == 0 ? "" : (", root=" + root_dir)) + (properties.size() == 0 ? "" : (", props=" + properties)));
        tracker_context = plugin_interface.getTracker().createWebContext(Constants.APP_NAME + " - " + plugin_interface.getPluginName(), port, protocol, bind_ip, tc_properties);
        Boolean prop_enable_i2p = (Boolean) properties.get(PR_ENABLE_I2P);
        if (prop_enable_i2p == null || prop_enable_i2p) {
            network_dispatcher.dispatch(new AERunnable() {

                @Override
                public void runSupport() {
                    Map<String, Object> options = new HashMap<>();
                    options.put(AEProxyFactory.SP_PORT, port);
                    Map<String, Object> reply = AEProxyFactory.getPluginServerProxy(plugin_interface.getPluginName(), AENetworkClassifier.AT_I2P, plugin_interface.getPluginID(), options);
                    if (reply != null) {
                        param_i2p_dest.setVisible(true);
                        String host = (String) reply.get("host");
                        if (!param_i2p_dest.getValue().equals(host)) {
                            param_i2p_dest.setValue(host);
                            if (p_sid != null) {
                                updatePairing(p_sid);
                            }
                        }
                    }
                }
            });
        }
        Boolean prop_enable_tor = (Boolean) properties.get(PR_ENABLE_TOR);
        if (prop_enable_tor == null || prop_enable_tor) {
            network_dispatcher.dispatch(new AERunnable() {

                @Override
                public void runSupport() {
                    Map<String, Object> options = new HashMap<>();
                    options.put(AEProxyFactory.SP_PORT, port);
                    Map<String, Object> reply = AEProxyFactory.getPluginServerProxy(plugin_interface.getPluginName(), AENetworkClassifier.AT_TOR, plugin_interface.getPluginID(), options);
                    if (reply != null) {
                        param_tor_dest.setVisible(true);
                        String host = (String) reply.get("host");
                        if (!param_tor_dest.getValue().equals(host)) {
                            param_tor_dest.setValue(host);
                            if (p_sid != null) {
                                updatePairing(p_sid);
                            }
                        }
                    }
                }
            });
        }
        Boolean pr_enable_keep_alive = (Boolean) properties.get(PR_ENABLE_KEEP_ALIVE);
        if (pr_enable_keep_alive != null && pr_enable_keep_alive) {
            tracker_context.setEnableKeepAlive(true);
        }
        tracker_context.addPageGenerator(this);
        tracker_context.addAuthenticationListener(new TrackerAuthenticationAdapter() {

            private String last_pw = "";

            private byte[] last_hash = {};

            private final int DELAY = 10 * 1000;

            private Map<String, Object[]> fail_map = new HashMap<>();

            @Override
            public boolean authenticate(String headers, URL resource, String user, String pw) {
                // System.out.println( resource + ": " + user + "/" + pw );
                long now = SystemTime.getMonotonousTime();
                String client_address = getHeaderField(headers, "X-Real-IP");
                if (client_address == null) {
                    client_address = "<unknown>";
                }
                synchronized (logout_timer) {
                    Long logout_time = logout_timer.get(client_address);
                    if (logout_time != null && now - logout_time <= LOGOUT_GRACE_MILLIS) {
                        tls.set(GRACE_PERIOD_MARKER);
                        return (true);
                    }
                }
                boolean result = authenticateSupport(headers, resource, user, pw);
                if (!result) {
                    if (!pw.equals("")) {
                        AESemaphore waiter = null;
                        synchronized (fail_map) {
                            Object[] x = fail_map.get(client_address);
                            if (x == null) {
                                x = new Object[] { new AESemaphore("af:waiter"), new Long(-1), new Long(-1), now };
                                fail_map.put(client_address, x);
                            } else {
                                x[1] = x[2];
                                x[2] = x[3];
                                x[3] = now;
                                long t = (Long) x[1];
                                if (now - t < 10 * 1000) {
                                    log("Too many recent authentication failures from '" + client_address + "' - rate limiting");
                                    x[2] = now + DELAY;
                                    // there's a bug where flipping the password on doesn't reset the pw so we automatically fail without checking
                                    // this is not the correct fix, but it works
                                    last_pw = "";
                                    waiter = (AESemaphore) x[0];
                                }
                            }
                        }
                        if (waiter != null) {
                            waiter.reserve(DELAY);
                        }
                    }
                } else {
                    synchronized (fail_map) {
                        fail_map.remove(client_address);
                    }
                    String cookies = getHeaderField(headers, "Cookie");
                    if (pairing_session_code != null) {
                        if (cookies == null || !cookies.contains(pairing_session_code)) {
                            tls.set(pairing_session_code);
                        }
                    }
                }
                recordAuthRequest(client_address, result);
                if (!result) {
                // going to be generous here as (old android browsers at least) sometimes fail to provide
                // auth on .png files
                // no I'm not, too many risks associated with this (e.g. xmwebui has some
                // prefix url logic which may be exploitable)
                // if ( resource.getPath().endsWith( ".png" )){
                // 
                // result = true;
                // }
                }
                return (result);
            }

            private boolean authenticateSupport(String headers, URL resource, String user, String pw) {
                boolean result;
                boolean auto_auth = param_auto_auth != null && param_auto_auth.getValue();
                if (!pw_enable.getValue()) {
                    String whitelist = p_no_pw_whitelist.getValue().trim();
                    if (whitelist.equals("*")) {
                        result = true;
                    } else {
                        String actual_host = getHeaderField(headers, "host");
                        int actual_port = protocol == Tracker.PR_HTTP ? 80 : 443;
                        String referrer = getHeaderField(headers, "referer");
                        if (actual_host.startsWith("[")) {
                            int pos = actual_host.lastIndexOf(']');
                            if (pos != -1) {
                                String rem = actual_host.substring(pos + 1);
                                actual_host = actual_host.substring(0, pos + 1);
                                pos = rem.indexOf(':');
                                if (pos != -1) {
                                    actual_port = Integer.parseInt(rem.substring(pos + 1).trim());
                                }
                            }
                        } else {
                            int pos = actual_host.indexOf(':');
                            if (pos != -1) {
                                actual_port = Integer.parseInt(actual_host.substring(pos + 1).trim());
                                actual_host = actual_host.substring(0, pos);
                            }
                        }
                        String[] allowed = whitelist.split(",");
                        result = false;
                        String msg = "";
                        if (actual_port != port) {
                            msg = "port mismatch: " + port + "/" + actual_port;
                        } else {
                            for (String a : allowed) {
                                a = a.trim();
                                if (a.equals("$")) {
                                    InetAddress bind = getServerBindIP();
                                    if (bind != null) {
                                        if (bind instanceof Inet6Address) {
                                            a = "[" + bind.getHostAddress() + "]";
                                        } else {
                                            a = bind.getHostAddress();
                                        }
                                    }
                                }
                                if (actual_host.equals(a.trim())) {
                                    result = true;
                                    break;
                                }
                                // Support ranges (copied from code in setupAccess)
                                IPRange ip_range = plugin_interface.getIPFilter().createRange(true);
                                String aTrimmed = a.trim();
                                int sep = aTrimmed.indexOf("-");
                                if (sep == -1) {
                                    ip_range.setStartIP(aTrimmed);
                                    ip_range.setEndIP(aTrimmed);
                                } else {
                                    ip_range.setStartIP(aTrimmed.substring(0, sep).trim());
                                    ip_range.setEndIP(aTrimmed.substring(sep + 1).trim());
                                }
                                ip_range.checkValid();
                                if (ip_range.isValid() && ip_range.isInRange(actual_host)) {
                                    result = true;
                                    break;
                                }
                            }
                            if (!result) {
                                msg = "host '" + actual_host + "' not in whitelist";
                            } else {
                                if (referrer != null) {
                                    result = false;
                                    try {
                                        URL url = new URL(referrer);
                                        int ref_port = url.getPort();
                                        if (ref_port == -1) {
                                            ref_port = url.getDefaultPort();
                                        }
                                        if (ref_port == port) {
                                            result = true;
                                        }
                                    } catch (Throwable e) {
                                    }
                                    if (!result) {
                                        msg = "referrer mismatch: " + referrer;
                                    }
                                }
                            }
                        }
                        if (!result) {
                            log.log("Access denied: No password and " + msg);
                        }
                    }
                } else {
                    if (auto_auth) {
                        user = user.trim().toLowerCase();
                        pw = pw.toUpperCase();
                    }
                    if (!user.equals(p_user_name.getValue())) {
                        log.log("Access denied: Incorrect user name: " + user);
                        result = false;
                    } else {
                        byte[] hash = last_hash;
                        if (!last_pw.equals(pw)) {
                            hash = plugin_interface.getUtilities().getSecurityManager().calculateSHA1(auto_auth ? pw.toUpperCase().getBytes() : pw.getBytes());
                            last_pw = pw;
                            last_hash = hash;
                        }
                        result = Arrays.equals(hash, p_password.getValue());
                        if (!result) {
                            log.log("Access denied: Incorrect password");
                        }
                    }
                }
                if (result) {
                    // user name and password match, see if we've come from the pairing process
                    checkCookieSet(headers, resource);
                } else if (auto_auth) {
                    // either the ac is in the url, referer or we have a cookie set
                    int x = checkCookieSet(headers, resource);
                    if (x == 1) {
                        result = true;
                    } else if (x == 0) {
                        result = hasOurCookie(getHeaderField(headers, "Cookie"));
                    }
                } else {
                    result = hasOurCookie(getHeaderField(headers, "Cookie"));
                }
                return (result);
            }

            /**
             * @param headers
             * @param resource
             * @return 0 = unknown, 1 = ok, 2 = bad
             */
            private int checkCookieSet(String headers, URL resource) {
                if (pairing_access_code == null) {
                    return (2);
                }
                String[] locations = { resource.getQuery(), getHeaderField(headers, "Referer") };
                for (String location : locations) {
                    if (location != null) {
                        boolean skip_fail = false;
                        int param_len = 0;
                        int p1 = location.indexOf("vuze_pairing_ac=");
                        if (p1 == -1) {
                            p1 = location.indexOf("ac=");
                            if (p1 != -1) {
                                param_len = 3;
                                skip_fail = true;
                            }
                        } else {
                            param_len = 16;
                        }
                        if (p1 != -1) {
                            int p2 = location.indexOf('&', p1);
                            String ac = location.substring(p1 + param_len, p2 == -1 ? location.length() : p2).trim();
                            p2 = ac.indexOf('#');
                            if (p2 != -1) {
                                ac = ac.substring(0, p2);
                            }
                            if (ac.equalsIgnoreCase(pairing_access_code)) {
                                tls.set(pairing_session_code);
                                return (1);
                            } else {
                                if (!skip_fail) {
                                    return (2);
                                }
                            }
                        }
                    }
                }
                return (0);
            }

            private String getHeaderField(String headers, String field) {
                String[] lines = headers.split("\n");
                for (String line : lines) {
                    int pos = line.indexOf(':');
                    if (pos != -1) {
                        if (line.substring(0, pos).equalsIgnoreCase(field)) {
                            return (line.substring(pos + 1).trim());
                        }
                    }
                }
                return (null);
            }
        });
    } catch (TrackerException e) {
        log.log("Server initialisation failed", e);
    }
}
Also used : IPRange(com.biglybt.pif.ipfilter.IPRange) URL(java.net.URL) NetworkAdmin(com.biglybt.core.networkmanager.admin.NetworkAdmin) TrackerException(com.biglybt.pif.tracker.TrackerException) Inet6Address(java.net.Inet6Address) NetworkAdminPropertyChangeListener(com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener) JSONObject(org.json.simple.JSONObject) InetAddress(java.net.InetAddress)

Example 3 with NetworkAdminPropertyChangeListener

use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.

the class PMSWTImpl method initialise.

@Override
public void initialise(final PluginInterface pi, final BooleanParameter icon_enable) {
    final NetworkAdmin na = NetworkAdmin.getSingleton();
    na.addPropertyChangeListener(new NetworkAdminPropertyChangeListener() {

        @Override
        public void propertyChanged(String property) {
            if (property == NetworkAdmin.PR_NETWORK_INTERFACES) {
                updateLocalAddresses(na);
            }
        }
    });
    updateLocalAddresses(na);
    pi.getUIManager().addUIListener(new UIManagerListener() {

        @Override
        public void UIAttached(final UIInstance instance) {
            if (instance instanceof UISWTInstance) {
                UIFunctions uif = UIFunctionsManager.getUIFunctions();
                if (uif != null) {
                    uiUpdaterListener = new UIUpdaterListener() {

                        @Override
                        public void updateComplete(int count) {
                            last_update_count = count;
                            updateStatus(true);
                        }
                    };
                    uif.getUIUpdater().addListener(uiUpdaterListener);
                }
                Utils.execSWTThread(new AERunnable() {

                    @Override
                    public void runSupport() {
                        ImageLoader imageLoader = ImageLoader.getInstance();
                        icon_idle = imageLoader.getImage("pair_sb_idle");
                        icon_green = imageLoader.getImage("pair_sb_green");
                        icon_red = imageLoader.getImage("pair_sb_red");
                        UISWTInstance ui_instance = (UISWTInstance) instance;
                        status = ui_instance.createStatusEntry();
                        last_tooltip_text = MessageText.getString("pairing.ui.icon.tip");
                        status.setTooltipText(last_tooltip_text);
                        status.setImageEnabled(true);
                        status.setImage(icon_idle);
                        last_image = icon_idle;
                        boolean is_visible = icon_enable.getValue();
                        status.setVisible(is_visible);
                        if (is_visible) {
                            updateStatus(false);
                        }
                        final MenuItem mi_show = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "pairing.ui.icon.show");
                        mi_show.setStyle(MenuItem.STYLE_CHECK);
                        mi_show.setData(Boolean.valueOf(is_visible));
                        mi_show.addListener(new MenuItemListener() {

                            @Override
                            public void selected(MenuItem menu, Object target) {
                                icon_enable.setValue(false);
                            }
                        });
                        iconEnableListener = new ParameterListener() {

                            @Override
                            public void parameterChanged(Parameter param) {
                                boolean is_visible = icon_enable.getValue();
                                status.setVisible(is_visible);
                                mi_show.setData(Boolean.valueOf(is_visible));
                                if (is_visible) {
                                    updateStatus(false);
                                }
                            }
                        };
                        icon_enable.addListener(iconEnableListener);
                        MenuItem mi_pairing = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "MainWindow.menu.pairing");
                        mi_pairing.addListener(new MenuItemListener() {

                            @Override
                            public void selected(MenuItem menu, Object target) {
                                UIFunctions uif = UIFunctionsManager.getUIFunctions();
                                if (uif == null) {
                                    Debug.out("UIFunctions not available, can't open remote pairing window");
                                } else {
                                    uif.openRemotePairingWindow();
                                }
                            }
                        });
                        MenuItem mi_sep = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "");
                        mi_sep.setStyle(MenuItem.STYLE_SEPARATOR);
                        MenuItem mi_options = pi.getUIManager().getMenuManager().addMenuItem(status.getMenuContext(), "MainWindow.menu.view.configuration");
                        mi_options.addListener(new MenuItemListener() {

                            @Override
                            public void selected(MenuItem menu, Object target) {
                                UIFunctions uif = UIFunctionsManager.getUIFunctions();
                                if (uif != null) {
                                    uif.getMDI().showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, PairingManager.CONFIG_SECTION_ID);
                                }
                            }
                        });
                        UISWTStatusEntryListener click_listener = new UISWTStatusEntryListener() {

                            @Override
                            public void entryClicked(UISWTStatusEntry entry) {
                                UIFunctions uif = UIFunctionsManager.getUIFunctions();
                                if (uif != null) {
                                    uif.getMDI().showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, PairingManager.CONFIG_SECTION_ID);
                                }
                            }
                        };
                        status.setListener(click_listener);
                    }
                });
            }
        }

        @Override
        public void UIDetached(UIInstance instance) {
            if (instance instanceof UISWTInstance) {
                UIFunctions uif = UIFunctionsManager.getUIFunctions();
                if (uif != null && uiUpdaterListener != null) {
                    uif.getUIUpdater().removeListener(uiUpdaterListener);
                    uiUpdaterListener = null;
                }
                if (status != null) {
                    // menu items get destroyed with this call
                    status.destroy();
                    status = null;
                }
                if (icon_enable != null && iconEnableListener != null) {
                    icon_enable.removeListener(iconEnableListener);
                    iconEnableListener = null;
                }
            }
        }
    });
}
Also used : UIUpdaterListener(com.biglybt.ui.common.updater.UIUpdater.UIUpdaterListener) UISWTStatusEntryListener(com.biglybt.ui.swt.pif.UISWTStatusEntryListener) MenuItem(com.biglybt.pif.ui.menus.MenuItem) NetworkAdminPropertyChangeListener(com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener) NetworkAdmin(com.biglybt.core.networkmanager.admin.NetworkAdmin) UIFunctions(com.biglybt.ui.UIFunctions) UISWTStatusEntry(com.biglybt.ui.swt.pif.UISWTStatusEntry) ParameterListener(com.biglybt.pif.ui.config.ParameterListener) BooleanParameter(com.biglybt.pif.ui.config.BooleanParameter) Parameter(com.biglybt.pif.ui.config.Parameter) MenuItemListener(com.biglybt.pif.ui.menus.MenuItemListener) UISWTInstance(com.biglybt.ui.swt.pif.UISWTInstance) UIManagerListener(com.biglybt.pif.ui.UIManagerListener) ImageLoader(com.biglybt.ui.swt.imageloader.ImageLoader) UIInstance(com.biglybt.pif.ui.UIInstance)

Example 4 with NetworkAdminPropertyChangeListener

use of com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener in project BiglyBT by BiglySoftware.

the class PRUDPPacketHandlerImpl method receiveLoop.

protected void receiveLoop(AESemaphore init_sem) {
    long last_socket_close_time = 0;
    NetworkAdminPropertyChangeListener prop_listener = new NetworkAdminPropertyChangeListener() {

        @Override
        public void propertyChanged(String property) {
            if (property == NetworkAdmin.PR_DEFAULT_BIND_ADDRESS) {
                setDefaultBindAddress(NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress());
            }
        }
    };
    NetworkAdmin.getSingleton().addPropertyChangeListener(prop_listener);
    try {
        while (!(failed || destroyed)) {
            if (socket != null) {
                try {
                    socket.close();
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
            }
            InetSocketAddress address = null;
            DatagramSocket new_socket = null;
            try {
                if (target_bind_ip == null) {
                    address = new InetSocketAddress("127.0.0.1", port);
                    new_socket = new DatagramSocket(port);
                } else {
                    address = new InetSocketAddress(target_bind_ip, port);
                    new_socket = new DatagramSocket(address);
                }
            } catch (BindException e) {
                // some firewalls (e.g. Comodo) seem to close sockets on us and then not release them quickly so we come through here and get
                // an 'address already in use' failure
                boolean rebind_worked = false;
                int delay = 25;
                for (int i = 0; i < 16 && !(failed || destroyed); i++) {
                    try {
                        Thread.sleep(delay);
                        delay = delay * 2;
                        if (delay > 1000) {
                            delay = 1000;
                        }
                        if (target_bind_ip == null) {
                            address = new InetSocketAddress("127.0.0.1", port);
                            new_socket = new DatagramSocket(port);
                        } else {
                            address = new InetSocketAddress(target_bind_ip, port);
                            new_socket = new DatagramSocket(address);
                        }
                        if (Logger.isEnabled())
                            Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: rebind to " + target_bind_ip + " worked (tries=" + (i + 1) + ") after getting " + Debug.getNestedExceptionMessage(e)));
                        rebind_worked = true;
                        break;
                    } catch (Throwable f) {
                    }
                }
                if (!rebind_worked) {
                    if (Logger.isEnabled())
                        Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: bind failed with " + Debug.getNestedExceptionMessage(e)));
                    if (target_bind_ip.isAnyLocalAddress()) {
                        InetAddress guess = NetworkAdmin.getSingleton().guessRoutableBindAddress();
                        if (guess != null) {
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: retrying with bind IP guess of " + guess));
                            try {
                                InetSocketAddress guess_address = new InetSocketAddress(guess, port);
                                new_socket = new DatagramSocket(guess_address);
                                target_bind_ip = guess;
                                address = guess_address;
                                if (Logger.isEnabled())
                                    Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: Switched to explicit bind ip " + target_bind_ip + " after initial bind failure with wildcard (" + e.getMessage() + ")"));
                            } catch (Throwable f) {
                                throw (e);
                            }
                        } else {
                            throw (e);
                        }
                    } else {
                        throw (e);
                    }
                }
            }
            new_socket.setReuseAddress(true);
            // short timeout on receive so that we can interrupt a receive fairly quickly
            new_socket.setSoTimeout(1000);
            // only make the socket public once fully configured
            socket = new_socket;
            current_bind_ip = target_bind_ip;
            init_sem.release();
            if (Logger.isEnabled())
                Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: receiver established on port " + port + (current_bind_ip == null ? "" : (", bound to " + current_bind_ip))));
            byte[] buffer = null;
            long successful_accepts = 0;
            long failed_accepts = 0;
            while (!(failed || destroyed)) {
                if (current_bind_ip != target_bind_ip) {
                    break;
                }
                try {
                    if (buffer == null) {
                        buffer = new byte[MAX_PACKET_SIZE];
                    }
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address);
                    receiveFromSocket(packet);
                    if (packet.getLength() > MAX_PACKET_SIZE) {
                        if (MAX_PACKET_SIZE < PRUDPPacket.MAX_PACKET_SIZE) {
                            Debug.out("UDP Packet truncated: received length=" + packet.getLength() + ", current max=" + MAX_PACKET_SIZE);
                            MAX_PACKET_SIZE = Math.min(packet.getLength() + 256, PRUDPPacket.MAX_PACKET_SIZE);
                            buffer = null;
                            continue;
                        }
                    }
                    long receive_time = SystemTime.getCurrentTime();
                    successful_accepts++;
                    failed_accepts = 0;
                    for (PRUDPPrimordialHandler prim_hand : primordial_handlers) {
                        if (prim_hand.packetReceived(packet)) {
                            // primordial handlers get their own buffer as we can't guarantee
                            // that they don't need to hang onto the data
                            buffer = null;
                            stats.primordialPacketReceived(packet.getLength());
                            break;
                        }
                    }
                    if (buffer != null) {
                        process(packet, receive_time);
                    }
                } catch (SocketTimeoutException e) {
                } catch (Throwable e) {
                    // on vista we get periodic socket closures
                    String message = e.getMessage();
                    if (socket.isClosed() || (message != null && message.toLowerCase().contains("socket closed"))) {
                        long now = SystemTime.getCurrentTime();
                        if (now - last_socket_close_time < 500) {
                            Thread.sleep(250);
                        }
                        last_socket_close_time = now;
                        if (Logger.isEnabled())
                            Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: recycled UDP port " + port + " after close: ok=" + successful_accepts));
                        break;
                    }
                    failed_accepts++;
                    if (Logger.isEnabled())
                        Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: receive failed on port " + port + ": ok=" + successful_accepts + ", fails=" + failed_accepts, e));
                    if ((failed_accepts > 100 && successful_accepts == 0) || failed_accepts > 1000) {
                        Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Network.alert.acceptfail"), new String[] { "" + port, "UDP" });
                        // break, sometimes get a screaming loop. e.g.
                        /*
							[2:01:55]  DEBUG::Tue Dec 07 02:01:55 EST 2004
							[2:01:55]    java.net.SocketException: Socket operation on nonsocket: timeout in datagram socket peek
							[2:01:55]  	at java.net.PlainDatagramSocketImpl.peekData(Native Method)
							[2:01:55]  	at java.net.DatagramSocket.receive(Unknown Source)
							[2:01:55]  	at com.biglybt.core.tracker.server.impl.udp.TRTrackerServerUDP.recvLoop(TRTrackerServerUDP.java:118)
							[2:01:55]  	at com.biglybt.core.tracker.server.impl.udp.TRTrackerServerUDP$1.runSupport(TRTrackerServerUDP.java:90)
							[2:01:55]  	at com.biglybt.core.util.AEThread.run(AEThread.java:45)
							*/
                        init_error = e;
                        failed = true;
                    }
                }
            }
        }
    } catch (Throwable e) {
        init_error = e;
        if (!(e instanceof BindException && Constants.isWindowsVistaOrHigher)) {
            Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Tracker.alert.listenfail"), new String[] { "UDP:" + port });
        }
        Logger.log(new LogEvent(LOGID, "PRUDPPacketReceiver: " + "DatagramSocket bind failed on port " + port, e));
    } finally {
        init_sem.release();
        destroy_sem.releaseForever();
        if (socket != null) {
            try {
                socket.close();
            } catch (Throwable e) {
                Debug.printStackTrace(e);
            }
        }
        // make sure we destroy the delegate too if something happend
        PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
        if (delegate != null) {
            delegate.destroy();
        }
        NetworkAdmin.getSingleton().removePropertyChangeListener(prop_listener);
    }
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) LogAlert(com.biglybt.core.logging.LogAlert) NetworkAdminPropertyChangeListener(com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener)

Aggregations

NetworkAdminPropertyChangeListener (com.biglybt.core.networkmanager.admin.NetworkAdminPropertyChangeListener)4 NetworkAdmin (com.biglybt.core.networkmanager.admin.NetworkAdmin)3 LogAlert (com.biglybt.core.logging.LogAlert)2 LogEvent (com.biglybt.core.logging.LogEvent)2 URL (java.net.URL)2 ParameterListener (com.biglybt.core.config.ParameterListener)1 DHT (com.biglybt.core.dht.DHT)1 DHTListener (com.biglybt.core.dht.DHTListener)1 DHTSpeedTester (com.biglybt.core.dht.speed.DHTSpeedTester)1 GlobalManagerAdapter (com.biglybt.core.global.GlobalManagerAdapter)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 VuzeFile (com.biglybt.core.vuzefile.VuzeFile)1 VuzeFileComponent (com.biglybt.core.vuzefile.VuzeFileComponent)1 VuzeFileProcessor (com.biglybt.core.vuzefile.VuzeFileProcessor)1 IPRange (com.biglybt.pif.ipfilter.IPRange)1 Torrent (com.biglybt.pif.torrent.Torrent)1 TorrentDownloader (com.biglybt.pif.torrent.TorrentDownloader)1 TrackerException (com.biglybt.pif.tracker.TrackerException)1 UIInstance (com.biglybt.pif.ui.UIInstance)1 UIManagerListener (com.biglybt.pif.ui.UIManagerListener)1