Example #1
0
    def connect(self, go_to_current_folder = False):
        """
           connect to the IMAP server
        """

        # check if it is needed to disbale cert verification (leave that option at the last resort)
        # if the cert verification doesn't work.
        disable_cert_verification = gmvault_utils.get_conf_defaults().getboolean("GoogleOauth2", "disable_cacert_verification", default=False)
        context = None
        if disable_cert_verification:
            LOG.critical("Beware disabling CA Cert verification for the IMAP connection to Gmail.")
            context = imapclient.create_default_context()
            # don't check if certificate hostname doesn't match target hostname
            context.check_hostname = False
            # don't check if the certificate is trusted by a certificate authority
            context.verify_mode = ssl.CERT_NONE
        else:
            # create a custom ssl context to handle CA cert verification in all cases
            # In some plateform the CA certs are not available so use the ones provided by Gmvault
            # CA certs are coming from https://curl.haxx.se/ca/cacert.pem
            context = imapclient.create_default_context(cafile= gmvault_utils.get_ca_certs_filepath())

        # create imap object
        self.server = mimap.MonkeyIMAPClient(self.host, port = self.port, use_uid = self.use_uid, need_ssl = self.ssl, ssl_context = context)
        # connect with password or xoauth
        if self.credential['type'] == 'passwd':
            self.server.login(self.login, self.credential['value'])
        elif self.credential['type'] == 'oauth2':
            #connect with oauth2
            if self.once_connected:
                self.credential = credential_utils.CredentialHelper.get_oauth2_credential(self.login, renew_cred = False)

            LOG.debug("credential['value'] = %s" % (self.credential['value']))
            #try to login
            self.server.oauth2_login(self.credential['value'])
        else:
            raise Exception("Unknown authentication method %s. Please use xoauth or passwd authentication " \
                            % (self.credential['type']))
            
        #set connected to True to handle reconnection in case of failure
        self.once_connected = True
        
        # check gmailness
        self.check_gmailness()
         
        # find allmail chats and drafts folders
        self.find_folder_names()

        if go_to_current_folder and self.current_folder:
            self.server.select_folder(self.current_folder, readonly = self.readonly_folder)
            
        #enable compression
        if gmvault_utils.get_conf_defaults().get_boolean('General', 'enable_imap_compression', True):
            self.enable_compression()
            LOG.debug("After Enabling compression.")
        else:
            LOG.debug("Do not enable imap compression.") 
Example #2
0
def fetch_test_submissions(previous_history, config):
    """ fetch emails from IMAP server using the given configuration
        each email is parsed to see whether it matches a submission
        if so, its token is extracted and checked against the given
        history.
        if found, the email is deleted from the server and the entry
        is removed from the history.
        any entries left in the history are returned
    """
    context = create_default_context()
    context.check_hostname = False
    context.verify_mode = False
    server = IMAPClient(config['imap_host'], use_uid=True, ssl=True, ssl_context=context)
    server.login(config['imap_user'], config['imap_passwd'])
    server.select_folder('INBOX')
    history = previous_history.copy()
    candidates = server.fetch(server.search(criteria='NOT DELETED SUBJECT "Drop ID"'), ['BODY[HEADER.FIELDS (SUBJECT)]'])
    for imap_id, message in candidates.items():
        subject = message.get('BODY[HEADER.FIELDS (SUBJECT)]', 'Subject: ')
        try:
            drop_id = find_drop_id.findall(subject)[0]
        except IndexError:
            # ignore emails that are not test submissions
            continue
        print "Found submission '%s'" % drop_id
        server.delete_messages([imap_id])
        try:
            del history[drop_id]
        except KeyError:
            pass  # TODO: log this?
    server.logout()
    return history
Example #3
0
    def __init__(self, cfg):
        super().__init__(cfg)

        # Use default client behavior if ca_file not provided.
        context = imapclient.create_default_context()
        if 'ca_file' in cfg['server']:
            context.cafile = cfg['server']['ca_file']

        if 'check_hostname' in cfg['server']:
            context.check_hostname = tobool(cfg['server']['check_hostname'])

        ssl = True
        if 'ssl' in cfg['server']:
            ssl = tobool(cfg['server']['ssl'])

        self._conn = imapclient.IMAPClient(
            cfg['server']['hostname'],
            use_uid=True,
            ssl=ssl,
            port=cfg['server'].get('port'),
            ssl_context=context,
        )
        username = cfg['server']['username']
        password = secrets.get_password(cfg)
        self._conn.login(username, password)
        self._mbox_names = None
