Ejemplo n.º 1
0
    def setUp(self):
        # Start the daemon
        self.currentdir = os.path.dirname(
            os.path.abspath(inspect.getfile(inspect.currentframe())))
        self.parentdir = os.path.dirname(self.currentdir)
        self.xmlfilepath = self.currentdir + "/sample/challenge.xml"
        self.d = vagrantData(self.xmlfilepath)

        self.assertTrue(self.d.parse())
Ejemplo n.º 2
0
    def setUp(self):
        # Start the daemon
        self.currentdir = os.path.dirname(
            os.path.abspath(inspect.getfile(inspect.currentframe())))
        self.parentdir = os.path.dirname(self.currentdir)
        self.xmlfilepath = self.currentdir + "/sample/challenge.xml"
        self.d = vagrantData(self.xmlfilepath)

        self.assertTrue(self.d.parse())
Ejemplo n.º 3
0
    def test_create_box(self):
        # Send a command via pipe
        # Make a connection to the daemon
        randStr = "qwerty123"
        o_pipename = "../tmp/pipe"
        i_pipename = "../tmp/" + randStr
        outfifo = open(o_pipename, 'w+')
        command = randStr + " create " + self.currentdir + "/sample "
        print "COMMAND: %s" % command
        outfifo.write(command)
        outfifo.close()

        # Now listen to a specific pipe
        if not os.path.exists(i_pipename):
            os.mkfifo(i_pipename)
        i_fifo = open(i_pipename, 'r')
        while True:
            line = i_fifo.readline()[:-1]
            if line:
                data = json.loads(line)

                self.assertEquals('success', data['message'])
                self.assertEquals('ubuntu/trusty64', data['data']['basebox'])
                self.basebox = data['data']['basebox']
                self.__class__.g_boxId = data['data']['boxId']

                self.assertFalse(data['error'])

                challengeBoxPath = data['data']['basePath'] + "/" + data[
                    'data']['boxId']

                challengePath = data['data']['basePath'] + "/" + data['data'][
                    'boxId']

                # Check if challenge directory was created
                self.assertTrue(os.path.exists(challengePath))

                # Check if required files and folders were created
                self.assertTrue(
                    os.path.exists(challengePath + "/challenge.xml"))

                xmlData = vagrantData(challengePath + "/challenge.xml")
                xmlData.parse()

                self.assertTrue(os.path.exists(challengePath + "/files"))

                for _file in xmlData.files:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _file.src))

                for _flag in xmlData.flags:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _flag))

                for _script in xmlData.scripts:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _script))

                self.assertTrue(os.path.exists(challengePath + "/manifests"))

                self.assertTrue(os.path.exists(challengePath + "/Vagrantfile"))

                self.assertTrue(os.path.exists(challengePath + "/.status"))

                with open(challengePath + "/.status", 'r') as status_file:
                    status = json.loads(status_file.readline())
                    self.assertEquals(data['data']['basebox'],
                                      status['basebox'])
                    self.assertEquals(status['active'], 0)

                # TODO: verify more data as per xml provided

                # Add this directory to array for clearing at teardown
                self.dirsToClean.append(data['data']['basePath'] + "/" +
                                        data['data']['boxId'])

                # Verify the files, scripts against the challenge XML
                os.unlink(i_pipename)
                break
