Pyelliptic code clean 1

This commit is contained in:
Omkar Pakki 2019-07-10 00:02:15 +05:30
parent d0c115ed57
commit 43e1c0149b
5 changed files with 223 additions and 195 deletions

View File

@ -74,7 +74,7 @@ def base10_add(a, b):
m = ((b[1] - a[1]) * inv(b[0] - a[0], P)) % P
x = (m * m - a[0] - b[0]) % P
y = (m * (a[0] - x) - a[1]) % P
return (x, y)
return x, y
def base10_double(a):
@ -83,7 +83,7 @@ def base10_double(a):
m = ((3 * a[0] * a[0] + A) * inv(2 * a[1], P)) % P
x = (m * m - 2 * a[0]) % P
y = (m * (a[0] - x) - a[1]) % P
return (x, y)
return x, y
def base10_multiply(a, n):
@ -99,7 +99,7 @@ def base10_multiply(a, n):
def hex_to_point(h):
return (decode(h[2:66], 16), decode(h[66:], 16))
return decode(h[2:66], 16), decode(h[66:], 16)
def point_to_hex(p):

View File

@ -21,17 +21,17 @@ class Cipher:
ctx2 = pyelliptic.Cipher("secretkey", iv, 0, ciphername='aes-256-cfb')
print ctx2.ciphering(ciphertext)
"""
def __init__(self, key, iv, do, ciphername='aes-256-cbc'):
def __init__(self, key, iv, do, cipher_name='aes-256-cbc'):
"""
do == 1 => Encrypt; do == 0 => Decrypt
"""
self.cipher = OpenSSL.get_cipher(ciphername)
self.cipher = OpenSSL.get_cipher(cipher_name)
self.ctx = OpenSSL.EVP_CIPHER_CTX_new()
if do == 1 or do == 0:
k = OpenSSL.malloc(key, len(key))
IV = OpenSSL.malloc(iv, len(iv))
iv1 = OpenSSL.malloc(iv, len(iv))
OpenSSL.EVP_CipherInit_ex(
self.ctx, self.cipher.get_pointer(), 0, k, IV, do)
self.ctx, self.cipher.get_pointer(), 0, k, iv1, do)
else:
raise Exception("RTFM ...")
@ -43,21 +43,21 @@ class Cipher:
return OpenSSL.cipher_algo.keys()
@staticmethod
def get_blocksize(ciphername):
cipher = OpenSSL.get_cipher(ciphername)
def get_blocksize(cipher_name):
cipher = OpenSSL.get_cipher(cipher_name)
return cipher.get_blocksize()
@staticmethod
def gen_IV(ciphername):
cipher = OpenSSL.get_cipher(ciphername)
def gen_IV(cipher_name):
cipher = OpenSSL.get_cipher(cipher_name)
return OpenSSL.rand(cipher.get_blocksize())
def update(self, input):
def update(self, in_put):
i = OpenSSL.c_int(0)
buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize())
inp = OpenSSL.malloc(input, len(input))
buffer = OpenSSL.malloc(b"", len(in_put) + self.cipher.get_blocksize())
inp = OpenSSL.malloc(in_put, len(in_put))
if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer),
OpenSSL.byref(i), inp, len(input)) == 0:
OpenSSL.byref(i), inp, len(in_put)) == 0:
raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...")
return buffer.raw[0:i.value]
@ -69,11 +69,11 @@ class Cipher:
raise Exception("[OpenSSL] EVP_CipherFinal_ex FAIL ...")
return buffer.raw[0:i.value]
def ciphering(self, input):
def ciphering(self, in_put):
"""
Do update and final in one method
"""
buff = self.update(input)
buff = self.update(in_put)
return buff + self.final()
def __del__(self):

View File

@ -175,9 +175,9 @@ class ECC(object):
group, pub_key, pub_key_x, pub_key_y, 0) == 0:
raise Exception("[OpenSSL] EC_POINT_get_affine_coordinates_GFp FAIL ...")
privkey = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(priv_key))
pubkeyx = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(pub_key_x))
pubkeyy = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(pub_key_y))
privkey = OpenSSL.malloc(0, OpenSSL.bn_num_bytes(priv_key))
pubkeyx = OpenSSL.malloc(0, OpenSSL.bn_num_bytes(pub_key_x))
pubkeyy = OpenSSL.malloc(0, OpenSSL.bn_num_bytes(pub_key_y))
OpenSSL.BN_bn2bin(priv_key, privkey)
privkey = privkey.raw
OpenSSL.BN_bn2bin(pub_key_x, pubkeyx)

View File

@ -19,7 +19,9 @@ class CipherName:
self._blocksize = blocksize
def __str__(self):
return "Cipher : " + self._name + " | Blocksize : " + str(self._blocksize) + " | Fonction pointer : " + str(self._pointer)
return "Cipher : {} | Blocksize : {} | Fonction pointer : {}".format(
self._name, str(self._blocksize), str(self._pointer)
)
def get_pointer(self):
return self._pointer()
@ -33,33 +35,33 @@ class CipherName:
def get_version(library):
version = None
hexversion = None
hex_version = None
cflags = None
try:
#OpenSSL 1.1
OPENSSL_VERSION = 0
OPENSSL_CFLAGS = 1
# OpenSSL 1.1
openssl_version = 0
openssl_cflags = 1
library.OpenSSL_version.argtypes = [ctypes.c_int]
library.OpenSSL_version.restype = ctypes.c_char_p
version = library.OpenSSL_version(OPENSSL_VERSION)
cflags = library.OpenSSL_version(OPENSSL_CFLAGS)
version = library.OpenSSL_version(openssl_version)
cflags = library.OpenSSL_version(openssl_cflags)
library.OpenSSL_version_num.restype = ctypes.c_long
hexversion = library.OpenSSL_version_num()
hex_version = library.OpenSSL_version_num()
except AttributeError:
try:
#OpenSSL 1.0
SSLEAY_VERSION = 0
SSLEAY_CFLAGS = 2
# OpenSSL 1.0
ssleay_version = 0
ssleay_cflags = 2
library.SSLeay.restype = ctypes.c_long
library.SSLeay_version.restype = ctypes.c_char_p
library.SSLeay_version.argtypes = [ctypes.c_int]
version = library.SSLeay_version(SSLEAY_VERSION)
cflags = library.SSLeay_version(SSLEAY_CFLAGS)
hexversion = library.SSLeay()
version = library.SSLeay_version(ssleay_version)
cflags = library.SSLeay_version(ssleay_cflags)
hex_version = library.SSLeay()
except AttributeError:
#raise NotImplementedError('Cannot determine version of this OpenSSL library.')
# raise NotImplementedError('Cannot determine version of this OpenSSL library.')
pass
return (version, hexversion, cflags)
return version, hex_version, cflags
class _OpenSSL:
@ -130,7 +132,8 @@ class _OpenSSL:
self.EC_POINT_get_affine_coordinates_GFp = self._lib.EC_POINT_get_affine_coordinates_GFp
self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int
self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_POINT_get_affine_coordinates_GFp.argtypes = [
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
self.EC_KEY_set_private_key.restype = ctypes.c_int
@ -148,7 +151,8 @@ class _OpenSSL:
self.EC_POINT_set_affine_coordinates_GFp = self._lib.EC_POINT_set_affine_coordinates_GFp
self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int
self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_POINT_set_affine_coordinates_GFp.argtypes = [
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_POINT_new = self._lib.EC_POINT_new
self.EC_POINT_new.restype = ctypes.c_void_p
@ -164,7 +168,8 @@ class _OpenSSL:
self.EC_POINT_mul = self._lib.EC_POINT_mul
self.EC_POINT_mul.restype = None
self.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_POINT_mul.argtypes = [
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
self.EC_KEY_set_private_key.restype = ctypes.c_int
@ -223,13 +228,13 @@ class _OpenSSL:
self.EVP_aes_256_cbc.restype = ctypes.c_void_p
self.EVP_aes_256_cbc.argtypes = []
#self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr
#self.EVP_aes_128_ctr.restype = ctypes.c_void_p
#self.EVP_aes_128_ctr.argtypes = []
# self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr
# self.EVP_aes_128_ctr.restype = ctypes.c_void_p
# self.EVP_aes_128_ctr.argtypes = []
#self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr
#self.EVP_aes_256_ctr.restype = ctypes.c_void_p
#self.EVP_aes_256_ctr.argtypes = []
# self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr
# self.EVP_aes_256_ctr.restype = ctypes.c_void_p
# self.EVP_aes_256_ctr.argtypes = []
self.EVP_aes_128_ofb = self._lib.EVP_aes_128_ofb
self.EVP_aes_128_ofb.restype = ctypes.c_void_p
@ -266,8 +271,8 @@ class _OpenSSL:
self.EVP_CipherUpdate = self._lib.EVP_CipherUpdate
self.EVP_CipherUpdate.restype = ctypes.c_int
self.EVP_CipherUpdate.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
self.EVP_CipherUpdate.argtypes = [
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
self.EVP_CipherFinal_ex = self._lib.EVP_CipherFinal_ex
self.EVP_CipherFinal_ex.restype = ctypes.c_int
@ -388,8 +393,8 @@ class _OpenSSL:
'aes-256-cfb': CipherName('aes-256-cfb', self.EVP_aes_256_cfb128, 16),
'aes-128-ofb': CipherName('aes-128-ofb', self._lib.EVP_aes_128_ofb, 16),
'aes-256-ofb': CipherName('aes-256-ofb', self._lib.EVP_aes_256_ofb, 16),
#'aes-128-ctr': CipherName('aes-128-ctr', self._lib.EVP_aes_128_ctr, 16),
#'aes-256-ctr': CipherName('aes-256-ctr', self._lib.EVP_aes_256_ctr, 16),
# 'aes-128-ctr': CipherName('aes-128-ctr', self._lib.EVP_aes_128_ctr, 16),
# 'aes-256-ctr': CipherName('aes-256-ctr', self._lib.EVP_aes_256_ctr, 16),
'bf-cfb': CipherName('bf-cfb', self.EVP_bf_cfb64, 8),
'bf-cbc': CipherName('bf-cbc', self.EVP_bf_cbc, 8),
'rc4': CipherName('rc4', self.EVP_rc4, 128), # 128 is the initialisation size not block size
@ -430,7 +435,7 @@ class _OpenSSL:
'sect571r1': 734,
}
def BN_num_bytes(self, x):
def bn_num_bytes(self, x):
"""
returns the length of a BN (OpenSSl API)
"""
@ -452,13 +457,13 @@ class _OpenSSL:
raise Exception("Unknown curve")
return self.curves[name]
def get_curve_by_id(self, id):
def get_curve_by_id(self, curve_id):
"""
returns the name of a elliptic curve with his id
"""
res = None
for i in self.curves:
if self.curves[i] == id:
if self.curves[i] == curve_id:
res = i
break
if res is None:
@ -485,7 +490,6 @@ class _OpenSSL:
"""
returns a create_string_buffer (ctypes)
"""
buffer = None
if data != 0:
if sys.version_info.major == 3 and isinstance(data, type('')):
data = data.encode()
@ -494,26 +498,27 @@ class _OpenSSL:
buffer = self.create_string_buffer(size)
return buffer
def loadOpenSSL():
def load_open_ssl():
global OpenSSL
from os import path, environ
from ctypes.util import find_library
libdir = []
if getattr(sys,'frozen', None):
lib_dir = []
if getattr(sys, 'frozen', None):
if 'darwin' in sys.platform:
libdir.extend([
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.1.0.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.2.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.1.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.0.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.0.9.8.dylib'),
lib_dir.extend([
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.1.0.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.2.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.1.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.0.dylib'),
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.0.9.8.dylib'),
])
elif 'win32' in sys.platform or 'win64' in sys.platform:
libdir.append(path.join(sys._MEIPASS, 'libeay32.dll'))
lib_dir.append(path.join(sys._MEIPASS, 'libeay32.dll'))
else:
libdir.extend([
lib_dir.extend([
path.join(sys._MEIPASS, 'libcrypto.so'),
path.join(sys._MEIPASS, 'libssl.so'),
path.join(sys._MEIPASS, 'libcrypto.so.1.1.0'),
@ -528,19 +533,19 @@ def loadOpenSSL():
path.join(sys._MEIPASS, 'libssl.so.0.9.8'),
])
if 'darwin' in sys.platform:
libdir.extend(['libcrypto.dylib', '/usr/local/opt/openssl/lib/libcrypto.dylib'])
lib_dir.extend(['libcrypto.dylib', '/usr/local/opt/openssl/lib/libcrypto.dylib'])
elif 'win32' in sys.platform or 'win64' in sys.platform:
libdir.append('libeay32.dll')
lib_dir.append('libeay32.dll')
else:
libdir.append('libcrypto.so')
libdir.append('libssl.so')
libdir.append('libcrypto.so.1.0.0')
libdir.append('libssl.so.1.0.0')
lib_dir.append('libcrypto.so')
lib_dir.append('libssl.so')
lib_dir.append('libcrypto.so.1.0.0')
lib_dir.append('libssl.so.1.0.0')
if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform:
libdir.append(find_library('ssl'))
lib_dir.append(find_library('ssl'))
elif 'win32' in sys.platform or 'win64' in sys.platform:
libdir.append(find_library('libeay32'))
for library in libdir:
lib_dir.append(find_library('libeay32'))
for library in lib_dir:
try:
OpenSSL = _OpenSSL(library)
return
@ -548,4 +553,5 @@ def loadOpenSSL():
pass
raise Exception("Couldn't find and load the OpenSSL library. You must install it.")
loadOpenSSL()
load_open_ssl()

View File

@ -31,6 +31,9 @@ for tunneling connections through SOCKS proxies.
"""
import socket
import struct
"""
Minor modifications made by Christopher Gilbert (http://motomastyle.com/)
@ -41,23 +44,38 @@ mainly to merge bug fixes found in Sourceforge
"""
import socket
import struct
import sys
PROXY_TYPE_SOCKS4 = 1
PROXY_TYPE_SOCKS5 = 2
PROXY_TYPE_HTTP = 3
proxy_type_socks4 = 1
proxy_type_socks5 = 2
proxy_type_http = 3
_defaultproxy = None
_orgsocket = socket.socket
_default_proxy = None
_org_socket = socket.socket
class ProxyError(Exception):
pass
class GeneralProxyError(ProxyError):
pass
class Socks5AuthError(ProxyError):
pass
class Socks5Error(ProxyError):
pass
class Socks4Error(ProxyError):
pass
class HTTPError(ProxyError):
pass
class ProxyError(Exception): pass
class GeneralProxyError(ProxyError): pass
class Socks5AuthError(ProxyError): pass
class Socks5Error(ProxyError): pass
class Socks4Error(ProxyError): pass
class HTTPError(ProxyError): pass
_generalerrors = ("success",
"invalid data",
@ -93,13 +111,15 @@ _socks4errors = ("request granted",
"request rejected because the client program and identd report different user-ids",
"unknown error")
def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
"""setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
Sets a default proxy which all further socksocket objects will use,
unless explicitly changed.
"""
global _defaultproxy
_defaultproxy = (proxytype, addr, port, rdns, username, password)
global _default_proxy
_default_proxy = (proxytype, addr, port, rdns, username, password)
def wrapmodule(module):
"""wrapmodule(module)
@ -108,12 +128,13 @@ def wrapmodule(module):
This will only work on modules that import socket directly into the namespace;
most of the Python Standard Library falls into this category.
"""
if _defaultproxy != None:
module.socket.socket = socksocket
if _default_proxy is not None:
module.socket.socket = Socksocket
else:
raise GeneralProxyError((4, "no proxy specified"))
class socksocket(socket.socket):
class Socksocket(socket.socket):
"""socksocket([family[, type[, proto]]]) -> socket object
Open a SOCKS enabled socket. The parameters are the same as
those of the standard socket init. In order for SOCKS to work,
@ -121,13 +142,13 @@ class socksocket(socket.socket):
"""
def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
_orgsocket.__init__(self, family, type, proto, _sock)
if _defaultproxy != None:
self.__proxy = _defaultproxy
_org_socket.__init__(self, family, type, proto, _sock)
if _default_proxy is not None:
self.__proxy = _default_proxy
else:
self.__proxy = (None, None, None, None, None, None)
self.__proxysockname = None
self.__proxypeername = None
self.__proxy_sock_name = None
self.__proxy_peer_name = None
def __recvall(self, count):
"""__recvall(count) -> data
@ -140,7 +161,8 @@ class socksocket(socket.socket):
raise GeneralProxyError((6, "timed out"))
while len(data) < count:
d = self.recv(count-len(data))
if not d: raise GeneralProxyError((0, "connection closed unexpectedly"))
if not d:
raise GeneralProxyError((0, "connection closed unexpectedly"))
data = data + d
return data
@ -181,7 +203,7 @@ class socksocket(socket.socket):
Negotiates a connection through a SOCKS5 server.
"""
# First we'll send the authentication packages we support.
if (self.__proxy[4]!=None) and (self.__proxy[5]!=None):
if self.__proxy[4] is not None and self.__proxy[5] is not None:
# The username/password details were supplied to the
# setproxy method so we support the USERNAME/PASSWORD
# authentication (in addition to the standard none).
@ -203,7 +225,10 @@ class socksocket(socket.socket):
elif chosenauth[1:2] == chr(0x02).encode():
# Okay, we need to perform a basic username/password
# authentication.
self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
self.sendall(
chr(0x01).encode() + chr(len(self.__proxy[4])) +
self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]
)
authstat = self.__recvall(2)
if authstat[0:1] != chr(0x01).encode():
# Bad response
@ -250,7 +275,7 @@ class socksocket(socket.socket):
elif resp[1:2] != chr(0x00).encode():
# Connection failed
self.close()
if ord(resp[1:2])<=8:
if ord(resp[1:2]) <= 8:
raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
else:
raise Socks5Error((9, _socks5errors[9]))
@ -262,13 +287,13 @@ class socksocket(socket.socket):
boundaddr = self.__recvall(ord(resp[4:5]))
else:
self.close()
raise GeneralProxyError((1,_generalerrors[1]))
raise GeneralProxyError((1, _generalerrors[1]))
boundport = struct.unpack(">H", self.__recvall(2))[0]
self.__proxysockname = (boundaddr, boundport)
if ipaddr != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
self.__proxy_sock_name = (boundaddr, boundport)
if ipaddr:
self.__proxy_peer_name = (socket.inet_ntoa(ipaddr), destport)
else:
self.__proxypeername = (destaddr, destport)
self.__proxy_peer_name = (destaddr, destport)
def __resolvesocks5(self, host):
# Now we can request the actual connection
@ -277,7 +302,7 @@ class socksocket(socket.socket):
req = req + struct.pack(">H", 8444)
self.sendall(req)
# Get the response
ip = ""
resp = self.__recvall(4)
if resp[0:1] != chr(0x05).encode():
self.close()
@ -285,7 +310,7 @@ class socksocket(socket.socket):
elif resp[1:2] != chr(0x00).encode():
# Connection failed
self.close()
if ord(resp[1:2])<=8:
if ord(resp[1:2]) <= 8:
raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
else:
raise Socks5Error((9, _socks5errors[9]))
@ -297,65 +322,64 @@ class socksocket(socket.socket):
ip = self.__recvall(ord(resp[4:5]))
else:
self.close()
raise GeneralProxyError((1,_generalerrors[1]))
boundport = struct.unpack(">H", self.__recvall(2))[0]
raise GeneralProxyError((1, _generalerrors[1]))
return ip
def getproxysockname(self):
"""getsockname() -> address info
Returns the bound IP address and port number at the proxy.
"""
return self.__proxysockname
return self.__proxy_sock_name
def getproxypeername(self):
"""getproxypeername() -> address info
Returns the IP and port number of the proxy.
"""
return _orgsocket.getpeername(self)
return _org_socket.getpeername(self)
def getpeername(self):
"""getpeername() -> address info
Returns the IP address and port number of the destination
machine (note: getproxypeername returns the proxy)
"""
return self.__proxypeername
return self.__proxy_peer_name
def getproxytype(self):
return self.__proxy[0]
def __negotiatesocks4(self,destaddr,destport):
def __negotiatesocks4(self, destination_address, destination_port):
"""__negotiatesocks4(self,destaddr,destport)
Negotiates a connection through a SOCKS4 server.
"""
# Check if the destination address provided is an IP address
rmtrslv = False
try:
ipaddr = socket.inet_aton(destaddr)
ipaddr = socket.inet_aton(destination_address)
except socket.error:
# It's a DNS name. Check where it should be resolved.
if self.__proxy[3]:
ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)
rmtrslv = True
else:
ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
ipaddr = socket.inet_aton(socket.gethostbyname(destination_address))
# Construct the request packet
req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr
req = struct.pack(">BBH", 0x04, 0x01, destination_port) + ipaddr
# The username parameter is considered userid for SOCKS4
if self.__proxy[4] != None:
if self.__proxy[4] is not None:
req = req + self.__proxy[4]
req = req + chr(0x00).encode()
# DNS name if remote resolving is required
# NOTE: This is actually an extension to the SOCKS4 protocol
# called SOCKS4A and may not be supported in all cases.
if rmtrslv:
req = req + destaddr + chr(0x00).encode()
req = req + destination_address + chr(0x00).encode()
self.sendall(req)
# Get the response from the server
resp = self.__recvall(8)
if resp[0:1] != chr(0x00).encode():
# Bad data
self.close()
raise GeneralProxyError((1,_generalerrors[1]))
raise GeneralProxyError((1, _generalerrors[1]))
if resp[1:2] != chr(0x5A).encode():
# Server returned an error
self.close()
@ -365,44 +389,48 @@ class socksocket(socket.socket):
else:
raise Socks4Error((94, _socks4errors[4]))
# Get the bound address/port
self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
if rmtrslv != None:
self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
self.__proxy_sock_name = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
if rmtrslv is not None:
self.__proxy_peer_name = (socket.inet_ntoa(ipaddr), destination_port)
else:
self.__proxypeername = (destaddr, destport)
self.__proxy_peer_name = (destination_address, destination_port)
def __negotiatehttp(self, destaddr, destport):
def __negotiatehttp(self, destination_address, destination_port):
"""__negotiatehttp(self,destaddr,destport)
Negotiates a connection through an HTTP server.
"""
# If we need to resolve locally, we do this now
if not self.__proxy[3]:
addr = socket.gethostbyname(destaddr)
addr = socket.gethostbyname(destination_address)
else:
addr = destaddr
self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode())
addr = destination_address
self.sendall(("CONNECT {} : {} HTTP/1.1\r\n Host: {} \r\n\r\n".format(
addr, str(destination_port), destination_address)
).encode())
# We read the response until we get the string "\r\n\r\n"
resp = self.recv(1)
while resp.find("\r\n\r\n".encode()) == -1:
resp = resp + self.recv(1)
# We just need the first line to check if the connection
# was successful
statusline = resp.splitlines()[0].split(" ".encode(), 2)
if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
status_line = resp.splitlines()[0].split(" ".encode(), 2)
if status_line[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
self.close()
raise GeneralProxyError((1, _generalerrors[1]))
try:
statuscode = int(statusline[1])
statuscode = int(status_line[1])
except ValueError:
self.close()
raise GeneralProxyError((1, _generalerrors[1]))
if statuscode != 200:
self.close()
raise HTTPError((statuscode, statusline[2]))
self.__proxysockname = ("0.0.0.0", 0)
self.__proxypeername = (addr, destport)
raise HTTPError((statuscode, status_line[2]))
self.__proxy_sock_name = ("0.0.0.0", 0)
self.__proxy_peer_name = (addr, destination_port)
def connect(self, destpair):
def connect(self, destination_pair):
"""connect(self, despair)
Connects to the specified destination through a proxy.
destpar - A tuple of the IP/DNS address and the port number.
@ -410,15 +438,15 @@ class socksocket(socket.socket):
To select the proxy server use setproxy().
"""
# Do a minimal input check first
if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int):
if (not type(destination_pair) in (list, tuple)) or \
(len(destination_pair) < 2) or \
(type(destination_pair[0]) != type('')) or (not isinstance(destination_pair[1], int)):
raise GeneralProxyError((5, _generalerrors[5]))
if self.__proxy[0] == PROXY_TYPE_SOCKS5:
if self.__proxy[2] != None:
portnum = self.__proxy[2]
else:
portnum = 1080
if self.__proxy[0] == proxy_type_socks5:
port_number = self.__proxy[2] if self.__proxy[2] is not None else 1080
try:
_orgsocket.connect(self, (self.__proxy[1], portnum))
_org_socket.connect(self, (self.__proxy[1], port_number))
except socket.error as e:
# ENETUNREACH, WSAENETUNREACH
if e[0] in [101, 10051]:
@ -431,21 +459,17 @@ class socksocket(socket.socket):
raise GeneralProxyError((9, _generalerrors[9]))
raise
self.__negotiatesocks5()
self.__connectsocks5(destpair[0], destpair[1])
elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
if self.__proxy[2] != None:
portnum = self.__proxy[2]
else:
portnum = 1080
_orgsocket.connect(self,(self.__proxy[1], portnum))
self.__negotiatesocks4(destpair[0], destpair[1])
elif self.__proxy[0] == PROXY_TYPE_HTTP:
if self.__proxy[2] != None:
portnum = self.__proxy[2]
else:
portnum = 8080
self.__connectsocks5(destination_pair[0], destination_pair[1])
elif self.__proxy[0] == proxy_type_socks4:
port_number = self.__proxy[2] if self.__proxy[2] is not None else 1080
_org_socket.connect(self, (self.__proxy[1], port_number))
self.__negotiatesocks4(destination_pair[0], destination_pair[1])
elif self.__proxy[0] == proxy_type_http:
port_number = self.__proxy[2] if self.__proxy[2] is not None else 8080
try:
_orgsocket.connect(self,(self.__proxy[1], portnum))
_org_socket.connect(self, (self.__proxy[1], port_number))
except socket.error as e:
# ENETUNREACH, WSAENETUNREACH
if e[0] in [101, 10051]:
@ -457,19 +481,17 @@ class socksocket(socket.socket):
if e[0] in [113, 10065]:
raise GeneralProxyError((9, _generalerrors[9]))
raise
self.__negotiatehttp(destpair[0], destpair[1])
elif self.__proxy[0] == None:
_orgsocket.connect(self, (destpair[0], destpair[1]))
self.__negotiatehttp(destination_pair[0], destination_pair[1])
elif not self.__proxy[0]:
_org_socket.connect(self, (destination_pair[0], destination_pair[1]))
else:
raise GeneralProxyError((4, _generalerrors[4]))
def resolve(self, host):
if self.__proxy[0] == PROXY_TYPE_SOCKS5:
if self.__proxy[2] != None:
portnum = self.__proxy[2]
else:
portnum = 1080
_orgsocket.connect(self, (self.__proxy[1], portnum))
if self.__proxy[0] == proxy_type_socks5:
port_number = self.__proxy[2] if self.__proxy[2] is not None else 1080
_org_socket.connect(self, (self.__proxy[1], port_number))
self.__negotiatesocks5()
return self.__resolvesocks5(host)
else: