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())
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
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)
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