Source code for opennode.oms.security.passwd
import argparse
import hashlib
import os
import random
import string
import sys
from base64 import encodestring as encode
from getpass import getpass
from twisted.cred.checkers import FilePasswordDB
from twisted.cred.credentials import UsernamePassword
from twisted.cred.error import UnauthorizedLogin
from opennode.oms.config import get_config
from opennode.oms.security.authentication import ssha_hash
from opennode.oms.util import blocking_yield
[docs]def ask_password():
pw = getpass("Password: ")
confirm = getpass("Confirm password: ")
if pw != confirm:
print "Password mismatch, aborting"
sys.exit(1)
return hash_pw(pw)
[docs]def hash_pw(password):
salt = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in xrange(4))
h = hashlib.sha1(password)
h.update(salt)
return "{SSHA}" + encode(h.digest() + salt).rstrip()
[docs]def run():
conf = get_config()
basedir = conf.get_base_dir()
if basedir:
os.chdir(basedir)
parser = argparse.ArgumentParser(description='Manage OMS passwords')
parser.add_argument('user', help="user name")
parser.add_argument('-g', help="group(s): comma separated list of groups the user belongs to", required=False, default=None)
parser.add_argument('-s', action='store_true', help="force password prompt even if setting group(s) via -g", required=False, default=None)
group = parser.add_mutually_exclusive_group()
group.add_argument('-a', action='store_true', help="add user")
group.add_argument('-d', action='store_true', help="delete user")
group.add_argument('-c', action='store_true', help="check password, useful to troubleshoot login issues")
args = parser.parse_args()
passwd_file = conf.get('auth', 'passwd_file')
if not os.path.exists(passwd_file):
with open(passwd_file, 'w') as f:
pass
if args.d:
with open(passwd_file) as f:
lines = f.readlines()
with open(passwd_file, 'w') as f:
for line in lines:
if line.startswith(args.user + ':'):
continue
print >>f, line,
elif args.a:
# check if user exists
with open(passwd_file) as f:
for line in f:
if line.startswith(args.user + ':'):
print "User %s already exists" % args.user
sys.exit(1)
pw = ask_password()
with open(passwd_file, 'a') as f:
print >>f, '%s:%s:%s' % (args.user, pw, args.g or 'users')
elif args.c:
password_checker = FilePasswordDB(passwd_file, hash=ssha_hash)
credentials = UsernamePassword(args.user, getpass("Password: "))
try:
blocking_yield(password_checker.requestAvatarId(credentials))
except UnauthorizedLogin:
print "Wrong credentials"
sys.exit(1)
print "ok"
else:
with open(passwd_file) as f:
lines = f.readlines()
found = False
for line in lines:
if line.startswith(args.user + ':'):
found = True
if not found:
print "User %s doesn't exists" % args.user
sys.exit(1)
pw = None
if args.s or not args.g:
pw = ask_password()
with open(passwd_file, 'w') as f:
for line in lines:
if line.startswith(args.user + ':'):
user, old_pw, groups = line.split(':')
if args.g:
groups = args.g + '\n'
if pw == None:
pw = old_pw
print >>f, '%s:%s:%s' % (user, pw, groups),
else:
print >>f, line,