def verify(self): """ Test if this socks5 can be connected to and retrieve its own IP through the configured IP api. Automatically updates the 'operational' value in the database :returns: True if server is operational, false otherwise :rtype: bool """ operational = False ip = self.host if not is_ipv4(ip): ip = get_ipv4_hostname(ip) response = get_over_socks5( cfg("operationality", "ip_api"), self.host, self.port, username=self.username, password=self.password, timeout=cfg("operationality", "timeout") ) if response: if ip == response: operational = True # If a private ip is used, the api response will not match with # the configured host or its ip. There was however a response, # therefore we still mark it as operational elif is_reserved_ipv4(ip) and is_ipv4(response): operational = True db.set_operational(self.id, operational) return operational
def test_validify_host_port(): res = validify_host_port("8.8.8.8", 4000) assert res.ip == "8.8.8.8" assert res.port == 4000 res2 = validify_host_port("example.com", "7823") assert is_ipv4(res2.ip) assert res2.port == 7823 # Invalid hostname res3 = validify_host_port("someinvalidhostanme.tosti", 4000) assert res3 is None res4 = validify_host_port("example.com", 65537) assert res4 is None res5 = validify_host_port("example.com", -10) assert res5 is None res6 = validify_host_port("example.com", "65536") assert res6 is None res7 = validify_host_port("example.com", "-1") assert res7 is None res8 = validify_host_port("example.com", "0") assert res8 is None res9 = validify_host_port("example.com", "doges") assert res9 is None res10 = validify_host_port("example.com", None) assert res10 is None res11 = validify_host_port(None, 8132) assert res11 is None
def test_is_ipv4(): ipv4 = [ "8.8.8.8", "45.19.77.17", "8.8.4.4", "123.38.177.1", "192.167.1.1", "11.0.0.1", "1.0.0.0", "127.0.0.1", "192.168.0.29", "172.16.18.10", "169.254.13.3", "10.0.10.11", "0.0.0.9", "255.255.255.0", "192.88.99.17" ] for ip in ipv4: assert is_ipv4(ip) hostnames = ["example.com", "hostname.example.com"] for h in hostnames: assert not is_ipv4(h) ipv6 = ["2001:db8:85a3:8d3:1319:8a2e:370", "0:0:0:0:0:0:0:1"] for ipv6 in ipv6: assert not is_ipv4(ipv6)
def update_geodb(): version_file = cwd("geodb", ".version") if not os.path.isfile(version_file): log.error("No geodb version file '%s' is missing", version_file) return with open(version_file, "rb") as fp: current_version = fp.read() try: latest_version = urllib2.urlopen(cfg("geodb", "geodb_md5_url")).read() except urllib2.URLError as e: log.error("Error retrieving latest geodb version hash: %s", e) return if current_version == latest_version: log.info("GeoIP database at latest version") return extracted = cwd("geodb", "extracted") renamed = None if os.path.exists(extracted): renamed = cwd("geodb", "old-extracted") os.rename(extracted, renamed) try: url = cfg("geodb", "geodb_url") log.info("Downloading latest version: '%s'", url) mmdbtar = urllib2.urlopen(url).read() except urllib2.URLError as e: log.error( "Failed to download new mmdb tar. Is the URL correct? %s", e ) if renamed: log.error("Restoring old version..") os.rename(renamed, extracted) return tarpath = cwd("geodb", "geodblite.tar.gz") with open(tarpath, "wb") as fw: fw.write(mmdbtar) os.mkdir(extracted) unpack_mmdb(tarpath, cwd("geodb", "extracted", "geodblite.mmdb")) log.info("Version update complete") if renamed: log.debug("Removing old version") shutil.rmtree(renamed) log.info("Updating geo IP information for all existing servers") GeoInfo.georeader = None for socks5 in db.list_socks5(): log.debug( "Updating server: '%s'. Current country: %s", socks5.host, socks5.country ) ip = socks5.host if not is_ipv4(ip): ip = get_ipv4_hostname(ip) geoinfo = GeoInfo.ipv4info(ip) old = (socks5.country, socks5.country_code, socks5.city) new = (geoinfo["country"], geoinfo["country_code"], geoinfo["city"]) if old == new: log.debug("Geo IP info unchanged") continue log.debug( "Geo IP info changed. New country=%s, country_code=%s, city=%s", geoinfo["country"], geoinfo["country_code"], geoinfo["city"] ) db.update_geoinfo( socks5.id, country=geoinfo["country"], country_code=geoinfo["country_code"], city=geoinfo["city"] )