modify some

pull/26/head
ibuler 2015-06-15 19:20:05 +08:00
parent fdcaa358e5
commit 8d167baf46
2 changed files with 158 additions and 200 deletions

View File

@ -40,11 +40,10 @@ except ImportError:
CONF.read(os.path.join(BASE_DIR, 'jumpserver.conf')) CONF.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
log_dir = os.path.join(BASE_DIR, 'logs') log_dir = os.path.join(BASE_DIR, 'logs')
login_name = getpass.getuser() login_user = Juser(username=getpass.getuser())
user = Juser(username=login_name)
def color_print(msg, color='blue'): def color_print(msg, color='red', exits=False):
""" """
Print colorful string. Print colorful string.
颜色打印 颜色打印
@ -54,199 +53,133 @@ def color_print(msg, color='blue'):
'red': '\033[1;31m%s\033[0m'} 'red': '\033[1;31m%s\033[0m'}
print color_msg.get(color, 'blue') % msg print color_msg.get(color, 'blue') % msg
if exits:
time.sleep(2)
sys.exit()
def color_print_exit(msg, color='red'): class Jtty(object):
""" def __init__(self, chan, user, asset):
Print colorful string and exit. self.chan = chan
颜色打印并推出 self.username = user.username
""" self.ip = asset.ip
color_print(msg, color=color)
time.sleep(2)
sys.exit()
@staticmethod
def get_win_size():
"""
This function use to get the size of the windows!
获得terminal窗口大小
"""
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912L
s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s)
return struct.unpack('HHHH', x)[0:2]
def get_win_size(): def set_win_size(self, sig, data):
""" """
This function use to get the size of the windows! This function use to set the window size of the terminal!
获得terminal窗口大小 设置terminal窗口大小
""" """
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912L
s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s)
return struct.unpack('HHHH', x)[0:2]
def set_win_size(sig, data):
"""
This function use to set the window size of the terminal!
设置terminal窗口大小
"""
try:
win_size = get_win_size()
channel.resize_pty(height=win_size[0], width=win_size[1])
except Exception:
pass
def log_record(username, host):
"""
Logging user command and output.
记录用户的日志
"""
connect_log_dir = os.path.join(log_dir, 'connect')
timestamp_start = int(time.time())
today = time.strftime('%Y%m%d', time.localtime(timestamp_start))
time_now = time.strftime('%H%M%S', time.localtime(timestamp_start))
today_connect_log_dir = os.path.join(connect_log_dir, today)
log_filename = '%s_%s_%s.log' % (username, host, time_now)
log_file_path = os.path.join(today_connect_log_dir, log_filename)
dept = User.objects.filter(username=username)
if dept:
dept = dept[0]
dept_name = dept.name
else:
dept_name = 'None'
pid = os.getpid()
pts = os.popen("ps axu | grep %s | grep -v grep | awk '{ print $7 }'" % pid).read().strip()
remote_ip = os.popen("who | grep %s | awk '{ print $5 }'" % pts).read().strip('()\n')
if not os.path.isdir(today_connect_log_dir):
try: try:
os.makedirs(today_connect_log_dir) win_size = self.get_win_size()
os.chmod(today_connect_log_dir, 0777) self.channel.resize_pty(height=win_size[0], width=win_size[1])
except OSError: except Exception:
raise ServerError('Create %s failed, Please modify %s permission.' % (today_connect_log_dir, connect_log_dir)) pass
try: def log_record(self):
log_file = open(log_file_path, 'a') """
except IOError: Logging user command and output.
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir) 记录用户的日志
"""
tty_log_dir = os.path.join(log_dir, 'tty')
timestamp_start = int(time.time())
date_start = time.strftime('%Y%m%d', time.localtime(timestamp_start))
time_start = time.strftime('%H%M%S', time.localtime(timestamp_start))
today_connect_log_dir = os.path.join(tty_log_dir, date_start)
log_filename = '%s_%s_%s.log' % (self.username, self.host, time_start)
log_file_path = os.path.join(today_connect_log_dir, log_filename)
dept = User.objects.filter(username=username)
if dept:
dept = dept[0]
dept_name = dept.name
else:
dept_name = 'None'
log = Log(user=username, host=host, remote_ip=remote_ip, dept_name=dept_name, pid = os.getpid()
log_path=log_file_path, start_time=datetime.datetime.now(), pid=pid) pts = os.popen("ps axu | grep %s | grep -v grep | awk '{ print $7 }'" % pid).read().strip()
log_file.write('Start time is %s\n' % datetime.datetime.now()) remote_ip = os.popen("who | grep %s | awk '{ print $5 }'" % pts).read().strip('()\n')
log.save()
return log_file, log
if not os.path.isdir(today_connect_log_dir):
def posix_shell(chan, username, host):
"""
Use paramiko channel connect server interactive.
使用paramiko模块的channel连接后端进入交互式
"""
log_file, log = log_record(username, host)
old_tty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
while True:
try: try:
r, w, e = select.select([chan, sys.stdin], [], []) os.makedirs(today_connect_log_dir)
except Exception: os.chmod(today_connect_log_dir, 0777)
pass except OSError:
raise ServerError('Create %s failed, Please modify %s permission.' % (today_connect_log_dir, connect_log_dir))
if chan in r: try:
log_file = open(log_file_path, 'a')
except IOError:
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
log = Log(user=username, host=host, remote_ip=remote_ip, dept_name=dept_name,
log_path=log_file_path, start_time=datetime.datetime.now(), pid=pid)
log_file.write('Start time is %s\n' % datetime.datetime.now())
log.save()
return log_file, log
def posix_shell(chan, username, host):
"""
Use paramiko channel connect server interactive.
使用paramiko模块的channel连接后端进入交互式
"""
log_file, log = log_record(username, host)
old_tty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
while True:
try: try:
x = chan.recv(1024) r, w, e = select.select([chan, sys.stdin], [], [])
if len(x) == 0: except Exception:
break
sys.stdout.write(x)
sys.stdout.flush()
log_file.write(x)
log_file.flush()
except socket.timeout:
pass pass
if sys.stdin in r: if chan in r:
x = os.read(sys.stdin.fileno(), 1) try:
if len(x) == 0: x = chan.recv(1024)
break if len(x) == 0:
chan.send(x) break
sys.stdout.write(x)
sys.stdout.flush()
log_file.write(x)
log_file.flush()
except socket.timeout:
pass
finally: if sys.stdin in r:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty) x = os.read(sys.stdin.fileno(), 1)
log_file.write('End time is %s' % datetime.datetime.now()) if len(x) == 0:
log_file.close() break
log.is_finished = True chan.send(x)
log.log_finished = False
log.end_time = datetime.datetime.now()
log.save()
finally:
# def get_user_host_group(username): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
# """ log_file.write('End time is %s' % datetime.datetime.now())
# Get the host groups of under the user control. log_file.close()
# 获取用户有权限的主机组 log.is_finished = True
# """ log.log_finished = False
# groups_attr = {} log.end_time = datetime.datetime.now()
# group_all = get_host_groups(username) log.save()
# for group in group_all:
# groups_attr[group.name] = [group.id, group.comment]
# return groups_attr
# def get_user_host_group_member(username, gid):
# """
# Get the host group hosts of under the user control.
# 获取用户有权限主机组下的主机
# """
# groups_attr = get_user_host_group(username)
# groups_ids = [attr[0] for name, attr in groups_attr.items()]
# hosts_attr = {}
# if int(gid) in groups_ids:
# user = User.objects.filter(username=username)
# if user:
# user = user[0]
# hosts = get_host_groups(gid)
# for host in hosts:
# alias = AssetAlias.objects.filter(user=user, host=host)
# if alias and alias[0].alias != '':
# hosts_attr[host.ip] = [host.id, host.ip, alias[0].alias]
# else:
# hosts_attr[host.ip] = [host.id, host.ip, host.comment]
# return hosts_attr
# def user_asset_info(user, printable=False):
# """
# Get or Print asset info
# 获取或打印用户资产信息
# """
# assets_info = {}
# try:
# assets = get_asset(user)
# except ServerError, e:
# color_print(e, 'red')
# return
#
# for asset in assets:
# asset_alias = AssetAlias.objects.filter(user=user, asset=asset)
# if asset_alias and asset_alias[0].alias != '':
# assets_info[asset.ip] = [asset.id, asset.ip, asset_alias[0].alias]
# else:
# assets_info[asset.ip] = [asset.id, asset.ip, asset.comment]
#
# if printable:
# ips = assets_info.keys()
# ips.sort()
# for ip in ips:
# print '%-15s -- %s' % (ip, assets_info[ip][2])
# print ''
# else:
# return assets_info
def verify_connect(username, part_ip): def verify_connect(username, part_ip):
ip_matched = [] ip_matched = []
try: try:
assets_info = user.get_asset_info() assets_info = login_user.get_asset_info()
except ServerError, e: except ServerError, e:
color_print(e, 'red') color_print(e, 'red')
return False return False
@ -260,7 +193,7 @@ def verify_connect(username, part_ip):
if part_ip in info: if part_ip in info:
ip_matched.append(ip) ip_matched.append(ip)
logger.debug('%s matched input %s: %s' % (user.username, part_ip, ip_matched)) logger.debug('%s matched input %s: %s' % (login_user.username, part_ip, ip_matched))
ip_matched = list(set(ip_matched)) ip_matched = list(set(ip_matched))
if len(ip_matched) > 1: if len(ip_matched) > 1:
@ -385,7 +318,7 @@ def exec_cmd_servers(username):
inputs = raw_input('\033[1;32mip(s)>: \033[0m') inputs = raw_input('\033[1;32mip(s)>: \033[0m')
if inputs in ['q', 'Q']: if inputs in ['q', 'Q']:
break break
get_hosts = user.get_asset_info().keys() get_hosts = login_user.get_asset_info().keys()
if ',' in inputs: if ',' in inputs:
ips_input = inputs.split(',') ips_input = inputs.split(',')
@ -419,8 +352,8 @@ def exec_cmd_servers(username):
if __name__ == '__main__': if __name__ == '__main__':
if not user.validate(): if not login_user.validate():
color_print_exit(u'没有该用户 No that user.') color_print(u'没有该用户 No that user.', exits=True)
print_prompt() print_prompt()
gid_pattern = re.compile(r'^g\d+$') gid_pattern = re.compile(r'^g\d+$')
@ -434,10 +367,10 @@ if __name__ == '__main__':
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit(0) sys.exit(0)
if option in ['P', 'p']: if option in ['P', 'p']:
user.get_asset_info(printable=True) login_user.get_asset_info(printable=True)
continue continue
elif option in ['G', 'g']: elif option in ['G', 'g']:
user.get_asset_group_info(printable=True) login_user.get_asset_group_info(printable=True)
continue continue
elif gid_pattern.match(option): elif gid_pattern.match(option):
gid = option[1:].strip() gid = option[1:].strip()

