I would like to propose an alternative method of user authentication via posted emails that uses many mail servers' virtual hosting facilities. Due to limitations listed below, this would be merely an option, as opposed to a replacement, for the current authentication scheme.
Here's the problem:
It's fairly easy to trick a mail server into thinking an email came from one user, when in fact, it came from another one (they are easily spoofed). Some email clients do not support the password: secret syntax that the regular Commands syntax supports or it is very inconvenient (such as mobile devices, publishing feeds, etc). I would like to still offer pass phrase authentication for these users who post via email. This pass phrase could be different from a regular login pass phrase and stored with a user's profile. The benefit to having separate password/pass phrase values would be that you could change one without it affecting the other. Posting your login password via email is not very secure, hence the secondary pass phrase notion.
A solution:
Many email servers offer a means of passing in additional data using the recipient's email address. A simple example would be a catch-all domain address that all collects into a single mailbox (passphrase_data@drupal_post.example.com). Others have schemes such as post_mailbox:passphrase_data@example.com, where there's a real mailbox named 'post_mailbox' and the routing component of the mail server ignores everything between the colon and the '@'. The From: header would still be used to identify the user, but the added pass phrase validation would be in place.
What would this add to mailhandler?
It would add greater flexibility to the secure posting method.
It would keep your login password less accessible to hackers.
It would restrict hijacked identities (via spoofed From: addresses) and people posting unauthorized content to an account.
It would allow a user to add a secure posting address to an address book without having to edit the textual part of the body every time (or at all).
What would need to be done to implement this scheme?
Site admins would need access to an email server with some sort of globbing functionality as described above.
User profile would need to collect a separate passphrase to use for authentication.
Mailhandler would need to know how to parse the To: header to retrieve the passphrase from it. Maybe define a regexp for this? /([^@]+)@example.com/ for example.
Mailhandler would need to validate the passphrase against the user profiles's passphrase value.
| Comment | File | Size | Author |
|---|---|---|---|
| #42 | mailhandler-11962-42.patch | 16.43 KB | Ian Ward |
| #41 | mailhandler-11962-41.patch | 13.45 KB | Ian Ward |
| #38 | 11962_authentication_mailhandler.patch | 9.75 KB | meba |
| #29 | mailhandler_toauthentication.tgz | 1.98 KB | j0rd |
| #26 | mailhandler.patch | 7.96 KB | PGiro |
Comments
Comment #1
moshe weitzman commentedi recognize the problem that we are trying to solve, and agree that it is worth solving. but the proposed solution adds quite a bit of complexity for the admin and for the user. lets try to find a simpler solution. if we can't then the proposed solution is acceptable.
Comment #2
javanaut commentedI've given this a bit of consideration, and for my own goals for mailhandler, I don't see another way around it. I am open to suggestions on an easier way to accomplish this, though. As far as added complexity for admins and users...
Admins:
Would need more than just basic email server admin skills. We could offer documentation about this for several popular mail servers.
Might need some understanding of regular expressions (unless very well documented with examples or we provide some wrapper code to do the dirty work).
Users:
Would have an additional user profile field to update (passphrase).
Would have to coordinate all sources of email (desktop mail clients, phone address books, mailing lists, etc) with this passphrase.
I also realize that a big piece of complexity is having users/admins understand how it all works together. The education challenge for the average person would be, IMO, our biggest challenge.
Should I/we post this to drupal_dev mailing list for more feedback? I'm not sure how many of the developers there use mailhandler, but I do agree that finding a simpler solution would be worth the effort, and I'm fresh out of ideas at the moment :)
Comment #3
moshe weitzman commentedWhat is the likelihood that an Admin's mail priovider already supports this email address capability. For example, if I host with pair.com or rackspace or phpwebhosting or dreamhost, do I already have this feature. It seems unlikely that I could convince one of these hosting companies to provide these special features. I don't think many Drupal admins control their mail server.
I suppose that emailing a confirmation message back to the author is too cumbersome for moblog posting? This is standard for mailman lists and so forth.
Authentication via email sucks.
Comment #4
moshe weitzman commentedHmm. I didn't mean to sound so pessimistic in my last post. I want this feature, and will likely commit it if a patch appears.
Javanaut - perhaps you could writeup some docs about how to configure a mail server for this feature? also helpful might be a list of email providers known to support this.
Javanaut - you are welcome to become Maintainer of this module. Let me know.
Comment #5
javanaut commentedI guess I was under the impression that many users had wildcard email addresses. This seems like a common thing nowadays. In fact, I got the notion of the wildcard mail box from a relatively non-technical acquaintance of mine. There was a checkbox when he signed up for his domain hosting service to accept all mail to his domain. I don't recall who his provider is, but this seems like a common enough feature. I will look around and see what's commonly supported.
As for mailback confirmation, I think that would just push the awkwardness off of the admin and onto the user, at least for moblogging purposes.
Well, I ended up digging around for some info just on the hosting services that you mentioned:
Rackspace conversation:
Me: do you support wildcard email boxes?
Rackspace: "You will have full root access to the server and you can apply email you like. We do not support wildcard email boxes but it will not be a problem to have it up in your server.."
Pair conversation:
Me: Which of your accounts, if any, support wildcard mailboxes?
Pair: (still awaiting answer via email)
PHPWebHosting.com:
http://phpwebhosting.com/email.html - "Email Aliases
Email aliases allow you to receive mail @yourdomain.com but not need to worry about setting up and checking yet another email account. With email aliases, an address at your domain (webmaster@yourdomain.com for example) will automatically be redirected to your existing POP3 email account. "
Dreamhost.com:
"Email Addresses
Every DreamHost plan comes with unlimited email addresses @yourdomain.com! These addresses are configured through our web panel and can be set to go straight to a DreamHost mailbox or forward to another email address. One email address (also known as an email "alias") can be set to forward to any number of other addresses and mailboxes! You can also set an email address to just discard any mail sent to it (optionally bouncing back a failure message to the sender). Finally, you can set up a "catch-all" email address at your domain which will handle all mail sent to any address @yourdomain.com that you haven't specifically set up. Having your own domain means you can really get creative with your use of email addresses!
"
As you can see, this appears to be a somewhat popular feature.
Comment #6
moshe weitzman commentedI didn't think of the solution where an admin just uses a catchall email address. Sounds good. You gonna write some code?
Comment #7
javanaut commentedI can do this part, no problem.
Unfortunately, my available time for work here comes in bursts, with long lulls in availability. I would make a poor maintainer for this reason. I feel honored that you would offer this, but alas, I'm wondering how I'm going to maintain the projects that I'm currently working on ;)
Comment #8
javanaut commentedDo you think I should roll this into the Report Errors Via Email feature, or just wait until the error reporting feature is completed first? I would like for this feature to use the error reporting mechanism if possible.
Comment #9
javanaut commentedBTW, Pair Networks responded with:
Comment #10
killes@www.drop.org commentedI am a bit surprised that there are still people left who are brave enough to use wildcard addresses. I thought all of them had been drowned in spam...
For more comments see:
http://lists.drupal.org/archives/drupal-devel/2004-10/msg00518.html
Comment #11
moshe weitzman commentedi don't think spam and wildcard addresses is applicable here. the entity using a wildcard address is the mailhandler inbox, not a person. further, if this address gets spammed the messages will simply be rejected as unauthenticated.
Comment #12
moshe weitzman commentedAfter some more thought, i agree that a catch_all mailbox is the way to go.
I noticed solves this problem without forcing the user to create a passphrase. they simply assign an email address to each user. the security is in the obscurity. if the secret email address is ever compromised, flickr provides areset button which isues you a new address. its a bit simpler than forcing the user to pick a passphrase.
I think this is pretty distinct fromthe 'report errors by email' issue.
Comment #13
moshe weitzman commentedi like how flickr handles this - http://flickr.com/account/uploadbyemail/. they issue you a secret alias email address like @mobile.flickr.com. anything sent to that address is assumed from you. you can regenerate a new alias at any time from your user profile. that protects you when you gave your address away to a mean person.
so, now this need seems solvable with just mailalias.module and a little UI help on the profile pages. i am considering removing the security feature of mailhandler and request that users use this alias method instead. any thoughts?
Comment #14
moshe weitzman commentedtokenuth module provides a secret hash per user so i'd like mailhandler to just integrate with tokenauth
Comment #15
strangeways commentedI realize I'm responding to a rather old discussion, but since this issue is still open, I thought this might be useful. I like the idea of using a secret email address per user, but it may not be feasible for most people to create that many aliases. Instead, you could use "plus" addressing so that only one email address is needed but still allows a unique key per user. E.g.,
myemail+1234@example.com
myemail+abcd@example.com
These should both be delivered to myemail@example.com, but mailhandler could then look at the "1234" or "abcd" and see if that secret key matches with the From address on the email.
The biggest issue with this is that not all mail providers support it. Some support a minus sign instead of the plus sign, some support both, and some support neither (see this Wikipedia entry). A solution might be to allow configuration of which symbol to use; alternately just support plus addressing, and if someone's email hosting doesn't support it, they can create an address on a free service like Gmail that supports POP. According to Wikipedia, there is also the issue of "some systems ... refusing to send mail addressed to a user on another system merely because the local-part of the address contains the plus sign (+)." I don't know how common a problem this is, however.
Comment #16
Mike Sances commentedsubscribing
Comment #17
j0rd commentedI need this feature as well.
Has this been done for Mailhandler yet? I noticed Mailalias module, but it's still stuck in the D5 Era. I would argue that this should be in Mailhandler by default as an optional security feature.
I'd like to know what people are doing to provide this extra layer of authentication, because as with the original poster, I realize it's easy to spoof email addresses and thus hijack accounts.
As a "proof of concept" i just wrote this "exploit" to test out how easy it was to spoof. Turns out, pretty friggin simple. I would have hoped that gmail (which i'm using for my mailhandler drop) would have spam filtered it out, but this was not the case.
Here's the "code"
For all those who don't think this is a problem, please provide me with your email address and your mailhandler email address and I'll make some money off viagra affiliates.
Comment #18
j0rd commentedI'm going to need to code this for my project, so if anyone wants feature requests right now I would suggest asking for them.
Right now, I'm going to create unique unique random auto-generated keys which when users submit their emails to the mailhandler address, it will get verified againsnt that and there from address. If it fails, I'll skip it and mark the email as read or delete it depending on the settings.
I'll display this key privately to the users profile page in a tab or secondary menu or what ever drupal calls it.
I'll add this as an optional configuration Mailhandler config under "Use Password".
I'll assume that most people will be using a catch-all, but I'll also provide a hook which people who do not want catch-alls, can create the email alias/address for that user (and perhaps also change the auto-generated key, which is to be used).
Anything else people want? or things I'm not thinking of.
I'll also be creating this as a patch for mailhandler of HEAD of the D6 version, as I believe it's an integral security "feature" which should be added by default. What do you guys think?
Comment #19
moshe weitzman commentedUser tokens is a feature of tokenauth module.
Comment #20
j0rd commentedcurrently token auth does not provide this functionality, but it appears the author would like to integrate it with mail handler as it's in the TODO.
Comment #21
PGiro commentedj0rd, did you move forward on this ? I need similar functionnality for a mobile site too.
I was planning on doing the same as you except that I don't want users to have to type their auth key everytime. I want to setup up a generic mailhandler account mailhandler@example.com and then assign addresses to users such as mailhandler-SDSDIZENFSD@example.com and mailhander-2348FSN23@example.com. They can then send their emails to those two addresses and I will be able to match the account. This requires a simple catch-all account and, if you're using exim a simple suffix configuration.
I'd be willing to code into your patch/module my way of doing it if you design it so it can support both, there is so much in common in our solutions.
Thanks
Comment #22
j0rd commentedI've yet to start the work, but still require this feature. I have a project that will require this which I'll finish in the next month or so.
I'll post my solution when it's available.
Comment #23
PGiro commentedOk, I'll take that as a "Thanks, but I'm not interested".
@z.stolar: going along with my other refactoring post. I'd suggest we slightly refactor the module so that
- mailhandler_authenticate is in fact a hook (of which there can be only one implementation enabled at a time)
- mailhandler offers a module which implements the standard way of doing it
- mailalias_user would be changed so that the code from lines 371 to 379 are implemented in that hook
Then I can provide a custom module back to the community and it will support future versions of mailhandler. And anyone else who comes up with their own need can handle it.
Would this be a good plan ?
Comment #24
z.stolar commented@PGiro: I'll happily examine any improvements to mailhandler, as patches or stand-alone modules (preferable in your case), and if needed, introduce a new hook.
Comment #25
PGiro commented@z.stolar: ok, will do then.
Comment #26
PGiro commentedHere is my tentative patch to open up the discussion. I have yet to get mailsave_imagefield to work so I can fully test it.
I have made the process_message method call a private _authenticate method. This one checks that there exists an implementation of mailhandler_authenticate somewhere in the PHP code. If there is, it calls it.
I have provided 2 modules
- mailhandler_fromauthentication.module which corresponds to the current code in mailhandler_authenticate() when mailalias is not installed
- mailhandler_fromaliasauthentication.module which corresponds to the current code in mailhandler_authenticate()
So really it's now easy to plug in any authentication scheme anyone would like and make them separate modules.
Why didn't I use the typical drupal pattern of "module_implements" : because I never want to rely on From: to authenticate...
Comment #27
PGiro commented@z.stolar : can you find time to check my patch ?
Comment #28
z.stolar commented@PGiro: I'll do my best. I'm in a rather busy time now.
I appreciate your efforts. If others in this thread are willing to review it, it'll be a great help!
Comment #29
j0rd commentedI applied PGiro's patch (#26) and have implemented to "from address + to alias" authentication method using the framework this patch provides. See attached file if you require this. It uses Token Auth as moshe has recommended (#14).
While I see PGiro's approach abstracting the authentication for Mailhandler is great, I think the method of how it currently operates could be improved using hooks. The way PGiro has done it (and I understand why he's done it this way) involves abstracting the authentication function out into a module and then enabling a single module of authentication. While this works, I've never seen another module do this and it feels unnatural to a seasoned Drupal dude.
Perhaps it could be done, by leaving the default authentication method in the mailhandler module and allowing other modules to provide authentication methods....then provide Mailhandler with an entry point, in which you can choose a different authentication method on a configuration page. Perhaps it's best if someone takes a look and improves how this is done before more authentication modules are written.
DESCRIPTION:
This module uses authenticates off the from address, much like the default mailhandler module.
It also provides another check which is based off the email address the user sends his email to.
This will require that your mailserver is setup to accept "catch-all" emails on the domain.
EXAMPLE:
Comment #30
PGiro commented@j0rd: you are absolutly right, I didn't do it the usual drupal way by using hooks. There reason being that hooks allow multiple modules to responde to an event but in our case, we only want one module doing the authenticating which, I felt, was different
So your patch requires my patch ? Is that it ?
Because I'd like to reuse your form_alter stuff which I haven't gotten around to writing yet!
@z.stolar : can we get some feedback so j0rd and I can move on to what next be done ?
Comment #31
z.stolar commented@PGiro: I didn't go over *all* lines of the patch, but have gone deep enough to notice quite a few issues with it. For example, I don't like the fact that your module uses mailhandler's name space for its hook. Also, various syntax and coding standards errors were observed.
I acknowledge the importance of this feature, but I think that if you already took the separate module path, you should try and implement as much as possible in that module. As I said above, if you need the addition of a hook in mailhandler, or any other changes for that matter, please submit a patch for these changes.
Comment #32
PGiro commented@z.stolar: needless to say I am disappointed in your response.
I have submitted said patch and have explained why the method is in the mailhandler namespace. I would rather have discussed the merits of that versus a real drupal hook rather than just a "you're using a method in my namespace" which I believe makes sense in the context I described (we don't want multiple modules implementing the hook, unlike all other drupal hooks I know of). Like j0rd said, this is non-standard and maybe there's a better way. I was hoping for a discussion.
I don't know what you mean by "took the separate module path". In fact, I have not : I provided an explanation of what I thought we could do to provide the requried functionality and I asked for some feedback from you. Since I did not get a response on that and you asked for a patch, I submitted the patch.
Now, I get a response about the coding standards and syntax which brings nothing to the discussion except give me the feeling I am wasting my time trying to coordinate with you and contribute.
Do you want to discuss this or not ? If so, please review my patch on the merits of the functionality it provides and please don't just list a catalog of coding standard errors, that's beside the point at this stage of the discussion.
If not, just say you don't care/don't have the time/don't want to so I stop wasting my time trying to plug into your project.
Comment #33
z.stolar commented@PGiro: Allow me to apologize for my brief answer.
Let's understand what it's all about. First and most, the discussion IS open, and was never shut down. My comments about the syntax/standards, wasn't the most important one, but it is important to understand that it's easier to /read/ a patch, when it follows the standards. Such a patch has a higher chance of being processed. Certainly it is not the issue itself though.
The separate module path: What you did was to create a new (sub)module of mailhandler, which in my opinion is the right path. What I meant to say, is that you should not implement mailhandler's (new) hook in your module, as if it was mailhandler's (talking about mailhandler_authenticate). You should rather use your new module's name space for that.
As stated above - the discussion is open, and anyway - who am I to close it?
I don't mean to act as a single moderator, and if there will be a collective understanding that your patch is ready and necessary, I won't stand in your way.
However, I don't promise to accept every solution, even if it's a good one. Again - this decision should be collective (more than you and me ;-) ), and the patch should be tested and reviewed by a larger public, before it is applied.
I hope this satisfies you, and again - sorry for being too short of words earlier.
Comment #34
Ian Ward commentedI've just read through this issue. While there should only ever be one authentication method on a mailbox, do people see the need to allow for multiple authentication methods in order that one mailbox may use one method, while another uses a different method? It appears that the patch is one authentication method module-wide, as opposed to per-mailbox, but maybe I am missing something. If it were per-mailbox, you could have mailhandler's mailhandler_authenticate() look at the mailbox it is acting on. When you setup a mailbox, you could invoke some mailhandler_authenticate() hook to find modules that offer authentication means, and then when you save the mailbox, you save the authentication method w/ that mailbox to the database. What do you think about this?
Comment #35
PGiro commented@z.stolar: I'll answer your comment in the upcoming days. I've been working on something else at the moment
Comment #36
j0rd commentedI like the idea of selecting an authentication method per mailbox. I don't think this is all that important, but it's easily coded.
I like the idea of "contrib" modules supplying mailhandler with extra methods of authencation via hooks.
I like the idea of having the authentication methods being selectable on the configuration page, again because this is easily done.
I like the idea of having it default to the current authentication method available in the module.
--
It wouldn't be much work from the patch PGiro has already supplied.
Comment #37
meba commentedWe have implemented this feature without even needing a patch - mailhandler allows you to specify a header used for looking up From address. We have simply set it to be "To" header. Then used mailalias.module to give every user some alias (like "andy-random123123@drupal.org"). User sends email to andy-random123123@drupal.org, which is a wildcard for some mailbox. Mailhandler gets the email, finds the "From" in "To" header (that's the tricky part :-) and assigns a proper user. Done.
Is there a catch in our approach? :)
Comment #38
meba commentedAttaching a proof of concept patch (will be perfected later) to implement a generic authentication framework for mailhandler. What it does/allows:
hook_mailhandler_authenticate
Any module can implement hook_mailhandler_authenticate and will receive email headers and body to match users. Example: Match a special X-MyModule-From: XYZ header to own database table.
If at least one (first) module returns a valid user email, authentication succeeds.
Authentication fallback
Because there needs to be a fallback and currently, there needs to be a way to disable this fallback, I have implemented new setting for every mailbox, called "Authenticate using From header". It defaults to true and all current mailboxes will be updated to have it enabled (= it's backwards compatible).
Why? If you implement the hook and then still allow matching to a From address, everybody can still fake users by knowing their from. You need to be able to disable this behavior by disallowing matching the From: in authenticate at all
Possible change: Automatically disallow From matching if there is at least one authenticating module?
Compatibility
This aims to be almost backwards compatible. If you are not using mailalias module, the behavior shouldn't change. If you are using mailalias module, you need to upgrade it too (patch will follow into the mailalias queue - simply implement the new hook)
Comment #39
Ian Ward commented@meba - I am thinking each mailbox should store the name of the callback for its authentication method so that it may be called explicitly instead of the idea that as long as one of the authentication methods succeeds, proceed. This would still use a hook for declaration of authentication methods and on the form you would select a default for each mailbox. A hook should be able to implement more than one authentication method which would allow the mailhandler module itself to ship with the current method, virtual passphrase, and "no authentication", for example.
Comment #40
Ian Ward commentedWhat do you think of the following (untested code):
Implements info and execution hook
Modules define their authentication methods
The default authentication method currently used in mailhandler
Calling code, which was (until today) in mailhandler_retrieve_message
Used to be:
$node = mailhandler_authenticate($node, $header, $origbody, $mailbox);and would now be:
$node = mailhandler_mailhandler_authenticate ('execute', $mailbox['authentication'], array($node, $header, $origbody, $mailbox);The info hook would be called on the settings page for when making/editing a new mailbox in order to retrieve/list the available authentication methods, which should also handle when an authentication method disappears for which a mailbox is using.
Comment #41
Ian Ward commentedHere is working code and update path of the above concept with some fixes.
Comment #42
Ian Ward commentedAttached is a new patch that, in addition to the default email address-based authentication, implements token auth authentication along the lines of @j0rd's #29
Comment #43
Ian Ward commentedI committed the patch from #42 along with additional documentation. If you apply this patch note you must run update.php. Additional rough edges to clean up include:
* support for mail aliases when using the tokenauth authentication plugin
* more documentation about the authentication plugin system
* better fail-over when a plugin is missing
Comment #44
Ian Ward commentedThe three tasks in #43 are complete. I will leave this open for additional feedback until the next release of mailhandler is made.
Comment #45
Ian Ward commentedFixed
Comment #46
gregglesI just downloaded/installed the 6.x-1.10 code and have found that the Message authentication method always reverts to "Mailhandler Default" even if I set it to Mailcomment Default. Debugging now, but I wanted to notify you/others about the bug.
Comment #47
gregglesI'm not sure exactly what was happening, but I think it was caused by a problem on my site. The form was actually throwing an "invalid submission" error because no input format was selected but there was no input format only because someone "accidentally" deleted it.
We could potentially add a condition to the hook_validate to give a better error message about the input format, but that's for a different issue.
Comment #49
yngens commentedsubscribing just to have this excellent discussion in the list of my posts.
Comment #50
feamin commentedI have another question on this issue. This is the tokenauth module for mailhandler?
I want to receive emails to my server at an address like foo@myserver.com.
I would like all mail received at that address to be processed by mailhandler.
I would also like to use the token auth, so really mail is sent to foo+token@myserver.com.
I DO NOT want to check the from addresses at all. I want the authentication just based off the token in the To: address. If the token is in the To address, then authentication based on whatever user has that token, would be ideal, but otherwise just making sure the token matches a particular existing user is fine.
This way, someone can send from ANY address, and still post via tokens.
Is this possible with the current configuration? If not, can someone point to where in the php code and what file so I can comment this out?
Thanks