/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/_urllib2_wrappers.py

  • Committer: Vincent Ladeuil
  • Date: 2009-05-04 15:21:26 UTC
  • mto: (4349.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4350.
  • Revision ID: v.ladeuil+lp@free.fr-20090504152126-13juy7bmikof23xc
Tighten multiple auth schemes handling.

* bzrlib/transport/http/_urllib2_wrappers.py:
(AbstractAuthHandler): Add a 'scheme' attribute to identify the
handlers.
(AbstractAuthHandler.auth_required): Once the most secured scheme
is known to be proposed by the server, the other handlers should
not be tried.

Show diffs side-by-side

added added

removed removed

Lines of Context:
978
978
      successful and the request authentication parameters have been updated.
979
979
    """
980
980
 
 
981
    scheme = None
 
982
    """The scheme as it appears in the server header (lower cased)"""
 
983
 
981
984
    _max_retry = 3
982
985
    """We don't want to retry authenticating endlessly"""
983
986
 
1044
1047
        auth = self.get_auth(request)
1045
1048
        auth['modified'] = False
1046
1049
        # FIXME: the auth handler should be selected at a single place instead
1047
 
        # of letting all handlers try to match all headers.
 
1050
        # of letting all handlers try to match all headers, but the current
 
1051
        # design doesn't allow a simple implementation.
1048
1052
        for server_header in server_headers:
1049
1053
            # Several schemes can be proposed by the server, try to match each
1050
1054
            # one in turn
1057
1061
                    # We already tried that, give up
1058
1062
                    return None
1059
1063
 
 
1064
                # Only the most secure scheme proposed by the server should be
 
1065
                # used, since the handlers use 'handler_order' to describe that
 
1066
                # property, the first handler tried takes precedence, the
 
1067
                # others should not attempt to authenticate if the best one
 
1068
                # failed.
 
1069
                best_scheme = auth.get('best_scheme', None)
 
1070
                if best_scheme is None:
 
1071
                    # At that point, if current handler should doesn't succeed
 
1072
                    # the credentials are wrong (or incomplete), but we know
 
1073
                    # that the associated scheme should be used.
 
1074
                    best_scheme = auth['best_scheme'] = self.scheme
 
1075
                if  best_scheme != self.scheme:
 
1076
                    continue
 
1077
 
1060
1078
                if self.requires_username and auth.get('user', None) is None:
1061
1079
                    # Without a known user, we can't authenticate
1062
1080
                    return None
1199
1217
    NTLM support may also be added.
1200
1218
    """
1201
1219
 
 
1220
    scheme = 'negotiate'
1202
1221
    handler_order = 480
1203
 
 
1204
1222
    requires_username = False
1205
1223
 
1206
1224
    def auth_match(self, header, auth):
1207
1225
        scheme, raw_auth = self._parse_auth_header(header)
1208
 
        if scheme != 'negotiate':
 
1226
        if scheme != self.scheme:
1209
1227
            return False
1210
1228
        self.update_auth(auth, 'scheme', scheme)
1211
1229
        resp = self._auth_match_kerberos(auth)
1244
1262
class BasicAuthHandler(AbstractAuthHandler):
1245
1263
    """A custom basic authentication handler."""
1246
1264
 
 
1265
    scheme = 'basic'
1247
1266
    handler_order = 500
1248
 
 
1249
1267
    auth_regexp = re.compile('realm="([^"]*)"', re.I)
1250
1268
 
1251
1269
    def build_auth_header(self, auth, request):
1262
1280
 
1263
1281
    def auth_match(self, header, auth):
1264
1282
        scheme, raw_auth = self._parse_auth_header(header)
1265
 
        if scheme != 'basic':
 
1283
        if scheme != self.scheme:
1266
1284
            return False
1267
1285
 
1268
1286
        match, realm = self.extract_realm(raw_auth)
1304
1322
class DigestAuthHandler(AbstractAuthHandler):
1305
1323
    """A custom digest authentication handler."""
1306
1324
 
 
1325
    scheme = 'digest'
1307
1326
    # Before basic as digest is a bit more secure and should be preferred
1308
1327
    handler_order = 490
1309
1328
 
1315
1334
 
1316
1335
    def auth_match(self, header, auth):
1317
1336
        scheme, raw_auth = self._parse_auth_header(header)
1318
 
        if scheme != 'digest':
 
1337
        if scheme != self.scheme:
1319
1338
            return False
1320
1339
 
1321
1340
        # Put the requested authentication info into a dict