View File

@ -12,6 +12,7 @@ import ldap
from ldap import modlist from ldap import modlist
import hashlib import hashlib
import datetime import datetime
import random
import subprocess import subprocess
from django.core.paginator import Paginator, EmptyPage, InvalidPage from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
@ -150,34 +151,57 @@ def pages(posts, r):
class PyCrypt(object): class PyCrypt(object):
"""This class used to encrypt and decrypt password.""" """
This class used to encrypt and decrypt password.
对称加密库
"""
def __init__(self, key): def __init__(self, key):
self.key = key self.key = key
self.mode = AES.MODE_CBC self.mode = AES.MODE_CBC
def encrypt(self, text): def _random_pass(self):
cryptor = AES.new(self.key, self.mode, b'0000000000000000') """
length = 16 random password
随机生成密码
"""
salt_key = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@$%^&*()_'
symbol = '!@$%^&*()_'
salt_list = []
for i in range(60):
salt_list.append(random.choice(salt_key))
for i in range(4):
salt_list.append(random.choice(symbol))
salt = ''.join(salt_list)
self.salt = salt
def encrypt(self):
"""
encrypt gen password
加密生成密码
"""
cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
length = 64
try: try:
count = len(text) count = len(self.salt)
except TypeError: except TypeError:
raise ServerError('Encrypt password error, TYpe error.') # raise ServerError('Encrypt password error, TYpe error.')
pass
add = (length - (count % length)) add = (length - (count % length))
text += ('\0' * add) self.salt += ('\0' * add)
ciphertext = cryptor.encrypt(text) cipher_text = cryptor.encrypt(self.salt)
return b2a_hex(ciphertext) return b2a_hex(cipher_text)
def decrypt(self, text): def decrypt(self, text):
cryptor = AES.new(self.key, self.mode, b'0000000000000000') cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
try: try:
plain_text = cryptor.decrypt(a2b_hex(text)) plain_text = cryptor.decrypt(a2b_hex(text))
except TypeError: except TypeError:
raise ServerError('Decrypt password error, TYpe error.') # raise ServerError('Decrypt password error, TYpe error.')
pass
return plain_text.rstrip('\0') return plain_text.rstrip('\0')
CRYPTOR = PyCrypt(KEY)
class ServerError(Exception): class ServerError(Exception):
@ -595,17 +619,15 @@ def asset_perm_api(asset):
return user_permed_list return user_permed_list
def get_connect_item(username, ip): def get_connect_item(user, ip):
asset = get_object(Asset, ip=ip) asset = get_object(Asset, ip=ip)
port = int(asset.port) port = int(asset.port)
if not asset.is_active: if not asset.is_active:
raise ServerError('Host %s is not active.' % ip) raise ServerError('Host %s is not active.' % ip)
user = get_object(User, username=username)
if not user.is_active: if not user.is_active:
raise ServerError('User %s is not active.' % username) raise ServerError('User %s is not active.' % user.username)
login_type_dict = { login_type_dict = {
'L': user.ldap_pwd, 'L': user.ldap_pwd,
@ -613,7 +635,7 @@ def get_connect_item(username, ip):
if asset.login_type in login_type_dict: if asset.login_type in login_type_dict:
password = CRYPTOR.decrypt(login_type_dict[asset.login_type]) password = CRYPTOR.decrypt(login_type_dict[asset.login_type])
return username, password, ip, port return user.username, password, ip, port
elif asset.login_type == 'M': elif asset.login_type == 'M':
username = asset.username username = asset.username
@ -749,4 +771,7 @@ def node_auth(request):
else: else:
result = {'auth': {'username': username, 'result': 'failed'}} result = {'auth': {'username': username, 'result': 'failed'}}
return HttpResponse(json.dumps(result, sort_keys=True, indent=2), content_type='application/json') return HttpResponse(json.dumps(result, sort_keys=True, indent=2), content_type='application/json')
CRYPTOR = PyCrypt(KEY)