Skip to content

Instantly share code, notes, and snippets.

@sstevan
Last active February 19, 2024 04:59
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save sstevan/efccf3d5d3e73039c21aa848353ff52f to your computer and use it in GitHub Desktop.
Save sstevan/efccf3d5d3e73039c21aa848353ff52f to your computer and use it in GitHub Desktop.
Python (v2 - v3) - IMAP through SOCKS proxy using PySocks module
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 = "test@esp.com"
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)
@AbdullahY36
Copy link

AbdullahY36 commented Aug 11, 2022

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")

@ItzmeSwapy
Copy link

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

@Peter-XL
Copy link

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

@ramazk
Copy link

ramazk commented Jan 3, 2023

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?

@sstevan
Copy link
Author

sstevan commented Jan 3, 2023

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?

@ramazk
Copy link

ramazk commented Jan 4, 2023

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/python@3.10/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.

@tmxd09887
Copy link

same error

TypeError: SocksIMAP4SSL._create_socket() takes 1 positional argument but 2 were given

@xyzonline
Copy link

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')

@Anthonybelui
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment