From a0d279131e3cf8c82ad86433ba2634ddc195b65c Mon Sep 17 00:00:00 2001 From: Scratchcat1 Date: Tue, 17 Oct 2017 18:33:03 +0100 Subject: [PATCH] Add files via upload -Fixed an issue with Drone battery drain. -Fixed an issue where DroneInfo used the indexs of the Titles rather than the correct values, causing drones to all move at the same speed and assume the same DroneID etc. -Added option to override key exchange in favour of preshared keys. -Moved some constants into AATC_Config --- AATC_Config.py | 16 +++++++++ AATC_Crypto.py | 75 ++++++++++-------------------------------- AATC_Drone.py | 21 ++++++------ AATC_Drone_Logic.py | 67 ++++--------------------------------- AATC_Server_002.py | 22 ------------- AATC_Server_Starter.py | 3 +- 6 files changed, 52 insertions(+), 152 deletions(-) create mode 100644 AATC_Config.py 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")