I'm working in a mail client project using C#. I'm using both the POP and IMAP protocol to communicate with the server. The problem is than I can not figure out why when I want to get the UID for a message the result from the POP server and the IMAP server are different.
POP
C: UIDL 1
S: +OK 1 UID2-1269789826
and
IMAP
C: $ FETCH 1 (UID)
S: * 1 FETCH (UID 2)
S: $ OK Fetch completed.
Why the result for obtaining the UID is so different? In IMAP is another function for this?
Any help is welcome.
Thanks.
POP3 and IMAP are two distinct protocols. The UIDs used by these two protocols are not related and are not supposed to be the same at all. In fact, a POP3 UID is an arbitrary string while an IMAP UID is a 32-bit number (transmitted as string).
In theory, it is possible to write a mailserver that supports both IMAP and POP3 use the same UID for both protocols, but I'm not aware of any server that would actually do this. In practice, you have to treat POP3 UIDs and IMAP UIDs as unrelated values.
RFC 1939 (POP3):
The unique-id of a message is an arbitrary server-determined string, consisting of one to 70 characters in the range 0x21 to 0x7E, which uniquely identifies a message within a maildrop and which persists across sessions.
RFC 3501 (IMAP):
(Unique Identifier (UID) Message Attribute is) a 32-bit value assigned to each message, which when used with the unique identifier validity value (see below) forms a 64-bit value that MUST NOT refer to any other message in the mailbox or any subsequent mailbox with the same name forever.
Very important IMAP fact
This is what I learnt playing with GMail (I expect other systems to be the same):
Sent a message to my inbox
It has UID 45
Move the message to junk
It now has UID 5 (because UID is unique per mailbox)
Move it back to inbox
It now has UID 46
Move it back to junk
It now has UID 6
Get the idea...
I moved the messages using the GMail.com UI
As far as I can tell UID is only useful in finding the latest emails in a folder. You can run the command Search("UID 34:*) to get all messages in a folder with UID 34 or above.
But don't start using UID as a key to that message in a database or you'll end up with dupes.
I think I'm going to take the time received and hash it with the message contents to get a UID I can actually put into a database.
Related
Is there a way to fetch only the new emails from the mail server (e.g. when you store the fetched emails locally) instead of fetching all of them?
I guess I could fetch emails in bunches of 5 and compare, for example, the hash of the last email (or its Uid from Pop3Client.GetMessageUid()) to the hash of the fetched emails, but I am not sure if this is the best and most reliable way. I think this will be a waste of bandwidth or bombarding the server with multiple requests.
Does the protocol allow specifying a point in time (using date, last email hash or whatever), after which it should return the emails?
Currently, I am using OpenPop.NET's OpenPop.Pop3.Pop3Client.
EDIT
I have found an example here:
http://hpop.sourceforge.net/exampleDownloadUnread.php
Although it doesn't suit my needs 100% (because it fetched ALL UIDs which may be too many) it is a good starting point.
Basically, what I want to do is what this IMAP sample does by comparing UIDs:
http://www.limilabs.com/blog/get-new-emails-using-imap
EDIT 2
I have found this similar question, but it also suggest the approach that retrieves ALL UIDs:
How to retrieve only new emails using POP3 protocol
You'll need to download all of the UIDs no matter what you do because you'll need to compare them to what you've already downloaded (in some sort of UID log) as well as having the UIDs of the new messages so that you can log them to compare against the next time you connect.
It should be noted, however, that not all POP3 servers support the UIDL command (it is an extension, after all), so if your code is meant to be used with a variety of POP3 servers, it will have to deal with that. How you deal with it is up to you, but I believe that my approach in the past has been to md5sum a collection of headers (although not all of them, because some POP3 servers might add or modify headers such as X-Status or Status or some custom header). You can probably get away with just hashing the Received headers.
I want to send email message with smtp/imap and check for reply after a while.
So I am looking for an open source library which provide an API for sending email and check for replies later.
As far as I understand, Every message already contains unique ID and I see a lot of libraries allowing to download message by ID. but none of the SMTP clients that I saw returning this ID when sending emails.
This kind of API is helpful (S22.Imap):
using (ImapClient Client = new ImapClient("imap.gmail.com", 993,
"username", "password", AuthMethod.Login, true))
{
uids = GetUIdsFromMyDatabase();//how can that be achieved?
IEnumerable<MailMessage> messages = Client.GetMessages(uids);
}
But it leaves 2 questions opened:
1. Where can I get the sent message ID?
2. How can I connect between reply and its parent (sent one)?
SMTP clients can make a Message-ID themselves. They just have to be sure that the left-hand-side is sort of unique.
If the client doesn't make an ID the SMTP server will, but it will not tell the SMTP client what the ID is. One easy and safe way is to feed the message you're about to send (the entire message) through an MD5 or SHA1 hash, base64-encode the result and make an ID of the form <hash#doma.in> where hash is the base64'd hash and doma.in is the From field's domain.
The conventional way to connect replies is to use Message-ID and References. When you send a reply, you set your References to be concatenation of the original message's References and Message-ID fields.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to check if an email address exists without sending an email?
Hi All,
I have a email functionality in my asp.net Web Application, Email Addresses are taken from a database. Is it possible to check whether E-Mail address really exists OR not. How can I do it ?.. I have searched in forums and Google got some related info which says using VRFY, RCPT Commands... but I didn't understand how can those commands be used in .NET using C#.. There are some third party tools but my client will not buy those tools..
I have SMTP mail server details,, ?? Is there any way this can be achieved ?
The only way is to open an SMTP connection and first try the VRFY, if this results in no, it does not exist, BUT if it is Yes it might only be that the server do not tell so the second step is to send the commands to send an email but after RCPT TO you abort, do not send the data command as some servers might actually send the email then even if you abort.
If it does not protest after RCPT TO you might as well try to send for real because that will then be the only way to test further, but some servers will accept the address and only fail later or even fail with a return message that will not be detected in the SMTP session at all.
So you cannot 100 % test an email without actually sending to the address and have the recipient either return the email to you or click a link to confirm the address.
I know it is possible to send an email with a fake address to impersonate someone else. I seen automated emails coming from my friend email address that he sent to me but did not write himself.
I know email servers ask the email provider if they really sent the message and if it is no it tends to go into spam or is marked untrusted. How do i access this data in my app? I havent chosen an imap library and thats because i dont know which may support this.
This functionality is not supported by imap.
Some servers store information like this in the header of the mail (like spamassassin info or SPF checks) so that is available with any imap library but depends highly on the mail server the app is connecting to.
In general it's not possible with IMAP. IMAP is intended for reading email, not for sending. You may try to fake email sender when sending email via SMTP protocol.
This is exactly what spam senders do (and what mail servers tries to detected).
It used to easy. SMTP dialog follows:
S: MAIL FROM:<your.friend#example.com>
R: 250 OK
S: RCPT TO:<somene#example.com>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: <CRLF>.<CRLF>
R: 250 OK
But now things are getting more interesting. There is still race of arms between those two - for example:
Attack
Try to submit false "FROM:" address during communication with SMTP server.
Defense: SMTP server may require you to authenticate and allow only 'from' address associated with your account.
Another attack
Try to use third party SMTP server that has no such rule.
Defense (third party SMTP server): Allow sending only emails with 'from' domains matches with 'own' domains.
Defense (recipient's SMTP server): Add SPF record to your domain. This records includes all hosts that are allowed to send email with sender in this domain. If the email is sent from not allowed host increase it's spam score or delete it.
Another attack
Infect computer which is allowed to send email for specified domain with virus and send emails using it.
Defense: Educate users and/or use good antivirus.
And so on... There will be always ways how to fake sender's email address and how to fake it. Check following links for more info:
RFC 821 - SMTP
So You'd Like to Send Some Email (Through Code)
Im writing a tool c# (and System.Net.Mail) which will be sending around 4000 emails fornigtly.
Can i simply loop through a list of 4000 email addresses and send emails one at a time?
or will this cause any potential problems?
Is there a better way to do this?
Thanks
First of all you must have rDNS record that will map IP address back to domain name. Without it mail services like GMail will hold your e-mails for hours or even days. Furthermore you may become blacklisted after few dozens of letters. rDNS usually can be set using hoster's control panel or by support request.
Second, don't be tempted to use your ISP's or GMail's SMTP servers. You will quickly run out of daily quota. It is usually not allowed to send more than few dozens letters (50 for GMail AFAIK). So either send mail from your own server, or use a 3rd party service like auth smtp.
Such services are useful also if you're unable to set rDNS for some reason.
P.S. If the content of your letters is OK (i.e. they are not spam actually) and rDNS/SMTP are set correctly, you can send at any rate, without pauses.
Provided you don;t break any server limitations, such as memory or disk space, technically there is no issue. However you will run into problems with with ISP's and mail forwarders who may block your domains for spam - rightly or wrongly..
You could send the 4000 emails in one go, but you do run the risk of getting marked very quickly as a spammer.
Your best option is to 'burst send' so send maybe 100 straight away, in 10mins send another 100 etc.
If you do it this way your are less likely to be seen as a spammer.
Check that the machine sending the mails has a valid PTR record - i.e., if you're sending from www.example.com with IP 1.2.3.4, that a PTR query on 1.2.3.4 will return www.example.com; I'd look into SPF and DKIM, too.
Some e-mail hosts have an incoming rate limit (e.g. Hotmail used that in the past) - "if you are sending us more than x emails/minute, you get a higher spam score". I had a script to "stir the queue", so that the per-minute rate to a single server was lowered.
Also, check this - it has plenty of good advice on e-mail content, but that's slightly off-topic.
In addition to what has been mentioned above, be sure to set up adequate logging.
I.e. you should log sent emails so if you need re-send emails you can be sure not to send duplicates.
Also, you can set up an app to log bounced emails and use this to remove addresses etc.
You can of course write your own software or purchase some.
http://www.quiksoft.com/bouncebuster/