[MERGE] GSSAPI Authentication support for HTTP
Vincent Ladeuil
v.ladeuil+lp at free.fr
Tue Feb 17 10:29:12 GMT 2009
>>>>> "Jelmer" == Jelmer Vernooij <jelmer at samba.org> writes:
Jelmer> The attached patch adds support for WWW-Authenticate:
Jelmer> Negotiate using Kerberos (GSSAPI).
Great.
Jelmer> I've tested it here locally against a couple of
Jelmer> servers, but it's hard to do automated tests, as
Jelmer> setting up a KDC + mod_auth_kerberos is nontrivial.
You should try it via the lp:~vila/bzr/local_test_server plugin
anyway. That will document the steps you went through to get a
working Kerberos installation (and what means KDC ?).
Jelmer> Since this code is only executed for
Jelmer> "WWW-Authenticate: Negotiate", it can potentially
Jelmer> only break in situations that didn't work previously
Jelmer> anyway.
Which is a bit short of a reason to not test it :-)
Look at bzrlib.test.test_http.TestActivity for a way to test an
unmodified client against a server for which all responses are
pre-canned and bzrlib.test.test_http.TestAuth for tests currently
done for the supported authentication schemes.
Recording the session against a working http server with Kerberos
(with some random user/pass combo, but note that the tests use
joe/foo) should get most of the needed responses (AFAICT from the
client side you propose below).
If you encounter problems due to limitations in the canned
responses approach you may redefine some tests as being not
applicable until we get a proper test server (a local test server
counts as one :).
Jelmer> At the moment, it's necessary to specify a username
Jelmer> in the URL as bzr requires it for authentication,
Jelmer> even though this is not required by
Jelmer> Kerberos/GSSAPI. The specified username is ignored.
Patches welcome even if it implements only the part necessary to
make Negotiate remove that constraint while leaving it for the
other schemes.
Jelmer> # Bazaar merge directive format 2 (Bazaar 0.90)
Jelmer> # revision_id: jelmer at samba.org-20090217015430-62v560na6f1ngybp
Jelmer> # target_branch: http://bazaar-vcs.org/bzr/bzr.dev
Jelmer> # testament_sha1: c22b4672fb24f1beef348033eff85d841b22cb97
Jelmer> # timestamp: 2009-02-17 02:55:39 +0100
Jelmer> # base_revision_id: pqm at pqm.ubuntu.com-20090216172448-vj35mjoe463c3bk2
Jelmer> #
Jelmer> # Begin patch
Jelmer> === modified file 'NEWS'
Jelmer> --- NEWS 2009-02-15 22:56:22 +0000
Jelmer> +++ NEWS 2009-02-17 01:54:30 +0000
Jelmer> @@ -27,6 +27,8 @@
Jelmer> generation of a working tree in the new branch.
Jelmer> (Daniel Watkins, John Klinger, #273993)
Jelmer> + * Support for GSSAPI authentication when using HTTP. (Jelmer Vernooij)
Jelmer> +
Does it work for https too ? If so, it's worth mentioning (and
testing :-).
<snip/>
Jelmer> === modified file 'bzrlib/transport/http/_urllib2_wrappers.py'
Jelmer> --- bzrlib/transport/http/_urllib2_wrappers.py 2009-02-09 18:25:43 +0000
Jelmer> +++ bzrlib/transport/http/_urllib2_wrappers.py 2009-02-17 01:54:30 +0000
Jelmer> @@ -943,7 +943,7 @@
Jelmer> preventively set authentication headers after the first
Jelmer> successful authentication.
Jelmer> - This can be used for http and proxy, as well as for basic and
Jelmer> + This can be used for http and proxy, as well as for basic, negotiate and
Jelmer> digest authentications.
Jelmer> This provides an unified interface for all authentication handlers
Jelmer> @@ -1143,6 +1143,63 @@
Jelmer> https_request = http_request # FIXME: Need test
Jelmer> +class NegotiateAuthHandler(AbstractAuthHandler):
Jelmer> + """A authentication handler that handles WWW-Authenticate: Negotiate.
Jelmer> +
Jelmer> + At the moment this handler supports just Kerberos. In the future,
Jelmer> + NTLM support may also be added.
Jelmer> + """
Jelmer> +
Jelmer> + handler_order = 480
Jelmer> +
Jelmer> + auth_regexp = re.compile('realm="([^"]*)"', re.I)
Jelmer> +
Jelmer> + def auth_match(self, header, auth):
Jelmer> + try:
Jelmer> + scheme, raw_auth = header.split(None, 1)
Jelmer> + except ValueError:
Jelmer> + scheme = header
Jelmer> + raw_auth = ""
Jelmer> + scheme = scheme.lower()
Jelmer> + if scheme != 'negotiate':
Jelmer> + return False
Jelmer> + match = self.auth_regexp.search(raw_auth)
Jelmer> + if match:
Jelmer> + self.update_auth(auth, 'realm', match.groups()[0])
Jelmer> + self.update_auth(auth, 'scheme', scheme)
Jelmer> + resp = self._auth_match_kerberos(auth)
Jelmer> + if resp is None:
Jelmer> + return False
Jelmer> + # Optionally should try to authenticate using NTLM here
Jelmer> + self.update_auth(auth, 'negotiate_response', resp)
Jelmer> + return True
Jelmer> +
Jelmer> + def _auth_match_kerberos(self, auth):
Jelmer> + """Try to create a GSSAPI response for authenticating against a host."""
Jelmer> + try:
Jelmer> + import kerberos
Jelmer> + except ImportError:
Jelmer> + return None
That would be better done at the module level (setting some flag
on import errors) so that the import is attempted only once
instead of once by *connection*.
Jelmer> + ret, vc = kerberos.authGSSClientInit("HTTP@%(host)s" % auth)
Is it valid for https too ?
Jelmer> + if ret < 1:
Jelmer> + trace.warning('Unable to create GSSAPI context for %(host)s', auth)
Jelmer> + return None
What kind of error is that ? Shouldn't we give more feedback about
some bad credentials is it just some internal check that should
cover possible bugs in the implementation or server setup ?
Or is it just the way you detect that the server implements
Kerberos scheme ?
Jelmer> + ret = kerberos.authGSSClientStep(vc, "")
Jelmer> + if ret < 0:
Jelmer> + trace.mutter('authGSSClientStep failed: %d', ret)
Jelmer> + return None
Jelmer> + return kerberos.authGSSClientResponse(vc)
Jelmer> +
Jelmer> + def build_auth_header(self, auth, request):
Jelmer> + return "Negotiate %s" % auth['negotiate_response']
Jelmer> +
Jelmer> + def auth_params_reusable(self, auth):
Jelmer> + # If the auth scheme is known, it means a previous
Jelmer> + # authentication was successful, all information is
Jelmer> + # available, no further checks are needed.
Jelmer> + return auth.get('scheme', None) == 'negotiate'
Shouldn't you test the 'negotiate_response' here to ensure you
really authenticate before ?
In summary: the patch is warmly welcome, but since you have *now*
the knowledge and a working setup, it will be a shame to not
capture that knowledge in the tests, so:
BB:resubmit
Vincent
More information about the bazaar
mailing list