def sendDataSenze(self, sensors, data, recipient): global device global aesKeys response = 'DATA' driver = myDriver() cry = myCrypto(device) for sensor in sensors: #If temperature is requested if "tp" == sensor: response = '%s #tp %s' % (response, driver.readTp()) #If AES key is requested if "key" == sensor: aeskey = "" #Generate AES Key if cry.generateAES(driver.readTime()): aeskey = cry.key #Save AES key aesKeys[recipient] = aeskey #AES key is encrypted by the recipient public key rep = myCrypto(recipient) encKey = rep.encryptRSA(b64encode(aeskey)) response = '%s #key %s' % (response, encKey) #If photo is requested elif "photo" == sensor: cam = myCamDriver() cam.takePhoto() photo = cam.readPhotob64() print photo response = '%s #photo %s' % (response, photo) #If time is requested elif "time" == sensor: response = '%s #time %s' % (response, driver.readTime()) #If gps is requested elif "gps" == sensor: #if AES key is available, gps data will be encrypted gpsData = '%s' % (driver.readGPS()) if recipient in aesKeys: rep = myCrypto(recipient) rep.key = aesKeys[recipient] gpsData = rep.encrypt(gpsData) response = '%s #gps %s' % (response, gpsData) #If gpio is requested elif "gpio" in sensor: m = re.search(r'\d+$', sensor) pinnumber = int(m.group()) print pinnumber response = '%s #gpio%s %s' % (response, pinnumber, driver.readGPIO(port=pinnumber)) else: response = '%s #%s NULL' % (response, sensor) response = "%s @%s" % (response, recipient) self.sendDatagram(senze=response)
def handleServerResponse(self, senze): sender = senze.getSender() data = senze.getData() sensors = senze.getSensors() cmd = senze.getCmd() if cmd == "DATA": if 'msg' in sensors and 'UserRemoved' in data['msg']: cry = myCrypto(device) try: os.remove(".devicename") os.remove(cry.pubKeyLoc) os.remove(cry.privKeyLoc) print "Device was successfully removed" except OSError: print "Cannot remove user configuration files" reactor.stop() elif 'pubkey' in sensors and data[ 'pubkey'] != "" and 'name' in sensors and data[ 'name'] != "": recipient = myCrypto(data['name']) if recipient.saveRSAPubKey(data['pubkey']): print "Public key=> " + data['pubkey'] + " Saved." else: print "Error: Saving the public key."
def sendDataSenze(self, sensors, data, recipient): global device global aesKeys response = 'DATA' driver = myDriver() cry = myCrypto(device) for sensor in sensors: #If AES key is requested if "key" == sensor: aeskey = "" #Generate AES Key if cry.generateAES(driver.readTime()): aeskey = cry.key #Save AES key aesKeys[recipient] = aeskey #AES key is encrypted by the recipient public key rep = myCrypto(recipient) encKey = rep.encryptRSA(b64encode(aeskey)) response = '%s #key %s' % (response, encKey) #If time is requested elif "time" == sensor: response = '%s #time %s' % (response, driver.readTime()) else: response = '%s #%s NULL' % (response, sensor) response = "%s @%s" % (response, recipient) self.sendDatagram(senze=response)
def init(): #cam=myCamDriver() global device global pubkey global serverPubKey global server #Here we will generate public and private keys for the device #These keys will be used to perform authentication and key exchange try: cry = myCrypto(name=device) #If keys are not available yet if not os.path.isfile(cry.pubKeyLoc): # Generate or loads an RSA keypair with an exponent of 65537 in PEM format # Private key and public key was saved in the .devicenamePriveKey and .devicenamePubKey files cry.generateRSA(bits=1024) pubkey = cry.loadRSAPubKey() print "DEVICE KEY : ", pubkey except: print "ERRER: Cannot genereate private/public keys for the device." raise SystemExit #Here we will load the public key of the server try: cry = myCrypto(name=server) #If keys are not available yet if os.path.isfile(cry.pubKeyLoc): serverPubKey = cry.loadRSAPubKey() print "SERVER KEY: ", serverPubKey except: print "ERRER: Cannot load server public key." raise SystemExit
def sendDataSenze(self,sensors,data,recipient): global device global aesKeys response='DATA' driver=myDriver() cry=myCrypto(device) for sensor in sensors: #If temperature is requested if "tp" == sensor: response ='%s #tp %s' %(response,driver.readTp()) #If AES key is requested if "key" == sensor: aeskey="" #Generate AES Key if cry.generateAES(driver.readTime()): aeskey=cry.key #Save AES key aesKeys[recipient]=aeskey #AES key is encrypted by the recipient public key rep=myCrypto(recipient) encKey=rep.encryptRSA(b64encode(aeskey)) response ='%s #key %s' %(response,encKey) #If photo is requested elif "photo" == sensor: cam=myCamDriver() cam.takePhoto() photo=cam.readPhotob64() response ='%s #photo %s' %(response,photo) #If time is requested elif "time" == sensor: response ='%s #time %s' %(response,driver.readTime()) #If gps is requested elif "gps" == sensor: #if AES key is available, gps data will be encrypted gpsData='%s' %(driver.readGPS()) if recipient in aesKeys: rep=myCrypto(recipient) rep.key=aesKeys[recipient] gpsData=rep.encrypt(gpsData) response ='%s #gps %s' %(response,gpsData) #If gpio is requested elif "gpio" in sensor: m=re.search(r'\d+$',sensor) pinnumber=int(m.group()) print pinnumber response ='%s #gpio%s %s' %(response,pinnumber,driver.readGPIO(port=pinnumber)) else: response ='%s #%s NULL' %(response,sensor) response="%s @%s" %(response,recipient) senze=cry.signSENZE(response) print senze self.transport.write(senze)
def handleDeviceResponse(self, senz): sender = senz.getSender() data = senz.getData() sensors = senz.getSensors() cmd = senz.getCmd() global buf, aesKeys if cmd == "DATA": for sensor in sensors: print sensor + "=>" + data[sensor] if sensor == 'photo': if data['photo'] == 'ON': buf = '' elif data['photo'] == 'OFF': cam = myCamDriver() cam.savePhoto(buf, "photo.jpg") #cam.showPhoto("photo.jpg") thread.start_new_thread(cam.showPhoto, ("photo.jpg", )) buf = '' else: buf = "%s%s" % (buf, data['photo']) #Received and saved the AES key elif sensor == 'key' and data['key'] != "": #Key need to be decrypted by using the private key cry = myCrypto(self.device) dec = cry.decryptRSA(data['key']) aesKeys[sender] = b64decode(dec) #Decrypt and show the gps data elif sensor == 'gps' and data['gps'] != "": gpsData = data['gps'] if sender in aesKeys: rep = myCrypto(sender) rep.key = aesKeys[sender] gpsData = rep.decrypt(gpsData) print "** GPS=>" + gpsData elif cmd == "SHARE": print "This should be implemented" elif cmd == "UNSHAR": print "This should be implemented" elif cmd == "GET": #If GET Senze was received. The device must handle it. reactor.callLater(1, self.sendDataSenze, sensors=sensors, data=data, recipient=sender) elif cmd == "PUT": reactor.callLater(1, self.handlePUTSenze, sensors=sensors, data=data, recipient=sender) else: print "Unknown command"
def datagramReceived(self, datagram, host): global device print 'Datagram received: ', repr(datagram) parser=myParser(datagram) recipients=parser.getUsers() sender=parser.getSender() signature=parser.getSignature() data=parser.getData() sensors=parser.getSensors() cmd=parser.getCmd() validQuery=False cry=myCrypto(device) if state=="READY": if serverPubkey !="" and sender=="mysensors": if cry.verifySENZE(parser,serverPubkey): self.handleServerResponse(parser) else: print "SENZE Verification failed" else: if sender!="": recipient=myCrypto(sender) if os.path.isfile(recipient.pubKeyLoc): pub=recipient.loadRSAPubKey() else: pub="" if pub!="" and cry.verifySENZE(parser,pub): print "SENZE Verified" self.handleDeviceResponse(parser) else: print "SENZE Verification failed" else: if cmd=="DATA": if 'msg' in sensors and 'UserCreated' in data['msg']: # Creating the .devicename file and store the device name # public key of mysensor server f=open(".devicename",'w') f.write(device+'\n') if 'pubkey' in sensors: pubkey=data['pubkey'] f.write(pubkey+'\n') f.close() print device+ " was created at the server." print "You should execute the program again." print "The system halted!" reactor.stop() elif 'msg' in sensors and 'UserCreationFailed' in data['msg']: print "This user name may be already taken" print "You can try it again with different username" print "The system halted!" reactor.stop()
def datagramReceived(self, datagram, host): global device print 'Datagram received: ', repr(datagram) parser = myParser(datagram) recipients = parser.getUsers() sender = parser.getSender() signature = parser.getSignature() data = parser.getData() sensors = parser.getSensors() cmd = parser.getCmd() validQuery = False cry = myCrypto(device) if state == "READY": if serverPubkey != "" and sender == "mysensors": if cry.verifySENZE(parser, serverPubkey): self.handleServerResponse(parser) else: print "SENZE Verification failed" else: if sender != "": recipient = myCrypto(sender) if os.path.isfile(recipient.pubKeyLoc): pub = recipient.loadRSAPubKey() else: pub = "" if pub != "" and cry.verifySENZE(parser, pub): print "SENZE Verified" self.handleDeviceResponse(parser) else: print "SENZE Verification failed" else: if cmd == "DATA": if 'msg' in sensors and 'UserCreated' in data['msg']: # Creating the .devicename file and store the device name # public key of mysensor server f = open(".devicename", 'w') f.write(device + '\n') if 'pubkey' in sensors: pubkey = data['pubkey'] f.write(pubkey + '\n') f.close() print device + " was created at the server." print "You should execute the program again." print "The system halted!" reactor.stop() elif 'msg' in sensors and 'UserCreationFailed' in data['msg']: print "This user name may be already taken" print "You can try it again with different username" print "The system halted!" reactor.stop()
def handleDeviceResponse(self,senze): global device global aesKeys sender=senze.getSender() data=senze.getData() sensors=senze.getSensors() cmd=senze.getCmd() if cmd=="DATA": for sensor in sensors: if sensor in data.keys(): print sensor+"=>"+data[sensor] if 'photo' in sensors: #try: cam=myCamDriver() cam.savePhoto(data['photo'],"p1.jpg") #cam.showPhoto("p1.jpg") #self.savePhoto(data['photo'],"p1.jpg") thread.start_new_thread(cam.showPhoto,("p1.jpg",)) #except: # print "Error: unable to show the photo" #cam.savePhoto(data['photo'],"p1.jpg") #Received and saved the AES key elif 'key' in sensors and data['key']!="": #Key need to be decrypted by using the private key cry=myCrypto(device) dec=cry.decryptRSA(data['key']) aesKeys[sender]=b64decode(dec) #Decrypt and show the gps data elif 'gps' in sensors and data['gps']!="": gpsData=data['gps'] if sender in aesKeys: rep=myCrypto(sender) rep.key=aesKeys[sender] gpsData=rep.decrypt(gpsData) print "GPS=>"+gpsData elif cmd=="SHARE": print "This should be implemented" elif cmd=="UNSHAR": print "This should be implemented" elif cmd=="GET": #If GET Senze was received. The device must handle it. reactor.callLater(1,self.sendDataSenze,sensors=sensors,data=data,recipient=sender) elif cmd=="PUT": reactor.callLater(1,self.handlePUTSenze,sensors=sensors,data=data,recipient=sender) else: print "Unknown command"
def handlePUTSenze(self, sensors, data, recipient): response = 'DATA' driver = myDriver() cry = myCrypto(self.device) for sensor in sensors: #If GPIO operation is requested if "gpio" in sensor: pinnumber = 0 #search for gpio pin number m = re.search(r'\d+$', sensor) if m: pinnumber = int(m.group()) if pinnumber > 0 and pinnumber <= 16: if data[sensor] == "ON": ans = driver.handleON(port=pinnumber) else: ans = driver.handleOFF(port=pinnumber) response = '%s #gpio%s %s' % (response, pinnumber, ans) else: response = '%s #gpio%d UnKnown' % (response, pinnumber) elif "time" in sensors: print "Received time :", data["time"] else: response = '%s #%s UnKnown' % (response, sensor) print "******", response response = "%s @%s" % (response, recipient) self.sendDatagram(response)
def init(): # If servername is not there we will read the server name from keyboard # else we will get it from config.cfg file global serverName global serverPubkey print "serverName",serverName try: if serverName == "": serverName = raw_input("Enter the server name:") except: logger.error("Cannot access server name") raise SystemExit # Here we will generate public and private keys for the server # These keys will be used to authentication # If keys are not available yet it will be generated global serverPubkey try: cry = myCrypto(serverName) if not os.path.isfile(cry.pubKeyLoc) and not os.path.isfile(cry.privKeyLoc): # Private key and public key was saved in the id_rsa and id_rsa.pub files cry.generateRSA(1024) serverPubkey = cry.loadRSAPubKey() except: logger.error("Cannot genereate private/public keys for the server.") raise SystemExit
def handle_GET(self,recipients,sensors,reply): global connections failed_recipients=[] """ print "R->",recipients print "Reply->",reply print "S->",sensors """ #If GET addresses to the mysensors if self.server in recipients: if 'pubkey' in sensors: cry=myCrypto(self.server) publicKey=cry.loadRSAPubKey() st='@%s DATA #pubkey %s' %(self.server,publicKey) self.sendMessage(st,False) #Otherwise GET message will forward to the recipients else: for recipient in recipients: if self.isConnected(recipient): rep=myUser(self.usrDB,recipient) if rep.isShare(self.user,sensors): connections[recipient].sendMessage("@"+self.user+reply,False) else: failed_recipients.append(recipient) else:failed_recipients.append(recipient) st='@%s DATA #msg ' %(self.server) if len(failed_recipients)==0: self.sendMessage(st+"GETSendDone",False) else: self.sendMessage(st+"GETSendFailed:"+str(failed_recipients),False)
def handleDeviceResponse(self, senze): global device global aesKeys sender = senze.getSender() data = senze.getData() sensors = senze.getSensors() cmd = senze.getCmd() if cmd == "DATA": for sensor in sensors: if sensor in data.keys(): print sensor + "=>" + data[sensor] #Received and saved the AES key if 'key' in sensors and data['key'] != "": #Key need to be decrypted by using the private key cry = myCrypto(device) dec = cry.decryptRSA(data['key']) aesKeys[sender] = b64decode(dec) #Decrypt and show the gps data elif cmd == "SHARE": print "This should be implemented" elif cmd == "UNSHAR": print "This should be implemented" elif cmd == "GET": #If GET Senze was received. The device must handle it. reactor.callLater(1,self.sendDataSenze, sensors=sensors, data=data, recipient=sender) elif cmd == "PUT": reactor.callLater(1, self.handlePUTSenze, sensors=sensors, data=data, recipient=sender) else: print "Unknown command"
def handlePUTSenze(self,sensors,data,recipient): global device response='DATA' driver=myDriver() cry=myCrypto(device) for sensor in sensors: #If GPIO operation is requested if "gpio" in sensor: pinnumber=0 #search for gpio pin number m=re.search(r'\d+$',sensor) if m : pinnumber=int(m.group()) if pinnumber>0 and pinnumber<=16: if data[sensor]=="ON": ans=driver.handleON(port=pinnumber) else: ans=driver.handleOFF(port=pinnumber) #response='%s #gpio%s %s' %(response,pinnumber,ans) response='%s #msg %s' %(response,ans) else: response='%s #gpio%d UnKnown' %(response,pinnumber) elif sensor!="time": response='%s #%s UnKnown' %(response,sensor) response="%s @%s" %(response,recipient) senze=cry.signSENZE(response) self.transport.write(senze)
def init(): #cam=myCamDriver() global device global pubkey global state #If .device name is not there, we will read the device name from keyboard #else we will get it from .devicename file try: if not os.path.isfile(".devicename"): device=raw_input("Enter the device name: ") # Account need to be created at the server state='INITIAL' else: #The device name will be read form the .devicename file f=open(".devicename","r") device = f.readline().rstrip("\n") state='READY' except: print "ERRER: Cannot access the device name file." raise SystemExit #Here we will generate public and private keys for the device #These keys will be used to perform authentication and key exchange try: cry=myCrypto(name=device) #If keys are not available yet if not os.path.isfile(cry.pubKeyLoc): # Generate or loads an RSA keypair with an exponent of 65537 in PEM format # Private key and public key was saved in the .devicenamePriveKey and .devicenamePubKey files cry.generateRSA(bits=1024) pubkey=cry.loadRSAPubKey() except: print "ERRER: Cannot genereate private/public keys for the device." raise SystemExit print pubkey
def init(): # If .servername is not there we will read the server name from keyboard # else we will get it from .servername file try: if not os.path.isfile(".servername"): serverName = raw_input("Enter the server name:") f = open(".servername", 'w') f.write(serverName + '\n') f.close() else: #The server name will be read form the .servername file f = open(".servername", "r") serverName = f.readline().rstrip("\n") except: logger.error("Cannot access server name file") raise SystemExit # Here we will generate public and private keys for the server # These keys will be used to authentication # If keys are not available yet global serverPubkey try: cry = myCrypto(serverName) if not os.path.isfile(cry.pubKeyLoc): # Private key and public key was saved in the # .servernamePriveKey and .servernamePubKey files cry.generateRSA(1024) serverPubkey = cry.loadRSAPubKey() except: logger.error("Cannot genereate private/public keys for the server.") raise SystemExit
def GETSenze(self, query): global connections global database global serverName sender = query.getSender() sensors = query.getSensors() usr = myUser(database, serverName) recipients = query.getUsers() for recipient in recipients: recipientDB = myUser(database, recipient) if 'pubkey' in sensors: #Since mysensors already has public key of it clients, #it responses on behalf of the client. pubkey = recipientDB.loadPublicKey() if pubkey != '': if sender in connections.keys(): backward = connections[sender] senze = 'DATA #name %s #pubkey %s' % (recipient, pubkey) cry = myCrypto(serverName) senze = cry.signSENZE(senze) self.transport.write(senze, backward) #Otherwise GET message will forward to the recipients else: if recipient in connections.keys(): forward = connections[recipient] if forward != 0 and \ recipientDB.isShare(sender, query.getSensors()): self.transport.write(query.getFULLSENZE(), forward) else: logger.error('Senz not shared with recipient: %s' % recipient) else: logger.error('No recipient found: %s' % recipient)
def handlePUTSenze(self, sensors, data, recipient): global device response = 'DATA' driver = myDriver() cry = myCrypto(device) for sensor in sensors: #If GPIO operation is requested if "gpio" in sensor: pinnumber = 0 #search for gpio pin number m = re.search(r'\d+$', sensor) if m: pinnumber = int(m.group()) if pinnumber > 0 and pinnumber <= 16: if data[sensor] == "ON": ans = driver.handleON(port=pinnumber) else: ans = driver.handleOFF(port=pinnumber) #response='%s #gpio%s %s' %(response,pinnumber,ans) response = '%s #msg %s' % (response, ans) else: response = '%s #gpio%d UnKnown' % (response, pinnumber) elif sensor != "time": response = '%s #%s UnKnown' % (response, sensor) response = "%s @%s" % (response, recipient) senze = cry.signSENZE(response) self.transport.write(senze)
def createUser(self, query, address): global database global serverName global serverPubkey usr = myUser(database, serverName) cry = myCrypto(serverName) data = query.getData() pubkey = '' phone = '' reg_status = '' if 'pubkey' in data: pubkey = data['pubkey'] if 'phone' in data: phone = data['phone'] if cry.verifySENZE(query, pubkey): reg_status = usr.addUser(query.getSender(), phone, query.getSENZE(), pubkey, query.getSignature()) logger.info('Registration status: %s' % reg_status) if reg_status == 'REGISTERED': st = 'DATA #msg ALREADY_REGISTERED #pubkey %s ' % (serverPubkey) elif reg_status == 'DONE': st = 'DATA #msg REGISTRATION_DONE #pubkey %s ' % (serverPubkey) else: st = 'DATA #msg REGISTRATION_FAIL' senze = cry.signSENZE(st) self.transport.write(senze, address)
def init(): # If servername is not there we will read the server name from keyboard # else we will get it from config.cfg file global serverName global serverPubkey print "serverName", serverName try: if serverName == "": serverName = raw_input("Enter the server name:") except: logger.error("Cannot access server name") raise SystemExit # Here we will generate public and private keys for the server # These keys will be used to authentication # If keys are not available yet it will be generated global serverPubkey try: cry = myCrypto(serverName) if not os.path.isfile(cry.pubKeyLoc) and not os.path.isfile( cry.privKeyLoc): # Private key and public key was saved in the id_rsa and id_rsa.pub files cry.generateRSA(1024) serverPubkey = cry.loadRSAPubKey() except: logger.error("Cannot genereate private/public keys for the server.") raise SystemExit
def sendDataSenze(self,sensors,data,recipient): global device response='DATA' driver=myDriver() for sensor in sensors: #If temperature is requested if "tp" == sensor: response ='%s #tp %s' %(response,driver.readTp()) #If photo is requested elif "photo" == sensor: cam=myCamDriver() cam.takePhoto() photo=cam.readPhotob64() print photo response ='%s #photo %s' %(response,photo) #If time is requested elif "time" == sensor: response ='%s #time %s' %(response,driver.readTime()) #If gps is requested elif "gps" == sensor: response ='%s #gps %s' %(response,driver.readGPS()) #If gpio is requested elif "gpio" in sensor: m=re.search(r'\d+$',sensor) pinnumber=int(m.group()) print pinnumber response ='%s #gpio%s %s' %(response,pinnumber,driver.readGPIO(port=pinnumber)) else: response ='%s #%s NULL' %(response,sensor) cry=myCrypto(device) response="%s @%s" %(response,recipient) senze=cry.signSENZE(response) print senze self.transport.write(senze)
def init(): #cam=myCamDriver() global device global pubkey global state #If .device name is not there, we will read the device name from keyboard #else we will get it from .devicename file try: if not os.path.isfile(".devicename"): device = raw_input("Enter the device name: ") # Account need to be created at the server state = 'INITIAL' else: #The device name will be read form the .devicename file f = open(".devicename", "r") device = f.readline().rstrip("\n") state = 'READY' except: print "ERRER: Cannot access the device name file." raise SystemExit #Here we will generate public and private keys for the device #These keys will be used to perform authentication and key exchange try: cry = myCrypto(name=device) #If keys are not available yet if not os.path.isfile(cry.pubKeyLoc): # Generate or loads an RSA keypair with an exponent of 65537 in PEM format # Private key and public key was saved in the .devicenamePriveKey and .devicenamePubKey files cry.generateRSA(bits=1024) pubkey = cry.loadRSAPubKey() except: print "ERRER: Cannot genereate private/public keys for the device." raise SystemExit print pubkey
def datagramReceived(self, datagram, address): global serverName global usrDatabase logger.info('senz received: %s' % datagram) query = myParser(datagram) recipients = query.getUsers() sender = query.getSender() signature = query.getSignature() data = query.getData() sensors = query.getSensors() cmd = query.getCmd() validQuery = False cry = myCrypto(serverName) senderDB = myUser(database, sender) pubkey = senderDB.loadPublicKey() if cmd == "SHARE" and "pubkey" in sensors and serverName in recipients: #Create a new account self.createUser(query, address) validQuery = True elif cmd == "UNSHARE" and "pubkey" in sensors and\ serverName in recipients: #Remove the account status = False if pubkey != "": if cry.verifySENZE(query, pubkey): status = self.removeUser(sender, pubkey, address) validQuery = True else: if pubkey != "": if cry.verifySENZE(query, pubkey): validQuery = True if validQuery: connections[sender] = address connectionsTime[sender] = time.time() if cmd == "SHARE": self.shareSensors(query) elif cmd == "UNSHARE": self.unshareSensors(query) elif cmd == "GET": self.GETSenze(query) elif cmd == "PUT": self.PUTSenze(query) elif cmd == "DATA": self.DATASenze(query) else: senze = "DATA #msg SignatureVerificationFailed" senze = cry.signSENZE(senze) self.transport.write(senze, address)
def datagramReceived(self, datagram, host): global device global server print 'Datagram received: ', repr(datagram) senz = SenZ(datagram) handler = myHandler(self.transport, device, senz) cry = myCrypto(device) if self.state == "INITIAL": if senz.sender == server: self.state = handler.registrationDone() if self.state == "READY": if not bootSenz: reactor.callLater(1, self.readSenze) else: for s in bootSenz: reactor.callLater(3, self.sendDatagram, bootSenz[s]) elif self.state == "READY": if serverPubKey != "" and senz.sender == server: if cry.verifySENZE(senz, serverPubKey): handler.handleServerResponse(senz) else: print("SENZE Verification failed") else: if senz.sender != "": recipient = myCrypto(senz.sender) if os.path.isfile(recipient.pubKeyLoc): pub = recipient.loadRSAPubKey() else: pub = "" if pub != "" and cry.verifySENZE(senz, pub): print("SENZE Verified") handler.handleDeviceResponse(senz) else: print("SENZE Verification failed") else: print("Unknown Sate")
def removeUser(self, sender, pubkey, address): global database global serverName usr = myUser(database, serverName) cry = myCrypto(serverName) status = usr.delUser(sender, pubkey) st = "DATA #msg " if status: st += 'UserRemoved' else: st += 'UserCannotRemoved' senze = cry.signSENZE(st) self.transport.write(senze, address)
def handle_PUT_MySensors(self, cmd, recipients, sensors, data, reply): status = False usr = myUser(self.usrDB, self.user) cry = myCrypto(self.server) type = 'skey' n = '' k = '' p = '' pub = '' sig = '' e = '' if 'name' in data: n = data['name'] if 'skey' in data: k = data['skey'] if 'hkey' in data: k = data['hkey'] type = 'hkey' # If PIN is encrypted, it should be decrypted. if 'enckey' in data: k = cry.decryptRSA(data['enckey']) #print k if 'pubkey' in data and 'signature' in data: pub = data['pubkey'] sig = data['signature'] type = 'pubkey' if 'phone' in data: p = data['phone'] if 'email' in data: e = data['email'] st = '@%s DATA #name %s #msg ' % (self.server, n) if cmd == 'PUT': if type == 'pubkey': if cry.verifySign(pub, sig, n): status = usr.putUser(n, p, e, pub, type) else: status = False else: status = usr.putUser(n, p, e, k, type) if status: st += 'UserCreated' else: st += 'UserCreationFailed' else: status = usr.delUser(n, p, k, pub) if status: st += 'UserDeleted' else: st += 'UserDeletionFailed' self.sendMessage(st, False)
def datagramReceived(self, datagram, address): global serverName global database logger.info('senz received: %s' % datagram) print datagram senz = SenZ(datagram) validQuery = False cry = myCrypto(serverName) senderDB = myUser(database, senz.sender) pubkey = senderDB.loadPublicKey() if senz.command == "SHARE" and "pubkey" in senz.sensors and serverName in senz.recipients: #Create a new account self.createUser(senz, address) validQuery = True elif senz.command == "UNSHARE" and "pubkey" in senz.sensors and\ serverName in senz.recipients: #Remove the account if pubkey != "": if cry.verifySENZE(senz, pubkey): status = self.removeUser(senz.sender, pubkey, address) validQuery = True else: if pubkey != "": if cry.verifySENZE(senz, pubkey): validQuery = True if validQuery: connections[senz.sender] = address connectionsTime[senz.sender] = time.time() if senz.command == "SHARE": self.shareSensors(senz) elif senz.command == "UNSHARE": self.unshareSensors(senz) elif senz.command == "GET": self.GETSenze(senz) elif senz.command == "PUT": self.PUTSenze(senz) elif senz.command == "DATA": self.DATASenze(senz) else: senze = "DATA #msg SignatureVerificationFailed" senze = cry.signSENZE(senze) self.transport.write(senze, address)
def datagramReceived(self, datagram, address): global serverName global database logger.info('senz received: %s' % datagram) print datagram senz = SenZ(datagram) validQuery = False cry = myCrypto(serverName) senderDB = myUser(database,senz.sender) pubkey = senderDB.loadPublicKey() if senz.command == "SHARE" and "pubkey" in senz.sensors and serverName in senz.recipients: #Create a new account self.createUser(senz,address) validQuery = True elif senz.command == "UNSHARE" and "pubkey" in senz.sensors and\ serverName in senz.recipients: #Remove the account if pubkey != "": if cry.verifySENZE(senz,pubkey): status = self.removeUser(senz.sender, pubkey, address) validQuery = True else: if pubkey != "": if cry.verifySENZE(senz, pubkey): validQuery = True if validQuery: connections[senz.sender] = address connectionsTime[senz.sender] = time.time() if senz.command == "SHARE": self.shareSensors(senz) elif senz.command == "UNSHARE": self.unshareSensors(senz) elif senz.command == "GET": self.GETSenze(senz) elif senz.command == "PUT": self.PUTSenze(senz) elif senz.command == "DATA": self.DATASenze(senz) else: senze = "DATA #msg SignatureVerificationFailed" senze = cry.signSENZE(senze) self.transport.write(senze, address)
def handleServerResponse(self,senze): sender=senze.getSender() data=senze.getData() sensors=senze.getSensors() cmd=senze.getCmd() if cmd=="DATA": if 'msg' in sensors and 'UserRemoved' in data['msg']: cry=myCrypto(device) try: os.remove(".devicename") os.remove(cry.pubKeyLoc) os.remove(cry.privKeyLoc) print "Device was successfully removed" except OSError: print "Cannot remove user configuration files" reactor.stop() elif 'pubkey' in sensors and data['pubkey']!="" and 'name' in sensors and data['name']!="": recipient=myCrypto(data['name']) if recipient.saveRSAPubKey(data['pubkey']): print "Public key=> "+data['pubkey']+" Saved." else: print "Error: Saving the public key."
def handle_PUT_MySensors(self,cmd,recipients,sensors,data,reply): status=False usr=myUser(self.usrDB,self.user) cry=myCrypto(self.server) type='skey' n=''; k=''; p='';pub='';sig='';e='' if 'name' in data: n= data['name'] if 'skey' in data: k= data['skey'] if 'hkey' in data: k= data['hkey'] type='hkey' # If PIN is encrypted, it should be decrypted. if 'enckey' in data: k= cry.decryptRSA(data['enckey']) #print k if 'pubkey' in data and 'signature' in data: pub=data['pubkey'] sig=data['signature'] type='pubkey' if 'phone' in data: p= data['phone'] if 'email' in data: e= data['email'] st='@%s DATA #name %s #msg ' %(self.server,n) if cmd=='PUT': if type=='pubkey': if cry.verifySign(pub,sig,n): status=usr.putUser(n,p,e,pub,type) else: status=False else: status=usr.putUser(n,p,e,k,type) if status: st+='UserCreated' else: st+='UserCreationFailed' else: status=usr.delUser(n,p,k,pub) if status: st+='UserDeleted' else: st+='UserDeletionFailed' self.sendMessage(st,False)
def createUser(self, query, address): global database global serverName global serverPubkey usr = myUser(database, serverName) cry = myCrypto(serverName) data = query.getData() pubkey = '' phone = '' if 'pubkey' in data: pubkey = data['pubkey'] if 'phone' in data: phone = data['phone'] if cry.verifySENZE(query, pubkey): status = usr.addUser(query.getSender(), phone, query.getSENZE(), pubkey, query.getSignature()) if status: st = 'DATA #msg UserCreated #pubkey %s ' % (serverPubkey) else: st = 'DATA #msg UserCreationFailed' senze = cry.signSENZE(st) self.transport.write(senze, address)
def onOpen(self): ''' Call when opening a websocket. Initializing the all globle parameters here ''' global serverName self.server=serverName global pubkey self.publicKey=pubkey global usrDatabase self.usrDB=usrDatabase print "Total no of connections:"+str(factory.getConnectionCount()) self.myState="INITIAL" #The server sends its public key and #signature of websocket key. So the clients can verify the server authenticity. cry=myCrypto(serverName) sig=cry.signData(self.key) msg="@"+self.server+" DATA #pubkey "+self.publicKey msg+=" #websocketkey "+self.key+" #signature "+sig self.sendMessage(msg,False)
def onOpen(self): ''' Call when opening a websocket. Initializing the all globle parameters here ''' global serverName self.server = serverName global pubkey self.publicKey = pubkey global usrDatabase self.usrDB = usrDatabase print "Total no of connections:" + str(factory.getConnectionCount()) self.myState = "INITIAL" #The server sends its public key and #signature of websocket key. So the clients can verify the server authenticity. cry = myCrypto(serverName) sig = cry.signData(self.key) msg = "@" + self.server + " DATA #pubkey " + self.publicKey msg += " #websocketkey " + self.key + " #signature " + sig self.sendMessage(msg, False)
def sendDataSenze(self, sensors, data, recipient): global device response = 'DATA' driver = myDriver() for sensor in sensors: #If temperature is requested if "tp" == sensor: response = '%s #tp %s' % (response, driver.readTp()) #If photo is requested elif "photo" == sensor: cam = myCamDriver() cam.takePhoto() photo = cam.readPhotob64() print photo response = '%s #photo %s' % (response, photo) #If time is requested elif "time" == sensor: response = '%s #time %s' % (response, driver.readTime()) #If gps is requested elif "gps" == sensor: response = '%s #gps %s' % (response, driver.readGPS()) #If gpio is requested elif "gpio" in sensor: m = re.search(r'\d+$', sensor) pinnumber = int(m.group()) print pinnumber response = '%s #gpio%s %s' % (response, pinnumber, driver.readGPIO(port=pinnumber)) else: response = '%s #%s NULL' % (response, sensor) cry = myCrypto(device) response = "%s @%s" % (response, recipient) senze = cry.signSENZE(response) print senze self.transport.write(senze)
def handle_GET(self, recipients, sensors, reply): global connections failed_recipients = [] """ print "R->",recipients print "Reply->",reply print "S->",sensors """ #If GET addresses to the mysensors if self.server in recipients: if 'pubkey' in sensors: cry = myCrypto(self.server) publicKey = cry.loadRSAPubKey() st = '@%s DATA #pubkey %s' % (self.server, publicKey) self.sendMessage(st, False) #Otherwise GET message will forward to the recipients else: for recipient in recipients: if self.isConnected(recipient): rep = myUser(self.usrDB, recipient) if rep.isShare(self.user, sensors): connections[recipient].sendMessage( "@" + self.user + reply, False) else: failed_recipients.append(recipient) else: failed_recipients.append(recipient) st = '@%s DATA #msg ' % (self.server) if len(failed_recipients) == 0: self.sendMessage(st + "GETSendDone", False) else: self.sendMessage( st + "GETSendFailed:" + str(failed_recipients), False)
def login(self,key,sig,server): #doc=db.find_one({"name":self.name,"skey":key}) if(self.usrDoc): #PIN is compared with hash of the key if 'skey' in self.usrDoc: s = hashlib.sha1() s.update(key) key=b64encode(s.digest()) if self.usrDoc['skey']==key: return True #Hash key is sent elif 'hkey' in self.usrDoc: hkey=self.usrDoc['hkey'] s = hashlib.sha1() s.update(hkey+sig) tkey=b64encode(s.digest()) if tkey==key: return True #Signature will be verified with the public key elif 'publickey' in self.usrDoc: cry=myCrypto(server) if cry.verifySign(self.usrDoc['publickey'],sig,key): return True return False
def registrationDone(self): cry = myCrypto(name=self.device) state = "INITIAL" if 'msg' in self.senz.sensors and 'pubkey' in self.senz.sensors: if cry.verifySENZE(self.senz, self.senz.data['pubkey']): if 'REG_DONE' in self.senz.data['msg']: self.saveRootKey(self.senz.data['pubkey']) state = 'READY' print(self.device + " was created at the server.") print( "You should execute the program again with READY state." ) elif 'REG_ALR' in self.senz.data['msg']: print(self.device + " was already created at the server.") state = "READY" else: print("This user name is already taken") print("You can try it again with different username") print("The system halted!") else: print("SENZE Verification failed") else: print("Unknown server response") return state
def login(self, key, sig, server): #doc=db.find_one({"name":self.name,"skey":key}) if (self.usrDoc): #PIN is compared with hash of the key if 'skey' in self.usrDoc: s = hashlib.sha1() s.update(key) key = b64encode(s.digest()) if self.usrDoc['skey'] == key: return True #Hash key is sent elif 'hkey' in self.usrDoc: hkey = self.usrDoc['hkey'] s = hashlib.sha1() s.update(hkey + sig) tkey = b64encode(s.digest()) if tkey == key: return True #Signature will be verified with the public key elif 'publickey' in self.usrDoc: cry = myCrypto(server) if cry.verifySign(self.usrDoc['publickey'], sig, key): return True return False
def handleDeviceResponse(self, senze): global device global aesKeys sender = senze.getSender() data = senze.getData() sensors = senze.getSensors() cmd = senze.getCmd() if cmd == "DATA": for sensor in sensors: if sensor in data.keys(): print sensor + "=>" + data[sensor] #Received and saved the AES key if 'key' in sensors and data['key'] != "": #Key need to be decrypted by using the private key cry = myCrypto(device) dec = cry.decryptRSA(data['key']) #line aesKeys[sender] = b64decode(dec) #Decrypt and show the gps data elif cmd == "SHARE": print "This should be implemented" elif cmd == "UNSHAR": print "This should be implemented" elif cmd == "GET": #If GET Senze was received. The device must handle it. reactor.callLater(1,self.sendDataSenze, sensors=sensors, data=data, recipient=sender) elif cmd == "PUT": reactor.callLater(1, self.handlePUTSenze, sensors=sensors, data=data, recipient=sender) else: print "Unknown command"
def register(self): global server cry = myCrypto(name=device) senze = 'SHARE #pubkey %s @%s' % (pubkey, server) senze = cry.signSENZE(senze) self.transport.write(senze)
f=open(".servername",'w') f.write(serverName+'\n') f.close() else: #The server name will be read form the .servername file f=open(".servername","r") serverName = f.readline().rstrip("\n") except: print "ERRER: Cannot access the server name file." raise SystemExit #Here we will generate public and private keys for the server #These keys will be used to authentication #If keys are not available yet try: cry=myCrypto(serverName) if not os.path.isfile(cry.pubKeyLoc): # Generate or loads an RSA keypair with an exponent of 65537 in PEM format # Private key and public key was saved in the .servernamePriveKey and .servernamePubKey files cry.generateRSA(1024) pubkey=cry.loadRSAPubKey() except: print "ERRER: Cannot genereate private/public keys for the server." raise SystemExit print pubkey #Create connection to the Mongo DB try: client = MongoClient('localhost', 27017) #Creating the database for the server db = client[serverName]
def handle_LOGIN(self,data): print data global connections global deletedConnections """ This method handles login process of each user. At present user connection socket id is stored in 'connections'. Finally we create a DATA Senze and send it to corresponding user, DATA Senze contains Login success/fail status. We authenticate users by using a PIN number or a digital signature. """ name=''; pin='';sig='' if 'name' in data: name= data['name'] if 'skey' in data: pin= data['skey'] if 'hkey' in data: pin= data['hkey'] # If PIN is encrypted, it should be decrypted. if 'enckey' in data: cry=myCrypto(self.server) pin= cry.decryptRSA(data['enckey']) #print pin # If hkey is given, #sec-websocket-key is taken as the session key. elif 'hkey' in data: #sec-websocket-key is used as the session key sig=self.key pin=data['hkey'] #print pin # Signature is available, the user authentication is based on digital signature. elif 'signature' in data: sig=data['signature'] #sec-websocket-key is used as the pin pin=self.key usr=myUser(self.usrDB,name) replyMsg="@"+self.server+" DATA #name "+name #Verify the user by using a PIN or signature if usr.login(pin,sig,self.server): # We need to check user alredy have a connection if self.isConnected(name): #Let's close it deletedConnections[name]=connections[name] connections[name].sendClose() # Set the connected name self.user=name # Adding websocket connection to connection pool connections[self.user]=self self.myState="READY" replyMsg+=" #msg LoginSUCCESS" self.sendMessage(replyMsg,False) #In order to keep the live connection, the server will send a ping after 5m #After that the server will send a ping every 10m (See onPong message) self.factory.reactor.callLater(self.pingingIntervel,self.sendPingMessage) self.factory.reactor.callLater(self.pingingIntervel*2,self.sendPingMessage) #If login failed, let's inform it if self.myState=="INITIAL": replyMsg+=" #msg LoginFAILED" self.sendMessage(replyMsg,False)
f = open(".servername", 'w') f.write(serverName + '\n') f.close() else: #The server name will be read form the .servername file f = open(".servername", "r") serverName = f.readline().rstrip("\n") except: print "ERRER: Cannot access the server name file." raise SystemExit #Here we will generate public and private keys for the server #These keys will be used to authentication #If keys are not available yet try: cry = myCrypto(serverName) if not os.path.isfile(cry.pubKeyLoc): # Generate or loads an RSA keypair with an exponent of 65537 in PEM format # Private key and public key was saved in the .servernamePriveKey and .servernamePubKey files cry.generateRSA(1024) pubkey = cry.loadRSAPubKey() except: print "ERRER: Cannot genereate private/public keys for the server." raise SystemExit print pubkey #Create connection to the Mongo DB try: client = MongoClient('localhost', 27017) #Creating the database for the server db = client[serverName]
def sendDatagram(self,senze): cry=myCrypto(name=device) senze=cry.signSENZE(senze) print senze self.transport.write(senze)
def register(self): global server cry=myCrypto(name=device) senze ='SHARE #pubkey %s @%s' %(pubkey,server) senze=cry.signSENZE(senze) self.transport.write(senze)
def sendDatagram(self, senze): global device cry = myCrypto(name=device) senze = cry.signSENZE(senze) print(senze) self.transport.write(senze)
def handle_LOGIN(self, data): print data global connections global deletedConnections """ This method handles login process of each user. At present user connection socket id is stored in 'connections'. Finally we create a DATA Senze and send it to corresponding user, DATA Senze contains Login success/fail status. We authenticate users by using a PIN number or a digital signature. """ name = '' pin = '' sig = '' if 'name' in data: name = data['name'] if 'skey' in data: pin = data['skey'] if 'hkey' in data: pin = data['hkey'] # If PIN is encrypted, it should be decrypted. if 'enckey' in data: cry = myCrypto(self.server) pin = cry.decryptRSA(data['enckey']) #print pin # If hkey is given, #sec-websocket-key is taken as the session key. elif 'hkey' in data: #sec-websocket-key is used as the session key sig = self.key pin = data['hkey'] #print pin # Signature is available, the user authentication is based on digital signature. elif 'signature' in data: sig = data['signature'] #sec-websocket-key is used as the pin pin = self.key usr = myUser(self.usrDB, name) replyMsg = "@" + self.server + " DATA #name " + name #Verify the user by using a PIN or signature if usr.login(pin, sig, self.server): # We need to check user alredy have a connection if self.isConnected(name): #Let's close it deletedConnections[name] = connections[name] connections[name].sendClose() # Set the connected name self.user = name # Adding websocket connection to connection pool connections[self.user] = self self.myState = "READY" replyMsg += " #msg LoginSUCCESS" self.sendMessage(replyMsg, False) #In order to keep the live connection, the server will send a ping after 5m #After that the server will send a ping every 10m (See onPong message) self.factory.reactor.callLater(self.pingingIntervel, self.sendPingMessage) self.factory.reactor.callLater(self.pingingIntervel * 2, self.sendPingMessage) #If login failed, let's inform it if self.myState == "INITIAL": replyMsg += " #msg LoginFAILED" self.sendMessage(replyMsg, False)