Ejemplo n.º 4
0
    def classifier(self, command):
        args = command.split(' ')

        if len(args) < 3:
            print """[%s] Invalid command: {%s} sent to daemon.
            Skipping the command!""" % (time.time(), command)
            return

        self.outPipe = self.currentPath + "/tmp/" + args[0]

        # Init entries to out dictionery
        self.out['error'] = False
        self.out['message'] = ''

        # ------------------------------------------------------------------------
        # Code to preform requested action
        # ------------------------------------------------------------------------
        os.chdir(self.currentPath)

        cmdString = args[1]
        if "create" == cmdString:
            """
            TASK - read xml file and create a box,return meaning full information
            """

            challengePath = args[2]
            xmlFile = challengePath + "/challenge.xml"
            # TODO verify the type of data ^
            xmlData = vagrantData(xmlFile)
            self.xmlData = xmlData
            success = xmlData.parse()
            if success is not True:
                self.out['error'] = True
                self.out['message'] = """Unable to parse provided XML!
                Error: %s """ % str(success)
            else:
                # TODO: verify the data loaded from XML
                data = {}
                data['basebox'] = xmlData.baseBox
                data['basePath'] = self.currentPath + "/data/boxes"

                # Add a base box if not exists
                self.vagrantAddBox(xmlData.baseBox)

                # Create a challenge directory
                if not os.path.exists("./data"):
                    os.makedirs("./data")

                tmpCurrentDir = "./data"

                if not os.path.exists(tmpCurrentDir + "/boxes"):
                    os.makedirs(tmpCurrentDir + "/boxes")
                tmpCurrentDir += "/boxes"

                challengeIdBase = xmlData.baseBox.replace('/', '_')
                i = 1
                challengeId = challengeIdBase + str(i)
                while os.path.exists(tmpCurrentDir + "/" + challengeId):
                    i += 1
                    challengeId = challengeIdBase + str(i)

                data['boxId'] = challengeId
                os.makedirs(tmpCurrentDir + "/" + challengeId)
                tmpCurrentDir += "/" + challengeId

                # Init vagrant at that directory
                if not self.vagrantInit(xmlData.baseBox, challengeId):
                    self.out['error'] = True
                    self.out['message'] = 'vagrant init failed'
                else:
                    shutil.copyfile(xmlFile, tmpCurrentDir + "/challenge.xml")
                    # create the files directory and copy the files, to that directory
                    # In same manner as provided in xml
                    os.makedirs(tmpCurrentDir + "/files")
                    directoriesCopies = []

                    # Copy the files
                    for _file in xmlData.files:
                        if helper.getRootFolder(_file.src) not in directoriesCopies:
                            # Copy that folder to this folder
                            directory = helper.getRootFolder(_file.src)
                            helper.copy(
                                challengePath + "/" + directory, tmpCurrentDir + "/files/" + directory)
                            directoriesCopies.append(directory)

                    # Copy the scripts
                    for _script in xmlData.scripts:
                        if helper.getRootFolder(_script) not in directoriesCopies:
                            # Copy that folder to this folder
                            directory = helper.getRootFolder(_script)
                            helper.copy(
                                challengePath + "/" + directory, tmpCurrentDir + "/files/" + directory)
                            directoriesCopies.append(directory)

                    # Copy the manifest file
                    if not xmlData.puppetManifest == '':
                        os.makedirs(tmpCurrentDir + "/manifests")
                        shutil.copyfile(
                            challengePath + "/" + xmlData.puppetManifest, tmpCurrentDir + "/manifests/default.pp")

                    # Modify the vagrantFile according to xml data
                    self.createVagrantFile(tmpCurrentDir)

                    # Create a .status file
                    status = {}
                    status['basebox'] = xmlData.baseBox
                    status['active'] = 0
                    with open(tmpCurrentDir + '/.status', 'w') as o_file:
                        o_file.write(json.dumps(status))

                    self.out['data'] = data
                    self.out['message'] = 'success'

        elif "start" == cmdString:
            _boxId = args[2]

            if not os.path.exists("./data"):
                self.out['error'] = True
                self.out[
                    'message'] = 'data directory does not exist. challenge cannot be created'
            else:
                tmpCurrentDir = "./data"
                if not os.path.exists(tmpCurrentDir + "/boxes"):
                    self.out['error'] = True
                    self.out[
                        'message'] = 'box for boxId %s not found' % _boxId
                elif not os.path.exists(tmpCurrentDir + "/boxes/" + _boxId):
                    self.out['error'] = True
                    self.out[
                        'message'] = 'box for boxId %s not found' % _boxId
                else:
                    if not os.path.exists(tmpCurrentDir + "/challenges"):
                        os.makedirs(tmpCurrentDir + "/challenges")

                    _challengeID = _boxId + helper.getRandStr(5)
                    while os.path.exists(tmpCurrentDir + "/challenges/" + _challengeID):
                        _challengeID = _boxId + helper.getRandStr(5)

                    # Copy all files to this challenge directory
                    helper.copy(
                        tmpCurrentDir + "/boxes/" + _boxId,
                        tmpCurrentDir + "/challenges/" + _challengeID)

                    # load the xml in this directory to memory
                    tmpCurrentDir += "/challenges/" + _challengeID
                    xmlFile = tmpCurrentDir + "/challenge.xml"
                    xmlData = vagrantData(xmlFile)
                    xmlData.parse()

                    # verify the content
                    # check for flags
                    err = False
                    fileNotFound = []

                    for flags in xmlData.flags:
                        if not os.path.exists(tmpCurrentDir + "/files/" + flags):
                            err = True
                            fileNotFound.append(flags)

                    # check for files
                    for files in xmlData.files:
                        if not os.path.exists(tmpCurrentDir + "/files/" + files.src):
                            print "[%s] file not found %s" % (time.time(),
                                tmpCurrentDir + "/files/" + files.src)

                            err = True
                            fileNotFound.append(files.src)

                    # check for scripts
                    for script in xmlData.scripts:
                        if not os.path.exists(tmpCurrentDir + "/files/" + script):
                            print "[%s] script not found %s" % (time.time(),
                                tmpCurrentDir + "/files/" + script)
                            err = True
                            fileNotFound.append(script)

                    # check for manifests
                    if not os.path.exists(tmpCurrentDir + "/manifests/default.pp"):
                        err = True
                        fileNotFound.append(xmlData.puppetManifest)

                    # local variable to store flag information
                    flag_info = []

                    if True == err:
                        self.out['err'] = True
                        self.out[
                            'message'] = 'following files were not found: \n'
                        for _file in fileNotFound:
                            self.out['message'] += _file + '\n'
                    else:
                        # modify the flag files
                        for flag in xmlData.flags:
                            _new_flag = helper.randomizeFlaginFile(
                                tmpCurrentDir + "/files/" + flag)
                            flag_info.append({"/files/" + flag: _new_flag})

                        # Subdomain thingy
                        print "modifying the vagrant file for network info"
                        self.modifyVagrantFile(
                            tmpCurrentDir + "/Vagrantfile", _challengeID)

                        # start the box
                        print "starting vagrant box"
                        self.VagrantUp(_challengeID)

                        # Update basebox status
                        with open("./data/boxes/" + _boxId + "/.status", 'r+') as bStatus:
                            baseboxStatus = json.loads(bStatus.readline())
                            baseboxStatus['active'] += 1
                            bStatus.seek(0)
                            bStatus.write(json.dumps(baseboxStatus))
                            bStatus.truncate()
                            bStatus.close()

                            with open(tmpCurrentDir + "/.status", 'w') as cStatus:
                                status = {
                                    'status': 'active',
                                    'basebox': baseboxStatus['basebox'],
                                    'boxId': _boxId
                                }
                                cStatus.write(json.dumps(status))

                    self.out['data'] = {}
                    self.out['data']['challengeId'] = _challengeID
                    self.out['data']['flags'] = flag_info
                    self.out['message'] = 'success'

        elif "stop" == cmdString:
            _challengeID = args[2]
            if not os.path.exists("./data/challenges/" + _challengeID):
                self.out['error'] = True
                self.out[
                    'message'] = 'unable to stop %s, as it doesn\'t exist' % _challengeID
            else:
                tmpCurrentDir = "./data/challenges/" + _challengeID

                # get the box ID
                with open(tmpCurrentDir + '/.status', 'r') as cStatus:
                    try:
                        boxId = json.loads(cStatus.readline())['boxId']
                        cStatus.close()

                        # Update basebox status
                        with open("./data/boxes/" + boxId + "/.status", 'r+') as bStatus:
                            baseboxStatus = json.loads(bStatus.readline())
                            baseboxStatus['active'] -= 1
                            bStatus.seek(0)
                            bStatus.write(json.dumps(baseboxStatus))
                            bStatus.truncate()
                    except:
                        print """[%s] found no boxId in .status file for 
                        challengeId: %s""" % (time.time(), _challengeID)

                # Stop the VM
                self.VagrantStop(_challengeID)

                # delete the challenegeID Dir
                shutil.rmtree(tmpCurrentDir)
                self.out['message'] = _challengeID + ' deleted successfully'
                self.out['data'] = {}
                self.out['data']['challenegeId'] = _challengeID

        elif "info" == cmdString:
            invalidCommand = False

            if "all" == args[2]:
                if "box" == args[3]:
                    # change this to showing all hackademic
                    # boxes added to system by parsing challenge.xml
                    # in each box that exist in ./data/boxes directory

                    self.out['data'] = []
                    tmpCurrentDir = "./data/boxes"

                    for _dir in os.listdir(tmpCurrentDir):
                        if os.path.isdir(tmpCurrentDir + "/" + _dir):
                            with open(tmpCurrentDir + "/" + _dir + "/.status", 'r') as status:
                                statusData = json.loads(status.readline())
                                statusData['last_modified'] = os.stat(
                                    tmpCurrentDir + "/" + _dir).st_mtime
                                statusData['boxId'] = _dir
                                self.out['data'].append(statusData)

                    self.out['message'] = 'success'

                elif "challenge" == args[3]:
                    # for each dir in ./data/challeneges
                    # Get status and print it back to client

                    self.out['data'] = []
                    tmpCurrentDir = "./data/challenges"

                    for _dir in os.listdir(tmpCurrentDir):
                        if os.path.isdir(tmpCurrentDir + "/" + _dir):
                            with open(tmpCurrentDir + "/" + _dir + "/.status", 'r') as status:
                                statusData = json.loads(status.readline())
                                statusData['last_modified'] = os.stat(
                                    tmpCurrentDir + "/" + _dir).st_mtime
                                statusData['challengeId'] = _dir
                                self.out['data'].append(statusData)

                    self.out['message'] = 'success'

                else:
                    invalidCommand = True

            elif "box" == args[2]:
                boxId = args[3]

                tmpCurrentDir = "./data/boxes/" + boxId
                self.out['data'] = []
                if not os.path.exists(tmpCurrentDir):
                    self.out['error'] = True
                    self.out['message'] = 'box doesn\'t exist'
                elif not os.path.exists(tmpCurrentDir + "/.status"):
                    self.out['error'] = True
                    self.out[
                        'message'] = 'no status information for the box available'
                else:
                    with open(tmpCurrentDir + "/.status", 'r') as status:
                        self.out['data'] = json.loads(status.readline())
                        self.out['data']['last_modified'] = os.stat(
                            tmpCurrentDir).st_mtime
                        self.out['data']['boxId'] = boxId
                        self.out['error'] = False
                        self.out['message'] = 'success'

            elif "challenge" == args[2]:
                challengeId = args[3]

                tmpCurrentDir = "./data/challenges/" + challengeId
                self.out['data'] = []
                if not os.path.exists(tmpCurrentDir):
                    self.out['error'] = True
                    self.out['message'] = 'challenge doesn\'t exist'
                elif not os.path.exists(tmpCurrentDir + "/.status"):
                    self.out['error'] = True
                    self.out[
                        'message'] = 'no status information for the challenge available'
                else:
                    with open(tmpCurrentDir + "/.status", 'r') as status:
                        self.out['data'] = json.loads(status.readline())
                        self.out['data']['last_modified'] = os.stat(
                            tmpCurrentDir).st_mtime
                        self.out['data']['challengeId'] = challengeId
                        self.out['error'] = False
                        self.out['message'] = 'success'

            else:
                invalidCommand = True

            if True == invalidCommand:
                self.out['error'] = True
                self.out['message'] = """usage of info command:
                info all box
                info all challenge
                info box <box ID>
                info challenge <challenge ID>
                """

        elif "destroy" == cmdString:
            self.data = {}
            if "all" == args[2]:
                print subprocess.check_output(['pwd'])
                for _dir in os.listdir("./data/challenges"):
                    if os.path.isdir("./data/challenges/" + _dir):
                        self.VagrantStop(_dir)
                        shutil.rmtree("./data/challenges/" + _dir)

                # reset 'active' in .status of everybox to 0
                for _dir in os.listdir("./data/boxes"):
                    if not os.path.isdir("./data/boxes/" + _dir):
                        continue
                    with open("./data/boxes/" + _dir + "/.status", 'r+') as status:
                        jStatus = json.loads(status.readline())
                        jStatus['active'] = 0
                        status.seek(0)
                        status.write(json.dumps(jStatus))
                        status.truncate()

                self.out['error'] = False
                self.out['message'] = 'all boxes destroyed'

            else:
                self.out['error'] = True
                self.out['message'] = 'invalid command'

        else:
            self.out['error'] = True
            self.out['error'] = 'Invalid command'
        # ------------------------------------------------------------------------
        # Code to respond back to the client
        # ------------------------------------------------------------------------
        # make a output fifo pipe
        if not os.path.exists(self.outPipe):
            os.mkfifo(self.outPipe)

        output = json.dumps(self.out) + ' '

        self.outfifo = open(self.outPipe, 'w+')
        self.outfifo.write(output)
        self.outfifo.close()

        print """[%s] Output sent back to client using pipe:
        %s""" % (time.time(), self.outPipe)
