sss_obfuscate revision 5daa8ae758349c0077fb5f664579809aa0ab4f78
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#!/usr/bin/python
297be3708069ef31814d6d75c0d71a50a78feb03Mark Andrews
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrewsimport sys
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinfrom optparse import OptionParser
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinimport pysss
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinimport SSSDConfig
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinimport getpass
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeindef parse_options():
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser = OptionParser()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser.set_description("sss_obfuscate converts a given password into \
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein human-unreadable format and places it into \
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein appropriate domain section of the SSSD config \
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein file. The password can be passed in by stdin, \
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein specified on the command-line or entered \
9011c72c568aedd03709f56f21d639fd55944a74Automatic Updater interactively")
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser.add_option("-s", "--stdin", action="store_true",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dest="stdin", default=False,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein help="Read the password from stdin.")
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser.add_option("-d", "--domain",
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews dest="domain", default=None,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein help="The domain to use the password in (mandatory)",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein metavar="DOMNAME")
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser.add_option("-f", "--file",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dest="filename", default=None,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein help="Set input file to FILE (default: Use system default, usually /etc/sssd/sssd.conf)",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein metavar="FILE")
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein parser.add_option("-p", "--password",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dest="password", default=None,
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews help="Password to obfuscate.",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein metavar="PASSWORD")
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein (options, args) = parser.parse_args()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return options, args
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeindef main():
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein options, args = parse_options()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if not options:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein print >> sys.stderr, "Cannot parse options"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if not options.domain:
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews print >> sys.stderr, "No domain specified"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if not options.stdin and not options.password:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: "))
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein p1, p2 = pprompt()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein while p1 != p2:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater print('Passwords do not match. Try again')
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein p1, p2 = pprompt()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein password = p1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater else:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein try:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein password = sys.stdin.read()
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater except KeyboardInterrupt:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater # Obfuscate the password
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater obfobj = pysss.password()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein obfpwd = obfobj.encrypt(password, obfobj.AES_256)
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater # Save the obfuscated password into the domain
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater try:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater sssdconfig = SSSDConfig.SSSDConfig()
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein except IOError:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater print "Cannot read internal configuration files."
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater return 1
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater try:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater sssdconfig.import_config(options.filename)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein except IOError:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater print "Permissions error reading config file"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater try:
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater domain = sssdconfig.get_domain(options.domain)
c6d486af36165da7eb970354981d145249e342e4Mark Andrews except SSSDConfig.NoDomainError:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein print "No such domain %s" % options.domain
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater try:
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater domain.set_option('ldap_default_authtok_type', 'obfuscated_password')
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein domain.set_option('ldap_default_authtok', obfpwd)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein except SSSDConfig.NoOptionError:
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater print "The domain %s does not seem to support the required options" % \
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein options.domain
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 1
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
9011c72c568aedd03709f56f21d639fd55944a74Automatic Updater sssdconfig.save_domain(domain)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein try:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein sssdconfig.write()
9011c72c568aedd03709f56f21d639fd55944a74Automatic Updater except IOError:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein # File could not be written
9011c72c568aedd03709f56f21d639fd55944a74Automatic Updater print >> sys.stderr, "Could not write to config file. Check that " \
aeb7938001b22e811a910e1b36cdf452f9193865Automatic Updater "you have the appropriate permissions to edit " \
9011c72c568aedd03709f56f21d639fd55944a74Automatic Updater "this file."
7208386cd37a2092c70eddf80cf29519b16c4c80Mark Andrews return 1
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return 0
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinif __name__ == "__main__":
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews ret = main()
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews sys.exit(ret)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein