diff --git a/AATC_Config.py b/AATC_Config.py new file mode 100644 index 0000000..cc7be40 --- /dev/null +++ b/AATC_Config.py @@ -0,0 +1,16 @@ +PRE_SHARED_ENCRYPTION_KEYS_ENABLE = False +PRE_SHARED_AES_KEY = b"00000000000000000000000000000000" +PRE_SHARED_IV_KEY = b"00000000000000000000000000000000" + +DEFAULT_AES_KEYSIZE = 32 +ALLOWED_AES_KEYSIZES = [16,24,32] + +DEFAULT_RSA_KEYSIZE = 2048 + + +DEFAULT_DRONE_BATTERY_VALUE = 100 +DEFAULT_DRONE_ATWAYPOINT_SIZES = (0.001,0.001,5) +DEFAULT_DRONE_COORDINATE = (0,0,0) + + +DRONE_BATTERY_DRAIN_MULT = 1 diff --git a/AATC_Crypto.py b/AATC_Crypto.py index 30b0663..d99635d 100644 --- a/AATC_Crypto.py +++ b/AATC_Crypto.py @@ -1,7 +1,5 @@ #AATC crypto module -# Diffie-Hellman from 'pip install diffiehellman ' -#import diffiehellman.diffiehellman as DH -import codecs,recvall,ast,binascii,os +import codecs,recvall,ast,binascii,os,AATC_Config from Crypto.Cipher import AES,PKCS1_OAEP from Crypto.PublicKey import RSA @@ -24,13 +22,16 @@ class Crypter: def __init__(self, con, mode = "CLIENT",AutoGenerate = True): self.con = con self.SetMode(mode) - if AutoGenerate: + if AATC_Config.PRE_SHARED_ENCRYPTION_KEYS_ENABLE: #Allows preshared encryption keys to be used + self.SetEncryptionKeys(AATC_Config.PRE_SHARED_AES_KEY, AATC_Config.PRE_SHARED_IV_KEY) + + elif AutoGenerate: self.GenerateKey() def SetMode(self,mode): self.mode = mode - def GenerateKey(self,key_size = 2048): + def GenerateKey(self,key_size = AATC_Config.DEFAULT_RSA_KEYSIZE): print("Generating encryption keys. Please stand by...") #Generating keys takes a long time and have found no way to shorted key length if self.mode == "SERVER": self.ServerGenerateKey() @@ -42,7 +43,7 @@ def GenerateKey(self,key_size = 2048): - def ClientGenerateKey(self,RSA_KeySize,AES_KeySize= 32): + def ClientGenerateKey(self,RSA_KeySize,AES_KeySize= AATC_Config.DEFAULT_AES_KEYSIZE): RSAKey = RSA.generate(RSA_KeySize) privateKey = RSAKey.exportKey("DER") @@ -65,8 +66,7 @@ def ClientGenerateKey(self,RSA_KeySize,AES_KeySize= 32): self.AESKey = RSAPrivateObject.decrypt(Message[0]) self.IV = RSAPrivateObject.decrypt(Message[1]) - self.EncryptAES = AES.new(self.AESKey,AES.MODE_GCM,self.IV) - self.DecryptAES = AES.new(self.AESKey,AES.MODE_GCM,self.IV) + self.SetEncryptionKeys(self.AESKey,self.IV) @@ -81,8 +81,8 @@ def ServerGenerateKey(self): if Command == "ExchangeKey": publicKey,AES_KeySize = Arguments[0],Arguments[1] - if AES_KeySize not in [16,24,32]: - AES_KeySize = 32 #If key size is not valid set size to default of 32 + if AES_KeySize not in AATC_Config.ALLOWED_AES_KEYSIZES: + AES_KeySize = AATC_Config.DEFAULT_AES_KEYSIZE #If key size is not valid set size to default of AATC_Config.DEFAULT_AES_KEYSIZE self.AESKey = binascii.b2a_hex(os.urandom(AES_KeySize//2)) # Here to allow regeneration of AES key while still in loop if required. self.IV = binascii.b2a_hex(os.urandom(AES_KeySize//2)) @@ -100,7 +100,13 @@ def ServerGenerateKey(self): else: self.Send((False,("Command does not exist",))) - + + self.SetEncryptionKeys(self.AESKey,self.IV) + + + def SetEncryptionKeys(self,AESKey,IV): + self.AESKey = AESKey + self.IV = IV self.EncryptAES = AES.new(self.AESKey,AES.MODE_GCM,self.IV) #Two seperate instances to encrypt and decrypt as non ECB AES is a stream cipher self.DecryptAES = AES.new(self.AESKey,AES.MODE_GCM,self.IV) #Errors will occur if encrypt and decrypt are not equal in count. @@ -109,53 +115,6 @@ def ServerGenerateKey(self): - -## def DHServerGenerateKey(self): -## DifHel = DH.DiffieHellman() -## -## -## Exit = False -## while not Exit : -## data = self.Recv() -## Command, Arguments = data[0],data[1] -## -## if Command == "PublicKey": -## try: -## DifHel.generate_public_key() -## DifHel.generate_shared_secret(Arguments[0]) -## self.Send(("PublicKey",(DifHel.public_key,))) -## except: -## self.Send((False,())) -## -## elif Command == "Exit": -## self.Send((True,())) -## Exit = True -## -## self.shared_key = DifHel.shared_key[0:32] -## self.AES = AES.new(self.shared_key) -## -## -## -## -## def DHClientGenerateKey(self,key_size): -## DifHel = DH.DiffieHellman() -## DifHel.generate_public_key() -## -## -## self.Send(("PublicKey",(DifHel.public_key,))) -## data = self.Recv() -## if data[0] == False: -## raise Exception("Error occured while transmitting public key") -## DifHel.generate_shared_secret(data[1][0]) -## -## self.Send(("Exit",())) -## data = self.Recv() -## if data[0] == False: -## raise Exception("Server failed to commit to exit") -## -## self.shared_key = DifHel.shared_key[0:32] -## self.AES = AES.new(self.shared_key) - diff --git a/AATC_Drone.py b/AATC_Drone.py index 6d99ef2..0138d0e 100644 --- a/AATC_Drone.py +++ b/AATC_Drone.py @@ -175,19 +175,20 @@ def MakeDroneInfo(DroneMessage,DroneData): class DroneInformation: def __init__(self,Message,DroneInfo): + DroneInfo = DroneInfo[0] Message = ast.literal_eval(Message) - Index = {} + ColumnValue = {} Titles = ["DroneID","UserID","DroneName","DroneType","DroneSpeed","DroneRange","DroneWeight"] for title in Titles: - Index[title] = Message.index(title) - - self.DroneID = Index["DroneID"] - self.UserID = Index["UserID"] - self.DroneName = Index["DroneName"] - self.DroneType = Index["DroneType"] - self.DroneSpeed = Index["DroneSpeed"] - self.DroneRange = Index["DroneRange"] - self.DroneWeight = Index["DroneWeight"] + ColumnValue[title] = DroneInfo[Message.index(title)] + + self.DroneID = ColumnValue["DroneID"] + self.UserID = ColumnValue["UserID"] + self.DroneName = ColumnValue["DroneName"] + self.DroneType = ColumnValue["DroneType"] + self.DroneSpeed = ColumnValue["DroneSpeed"] + self.DroneRange = ColumnValue["DroneRange"] + self.DroneWeight = ColumnValue["DroneWeight"] diff --git a/AATC_Drone_Logic.py b/AATC_Drone_Logic.py index a6caaf1..407c711 100644 --- a/AATC_Drone_Logic.py +++ b/AATC_Drone_Logic.py @@ -1,4 +1,4 @@ -import AATC_Drone,threading,queue,math,time,AATC_GPIO,random +import AATC_Drone,threading,queue,math,time,AATC_GPIO,random, AATC_Config import AATC_Coordinate class DroneLogicSystem: @@ -83,62 +83,7 @@ def RunFlight(self): -##def LaunchDroneLogic(DRONEID,DRONEPASSWORD,FlightQueue,StatusQueue,GPIO_Queue,SLEEP_TIME = 60): -## Exit = False -## while not Exit: -## try: -## D = AATC_Drone.CreateDroneInterface() -## LoginSucess,Message = D.Login(DRONEID,DRONEPASSWORD) -## print(LoginSucess,Message) -## if LoginSucess: -## -## AvailableFlight = False -## while not AvailableFlight: -## -## if not StatusQueue.empty(): -## Status = StatusQueue.get() -## StatusQueue.task_done() -## D.UpdateDroneStatus(Status["Coords"],Status["Battery"])#dfjsafkdsajdfjs -## -## Sucess,Message,FlightID = D.CheckForFlight() -## AvailableFlight = Sucess -## time.sleep(SLEEP_TIME) #At the end to pause to wait so that if the server is still writing waypoints it can finish. -## -## -## FlightID = FlightID[0][0] -## print("Obtaining flight and drone information. FlightID :",FlightID) -## DroneInfo, Flight, Waypoints = GetAllFlightInfo(D,DRONEID,FlightID) -## -## FlightQueue.put((False,(DroneInfo,Flight,Waypoints))) -## -## except Exception as e: -## print("Error occured in Drone Logic",str(e)) -## AvailableFlight = False -## -## if AvailableFlight: -## -## complete = False -## crashed = False -## while not complete: #While drone not at target location -## try: -## if crashed: -## D = AATC_Drone.CreateDroneInterface() -## LoginSucess,Message = D.Login(DRONEID,DRONEPASSWORD) -## crashed = False -## while StatusQueue.empty(): -## time.sleep(SLEEP_TIME) -## Status = StatusQueue.get() -## StatusQueue.task_done() -## Sucess,Message = D.UpdateDroneStatus(Status["Coords"],Status["Battery"]) -## if "MarkComplete" in Status: -## complete = True -## print("Flight ",Status["MarkComplete"]," complete") -## Sucess,Message = D.MarkFlightComplete(Status["MarkComplete"],1) -## print("Sucess",Sucess," Message:",Message) -## time.sleep(SLEEP_TIME) -## except Exception as e: -## print("Error in drone logic flight stage",e) -## crashed = True + def GetAllFlightInfo(D,DRONEID,FlightID): #Gets all drone flight information and packages the information into objects @@ -183,14 +128,14 @@ def PutStatus(StatusQueue,Coords,Battery,MarkComplete = None,EmptyOverride = Fal def DecrementBattery(DroneInfo,CoordA,CoordB,Battery): distance = AATC_Coordinate.DeltaCoordToMetres(CoordA,CoordB) - decAmount = (distance/DroneInfo.DroneRange)*100*(1+random.randint(-1,1)*0.1) + decAmount = (distance/DroneInfo.DroneRange)*100*(1+random.randint(-1,1)*0.1) * AATC_Config.DRONE_BATTERY_DRAIN_MULT Battery -= decAmount return Battery def DroneHardware(FlightQueue,StatusQueue): - Battery = 100 - Coords = AATC_Drone.Coordinate(0,0,0) - xSize,ySize,zSize = 0.001,0.001,5 + Battery = AATC_Config.DEFAULT_DRONE_BATTERY_VALUE + Coords = AATC_Drone.Coordinate(*AATC_Config.DEFAULT_DRONE_COORDINATE) + xSize,ySize,zSize = AATC_Config.DEFAULT_DRONE_ATWAYPOINT_SIZES while True: time.sleep(1) diff --git a/AATC_Server_002.py b/AATC_Server_002.py index 79d4c2a..c42a1e3 100644 --- a/AATC_Server_002.py +++ b/AATC_Server_002.py @@ -76,7 +76,6 @@ def Connection_Loop(self): if Command == "Exit": Exit = True - self.DB.Exit() print("Process will now exit") @@ -168,7 +167,6 @@ def ProcessCommand(self,Command,Arguments): Sucess,Message,Data = False,"Command does not exist",[] print("User tried to use unregistered command") return Sucess,Message,Data - def Login(self,Arguments): Username,Password = Arguments[0],Arguments[1] @@ -461,27 +459,7 @@ def Exit(self,Arguments = None): return True,"Server process is exiting",[] -class BotConnection(UserConnection): - def __init__(self,UserID,chat_id,packet,bot): - self.UserID = UserID - self.chat_id = chat_id - self.bot = HedaBot.Telebot(bot) - self.bot.setChatID(chat_id) - self.DB = AATC_DB.DBConnection() - - def Send(self,data): - Sucess,Message,Data = data[0],data[1],data[2] - data = str(Sucess) +"\n" +str(Message)+ "\n" + str(Data) - self.bot.sendMessage(data) - - def Login(self,Arguments): - Username,Password = Arguments[0],Arguments[1] - Sucess,Message,UserID = self.DB.CheckCredentials(Username,Password) - if UserID != -1: - self.DB.SetUserID(self.chat_id,UserID) - return Sucess,Message,[] - diff --git a/AATC_Server_Starter.py b/AATC_Server_Starter.py index 24af976..9e2fe47 100644 --- a/AATC_Server_Starter.py +++ b/AATC_Server_Starter.py @@ -1,4 +1,4 @@ -import multiprocessing,socket,AATC_NoFlyZoneGrapher,sys,time,AATC_GPIO +import multiprocessing,socket,AATC_NoFlyZoneGrapher,sys,time,AATC_GPIO,HedaBot import AATC_Server_002 as AATC_Server from AATC_Coordinate import * @@ -172,6 +172,7 @@ def StartProcesses(Control_Queue): Control_Queue.put(("Controller","Create_Process",("Grapher",AATC_NoFlyZoneGrapher.NoFlyZoneGrapher))) Control_Queue.put(("Controller","Create_Process",("Cleaner",AATC_Server.Cleaner))) + Control_Queue.put(("Controller","Create_Process",("Hedabot",HedaBot.TelebotLaunch,(HedaBot.telepot.Bot(HedaBot.BOT_TOKEN),)))) print("[StartProcesses] All processes started")