How get the IMAP server related to an email address - python

I would like to know if there exists a tool to get the IMAP server related to an email address.
For example, if I receive stack#hotmail.com, it should return: imap-mail.outlook.com. If I receive stack#outlook.com, it should also return: imap-mail.outlook.com
If no tool exists, I will create a little database with these informations.
Thank you.

here is a way to detect it, using a free api, u can pass your email as a parameter and it will return the imap server
def imapdetect(email):
with request.urlopen('https://emailsettings.firetrust.com/settings?q=' + email) as response:
if response.getcode() == 200:
source = response.read()
data = json.loads(source)
for i in range(0, len(data["settings"]) + 1):
if data["settings"][i]["protocol"] == "IMAP":
imapserver = data["settings"][i]["address"]
break
return imapserver

Related

python error login with imap even enabled from gmail

iam trying to use a imap with python but iam getting error every time, i followed all steps to active imap from gmail and unlock captcha but after the firt run iam getting this error pls help already thanks
raise self.error(dat[-1])
imaplib.error: b'[AUTHENTICATIONFAILED] Invalid credentials (Failure)'
after the gmail i got a Alerte security from gmail and all acces from imap is blocked
the code used `
# Importing libraries
import imaplib, email
user = 'USER_EMAIL_ADDRESS'
password = 'USER_PASSWORD'
imap_url = 'imap.gmail.com'
# Function to get email content part i.e its body part
def get_body(msg):
if msg.is_multipart():
return get_body(msg.get_payload(0))
else:
return msg.get_payload(None, True)
# Function to search for a key value pair
def search(key, value, con):
result, data = con.search(None, key, '"{}"'.format(value))
return data
# Function to get the list of emails under this label
def get_emails(result_bytes):
msgs = [] # all the email data are pushed inside an array
for num in result_bytes[0].split():
typ, data = con.fetch(num, '(RFC822)')
msgs.append(data)
return msgs
# this is done to make SSL connnection with GMAIL
con = imaplib.IMAP4_SSL(imap_url)
# logging the user in
con.login(user, password)
# calling function to check for email under this label
con.select('Inbox')
# fetching emails from this user "tu**h*****1#gmail.com"
msgs = get_emails(search('FROM', 'MY_ANOTHER_GMAIL_ADDRESS', con))
# Uncomment this to see what actually comes as data
# print(msgs)
# Finding the required content from our msgs
# User can make custom changes in this part to
# fetch the required content he / she needs
# printing them by the order they are displayed in your gmail
for msg in msgs[::-1]:
for sent in msg:
if type(sent) is tuple:
# encoding set as utf-8
content = str(sent[1], 'utf-8')
data = str(content)
# Handling errors related to unicodenecode
try:
indexstart = data.find("ltr")
data2 = data[indexstart + 5: len(data)]
indexend = data2.find("</div>")
# printtng the required content which we need
# to extract from our email i.e our body
print(data2[0: indexend])
except UnicodeEncodeError as e:
pass
'
If you are running this on a cloud host or the like, this will likely never work without implementing OAuth authentication (or maybe app specific passwords).
Google's account security appears to be set up to only allow logins from likely end-user hosts. If you're running it on your personal machine (that you also log in from), you will have to activate the reduced security setting, generate an app specific password, or implement OAuth.

Interaction between Python IMAPClient library and email package

I have a Django project where I am working on an email client. I've decided to use python's IMAPClient instead of standard library's imaplib for getting access to the messages. Currently, I don't make use of python's email package to encode/decode responses received from IMAPClient, and I have a feeling that I manually implement things that should be handled by email.
Example code for downloading attachment:
def download_attachment(server, msgid, index, encoding):
# index and encoding is known from previous analysis of bodystructure
file_content = f_fetch(server, msgid, index)
# the below code should be handled by email's message_from_bytes
# and subsequent get_payload(decode = True) function
if encoding == 'base64':
file_content = base64.b64decode(file_content)
elif ...
...
endif
#writing file_content to a folder
return
def f_fetch(server, msgid, index):
if not index:
index = '1'
response = server.fetch(msgid, 'BODY[' + index + ']')
key = ('BODY[' + index + ']').encode('utf-8')
if type(msgid) is str:
msgid = int(msgid)
return response[msgid][key]
So the question is, how should I rewrite this code to make use of email.
Specifically, what should I do with the response from IMAPClient to pass it to email's message_from_bytes() function?
If you wish to parse an email using the email package's message_from_bytes() function then you need to give it the entire, raw email body. To get this, fetch using the RFC822 selector like this:
fetch_data = server.fetch(msgid, ['RFC822'])
parsed = email.message_from_bytes(fetch_data[msgid][b'RFC822'])
If you're pulling individual message parts/attachments from the IMAP server, then the server is effectively doing the parsing work for you and you don't need to use the email package's parser.

unable to retrieve tornado secure cookie

for some reason I'm unable to retrieve a secure cookie I've set with tornado. Using firebug I can see the cookie and it's expiration date, but when I try to print or retrieve it, it keeps coming up as None. Is there some way I'm invalidating it that I can't see. This is the code I'm using:
class loginHandler(tornado.web.RequestHandler):
def post(self):
# first type of request made to this page is a post
userEmail = self.get_argument("username")
password = self.get_argument("password")
deviceType = self.get_argument("deviceType")
# get some info from the client header
userIp = self.request.headers['X-Real-Ip']
userAgentInfo = self.request.headers['User-Agent']
result = pumpkinsdb.loginUser(userEmail, password, deviceType, userIp, userAgentInfo)
if result == None:
self.redirect("/")
else:
fullname = pumpkinsdb.pumpkinsdb_user['fullName']
this_page_title = fullname if fullname else pumpkinsdb.pumpkinsdb_user['userEmail']
# successful login set up user's cookies
# self.set_secure_cookie("memberId", str(user['memberId']), expires_days=0.1, secure=True, httponly=True)
self.set_secure_cookie("memberId", str(pumpkinsdb.pumpkinsdb_user['memberId']))
self.write(str(self.get_secure_cookie("memberId")))
time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print "{} [{}::get] pid[{}] login requested for user: [{}] from [{}] using [{}]".format(
time_now, self.__class__.__name__, os.getpid(), pumpkinsdb.pumpkinsdb_user['emailAddress'],
pumpkinsdb.pumpkinsdb_user['userIp'], pumpkinsdb.pumpkinsdb_user['userAgentInfo'])
self.render('calendar.html', title = this_page_title)
def get(self):
validSession = self.get_secure_cookie("memberId")
if validSession:
this_page_title = pumpkinsdb.pumpkinsdb_user['fullName']
self.render('calendar.html', title = this_page_title)
else:
print self.get_secure_cookie("memberId")
self.write(str(validSession))
Is your cookie secret changing somehow when you restart the server? If the cookie secret changes, all existing cookies are invalidated. Note that even though the cookie secret should be randomly generated, this doesn't mean you should have something like cookie_secret=os.urandom(16) in your code, because that will generate a new secret every time. Instead, you need to call os.urandom once and save its output somewhere (keep it safe and private, like your TLS keys).
so basically the problem was I had four tornado processes running behind nginx and for each tornado process I generated a unique random string with:
cookie_secret = base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
obviously that was my problem because each tornado process had a different secret so when i tried to read it tornado thought it was invalid.
The key is to generate a unique random string but then store it somewhere secure such as in your options:
define(cookie_secret, "934893012jer9834jkkx;#$592920231####")
or whatever string you deem fit.
Thank you to everyone that responded. sorry about that.

how to sign request tokens?

I am currently trying to write a script to send off a request token, I have the header, and the claimset, but I don't understand the signature! OAuth requires my private key to be encrypted with SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function), but the closest I could find was RSAES-PKCS1-v1_5 (has RSA, and the SHA-256 hash). I followed the example, and tweaked it, so I could get it set, but heres my dillema:
signature = ""
h = SHA.new (signature)
key = RSA.importKey(open('C:\Users\Documents\Library\KEY\My Project 905320c6324f.json').read())
cipher = PKCS1_v1_5.new(key)
ciphertext = cipher.encrypt(message+h.digest())
print(ciphertext)
I'm a bit lost, the JSON file I was given has both public key, and private, do I copy and paste the private key into the signature variable (it gave me a invalid syntax)? Or do I past the directory again? I am so lost, and way over my head haha. I am currently running Python 3.4, with pyCrypto for the signature.
Based on what you've said below about wanting to write a command system using gmail, I wrote a simple script to do this using IMAP. I think this is probably simpler than trying to use Google APIs for a single user, unless you were wanting to do that simply for the exercise.
import imaplib, logging
from time import sleep
USERNAME = 'YOUR_USERNAME_HERE' # For gmail, this is your full email address.
PASSWORD = 'YOUR_PASSWORD_HERE'
CHECK_DELAY = 60 # In seconds
LOGGING_FORMAT = '%(asctime)s %(message)s'
logging.basicConfig(filename='imapTest.log', format=LOGGING_FORMAT, level=logging.INFO)
logging.info("Connecting to IMAP server...")
imap = imaplib.IMAP4_SSL('imap.gmail.com')
imap.login(USERNAME, PASSWORD)
logging.info("Connected to IMAP server.")
def get_command_messages():
logging.info("Checking for new commands.")
imap.check()
# Search the inbox (server-side) for messages containing the subject 'COMMAND' and which are from you.
# Substitute USERNAME below for the sending email address if it differs.
typ, data = imap.search(None, '(FROM "%s" SUBJECT "COMMAND")' %(USERNAME))
return data[0]
def delete_messages(message_nums):
logging.info("Deleting old commands.")
for message in message_nums.split():
imap.store(message, '+FLAGS', '\\DELETED')
imap.expunge()
# Select the inbox
imap.select()
# Delete any messages left over that match commands, so we are starting 'clean'.
# This probably isn't the nicest way to do this, but saves checking the DATE header.
message_nums = get_command_messages()
delete_messages(message_nums)
try:
while True:
sleep(CHECK_DELAY)
# Get the message body and sent time. Use BODY.PEEK instead of BODY if you don't want to mark the message as read, but we're deleting it anyway below.
message_nums = get_command_messages()
if message_nums:
# search returns space-separated message IDs, but we need them comma-separated for fetch.
typ, messages = imap.fetch(message_nums.replace(' ', ','), '(BODY[TEXT])')
logging.info("Found %d commands" %(len(messages[0])))
for message in messages[0]:
# You now have the message body in the message variable.
# From here, you can check against it to perform commands, e.g:
if 'shutdown' in message:
print("I got a shutdown command!")
# Do stuff
delete_messages(message_nums)
finally:
try:
imap.close()
except:
pass
imap.logout()
If you're set on using the Gmail API, though, Google strongly encourage you to use their existing Python library rather than attempt to do full authentication etc. yourself as you appear to be. With that, it should - more or less - be a case of replacing the imap calls above with the relevant Gmail API ones.

imaplib.error: command FETCH illegal in state AUTH

I'm trying to download attachments from Gmail, using a combination of pieces of code I found online, and some editing from myself. However, the following code:
import email, getpass, imaplib, os, random, time
import oauth2 as oauth
import oauth2.clients.imap as imaplib
MY_EMAIL = 'example#gmail.com'
MY_TOKEN = "token"
MY_SECRET = "secret"
consumer = oauth.Consumer('anonymous', 'anonymous')
token = oauth.Token(MY_TOKEN, MY_SECRET)
url = "https://mail.google.com/mail/b/"+MY_EMAIL+"/imap/"
m = imaplib.IMAP4_SSL('imap.gmail.com')
m.authenticate(url, consumer, token)
m.select('INBOX')
items = m.select("UNSEEN");
items = items[0].split()
for emailid in items:
data = m.fetch(emailid, "(RFC822)")
returns this error:
imaplib.error: command FETCH illegal
in state AUTH
Why would Fetch be illegal while I'm authorized?
You're lacking error checking on your calls to select. Typically, this is how I'll structure the first parts of a connection to a mailbox:
# self.conn is an instance of IMAP4 connected to my server.
status, msgs = self.conn.select('INBOX')
if status != 'OK':
return # could be break, or continue, depending on surrounding code.
msgs = int(msgs[0])
Essentially, the trouble you're encountering is that you've selected a mailbox that doesn't exist, your status message is probably not "OK" as it should be, and the value you're iterating over isn't valid. Remember, select expects a mailbox name. It does not search based on a flag (which may be what you're attempting with "UNSEEN"). When you select a non-existent mail box you actually get this as a response:
('NO', ['The requested item could not be found.'])
In which case, for email id in items is not operating properly. Not what you're after in any way, unfortunately. What you'd get on a valid mailbox would be like this:
('OK', ['337'])
Hope that helps.
To address the question in comments, if you want to actually retrieve the unseen messages in the mailbox you'd use this:
status, msgs = self.conn.select('INBOX')
# returns ('OK', ['336'])
status, ids = self.conn.search(None, 'UNSEEN')
# returns ('OK', ['324 325 326 336'])
if status == 'OK':
ids = map(int, ids[0].split())
The response is going to be similar to the response from select, but instead of a single integer for the number of messages you'll get a list of ids.
Why would Fetch be illegal while I'm authorized?
IMAP has a state concept.
You can only fetch messages if you have selected a folder.
Here is a nice picture which shows this:
Image source: http://www.tcpipguide.com/free/t_IMAP4GeneralOperationClientServerCommunicationandS-2.htm

Categories