mrrl-logincaps

MRRL version of logincaps
git clone https://ccx.te2000.cz/git/mrrl-logincaps
Log | Files | Refs

check-root-password.py (1471B)


      1 #!/usr/bin/env python
      2 
      3 from __future__ import (
      4     generators, division, absolute_import, with_statement, print_function
      5 )
      6 import sys
      7 import os
      8 import os.path
      9 import pwd
     10 import spwd
     11 import crypt
     12 import getpass
     13 
     14 
     15 def execve(argv, env=None):
     16     if env is None:
     17         env = os.environ
     18     if '/' in argv[0]:
     19         os.execve(argv[0], argv, env)
     20     else:
     21         for p in os.environ['PATH'].split(os.path.pathsep):
     22             try:
     23                 os.execve(os.path.join(p, argv[0]), argv, env)
     24             except OSError:
     25                 continue
     26     raise SystemExit(1)
     27 
     28 
     29 def constant_time_compare(val1, val2):
     30     """
     31     Returns True if the two strings are equal, False otherwise.
     32 
     33     The time taken is independent of the number of characters that match.
     34 
     35     For the sake of simplicity, this function executes in constant time only
     36     when the two strings have the same length. It short-circuits when they
     37     have different lengths.
     38     """
     39     if len(val1) != len(val2):
     40         return False
     41     result = 0
     42     for x, y in zip(val1, val2):
     43         result |= ord(x) ^ ord(y)
     44     return result == 0
     45 
     46 
     47 def main():
     48     root_hash = spwd.getspnam('root').sp_pwd
     49     root_pwent = pwd.getpwnam('root')
     50     p = getpass.getpass()
     51     if constant_time_compare(root_hash, crypt.crypt(p, root_hash)):
     52         # OK
     53         execve(sys.argv[1:])
     54     else:
     55         sys.stderr.write("Incorrect password\n")
     56         sys.exit(2)
     57 
     58 
     59 if __name__ == '__main__':
     60     sys.exit(main())
     61