aumain.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # coding: utf-8
  2. # 服务器端每5分钟更改密码,申请的时候管理服务器从服务器端获取token(time + server license)
  3. # 主机名md5[15:] + 用户名md5[15:] + timetoken md5[15:] + server uuid md5 的md5值[15:].upper()
  4. # 服务器端主动上报token至集中管理服务器并记录,每台服务器记录一条,每次都修改上一次的记录,当服务器端更改密码的程序出故障时,使用数据库记录的最后一次token
  5. # 平台登录申请使用google authenticator加password认证
  6. import time
  7. import logging
  8. import logging.config
  9. import socket
  10. import MySQLdb
  11. import hashlib
  12. import subprocess
  13. from config import Config
  14. import redis
  15. import base64
  16. import string
  17. import random
  18. class PWDManager(object):
  19. def __init__(self, user):
  20. """
  21. Dy token Manager
  22. """
  23. self.t = int(time.time())
  24. self.hostname = socket.gethostname()
  25. self.loginuser = user
  26. self.serverid = subprocess.Popen(['dmidecode -s system-uuid'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().strip()
  27. logging.config.fileConfig("logging.conf")
  28. self.logger = logging.getLogger("Main")
  29. self.conn = MySQLdb.connect(user=decodestr(Config.dbuser), passwd=decodestr(Config.dbpasswd), host=decodestr(Config.dbhost), port=int(decodestr(Config.dbport)))
  30. self.cursor = self.conn.cursor()
  31. self.redis_conn = redis.StrictRedis(host=decodestr(Config.redishost), port=int(decodestr(Config.redisport)), db=0)
  32. @property
  33. def tokengenerate(self):
  34. try:
  35. token_hostname = hashlib.md5(self.hostname).hexdigest()[10:]
  36. token_loginuser = hashlib.md5(self.loginuser).hexdigest()[10:]
  37. token_unix_time = hashlib.md5(str(int(self.t) / 300)).hexdigest()[10:]
  38. #token_serverid = hashlib.md5(self.serverid).hexdigest()[10:]
  39. token = hashlib.md5(token_hostname + token_loginuser + token_unix_time).hexdigest()[10:].upper()
  40. token, rd = self.recodepw(token)
  41. self.rd = '&'.join([str(x) for x in rd])
  42. self.logger.info('token created success.')
  43. self.token = token
  44. return token
  45. except Exception, e:
  46. self.logger.error("generate token faild!")
  47. self.logger.debug(e)
  48. @property
  49. def modifypwd(self):
  50. p1 = subprocess.Popen(['echo', self.token], stdout=subprocess.PIPE)
  51. p2 = subprocess.Popen(['passwd', '--stdin', self.loginuser], stdin=p1.stdout, stdout=subprocess.PIPE)
  52. result = p2.communicate()
  53. if result[-1]:
  54. self.logger.error(result[-1])
  55. return
  56. else:
  57. self.logger.debug("change security token success.")
  58. return True
  59. @property
  60. def reporter(self):
  61. result = True
  62. # database
  63. try:
  64. self.cursor.execute('select id from %s.token_info where host="%s"' % (decodestr(Config.dbname), self.hostname))
  65. token_id = self.cursor.fetchone()
  66. if not token_id:
  67. 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))
  68. self.conn.commit()
  69. else:
  70. self.cursor.execute(
  71. 'update %s.token_info set time = %s,rd_list=%s where host = "%s"' % ( decodestr(Config.dbname), self.t, self.rd, self.hostname ))
  72. self.conn.commit()
  73. self.logger.debug("update database scuess!")
  74. except Exception, e:
  75. self.logger.error("update database faild!")
  76. self.logger.debug(e)
  77. result = False
  78. #redis
  79. try:
  80. redis_set_t = self.redis_conn.set(self.hostname, self.t)
  81. redis_set_rd = self.redis_conn.set(self.hostname + 'rd', self.rd)
  82. if not redis_set_t and not redis_set_rd :
  83. result = False
  84. except Exception, e:
  85. self.logger.error("update redis faild!")
  86. self.logger.debug(e)
  87. result = False
  88. if result:
  89. self.logger.debug("update redis scuess!")
  90. return result
  91. def recodepw(self,token):
  92. spec_case = [x for x in '~!@#$%^&*()_+{}<>-='] + [x for x in string.lowercase]
  93. rd = random.sample(range(22),12)
  94. reset_token = ''
  95. for x in range(len(token)):
  96. if x in rd:
  97. w = spec_case[x]
  98. else:
  99. w = token[x]
  100. reset_token += w
  101. return reset_token, rd
  102. def decodestr(s):
  103. dns = s[5:].replace(s[-12:-4], '') + '=='
  104. return base64.decodestring(dns)
  105. # if __name__ == '__main__':
  106. # for user in users:
  107. # Agent = PWDManager(user)
  108. # token = Agent.tokengenerate
  109. # if token:
  110. # rep = Agent.reporter
  111. # if rep:
  112. # Agent.modifypwd
  113. # else:
  114. # continue
  115. # else:
  116. # continue
  117. # ~!@#$%^&*()_+{}<>-= 对应range(11,30)
  118. # a-z 对应 range(30,56)