I'm working about an email manager that can manage more than one mailboxes.
This is my scenario: I get the mails by a mailbox and I store their properties in a database, uid included. The mailbox can be configured to be downloaded with imap or pop3 protocol, it depends on the mailbox itself.
POP3 uids: 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.
IMAP uids: 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.
So, it is almost impossible to find two equal POP3 uids, although between different mailboxes. But is more likely to happen with IMAP uids.
So, I need the certainty that the uids are all different.
I don't need the code to do it, I need only to know if it is possible to do it, and how to do it, the need for a correct reasoning do.
The POP3 standard does not guarantee the UIDs to be unique -- you can see different messages with a common UID.
IMAP has no persistent UIDs which would work in the way you want them to work. The UIDs are guaranteed to be unique within a single mailbox, but under certain circumstances they might get changed (see RFC 3501 and the UIDVALIDITY response). In short, the only guarantee that IMAP provides is that a triplet of (mailbox name, UIDVALIDITY, UID) will ever refer to a single message, no matter what happens. This is useful for e.g. caching message parts, because they are guaranteed to be immutable. Please take care to realize that this does not mean that a single message will be always assigned the same triplet -- not at all, even if it remains in the same mailbox.
There are non-standard extensions which attempt to provide some kind of a GUID for you, but these differ between the IMAP server implementations and are not available everywhere.
Related
I'm reading RFC 7162, trying to figure out how a client should behave when communicating with a server that supports CONDSTORE but not QRESYNC.
The initial connection case is simple enough: the client compares its cached modseq value with the HIGHESTMODSEQ response to the SELECT command, and if it is lower, the client can retrieve any changes with FETCH + CHANGEDSINCE or SEARCH + MODSEQ. After doing that, the client can store the HIGHESTMODSEQ value as its new cached modseq value for the mailbox.
However, if the client receives unsolicited FETCH responses while the mailbox is selected, can it draw any reliable conclusions from the MODSEQ attributes in these updates? Would it be safe to cache the highest seen MODSEQ value, or would the client risk missing any updates to the mailbox state in doing so?
This is tricky.
The question probably refers to a language in RFC7162 which clarifies that HIGHESTMODSEQ and MODSEQ are two different beasts, and that a FETCH MODSEQ might arrive while a server is forced to withdraw some EXPUNGEs, maybe because the client sent a command which uses MSNs (see motivation in chapter 3.2).
In this particular case where the server is said to only support CONDSTORE and not QRESYNC, the MODSEQ and HIGHESTMODSEQ are only used for keeping track of metadata changes (such as FLAGS updates). They do not have to change on message expunges. The situation which the RFC is trying to prevent because of QRESYNC therefore can happen without any fatal consequences as you as a client cannot use HIGHESTMODSEQ for any other purpose but FLAGS updates. Based on that, I don't see a reason why a client shouldn't bump HIGHESTMODSEQ on a CONDSTORE-only server upon seeing a MODSEQ.
You should probably ask on the imap-protocol mailing list and seek clarification. I, too, have an open bug about how to deal with this properly, and the RFC is not completely clear to me.
I need to check email accounts whether exists or not, I need to do that using Delphi and Indy (if possible)
I have a windows database for ERP system and I need to make sure that the customer enter valid email into the system so I can send to my customer the quotes they request.
I tried to test on yahoo and google using send commands HELO, MAIL and RCPT but no success.
Mail servers have to protect themselves against spammers and others with malicious intent. They are not going to give up their secrets easily. It is common for mail servers to be configured to black hole messages sent to non-existent recipients. They don't respond to the sender saying, "sorry, that user doesn't exist, please try again."
So, if you want to verify whether or not an e-mail address has a human behind it I think the only way to be sure is to send an e-mail requesting a response.
You have to ask your customers to confirm their email address, i.e. entering it twice to reduce misspellings, asking to register and sending an activation link and so on. State explicitly they need a valid email address: if they're asking you a quote why should they enter an invalid address? But be aware some people may use disposable email addresses to protect their real ones.
You have no way to check if an address really exists just asking its server. Due to the large amount of spam and techniques implemented by spammer to harvest and clean their addresses lists, most servers are setup to defend themselves.
That's why I suggested to "be polite". I am sorry if you got it the wrong way, I was just telling you that if your application shows a "spammer-like" behaviour (and your previous version of the question was much unclearer about your aims), it can lead to your IPs being blacklisted. Then you can have much more troubles to send quotes to customers.
You may try ICS components, an open source library with good examples (see SMTPClient).
So this library or another one will not tell you if an email account exists or not because it's depending on the way the host answer to the commands about a non existent account.
In ICS, when the command have been sent you may have to manage an event : SmtpRequestDone(Sender: TObject; RqType: TSmtpRequest;ErrorCode: Word);
Where ErrorCode is the Error code (ie 550).
I'm interested in creating a challenge / response type process in Delphi. The scenario is this...we have 2 computers...1 belongs to the user and 1 belongs to a support technician.
The user is locked out of a certain program, and in order to gain 1 time access, I want:
The user to be presented with a challenge phrase, such as "28394LDJA9281DHQ" or some type of reasonably unique value
The user will call support staff and read this challenge (after the support staff has validated their identity)
The support person will type this challenge value into a program on their system which will generate a response, something equally as unique as the response, such as "9232KLSDF92SD"
The user types in the response and the program determines whether or not this is a valid response.
If it is, the user is granted 1 time access to the application.
Now, how to do this is my question? I will have 2 applications that will not have networked access to one another. Is there any functionality within Windows that can help me with this task?
I believe that I can use some functionality within CryptoAPI, but I really am not certain where to begin. I'd appreciate any help you could offer.
I would implement a MD5 based Challenge-Response authentication.
From wikipedia http://en.wikipedia.org/wiki/CRAM-MD5
Protocol
Challenge: In CRAM-MD5 authentication, the server first sends
a challenge string to the client.
Response: The client responds with a username followed by a space
character and then a 16-byte digest in
hexadecimal notation. The digest is
the output of HMAC-MD5 with the user's
password as the secret key, and the
server's original challenge as the
message.
Comparison: The server uses the same method to compute the expected
response. If the given response and
the expected response match then
authentication was successful.
This provides three important types of
security.
First, others cannot duplicate the hash without knowing the password.
This provides authentication.
Second, others cannot replay the hash—it is dependent on the
unpredictable challenge. This is
variously called freshness or replay
prevention.
Third, observers do not learn the password. This is called secrecy.
The two important features of this
protocol that provide these three
security benefits are the one-way hash
and the fresh random challenge.
Additionally, you may add some application-identification into the challenge string, for a double check on the sender of the challenge.
Important: it has some weaknesses, evaluate carefully how they may affect you.
Regarding the verbal challenge/response strategy: We used this approach to license a niche application on five thousand workstations world-wide for more than ten years. Our support team called it the "Missile Launch Codes" because of its similarity to the classic missile launch authentication process seen on old movies.
This is an extremely time consuming way to protect your program. It consumed enormous amounts of our staffs' and customers' time reading the codes to and from users. They all hated it.
Your situation/context may be different. Perhaps you won't be using it nearly as frequently as we did. But here are some suggestions:
Carefully consider the length and contents of the code: most users (and support staff) resent typing lots of characters. Many users are bad typists. Consider whether a long string and including punctuation marks and case sensitivity unduly burdens them compared to the amount of security added.
After years of using a verbal challenge/response implementation, we left it in place (as a fall-back) but added a simple automated system. We chose to use FTP rather than a more sophisticated web approach so that we didn't have to have any software running on our in-house server (or deal with our IT staff!)
Basically, we use FTP files to do the exchange that was previously done on the phone. The server places a file on the FTP server containing the challenge phrase. The file's name is the customer's name. Our support staff have a program that automatically creates this file on our ftp site.
The customer is instructed by our staff to hit a hot key that reads the FTP file, authenticates it, and places a response file back on the server.
Our support staffs' software has been polling waiting for the customer's software to create the response file. When it sees the file, it downloads it and confirms its contents, and deletes it from the server.
You can of course have this exchange happen as many times and in either direction as you need in a given session in order to accomplish your goals.
The data in the files can have the same MD5 keys that you would use verbally, so that it is as secure as you'd like.
A weakness in this system is that the user has to have FTP access. We've found that the majority of our users (all businesses) have FTP access available. (Of course, your customer base may not...) If our application in the field is unable to access our FTP site, it clearly announces the problem so that our customer can go to their IT staff to request that they open the access. Meanwhile, we just fall back to the verbal codes.
We used the plain vanilla Indy FTP tools with no problem.
No doubt there are some weaknesses in this approach (probably including some that we haven't thought of.) But, for our needs, it has been fantastic. Our support staff and customers love it.
Sorry if none of this is relevant to you. Hope this helps you some.
I would like to create an email client that can access multiple IMAP mailboxes. I'd also like a copy of all emails for processing. What is the best way to do this using IMAP commands?
Right now I have a script that iterates over the folders, FETCHing FLAGS on 1:* to see what's been read and if any previously read messages have been marked as new, then FETCH BODY.PEEK on all of the messages I don't have in my database. Is there a better way?
A better way would be to fetch UIDs of all messages (UID FETCH 1:* FLAGS), compare the resulting UID list with your database and then download any messages you don't have and remove any messages you have but the server doesn't (deleted by other IMAP clients or using a web interface, for example). This is the only reliable method to duplicate an IMAP folder, AFAIK.
(And don't forget to take UIDVALIDITY into account as well!)
Your original method would not work correctly if other IMAP clients were accessing the mailbox in addition to your application. In theory, it would work OK if you can stay connected to the IMAP server continuously, using NOOP and IDLE to check new and deleted messages, but this is never possible in practice - even GMail doesn't have 100% uptime :-)
An ultimate IMAP client would combine both these approaches.
I am writing a client application that fetches emails from an IMAP server and then stores them in a database. The problem is that once I have checked the mail, the next time I only want to download the mail that has arrived since. So if I had checked the server for mail two hour ago, I only want to get the mail that has arrived in the last two hours.
I could use SEARCH with SINCE DATE, but there's no support for time + date could be easily spoofed.
I also tried the RECENT flag, but that doesn't seem to work with gmail (in ruby it shows nil everytime).
You want to use the UniqueId (UID) for the messages. This is specifically why it was created.
You will want to keep track of the last UID requested, and then, to request all new messages you use the message set "[UID]:*", where [UID] is the actual UID value.
For example, lets say the last message feteched had a unique id of "123456". You would fetch
123456:*
Then, discard the first returned message.
UIDs are 'supposed' to be stable across sessions, and never change, and always increase in value. The catch to verify this, is to check the UIDValidity when you select the folder. If the UIDValidity number hasn't changed, then the UIDs should still be valid across sessions.
Here are the relevant parts from the RFC:
2.3.1.1. Unique Identifier (UID) Message Attribute
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. Unique identifiers
are assigned in a strictly ascending fashion in the mailbox; as each
message is added to the mailbox it is assigned a higher UID than the
message(s) which were added previously. Unlike message sequence
numbers, unique identifiers are not necessarily contiguous.
The unique identifier of a message MUST NOT change during the
session, and SHOULD NOT change between sessions. Any change of
unique identifiers between sessions MUST be detectable using the
UIDVALIDITY mechanism discussed below. Persistent unique identifiers
are required for a client to resynchronize its state from a previous
session with the server (e.g., disconnected or offline access
clients); this is discussed further in [IMAP-DISC].
Note: The next unique identifier value is intended to
provide a means for a client to determine whether any
messages have been delivered to the mailbox since the
previous time it checked this value.
Here is the link with more info:
http://www.faqs.org/rfcs/rfc3501.html
What I would do, is also keep track of the InternalDate of the messages downloaded. This way, if you ever lose UID sync, you can at least iterate through the messages, and find the last one you downloaded, based upon the InternalDate of the message.
There's an imap flag called "seen". Most clients would mark a message seen when viewing the message, so you'd want to iterate over messages on the server which do not have that flag set.
Here's a code snippet which should give you the right idea. The operative bit of course is
imap.search(["NOT", "SEEN"]).each do bla.bla.bla
If you are you able to filter incoming mail into a specific IMAP folder on the server side, your app
can read new messages in that folder and then move them into the standard INBOX folder after it's done.