Example #4
0
 def connect(self):
     self.disconnect()
     self.client = imapclient.IMAPClient(self.imaphost, port=None, use_uid=True)
     atexit.register(self.disconnect)
     ctx = imapclient.create_default_context()
     self.client.starttls(ssl_context=ctx)
     self.client.login(self.imapusername, self.imappassword)
     self.client.id_(None) # TODO: be nicer
     self.client.select_folder(self.inbox)
Example #5
0
def IMAP_client_factory(host, port, use_ssl=None):
    ssl_context=None
    if use_ssl:
        ssl_context=imapclient.create_default_context()
    
    if use_ssl=='insecure':
        ssl_context.check_hostname = False
        ssl_context.verify_mode = ssl.CERT_NONE
        
    return imapclient.IMAPClient(host,port,ssl=use_ssl, ssl_context=ssl_context, timeout=60)
Example #6
0
 def __init__(self, host, username, password, use_ssl, image_folder,
              force=False):
     self.host = host
     self.username = username
     self.password = password
     self.use_ssl = use_ssl
     self.image_folder = image_folder
     self.connection = None
     self.context = create_default_context()
     self.context.verify_mode = ssl.CERT_NONE
     self.force = force
Example #7
0
def create_imap_connection(host, port):
    use_ssl = port == 993

    # TODO: certificate pinning for well known sites
    context = create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE

    conn = IMAPClient(host, port=port, use_uid=True,
                      ssl=use_ssl, ssl_context=context)
    if not use_ssl:
        # Raises an exception if TLS can't be established
        conn.starttls(context)
    return conn
Example #8
0
def IMAP_client_factory(host, port, use_ssl=None):
    ssl_context = None
    if use_ssl:
        ssl_context = imapclient.create_default_context()

    if use_ssl == 'insecure':
        ssl_context.check_hostname = False
        ssl_context.verify_mode = ssl.CERT_NONE

    return imapclient.IMAPClient(host,
                                 port,
                                 ssl=use_ssl,
                                 ssl_context=ssl_context,
                                 timeout=60)
Example #9
0
def server():
    context = imapclient.create_default_context()

    # don't check if certificate hostname doesn't match target hostname
    context.check_hostname = False

    # don't check if the certificate is trusted by a certificate authority
    context.verify_mode = ssl.CERT_NONE

    server = ImapProxy(
        imapclient.IMAPClient(HOST,
                              use_uid=True,
                              ssl=True,
                              ssl_context=context))
    server.login(USERNAME, PASSWORD)
    return server
Example #10
0
def connectIMAP(account):
    username = account.username
    host = account.host
    password = account.password

    context = imapclient.create_default_context()
    if not account.verifySSL:
        context.verify_mode = ssl.CERT_NONE
        warn('SSL cert verification disabled for host %s' % host)

    imap = IMAPClient(
        host, use_uid=True, ssl=True,
        ssl_context=context)  # no one should ever use cleartext these days
    imap.login(username, password)
    info('logged in %s' % account.email)
    return imap
Example #11
0
def create_imap_connection(host, port):
    use_ssl = port == 993

    # TODO: certificate pinning for well known sites
    context = create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE

    conn = IMAPClient(host,
                      port=port,
                      use_uid=True,
                      ssl=use_ssl,
                      ssl_context=context)
    if not use_ssl:
        # Raises an exception if TLS can't be established
        conn.starttls(context)
    return conn
Example #12
0
    def connect(self):
        params = dict(
            use_uid = True,
            ssl = self.__config.ssl,
        )

        if self.__config.ssl:
            context = imapclient.create_default_context()
            context.check_hostname = False
            context.verify_mode = ssl.CERT_NONE
            params['ssl_context'] = context

        if self.__config.port:
            params['port'] = self.__config.port

        self.__server = imapclient.IMAPClient(self.__config.host, **params)
        self.__server.login(self.__config.username, self.__config.password)
        last_uid = self.set_folder(self.__folder)

        logger.info("Connect and login %s is successfull. Last uid is %s", self.__config.host, last_uid)

        return last_uid
