diff --git a/README.md b/README.md index c89af36..baf568f 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ routeros_api.RouterOsApiPool( ssl_verify=True, ssl_verify_hostname=True, ssl_context=None, + proxy_socks_host=None, + proxy_socks_port=None, ) ``` @@ -52,6 +54,8 @@ Optional Parameters: * `ssl_verify` - Boolean - Verify the SSL certificate? - Default **True** * `ssl_verify_hostname` - Boolean - Verify the SSL certificate hostname matches? - Default **True** * `ssl_context` - Object - Pass in a custom SSL context object. Overrides other options. - Default **None** +* `proxy_socks_host` - String - IP address for socks5 proxy - Default **None** +* `proxy_socks_port` - Integer - Port number for socks5 proxy - Default **None** #### Using SSL diff --git a/routeros_api/api.py b/routeros_api/api.py index 956aa9d..dc1650a 100644 --- a/routeros_api/api.py +++ b/routeros_api/api.py @@ -10,18 +10,19 @@ from routeros_api import resource -def connect(host, username='admin', password='', port=None, plaintext_login=False, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None): - return RouterOsApiPool(host, username, password, port, plaintext_login, use_ssl, ssl_verify, ssl_verify_hostname, ssl_context).get_api() +def connect(host, username='admin', password='', port=None, plaintext_login=False, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None, proxy_socks_host=None, proxy_socks_port=None): + return RouterOsApiPool(host, username, password, port, plaintext_login, use_ssl, ssl_verify, ssl_verify_hostname, ssl_context, proxy_socks_host, proxy_socks_port).get_api() class RouterOsApiPool(object): socket_timeout = 15.0 - def __init__(self, host, username='admin', password='', port=None, plaintext_login=False, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None): + def __init__(self, host, username='admin', password='', port=None, plaintext_login=False, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None, proxy_socks_host=None, proxy_socks_port=None): self.host = host self.username = username self.password = password - + self.proxy_socks_host = proxy_socks_host + self.proxy_socks_port = proxy_socks_port self.plaintext_login = plaintext_login self.ssl_context = ssl_context @@ -43,7 +44,7 @@ def __init__(self, host, username='admin', password='', port=None, plaintext_log def get_api(self): if not self.connected: self.socket = api_socket.get_socket(self.host, self.port, - timeout=self.socket_timeout, use_ssl=self.use_ssl, ssl_verify=self.ssl_verify, ssl_verify_hostname=self.ssl_verify_hostname, ssl_context=self.ssl_context) + timeout=self.socket_timeout, use_ssl=self.use_ssl, ssl_verify=self.ssl_verify, ssl_verify_hostname=self.ssl_verify_hostname, ssl_context=self.ssl_context, proxy_socks_host=self.proxy_socks_host, proxy_socks_port=self.proxy_socks_port) base = base_api.Connection(self.socket) communicator = api_communicator.ApiCommunicator(base) self.api = RouterOsApi(communicator) diff --git a/routeros_api/api_socket.py b/routeros_api/api_socket.py index 12f051d..59597f0 100644 --- a/routeros_api/api_socket.py +++ b/routeros_api/api_socket.py @@ -1,4 +1,5 @@ import socket +import socks import ssl from routeros_api import exceptions try: @@ -8,8 +9,14 @@ EINTR = getattr(errno, 'EINTR', 4) -def get_socket(hostname, port, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None, timeout=15.0): - api_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +def get_socket(hostname, port, use_ssl=False, ssl_verify=True, ssl_verify_hostname=True, ssl_context=None, timeout=15.0, proxy_socks_host=None, proxy_socks_port=None): + + if proxy_socks_host and proxy_socks_port is not None: + socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxy_socks_host, proxy_socks_port) + socket.socket = socks.socksocket + api_socket = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM) + else: + api_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) api_socket.settimeout(timeout) while True: try: @@ -50,7 +57,6 @@ def set_keepalive(sock, after_idle_sec=1, interval_sec=3, max_fails=5): if hasattr(socket, "TCP_KEEPCNT"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails) - class DummySocket(object): def close(self): pass