def test_invalid_conf(self): create_cwd(cwd()) Config._cache = {} with open(cwd("conf", "socks5man.conf"), "w") as fw: fw.write("socks5man to dominate them all") with pytest.raises(Socks5ConfigError): cfg("socks5man", "verify_interval")
def test_invalid_conf(self): create_cwd(cwd()) Config._cache = {} with open(cwd("conf", "socks5man.conf"), "wb") as fw: fw.write(os.urandom(512)) with pytest.raises(Socks5ConfigError): cfg("socks5man", "verify_interval")
def connect(self, create=False): self.engine = create_engine("sqlite:///%s" % cwd("socks5man.db")) self.Session = sessionmaker(bind=self.engine) if create: if not os.path.exists(cwd("socks5man.db")): self._create() elif not self.engine.dialect.has_table( self.engine, AlembicVersion.__tablename__): AlembicVersion.__table__.create(self.engine)
def test_measure_conn_time(self, ms): create_cwd(cwd()) socksocket = mock.MagicMock() ms.socksocket.return_value = socksocket self.db.add_socks5("example.com", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5") db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) res = s.measure_connection_time() assert isinstance(res, float) socksocket.set_proxy.assert_called_once_with(ms.SOCKS5, "example.com", 1337, username="******", password="******") socksocket.settimeout.assert_called_once_with(3) socksocket.connect.assert_called_once_with(("api.ipify.org", 80)) assert self.db.view_socks5(1).connect_time == res
def test_read_from_cache(self): create_cwd(cwd()) Config._cache = {} assert cfg("operationality", "ip_api") == "http://api.ipify.org" assert "operationality" in Config._cache Config._cache["operationality"]["ip_api"] = "http://example.com" assert cfg("operationality", "ip_api") == "http://example.com"
def ipv4info(ip): """Returns a dict containing the country, country_code, and city for a given IPv4 address""" result = { "country": "unknown", "country_code": "unknown", "city": "unknown" } if not GeoInfo.georeader: georeader = geodatabase.Reader( cwd("geodb", "extracted", "geodblite.mmdb")) if is_reserved_ipv4(ip): return result try: geodata = georeader.city(ip) if geodata.country.name: result["country"] = geodata.country.name if geodata.country.iso_code: result["country_code"] = geodata.country.iso_code if geodata.city.name: result["city"] = geodata.city.name except (GeoIP2Error, ValueError): return result return result
def test_add_invalid_auth_usage(self): create_cwd(path=cwd()) m = Manager() with pytest.raises(Socks5CreationError): m.add("example.com", 1337, username="******") with pytest.raises(Socks5CreationError): m.add("example.com", 1337, password="******")
def test_ip_api(self): """Verify that the default ip api returns an actual ip""" create_cwd(cwd()) res = urllib2.urlopen(cfg("operationality", "ip_api"), timeout=cfg("operationality", "timeout")) assert res.getcode() == 200 assert re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", res.read())
def test_bulk_add_invalid_auth_usage(self): create_cwd(path=cwd()) m = Manager() servers1 = [ { "host": "8.8.8.8", "port": 4242, "password": "******" }, { "host": "example.com", "port": 9133 } ] servers2 = [ { "host": "8.8.8.8", "port": 4242 }, { "host": "example.com", "username": "******", "port": 9133 } ] t1 = m.bulk_add(servers1) t2 = m.bulk_add(servers2) assert t1 == 1 assert t2 == 1
def test_add_invalid_auth_usage(self): create_cwd(path=cwd()) m = Manager() with pytest.raises(Socks5CreationError): m.add("example.com", 1337, username="******") with pytest.raises(Socks5CreationError): m.add("example.com", 1337, password="******")
def test_bulk_add_invalid_auth_usage(self): create_cwd(path=cwd()) m = Manager() servers1 = [ { "host": "8.8.8.8", "port": 4242, "password": "******" }, { "host": "example.com", "port": 9133 } ] servers2 = [ { "host": "8.8.8.8", "port": 4242 }, { "host": "example.com", "username": "******", "port": 9133 } ] t1 = m.bulk_add(servers1) t2 = m.bulk_add(servers2) assert t1 == 1 assert t2 == 1
def test_download_url(self): """Verify that the url used to measure an approximate bandwidth is still available""" create_cwd(cwd()) res = urllib2.urlopen(cfg("bandwidth", "download_url"), timeout=cfg("bandwidth", "timeout")) assert res.getcode() == 200 assert len(res.read()) > 0
def test_cwd_internal(self): tmpdir = self.tmpfile.mkdtemp() set_cwd(tmpdir) p = cwd("conf", "socks5man.conf", internal=True) p2 = os.path.join( socks5man.__path__[0], "setupdata", "conf", "socks5man.conf" ) assert p == p2
def test_ip_api(self): """Verify that the default ip api returns an actual ip""" create_cwd(cwd()) res = urllib2.urlopen( cfg("operationality", "ip_api"), timeout=cfg("operationality", "timeout") ) assert res.getcode() == 200 assert re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", res.read())
def test_measure_time_host(self): """Verify that the default connection measurement still accepts connections""" create_cwd(cwd()) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(cfg("connection_time", "timeout")) s.connect((cfg("connection_time", "hostname"), cfg("connection_time", "port"))) s.close()
def test_measure_time_host(self): """Verify that the default connection measurement still accepts connections""" create_cwd(cwd()) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(cfg("connection_time", "timeout")) s.connect(( cfg("connection_time", "hostname"), cfg("connection_time", "port") )) s.close()
def test_add_dnsport(self): create_cwd(path=cwd()) m = Manager() res = m.add("example.com", 1337, dnsport=5050) assert res.id == 1 all_socks = self.db.list_socks5() assert len(all_socks) == 1 assert all_socks[0].dnsport == 5050 assert all_socks[0].host == "example.com" assert all_socks[0].port == 1337
def test_download_url(self): """Verify that the url used to measure an approximate bandwidth is still available""" create_cwd(cwd()) res = urllib2.urlopen( cfg("bandwidth", "download_url"), timeout=cfg("bandwidth", "timeout") ) assert res.getcode() == 200 assert len(res.read()) > 0
def test_add_hostname(self): create_cwd(path=cwd()) m = Manager() res = m.add("example.com", 1337) assert res.id == 1 assert res.country == "United States" assert res.country_code == "US" assert res.city == "Norwell" assert res.host == "example.com" assert res.port == 1337
def test_add_auth(self): create_cwd(path=cwd()) m = Manager() res = m.add("example.com", 1337, username="******", password="******") assert res.id == 1 all_socks = self.db.list_socks5() assert len(all_socks) == 1 assert all_socks[0].host == "example.com" assert all_socks[0].port == 1337 assert all_socks[0].username == "Hello" assert all_socks[0].password == "Bye"
def test_success(self, ms): create_cwd(cwd()) socks5 = mock.MagicMock() socks5.host = "8.8.8.8" socks5.port = 4242 ms.return_value = socks5 self.db.add_socks5("8.8.8.8", 4242, "Germany", "DE") verify_all() socks5.verify.assert_called_once() socks5.measure_connection_time.assert_called_once() socks5.approx_bandwidth.assert_not_called()
def test_bulk_add_missinginfo(self): create_cwd(path=cwd()) servers = [ { "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 1
def test_verify_fail(self, mg): create_cwd(cwd()) mg.return_value = None self.db.add_socks5( "8.8.8.8", 1337, "germany", "DE", city="Frankfurt", operational=True, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) assert not s.verify() db_socks5_2 = self.db.view_socks5(1) assert not db_socks5_2.operational
def test_verify_private(self, mg): create_cwd(cwd()) mg.return_value = "8.8.8.8" self.db.add_socks5( "192.168.0.50", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) assert s.verify() db_socks5_2 = self.db.view_socks5(1) assert db_socks5_2.operational
def test_bulk_add_missinginfo(self): create_cwd(path=cwd()) servers = [ { "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 1
def test_add_description(self): create_cwd(path=cwd()) m = Manager() res = m.add("8.8.8.8", 1337, description="Many wow") assert res.id == 1 assert res.host == "8.8.8.8" assert res.port == 1337 all_socks = self.db.list_socks5() assert len(all_socks) == 1 assert all_socks[0].id == 1 assert all_socks[0].host == "8.8.8.8" assert all_socks[0].port == 1337 assert all_socks[0].description == "Many wow"
def test_verify_hostname(self, mg): create_cwd(cwd()) mg.return_value = "93.184.216.34" self.db.add_socks5( "example.com", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) assert s.verify() db_socks5_2 = self.db.view_socks5(1) assert db_socks5_2.operational
def test_bulk_add_faultyinfo(self): create_cwd(path=cwd()) servers = [ { "host": "98asdj9a8sdj9adsuiuiuiasd.cheese", "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 1
def read(self): if Config._cache: Config._cache = {} config = ConfigParser.ConfigParser() confpath = cwd("conf", "socks5man.conf") if not os.path.isfile(confpath): raise Socks5ConfigError( "Cannot read config. Config file '%s' does not exist" % confpath ) try: config.read(confpath) except ConfigParser.Error as e: raise Socks5ConfigError( "Cannot parse config file. Error: %s" % e ) for section in config.sections(): if section not in self._conf: raise Socks5ConfigError( "Config has unknown config section '%s'. Add section to" " the config class to prevent this error." % section ) if section not in Config._cache: Config._cache[section] = {} for k in config.options(section): option_type = self._conf[section].get(k) if not option_type: raise Socks5ConfigError( "Unknown option '%s' in config section '%s'. Add the" " option and its type to the config class to prevent" " this error." % (k, section) ) value = config.get(section, k) try: value = option_type(value) except ValueError as e: raise Socks5ConfigError( "Cannot cast value '%s' of option '%s' in section" " '%s' to type '%s'. %s" % ( value, k, section, option_type, e ) ) Config._cache[section][k] = value
def test_measure_conn_time_fail(self, ms): create_cwd(cwd()) socksocket = mock.MagicMock() ms.socksocket.return_value = socksocket socksocket.connect.side_effect = socket.error self.db.add_socks5( "example.com", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) s.measure_connection_time() is None self.db.view_socks5(1).connect_time is None
def test_add(self): create_cwd(path=cwd()) m = Manager() res = m.add("8.8.8.8", 1337, description="Many wow") assert res.id == 1 assert res.host == "8.8.8.8" assert res.port == 1337 assert res.country == "United States" assert res.country_code == "US" assert res.username is None assert res.password is None all_socks = self.db.list_socks5() assert len(all_socks) == 1 all_socks[0].description == "Many wow"
def test_approx_bandwidth_fail(self, ma): create_cwd(cwd()) ma.return_value = None self.db.add_socks5( "example.com", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) res = s.approx_bandwidth() assert res == None db_socks5_2 = self.db.view_socks5(1) assert db_socks5_2.bandwidth is None
def read(self): if Config._cache: Config._cache = {} config = configparser.ConfigParser() confpath = cwd("conf", "socks5man.conf") if not os.path.isfile(confpath): raise Socks5ConfigError( "Cannot read config. Config file '%s' does not exist" % confpath ) try: config.read(confpath) except configparser.Error as e: raise Socks5ConfigError( "Cannot parse config file. Error: %s" % e ) for section in config.sections(): if section not in self._conf: raise Socks5ConfigError( "Config has unknown config section '%s'. Add section to" " the config class to prevent this error." % section ) if section not in Config._cache: Config._cache[section] = {} for k in config.options(section): option_type = self._conf[section].get(k) if not option_type: raise Socks5ConfigError( "Unknown option '%s' in config section '%s'. Add the" " option and its type to the config class to prevent" " this error." % (k, section) ) value = config.get(section, k) try: value = option_type(value) except ValueError as e: raise Socks5ConfigError( "Cannot cast value '%s' of option '%s' in section" " '%s' to type '%s'. %s" % ( value, k, section, option_type, e ) ) Config._cache[section][k] = value
def test_bandwidth(self, ms): create_cwd(cwd()) socks5 = mock.MagicMock() socks5.host = "8.8.8.8" socks5.port = 4242 ms.return_value = socks5 self.db.add_socks5("8.8.8.8", 4242, "Germany", "DE") Config._cache["bandwidth"]["enabled"] = True verify_all() socks5.verify.assert_called_once() socks5.measure_connection_time.assert_called_once() socks5.approx_bandwidth.assert_called_once() Config._cache["bandwidth"]["enabled"] = False
def test_bulk_add_faultyinfo(self): create_cwd(path=cwd()) servers = [ { "host": "98asdj9a8sdj9adsuiuiuiasd.cheese", "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 1
def migrate(revision): if not db.db_migratable(): log.info("Database schema is already at the latest version") exit(0) try: subprocess.check_call( ["alembic", "upgrade", revision], cwd=cwd("db_migration", internal=True) ) except subprocess.CalledProcessError as e: log.exception("Database migration failed. %s", e) exit(1) log.info("Database migration successful!")
def test_bulk_add_strport(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": "4242" }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 2 assert self.db.view_socks5(host="8.8.8.8", port=4242).port == 4242
def test_unpack_mmdb(self): tmpdir = self.tempfile.mkdtemp() set_cwd(tmpdir) tar_p = cwd("geodb", "geodblite.tar.gz", internal=True) assert os.listdir(tmpdir) == [] os.mkdir(os.path.join(tmpdir, "geodb")) mmdb_p = os.path.join(tmpdir, "test.mmdb") unpack_mmdb(tarpath=tar_p, to=mmdb_p) assert os.path.isfile(mmdb_p) version_file = os.path.join(tmpdir, "geodb", ".version") assert os.path.isfile(version_file) assert md5(tar_p) == open(version_file, "rb").read() r = geodatabase.Reader(mmdb_p) geodata = r.city("8.8.8.8") assert geodata.country.name.lower() == "united states"
def test_bulk_add_nonew(self): create_cwd(path=cwd()) servers = [ { "host": "Shouldnotexistsstuff789as7h8asdj8asd.tosti", "port": 4242 }, { "host": "example.com", "port": None } ] m = Manager() with pytest.raises(Socks5CreationError): m.bulk_add(servers)
def migrate(revision): if not db.db_migratable(): log.info("Database schema is already at the latest version") exit(0) try: subprocess.check_call( ["alembic", "upgrade", revision], cwd=cwd("db_migration", internal=True) ) except subprocess.CalledProcessError as e: log.exception("Database migration failed. %s", e) exit(1) log.info("Database migration successful!")
def test_bulk_add_nonew(self): create_cwd(path=cwd()) servers = [ { "host": "Shouldnotexistsstuff789as7h8asdj8asd.tosti", "port": 4242 }, { "host": "example.com", "port": None } ] m = Manager() with pytest.raises(Socks5CreationError): m.bulk_add(servers)
def init_loggers(level=logging.INFO): logger = logging.getLogger() logger.setLevel(level) fmt = logging.Formatter( "%(asctime)s [%(name)s] %(levelname)s: %(message)s") # create a file handler fhandler = logging.FileHandler(cwd("socks5man.log")) fhandler.setFormatter(fmt) logger.addHandler(fhandler) shandler = ConsoleHandler(sys.stdout) shandler.setFormatter(fmt) logger.addHandler(shandler)
def test_bulk_add_strport(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": "4242" }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 2 assert self.db.view_socks5(host="8.8.8.8", port=4242).port == 4242
def test_download_verify_fail(self, ms, mu): create_cwd(cwd()) socks5 = mock.MagicMock() socks5.host = "8.8.8.8" socks5.port = 4242 ms.return_value = socks5 mu.side_effect = socket.error self.db.add_socks5("8.8.8.8", 4242, "Germany", "DE") Config._cache["bandwidth"]["enabled"] = True verify_all() socks5.verify.assert_called_once() socks5.measure_connection_time.assert_called_once() mu.assert_called_once_with(mock.ANY, timeout=5) socks5.approx_bandwidth.assert_not_called() Config._cache["bandwidth"]["enabled"] = False
def init_loggers(level=logging.INFO): logger = logging.getLogger() logger.setLevel(level) fmt = logging.Formatter( "%(asctime)s [%(name)s] %(levelname)s: %(message)s" ) # create a file handler fhandler = logging.FileHandler(cwd("socks5man.log")) fhandler.setFormatter(fmt) logger.addHandler(fhandler) shandler = ConsoleHandler(sys.stdout) shandler.setFormatter(fmt) logger.addHandler(shandler)
def test_add_hostname(self): create_cwd(path=cwd()) m = Manager() res = m.add("example.com", 1337) assert res.id == 1 assert res.country == "United States" assert res.country_code == "US" assert res.city == "Norwell" assert res.host == "example.com" assert res.port == 1337 all_socks = self.db.list_socks5() assert len(all_socks) == 1 assert all_socks[0].host == "example.com" assert all_socks[0].port == 1337 assert all_socks[0].country == "United States" assert all_socks[0].country_code == "US"
def test_cfg_defaults(self): create_cwd(cwd()) assert isinstance(cfg("socks5man", "verify_interval"), int) assert isinstance(cfg("socks5man", "bandwidth_interval"), int) assert isinstance(cfg("operationality", "ip_api"), (str, basestring)) assert isinstance(cfg("operationality", "timeout"), int) assert isinstance(cfg("connection_time", "enabled"), bool) assert isinstance(cfg("connection_time", "timeout"), int) assert isinstance(cfg("connection_time", "hostname"),(str, basestring)) assert isinstance(cfg("connection_time", "port"), int) assert isinstance(cfg("bandwidth", "enabled"), bool) assert isinstance(cfg("bandwidth", "download_url"), (str, basestring)) assert isinstance(cfg("bandwidth", "times"), int) assert isinstance(cfg("bandwidth", "timeout"), int) assert isinstance(cfg("geodb", "geodb_url"), (str, basestring)) assert isinstance(cfg("geodb", "geodb_md5_url"), (str, basestring))
def test_bulk_add_description(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers, description="Very wow") == 2 s = self.db.view_socks5(host="8.8.8.8", port=4242) assert s.port == 4242 assert s.description == "Very wow"
def test_verify(self, mg): create_cwd(cwd()) mg.return_value = "8.8.8.8" self.db.add_socks5( "8.8.8.8", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) assert s.verify() mg.assert_called_once_with( "http://api.ipify.org", "8.8.8.8", 1337, username="******", password="******", timeout=3 ) db_socks5_2 = self.db.view_socks5(1) assert db_socks5_2.operational
def test_bulk_add_description(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers, description="Very wow") == 2 s = self.db.view_socks5(host="8.8.8.8", port=4242) assert s.port == 4242 assert s.description == "Very wow"
def test_bulk_dnsport(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": 4242, "dnsport": 5050 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 2 allsocks = self.db.list_socks5() assert allsocks[0].dnsport == 5050
def test_approx_bandwidth(self, ma): create_cwd(cwd()) ma.return_value = 15.10 self.db.add_socks5( "example.com", 1337, "germany", "DE", city="Frankfurt", operational=False, username="******", password="******", description="Such wow, many socks5" ) db_socks5 = self.db.view_socks5(1) s = Socks5(db_socks5) res = s.approx_bandwidth() assert res == 15.10 ma.assert_called_once_with( "example.com", 1337, username="******", password="******", times=2, timeout=10 ) db_socks5_2 = self.db.view_socks5(1) assert db_socks5_2.bandwidth == 15.10
def test_bulk_add(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": 4242 }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 2 allsocks = self.db.list_socks5() assert len(allsocks) == 2 assert allsocks[0].country == "United States" assert allsocks[1].country == "United States"
def main(ctx, debug): """This tool can be used to manage your socks5 servers. Each subcommand has its own help information.""" level = logging.INFO if debug: level = logging.DEBUG init_loggers(level) if db.db_migratable(): log.error( "Database schema version mismatch. Expected: %s. Optionally make " "a backup of '%s' and then apply automatic database migration " "by using: 'socks5man migrate'", SCHEMA_VERSION, cwd("socks5man.db") ) if ctx.invoked_subcommand != "migrate": exit(1)
def test_bulk_add_auth(self): create_cwd(path=cwd()) servers = [ { "host": "8.8.8.8", "port": 4242, "username": "******", "password": "******" }, { "host": "example.com", "port": 9133 } ] m = Manager() assert m.bulk_add(servers) == 2 allsocks = self.db.list_socks5() assert allsocks[0].username == "hello" assert allsocks[0].password == "bye"