From ae0a36c9a59e7f872578b17b3b7fa8f72df3cb59 Mon Sep 17 00:00:00 2001 From: Xiaodong Xu Date: Tue, 31 Jan 2012 11:10:09 +0800 Subject: [PATCH] Add support for Apache Digest authentication for repo init. repo tool supports only Basic authentication for now. For those who want to use this tool to manage their own projects, in case the administrator has configured the Apache server with Digest authentication method, users will fail to be authenticated when they run the command 'repo init'. Add the digest authentication password manager to the handler list will fix this issue. Since Git HTTP protocol will require the user be authenticated for fetch operation first before pushing commits to the remote, it is unlikely for the administrator to implement anonymous read (aka pull) access and write access (aka push) for authenticated user. Both read and write have to be authenticated. Be aware that the user may have to add an extra line in his ~/.netrc file: ------------------- account example.com ------------------- where 'example.com' is the realm for Apache Digest authentication. Change-Id: I76eb27b205554426d9ce1965deaaf727b87916cd Signed-off-by: Xiaodong Xu --- main.py | 23 +++++++++++++++++++++-- repo | 9 +++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index a4cf4304..ea29851e 100755 --- a/main.py +++ b/main.py @@ -295,6 +295,24 @@ class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler): self.retried = 0 raise +class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler): + def http_error_auth_reqed(self, auth_header, host, req, headers): + try: + old_add_header = req.add_header + def _add_header(name, val): + val = val.replace('\n', '') + old_add_header(name, val) + req.add_header = _add_header + return urllib2.AbstractDigestAuthHandler.http_error_auth_reqed( + self, auth_header, host, req, headers) + except: + reset = getattr(self, 'reset_retry_count', None) + if reset is not None: + reset() + elif getattr(self, 'retried', None): + self.retried = 0 + raise + def init_http(): handlers = [_UserAgentHandler()] @@ -303,13 +321,14 @@ def init_http(): n = netrc.netrc() for host in n.hosts: p = n.hosts[host] - mgr.add_password(None, 'http://%s/' % host, p[0], p[2]) - mgr.add_password(None, 'https://%s/' % host, p[0], p[2]) + mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) + mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) except netrc.NetrcParseError: pass except IOError: pass handlers.append(_BasicAuthHandler(mgr)) + handlers.append(_DigestAuthHandler(mgr)) if 'http_proxy' in os.environ: url = os.environ['http_proxy'] diff --git a/repo b/repo index 2a13af5b..1977d635 100755 --- a/repo +++ b/repo @@ -28,7 +28,7 @@ if __name__ == '__main__': del magic # increment this whenever we make important changes to this script -VERSION = (1, 13) +VERSION = (1, 14) # increment this if the MAINTAINER_KEYS block is modified KEYRING_VERSION = (1,0) @@ -154,7 +154,7 @@ def _Init(args): """Installs repo by cloning it over the network. """ opt, args = init_optparse.parse_args(args) - if args or not opt.manifest_url: + if args: init_optparse.print_usage() sys.exit(1) @@ -311,11 +311,12 @@ def _InitHttp(): n = netrc.netrc() for host in n.hosts: p = n.hosts[host] - mgr.add_password(None, 'http://%s/' % host, p[0], p[2]) - mgr.add_password(None, 'https://%s/' % host, p[0], p[2]) + mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) + mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) except: pass handlers.append(urllib2.HTTPBasicAuthHandler(mgr)) + handlers.append(urllib2.HTTPDigestAuthHandler(mgr)) if 'http_proxy' in os.environ: url = os.environ['http_proxy']