This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2012年06月06日 08:11 by sandro.tosi, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| smtplib.patch | zvyn, 2014年03月03日 19:57 | Implements new member functions for each auth-method in SMTP. | review | |
| smtplibAuthobj.patch | zvyn, 2014年03月04日 19:33 | add support for arbitrary auth methods via authenticate(..., authobject) | review | |
| smtplib_auth.patch | zvyn, 2014年05月28日 22:25 | review | ||
| smtplib_auth_060614.patch | zvyn, 2014年06月06日 14:49 | review | ||
| smtplib_auth.patch | r.david.murray, 2014年07月03日 18:55 | review | ||
| 15014-auth-init-resp.diff | barry, 2015年07月07日 17:35 | review | ||
| Messages (30) | |||
|---|---|---|---|
| msg162396 - (view) | Author: Sandro Tosi (sandro.tosi) * (Python committer) | Date: 2012年06月06日 08:11 | |
Hello, I'm writing some tests from an MTA, and so I'm using smtplib. Sadly the login() method doesn't allow to choose the auth method to use (but it's selected from a static list compared with what's advertized from the MTA) while it would be useful to be able to choose the AUTH method to use. |
|||
| msg162407 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年06月06日 13:01 | |
Yes, this is a need I also ran into, but hadn't gotten around to submitting a bug for. If we are going to do this, though, I think we should do it right and add the ability to support arbitrary login methods. An example of one way to do this is the imaplib authobj protocol. As things are, I wound up implementing XYMCOOKIE login using the even-more-primitive-than-SMTP-cmd-level operation 'do_cmd'. |
|||
| msg212663 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014年03月03日 19:57 | |
I implemented one approach to solve this by writing new member functions for each method (see the patch attached). Bonus: It does not change the usage of login() in any way (which uses the new functions internally). Another option would be to make those functions private/put them into login() and provide an optional keyarg. Or auth objects, but as far as I can see only 3 methods are relevant so it might be an overkill? So that's the easy way to fix it, would be glad if it helps! |
|||
| msg212667 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年03月03日 20:33 | |
There is a lot of repeated code in those methods, which becomes a maintenance burden. That is one reason the imaplib authobj approach seems interesting to me. Also, going the authobj route would mean imaplib and smptlib had a consistent interface for this, and consistency is good where it makes sense. |
|||
| msg212668 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年03月03日 20:35 | |
Oh, sorry. I meant to start out that message by saying, thanks for the patch. Your idea is indeed interesting from the standpoint of not needing to change the rest of the API, but....and then the rest of my message. In other words, I appreciate your work and your approach, but I think the reasons I outline argue for a different approach. |
|||
| msg212720 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014年03月04日 13:51 | |
I looked into imaplib a bit to see how the problem is solved there; what I observed: - login() does 'PLAIN' only (and does not use authobj but smtplib would) - there exists an extra function login_cram_md5() for 'CRAM-MD5' So I guess the right way to do it would be to write an authenticate() method as in imaplib and use it in new member functions of the form login_[method](). In contrast to imaplib login() could still be used to probe through the three main methods (to avoid breaking backward compatibility). I'll try to implement this later today, so if you think it's completely dumb and read this before a patch is applied feel free to give me a quick reply to stop me from wasting my time :) |
|||
| msg212726 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年03月04日 15:55 | |
Ah, I was going on imperfect memory of how imaplib worked without looking it up. And I won't have time to do so today probably. Probably we should decide on the exact API before you implement anything. |
|||
| msg212735 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014年03月04日 19:33 | |
Maybe I am a bit hyperactive, but I already was at it when receiving your message, so I finished it. Anyhow most of what I have done is completely independent of the API chosen. What I did: 1. I implemented a new authenticate(self, mechanism, authobject) as in imaplib which can be used for all methods 2. I implemented authobjects for the three most important mechanisms 3. login() has a keyarg 'preferred_auth' which is a list of auth-methods (strings) I think 1. and 2. make sense regardless of how the API should look like in the end, because it's the only way without any code-redundancy. 3 is more a proposal. |
|||
| msg212739 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年03月04日 20:51 | |
OK, that makes sense to me. I'll take a look at it as soon as I can. |
|||
| msg218707 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年05月17日 16:13 | |
OK, I've finally had time to review this, sorry for the delay. The impalib mechanism is tailored to how imap works (that's the whole thing about "continuation response". smtplib auth works a bit differently, and your adaptation looks OK to me. The accompanying docstrings are a bit confusing, though, since they copy the imaplib language, which isn't entirely applicable. Instead of talking about a 'continuation response', it should talk about a '334 challenge response', I think. Also, both the imaplib and smptlib methods are named after the corresponding command names in the protocol. So for imaplib we have 'authenticate', but for smtplib it should be 'auth'. I also think we should expose the supported auth methods as part of the public API. I think exposing the preferred auth list is premature, since if we are going to do that we need to have a way to add elements to that list for the users's own auth methods and we don't have that. So let's confine this issue to adding the 'auth' method and using it in the login method. The tests should include a new test of calling the auth method directly. |
|||
| msg219315 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014年05月28日 22:25 | |
Done. |
|||
| msg219845 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年06月05日 20:47 | |
I made some review comments. Also, we need doc updates, including a what's new entry. |
|||
| msg219876 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年06月06日 12:22 | |
Ah, you are right, I wasn't looking at the full context of the diff when I made the comment about backward compatibility. So ignore that part :) On the other hand, exposing perferred_auth on the class would be a simple API for allowing auth extension (since one really needs to subclass to add an authobject, given that it needs access to self.user and self.password). But, like I said before, that can be a separate issue. |
|||
| msg219886 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2014年06月06日 14:49 | |
Here comes the patch implementing your suggestions. Changing the API to make adding new auth methods and still using login() would only require to make preferred_auth accessable as you mentioned. Using custom authobjects is possible with this patch. |
|||
| msg222205 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2014年07月03日 18:48 | |
New changeset 42917d774476 by R David Murray in branch 'default': #15014: Add 'auth' command to implement auth mechanisms and use it in login. http://hg.python.org/cpython/rev/42917d774476 |
|||
| msg222206 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年07月03日 18:55 | |
Thanks, Milan. I made some tweaks...mostly documentation and code style (your code style wasn't wrong, I just have some slightly different preferences with regards to line folding). I also eliminated the authobjects test method, since I didn't see that it added anything to duplicate the code from the login method to test them...they get tested via the login methods. Instead I added the loop to the test for the auth method, so that we test that calling the public API with the auth objects that are documented as part of the public API work. That is, if someone were to change login such that the method names changed but login still worked, the auth test method will throw an error because the documented method names changed. I'm attaching the final patch here so you can look at the differences via the reitveld patch-diff function, if you want to. |
|||
| msg245648 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年06月22日 20:39 | |
I believe this change broke RFC 4954's AUTH command when the optional initial-response is expected. 4ドル "The AUTH Command" says: AUTH mechanism [initial-response] ... initial-response: An optional initial client response. If present, this response MUST be encoded as described in Section 4 of [BASE64] or contain a single character "=" It's possible that some SMTP servers only look for a string like AUTH PLAIN <base64-gobbledygook> and won't issue a challenge if it's missing. Such an example is found in the lazr.smtptest and used by the testing SMTPd in GNU Mailman. It's possible that the servers are not standards compliant (I haven't completely groked RFC 4422), but still, since this is a backward incompatible change and breaks existing code, there should be some way of making smtplib.login() provide the initial-response, and it probably ought to be the default for backward compatibility. |
|||
| msg245649 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年06月22日 21:14 | |
Here's a rough thought for a fix. Some auth_*() methods require a challenge, but some don't, e.g. auth_plain(). Let's allow authobject() to be called with challenge=None. If they allow an initial-response, then they can just return the response bytes. If they return None, then they don't allow an initial-response and so must wait for the challenge (i.e. 334 response code). I think that would at least restore backward compatibility for AUTH PLAIN. |
|||
| msg245650 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年06月22日 21:47 | |
Also, smtpd is not compatible with auth challenges because found_terminator() doesn't know that the response its getting isn't a command but instead a challenge response. So really we need another bug to track fixes to smtpd.py to handle challenge responses. It makes no sense for smtpd and smtplib not to be compatible. (Who wants to reimplement smtpd in asyncio? :) |
|||
| msg245652 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年06月22日 22:00 | |
Sounds reasonable. I'll suggest a slight variation. We change the authobj signature to challenge=None, then the first thing we do in auth is 'initial_response = authobj()'. The return value can be the empty string or a real initial value, and we send the auth command with ' '.join(mechanism, initial_response).strip(). Then we do the challenge part only if we get the 334. There's already an open issue for smtpd auth, with at least a preliminary patch, but it got blocked a bit by Martin quoting an RFC... |
|||
| msg245653 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年06月22日 22:04 | |
The smtpd issue is issue 21935. |
|||
| msg245654 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年06月22日 22:05 | |
On Jun 22, 2015, at 10:00 PM, R. David Murray wrote: >We change the authobj signature to challenge=None, then the first thing we do >in auth is 'initial_response = authobj()'. The return value can be the empty >string or a real initial value, and we send the auth command with ' >'.join(mechanism, initial_response).strip(). Then we do the challenge part >only if we get the 334. Sounds good to me. I'll see if I can work up a patch. I have a hack in my testing code to work around the lack of auth in smtpd. It's not pretty but it works. |
|||
| msg246419 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年07月07日 15:30 | |
I have a patch to support initial-response, which I'll be posting here after a bit of clean up and a full (local) test run, with documentation. I ended up adding a keyword argument `initial_response_ok=True` to .login() and .auth(). The reason for this is that some clients may wish to force smtplib to do challenge/response. By default, mechanisms that support it (e.g. AUTH PLAIN) will send the initial response. Setting `initial_response_ok=False` in either SMTP.auth() or SMTP.login() will prevent smtplib from sending the initial response, and instead deal with challenge/response. I made initial_response_ok a keyword argument. |
|||
| msg246433 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年07月07日 17:35 | |
Attached patch includes test, documentation, and implementation. While this is technically a new feature, it fixes a regression in Python 3.5 w.r.t. 3.4. I'll email python-dev with a request for beta exemption. |
|||
| msg246436 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年07月07日 17:59 | |
I don't see any need to add the is_initial_auth_ok flag. Either the auth method returns something that is not None (initial auth is OK), or it doesn't (initial auth is not OK). Providing for that initial return value from the authobj is still a change to the new feature, but I don't think fixes to API bugs require an exception to the features rule, especially when they represent a fix to a regression. |
|||
| msg246437 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年07月07日 18:25 | |
On Jul 07, 2015, at 05:59 PM, R. David Murray wrote: >I don't see any need to add the is_initial_auth_ok flag. Either the auth >method returns something that is not None (initial auth is OK), or it doesn't >(initial auth is not OK). I added this because test_smtplib itself expects some challenge/response even for AUTH PLAIN. I could have done more surgery on test_smtplib to avoid this, but on thinking about it, I decided that it makes sense to allow for the override. smtplib is often used in test scenarios, so imagine testing an SMTP server implementation. To get full coverage you'd want to test both initial-response and challenge/response even for auth methods like PLAIN. Indeed, I've been thinking about writing an asyncio-based smtpd, and it would be nice to be able to handle both cases without having to derive from class SMTP and re-implementing auth_plain and auth_login. |
|||
| msg246438 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年07月07日 18:36 | |
OK, that makes sense. I'll try to give this a thorough review soon. |
|||
| msg246443 - (view) | Author: Barry A. Warsaw (barry) * (Python committer) | Date: 2015年07月07日 22:58 | |
Thanks! |
|||
| msg246473 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年07月08日 21:45 | |
Only one question, about a possible missing test. Otherwise this looks good to me. |
|||
| msg246505 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2015年07月09日 14:53 | |
New changeset 97a29b86a2dc by Barry Warsaw in branch '3.5': - Issue #15014: SMTP.auth() and SMTP.login() now support RFC 4954's optional https://hg.python.org/cpython/rev/97a29b86a2dc New changeset 2d9003d44694 by Barry Warsaw in branch 'default': - Issue #15014: SMTP.auth() and SMTP.login() now support RFC 4954's optional https://hg.python.org/cpython/rev/2d9003d44694 |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:31 | admin | set | github: 59219 |
| 2015年07月09日 14:58:32 | barry | set | status: open -> closed assignee: barry |
| 2015年07月09日 14:53:42 | python-dev | set | messages: + msg246505 |
| 2015年07月08日 21:45:38 | r.david.murray | set | messages: + msg246473 |
| 2015年07月07日 22:58:50 | barry | set | messages: + msg246443 |
| 2015年07月07日 18:36:25 | r.david.murray | set | messages: + msg246438 |
| 2015年07月07日 18:25:40 | barry | set | messages: + msg246437 |
| 2015年07月07日 17:59:27 | r.david.murray | set | messages: + msg246436 |
| 2015年07月07日 17:35:56 | barry | set | files:
+ 15014-auth-init-resp.diff messages: + msg246433 |
| 2015年07月07日 15:30:34 | barry | set | messages: + msg246419 |
| 2015年07月05日 01:10:31 | larry | set | priority: release blocker -> normal |
| 2015年06月22日 22:05:55 | barry | set | messages: + msg245654 |
| 2015年06月22日 22:04:25 | r.david.murray | set | messages: + msg245653 |
| 2015年06月22日 22:00:28 | r.david.murray | set | priority: normal -> release blocker stage: resolved -> needs patch messages: + msg245652 versions: + Python 3.6 |
| 2015年06月22日 21:47:00 | barry | set | messages: + msg245650 |
| 2015年06月22日 21:14:32 | barry | set | messages: + msg245649 |
| 2015年06月22日 20:39:38 | barry | set | status: closed -> open messages: + msg245648 |
| 2014年07月03日 18:55:30 | r.david.murray | set | status: open -> closed files: + smtplib_auth.patch messages: + msg222206 resolution: fixed stage: needs patch -> resolved |
| 2014年07月03日 18:48:48 | python-dev | set | nosy:
+ python-dev messages: + msg222205 |
| 2014年06月06日 14:49:39 | zvyn | set | files:
+ smtplib_auth_060614.patch messages: + msg219886 |
| 2014年06月06日 12:22:40 | r.david.murray | set | messages: + msg219876 |
| 2014年06月05日 20:47:35 | r.david.murray | set | messages: + msg219845 |
| 2014年05月28日 22:29:06 | zvyn | set | nosy:
+ jesstess |
| 2014年05月28日 22:25:29 | zvyn | set | files:
+ smtplib_auth.patch messages: + msg219315 |
| 2014年05月17日 16:13:33 | r.david.murray | set | messages: + msg218707 |
| 2014年04月15日 17:53:02 | r.david.murray | link | issue1521196 superseder |
| 2014年03月04日 20:51:50 | r.david.murray | set | messages: + msg212739 |
| 2014年03月04日 19:33:38 | zvyn | set | files:
+ smtplibAuthobj.patch messages: + msg212735 |
| 2014年03月04日 15:55:53 | r.david.murray | set | messages: + msg212726 |
| 2014年03月04日 13:51:38 | zvyn | set | messages: + msg212720 |
| 2014年03月03日 20:35:21 | r.david.murray | set | messages: + msg212668 |
| 2014年03月03日 20:33:00 | r.david.murray | set | messages:
+ msg212667 versions: + Python 3.5, - Python 3.3 |
| 2014年03月03日 19:57:50 | zvyn | set | files:
+ smtplib.patch nosy: + zvyn messages: + msg212663 keywords: + patch |
| 2012年06月08日 06:59:54 | catalin.iacob | set | nosy:
+ catalin.iacob |
| 2012年06月06日 13:02:19 | r.david.murray | set | nosy:
+ barry components: + email stage: needs patch |
| 2012年06月06日 13:01:56 | r.david.murray | set | title: smtplib: allow to choose auth method on login() -> smtplib: add support for arbitrary auth methods nosy: + r.david.murray messages: + msg162407 type: enhancement |
| 2012年06月06日 08:11:21 | sandro.tosi | create | |