@@ -256,126 +256,6 @@ def status_code(code):
256256 return r
257257
258258
259- def check_basic_auth (user , passwd ):
260- """Checks user authentication using HTTP Basic Auth."""
261-
262- auth = request .authorization
263- return auth and auth .username == user and auth .password == passwd
264-
265-
266- # Digest auth helpers
267- # qop is a quality of protection
268-
269-
270- def H (data , algorithm ):
271- if algorithm == 'SHA-256' :
272- return sha256 (data ).hexdigest ()
273- elif algorithm == 'SHA-512' :
274- return sha512 (data ).hexdigest ()
275- else :
276- return md5 (data ).hexdigest ()
277-
278-
279- def HA1 (realm , username , password , algorithm ):
280- """Create HA1 hash by realm, username, password
281-
282- HA1 = md5(A1) = MD5(username:realm:password)
283- """
284- if not realm :
285- realm = u''
286- return H (b":" .join ([username .encode ('utf-8' ),
287- realm .encode ('utf-8' ),
288- password .encode ('utf-8' )]), algorithm )
289-
290-
291- def HA2 (credentials , request , algorithm ):
292- """Create HA2 md5 hash
293-
294- If the qop directive's value is "auth" or is unspecified, then HA2:
295- HA2 = md5(A2) = MD5(method:digestURI)
296- If the qop directive's value is "auth-int" , then HA2 is
297- HA2 = md5(A2) = MD5(method:digestURI:MD5(entityBody))
298- """
299- if credentials .get ("qop" ) == "auth" or credentials .get ('qop' ) is None :
300- return H (b":" .join ([request ['method' ].encode ('utf-8' ), request ['uri' ].encode ('utf-8' )]), algorithm )
301- elif credentials .get ("qop" ) == "auth-int" :
302- for k in 'method' , 'uri' , 'body' :
303- if k not in request :
304- raise ValueError ("%s required" % k )
305- A2 = b":" .join ([request ['method' ].encode ('utf-8' ),
306- request ['uri' ].encode ('utf-8' ),
307- H (request ['body' ], algorithm ).encode ('utf-8' )])
308- return H (A2 , algorithm )
309- raise ValueError
310-
311-
312- def response (credentials , password , request ):
313- """Compile digest auth response
314-
315- If the qop directive's value is "auth" or "auth-int" , then compute the response as follows:
316- RESPONSE = MD5(HA1:nonce:nonceCount:clienNonce:qop:HA2)
317- Else if the qop directive is unspecified, then compute the response as follows:
318- RESPONSE = MD5(HA1:nonce:HA2)
319-
320- Arguments:
321- - `credentials`: credentials dict
322- - `password`: request user password
323- - `request`: request dict
324- """
325- response = None
326- algorithm = credentials .get ('algorithm' )
327- HA1_value = HA1 (
328- credentials .get ('realm' ),
329- credentials .get ('username' ),
330- password ,
331- algorithm
332- )
333- HA2_value = HA2 (credentials , request , algorithm )
334- if credentials .get ('qop' ) is None :
335- response = H (b":" .join ([
336- HA1_value .encode ('utf-8' ),
337- credentials .get ('nonce' , '' ).encode ('utf-8' ),
338- HA2_value .encode ('utf-8' )
339- ]), algorithm )
340- elif credentials .get ('qop' ) == 'auth' or credentials .get ('qop' ) == 'auth-int' :
341- for k in 'nonce' , 'nc' , 'cnonce' , 'qop' :
342- if k not in credentials :
343- raise ValueError ("%s required for response H" % k )
344- response = H (b":" .join ([HA1_value .encode ('utf-8' ),
345- credentials .get ('nonce' ).encode ('utf-8' ),
346- credentials .get ('nc' ).encode ('utf-8' ),
347- credentials .get ('cnonce' ).encode ('utf-8' ),
348- credentials .get ('qop' ).encode ('utf-8' ),
349- HA2_value .encode ('utf-8' )]), algorithm )
350- else :
351- raise ValueError ("qop value are wrong" )
352-
353- return response
354-
355-
356- def check_digest_auth (user , passwd ):
357- """Check user authentication using HTTP Digest auth"""
358-
359- if request .headers .get ('Authorization' ):
360- credentials = Authorization .from_header (request .headers .get ('Authorization' ))
361- if not credentials :
362- return
363- request_uri = request .script_root + request .path
364- if request .query_string :
365- request_uri += '?' + request .query_string
366- response_hash = response (credentials , passwd , dict (uri = request_uri ,
367- body = request .data ,
368- method = request .method ))
369- if credentials .get ('response' ) == response_hash :
370- return True
371- return False
372-
373-
374- def secure_cookie ():
375- """Return true if cookie should have secure attribute"""
376- return request .environ ['wsgi.url_scheme' ] == 'https'
377-
378-
379259def __parse_request_range (range_header_text ):
380260 """ Return a tuple describing the byte range requested in a GET request
381261 If the range is open ended on the left or right side, then a value of None
@@ -453,28 +333,3 @@ def next_stale_after_value(stale_after):
453333 return str (stal_after_count )
454334 except ValueError :
455335 return 'never'
456-
457-
458- def digest_challenge_response (app , qop , algorithm , stale = False ):
459- response = app .make_response ('' )
460- response .status_code = 401
461-
462- # RFC2616 Section4.2: HTTP headers are ASCII. That means
463- # request.remote_addr was originally ASCII, so I should be able to
464- # encode it back to ascii. Also, RFC2617 says about nonces: "The
465- # contents of the nonce are implementation dependent"
466- nonce = H (b'' .join ([
467- getattr (request , 'remote_addr' , u'' ).encode ('ascii' ),
468- b':' ,
469- str (time .time ()).encode ('ascii' ),
470- b':' ,
471- os .urandom (10 )
472- ]), algorithm )
473- opaque = H (os .urandom (10 ), algorithm )
474-
475- auth = WWWAuthenticate ("digest" )
476- auth .
set_digest (
'[email protected] ' ,
nonce ,
opaque = opaque ,
477- qop = ('auth' , 'auth-int' ) if qop is None else (qop ,), algorithm = algorithm )
478- auth .stale = stale
479- response .headers ['WWW-Authenticate' ] = auth .to_header ()
480- return response
0 commit comments