Ejemplo n.º 5
0
    def test_create_box(self):
        # Send a command via pipe
        # Make a connection to the daemon
        randStr = "qwerty123"
        o_pipename = "../tmp/pipe"
        i_pipename = "../tmp/" + randStr
        outfifo = open(o_pipename, 'w+')
        command = randStr + " create " + self.currentdir + "/sample "
        print "COMMAND: %s" % command
        outfifo.write(command)
        outfifo.close()

        # Now listen to a specific pipe
        if not os.path.exists(i_pipename):
            os.mkfifo(i_pipename)
        i_fifo = open(i_pipename, 'r')
        while True:
            line = i_fifo.readline()[:-1]
            if line:
                data = json.loads(line)

                self.assertEquals('success', data['message'])
                self.assertEquals('ubuntu/trusty64', data['data']['basebox'])
                self.basebox = data['data']['basebox']
                self.__class__.g_boxId = data['data']['boxId']

                self.assertFalse(data['error'])

                challengeBoxPath = data['data'][
                    'basePath'] + "/" + data['data']['boxId']

                challengePath = data['data'][
                    'basePath'] + "/" + data['data']['boxId']

                # Check if challenge directory was created
                self.assertTrue(os.path.exists(challengePath))

                # Check if required files and folders were created
                self.assertTrue(
                    os.path.exists(challengePath + "/challenge.xml"))

                xmlData = vagrantData(challengePath + "/challenge.xml")
                xmlData.parse()

                self.assertTrue(os.path.exists(challengePath + "/files"))

                for _file in xmlData.files:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _file.src))

                for _flag in xmlData.flags:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _flag))

                for _script in xmlData.scripts:
                    self.assertTrue(
                        os.path.exists(challengePath + "/files/" + _script))

                self.assertTrue(os.path.exists(challengePath + "/manifests"))

                self.assertTrue(os.path.exists(challengePath + "/Vagrantfile"))

                self.assertTrue(os.path.exists(challengePath + "/.status"))

                with open(challengePath + "/.status", 'r') as status_file:
                    status = json.loads(status_file.readline())
                    self.assertEquals(
                        data['data']['basebox'], status['basebox'])
                    self.assertEquals(status['active'], 0)

                # TODO: verify more data as per xml provided

                # Add this directory to array for clearing at teardown
                self.dirsToClean.append(
                    data['data']['basePath'] + "/" + data['data']['boxId'])

                # Verify the files, scripts against the challenge XML
                os.unlink(i_pipename)
                break