aumain.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. return token
  44. except Exception, e:
  45. self.logger.error("generate token faild!")
  46. self.logger.debug(e)
  47. @property
  48. def modifypwd(self):
  49. p1 = subprocess.Popen(['echo', self.tokengenerate], stdout=subprocess.PIPE)
  50. p2 = subprocess.Popen(['passwd', '--stdin', self.loginuser], stdin=p1.stdout, stdout=subprocess.PIPE)
  51. result = p2.communicate()
  52. if result[-1]:
  53. self.logger.error(result[-1])
  54. return
  55. else:
  56. self.logger.debug("change security token success.")
  57. return True
  58. @property
  59. def reporter(self):
  60. result = True
  61. # database
  62. try:
  63. self.cursor.execute('select id from %s.token_info where host="%s"' % (decodestr(Config.dbname), self.hostname))
  64. token_id = self.cursor.fetchone()
  65. if not token_id:
  66. 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))
  67. self.conn.commit()
  68. else:
  69. self.cursor.execute(
  70. 'update %s.token_info set time = %s,rd_list=%s where host = "%s"' % ( decodestr(Config.dbname), self.t, self.rd, self.hostname ))
  71. self.conn.commit()
  72. self.logger.debug("update database scuess!")
  73. except Exception, e:
  74. self.logger.error("update database faild!")
  75. self.logger.debug(e)
  76. result = False
  77. #redis
  78. try:
  79. redis_set_t = self.redis_conn.set(self.hostname, self.t)
  80. redis_set_rd = self.redis_conn.set(self.hostname + 'rd', self.rd)
  81. if not redis_set_t and not redis_set_rd :
  82. result = False
  83. except Exception, e:
  84. self.logger.error("update redis faild!")
  85. self.logger.debug(e)
  86. result = False
  87. if result:
  88. self.logger.debug("update redis scuess!")
  89. return result
  90. def recodepw(self,token):
  91. spec_case = [x for x in '~!@#$%^&*()_+{}<>-='] + [x for x in string.lowercase]
  92. rd = random.sample(range(22),12)
  93. reset_token = ''
  94. for x in range(len(token)):
  95. if x in rd:
  96. w = spec_case[x]
  97. else:
  98. w = token[x]
  99. reset_token += w
  100. return reset_token, rd
  101. def decodestr(s):
  102. dns = s[5:].replace(s[-12:-4], '') + '=='
  103. return base64.decodestring(dns)
  104. # if __name__ == '__main__':
  105. # for user in users:
  106. # Agent = PWDManager(user)
  107. # token = Agent.tokengenerate
  108. # if token:
  109. # rep = Agent.reporter
  110. # if rep:
  111. # Agent.modifypwd
  112. # else:
  113. # continue
  114. # else:
  115. # continue
  116. # ~!@#$%^&*()_+{}<>-= 对应range(11,30)
  117. # a-z 对应 range(30,56)