Merge "Adds Credential Manipulation"
authorJack Morgan <jack.morgan@intel.com>
Tue, 9 Jan 2018 00:12:49 +0000 (00:12 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 9 Jan 2018 00:12:49 +0000 (00:12 +0000)
laas-fog/pharoslaas/actions/genPass.sh [new file with mode: 0644]
laas-fog/pharoslaas/actions/genPass.yaml [new file with mode: 0644]
laas-fog/pharoslaas/actions/setPass.sh [new file with mode: 0644]
laas-fog/pharoslaas/actions/setPass.yaml [new file with mode: 0644]
laas-fog/pharoslaas/actions/vpnAction.py [new file with mode: 0644]
laas-fog/pharoslaas/actions/vpn_delete_user.py [new file with mode: 0644]
laas-fog/pharoslaas/actions/vpn_delete_user.yaml [new file with mode: 0644]
laas-fog/pharoslaas/actions/vpn_make_user.py [new file with mode: 0644]
laas-fog/pharoslaas/actions/vpn_make_user.yaml [new file with mode: 0644]
laas-fog/pharoslaas/actions/workflows/password_workflow.yaml [new file with mode: 0644]

diff --git a/laas-fog/pharoslaas/actions/genPass.sh b/laas-fog/pharoslaas/actions/genPass.sh
new file mode 100644 (file)
index 0000000..5eba059
--- /dev/null
@@ -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 (file)
index 0000000..c56daa6
--- /dev/null
@@ -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 (file)
index 0000000..8b1ddfc
--- /dev/null
@@ -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 (file)
index 0000000..0c12cba
--- /dev/null
@@ -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 (file)
index 0000000..819ba13
--- /dev/null
@@ -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 (file)
index 0000000..eac5f78
--- /dev/null
@@ -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 (file)
index 0000000..4e06411
--- /dev/null
@@ -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 (file)
index 0000000..56cf9e6
--- /dev/null
@@ -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 (file)
index 0000000..eb90956
--- /dev/null
@@ -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 (file)
index 0000000..d400c53
--- /dev/null
@@ -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