Example #13
0
File: views.py Project: iggy/simone
def index(request):
    """main index view

    :param request: request object from Django
    """
    # if they haven't filled in their options, we won't have much luck
    # connecting to their mail server
    try:
        if request.user.imapserver_set.all()[0].username == None:
            pass
    except:
        return HttpResponseRedirect('config/newconfig/')

    folder = "INBOX"

    # defaultEditor = request.user.editor

    srvr = request.user.imapserver_set.all()[0]
    try:
        sslcontext = imapclient.create_default_context()
        sslcontext.check_hostname = False
        # sslcontext.wrap_context
        sslcontext.verify_mode = ssl.CERT_OPTIONAL
        sslcontext.options |= ssl.OP_NO_SSLv2
        sslcontext.options |= ssl.OP_NO_SSLv3
        imap = imapclient.IMAPClient(srvr.address, port=srvr.port, use_uid=False, ssl=srvr.ssl, ssl_context=sslcontext)
        imap.login(srvr.username, srvr.passwd)
        folderlist = imap.list_folders()
        folderlist.reverse()
        imap.logout()
        return render(request, 'main.html', locals())
    except imaplib.IMAP4.error as imaperr:
        return HttpResponse('Error connecting to IMAP server: {}<br>{}'.format(srvr.address, imaperr))
    except OSError as oserr:
        resp = """Error connecting to IMAP server: {}<br>
        {}<br>
        Possibly a DNS issue?"""
        return HttpResponse(resp.format(srvr.address, oserr))
Example #14
0
def index(request):
    """main index view

    :param request: request object from Django
    """
    # if they haven't filled in their options, we won't have much luck
    # connecting to their mail server
    try:
        if request.user.imapserver_set.all()[0].username == None:
            pass
    except:
        return HttpResponseRedirect('config/newconfig/')

    folder = "INBOX"

    # defaultEditor = request.user.editor

    srvr = request.user.imapserver_set.all()[0]
    try:
        sslcontext = imapclient.create_default_context()
        sslcontext.check_hostname = False
        # sslcontext.wrap_context
        sslcontext.verify_mode = ssl.CERT_OPTIONAL
        sslcontext.options |= ssl.OP_NO_SSLv2
        sslcontext.options |= ssl.OP_NO_SSLv3
        imap = imapclient.IMAPClient(srvr.address,
                                     port=srvr.port,
                                     use_uid=False,
                                     ssl=srvr.ssl,
                                     ssl_context=sslcontext)
        imap.login(srvr.username, srvr.passwd)
        folderlist = imap.list_folders()
        folderlist.reverse()
        imap.logout()
        return render(request, 'main.html', locals())
    except imaplib.IMAP4.error as imaperr:
        return HttpResponse('Error connecting to IMAP server: {}<br>{}'.format(
            srvr.address, imaperr))
Example #15
0
    def _run(self):
        # Run commands in thread
        if self._ssl:
            kwargs = dict(ssl_context=imapclient.create_default_context())
        else:
            kwargs = {}
        try:
            conn = IMAPClient(self._host, self._port, ssl=self._ssl, **kwargs)
        except Exception as exn:
            future, method, args = self._command_queue.get()
            self._response_queue.put((future, exn))
            self._command_queue.task_done()
            os.write(self._ready_w, b'x')
            return
        try:
            while True:
                future, method, args = self._command_queue.get()
                if method is self.BREAK:
                    break
                elif method is self.NOOP:
                    result = None
                else:
                    # TODO check if future is cancelled
                    try:
                        result = getattr(conn, method)(*args)
                    except Exception as exn:
                        result = exn
                # TODO use call_soon_threadsafe instead of _response_queue?
                self._response_queue.put((future, result))
                self._command_queue.task_done()
                os.write(self._ready_w, b'x')
        finally:
            conn.shutdown()

        assert method is self.BREAK
        self._response_queue.put((future, None))
        self._command_queue.task_done()
        os.write(self._ready_w, b'x')
Example #16
0
def fetch_test_submissions(previous_history, config):
    """ fetch emails from IMAP server using the given configuration
        each email is parsed to see whether it matches a submission
        if so, its token is extracted and checked against the given
        history.
        if found, the email is deleted from the server and the entry
        is removed from the history.
        any entries left in the history are returned
    """
    context = create_default_context()
    context.check_hostname = False
    context.verify_mode = False
    server = IMAPClient(config['imap_host'],
                        use_uid=True,
                        ssl=True,
                        ssl_context=context)
    server.login(config['imap_user'], config['imap_passwd'])
    server.select_folder('INBOX')
    history = previous_history.copy()
    candidates = server.fetch(
        server.search(criteria='NOT DELETED SUBJECT "Drop"'),
        ['BODY[HEADER.FIELDS (SUBJECT)]'])
    for imap_id, message in candidates.items():
        subject = message.get('BODY[HEADER.FIELDS (SUBJECT)]', 'Subject: ')
        try:
            drop_id = find_drop_id.findall(subject)[0]
        except IndexError:
            # ignore emails that are not test submissions
            continue
        server.delete_messages([imap_id])
        try:
            del history[drop_id]
        except KeyError:
            pass  # TODO: log this?
    server.logout()
    return history
