1 ##############################################################################
2 # Copyright 2017 Parker Berberian and Others #
4 # Licensed under the Apache License, Version 2.0 (the "License"); #
5 # you may not use this file except in compliance with the License. #
6 # You may obtain a copy of the License at #
8 # http://www.apache.org/licenses/LICENSE-2.0 #
10 # Unless required by applicable law or agreed to in writing, software #
11 # distributed under the License is distributed on an "AS IS" BASIS, #
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13 # See the License for the specific language governing permissions and #
14 # limitations under the License. #
15 ##############################################################################
20 from base64 import b64encode
21 from st2actions.runners.pythonrunner import Action
24 'frodo_baggins', 'samwise_gamgee', 'peregrin_took', 'meriadoc_brandybuck',
25 'bilbo_baggins', 'gandalf_grey', 'aragorn_dunadan', 'arwen_evenstar',
26 'saruman_white', 'pippin_took', 'merry _randybuck', 'legolas_greenleaf',
27 'gimli_gloin', 'anakin_skywalker', 'padme_amidala', 'han_solo',
28 'jabba_hut', 'mace_windu', 'count_dooku', 'qui-gon_jinn',
29 'admiral_ackbar', 'emperor_palpatine'
33 class VPNAction(Action):
35 This class communicates with the ldap server to manage vpn users.
36 This class extends the above ABC, and implements the makeNewUser,
37 removeOldUser, and __init__ abstract functions you must override to
38 extend the VPN_BaseClass
41 def __init__(self, config=None):
43 init takes the parsed vpn config file as an arguement.
44 automatically connects and authenticates on the ldap server
45 based on the configuration file
47 self.config = config['vpn']
48 server = self.config['server']
49 self.uri = "ldap://"+server
52 user = self.config['authentication']['user']
53 pswd = self.config['authentication']['pass']
54 if os.path.isfile(pswd):
55 pswd = open(pswd).read()
56 self.connect(user, pswd)
58 def connect(self, root_dn, root_pass):
60 Opens a connection to the server in the config file
61 and authenticates as the given user
63 self.conn = ldap.initialize(self.uri)
64 self.conn.simple_bind_s(root_dn, root_pass)
66 def addUser(self, full_name, passwd):
68 Adds a user to the ldap server. Creates the new user with the classes
69 and in the directory given in the config file.
70 full_name should be two tokens seperated by a space. The first token
71 will become the username
72 private helper function for the makeNewUser()
74 full_name = str(full_name)
75 passwd = str(passwd) # avoids unicode bug
76 first = full_name.split('_')[0]
77 last = full_name.split('_')[1]
78 user_dir = self.config['directory']['user']
79 user_dir += ','+self.config['directory']['root']
80 user_dir = str(user_dir)
81 dn = "uid=" + first + ',' + user_dir
83 ('objectclass', ['top', 'inetOrgPerson']),
87 ('userpassword', passwd),
88 ('ou', str(self.config['directory']['user'].split('=')[1]))
90 self.conn.add_s(dn, record)
93 def makeNewUser(self, name=None, passwd=None):
95 creates a new user in the ldap database, with the given name
96 if supplied. If no name is given, we will try to select from the
97 pre-written list above, and will resort to generating a random string
98 as a username if the preconfigured names are all taken.
99 Returns the username and password the user needs to authenticate, and
100 the dn that we can use to manage the user.
104 while not self.checkName(name):
107 name = self.randoString(8)
108 name += ' '+self.randoString(8)
109 break # generates a random name to prevent infinite loop
110 name = self.genUserName()
112 passwd = self.randoString(15)
113 username, dn = self.addUser(name, passwd)
114 return username, passwd, dn
116 def checkName(self, name):
118 returns true if the name is available
122 uid = name.split('_')[0]
123 base = self.config['directory']['user'] + ','
124 base += self.config['directory']['root']
125 filtr = '(uid=' + uid + ')'
127 ans = self.conn.search_st(
138 uses /dev/urandom to generate a random string of length n
141 # defines valid characters
142 alpha = 'abcdefghijklmnopqrstuvwxyz'
144 alpha_num += alpha.upper()
145 alpha_num += "0123456789"
147 # generates random string from /dev/urandom
148 rnd = b64encode(os.urandom(3*n)).decode('utf-8')
151 if char in alpha_num:
152 random_string += char
153 return str(random_string[:n])
155 def genUserName(self):
157 grabs a random name from the list above
159 i = random.randint(0, len(names) - 1)
162 def deleteUser(self, dn):
163 dn = str(dn) # avoids unicode bug
166 def getAllUsers(self):
168 returns all the user dn's in the ldap database in a list
170 base = self.config['directory']['user'] + ','
171 base += self.config['directory']['root']
172 filtr = '(objectclass='+self.config['user']['objects'][-1]+')'
174 ans = self.conn.search_st(
182 users.append(user[0]) # adds the dn of each user