예제 #1
0
    def check(self, force=False, config=False):
        common.log('UpdateChecker', 'check', 'force={}'.format(force))
        # Load the settings
        settings = Settings(config)
        settings.load()

        # If force=True, then definitely check
        if force:
            check_for_updates = True
        else:
            check_for_updates = False

            # See if it's been 1 day since the last check
            autoupdate_timestamp = settings.get('autoupdate_timestamp')
            if autoupdate_timestamp:
                last_checked = datetime.datetime.fromtimestamp(autoupdate_timestamp)
                now = datetime.datetime.now()

                one_day = datetime.timedelta(days=1)
                if now - last_checked > one_day:
                    check_for_updates = True
            else:
                check_for_updates = True

        # Check for updates
        if check_for_updates:
            common.log('UpdateChecker', 'check', 'checking for updates')
            # Download the latest-version file over Tor
            try:
                # User agent string includes OnionShare version and platform
                user_agent = 'OnionShare {}, {}'.format(common.get_version(), platform.system())

                # If the update is forced, add '?force=1' to the URL, to more
                # accurately measure daily users
                path = '/latest-version.txt'
                if force:
                    path += '?force=1'

                onion_domain = 'elx57ue5uyfplgva.onion'

                common.log('UpdateChecker', 'check', 'loading http://{}{}'.format(onion_domain, path))

                (socks_address, socks_port) = self.onion.get_tor_socks_port()
                socks.set_default_proxy(socks.SOCKS5, socks_address, socks_port)

                s = socks.socksocket()
                s.settimeout(15) # 15 second timeout
                s.connect((onion_domain, 80))

                http_request = 'GET {} HTTP/1.0\r\n'.format(path)
                http_request += 'Host: {}\r\n'.format(onion_domain)
                http_request += 'User-Agent: {}\r\n'.format(user_agent)
                http_request += '\r\n'
                s.sendall(http_request.encode('utf-8'))

                http_response = s.recv(1024)
                latest_version = http_response[http_response.find(b'\r\n\r\n'):].strip().decode('utf-8')

                common.log('UpdateChecker', 'check', 'latest OnionShare version: {}'.format(latest_version))

            except Exception as e:
                common.log('UpdateChecker', 'check', '{}'.format(e))
                raise UpdateCheckerCheckError

            # Validate that latest_version looks like a version string
            # This regex is: 1-3 dot-separated numeric components
            version_re = r"^(\d+\.)?(\d+\.)?(\d+)$"
            if not re.match(version_re, latest_version):
                raise UpdateCheckerInvalidLatestVersion(latest_version)

            # Update the last checked timestamp (dropping the seconds and milliseconds)
            timestamp = datetime.datetime.now().replace(microsecond=0).replace(second=0).timestamp()
            settings.set('autoupdate_timestamp', timestamp)
            settings.save()

            # Do we need to update?
            update_url = 'https://github.com/micahflee/onionshare/releases/tag/v{}'.format(latest_version)
            installed_version = common.get_version()
            if installed_version < latest_version:
                self.update_available.emit(update_url, installed_version, latest_version)
                return

            # No updates are available
            self.update_not_available.emit()
