requests/requests-kerberos — pull request #10 by mkomitee (2013-03-09 16:08:56+00:00)
Title: Significant refactor for 1.1.0 API

## Introduction

As the original author to this library, I've learned quite a bit about kerberos since I initially drafted it. This is an attempt to both make the code work correctly with the v1.1.0 API, and to also be more correct and secure. For example, we weren't authenticating the servers response, ... we were requesting the response a second time and authenticating that. There's no need. Similarly, we weren't requiring mutual authentication, and there was no way to do so. We were simply performing mutual authentication if the server sent the right header. Now we can state whether we require it completely, would like to use it opportunistically, or just ignore it. These are security decisions the user should make, and not us. I've chosen to follow the example in requests (with SSL) and default to more secure.

## Possible Issues

### Multiple commits?

I worked on this on and off over the last few months in my spare time and the code evolved into this state over time. It took longer than expected in part because there were changes that needed to be merged into requests before this could be implemented completely and correctly. I'm submitting this as one commit because breaking it out into sensible individual commits would be quite difficult. If you'd prefer smaller commits, take a look in my master branch which has smaller commits, but a lot of intermediate and unusable junk as well.

### Testsuite & 3.x?

This includes a test suite which passes on 2.7 and 2.6. It MAY pass on 3.3, but I can't get the kerberos library to install into my 3.3 virtualenv, so there's a chance it fails. I've also had one independent tester verify that not only the tests pass in his environment, the code performs as expected.

## Changes

### Rename kerberos module to kerberos_

Our kerberos module itself imports kerberos, expecting to get the kerberos package, but it currently gets itself, which means none of the kerberos library routines are actually available and everything is a non-starter. This follows PEP8 for what to do when you have a variable that conflicts with a builtin. Add a trailing _.

### Handle errors more sensibly

If authentication fails, the server response will be passed to the user. This is likely to be a 401. A 403 would indicate successful authentication with an unauthorized user. If the client requires mutual authentication (the default, similar to SSL certificate validation in requests proper), an exception will be raised so that the user does not have the opportunity to accept an untrusted response. If they're okay without requiring
mutual authentication, then they can specify that when constructing their HTTPKerberosAuth object.

### 1.x API Change

Request objects no longer have a send mechanism. We need to either generate a session and send with that or just use the connection connected to the response object. This was essentially stolen from HTTPDigest authentication and another pull request.

### Fix incorrect implementation of mutual authentication

Performing another request during mutual authentication does not make sense. We're authenticating the response we already received.

### Allow different settings for mutual authentication

* REQUIRED: all responses will be authenticated with the exception of errors. Errors will have their contents and headers stripped. If a non-error response cannot be authenticated, a MutualAuthenticationError exception will be raised.
* OPTIONAL: mutual authentication will be attempted if supported, and if supported and failed, a MutualAuthenticationError exception will be raised. Responses which do not support mutual authentication will be returned directly to the user.
* DISABLED: mutual authentication will not be attempted, even if supported.

### Support authentication of redirects

Track multiple contexts so that if/when we can authenticate redirects, we can support redirects to different hosts.

This is the right thing to do and required some changes in requests which is part of the reason why it took so long for this pull request to be submit.

### Sanitize untrusted responses

We want to be able to return unauthenticated errors to the user because they can be helpful in debugging, but we want to ensure that their content isn't used because the user is trusting us not to give them untrusted data. Hence the SanitizedResponse class.

### Use user supplied options when retransmitting authenticated requests

This is the right thing to do and required some changes in requests which is part of the reason why it took so long for this pull request to be submit.

### Generate a test suite

Huzzah.