class ServerHandler():
    def __init__(self):
        self.host = '127.0.0.1'
        self.port = 65433
        self.leadAddress = None
        self.vectorManager = VectorManager()
        self.vectorManager.retrieveVectors()
        self.pendingVectors = dict()
        self.pendingVectorFilename = "pendingVectors.pkl"
        self.retrievePendingVectors()
        self.clientsConnected = list()
        self.bind()

    def bind(self):
        self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serverSocket.bind((self.host, self.port))
        self.serverSocket.listen()

    def addNewClient(self, clientAddress):
        self.clientsConnected.append(clientAddress)

    def removeClient(self, clientAddress):
        self.clientsConnected.remove(clientAddress)

    def storePendingVectors(self):
        with open(self.pendingVectorFilename, 'wb') as pkl_file:
            pickle.dump(self.pendingVectors, pkl_file)

    def retrievePendingVectors(self):
        filename_path = Path(self.pendingVectorFilename)
        if filename_path.exists():
            with open(self.pendingVectorFilename, 'rb') as pkl_file:
                self.pendingVectors = pickle.load(pkl_file)
 def __init__(self):
     self.host = '127.0.0.1'
     self.port = 65433
     self.leadAddress = None
     self.vectorManager = VectorManager()
     self.vectorManager.retrieveVectors()
     self.pendingVectors = dict()
     self.pendingVectorFilename = "pendingVectors.pkl"
     self.retrievePendingVectors()
     self.clientsConnected = list()
     self.bind()
 def __init__(self):
     self.logEntryManager = LogEntryManager()
     # self.logEntryManager.deleteLogEntriesDb()
     self.vectorManager = VectorManager()
     self.vectorManager.retrieveVectors()
     self.iconManager = IconManager()
     # self.iconManager.deleteStoredconsDb()
     self.logFileManager = LogFileManager(SplunkInterface())
     self.logFileManager.retrieveRootPath()
     # self.logFileManager.deleteLogFilesDb()
     self.logFileManager.retrieveLogFilesDb()
     self.eventConfig = EventConfig()
     # self.eventConfig.deleteEventConfig()
     self.isLead = False
     self.hasLead = False
     self.serverIp = None
     self.serverPort = 65433
     self.isConnected = False
     self.retrieveServerIp()
     self.address = hex(uuid.getnode())
     self.socket = None
     self.connectToServer()
     self.requestEventConfig()
 def __init__(self, clientHandler, triggerHelper):
     super(VectorDbConfiguration, self).__init__()
     self.clientHandler = clientHandler
     self.triggerHelper = triggerHelper
     self.colsPullTable = [
         "Vector Name", "Vector Description", "Vector Graph"
     ]
     self.colsPushTable = [
         "Vector Name", "Vector Description", "Change Summary",
         "Vector Graph"
     ]
     self.colsApproveTable = [
         "Source IP", "Request Timestamp", "Vector Name",
         "Vector Description", "Graph", "Approve"
     ]
     self.pushedVectorManager = VectorManager()
     self.pushedVectorManager.filename = "pushedVectors.pkl"
     self.pushedVectorManager.retrieveVectors()
     self.pulledVectorManager = VectorManager()
     self.pulledVectorManager.filename = "pulledVectors.pkl"
     self.pulledVectorManager.retrieveVectors()
     self.pendingVectors = dict()
     self.vectorDbLayout = QtWidgets.QVBoxLayout(self)
     self.initializeConfiguration()
Exemple #5
0
from LogEntryManager import LogEntryManager
from VectorManager import VectorManager

