MobileBlur

Hex Artifact Content
Login

Artifact b01ffcca560a1aa17770c9434fa52a46300f3ab8:


0000: 69 6d 70 6f 72 74 20 6f 73 2c 20 74 69 6d 65 0a  import os, time.
0010: 66 72 6f 6d 20 67 6c 75 6f 6e 20 69 6d 70 6f 72  from gluon impor
0020: 74 20 70 6f 72 74 61 6c 6f 63 6b 65 72 0a 66 72  t portalocker.fr
0030: 6f 6d 20 67 6c 75 6f 6e 2e 61 64 6d 69 6e 20 69  om gluon.admin i
0040: 6d 70 6f 72 74 20 61 70 61 74 68 0a 66 72 6f 6d  mport apath.from
0050: 20 67 6c 75 6f 6e 2e 66 69 6c 65 75 74 69 6c 73   gluon.fileutils
0060: 20 69 6d 70 6f 72 74 20 72 65 61 64 5f 66 69 6c   import read_fil
0070: 65 0a 23 20 23 23 23 23 23 23 23 23 23 23 23 23  e.# ############
0080: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0090: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
00a0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 0a  ###############.
00b0: 23 20 23 23 20 6d 61 6b 65 20 73 75 72 65 20 61  # ## make sure a
00c0: 64 6d 69 6e 69 73 74 72 61 74 6f 72 20 69 73 20  dministrator is 
00d0: 6f 6e 20 6c 6f 63 61 6c 68 6f 73 74 20 6f 72 20  on localhost or 
00e0: 68 74 74 70 73 0a 23 20 23 23 23 23 23 23 23 23  https.# ########
00f0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0100: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0110: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0120: 23 23 23 0a 0a 68 74 74 70 5f 68 6f 73 74 20 3d  ###..http_host =
0130: 20 72 65 71 75 65 73 74 2e 65 6e 76 2e 68 74 74   request.env.htt
0140: 70 5f 68 6f 73 74 2e 73 70 6c 69 74 28 27 3a 27  p_host.split(':'
0150: 29 5b 30 5d 0a 0a 69 66 20 72 65 71 75 65 73 74  )[0]..if request
0160: 2e 65 6e 76 2e 77 65 62 32 70 79 5f 72 75 6e 74  .env.web2py_runt
0170: 69 6d 65 5f 67 61 65 3a 0a 20 20 20 20 73 65 73  ime_gae:.    ses
0180: 73 69 6f 6e 5f 64 62 20 3d 20 44 41 4c 28 27 67  sion_db = DAL('g
0190: 61 65 27 29 0a 20 20 20 20 73 65 73 73 69 6f 6e  ae').    session
01a0: 2e 63 6f 6e 6e 65 63 74 28 72 65 71 75 65 73 74  .connect(request
01b0: 2c 20 72 65 73 70 6f 6e 73 65 2c 20 64 62 3d 73  , response, db=s
01c0: 65 73 73 69 6f 6e 5f 64 62 29 0a 20 20 20 20 68  ession_db).    h
01d0: 6f 73 74 73 20 3d 20 28 68 74 74 70 5f 68 6f 73  osts = (http_hos
01e0: 74 2c 20 29 0a 0a 69 66 20 72 65 71 75 65 73 74  t, )..if request
01f0: 2e 65 6e 76 2e 68 74 74 70 5f 78 5f 66 6f 72 77  .env.http_x_forw
0200: 61 72 64 65 64 5f 66 6f 72 20 6f 72 20 72 65 71  arded_for or req
0210: 75 65 73 74 2e 69 73 5f 68 74 74 70 73 3a 0a 20  uest.is_https:. 
0220: 20 20 20 73 65 73 73 69 6f 6e 2e 73 65 63 75 72     session.secur
0230: 65 28 29 0a 65 6c 69 66 20 6e 6f 74 20 72 65 71  e().elif not req
0240: 75 65 73 74 2e 69 73 5f 6c 6f 63 61 6c 20 61 6e  uest.is_local an
0250: 64 20 6e 6f 74 20 44 45 4d 4f 5f 4d 4f 44 45 3a  d not DEMO_MODE:
0260: 0a 20 20 20 20 72 61 69 73 65 20 48 54 54 50 28  .    raise HTTP(
0270: 32 30 30 2c 20 54 28 27 41 64 6d 69 6e 20 69 73  200, T('Admin is
0280: 20 64 69 73 61 62 6c 65 64 20 62 65 63 61 75 73   disabled becaus
0290: 65 20 69 6e 73 65 63 75 72 65 20 63 68 61 6e 6e  e insecure chann
02a0: 65 6c 27 29 29 0a 0a 74 72 79 3a 0a 20 20 20 20  el'))..try:.    
02b0: 5f 63 6f 6e 66 69 67 20 3d 20 7b 7d 0a 20 20 20  _config = {}.   
02c0: 20 70 6f 72 74 20 3d 20 69 6e 74 28 72 65 71 75   port = int(requ
02d0: 65 73 74 2e 65 6e 76 2e 73 65 72 76 65 72 5f 70  est.env.server_p
02e0: 6f 72 74 20 6f 72 20 30 29 0a 20 20 20 20 72 65  ort or 0).    re
02f0: 73 74 72 69 63 74 65 64 28 72 65 61 64 5f 66 69  stricted(read_fi
0300: 6c 65 28 61 70 61 74 68 28 27 2e 2e 2f 70 61 72  le(apath('../par
0310: 61 6d 65 74 65 72 73 5f 25 69 2e 70 79 27 20 25  ameters_%i.py' %
0320: 20 70 6f 72 74 2c 20 72 65 71 75 65 73 74 29 29   port, request))
0330: 2c 20 5f 63 6f 6e 66 69 67 29 0a 0a 20 20 20 20  , _config)..    
0340: 69 66 20 6e 6f 74 20 27 70 61 73 73 77 6f 72 64  if not 'password
0350: 27 20 69 6e 20 5f 63 6f 6e 66 69 67 20 6f 72 20  ' in _config or 
0360: 6e 6f 74 20 5f 63 6f 6e 66 69 67 5b 27 70 61 73  not _config['pas
0370: 73 77 6f 72 64 27 5d 3a 0a 20 20 20 20 20 20 20  sword']:.       
0380: 20 72 61 69 73 65 20 48 54 54 50 28 32 30 30 2c   raise HTTP(200,
0390: 20 54 28 27 61 64 6d 69 6e 20 64 69 73 61 62 6c   T('admin disabl
03a0: 65 64 20 62 65 63 61 75 73 65 20 6e 6f 20 61 64  ed because no ad
03b0: 6d 69 6e 20 70 61 73 73 77 6f 72 64 27 29 29 0a  min password')).
03c0: 65 78 63 65 70 74 20 49 4f 45 72 72 6f 72 3a 0a  except IOError:.
03d0: 20 20 20 20 69 6d 70 6f 72 74 20 67 6c 75 6f 6e      import gluon
03e0: 2e 66 69 6c 65 75 74 69 6c 73 0a 20 20 20 20 69  .fileutils.    i
03f0: 66 20 72 65 71 75 65 73 74 2e 65 6e 76 2e 77 65  f request.env.we
0400: 62 32 70 79 5f 72 75 6e 74 69 6d 65 5f 67 61 65  b2py_runtime_gae
0410: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 67 6c 75  :.        if glu
0420: 6f 6e 2e 66 69 6c 65 75 74 69 6c 73 2e 63 68 65  on.fileutils.che
0430: 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c 73 28 72  ck_credentials(r
0440: 65 71 75 65 73 74 29 3a 0a 20 20 20 20 20 20 20  equest):.       
0450: 20 20 20 20 20 73 65 73 73 69 6f 6e 2e 61 75 74       session.aut
0460: 68 6f 72 69 7a 65 64 20 3d 20 54 72 75 65 0a 20  horized = True. 
0470: 20 20 20 20 20 20 20 20 20 20 20 73 65 73 73 69             sessi
0480: 6f 6e 2e 6c 61 73 74 5f 74 69 6d 65 20 3d 20 74  on.last_time = t
0490: 69 6d 65 2e 74 69 6d 65 28 29 0a 20 20 20 20 20  ime.time().     
04a0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
04b0: 20 20 20 20 20 72 61 69 73 65 20 48 54 54 50 28       raise HTTP(
04c0: 32 30 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20  200,.           
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 54 28 27 61              T('a
04e0: 64 6d 69 6e 20 64 69 73 61 62 6c 65 64 20 62 65  dmin disabled be
04f0: 63 61 75 73 65 20 6e 6f 74 20 73 75 70 70 6f 72  cause not suppor
0500: 74 65 64 20 6f 6e 20 67 6f 6f 67 6c 65 20 61 70  ted on google ap
0510: 70 20 65 6e 67 69 6e 65 27 29 29 0a 20 20 20 20  p engine')).    
0520: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 72 61  else:.        ra
0530: 69 73 65 20 48 54 54 50 28 32 30 30 2c 20 54 28  ise HTTP(200, T(
0540: 27 61 64 6d 69 6e 20 64 69 73 61 62 6c 65 64 20  'admin disabled 
0550: 62 65 63 61 75 73 65 20 75 6e 61 62 6c 65 20 74  because unable t
0560: 6f 20 61 63 63 65 73 73 20 70 61 73 73 77 6f 72  o access passwor
0570: 64 20 66 69 6c 65 27 29 29 0a 0a 0a 64 65 66 20  d file'))...def 
0580: 76 65 72 69 66 79 5f 70 61 73 73 77 6f 72 64 28  verify_password(
0590: 70 61 73 73 77 6f 72 64 29 3a 0a 20 20 20 20 73  password):.    s
05a0: 65 73 73 69 6f 6e 2e 70 61 6d 5f 75 73 65 72 20  ession.pam_user 
05b0: 3d 20 4e 6f 6e 65 0a 20 20 20 20 69 66 20 44 45  = None.    if DE
05c0: 4d 4f 5f 4d 4f 44 45 3a 0a 20 20 20 20 20 20 20  MO_MODE:.       
05d0: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
05e0: 20 65 6c 69 66 20 6e 6f 74 20 27 70 61 73 73 77   elif not 'passw
05f0: 6f 72 64 27 20 69 6e 20 5f 63 6f 6e 66 69 67 3a  ord' in _config:
0600: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
0610: 46 61 6c 73 65 0a 20 20 20 20 65 6c 69 66 20 5f  False.    elif _
0620: 63 6f 6e 66 69 67 5b 27 70 61 73 73 77 6f 72 64  config['password
0630: 27 5d 2e 73 74 61 72 74 73 77 69 74 68 28 27 70  '].startswith('p
0640: 61 6d 5f 75 73 65 72 3a 27 29 3a 0a 20 20 20 20  am_user:'):.    
0650: 20 20 20 20 73 65 73 73 69 6f 6e 2e 70 61 6d 5f      session.pam_
0660: 75 73 65 72 20 3d 20 5f 63 6f 6e 66 69 67 5b 27  user = _config['
0670: 70 61 73 73 77 6f 72 64 27 5d 5b 39 3a 5d 2e 73  password'][9:].s
0680: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 69  trip().        i
0690: 6d 70 6f 72 74 20 67 6c 75 6f 6e 2e 63 6f 6e 74  mport gluon.cont
06a0: 72 69 62 2e 70 61 6d 0a 20 20 20 20 20 20 20 20  rib.pam.        
06b0: 72 65 74 75 72 6e 20 67 6c 75 6f 6e 2e 63 6f 6e  return gluon.con
06c0: 74 72 69 62 2e 70 61 6d 2e 61 75 74 68 65 6e 74  trib.pam.authent
06d0: 69 63 61 74 65 28 73 65 73 73 69 6f 6e 2e 70 61  icate(session.pa
06e0: 6d 5f 75 73 65 72 2c 70 61 73 73 77 6f 72 64 29  m_user,password)
06f0: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
0700: 20 20 20 72 65 74 75 72 6e 20 5f 63 6f 6e 66 69     return _confi
0710: 67 5b 27 70 61 73 73 77 6f 72 64 27 5d 20 3d 3d  g['password'] ==
0720: 20 43 52 59 50 54 28 29 28 70 61 73 73 77 6f 72   CRYPT()(passwor
0730: 64 29 5b 30 5d 0a 0a 0a 23 20 23 23 23 23 23 23  d)[0]...# ######
0740: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0750: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0760: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0770: 23 23 23 23 23 0a 23 20 23 23 20 68 61 6e 64 6c  #####.# ## handl
0780: 65 20 62 72 75 74 65 2d 66 6f 72 63 65 20 6c 6f  e brute-force lo
0790: 67 69 6e 20 61 74 74 61 63 6b 73 0a 23 20 23 23  gin attacks.# ##
07a0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
07b0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
07c0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
07d0: 23 23 23 23 23 23 23 23 23 0a 0a 64 65 6e 79 5f  #########..deny_
07e0: 66 69 6c 65 20 3d 20 6f 73 2e 70 61 74 68 2e 6a  file = os.path.j
07f0: 6f 69 6e 28 72 65 71 75 65 73 74 2e 66 6f 6c 64  oin(request.fold
0800: 65 72 2c 20 27 70 72 69 76 61 74 65 27 2c 20 27  er, 'private', '
0810: 68 6f 73 74 73 2e 64 65 6e 79 27 29 0a 61 6c 6c  hosts.deny').all
0820: 6f 77 65 64 5f 6e 75 6d 62 65 72 5f 6f 66 5f 61  owed_number_of_a
0830: 74 74 65 6d 70 74 73 20 3d 20 35 0a 65 78 70 69  ttempts = 5.expi
0840: 72 61 74 69 6f 6e 5f 66 61 69 6c 65 64 5f 6c 6f  ration_failed_lo
0850: 67 69 6e 73 20 3d 20 33 36 30 30 0a 0a 64 65 66  gins = 3600..def
0860: 20 72 65 61 64 5f 68 6f 73 74 73 5f 64 65 6e 79   read_hosts_deny
0870: 28 29 3a 0a 20 20 20 20 69 6d 70 6f 72 74 20 64  ():.    import d
0880: 61 74 65 74 69 6d 65 0a 20 20 20 20 68 6f 73 74  atetime.    host
0890: 73 20 3d 20 7b 7d 0a 20 20 20 20 69 66 20 6f 73  s = {}.    if os
08a0: 2e 70 61 74 68 2e 65 78 69 73 74 73 28 64 65 6e  .path.exists(den
08b0: 79 5f 66 69 6c 65 29 3a 0a 20 20 20 20 20 20 20  y_file):.       
08c0: 20 68 6f 73 74 73 20 3d 20 7b 7d 0a 20 20 20 20   hosts = {}.    
08d0: 20 20 20 20 66 20 3d 20 6f 70 65 6e 28 64 65 6e      f = open(den
08e0: 79 5f 66 69 6c 65 2c 20 27 72 27 29 0a 20 20 20  y_file, 'r').   
08f0: 20 20 20 20 20 70 6f 72 74 61 6c 6f 63 6b 65 72       portalocker
0900: 2e 6c 6f 63 6b 28 66 2c 20 70 6f 72 74 61 6c 6f  .lock(f, portalo
0910: 63 6b 65 72 2e 4c 4f 43 4b 5f 53 48 29 0a 20 20  cker.LOCK_SH).  
0920: 20 20 20 20 20 20 66 6f 72 20 6c 69 6e 65 20 69        for line i
0930: 6e 20 66 2e 72 65 61 64 6c 69 6e 65 73 28 29 3a  n f.readlines():
0940: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
0950: 6e 6f 74 20 6c 69 6e 65 2e 73 74 72 69 70 28 29  not line.strip()
0960: 20 6f 72 20 6c 69 6e 65 2e 73 74 61 72 74 73 77   or line.startsw
0970: 69 74 68 28 27 23 27 29 3a 0a 20 20 20 20 20 20  ith('#'):.      
0980: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e            contin
0990: 75 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  ue.            f
09a0: 69 65 6c 64 73 20 3d 20 6c 69 6e 65 2e 73 74 72  ields = line.str
09b0: 69 70 28 29 2e 73 70 6c 69 74 28 29 0a 20 20 20  ip().split().   
09c0: 20 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e 28           if len(
09d0: 66 69 65 6c 64 73 29 20 3e 20 32 3a 0a 20 20 20  fields) > 2:.   
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 68 6f 73               hos
09f0: 74 73 5b 66 69 65 6c 64 73 5b 30 5d 2e 73 74 72  ts[fields[0].str
0a00: 69 70 28 29 5d 20 3d 20 28 20 23 20 69 70 0a 20  ip()] = ( # ip. 
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a20: 20 20 20 69 6e 74 28 66 69 65 6c 64 73 5b 31 5d     int(fields[1]
0a30: 2e 73 74 72 69 70 28 29 29 2c 20 20 23 20 6e 20  .strip()),  # n 
0a40: 61 74 74 65 6d 70 73 0a 20 20 20 20 20 20 20 20  attemps.        
0a50: 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 28              int(
0a60: 66 69 65 6c 64 73 5b 32 5d 2e 73 74 72 69 70 28  fields[2].strip(
0a70: 29 29 20 20 20 23 20 6c 61 73 74 20 61 74 74 65  ))   # last atte
0a80: 6d 70 74 73 0a 20 20 20 20 20 20 20 20 20 20 20  mpts.           
0a90: 20 20 20 20 20 20 20 20 20 29 0a 20 20 20 20 20           ).     
0aa0: 20 20 20 70 6f 72 74 61 6c 6f 63 6b 65 72 2e 75     portalocker.u
0ab0: 6e 6c 6f 63 6b 28 66 29 0a 20 20 20 20 20 20 20  nlock(f).       
0ac0: 20 66 2e 63 6c 6f 73 65 28 29 20 20 0a 20 20 20   f.close()  .   
0ad0: 20 72 65 74 75 72 6e 20 68 6f 73 74 73 0a 20 20   return hosts.  
0ae0: 20 20 20 20 20 20 0a 64 65 66 20 77 72 69 74 65        .def write
0af0: 5f 68 6f 73 74 73 5f 64 65 6e 79 28 64 65 6e 69  _hosts_deny(deni
0b00: 65 64 5f 68 6f 73 74 73 29 3a 0a 20 20 20 20 66  ed_hosts):.    f
0b10: 20 3d 20 6f 70 65 6e 28 64 65 6e 79 5f 66 69 6c   = open(deny_fil
0b20: 65 2c 20 27 77 27 29 0a 20 20 20 20 70 6f 72 74  e, 'w').    port
0b30: 61 6c 6f 63 6b 65 72 2e 6c 6f 63 6b 28 66 2c 20  alocker.lock(f, 
0b40: 70 6f 72 74 61 6c 6f 63 6b 65 72 2e 4c 4f 43 4b  portalocker.LOCK
0b50: 5f 45 58 29 0a 20 20 20 20 66 6f 72 20 6b 65 79  _EX).    for key
0b60: 2c 20 76 61 6c 20 69 6e 20 64 65 6e 69 65 64 5f  , val in denied_
0b70: 68 6f 73 74 73 2e 69 74 65 6d 73 28 29 3a 0a 20  hosts.items():. 
0b80: 20 20 20 20 20 20 20 69 66 20 74 69 6d 65 2e 74         if time.t
0b90: 69 6d 65 28 29 2d 76 61 6c 5b 31 5d 20 3c 20 65  ime()-val[1] < e
0ba0: 78 70 69 72 61 74 69 6f 6e 5f 66 61 69 6c 65 64  xpiration_failed
0bb0: 5f 6c 6f 67 69 6e 73 3a 0a 20 20 20 20 20 20 20  _logins:.       
0bc0: 20 20 20 20 20 6c 69 6e 65 20 3d 20 27 25 73 20       line = '%s 
0bd0: 25 73 20 25 73 5c 6e 27 20 25 20 28 6b 65 79 2c  %s %s\n' % (key,
0be0: 20 76 61 6c 5b 30 5d 2c 20 76 61 6c 5b 31 5d 29   val[0], val[1])
0bf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 2e 77  .            f.w
0c00: 72 69 74 65 28 6c 69 6e 65 29 0a 20 20 20 20 70  rite(line).    p
0c10: 6f 72 74 61 6c 6f 63 6b 65 72 2e 75 6e 6c 6f 63  ortalocker.unloc
0c20: 6b 28 66 29 0a 20 20 20 20 66 2e 63 6c 6f 73 65  k(f).    f.close
0c30: 28 29 20 20 20 20 20 20 20 20 0a 0a 64 65 66 20  ()        ..def 
0c40: 6c 6f 67 69 6e 5f 72 65 63 6f 72 64 28 73 75 63  login_record(suc
0c50: 63 65 73 73 3d 54 72 75 65 29 3a 0a 20 20 20 20  cess=True):.    
0c60: 64 65 6e 69 65 64 5f 68 6f 73 74 73 20 3d 20 72  denied_hosts = r
0c70: 65 61 64 5f 68 6f 73 74 73 5f 64 65 6e 79 28 29  ead_hosts_deny()
0c80: 0a 20 20 20 20 76 61 6c 20 3d 20 28 30 2c 30 29  .    val = (0,0)
0c90: 0a 20 20 20 20 69 66 20 73 75 63 63 65 73 73 20  .    if success 
0ca0: 61 6e 64 20 72 65 71 75 65 73 74 2e 63 6c 69 65  and request.clie
0cb0: 6e 74 20 69 6e 20 64 65 6e 69 65 64 5f 68 6f 73  nt in denied_hos
0cc0: 74 73 3a 0a 20 20 20 20 20 20 20 20 64 65 6c 20  ts:.        del 
0cd0: 64 65 6e 69 65 64 5f 68 6f 73 74 73 5b 72 65 71  denied_hosts[req
0ce0: 75 65 73 74 2e 63 6c 69 65 6e 74 5d 0a 20 20 20  uest.client].   
0cf0: 20 65 6c 69 66 20 6e 6f 74 20 73 75 63 63 65 73   elif not succes
0d00: 73 20 61 6e 64 20 6e 6f 74 20 72 65 71 75 65 73  s and not reques
0d10: 74 2e 69 73 5f 6c 6f 63 61 6c 3a 0a 20 20 20 20  t.is_local:.    
0d20: 20 20 20 20 76 61 6c 20 3d 20 64 65 6e 69 65 64      val = denied
0d30: 5f 68 6f 73 74 73 2e 67 65 74 28 72 65 71 75 65  _hosts.get(reque
0d40: 73 74 2e 63 6c 69 65 6e 74 2c 28 30 2c 30 29 29  st.client,(0,0))
0d50: 0a 20 20 20 20 20 20 20 20 69 66 20 74 69 6d 65  .        if time
0d60: 2e 74 69 6d 65 28 29 2d 76 61 6c 5b 31 5d 3c 65  .time()-val[1]<e
0d70: 78 70 69 72 61 74 69 6f 6e 5f 66 61 69 6c 65 64  xpiration_failed
0d80: 5f 6c 6f 67 69 6e 73 20 5c 0a 20 20 20 20 20 20  _logins \.      
0d90: 20 20 20 20 20 20 61 6e 64 20 76 61 6c 5b 30 5d        and val[0]
0da0: 20 3e 3d 20 61 6c 6c 6f 77 65 64 5f 6e 75 6d 62   >= allowed_numb
0db0: 65 72 5f 6f 66 5f 61 74 74 65 6d 70 74 73 3a 0a  er_of_attempts:.
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
0dd0: 72 6e 20 76 61 6c 5b 30 5d 20 23 20 6c 6f 63 6b  rn val[0] # lock
0de0: 65 64 20 6f 75 74 0a 20 20 20 20 20 20 20 20 74  ed out.        t
0df0: 69 6d 65 2e 73 6c 65 65 70 28 32 2a 2a 76 61 6c  ime.sleep(2**val
0e00: 5b 30 5d 29 0a 20 20 20 20 20 20 20 20 76 61 6c  [0]).        val
0e10: 20 3d 20 28 76 61 6c 5b 30 5d 2b 31 2c 69 6e 74   = (val[0]+1,int
0e20: 28 74 69 6d 65 2e 74 69 6d 65 28 29 29 29 20 20  (time.time()))  
0e30: 20 20 20 20 20 20 0a 20 20 20 20 20 20 20 20 64        .        d
0e40: 65 6e 69 65 64 5f 68 6f 73 74 73 5b 72 65 71 75  enied_hosts[requ
0e50: 65 73 74 2e 63 6c 69 65 6e 74 5d 20 3d 20 76 61  est.client] = va
0e60: 6c 0a 20 20 20 20 77 72 69 74 65 5f 68 6f 73 74  l.    write_host
0e70: 73 5f 64 65 6e 79 28 64 65 6e 69 65 64 5f 68 6f  s_deny(denied_ho
0e80: 73 74 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20  sts).    return 
0e90: 76 61 6c 5b 30 5d 0a 20 20 20 20 20 20 20 20 0a  val[0].        .
0ea0: 0a 23 20 23 23 23 23 23 23 23 23 23 23 23 23 23  .# #############
0eb0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0ec0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0ed0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 0a 23  ##############.#
0ee0: 20 23 23 20 73 65 73 73 69 6f 6e 20 65 78 70 69   ## session expi
0ef0: 72 61 74 69 6f 6e 0a 23 20 23 23 23 23 23 23 23  ration.# #######
0f00: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0f10: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0f20: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
0f30: 23 23 23 23 0a 0a 74 30 20 3d 20 74 69 6d 65 2e  ####..t0 = time.
0f40: 74 69 6d 65 28 29 0a 69 66 20 73 65 73 73 69 6f  time().if sessio
0f50: 6e 2e 61 75 74 68 6f 72 69 7a 65 64 3a 0a 0a 20  n.authorized:.. 
0f60: 20 20 20 69 66 20 73 65 73 73 69 6f 6e 2e 6c 61     if session.la
0f70: 73 74 5f 74 69 6d 65 20 61 6e 64 20 73 65 73 73  st_time and sess
0f80: 69 6f 6e 2e 6c 61 73 74 5f 74 69 6d 65 20 3c 20  ion.last_time < 
0f90: 74 30 20 2d 20 45 58 50 49 52 41 54 49 4f 4e 3a  t0 - EXPIRATION:
0fa0: 0a 20 20 20 20 20 20 20 20 73 65 73 73 69 6f 6e  .        session
0fb0: 2e 66 6c 61 73 68 20 3d 20 54 28 27 73 65 73 73  .flash = T('sess
0fc0: 69 6f 6e 20 65 78 70 69 72 65 64 27 29 0a 20 20  ion expired').  
0fd0: 20 20 20 20 20 20 73 65 73 73 69 6f 6e 2e 61 75        session.au
0fe0: 74 68 6f 72 69 7a 65 64 20 3d 20 46 61 6c 73 65  thorized = False
0ff0: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
1000: 20 20 20 73 65 73 73 69 6f 6e 2e 6c 61 73 74 5f     session.last_
1010: 74 69 6d 65 20 3d 20 74 30 0a 0a 69 66 20 6e 6f  time = t0..if no
1020: 74 20 73 65 73 73 69 6f 6e 2e 61 75 74 68 6f 72  t session.author
1030: 69 7a 65 64 20 61 6e 64 20 6e 6f 74 20 5c 0a 20  ized and not \. 
1040: 20 20 20 28 72 65 71 75 65 73 74 2e 63 6f 6e 74     (request.cont
1050: 72 6f 6c 6c 65 72 20 3d 3d 20 27 64 65 66 61 75  roller == 'defau
1060: 6c 74 27 20 61 6e 64 20 5c 0a 20 20 20 20 20 72  lt' and \.     r
1070: 65 71 75 65 73 74 2e 66 75 6e 63 74 69 6f 6e 20  equest.function 
1080: 69 6e 20 28 27 69 6e 64 65 78 27 2c 27 75 73 65  in ('index','use
1090: 72 27 29 29 3a 0a 0a 20 20 20 20 69 66 20 72 65  r')):..    if re
10a0: 71 75 65 73 74 2e 65 6e 76 2e 71 75 65 72 79 5f  quest.env.query_
10b0: 73 74 72 69 6e 67 3a 0a 20 20 20 20 20 20 20 20  string:.        
10c0: 71 75 65 72 79 5f 73 74 72 69 6e 67 20 3d 20 27  query_string = '
10d0: 3f 27 20 2b 20 72 65 71 75 65 73 74 2e 65 6e 76  ?' + request.env
10e0: 2e 71 75 65 72 79 5f 73 74 72 69 6e 67 0a 20 20  .query_string.  
10f0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
1100: 71 75 65 72 79 5f 73 74 72 69 6e 67 20 3d 20 27  query_string = '
1110: 27 0a 0a 20 20 20 20 69 66 20 72 65 71 75 65 73  '..    if reques
1120: 74 2e 65 6e 76 2e 77 65 62 32 70 79 5f 6f 72 69  t.env.web2py_ori
1130: 67 69 6e 61 6c 5f 75 72 69 3a 0a 20 20 20 20 20  ginal_uri:.     
1140: 20 20 20 75 72 6c 20 3d 20 72 65 71 75 65 73 74     url = request
1150: 2e 65 6e 76 2e 77 65 62 32 70 79 5f 6f 72 69 67  .env.web2py_orig
1160: 69 6e 61 6c 5f 75 72 69 0a 20 20 20 20 65 6c 73  inal_uri.    els
1170: 65 3a 0a 20 20 20 20 20 20 20 20 75 72 6c 20 3d  e:.        url =
1180: 20 72 65 71 75 65 73 74 2e 65 6e 76 2e 70 61 74   request.env.pat
1190: 68 5f 69 6e 66 6f 20 2b 20 71 75 65 72 79 5f 73  h_info + query_s
11a0: 74 72 69 6e 67 0a 20 20 20 20 72 65 64 69 72 65  tring.    redire
11b0: 63 74 28 55 52 4c 28 72 65 71 75 65 73 74 2e 61  ct(URL(request.a
11c0: 70 70 6c 69 63 61 74 69 6f 6e 2c 20 27 64 65 66  pplication, 'def
11d0: 61 75 6c 74 27 2c 20 27 69 6e 64 65 78 27 2c 20  ault', 'index', 
11e0: 76 61 72 73 3d 64 69 63 74 28 73 65 6e 64 3d 75  vars=dict(send=u
11f0: 72 6c 29 29 29 0a 65 6c 69 66 20 73 65 73 73 69  rl))).elif sessi
1200: 6f 6e 2e 61 75 74 68 6f 72 69 7a 65 64 20 61 6e  on.authorized an
1210: 64 20 5c 0a 20 20 20 20 20 72 65 71 75 65 73 74  d \.     request
1220: 2e 63 6f 6e 74 72 6f 6c 6c 65 72 20 3d 3d 20 27  .controller == '
1230: 64 65 66 61 75 6c 74 27 20 61 6e 64 20 5c 0a 20  default' and \. 
1240: 20 20 20 20 72 65 71 75 65 73 74 2e 66 75 6e 63      request.func
1250: 74 69 6f 6e 20 3d 3d 20 27 69 6e 64 65 78 27 3a  tion == 'index':
1260: 0a 20 20 20 20 72 65 64 69 72 65 63 74 28 55 52  .    redirect(UR
1270: 4c 28 72 65 71 75 65 73 74 2e 61 70 70 6c 69 63  L(request.applic
1280: 61 74 69 6f 6e 2c 20 27 64 65 66 61 75 6c 74 27  ation, 'default'
1290: 2c 20 27 73 69 74 65 27 29 29 0a 0a 0a 69 66 20  , 'site'))...if 
12a0: 72 65 71 75 65 73 74 2e 63 6f 6e 74 72 6f 6c 6c  request.controll
12b0: 65 72 3d 3d 27 61 70 70 61 64 6d 69 6e 27 20 61  er=='appadmin' a
12c0: 6e 64 20 44 45 4d 4f 5f 4d 4f 44 45 3a 0a 20 20  nd DEMO_MODE:.  
12d0: 20 20 73 65 73 73 69 6f 6e 2e 66 6c 61 73 68 20    session.flash 
12e0: 3d 20 27 41 70 70 61 64 6d 69 6e 20 64 69 73 61  = 'Appadmin disa
12f0: 62 6c 65 64 20 69 6e 20 64 65 6d 6f 20 6d 6f 64  bled in demo mod
1300: 65 27 0a 20 20 20 20 72 65 64 69 72 65 63 74 28  e'.    redirect(
1310: 55 52 4c 28 27 64 65 66 61 75 6c 74 27 2c 27 73  URL('default','s
1320: 69 74 65 73 27 29 29 0a 0a                       ites'))..