-
-
Save sstevan/efccf3d5d3e73039c21aa848353ff52f to your computer and use it in GitHub Desktop.
import ssl | |
from socks import create_connection | |
from socks import PROXY_TYPE_SOCKS4 | |
from socks import PROXY_TYPE_SOCKS5 | |
from socks import PROXY_TYPE_HTTP | |
from imaplib import IMAP4 | |
from imaplib import IMAP4_PORT | |
from imaplib import IMAP4_SSL_PORT | |
__author__ = "sstevan" | |
__license__ = "GPLv3" | |
__version__ = "0.1" | |
class SocksIMAP4(IMAP4): | |
""" | |
IMAP service trough SOCKS proxy. PySocks module required. | |
""" | |
PROXY_TYPES = {"socks4": PROXY_TYPE_SOCKS4, | |
"socks5": PROXY_TYPE_SOCKS5, | |
"http": PROXY_TYPE_HTTP} | |
def __init__(self, host, port=IMAP4_PORT, proxy_addr=None, proxy_port=None, | |
rdns=True, username=None, password=None, proxy_type="socks5", timeout=None): | |
self.proxy_addr = proxy_addr | |
self.proxy_port = proxy_port | |
self.rdns = rdns | |
self.username = username | |
self.password = password | |
self.proxy_type = SocksIMAP4.PROXY_TYPES[proxy_type.lower()] | |
IMAP4.__init__(self, host, port, timeout) | |
def _create_socket(self): | |
return create_connection((self.host, self.port), proxy_type=self.proxy_type, proxy_addr=self.proxy_addr, | |
proxy_port=self.proxy_port, proxy_rdns=self.rdns, proxy_username=self.username, | |
proxy_password=self.password) | |
class SocksIMAP4SSL(SocksIMAP4): | |
def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None, proxy_addr=None, | |
proxy_port=None, rdns=True, username=None, password=None, proxy_type="socks5", timeout=None): | |
if ssl_context is not None and keyfile is not None: | |
raise ValueError("ssl_context and keyfile arguments are mutually " | |
"exclusive") | |
if ssl_context is not None and certfile is not None: | |
raise ValueError("ssl_context and certfile arguments are mutually " | |
"exclusive") | |
self.keyfile = keyfile | |
self.certfile = certfile | |
if ssl_context is None: | |
ssl_context = ssl._create_stdlib_context(certfile=certfile, | |
keyfile=keyfile) | |
self.ssl_context = ssl_context | |
SocksIMAP4.__init__(self, host, port, proxy_addr=proxy_addr, proxy_port=proxy_port, | |
rdns=rdns, username=username, password=password, proxy_type=proxy_type, timeout) | |
def _create_socket(self): | |
sock = SocksIMAP4._create_socket(self) | |
server_hostname = self.host if ssl.HAS_SNI else None | |
return self.ssl_context.wrap_socket(sock, server_hostname=server_hostname) | |
# Looks like newer versions of Python changed open() method in IMAP4 lib. | |
# Adding timeout as additional parameter should resolve issues mentioned in comments. | |
# Check https://github.com/python/cpython/blob/main/Lib/imaplib.py#L202 for more details. | |
def open(self, host='', port=IMAP4_PORT, timeout=None): | |
SocksIMAP4.open(self, host, port, timeout) | |
if __name__ == "__main__": | |
email = "[email protected]" | |
password = "secret_password" | |
imap_server = "imap.esp.com" | |
imap_port = 993 | |
proxy_addr = "100.42.161.8" | |
proxy_port = 45554 | |
proxy_type = "socks5" | |
mailbox = SocksIMAP4SSL(host=imap_server, port=imap_port, | |
proxy_addr=proxy_addr, proxy_port=proxy_port, proxy_type=proxy_type) | |
mailbox.login(email, password) | |
typ, data = mailbox.list() | |
print(typ) | |
print(data) |
Thanks a lot for sharing!
Nice job! THX a lot
This works like a charm! (Python 3.6) Thanks so much!!
beauty
Hey @exengineer00
You might want to delete your message and change your password since it is publicly exposed now.
Beside username and password, you will need following data to be valid:
email = "[email protected]"
password = "secret_password"
imap_server = "imap.esp.com"
imap_port = 993
proxy_addr = "100.42.161.8"
proxy_port = 45554
proxy_type = "socks5"
i use a gmail account and socks4 , so i do it like that,
email = "*******@gmail.com"
password = "**********"`
imap_server = "imap.gmail.com"
imap_port = 993
proxy_addr = "here_i_put_the_proxy_IP"
proxy_port = proxy's_port
proxy_type = "socks4"
but when i bought the socks4 proxy i got a authenication username and password with it , partly from the IP and the port
The proxy address and the port are fine i tried them.
I'm attempting to implement this using proxies of the format HOST:PORT:USER:PASSWORD
.
An example (dummy user/pass) would be: gw.proxy.rainproxy.io:5959:Pp7fwti5n-res-any-sid-109111001:abEDxts7v
I can test that the proxy works:
USER = 'Pp7fwti5n-res-any-sid-' + random8Digits()
PASS = 'abEDxts7v'
HOST = 'gw.proxy.rainproxy.io'
PORT = 5959
proxy = f'{USER}:{PASS}@{HOST}:{PORT}'
proxies = {
'http': 'http://' + proxy,
'https': 'http://' + proxy
}
response = requests.get(
'https://ip.nf/me.json',
proxies=proxies, timeout=15
)
My code looks like this:
def fetchRecentEmail(emailAddr, emailPassword, timeout=120):
host = fetch_imap_server(emailAddr) # e.g. 'outlook.office365.com'
with IMAP4_SSL(host) as session:
status, _ = session.login(emailAddr, emailPassword)
if status == 'OK':
# fetch most recent message
status, messageData = session.select("Inbox")
:
How can I tweak my code to proxify the email session?
This would be nonsense I'm sure:
proxy_addr = f'{PROXY_USER}:{PROXY_PASSWORD}@{PROXY_HOST}:{PROXY_PORT}'
proxy_port = 45554
proxy_type = "socks5"
But how to do it?
Maybe I could fetch the IP that my proxy returns and use that...?
But how could that work? If that works without user/password then ANYONE could use that proxy-IP. The proxy provider company would go out of business I'm sure.
So how to pass this proxy-provider user/password in?
Looking more carefully I've just noticed that the code DOES handle a proxy of the format USER:PASS:HOST:PORT
username
and password
can be supplied to SocksIMAP4.init and these are PROXY username/password. I thought they were EMAIL user/password. Bit confusing. I'm changing the variable names in my local code.
However this code fails:
USER, PASS,URL, PORT = ...
PROXY_TYPE = 'http' # rainproxies are HTTP
mailbox = SocksIMAP4SSL(
host='outlook.office365.com',
# port=imap_port,
proxy_type='http',
proxy_addr=URL,
proxy_port=PORT,
username=USER,
password=PASS
)
# ^ fails here
mailbox.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
typ, data = mailbox.list()
print(typ, data)
The error is happening on this line (in our SocksIMAP4.init): https://gist.github.com/sstevan/efccf3d5d3e73039c21aa848353ff52f#file-socksimap-py-L36
IMAP4.__init__(self, host, port)
Printing values and looking at the error I have no clue what's happening:
print(f'host:`{host}`') # `outlook.office365.com`
print(f'port:`{port}`') # `993`
IMAP4.__init__(self, host, port)
# ~/.pyenv/versions/3.10.0/lib/python3.10/imaplib.py:202
# 202 self.open(host, port, timeout)
# ^ SocksIMAP4SSL.open() takes from 1 to 3 positional arguments but 4 were given
Looking into the sourcefile at /Users/pi/.pyenv/versions/3.10.0/lib/python3.10/imaplib.py:
def __init__(self, host='', port=IMAP4_PORT, timeout=None):
:
# Open socket to server.
self.open(host, port, timeout)
This makes no sense to me. How can Python be interpreting host, port, timeout
as "4 positional arguments"?
Hello, I just saw your job on Upwork.
Try this code. If you can share your full code, that'll be easier.
import ssl
from socks import create_connection
from socks import PROXY_TYPE_SOCKS4
from socks import PROXY_TYPE_SOCKS5
from socks import PROXY_TYPE_HTTP
from imaplib import IMAP4
from imaplib import IMAP4_PORT
from imaplib import IMAP4_SSL_PORT
__author__ = "sstevan"
__license__ = "GPLv3"
__version__ = "0.1"
class SocksIMAP4(IMAP4):
"""
IMAP service trough SOCKS proxy. PySocks module required.
"""
PROXY_TYPES = {"socks4": PROXY_TYPE_SOCKS4,
"socks5": PROXY_TYPE_SOCKS5,
"http": PROXY_TYPE_HTTP}
def __init__(self, host, port=IMAP4_PORT, proxy_addr=None, proxy_port=None,
rdns=True, username=None, password=None, proxy_type="socks5"):
self.proxy_addr = proxy_addr
self.proxy_port = proxy_port
self.rdns = rdns
self.username = username
self.password = password
self.proxy_type = SocksIMAP4.PROXY_TYPES[proxy_type.lower()]
IMAP4.__init__(self, host, port)
def _create_socket(self):
return create_connection((self.host, self.port), proxy_type=self.proxy_type, proxy_addr=self.proxy_addr,
proxy_port=self.proxy_port, proxy_rdns=self.rdns, proxy_username=self.username,
proxy_password=self.password,timeout=120)
class SocksIMAP4SSL(SocksIMAP4):
def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None, proxy_addr=None,
proxy_port=None, rdns=True, username=None, password=None, proxy_type="socks5"):
if ssl_context is not None and keyfile is not None:
raise ValueError("ssl_context and keyfile arguments are mutually "
"exclusive")
if ssl_context is not None and certfile is not None:
raise ValueError("ssl_context and certfile arguments are mutually "
"exclusive")
self.keyfile = keyfile
self.certfile = certfile
if ssl_context is None:
ssl_context = ssl._create_stdlib_context(certfile=certfile,
keyfile=keyfile)
self.ssl_context = ssl_context
SocksIMAP4.__init__(self, host, port, proxy_addr=proxy_addr, proxy_port=proxy_port,
rdns=rdns, username=username, password=password, proxy_type=proxy_type)
def _create_socket(self):
sock = SocksIMAP4._create_socket(self)
server_hostname = self.host if ssl.HAS_SNI else None
return self.ssl_context.wrap_socket(sock, server_hostname=server_hostname)
def open(self, host='', port=IMAP4_PORT):
SocksIMAP4.open(self, host, port)
if __name__ == "__main__":
# edit this part for your proxy and imap server
email = ""
password = ""
imap_server = "imap.gmail.com"
imap_port = 993
proxy_addr = 'gw.proxy.rainproxy.io'
proxy_port = 5959
usernameproxy = 'Pp7fwti5n-res-any-sid-109111001'
passwordproxy = 'abEDxts7v'
proxy_type = "socks4"
with SocksIMAP4SSL(host=imap_server, port=imap_port, proxy_addr=proxy_addr, proxy_port=proxy_port, username=usernameproxy, password=passwordproxy, proxy_type=proxy_type) as session:
status, _ = session.login(email, password)
if status == 'OK':
# fetch most recent message
status, messageData = session.select("Inbox")
Traceback (most recent call last): File "C:\IG\tests\proxycon.py", line 91, in <module> with SocksIMAP4SSL(host=imap_server, port=imap_port, proxy_addr=proxy_addr, proxy_port=proxy_port, File "C:\IG\tests\proxycon.py", line 63, in __init__ SocksIMAP4.__init__(self, host, port, proxy_addr=proxy_addr, proxy_port=proxy_port, File "C:\IG\tests\proxycon.py", line 36, in __init__ IMAP4.__init__(self, host, port) File "C:\Users\rjenk\AppData\Local\Programs\Python\Python310\lib\imaplib.py", line 202, in __init__ self.open(host, port, timeout) TypeError: SocksIMAP4SSL.open() takes from 1 to 3 positional arguments but 4 were given
Getting this error
Traceback (most recent call last): File "C:\IG\tests\proxycon.py", line 91, in <module> with SocksIMAP4SSL(host=imap_server, port=imap_port, proxy_addr=proxy_addr, proxy_port=proxy_port, File "C:\IG\tests\proxycon.py", line 63, in __init__ SocksIMAP4.__init__(self, host, port, proxy_addr=proxy_addr, proxy_port=proxy_port, File "C:\IG\tests\proxycon.py", line 36, in __init__ IMAP4.__init__(self, host, port) File "C:\Users\rjenk\AppData\Local\Programs\Python\Python310\lib\imaplib.py", line 202, in __init__ self.open(host, port, timeout) TypeError: SocksIMAP4SSL.open() takes from 1 to 3 positional arguments but 4 were given
Getting this error
https://stackoverflow.com/questions/72420632/python-connect-to-imap-through-socks
https://stackoverflow.com/questions/72420632/python-connect-to-imap-through-socks
Would you be so kind to tell where exactly to add one more parameter to make it working as stated in this stackoverflow?
Hey @ramazk I have seen that most complaints are about timeout
parameter. I have tried to fix the script, without testing, and added timeout to the open()
method. Would you mind checking if the error is still the same?
Hi @sstevan, I have tried version of the script above. It has SyntaxError on line 64, so I have changed ...,timeout)
to ...,timeout=None)
. And received this error:
File "/Users/ramazk/Python/test-email2.py", line 75, in open SocksIMAP4.open(self, host, port, timeout) File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/imaplib.py", line 312, in open self.sock = self._create_socket(timeout) TypeError: SocksIMAP4SSL._create_socket() takes 1 positional argument but 2 were given
May be you have ideas how to make it working? Thanks in advance.
same error
TypeError: SocksIMAP4SSL._create_socket() takes 1 positional argument but 2 were given
import imaplib
import socks
import socket
socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", port=10808)
socket.socket = socks.socksocket
M = imaplib.IMAP4_SSL(host='mail.xxxx.xyz')
print('connected')
M.login(USERNAME, PASSWORD)
print('login success')
20.02.2023 Code fix:
https://gist.github.com/Anthonybelui/eca1bf3bea6729c1ef98b5bda1be958f
In Python 2.7 the function "open" in imaplib does not use '_create_socket' to create a socket, as in 3 version.