logEntryManager = LogEntryManager()
vectorManager = VectorManager()
class VectorDbConfiguration(QWidget):
    def __init__(self, clientHandler, triggerHelper):
        super(VectorDbConfiguration, self).__init__()
        self.clientHandler = clientHandler
        self.triggerHelper = triggerHelper
        self.colsPullTable = [
            "Vector Name", "Vector Description", "Vector Graph"
        ]
        self.colsPushTable = [
            "Vector Name", "Vector Description", "Change Summary",
            "Vector Graph"
        ]
        self.colsApproveTable = [
            "Source IP", "Request Timestamp", "Vector Name",
            "Vector Description", "Graph", "Approve"
        ]
        self.pushedVectorManager = VectorManager()
        self.pushedVectorManager.filename = "pushedVectors.pkl"
        self.pushedVectorManager.retrieveVectors()
        self.pulledVectorManager = VectorManager()
        self.pulledVectorManager.filename = "pulledVectors.pkl"
        self.pulledVectorManager.retrieveVectors()
        self.pendingVectors = dict()
        self.vectorDbLayout = QtWidgets.QVBoxLayout(self)
        self.initializeConfiguration()

    def initializeConfiguration(self):
        for i in reversed(range(self.vectorDbLayout.count())):
            self.vectorDbLayout.removeWidget(
                self.vectorDbLayout.itemAt(i).widget())
        self.vectorDbLabel = QtWidgets.QLabel(self)
        self.vectorDbLayout.addWidget(self.vectorDbLabel)
        if self.clientHandler.isLead:
            self.approvalLabel = QtWidgets.QLabel(self)
            self.vectorDbLayout.addWidget(self.approvalLabel)
            self.approvalTableWidget = QtWidgets.QTableWidget(self)
            self.approvalTableWidget.setColumnCount(0)
            self.approvalTableWidget.setRowCount(0)
            self.vectorDbLayout.addWidget(self.approvalTableWidget)
            self.updateApproveTable(self.pendingVectors)
        else:
            self.pullTableLabel = QtWidgets.QLabel(self)
            self.vectorDbLayout.addWidget(self.pullTableLabel)
            self.pullTableWidget = QtWidgets.QTableWidget(self)
            self.pullTableWidget.setColumnCount(0)
            self.pullTableWidget.setRowCount(0)
            self.vectorDbLayout.addWidget(self.pullTableWidget)
            self.pullButton = QtWidgets.QPushButton(self)
            self.pullButton.clicked.connect(self.handlePull)
            self.vectorDbLayout.addWidget(self.pullButton)
            self.pushTableLabel = QtWidgets.QLabel(self)
            self.vectorDbLayout.addWidget(self.pushTableLabel)
            self.pushTableWidget = QtWidgets.QTableWidget(self)
            self.pushTableWidget.setColumnCount(0)
            self.pushTableWidget.setRowCount(0)
            self.vectorDbLayout.addWidget(self.pushTableWidget)
            self.pushButton = QtWidgets.QPushButton(self)
            self.vectorDbLayout.addWidget(self.pushButton)
            self.pushButton.clicked.connect(self.handlePush)
            self.vectorDbLayout.addWidget(self.pushButton)
            self.updatePullTable(self.pulledVectorManager)
            self.updatePushTable(self.pushedVectorManager)
        self.initializeText()

    def onTabChange(self):
        if self.clientHandler.isLead:
            if self.clientHandler.isConnected:
                self.pendingVectors = self.clientHandler.getPendingVectors()
            else:
                print(
                    "Could not collect pending vectors. Not connected to server."
                )
        self.initializeConfiguration()

    def handlePull(self):
        if self.clientHandler.isConnected:
            self.clientHandler.pullVector()
            self.triggerHelper.connectVectorConfigurationTableTrigger()
            self.triggerHelper.emitVectorConfigurationTableTrigger()
            self.pulledVectorManager = deepcopy(
                self.clientHandler.vectorManager)
            self.pulledVectorManager.filename = "pulledVectors.pkl"
            self.pulledVectorManager.storeVectors()
            self.updatePullTable(self.pulledVectorManager)
        else:
            print("Not connected to server.")

    def handlePush(self):
        if self.clientHandler.isConnected:
            self.pushedVectorManager = deepcopy(
                self.clientHandler.vectorManager)
            self.determineVectorsToPush()
            self.clientHandler.pushVector(self.pushedVectorManager)
            self.pushedVectorManager.filename = "pushedVectors.pkl"
            self.pushedVectorManager.storeVectors()
            self.updatePushTable(self.pushedVectorManager)
        else:
            print("Not connected to server.")

    def determineVectorsToPush(self):
        pushedVectors = list(self.pushedVectorManager.vectors.values())
        for vector in list(self.pulledVectorManager.vectors.values()):
            if vector.vectorName not in self.pushedVectorManager.vectors:
                self.pushedVectorManager.vectors[vector.vectorName] = deepcopy(
                    self.pulledVectorManager.vectors[vector.vectorName])
                self.pushedVectorManager.vectors[
                    vector.vectorName].changeSummary = "Deleted"
        for vector in pushedVectors:
            if vector.vectorName in self.pulledVectorManager.vectors:
                if vector.equals(
                        self.pulledVectorManager.vectors[vector.vectorName]):
                    del self.pushedVectorManager.vectors[vector.vectorName]
                else:
                    vector.changeSummary = "Modified"
            else:
                vector.changeSummary = "Added"

    def updatePullTable(self, pulledVectorManager):
        vectors = pulledVectorManager.vectors
        totalRows = len(vectors)
        self.pullTableWidget.setColumnCount(len(self.colsPullTable))
        self.pullTableWidget.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOn)
        self.pullTableWidget.setRowCount(totalRows)
        header = self.pullTableWidget.horizontalHeader()
        for colNum in range(len(self.colsPullTable)):
            header.setSectionResizeMode(colNum, QtWidgets.QHeaderView.Stretch)
            headerItem = QTableWidgetItem(self.colsPullTable[colNum])
            headerItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pullTableWidget.setHorizontalHeaderItem(colNum, headerItem)
        rowNum = 0
        for vectorName, vector in vectors.items():
            self.pullTableWidget.setRowHeight(rowNum, 50)
            vectorNameItem = QtWidgets.QTableWidgetItem(vectorName)
            vectorNameItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pullTableWidget.setItem(
                rowNum, self.colsPullTable.index("Vector Name"),
                vectorNameItem)
            vectorDescriptionItem = QtWidgets.QTableWidgetItem(
                vector.vectorDescription)
            vectorDescriptionItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pullTableWidget.setItem(
                rowNum, self.colsPullTable.index("Vector Description"),
                vectorDescriptionItem)
            graphButton = ViewGraphButton(vector)
            graphButton.setText("View Graph")
            graphButton.setFont(QtGui.QFont('SansSerif', 7))
            self.pullTableWidget.setCellWidget(
                rowNum, self.colsPullTable.index("Vector Graph"), graphButton)
            rowNum += 1
        self.pullTableWidget.setEditTriggers(
            QtWidgets.QTableWidget.NoEditTriggers)

    def updatePushTable(self, pushedVectorManager):
        vectors = pushedVectorManager.vectors
        totalRows = len(vectors)
        self.pushTableWidget.setColumnCount(len(self.colsPushTable))
        self.pushTableWidget.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOn)
        self.pushTableWidget.setRowCount(totalRows)
        header = self.pushTableWidget.horizontalHeader()
        for colNum in range(len(self.colsPushTable)):
            header.setSectionResizeMode(colNum, QtWidgets.QHeaderView.Stretch)
            headerItem = QTableWidgetItem(self.colsPushTable[colNum])
            headerItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableWidget.setHorizontalHeaderItem(colNum, headerItem)
        rowNum = 0
        for vectorName, vector in vectors.items():
            self.pushTableWidget.setRowHeight(rowNum, 50)
            vectorNameItem = QtWidgets.QTableWidgetItem(vectorName)
            vectorNameItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableWidget.setItem(
                rowNum, self.colsPushTable.index("Vector Name"),
                vectorNameItem)
            vectorChangeSummaryItem = QtWidgets.QTableWidgetItem(
                vector.changeSummary)
            vectorChangeSummaryItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableWidget.setItem(
                rowNum, self.colsPushTable.index("Change Summary"),
                vectorChangeSummaryItem)
            vectorDescriptionItem = QtWidgets.QTableWidgetItem(
                vector.vectorDescription)
            vectorDescriptionItem.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableWidget.setItem(
                rowNum, self.colsPushTable.index("Vector Description"),
                vectorDescriptionItem)
            graphButton = ViewGraphButton(vector)
            graphButton.setText("View Graph")
            graphButton.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableWidget.setCellWidget(
                rowNum, self.colsPushTable.index("Vector Graph"), graphButton)
            rowNum += 1
        self.pushTableWidget.setEditTriggers(
            QtWidgets.QTableWidget.NoEditTriggers)

    def initializeText(self):
        self.vectorDbLabel.setText("VECTOR DB CONFIGURATION")
        self.vectorDbLabel.setFont(QtGui.QFont('SansSerif', 7))
        if self.clientHandler.isLead:
            self.approvalLabel.setText("Approval sync:")
            self.approvalLabel.setFont(QtGui.QFont('SansSerif', 7))
        else:
            self.pullTableLabel.setText("Pulled Vector DB Table (Analyst):")
            self.pullTableLabel.setFont(QtGui.QFont('SansSerif', 7))
            self.pushTableLabel.setText("Pushed Vector DB Table (Analyst):")
            self.pushTableLabel.setFont(QtGui.QFont('SansSerif', 7))
            self.pushButton.setText("Push Button")
            self.pushButton.setFont(QtGui.QFont('SansSerif', 7))
            self.pullButton.setText("Pull Button")
            self.pullButton.setFont(QtGui.QFont('SansSerif', 7))

    def updateApproveTable(self, pendingVectors):
        self.colsApproveTable = [
            "Vector Name", "Vector Description", "Change Summary", "Graph",
            "Approve", "Reject"
        ]
        totalRows = len(pendingVectors)
        self.approvalTableWidget.setColumnCount(len(self.colsApproveTable))
        self.approvalTableWidget.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOn)
        self.approvalTableWidget.setRowCount(totalRows)
        header = self.approvalTableWidget.horizontalHeader()
        for colNum in range(len(self.colsApproveTable)):
            header.setSectionResizeMode(colNum, QtWidgets.QHeaderView.Stretch)
            headerItem = QTableWidgetItem(self.colsApproveTable[colNum])
            headerItem.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setHorizontalHeaderItem(
                colNum, headerItem)
        rowNum = 0
        for vectorKey, vector in pendingVectors.items():
            self.approvalTableWidget.setRowHeight(rowNum, 50)
            vectorNameItem = QtWidgets.QTableWidgetItem(vector.vectorName)
            vectorNameItem.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setItem(
                rowNum, self.colsApproveTable.index("Vector Name"),
                vectorNameItem)
            changeItem = QtWidgets.QTableWidgetItem(vector.changeSummary)
            changeItem.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setItem(
                rowNum, self.colsApproveTable.index("Change Summary"),
                changeItem)
            vectorDescriptionItem = QtWidgets.QTableWidgetItem(
                vector.vectorDescription)
            vectorDescriptionItem.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setItem(
                rowNum, self.colsApproveTable.index("Vector Description"),
                vectorDescriptionItem)
            graphButton = ViewGraphButton(vector)
            graphButton.setText("View Graph")
            graphButton.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setCellWidget(
                rowNum, self.colsApproveTable.index("Graph"), graphButton)
            approveButton = ApproveVectorButton(self.updateApproveTable,
                                                self.clientHandler, vectorKey,
                                                vector)
            approveButton.setText("Approve")
            approveButton.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setCellWidget(
                rowNum, self.colsApproveTable.index("Approve"), approveButton)
            rejectButton = ApproveVectorButton(self.updateApproveTable,
                                               self.clientHandler, vectorKey,
                                               vector)
            rejectButton.setText("Reject")
            rejectButton.setFont(QtGui.QFont('SansSerif', 7))
            self.approvalTableWidget.setCellWidget(
                rowNum, self.colsApproveTable.index("Reject"), rejectButton)
            rowNum += 1
        self.approvalTableWidget.setEditTriggers(
            QtWidgets.QTableWidget.NoEditTriggers)