예제 #2
0
    def check(self, force=False, config=False):
        self.common.log('UpdateChecker', 'check', 'force={}'.format(force))
        # Load the settings
        settings = Settings(self.common, config)
        settings.load()

        # If force=True, then definitely check
        if force:
            check_for_updates = True
        else:
            check_for_updates = False

            # See if it's been 1 day since the last check
            autoupdate_timestamp = settings.get('autoupdate_timestamp')
            if autoupdate_timestamp:
                last_checked = datetime.datetime.fromtimestamp(
                    autoupdate_timestamp)
                now = datetime.datetime.now()

                one_day = datetime.timedelta(days=1)
                if now - last_checked > one_day:
                    check_for_updates = True
            else:
                check_for_updates = True

        # Check for updates
        if check_for_updates:
            self.common.log('UpdateChecker', 'check', 'checking for updates')
            # Download the latest-version file over Tor
            try:
                # User agent string includes OnionShare version and platform
                user_agent = 'OnionShare {}, {}'.format(
                    self.common.version, self.common.platform)

                # If the update is forced, add '?force=1' to the URL, to more
                # accurately measure daily users
                path = '/latest-version.txt'
                if force:
                    path += '?force=1'

                if Version(self.onion.tor_version) >= Version('0.3.2.9'):
                    onion_domain = 'lldan5gahapx5k7iafb3s4ikijc4ni7gx5iywdflkba5y2ezyg6sjgyd.onion'
                else:
                    onion_domain = 'elx57ue5uyfplgva.onion'

                self.common.log(
                    'UpdateChecker', 'check',
                    'loading http://{}{}'.format(onion_domain, path))

                (socks_address, socks_port) = self.onion.get_tor_socks_port()
                socks.set_default_proxy(socks.SOCKS5, socks_address,
                                        socks_port)

                s = socks.socksocket()
                s.settimeout(15)  # 15 second timeout
                s.connect((onion_domain, 80))

                http_request = 'GET {} HTTP/1.0\r\n'.format(path)
                http_request += 'Host: {}\r\n'.format(onion_domain)
                http_request += 'User-Agent: {}\r\n'.format(user_agent)
                http_request += '\r\n'
                s.sendall(http_request.encode('utf-8'))

                http_response = s.recv(1024)
                latest_version = http_response[
                    http_response.find(b'\r\n\r\n'):].strip().decode('utf-8')

                self.common.log(
                    'UpdateChecker', 'check',
                    'latest OnionShare version: {}'.format(latest_version))

            except Exception as e:
                self.common.log('UpdateChecker', 'check', '{}'.format(e))
                self.update_error.emit()
                raise UpdateCheckerCheckError

            # Validate that latest_version looks like a version string
            # This regex is: 1-3 dot-separated numeric components
            version_re = r"^(\d+\.)?(\d+\.)?(\d+)$"
            if not re.match(version_re, latest_version):
                self.update_invalid_version.emit(latest_version)
                raise UpdateCheckerInvalidLatestVersion(latest_version)

            # Update the last checked timestamp (dropping the seconds and milliseconds)
            timestamp = datetime.datetime.now().replace(microsecond=0).replace(
                second=0).timestamp()
            # Re-load the settings first before saving, just in case they've changed since we started our thread
            settings.load()
            settings.set('autoupdate_timestamp', timestamp)
            settings.save()

            # Do we need to update?
            update_url = 'https://github.com/micahflee/onionshare/releases/tag/v{}'.format(
                latest_version)
            installed_version = self.common.version
            if installed_version < latest_version:
                self.update_available.emit(update_url, installed_version,
                                           latest_version)
                return

            # No updates are available
            self.update_not_available.emit()
예제 #3
0
    def check(self, force=False):
        # Load the settings
        settings = Settings()
        settings.load()

        # If force=True, then definitely check
        if force:
            check_for_updates = True
        else:
            check_for_updates = False

            # See if it's been 1 day since the last check
            autoupdate_timestamp = settings.get('autoupdate_timestamp')
            if autoupdate_timestamp:
                last_checked = datetime.datetime.fromtimestamp(
                    autoupdate_timestamp)
                now = datetime.datetime.now()

                one_day = datetime.timedelta(days=1)
                if now - last_checked > one_day:
                    check_for_updates = True
            else:
                check_for_updates = True

        # Check for updates
        if check_for_updates:
            # Create an Onion object, for checking for updates over tor
            try:
                onion = Onion(settings=settings,
                              bundled_tor_func=self._bundled_tor_func)
            except:
                raise UpdateCheckerTorError

            # Download the latest-version file over Tor
            try:
                # User agent string includes OnionShare version and platform
                user_agent = 'OnionShare {}, {}'.format(
                    helpers.get_version(), platform.system())

                # If the update is forced, add '?force=1' to the URL, to more
                # accurately measure daily users
                path = '/latest-version.txt'
                if force:
                    path += '?force=1'

                (socks_address, socks_port) = onion.get_tor_socks_port()
                socks.set_default_proxy(socks.SOCKS5, socks_address,
                                        socks_port)

                s = socks.socksocket()
                s.settimeout(15)  # 15 second timeout
                s.connect(('elx57ue5uyfplgva.onion', 80))

                http_request = 'GET {} HTTP/1.0\r\n'.format(path)
                http_request += 'Host: elx57ue5uyfplgva.onion\r\n'
                http_request += 'User-Agent: {}\r\n'.format(user_agent)
                http_request += '\r\n'
                s.sendall(http_request.encode('utf-8'))

                http_response = s.recv(1024)
                latest_version = http_response[
                    http_response.find(b'\r\n\r\n'):].strip().decode('utf-8')

                # Clean up from Onion
                onion.cleanup()
            except:
                raise UpdateCheckerSOCKSHTTPError

            # Validate that latest_version looks like a version string
            # This regex is: 1-3 dot-separated numeric components
            version_re = r"^(\d+\.)?(\d+\.)?(\d+)$"
            if not re.match(version_re, latest_version):
                raise UpdateCheckerInvalidLatestVersion(latest_version)

            # Update the last checked timestamp (dropping the seconds and milliseconds)
            timestamp = datetime.datetime.now().replace(microsecond=0).replace(
                second=0).timestamp()
            settings.set('autoupdate_timestamp', timestamp)
            settings.save()

            # Do we need to update?
            update_url = 'https://github.com/micahflee/onionshare/releases/tag/v{}'.format(
                latest_version)
            installed_version = helpers.get_version()
            if installed_version < latest_version:
                self.update_available.emit(update_url, installed_version,
                                           latest_version)
                return

            # No updates are available
            self.update_not_available.emit()