diff --git a/connect.py b/connect.py index 03f03a5c4..6b14e2f3a 100755 --- a/connect.py +++ b/connect.py @@ -16,8 +16,6 @@ import getpass import fnmatch import readline from multiprocessing import Pool -from Crypto.Cipher import AES -from binascii import b2a_hex, a2b_hex from ConfigParser import ConfigParser from django.core.exceptions import ObjectDoesNotExist @@ -27,6 +25,7 @@ from juser.models import User from jasset.models import Asset from jlog.models import Log from jperm.views import perm_user_asset +from jumpserver.views import PyCrypt try: import termios @@ -75,34 +74,6 @@ class ServerError(Exception): pass -class PyCrypt(object): - """This class used to encrypt and decrypt password.""" - - def __init__(self, key): - self.key = key - self.mode = AES.MODE_CBC - - def encrypt(self, text): - cryptor = AES.new(self.key, self.mode, b'0000000000000000') - length = 16 - try: - count = len(text) - except TypeError: - raise ServerError('Encrypt password error, TYpe error.') - add = (length - (count % length)) - text += ('\0' * add) - ciphertext = cryptor.encrypt(text) - return b2a_hex(ciphertext) - - def decrypt(self, text): - cryptor = AES.new(self.key, self.mode, b'0000000000000000') - try: - plain_text = cryptor.decrypt(a2b_hex(text)) - except TypeError: - raise ServerError('Decrypt password error, TYpe error.') - return plain_text.rstrip('\0') - - def get_win_size(): """This function use to get the size of the windows!""" if 'TIOCGWINSZ' in dir(termios): diff --git a/jperm/models.py b/jperm/models.py index 083f8089d..0f41c7d10 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -18,7 +18,8 @@ class CmdGroup(models.Model): class SudoPerm(models.Model): + name = models.CharField(max_length=20) user_group = models.ManyToManyField(UserGroup) asset_group = models.ManyToManyField(BisGroup) cmd_group = models.ManyToManyField(CmdGroup) - comment = models.CharField(max_length=30) \ No newline at end of file + comment = models.CharField(max_length=30, null=True, blank=True) \ No newline at end of file diff --git a/jperm/views.py b/jperm/views.py index 68518fc02..7433a61a6 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -7,6 +7,14 @@ from jasset.models import Asset, BisGroup from jperm.models import Perm, SudoPerm, CmdGroup from django.core.paginator import Paginator, EmptyPage, InvalidPage from django.db.models import Q +from jumpserver.views import LDAP_ENABLE, ldap_conn, CONF + + +if LDAP_ENABLE: + LDAP_HOST_URL = CONF.get('ldap', 'host_url') + LDAP_BASE_DN = CONF.get('ldap', 'base_dn') + LDAP_ROOT_DN = CONF.get('ldap', 'root_dn') + LDAP_ROOT_PW = CONF.get('ldap', 'root_pw') def perm_group_update(user_group_name='', user_group_id='', asset_groups_name='', asset_groups_id=''): @@ -138,7 +146,6 @@ def perm_asset_detail(request): return render_to_response('jperm/perm_asset_detail.html', locals()) - def user_asset_cmd_groups_get(user_groups_select, asset_groups_select, cmd_groups_select): user_groups_select_list = [] asset_groups_select_list = [] @@ -167,10 +174,41 @@ def sudo_db_add(user_groups_select, asset_groups_select, cmd_groups_select, comm sudo_perm.cmd_group = cmd_groups_select_list -def sudo_ldap_add(user_groups_select, asset_groups_select, cmd_groups_select): +def unicode2str(unicode_list): + return [str(i) for i in unicode_list] + + +def sudo_ldap_add(name, users_runas, user_groups_select, asset_groups_select, cmd_groups_select): user_groups_select_list, asset_groups_select_list, cmd_groups_select_list = \ user_asset_cmd_groups_get(user_groups_select, asset_groups_select, cmd_groups_select) + users = [] + assets = [] + cmds = [] + + for user_group in user_groups_select_list: + users.extend(user_group.user_set.all()) + + for asset_group in asset_groups_select_list: + assets.extend(asset_group.asset_set.all()) + + for cmd_group in cmd_groups_select_list: + cmds.extend(cmd_group.cmd.split(',')) + + users_name = [user.name for user in users] + assets_ip = [asset.ip for asset in assets] + + sudo_dn = 'cn=%s,ou=Sudoers,%s' % (name, LDAP_BASE_DN) + sudo_attr = {'objectClass': ['top', 'sudoRole'], + 'cn': ['%s' % str(name)], + 'sudoCommand': unicode2str(cmds), + 'sudoHost': unicode2str(assets_ip), + 'sudoOption': ['!authenticate'], + 'sudoRunAsUser': unicode2str(users_runas), + 'sudoUser': unicode2str(users_name)} + + ldap_conn.add(sudo_dn, sudo_attr) + def sudo_add(request): header_title, path1, path2 = u'Sudo授权 | Perm Sudo Add.', u'jperm', u'sudo_add' @@ -179,16 +217,17 @@ def sudo_add(request): cmd_groups = CmdGroup.objects.all() if request.method == 'POST': + name = request.POST.get('name') + users_runas = request.POST.get('runas', 'root').split(',') user_groups_select = request.POST.getlist('user_groups_select') asset_groups_select = request.POST.getlist('asset_groups_select') cmd_groups_select = request.POST.getlist('cmd_groups_select') comment = request.POST.get('comment', '') sudo_db_add(user_groups_select, asset_groups_select, cmd_groups_select, comment) - + sudo_ldap_add(name, users_runas, user_groups_select, asset_groups_select, cmd_groups_select) msg = '添加成功' - return render_to_response('jperm/sudo_add.html', locals()) diff --git a/jumpserver/views.py b/jumpserver/views.py index b47035043..b072d1ab0 100644 --- a/jumpserver/views.py +++ b/jumpserver/views.py @@ -3,15 +3,29 @@ import hashlib import ldap from ldap import modlist +from Crypto.Cipher import AES +from binascii import b2a_hex, a2b_hex +from ConfigParser import ConfigParser +import os from django.http import HttpResponse from django.shortcuts import render_to_response from django.http import HttpResponseRedirect from juser.models import User -from connect import PyCrypt, KEY from jasset.models import Asset, BisGroup, IDC +BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +CONF = ConfigParser() +CONF.read(os.path.join(BASE_DIR, 'jumpserver.conf')) + +LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable') +if LDAP_ENABLE: + LDAP_HOST_URL = CONF.get('ldap', 'host_url') + LDAP_BASE_DN = CONF.get('ldap', 'base_dn') + LDAP_ROOT_DN = CONF.get('ldap', 'root_dn') + LDAP_ROOT_PW = CONF.get('ldap', 'root_pw') + def md5_crypt(string): return hashlib.new("md5", string).hexdigest() @@ -30,7 +44,7 @@ def jasset_group_add(name, comment, type): emg = u'该业务组已存在!' else: BisGroup.objects.create(name=name, comment=comment, type=type) - smg = u'业务组%s添加成功' %name + smg = u'业务组%s添加成功' % name def jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_active, j_comment): @@ -151,3 +165,38 @@ class LDAPMgmt(): print e +class PyCrypt(object): + """This class used to encrypt and decrypt password.""" + + def __init__(self, key): + self.key = key + self.mode = AES.MODE_CBC + + def encrypt(self, text): + cryptor = AES.new(self.key, self.mode, b'0000000000000000') + length = 16 + try: + count = len(text) + except TypeError: + raise ServerError('Encrypt password error, TYpe error.') + add = (length - (count % length)) + text += ('\0' * add) + ciphertext = cryptor.encrypt(text) + return b2a_hex(ciphertext) + + def decrypt(self, text): + cryptor = AES.new(self.key, self.mode, b'0000000000000000') + try: + plain_text = cryptor.decrypt(a2b_hex(text)) + except TypeError: + raise ServerError('Decrypt password error, TYpe error.') + return plain_text.rstrip('\0') + + +if LDAP_ENABLE: + ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW) +else: + ldap_conn = None + + + diff --git a/juser/views.py b/juser/views.py index 933a0dca3..deaf6b6a0 100644 --- a/juser/views.py +++ b/juser/views.py @@ -20,17 +20,16 @@ from juser.models import UserGroup, User from connect import PyCrypt, KEY from connect import BASE_DIR from connect import CONF -from jumpserver.views import md5_crypt,LDAPMgmt +from jumpserver.views import md5_crypt, LDAPMgmt, LDAP_ENABLE, ldap_conn - -CRYPTOR = PyCrypt(KEY) -LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable') if LDAP_ENABLE: LDAP_HOST_URL = CONF.get('ldap', 'host_url') LDAP_BASE_DN = CONF.get('ldap', 'base_dn') LDAP_ROOT_DN = CONF.get('ldap', 'root_dn') LDAP_ROOT_PW = CONF.get('ldap', 'root_pw') +CRYPTOR = PyCrypt(KEY) + def gen_rand_pwd(num): """生成随机密码""" @@ -176,20 +175,18 @@ def ldap_add_user(username, ldap_pwd): 'userPassword': ['{crypt}x'], 'gidNumber': [str(user.id)]} - sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN) - sudo_attr = {'objectClass': ['top', 'sudoRole'], - 'cn': ['%s' % str(username)], - 'sudoCommand': ['/bin/pwd'], - 'sudoHost': ['192.168.1.1'], - 'sudoOption': ['!authenticate'], - 'sudoRunAsUser': ['root'], - 'sudoUser': ['%s' % str(username)]} - - ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW) + # sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN) + # sudo_attr = {'objectClass': ['top', 'sudoRole'], + # 'cn': ['%s' % str(username)], + # 'sudoCommand': ['/bin/pwd'], + # 'sudoHost': ['192.168.1.1'], + # 'sudoOption': ['!authenticate'], + # 'sudoRunAsUser': ['root'], + # 'sudoUser': ['%s' % str(username)]} ldap_conn.add(user_dn, user_attr) ldap_conn.add(group_dn, group_attr) - ldap_conn.add(sudo_dn, sudo_attr) + # ldap_conn.add(sudo_dn, sudo_attr) def ldap_del_user(username): @@ -197,12 +194,21 @@ def ldap_del_user(username): group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN) sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN) - ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW) ldap_conn.delete(user_dn) ldap_conn.delete(group_dn) ldap_conn.delete(sudo_dn) +# def ldap_group_add(group_name, username_list, gid): +# group_dn = "cn=%s,ou=Group,%s" % (group_name, LDAP_BASE_DN) +# group_attr = {'objectClass': ['posixGroup', 'top'], +# 'cn': [str(group_name)], +# 'userPassword': ['{crypt}x'], +# 'gidNumber': [gid], +# 'memberUid': username_list} +# ldap_conn.add(group_dn, group_attr) + + def group_add(request, group_type_select='A'): error = '' msg = '' diff --git a/templates/jperm/sudo_add.html b/templates/jperm/sudo_add.html index 3ecbe8174..7756f2bf1 100644 --- a/templates/jperm/sudo_add.html +++ b/templates/jperm/sudo_add.html @@ -37,107 +37,132 @@
{{ msg }}
{% endif %}
-

用户组

-
- +
+ +
+ + 取个名字方便辨识,只支持英文 +
+
+
+ +
+ +
+ + + 允许以哪个用户允许sudo,逗号分隔,默认root + +
+
+
+ +
+ +
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+ +
-
-
- - +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
-

授权用户组

-
- +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
-
- -
- -
-

主机组

-
- -
-
- -
-
- - -
-
- -

授权主机组

-
- -
-
-
- -
- -
-

命令组

-
- -
-
- -
-
- - -
-
- -

命令组

-
- -
-
-
-
+
-
- - -
-
-
- - +
-
-
- + +
+
+
+ + +
+
+
+
diff --git a/templates/nav.html b/templates/nav.html index 3fb51ee85..dbff8989d 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -33,8 +33,23 @@ 授权管理