def decode(self, response, request): """ Do the default behavior but then strip out any 'qop' from the credential fields if no qop was specified. """ """ Decode the given response and attempt to generate a L{DigestedCredentials} from it. @type response: C{str} @param response: A string of comma seperated key=value pairs @type request: L{txweb2.server.Request} @param request: the request being processed @return: L{DigestedCredentials} @raise: L{error.LoginFailed} if the response does not contain a username, a nonce, an opaque, or if the opaque is invalid. """ response = ' '.join(response.splitlines()) try: parts = split(tokenize((response,), foldCase=False), Token(",")) auth = {} for (k, v) in [parseKeyValue(p) for p in parts]: auth[k.strip()] = v.strip() except ValueError: raise error.LoginFailed('Invalid response.') username = auth.get('username') if not username: raise error.LoginFailed('Invalid response, no username given.') if 'nonce' not in auth: raise error.LoginFailed('Invalid response, no nonce given.') # Now verify the nonce/cnonce values for this client result = (yield self._validate(auth, request)) if result: if hasattr(request, "originalMethod"): originalMethod = request.originalMethod else: originalMethod = None credentials = DigestedCredentials(username, originalMethod or request.method, self._real.authenticationRealm, auth) if not self.qop and credentials.fields.has_key('qop'): del credentials.fields['qop'] returnValue(credentials) else: raise error.LoginFailed('Invalid nonce/cnonce values')
def decode(self, response, request): """ Do the default behavior but then strip out any 'qop' from the credential fields if no qop was specified. """ """ Decode the given response and attempt to generate a L{DigestedCredentials} from it. @type response: C{str} @param response: A string of comma seperated key=value pairs @type request: L{txweb2.server.Request} @param request: the request being processed @return: L{DigestedCredentials} @raise: L{error.LoginFailed} if the response does not contain a username, a nonce, an opaque, or if the opaque is invalid. """ response = ' '.join(response.splitlines()) try: parts = split(tokenize((response,), foldCase=False), Token(",")) auth = {} for (k, v) in [parseKeyValue(p) for p in parts]: auth[k.strip()] = v.strip() except ValueError: raise error.LoginFailed('Invalid response.') username = auth.get('username') if not username: raise error.LoginFailed('Invalid response, no username given.') if 'nonce' not in auth: raise error.LoginFailed('Invalid response, no nonce given.') # Now verify the nonce/cnonce values for this client result = (yield self._validate(auth, request)) if result: if hasattr(request, "originalMethod"): originalMethod = request.originalMethod else: originalMethod = None credentials = DigestedCredentials(username, originalMethod or request.method, self._real.authenticationRealm, auth) if not self.qop and 'qop' in credentials.fields: del credentials.fields['qop'] returnValue(credentials) else: raise error.LoginFailed('Invalid nonce/cnonce values')
def testParse(self): parser = lambda val: list(http_headers.tokenize([val, ])) Token = http_headers.Token tests = (('foo,bar', ['foo', Token(','), 'bar']), ('FOO,BAR', ['foo', Token(','), 'bar']), (' \t foo \t bar \t , \t baz ', ['foo', Token(' '), 'bar', Token(','), 'baz']), ('()<>@,;:\\/[]?={}', [Token('('), Token(')'), Token('<'), Token('>'), Token('@'), Token(','), Token(';'), Token(':'), Token('\\'), Token('/'), Token('['), Token(']'), Token('?'), Token('='), Token('{'), Token('}')]), (' "foo" ', ['foo']), ('"FOO(),\\"BAR,"', ['FOO(),"BAR,'])) raiseTests = ('"open quote', '"ending \\', "control character: \x127", "\x00", "\x1f") for test, result in tests: self.assertEquals(parser(test), result) for test in raiseTests: self.assertRaises(ValueError, parser, test)
def _readHeaders(stream): """Read the MIME headers. Assumes we've just finished reading in the boundary string.""" ctype = fieldname = filename = None headers = [] # Now read headers while 1: line = stream.readline(size=1024) if isinstance(line, defer.Deferred): line = defer.waitForDeferred(line) yield line line = line.getResult() # print("GOT", line) if not line.endswith('\r\n'): if line == "": raise MimeFormatError("Unexpected end of stream.") else: raise MimeFormatError("Header line too long") line = line[:-2] # strip \r\n if line == "": break # End of headers parts = line.split(':', 1) if len(parts) != 2: raise MimeFormatError("Header did not have a :") name, value = parts name = name.lower() headers.append((name, value)) if name == "content-type": ctype = http_headers.parseContentType( http_headers.tokenize((value, ), foldCase=False)) elif name == "content-disposition": fieldname, filename = parseContentDispositionFormData(value) if ctype is None: ctype = http_headers.MimeType('application', 'octet-stream') if fieldname is None: raise MimeFormatError('Content-disposition invalid or omitted.') # End of headers, return (field name, content-type, filename) yield fieldname, filename, ctype return
def _readHeaders(stream): """Read the MIME headers. Assumes we've just finished reading in the boundary string.""" ctype = fieldname = filename = None headers = [] # Now read headers while 1: line = stream.readline(size=1024) if isinstance(line, defer.Deferred): line = defer.waitForDeferred(line) yield line line = line.getResult() # print("GOT", line) if not line.endswith("\r\n"): if line == "": raise MimeFormatError("Unexpected end of stream.") else: raise MimeFormatError("Header line too long") line = line[:-2] # strip \r\n if line == "": break # End of headers parts = line.split(":", 1) if len(parts) != 2: raise MimeFormatError("Header did not have a :") name, value = parts name = name.lower() headers.append((name, value)) if name == "content-type": ctype = http_headers.parseContentType(http_headers.tokenize((value,), foldCase=False)) elif name == "content-disposition": fieldname, filename = parseContentDispositionFormData(value) if ctype is None: ctype == http_headers.MimeType("application", "octet-stream") if fieldname is None: raise MimeFormatError("Content-disposition invalid or omitted.") # End of headers, return (field name, content-type, filename) yield fieldname, filename, ctype return