diff options
author | Parker Berberian <pberberian@iol.unh.edu> | 2017-12-20 13:13:34 -0500 |
---|---|---|
committer | Parker Berberian <pberberian@iol.unh.edu> | 2017-12-20 13:13:34 -0500 |
commit | a09a9d14fc8247e39d1d7bf0df5c14703831212e (patch) | |
tree | f7c74d48e3e9d43fa0804cc75121bac8337e5ead /laas-fog/pharoslaas | |
parent | bfd1f0efbe3196cdd6ab6bb811fc53828e45528f (diff) |
Adds Credential Manipulation
JIRA: PHAROS-327
Adds password_workflow, which sets a random password on the given host
and stores it encrypted in the datastore.
Also provides the actions to create and delete vpn users. Access information
is stored encrypted in the datastore.
Once the dashboard has email capabilities, we can automatically send out this info
and not have to store it. At the moment though, we have no other way to automatically
generate it and still be able to (manually) pass that info to the developer who books the pod.
Change-Id: I3e4fcfef748f20878bd7603f8ed1a0c7557c0763
Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'laas-fog/pharoslaas')
-rw-r--r-- | laas-fog/pharoslaas/actions/genPass.sh | 20 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/genPass.yaml | 26 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/setPass.sh | 19 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/setPass.yaml | 30 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/vpnAction.py | 183 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/vpn_delete_user.py | 47 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/vpn_delete_user.yaml | 30 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/vpn_make_user.py | 61 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/vpn_make_user.yaml | 31 | ||||
-rw-r--r-- | laas-fog/pharoslaas/actions/workflows/password_workflow.yaml | 18 |
10 files changed, 465 insertions, 0 deletions
diff --git a/laas-fog/pharoslaas/actions/genPass.sh b/laas-fog/pharoslaas/actions/genPass.sh new file mode 100644 index 0000000..5eba059 --- /dev/null +++ b/laas-fog/pharoslaas/actions/genPass.sh @@ -0,0 +1,20 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +pass=$(base64 /dev/urandom | head -c 50 | tr -d '/' | tr -d '+' | head -c 25) + +st2 key set "$1" "$pass" --encrypt diff --git a/laas-fog/pharoslaas/actions/genPass.yaml b/laas-fog/pharoslaas/actions/genPass.yaml new file mode 100644 index 0000000..c56daa6 --- /dev/null +++ b/laas-fog/pharoslaas/actions/genPass.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +name: genPass +entry_point: genPass.sh +enabled: true +runner_type: local-shell-script +parameters: + key: + type: string + required: true + position: 0 diff --git a/laas-fog/pharoslaas/actions/setPass.sh b/laas-fog/pharoslaas/actions/setPass.sh new file mode 100644 index 0000000..8b1ddfc --- /dev/null +++ b/laas-fog/pharoslaas/actions/setPass.sh @@ -0,0 +1,19 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +pass=$(st2 key get "$2" --decrypt | grep 'value' | awk '{print $4}') +ssh -o userknownhostsfile=/dev/null -o stricthostkeychecking=no root@$1 "echo -e '$pass\n$pass' | passwd" diff --git a/laas-fog/pharoslaas/actions/setPass.yaml b/laas-fog/pharoslaas/actions/setPass.yaml new file mode 100644 index 0000000..0c12cba --- /dev/null +++ b/laas-fog/pharoslaas/actions/setPass.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +name: setPass +enabled: true +entry_point: setPass.sh +runner_type: local-shell-script +parameters: + host: + required: true + type: string + position: 0 + key: + required: true + type: string + position: 1 diff --git a/laas-fog/pharoslaas/actions/vpnAction.py b/laas-fog/pharoslaas/actions/vpnAction.py new file mode 100644 index 0000000..819ba13 --- /dev/null +++ b/laas-fog/pharoslaas/actions/vpnAction.py @@ -0,0 +1,183 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +import ldap +import os +import random +from base64 import b64encode +from st2actions.runners.pythonrunner import Action + +names = [ + 'frodo_baggins', 'samwise_gamgee', 'peregrin_took', 'meriadoc_brandybuck', + 'bilbo_baggins', 'gandalf_grey', 'aragorn_dunadan', 'arwen_evenstar', + 'saruman_white', 'pippin_took', 'merry _randybuck', 'legolas_greenleaf', + 'gimli_gloin', 'anakin_skywalker', 'padme_amidala', 'han_solo', + 'jabba_hut', 'mace_windu', 'count_dooku', 'qui-gon_jinn', + 'admiral_ackbar', 'emperor_palpatine' +] + + +class VPNAction(Action): + """ + This class communicates with the ldap server to manage vpn users. + This class extends the above ABC, and implements the makeNewUser, + removeOldUser, and __init__ abstract functions you must override to + extend the VPN_BaseClass + """ + + def __init__(self, config=None): + """ + init takes the parsed vpn config file as an arguement. + automatically connects and authenticates on the ldap server + based on the configuration file + """ + self.config = config['vpn'] + server = self.config['server'] + self.uri = "ldap://"+server + + self.conn = None + user = self.config['authentication']['user'] + pswd = self.config['authentication']['pass'] + if os.path.isfile(pswd): + pswd = open(pswd).read() + self.connect(user, pswd) + + def connect(self, root_dn, root_pass): + """ + Opens a connection to the server in the config file + and authenticates as the given user + """ + self.conn = ldap.initialize(self.uri) + self.conn.simple_bind_s(root_dn, root_pass) + + def addUser(self, full_name, passwd): + """ + Adds a user to the ldap server. Creates the new user with the classes + and in the directory given in the config file. + full_name should be two tokens seperated by a space. The first token + will become the username + private helper function for the makeNewUser() + """ + full_name = str(full_name) + passwd = str(passwd) # avoids unicode bug + first = full_name.split('_')[0] + last = full_name.split('_')[1] + user_dir = self.config['directory']['user'] + user_dir += ','+self.config['directory']['root'] + user_dir = str(user_dir) + dn = "uid=" + first + ',' + user_dir + record = [ + ('objectclass', ['top', 'inetOrgPerson']), + ('uid', first), + ('cn', full_name), + ('sn', last), + ('userpassword', passwd), + ('ou', str(self.config['directory']['user'].split('=')[1])) + ] + self.conn.add_s(dn, record) + return first, dn + + def makeNewUser(self, name=None, passwd=None): + """ + creates a new user in the ldap database, with the given name + if supplied. If no name is given, we will try to select from the + pre-written list above, and will resort to generating a random string + as a username if the preconfigured names are all taken. + Returns the username and password the user needs to authenticate, and + the dn that we can use to manage the user. + """ + if name is None: + i = 0 + while not self.checkName(name): + i += 1 + if i == 20: + name = self.randoString(8) + name += ' '+self.randoString(8) + break # generates a random name to prevent infinite loop + name = self.genUserName() + if passwd is None: + passwd = self.randoString(15) + username, dn = self.addUser(name, passwd) + return username, passwd, dn + + def checkName(self, name): + """ + returns true if the name is available + """ + if name is None: + return False + uid = name.split('_')[0] + base = self.config['directory']['user'] + ',' + base += self.config['directory']['root'] + filtr = '(uid=' + uid + ')' + timeout = 5 + ans = self.conn.search_st( + base, + ldap.SCOPE_SUBTREE, + filtr, + timeout=timeout + ) + return len(ans) < 1 + + @staticmethod + def randoString(n): + """ + uses /dev/urandom to generate a random string of length n + """ + n = int(n) + # defines valid characters + alpha = 'abcdefghijklmnopqrstuvwxyz' + alpha_num = alpha + alpha_num += alpha.upper() + alpha_num += "0123456789" + + # generates random string from /dev/urandom + rnd = b64encode(os.urandom(3*n)).decode('utf-8') + random_string = '' + for char in rnd: + if char in alpha_num: + random_string += char + return str(random_string[:n]) + + def genUserName(self): + """ + grabs a random name from the list above + """ + i = random.randint(0, len(names) - 1) + return names[i] + + def deleteUser(self, dn): + dn = str(dn) # avoids unicode bug + self.conn.delete(dn) + + def getAllUsers(self): + """ + returns all the user dn's in the ldap database in a list + """ + base = self.config['directory']['user'] + ',' + base += self.config['directory']['root'] + filtr = '(objectclass='+self.config['user']['objects'][-1]+')' + timeout = 10 + ans = self.conn.search_st( + base, + ldap.SCOPE_SUBTREE, + filtr, + timeout=timeout + ) + users = [] + for user in ans: + users.append(user[0]) # adds the dn of each user + return users diff --git a/laas-fog/pharoslaas/actions/vpn_delete_user.py b/laas-fog/pharoslaas/actions/vpn_delete_user.py new file mode 100644 index 0000000..eac5f78 --- /dev/null +++ b/laas-fog/pharoslaas/actions/vpn_delete_user.py @@ -0,0 +1,47 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +import json +from vpnAction import VPNAction + + +class Del_VPN_User(VPNAction): + + def __init__(self, config=None): + super(Del_VPN_User, self).__init__(config=config) + + def run(self, dn=None, key=None): + if not dn or dn == "None": + if not key or key == "None": + return + vpn_info = json.loads( + self.action_service.get_value( + name=key, + local=False, + decrypt=True + ) + ) + dn = vpn_info['dn'] + st2key = key + else: + st2key = 'vpn_' + # get username from dn + for attr in dn.split(','): + if 'uid' in attr: + st2key += attr.split('=')[-1] + # we have the dn and key now + self.action_service.delete_value(name=st2key, local=False) + self.deleteUser(dn) diff --git a/laas-fog/pharoslaas/actions/vpn_delete_user.yaml b/laas-fog/pharoslaas/actions/vpn_delete_user.yaml new file mode 100644 index 0000000..4e06411 --- /dev/null +++ b/laas-fog/pharoslaas/actions/vpn_delete_user.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +name: vpn_delete_user +entry_point: vpn_delete_user.py +enabled: true +runner_type: python-script +parameters: + dn: + required: false + type: string + description: "dn of user to delete" + key: + required: false + type: string + description: "key in st2 datastore with vpn info" diff --git a/laas-fog/pharoslaas/actions/vpn_make_user.py b/laas-fog/pharoslaas/actions/vpn_make_user.py new file mode 100644 index 0000000..56cf9e6 --- /dev/null +++ b/laas-fog/pharoslaas/actions/vpn_make_user.py @@ -0,0 +1,61 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +import datetime +from vpnAction import VPNAction +import json + + +class Make_VPN_User(VPNAction): + + def __init__(self, config=None): + super(Make_VPN_User, self).__init__(config=config) + + def run(self, booking=None, user=None, passwd=None): + if user == "None": + user = None + if passwd == "None": + passwd = None + name, passwd, dn = self.makeNewUser(name=user, passwd=passwd) + vpn_info = {} + vpn_info['dn'] = dn + vpn_info['username'] = name + vpn_info['password'] = passwd + now = datetime.date.today() + vpn_info['created'] = now.isoformat() # 'YYYY-MM-DD' today + self.action_service.set_value( + name='vpn_'+name, + value=json.dumps(vpn_info), + local=False, + encrypt=True + ) + if booking is not None: + self.addUserToBooking(vpn_info, booking) + + def addUserToBooking(self, vpn_info, booking): + name = "booking_" + str(booking) + booking = json.loads( + self.action_service.get_value( + name=name, + local=False + ) + ) + booking['vpn_key'] = "vpn_" + vpn_info['username'] + self.action_service.set_value( + name=name, + value=json.dumps(booking), + local=False + ) diff --git a/laas-fog/pharoslaas/actions/vpn_make_user.yaml b/laas-fog/pharoslaas/actions/vpn_make_user.yaml new file mode 100644 index 0000000..eb90956 --- /dev/null +++ b/laas-fog/pharoslaas/actions/vpn_make_user.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +name: vpn_make_user +entry_point: vpn_make_user.py +runner_type: python-script +enabled: true +parameters: + booking: + required: false + type: string + user: + required: false + type: string + passwd: + required: false + type: string diff --git a/laas-fog/pharoslaas/actions/workflows/password_workflow.yaml b/laas-fog/pharoslaas/actions/workflows/password_workflow.yaml new file mode 100644 index 0000000..d400c53 --- /dev/null +++ b/laas-fog/pharoslaas/actions/workflows/password_workflow.yaml @@ -0,0 +1,18 @@ +--- +chain: + + - + name: genPasswd + ref: pharoslaas.genPass + parameters: + key: "{{host}}-pass" + on-success: setPasswd + + - + name: setPasswd + ref: pharoslaas.setPass + parameters: + host: "{{host}}" + key: "{{host}}-pass" + +default: genPasswd |