113 lines
2.7 KiB
Python
113 lines
2.7 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
import psycopg, crypt, crack, popen2, getopt, random, sys
|
||
|
|
||
|
def generate_password():
|
||
|
(o, i, e) = popen2.popen3("apg -n 1 -m 8 -x 12 -a 0")
|
||
|
|
||
|
return "".join(o.readlines()).strip()
|
||
|
|
||
|
def check_password(password):
|
||
|
try:
|
||
|
return crack.VeryFascistCheck(password)
|
||
|
except ValueError, ve:
|
||
|
print "Weak password:", ve
|
||
|
return None
|
||
|
|
||
|
def md5_crypt_password(password):
|
||
|
salt = "".join([chr(letter) for letter in random.sample(range(ord('a'), ord('z')), 8)])
|
||
|
|
||
|
return crypt.crypt(password, '$1$' + salt)
|
||
|
|
||
|
class InvalidDomain(Exception):
|
||
|
def __init__(self, domain):
|
||
|
self.domain = domain
|
||
|
|
||
|
def __str__(self):
|
||
|
return repr("Invalid domain %s" % (domain))
|
||
|
|
||
|
def validate_domain(domain):
|
||
|
cnx = psycopg.connect("user=exim4 password=CotOgigmeIk5 dbname=gnuviechadmin")
|
||
|
cr = cnx.cursor()
|
||
|
|
||
|
cr.execute("SELECT * FROM domain WHERE domainname=%(name)s" %
|
||
|
{'name': psycopg.QuotedString(domain)})
|
||
|
cnx.commit()
|
||
|
|
||
|
result = cr.fetchall()
|
||
|
if (not result):
|
||
|
raise InvalidDomain(domain)
|
||
|
#
|
||
|
#print "-- Information from mailalias --"
|
||
|
#cr.execute('SELECT * FROM mailalias')
|
||
|
#cnx.commit()
|
||
|
#
|
||
|
#print cr.description
|
||
|
#
|
||
|
#result = cr.fetchall()
|
||
|
#for line in result:
|
||
|
# print line
|
||
|
#
|
||
|
#print "-- Information from mailpasswd --"
|
||
|
#cr.execute('SELECT * FROM mailpasswd')
|
||
|
#cnx.commit()
|
||
|
#result = cr.fetchall()
|
||
|
#for line in result:
|
||
|
# print line
|
||
|
#
|
||
|
#print "-- Domains --"
|
||
|
#cr.execute('SELECT DISTINCT domain FROM mailalias')
|
||
|
#cnx.commit()
|
||
|
#result = cr.fetchall()
|
||
|
#for line in result:
|
||
|
# print line
|
||
|
|
||
|
def usage():
|
||
|
print """Usage information:
|
||
|
=====================
|
||
|
%(process)s -h|--help
|
||
|
- prints this help text
|
||
|
|
||
|
%(process)s --domain=<domain> [--password=<password>]
|
||
|
- adds a new pop user for the given domain
|
||
|
- if the optional password is ommitted a generated one is used
|
||
|
- the password is checked using cracklib
|
||
|
- if the password is too weak a generated one is used
|
||
|
""" % {'process': sys.argv[0]}
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
try:
|
||
|
options = getopt.getopt(sys.argv[1:], "h", ['help', 'password=', 'domain='])
|
||
|
except getopt.GetoptError:
|
||
|
usage()
|
||
|
sys.exit(1)
|
||
|
|
||
|
if (not options[0] or
|
||
|
dict(options[0]).has_key('-h') or
|
||
|
dict(options[0]).has_key('--help') or
|
||
|
not dict(options[0]).has_key('--domain') or
|
||
|
not dict(options[0])['--domain'].strip()):
|
||
|
usage()
|
||
|
sys.exit(1)
|
||
|
|
||
|
# specify the domain
|
||
|
domain = dict(options[0])['--domain']
|
||
|
try:
|
||
|
validate_domain(domain)
|
||
|
except InvalidDomain, iv:
|
||
|
print iv
|
||
|
sys.exit(1)
|
||
|
|
||
|
# specify the password
|
||
|
password = None
|
||
|
|
||
|
if dict(options[0]).has_key('--password'):
|
||
|
password = check_password(dict(options[0])['--password'])
|
||
|
if (password == None):
|
||
|
password = generate_password()
|
||
|
|
||
|
print domain
|
||
|
print password
|
||
|
|
||
|
print md5_crypt_password(password)
|