Example #17
0
def cpimap(user1, host1, pass1, user2, host2, pass2):
    context = imapclient.create_default_context()
    messages = Messages()

    M1 = imapclient.IMAPClient(host=host1, use_uid=True, ssl=True,
                               ssl_context=context)

    M1.login(user1, pass1)

    M2 = imapclient.IMAPClient(host=host2, use_uid=True, ssl=True,
                               ssl_context=context)
    M2.login(user2, pass2)

    imap_folders = M1.xlist_folders()
    folders = []

    for folder in imap_folders:
        folders.append(folder[-1])

    messages.relayMessage(
        'initialize_progress',
        {
            'message': (host1, host2),
            'progress': (1, len(folders))
        }
    )

    print('folders: ')
    pprint(folders)

    for fi, f in enumerate(folders):
        if not M2.folder_exists(f):
            M2.create_folder(f)

        M1.select_folder(f)

        uids = M1.search(['NOT', 'DELETED'])

        print('Found ' + str(len(uids)) + ' messages')

        for mi, m in enumerate(uids):
            message = M1.fetch(m, 'RFC822')
            message_body = message[m][b'RFC822']
            M2.append(f, message_body)

            messages.relayMessage(
                'update_progress',
                {
                    'message': (fi + 1, len(folders)),
                    'progress': (mi + 1, len(uids) + 1)
                }
            )

    M1.logout()
    M2.logout()

    messages.relayMessage(
        'finish_progress',
        {
            'message': (host1, host2),
            'progress': (0, 0)
        }
    )
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from __future__ import unicode_literals
import imapclient
from backports import ssl

HOST = 'imap.host.com'
USERNAME = '******'
PASSWORD = '******'

context = imapclient.create_default_context()

# don't check if certificate hostname doesn't match target hostname
context.check_hostname = False

# don't check if the certificate is trusted by a certificate authority
context.verify_mode = ssl.CERT_NONE

server = imapclient.IMAPClient(HOST,
                               use_uid=True,
                               ssl=True,
                               ssl_context=context)
server.login(USERNAME, PASSWORD)
# ...
Example #19
0
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from __future__ import unicode_literals
import imapclient

HOST = 'imap.host.com'
USERNAME = '******'
PASSWORD = '******'

context = imapclient.create_default_context(cafile="/path/to/cacert.pem")

server = imapclient.IMAPClient(HOST, use_uid=True, ssl=True, ssl_context=context)
server.login(USERNAME, PASSWORD)
# ...
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from __future__ import unicode_literals
import imapclient

HOST = 'imap.host.com'
USERNAME = '******'
PASSWORD = '******'

context = imapclient.create_default_context(cafile="/path/to/cacert.pem")

server = imapclient.IMAPClient(HOST,
                               use_uid=True,
                               ssl=True,
                               ssl_context=context)
server.login(USERNAME, PASSWORD)
# ...
Example #21
0
group.add_argument('-d', '--domain', action='store_true')
group.add_argument('-n', '--name', action='store_true')
group.add_argument('-s', '--subject', action='store_true')
parser.add_argument('folder')
args = parser.parse_args()

if args.address:
    make_key = utils.from_address
if args.domain:
    make_key = utils.from_domain
if args.name:
    make_key = utils.from_name
if args.subject:
    make_key = utils.from_subject

context = imapclient.create_default_context()
context.verify_mode = ssl.CERT_NONE
imap = imapclient.IMAPClient(host, ssl=True, ssl_context=context)
imap.login(username, password)
imap.select_folder(args.folder)
msgids = imap.search()
response = imap.fetch(msgids, ['BODY.PEEK[HEADER]'])
messages = []
for msgid in msgids:
    header = response[msgid]['BODY[HEADER]']
    message = email.message_from_string(header)
    messages.append(message)

