source code of /small-scripts/school-stuff/cloudauth.py

Last modified
Lines 144
Indexable No

Parent directory Download CGIread sitemap Main page

Quick links: lock_files log mk_key passwd_ok unlock_files

  1. #!/usr/bin/python
  2. import hashlib
  3. import time
  4. import os
  5. import pprint
  6. import fcntl
  7. assert __name__ != '__main__'
  8. # HA-HA, you cannot wait for the password ID you'd like!
  9. MAX_KEYS = 5
  10. myhash = lambda x: hashlib.sha1(x).hexdigest()
  11. ext_key = open('/var/www-secret/cloud.passwd-key').read()
  12. lock_f = None
  13. def lock_files():
  14.     '''
  15.     '''
  16.     global lock_f
  17.     lock_f = open('/var/www-secret/cloud.lock', 'w')
  18.     fcntl.lockf(lock_f, fcntl.LOCK_EX)
  19. def unlock_files():
  20.     '''
  21.     '''
  22.     global lock_f
  23.     fcntl.lockf(lock_f, fcntl.LOCK_UN)
  24.     lock_f.close()
  25. def log(what):
  26.     '''
  27.     '''
  28.     f = open('/var/log/cloudauth.log', 'a')
  29.     f.write('{} {} {}\n"{} {}" "{}" "{}"\n\n'.format(
  30.         time.strftime('%F %H:%M:%S'),
  31.         os.getenv('REMOTE_ADDR'),
  32.         what,
  33.         os.getenv('REQUEST_METHOD'),
  34.         os.getenv('REQUEST_URI'),
  35.         os.getenv('HTTP_USER_AGENT'),
  36.         os.getenv('HTTP_REFERER'),
  37.     ))
  38.     f.close()
  39. def mk_key():
  40.     '''
  41.     '''
  42.     lock_files()
  43.     
  44.     nkeys = []
  45.     for x in eval(open('/var/www-secret/cloud.nkeys').read()):
  46.         if x + 900 > time.time():
  47.             nkeys.append(x)
  48.     
  49.     if len(nkeys) > MAX_KEYS:
  50.         key = '{}_{}+{}'.format('HA-HA', int(time.time()), 'badkey')
  51.         log('nkeys ({}) > MAX_KEYS ({})'.format(len(nkeys), MAX_KEYS))
  52.     else:
  53.         nkeys.append(time.time())
  54.         f = open('/var/www-secret/cloud.nkeys', 'w')
  55.         f.write(pprint.pformat(nkeys))
  56.         f.close()
  57.         
  58.         # key = RND_time_CHK
  59.         n_passwds = len(eval(open('/var/www-secret/cloud.passwd').read()))
  60.         rnd = n_passwds
  61.         while rnd >= n_passwds:
  62.             rnd = ord(os.urandom(1))
  63.         gen_time = int(time.time())
  64.         s = '{}_{}'.format(hex(rnd), gen_time)
  65.         chk = myhash(s + ext_key)
  66.         key = '{}+{}'.format(s, chk)
  67.         log('Generated: ' + key)
  68.     
  69.     unlock_files()
  70.     return key
  71. def passwd_ok(passwd, key, maxtime):
  72.     '''
  73.     '''
  74.     lock_files()
  75.     
  76.     # Prevent an unicode related attack on the used_keys list.
  77.     key.encode('ascii')
  78.     passwd.encode('ascii')
  79.     
  80.     # Used keys.        Cleared after a day.
  81.     used_keys = filter(
  82.     lambda x: int(x.split('_')[1].split('+')[0]) + 86400 > time.time(),
  83.     eval(open('/var/www-secret/cloud.used-keys').read())
  84.     )
  85.     
  86.     # Temporary block.
  87.     unlock = eval(open('/var/www-secret/cloud.nologin').read())
  88.     
  89.     passwds = eval(open('/var/www-secret/cloud.passwd').read())
  90.     
  91.     real_key, chk = key.split('+')
  92.     raw_passwd_index, raw_gen_time = real_key.split('_')
  93.     passwd_index, gen_time = int(raw_passwd_index, 16), int(raw_gen_time)
  94.     
  95.     oka = (myhash(real_key + ext_key) == chk)
  96.     okb = (gen_time + maxtime > time.time())
  97.     okc = (passwds[passwd_index] == passwd)
  98.     okd = (key not in used_keys)
  99.     oke = (time.time() > unlock)
  100.     
  101.     log('Key "{}" hash={} time={} passwd={} norepeat={} noblock={}'.format(
  102.                 key, oka, okb, okc, okd, oke))
  103.     
  104.     if okd:
  105.         nkeys = eval(open('/var/www-secret/cloud.nkeys').read())
  106.         nkeys.pop(0)
  107.         f = open('/var/www-secret/cloud.nkeys', 'w')
  108.         f.write(pprint.pformat(nkeys))
  109.         f.close()
  110.     
  111.     ok = oka & okb & okc & okd & oke
  112.     
  113.     if ok:
  114.         # Key can no longer be used.
  115.         used_keys.append(key)
  116.     else:
  117.         if time.time() > unlock:
  118.             # First penalty: 2 min.
  119.             unlock = int(time.time() + 120)
  120.         else:
  121.             # Nth penalty: +5 min.
  122.             unlock += 300
  123.         f = open('/var/www-secret/cloud.nologin', 'w')
  124.         log('Unlock: ' + time.ctime(unlock))
  125.         f.write(str(unlock))
  126.         f.close()
  127.     
  128.     f = open('/var/www-secret/cloud.used-keys', 'w')
  129.     f.write(pprint.pformat(used_keys))
  130.     f.close()
  131.     
  132.     unlock_files()
  133.     return ok