class ClientHandler():
    def __init__(self):
        self.logEntryManager = LogEntryManager()
        # self.logEntryManager.deleteLogEntriesDb()
        self.vectorManager = VectorManager()
        self.vectorManager.retrieveVectors()
        self.iconManager = IconManager()
        # self.iconManager.deleteStoredconsDb()
        self.logFileManager = LogFileManager(SplunkInterface())
        self.logFileManager.retrieveRootPath()
        # self.logFileManager.deleteLogFilesDb()
        self.logFileManager.retrieveLogFilesDb()
        self.eventConfig = EventConfig()
        # self.eventConfig.deleteEventConfig()
        self.isLead = False
        self.hasLead = False
        self.serverIp = None
        self.serverPort = 65433
        self.isConnected = False
        self.retrieveServerIp()
        self.address = hex(uuid.getnode())
        self.socket = None
        self.connectToServer()
        self.requestEventConfig()

    @synchronized_method
    def connectToServer(self):
        if self.serverIp != None:
            try:
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.socket.connect((self.serverIp, self.serverPort))
                serverInformation = self.recvMsg()
                serverInformation = pickle.loads(serverInformation)
                serverInformation = list(serverInformation.values())[0]
                self.hasLead = serverInformation["Lead Address"] != None
                if self.hasLead:
                    if serverInformation["Lead Address"] == self.address:
                        self.isLead = True
                self.isConnected = True
                return True
            except:
                print(
                    "Unable to connect to server. Check to make sure server is running and server IP address."
                )
                return False
        else:
            return False

    @synchronized_method
    def storeServerIp(self):
        with open("serverIp.pkl", 'wb') as pkl_file:
            pickle.dump(self.serverIp, pkl_file)

    @synchronized_method
    def retrieveServerIp(self):
        filename_path = Path("serverIp.pkl")
        if filename_path.exists():
            with open("serverIp.pkl", 'rb') as pkl_file:
                self.serverIp = pickle.load(pkl_file)

    @synchronized_method
    def requestIcons(self):
        self.iconManager.retrieveIconsDb()

    @synchronized_method
    def requestEventConfig(self):
        self.eventConfig.retrieveEventConfigDb()

    @synchronized_method
    def updateEventConfig(self):
        self.eventConfig.storeEventConfigDb()

    @synchronized_method
    def updateIcons(self):
        self.iconManager.updateIconsDb()

    @synchronized_method
    def deleteIcon(self, iconName):
        self.iconManager.deleteIconDb(iconName)

    @synchronized_method
    def editLogEntry(self, logEntry):
        self.logEntryManager.updateLogEntryDb(logEntry)

    @synchronized_method
    def setLead(self):
        self.sendMsg(pickle.dumps({"Set Lead": self.address}))
        self.vectorManager.deleteStoredVectors()
        self.deletePulledVectors()
        self.deletePushedVectors()
        address = pickle.loads(self.recvMsg())
        if self.address == address:
            self.pullVector()
            self.isLead = True
            self.hasLead = True

    @synchronized_method
    def pushVector(self, vectorManager):
        pushedVectors = list(vectorManager.vectors.values())
        self.sendMsg(pickle.dumps({"Push Vectors": pushedVectors}))

    @synchronized_method
    def pullVector(self):
        self.sendMsg(pickle.dumps({"Pull Vectors": None}))
        newVectors = pickle.loads(self.recvMsg()).vectors
        for vector in list(self.vectorManager.vectors.values()):
            if vector.vectorName not in newVectors:
                self.logEntryManager.handleVectorDeleted(vector)
        self.vectorManager.vectors = newVectors
        self.vectorManager.storeVectors()
        vectors = list(self.vectorManager.vectors.values())
        self.logEntryManager.updateLogEntries(vectors)

    @synchronized_method
    def approveVector(self, vectorKey, vector):
        if vector.changeSummary == "Deleted":
            if vector.vectorName in self.vectorManager.vectors:
                del self.vectorManager.vectors[vector.vectorName]
                self.logEntryManager.handleVectorDeleted(vector)
                self.logEntryManager.handleVectorDeletedDb(vector)
        else:
            self.handleDeletedEvents(vector)
            self.vectorManager.vectors[vector.vectorName] = vector
            vectors = list(self.vectorManager.vectors.values())
            self.logEntryManager.updateLogEntries(vectors)
            self.logEntryManager.updateLogEntriesDb(vectors)
        self.sendMsg(pickle.dumps({"Approve Vector": [vectorKey, vector]}))
        return self.getPendingVectors()

    @synchronized_method
    def handleDeletedEvents(self, vector):
        if vector.vectorName in list(self.vectorManager.vectors.keys()):
            originalVector = self.vectorManager.vectors[vector.vectorName]
            updatedLogEntries = set()
            for significantEventId, significantEvent in vector.significantEvents.items(
            ):
                updatedLogEntries.add(significantEvent.logEntry.id)
            for significantEventId, significantEvent in originalVector.significantEvents.items(
            ):
                if significantEvent.logEntry.id not in updatedLogEntries:
                    self.logEntryManager.handleEventDeletedDb(
                        significantEvent.logEntry)

    @synchronized_method
    def updateVector(self, vector):
        self.logEntryManager.updateLogEntries([vector])
        self.logEntryManager.updateLogEntriesDb([vector])
        self.sendMsg(pickle.dumps({"Update Vector": vector}))

    @synchronized_method
    def sendLogEntries(self, logEntries):
        for logEntry in logEntries:
            self.logEntryManager.storeLogEntryDb(logEntry)

    @synchronized_method
    def searchLogEntries(self, commandSearch, creatorBlueTeam,
                         creatorWhiteTeam, creatorRedTeam, eventTypeBlueTeam,
                         eventTypeWhiteTeam, eventTypeRedTeam, startTime,
                         endTime, locationSearch):
        self.logEntryManager.retrieveLogEntriesDb()
        validLogEntries = self.logEntryManager.searchLogEntries(
            commandSearch, creatorBlueTeam, creatorWhiteTeam, creatorRedTeam,
            eventTypeBlueTeam, eventTypeWhiteTeam, eventTypeRedTeam, startTime,
            endTime, locationSearch)
        self.logEntryManager.logEntries.clear()
        self.logEntryManager.logEntriesInTable = validLogEntries
        for logEntry in validLogEntries:
            self.logEntryManager.logEntries[logEntry.id] = logEntry
            currentAssociatedVectors = list()
            for vectorName, vector in self.vectorManager.vectors.items():
                for signficiantEventId, significantEvent in vector.significantEvents.items(
                ):
                    if significantEvent.logEntry.id == logEntry.id:
                        currentAssociatedVectors.append(vectorName)
            logEntry.associatedVectors = currentAssociatedVectors

    @synchronized_method
    def rejectVector(self, vectorKey):
        self.sendMsg(pickle.dumps({"Reject Vector": vectorKey}))
        return self.getPendingVectors()

    @synchronized_method
    def getPendingVectors(self):
        self.sendMsg(pickle.dumps({"Get Pending Vectors": None}))
        pendingVectors = pickle.loads(self.recvMsg())
        return pendingVectors

    @synchronized_method
    def releaseLead(self):
        self.sendMsg(pickle.dumps({"Release Lead": self.address}))
        completed = pickle.loads(self.recvMsg())
        if completed:
            self.isLead = False
            self.hasLead = False
            for vector in list(self.vectorManager.vectors.values()):
                self.logEntryManager.handleVectorDeleted(vector)
            self.vectorManager.vectors.clear()
            self.vectorManager.deleteStoredVectors()

    @synchronized_method
    def sendMsg(self, msg):
        msg = struct.pack('>I', len(msg)) + msg
        self.socket.sendall(msg)

    @synchronized_method
    def recvMsg(self):
        raw_msglen = self.recvAll(4)
        if not raw_msglen:
            return None
        msglen = struct.unpack('>I', raw_msglen)[0]
        return self.recvAll(msglen)

    @synchronized_method
    def recvAll(self, n):
        data = bytearray()
        while len(data) < n:
            packet = self.socket.recv(n - len(data))
            if not packet:
                return None
            data.extend(packet)
        return data

    @synchronized_method
    def deletePushedVectors(self):
        filename_path = Path("pushedVectors.pkl")
        if filename_path.exists():
            os.remove(filename_path)

    @synchronized_method
    def deletePulledVectors(self):
        filename_path = Path("pulledVectors.pkl")
        if filename_path.exists():
            os.remove(filename_path)

    @synchronized_method
    def editLogEntryVectors(self, logEntry, newVectors):
        oldVectors = logEntry.associatedVectors
        logEntry.associatedVectors = newVectors
        self.vectorManager.handleUpdateToLogEntry(oldVectors, newVectors,
                                                  logEntry)
        if self.isLead:
            for vectorName in oldVectors:
                self.updateVector(self.vectorManager.vectors[vectorName])
            for vectorName in newVectors:
                self.updateVector(self.vectorManager.vectors[vectorName])