Mercurial > templog
comparison web/secure.py @ 211:59379b2bd056
key fingerprints are case- and whitespace-insensitive.
add some comments
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 26 Jun 2014 23:02:23 +0800 |
parents | 4fa8cbf31065 |
children | da769023bf08 |
comparison
equal
deleted
inserted
replaced
210:3f403e22c2e3 | 211:59379b2bd056 |
---|---|
1 import re | |
1 import os | 2 import os |
2 import time | 3 import time |
3 import fcntl | 4 import fcntl |
4 import hmac | 5 import hmac |
5 import binascii | 6 import binascii |
8 | 9 |
9 import bottle | 10 import bottle |
10 | 11 |
11 import config | 12 import config |
12 | 13 |
13 __all__ = ["get_csrf_blob", "check_csrf_blob", "setup_csrf", "get_user_hash"] | 14 __all__ = ["get_csrf_blob", "check_csrf_blob", "setup_csrf", "get_user_hash", |
15 "check_user_hash"] | |
14 | 16 |
15 HASH=hashlib.sha1 | 17 HASH=hashlib.sha1 |
16 | 18 |
19 CLEAN_RE = re.compile('[^a-z0-9A-Z]') | |
20 | |
21 def clean_hash(h): | |
22 return CLEAN_RE.sub('', h.lower()) | |
23 | |
17 def get_user_hash(): | 24 def get_user_hash(): |
25 """ | |
26 Uses the following apache config. | |
27 Needs a separate port or IP to no-certificate SSL, SNI isn't good enough. | |
28 | |
29 <location /~matt/templog/set> | |
30 Require all granted | |
31 SSLVerifyClient optional_no_ca | |
32 SSLVerifyDepth 1 | |
33 SSLOptions +StdEnvVars +ExportCertData +OptRenegotiate | |
34 </location> | |
35 """ | |
36 | |
18 verify = bottle.request.environ.get('SSL_CLIENT_VERIFY', '') | 37 verify = bottle.request.environ.get('SSL_CLIENT_VERIFY', '') |
19 if not (verify == 'GENEROUS' or verify == 'SUCCESS'): | 38 if not (verify == 'GENEROUS' or verify == 'SUCCESS'): |
20 return 'FAILVERIFY' | 39 return 'FAILVERIFY' |
21 blob = bottle.request.environ.get('SSL_CLIENT_CERT') | 40 blob = bottle.request.environ.get('SSL_CLIENT_CERT') |
22 if not blob: | 41 if not blob: |
24 | 43 |
25 b64 = ''.join(l for l in blob.split('\n') | 44 b64 = ''.join(l for l in blob.split('\n') |
26 if not l.startswith('-')) | 45 if not l.startswith('-')) |
27 | 46 |
28 return HASH(binascii.a2b_base64(b64)).hexdigest() | 47 return HASH(binascii.a2b_base64(b64)).hexdigest() |
48 | |
49 def check_user_hash(allowed_users): | |
50 current_hash = clean_hash(get_user_hash()) | |
51 for a in allowed_users: | |
52 if current_hash == clean_hash(a): | |
53 return True | |
54 return False | |
29 | 55 |
30 def setup_csrf(): | 56 def setup_csrf(): |
31 NONCE_SIZE=16 | 57 NONCE_SIZE=16 |
32 global _csrf_fd, _csrf_key | 58 global _csrf_fd, _csrf_key |
33 _csrf_fd = open('%s/csrf.dat' % config.DATA_PATH, 'r+') | 59 _csrf_fd = open('%s/csrf.dat' % config.DATA_PATH, 'r+') |