Show More
@@ -142,6 +142,11 b' Example:' | |||||
142 | foo.password = bar |
|
142 | foo.password = bar | |
143 | foo.schemes = http https |
|
143 | foo.schemes = http https | |
144 |
|
144 | |||
|
145 | bar.prefix = secure.example.org | |||
|
146 | bar.key = path/to/file.key | |||
|
147 | bar.cert = path/to/file.cert | |||
|
148 | bar.schemes = https | |||
|
149 | ||||
145 | Supported arguments: |
|
150 | Supported arguments: | |
146 |
|
151 | |||
147 | prefix;; |
|
152 | prefix;; | |
@@ -152,10 +157,17 b' Supported arguments:' | |||||
152 | against the URI with its scheme stripped as well, and the schemes |
|
157 | against the URI with its scheme stripped as well, and the schemes | |
153 | argument, q.v., is then subsequently consulted. |
|
158 | argument, q.v., is then subsequently consulted. | |
154 | username;; |
|
159 | username;; | |
155 | Username to authenticate with. |
|
160 | Optional. Username to authenticate with. If not given, and the | |
|
161 | remote site requires basic or digest authentication, the user | |||
|
162 | will be prompted for it. | |||
156 | password;; |
|
163 | password;; | |
157 |
Optional. Password to authenticate with. If not given the |
|
164 | Optional. Password to authenticate with. If not given, and the | |
|
165 | remote site requires basic or digest authentication, the user | |||
158 | will be prompted for it. |
|
166 | will be prompted for it. | |
|
167 | key;; | |||
|
168 | Optional. PEM encoded client certificate key file. | |||
|
169 | cert;; | |||
|
170 | Optional. PEM encoded client certificate chain file. | |||
159 | schemes;; |
|
171 | schemes;; | |
160 | Optional. Space separated list of URI schemes to use this |
|
172 | Optional. Space separated list of URI schemes to use this | |
161 | authentication entry with. Only used if the prefix doesn't include |
|
173 | authentication entry with. Only used if the prefix doesn't include |
@@ -109,7 +109,9 b' class passwordmgr(urllib2.HTTPPasswordMg' | |||||
109 | return (user, passwd) |
|
109 | return (user, passwd) | |
110 |
|
110 | |||
111 | if not user: |
|
111 | if not user: | |
112 |
|
|
112 | auth = self.readauthtoken(authuri) | |
|
113 | if auth: | |||
|
114 | user, passwd = auth.get('username'), auth.get('password') | |||
113 | if not user or not passwd: |
|
115 | if not user or not passwd: | |
114 | if not self.ui.interactive(): |
|
116 | if not self.ui.interactive(): | |
115 | raise util.Abort(_('http authorization required')) |
|
117 | raise util.Abort(_('http authorization required')) | |
@@ -132,7 +134,7 b' class passwordmgr(urllib2.HTTPPasswordMg' | |||||
132 | msg = _('http auth: user %s, password %s\n') |
|
134 | msg = _('http auth: user %s, password %s\n') | |
133 | self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set')) |
|
135 | self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set')) | |
134 |
|
136 | |||
135 |
def |
|
137 | def readauthtoken(self, uri): | |
136 | # Read configuration |
|
138 | # Read configuration | |
137 | config = dict() |
|
139 | config = dict() | |
138 | for key, val in self.ui.configitems('auth'): |
|
140 | for key, val in self.ui.configitems('auth'): | |
@@ -143,7 +145,7 b' class passwordmgr(urllib2.HTTPPasswordMg' | |||||
143 | # Find the best match |
|
145 | # Find the best match | |
144 | scheme, hostpath = uri.split('://', 1) |
|
146 | scheme, hostpath = uri.split('://', 1) | |
145 | bestlen = 0 |
|
147 | bestlen = 0 | |
146 |
bestauth = None |
|
148 | bestauth = None | |
147 | for auth in config.itervalues(): |
|
149 | for auth in config.itervalues(): | |
148 | prefix = auth.get('prefix') |
|
150 | prefix = auth.get('prefix') | |
149 | if not prefix: continue |
|
151 | if not prefix: continue | |
@@ -155,7 +157,7 b' class passwordmgr(urllib2.HTTPPasswordMg' | |||||
155 | if (prefix == '*' or hostpath.startswith(prefix)) and \ |
|
157 | if (prefix == '*' or hostpath.startswith(prefix)) and \ | |
156 | len(prefix) > bestlen and scheme in schemes: |
|
158 | len(prefix) > bestlen and scheme in schemes: | |
157 | bestlen = len(prefix) |
|
159 | bestlen = len(prefix) | |
158 |
bestauth = auth |
|
160 | bestauth = auth | |
159 | return bestauth |
|
161 | return bestauth | |
160 |
|
162 | |||
161 | class proxyhandler(urllib2.ProxyHandler): |
|
163 | class proxyhandler(urllib2.ProxyHandler): | |
@@ -411,8 +413,32 b' if has_https:' | |||||
411 | send = _gen_sendfile(httplib.HTTPSConnection) |
|
413 | send = _gen_sendfile(httplib.HTTPSConnection) | |
412 |
|
414 | |||
413 | class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler): |
|
415 | class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler): | |
|
416 | def __init__(self, ui): | |||
|
417 | keepalive.KeepAliveHandler.__init__(self) | |||
|
418 | urllib2.HTTPSHandler.__init__(self) | |||
|
419 | self.ui = ui | |||
|
420 | self.pwmgr = passwordmgr(self.ui) | |||
|
421 | ||||
414 | def https_open(self, req): |
|
422 | def https_open(self, req): | |
415 | return self.do_open(httpsconnection, req) |
|
423 | self.auth = self.pwmgr.readauthtoken(req.get_full_url()) | |
|
424 | return self.do_open(self._makeconnection, req) | |||
|
425 | ||||
|
426 | def _makeconnection(self, host, port=443, *args, **kwargs): | |||
|
427 | keyfile = None | |||
|
428 | certfile = None | |||
|
429 | ||||
|
430 | if args: # key_file | |||
|
431 | keyfile = args.pop(0) | |||
|
432 | if args: # cert_file | |||
|
433 | certfile = args.pop(0) | |||
|
434 | ||||
|
435 | # if the user has specified different key/cert files in | |||
|
436 | # hgrc, we prefer these | |||
|
437 | if self.auth and 'key' in self.auth and 'cert' in self.auth: | |||
|
438 | keyfile = self.auth['key'] | |||
|
439 | certfile = self.auth['cert'] | |||
|
440 | ||||
|
441 | return httpsconnection(host, port, keyfile, certfile, *args, **kwargs) | |||
416 |
|
442 | |||
417 | # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if |
|
443 | # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if | |
418 | # it doesn't know about the auth type requested. This can happen if |
|
444 | # it doesn't know about the auth type requested. This can happen if | |
@@ -460,7 +486,7 b' def opener(ui, authinfo=None):' | |||||
460 | ''' |
|
486 | ''' | |
461 | handlers = [httphandler()] |
|
487 | handlers = [httphandler()] | |
462 | if has_https: |
|
488 | if has_https: | |
463 | handlers.append(httpshandler()) |
|
489 | handlers.append(httpshandler(ui)) | |
464 |
|
490 | |||
465 | handlers.append(proxyhandler(ui)) |
|
491 | handlers.append(proxyhandler(ui)) | |
466 |
|
492 |
General Comments 0
You need to be logged in to leave comments.
Login now