counter = collections.Counter()
latest = collections.defaultdict(int)
for message in messages:
Example #22
0
def imapWatcher():
    """Watch our IMAP inbox. Periodically open mailbox, look for new messages, 
	parse content for submissions to send to Reddit, delete message.
	
	This function does not normally return.
	"""

    print('[imap] polling imap for new comments...')

    while True:

        context = imapclient.create_default_context()

        # don't check if certificate hostname doesn't match target hostname
        context.check_hostname = False

        # don't check if the certificate is trusted by a certificate authority
        context.verify_mode = ssl.CERT_NONE

        server = imapclient.IMAPClient(conf.imap['server'],
                                       use_uid=True,
                                       ssl=conf.imap['ssl'],
                                       ssl_context=context)
        server.login(conf.imap['username'], conf.imap['password'])

        select_info = server.select_folder('INBOX')
        # print(select_info)
        #print('%d messages in INBOX' % select_info['EXISTS'])

        #messages = server.search(['NOT', 'DELETED'])
        messages = server.search(['NOT', 'DELETED'])
        print("[imap] %d messages that aren't deleted" % len(messages))

        response = server.fetch(messages,
                                ['ENVELOPE', 'RFC822', 'FLAGS', 'RFC822.SIZE'])
        for msgid, data in response.items():
            envelope = data[b'ENVELOPE']
            raw_mail = data[b'RFC822']

            print("[imap] %s (%s)" % (msgid, envelope.to[0].mailbox))

            if envelope.to[0].mailbox == b'hermod-reg':
                # we're not doing this at the moment.
                r = reddit.getReddit()
                recipient = envelope.sender[0]
                to = "%s@%s" % (recipient.mailbox.decode('utf-8'),
                                recipient.host.decode('utf-8'))

                authUrl = r.auth.url(["identity","subscribe","mysubreddits","read","submit","edit","privatemessages"], \
                     to,'permanent',False)
                print("[imap] auth url: %s" % authUrl)
                sendAuthMail(to, authUrl)
                server.set_flags(msgid, (imapclient.DELETED))
                continue
            else:
                print('[imap] - processing comment submission -')
                msg = email.message_from_bytes(raw_mail)

                # figure out who sent it
                sender = envelope.sender[0]
                to = "%s@%s" % (sender.mailbox.decode('utf-8'),
                                sender.host.decode('utf-8'))

                # .. and find the right token
                tokens = util.readTokens()
                token = None
                for (t, a, o) in tokens:
                    if a == to:
                        token = t
                        break

                if token is None:
                    print('[imap] ERR: could not look up access token for %s' %
                          to)
                    print('[imap] submissions will not be delivered.')
                else:
                    print('[imap] using token %s' % token)

                body = ""
                # look for text
                if msg.is_multipart():
                    print("[imap] trouble: can't yet handle multipart message")
                    for part in msg.walk():
                        print("[imap]", part.get_content_type())
                        if part.get_content_type() == "text/plain":
                            body = part.get_payload(decode=True).decode(
                                part.get_content_charset(), 'ignore')
                            print("[imap] located text/plain part")
                        continue
                else:
                    body = msg.get_payload(decode=True).decode(
                        msg.get_content_charset(), 'ignore')

                # normalize CRLF
                body = re.sub("\r\n", "\n", body)
                # remove quoted-printable
                body = re.sub("\=\n", "", body)
                # split by newlines
                lines = body.split("\n")

                active = None
                response = ""
                for line in lines:
                    print("[imap] =>", active, line)
                    idmatch = re.search("\[\-\-(\w+_\w+)\-\-\]", line)

                    if idmatch is not None:
                        # send out previous response, if any
                        if active is not None:
                            reddit.sendResponse(active, response)
                        active = idmatch.group(1)
                        response = ""
                    elif line.strip().startswith("!subscribe"):
                        # TODO: find a way to mute this entire conversation
                        print("[imap] subscribing command: %s" % line)
                        parts = line.split(" ")
                        reddit.subscribe(None, token, parts[1])
                        util.restartThreads(token)
                    elif line.strip().startswith("!unsubscribe"):
                        # TODO: find a way to mute this entire conversation
                        print("[imap] unsubscribing command: %s" % line)
                        parts = line.split(" ")
                        reddit.unsubscribe(None, token, parts[1])
                        util.restartThreads(token)
                    elif line.strip().startswith("!mute"):
                        parts = line.split(" ")
                        print("[imap] muting %s" % parts[1])
                    elif not line.startswith(">"):
                        response = response + line.strip() + "\n"

                # send out last response we've been collecting
                if active is not None:
                    reddit.sendResponse(token, active, response)

                print("[imap] done, deleting message %s" % msgid)
                server.set_flags(msgid, (imapclient.DELETED))

        server.logout()
        # sleep for a while before checking again
        print("[imap] sleeping for 120 seconds")
        time.sleep(120)
Example #23
0
 def __init__(self):
     self.io = SocketIO('localhost', 8080)
     self.context = imapclient.create_default_context()
     self.context.check_hostname = False
     self.context.verify_mode = ssl.CERT_NONE