123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- # coding: utf-8
- # 服务器端每5分钟更改密码,申请的时候管理服务器从服务器端获取token(time + server license)
- # 主机名md5[15:] + 用户名md5[15:] + timetoken md5[15:] + server uuid md5 的md5值[15:].upper()
- # 服务器端主动上报token至集中管理服务器并记录,每台服务器记录一条,每次都修改上一次的记录,当服务器端更改密码的程序出故障时,使用数据库记录的最后一次token
- # 平台登录申请使用google authenticator加password认证
- import time
- import logging
- import logging.config
- import socket
- import MySQLdb
- import hashlib
- import subprocess
- from config import Config
- import redis
- import base64
- import string
- import random
- class PWDManager(object):
- def __init__(self, user):
- """
- Dy token Manager
- """
- self.t = int(time.time())
- self.hostname = socket.gethostname()
- self.loginuser = user
- self.serverid = subprocess.Popen(['dmidecode -s system-uuid'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().strip()
- logging.config.fileConfig("logging.conf")
- self.logger = logging.getLogger("Main")
- self.conn = MySQLdb.connect(user=decodestr(Config.dbuser), passwd=decodestr(Config.dbpasswd), host=decodestr(Config.dbhost), port=int(decodestr(Config.dbport)))
- self.cursor = self.conn.cursor()
- self.redis_conn = redis.StrictRedis(host=decodestr(Config.redishost), port=int(decodestr(Config.redisport)), db=0)
- @property
- def tokengenerate(self):
- try:
- token_hostname = hashlib.md5(self.hostname).hexdigest()[10:]
- token_loginuser = hashlib.md5(self.loginuser).hexdigest()[10:]
- token_unix_time = hashlib.md5(str(int(self.t) / 300)).hexdigest()[10:]
- #token_serverid = hashlib.md5(self.serverid).hexdigest()[10:]
- token = hashlib.md5(token_hostname + token_loginuser + token_unix_time).hexdigest()[10:].upper()
- token, rd = self.recodepw(token)
- self.rd = '&'.join([str(x) for x in rd])
- self.logger.info('token created success.')
- self.token = token
- return token
- except Exception, e:
- self.logger.error("generate token faild!")
- self.logger.debug(e)
- @property
- def modifypwd(self):
- p1 = subprocess.Popen(['echo', self.token], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['passwd', '--stdin', self.loginuser], stdin=p1.stdout, stdout=subprocess.PIPE)
- result = p2.communicate()
- if result[-1]:
- self.logger.error(result[-1])
- return
- else:
- self.logger.debug("change security token success.")
- return True
- @property
- def reporter(self):
- result = True
- # database
- try:
- self.cursor.execute('select id from %s.token_info where host="%s"' % (decodestr(Config.dbname), self.hostname))
- token_id = self.cursor.fetchone()
- if not token_id:
- self.cursor.execute('insert into %s.token_info(host,time,rd_list) VALUES ("%s",%s,%s)' % ( decodestr(Config.dbname), self.hostname, self.t, self.rd))
- self.conn.commit()
- else:
- self.cursor.execute(
- 'update %s.token_info set time = %s,rd_list=%s where host = "%s"' % ( decodestr(Config.dbname), self.t, self.rd, self.hostname ))
- self.conn.commit()
- self.logger.debug("update database scuess!")
- except Exception, e:
- self.logger.error("update database faild!")
- self.logger.debug(e)
- result = False
- #redis
- try:
- redis_set_t = self.redis_conn.set(self.hostname, self.t)
- redis_set_rd = self.redis_conn.set(self.hostname + 'rd', self.rd)
- if not redis_set_t and not redis_set_rd :
- result = False
- except Exception, e:
- self.logger.error("update redis faild!")
- self.logger.debug(e)
- result = False
- if result:
- self.logger.debug("update redis scuess!")
- return result
- def recodepw(self,token):
- spec_case = [x for x in '~!@#$%^&*()_+{}<>-='] + [x for x in string.lowercase]
- rd = random.sample(range(22),12)
- reset_token = ''
- for x in range(len(token)):
- if x in rd:
- w = spec_case[x]
- else:
- w = token[x]
- reset_token += w
- return reset_token, rd
- def decodestr(s):
- dns = s[5:].replace(s[-12:-4], '') + '=='
- return base64.decodestring(dns)
- # if __name__ == '__main__':
- # for user in users:
- # Agent = PWDManager(user)
- # token = Agent.tokengenerate
- # if token:
- # rep = Agent.reporter
- # if rep:
- # Agent.modifypwd
- # else:
- # continue
- # else:
- # continue
- # ~!@#$%^&*()_+{}<>-= 对应range(11,30)
- # a-z 对应 range(30,56)
|