Esempio n. 1
0
    def getPrivateData(self):
        url_get = "http://cs302.kiwi.land/api/get_privatedata"
        headers = self.createAuthorisedHeader(True)
        try:
            JSON_object = helper.postJson(None, headers, url_get)
            response = JSON_object.get("response", None)
        except Exception as e:
            print(e)
            return {}
        else:
            private_data = {}
            if response == "ok":
                private_data_encr = JSON_object.get("privatedata", None)
                if not private_data_encr:
                    return {}
                private_data_bytes = base64.b64decode(private_data_encr)

                try:
                    key = helper.getSymmetricKeyFromPassword(self.password2)
                    private_data_str = helper.decryptStringKey(
                        key, private_data_bytes)
                except nacl.exceptions.CryptoError as e:
                    print(e)
                    return 1
                except Exception as e:
                    print(e)
                    return 1
                else:
                    private_data = json.loads(private_data_str)
        return private_data
Esempio n. 2
0
    def pingCheckUsers(self):
        headers = self.createAuthorisedHeader(False)
        ts = str(time.time())

        all_users = database.getAllUsers()

        payload = {
            "my_time": ts,
            "connection_address": self.logserv.connection_address,
            "connection_location": self.logserv.connection_location
        }

        for user in all_users:
            username = user.get("username", None)
            user_address = user.get("address", None)
            user_status = user.get("status", None)
            if user_address is None or user_status != "online":
                continue
            url = "http://" + user_address + "/api/ping_check"
            try:
                JSON_object = helper.postJson(payload, headers, url)
                response = JSON_object.get("response", None)
                if response == "ok":
                    print("ping check successful")
                else:
                    print("ping check not ok")
                    database.makeUserOffline(username)
            except:
                print("cannot ping this user!!!!")
                database.makeUserOffline(username)
Esempio n. 3
0
    def reportUser(self, status=None):

        print("reporting user" + str(self.username))
        headers = self.createAuthorisedHeader(True)
        url = "http://cs302.kiwi.land/api/report"
        pubkey = self.signing_key.verify_key
        pubkey_hex = pubkey.encode(encoder=nacl.encoding.HexEncoder)
        pubkey_hex_str = pubkey_hex.decode('utf-8')
        connection_address = self.connection_address
        connection_location = self.connection_location

        if not status:
            status = self.status

        payload = {
            "connection_address": connection_address,
            "connection_location": connection_location,
            "incoming_pubkey": pubkey_hex_str,
            "status": status
        }
        try:
            JSON_object = helper.postJson(payload, headers, url)

            response = JSON_object.get("response", None)
            if response == "ok":
                return 0
            else:
                raise Exception("response not ok")
        except Exception as e:
            print(e)
            return 1
Esempio n. 4
0
    def testPublicKey(self):
        url = "http://cs302.kiwi.land/api/ping"

        if self.signing_key is None:
            return 1

        pubkey = self.signing_key.verify_key
        pubkey_hex = pubkey.encode(encoder=nacl.encoding.HexEncoder)
        pubkey_hex_str = pubkey_hex.decode('utf-8')

        #creating message and then signed
        message_bytes = bytes(pubkey_hex_str, encoding='utf-8')
        signed = self.signing_key.sign(message_bytes,
                                       encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')

        headers = self.createAuthorisedHeader(True)
        payload = {"pubkey": pubkey_hex_str, "signature": signature_hex_str}

        JSON_object = helper.postJson(payload, headers, url)

        response = JSON_object.get("response", None)
        signature = JSON_object.get("signature", None)
        if response == "ok" and signature == "ok":
            print("public key and signature is valid.")
            return 0
        else:
            print(JSON_object)
            print(response)
            print(signature)
            print(pubkey_hex_str)
            print("public key and or signature is invalid.")
            return 1
Esempio n. 5
0
    def checkPublicKey(self, pubkey_str):
        headers = self.createAuthorisedHeader(True)
        url = "http://cs302.kiwi.land/api/list_users"
        req = "?pubkey=" + pubkey_str
        JSON_object = helper.postJson(None, headers, url + req)

        response = JSON_object.get("response", None)
        if response == 'ok':
            self.users = JSON_object.get("users", None)
            return 0
        else:
            return 1
Esempio n. 6
0
 def getLoginServerRecord(self):
     url = "http://cs302.kiwi.land/api/get_loginserver_record"
     headers = self.createAuthorisedHeader(True)
     JSON_object = helper.postJson(None, headers, url)
     response = JSON_object.get("response", None)
     if response == "ok":
         self.login_server_record = JSON_object.get("loginserver_record",
                                                    None)
         database.addLoginServerRecord(self.username,
                                       self.login_server_record)
         return 0
     else:
         return 1
Esempio n. 7
0
    def getUsers(self):
        headers = self.createAuthorisedHeader(True)
        url = "http://cs302.kiwi.land/api/list_users"
        JSON_object = helper.postJson(None, headers, url)

        response = JSON_object.get("response", None)
        if response == 'ok':
            self.users = JSON_object.get("users", None)
            if self.users is not None:
                self.loadUsersIntoDatabase(self.users)
            return 0
        else:
            return 1
Esempio n. 8
0
    def sendBroadcastMessage(self, message):
        headers = self.createAuthorisedHeader(False)
  
        ud = database.getUserHashes(self.username)
        loginserver_record = ud.get("loginrecord")
        ts = str(time.time())
        message_bytes = bytes(loginserver_record+message+ts, encoding='utf-8')
        signed = self.signing_key.sign(message_bytes, encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')
        
        payload = {
            "loginserver_record": loginserver_record,
            "message": message,
            "sender_created_at": ts,
            "signature": signature_hex_str
        }
        try: 
            username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
        except Exception as e:
            print(e)
            return 1

        isMeta =re.search("^!(M|m)eta:", message)
        if not isMeta:
            database.addBroadCast(loginserver_record, message, ts, signature_hex_str, username, 'false')
        else:
            database.addBroadCast(loginserver_record, message, ts, signature_hex_str, username, 'true')

        all_users = database.getAllUsers()

        for user in all_users:
            user_address = user.get("address", None)
            user_status = user.get("status", None)
            if user_address is None or user_status != "online":
                continue
            url = "http://" + user_address + "/api/rx_broadcast"
            
            if user.get("username") == 'admin':
                url = "http://cs302.kiwi.land/api/rx_broadcast"

            try:
                JSON_object = helper.postJson(payload, headers, url)
                print(JSON_object)
                response = JSON_object.get("response", None)
                if response == "ok":
                    print("broadcast successfully sent")
                else:
                    print("response not OK")
            except:
                print("FAILED TO BROADCAST to url " + str(url))
Esempio n. 9
0
    def retrieveOfflineData(self, since):
        headers = self.createAuthorisedHeader(False)

        all_users = database.getAllUsers()
        for user in all_users:
            user_address = user.get("address", None)
            user_status = user.get("status", None)
            if user_address is None or user_status != "online":
                continue
            url = "http://" + user_address + "/api/rx_checkmessages?since=" + since
            print(url)

            try:
                JSON_object = helper.postJson(None, headers, url)
            except Exception as e:
                print("cannot retrieveOfflineData from " + str(url))
                print(e)
            else:
                response = JSON_object.get("response", None)
                if response == "ok":
                    broadcasts = JSON_object.get("broadcasts", [])
                    private_messages = JSON_object.get("private_messages", [])
                    for broadcast in broadcasts:
                        loginserver_record = broadcast.get("loginserver_record", None)
                        if not loginserver_record:
                            continue
                        message = broadcast.get("message", None)
                        username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
                        isMeta = re.search("^!Meta:(\w+):(\w+)", message)
                        if not isMeta:
                            database.addBroadCast(broadcast.get("loginserver_record", None), broadcast.get("message", None), broadcast.get("sender_created_at", None), broadcast.get("signature", None), username, 'false')
                        else:
                            database.addBroadCast(broadcast.get("loginserver_record", None), broadcast.get("message", None), broadcast.get("sender_created_at", None), broadcast.get("signature", None), username, 'true')
                            key = isMeta.group(1)
                            val = isMeta.group(2)
                            helper.addMetaData(key,val,username)
                    
                    for pm in private_messages:
                        loginserver_record = broadcast.get("loginserver_record", None)
                        if not loginserver_record:
                            continue
                        username, pubkey, server_time, signature_str = helper.breakLoginRecord(loginserver_record)
                        database.addReceivedMessage(pm.get("target_username", None), pm.get("target_pubkey", None), pm.get("encrypted_message", None), pm.get("sender_created_at", None), pm.get("signature", None), username, loginserver_record, 'false')
                else:
                    print("response not OK")
Esempio n. 10
0
    def addPrivateData(self, private_data):
        url_add = "http://cs302.kiwi.land/api/add_privatedata"

        headers = self.createAuthorisedHeader(True)

        ts = str(time.time())

        private_data_str = json.dumps(private_data)
        key = helper.getSymmetricKeyFromPassword(self.password2)
        private_data_encr = helper.encryptStringKey(
            key, private_data_str)  #encrypted private data
        private_data_hex_str = base64.b64encode(private_data_encr).decode(
            'utf-8')  #hexed private data
        print(len(private_data_hex_str))
        if len(private_data_hex_str) >= 4096:
            print("length of pd exceeds")
            self.clearPrivateData()
            return

        #creating message and then signed
        message_bytes = bytes(private_data_hex_str + self.login_server_record +
                              ts,
                              encoding='utf-8')
        signed = self.signing_key.sign(message_bytes,
                                       encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')

        payload = {
            "privatedata": private_data_hex_str,
            "loginserver_record": self.login_server_record,
            "client_saved_at": ts,
            "signature": signature_hex_str
        }
        try:
            JSON_object = helper.postJson(payload, headers, url_add)
            response = JSON_object.get("response", None)
            if response == "ok":
                print("added to private data successfully!")
                return 0
            else:
                raise Exception("failed to save private datta")
        except Exception as e:
            print(e)
            return 1
Esempio n. 11
0
    def addPublicKey(self):
        url = "http://cs302.kiwi.land/api/add_pubkey"

        # Generate a new random signing key
        hex_key = nacl.signing.SigningKey.generate().encode(
            encoder=nacl.encoding.HexEncoder)
        signing_key = nacl.signing.SigningKey(hex_key,
                                              encoder=nacl.encoding.HexEncoder)

        # dealing with public keys
        pubkey = signing_key.verify_key
        pubkey_hex = pubkey.encode(encoder=nacl.encoding.HexEncoder)
        pubkey_hex_str = pubkey_hex.decode('utf-8')

        #creating message and then signed
        message_bytes = bytes(pubkey_hex_str + self.username, encoding='utf-8')
        signed = signing_key.sign(message_bytes,
                                  encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')

        headers = self.createAuthorisedHeader(True)
        payload = {
            "pubkey": pubkey_hex_str,
            "username": self.username,
            "signature": signature_hex_str
        }

        JSON_object = helper.postJson(payload, headers, url)

        response = JSON_object.get("response", None)
        login_server_record = JSON_object.get("loginserver_record", None)

        if response == "ok" and login_server_record is not None:
            print("pubkey added successfully!")
            self.signing_key = signing_key
            self.hex_key = hex_key
            self.login_server_record = login_server_record
            #database.addLoginServerRecord(self.username, login_server_record)
            return 0
        else:
            print("Failed to add pubkey")
            return 1
Esempio n. 12
0
 def getNewApiKey(self):
     url = "http://cs302.kiwi.land/api/load_new_apikey"
     headers = self.createAuthorisedHeader(True)
     try:
         JSON_object = helper.postJson(None, headers, url)
         response = JSON_object.get("response", None)
         if response == "ok":
             apikey = JSON_object.get("api_key", None)
             self.apikey = apikey
         if not apikey or response != "ok":
             print("NO API KEY")
             return 1
     except Exception as e:
         print(e)
         return 1
     #filename = "tmp/api.txt"
     #os.makedirs(os.path.dirname(filename), exist_ok=True)
     #with open(filename, "w") as f:
     #f.write(apikey)
     return 0
Esempio n. 13
0
    def sendGroupMessage(self, target_group_hash, message):
        headers = self.createAuthorisedHeader(False)
        target_group_bytes = bytes(target_group_hash, encoding='utf-8')
        try:
            key = helper.getEncryptionKey(self.logserv,target_group_bytes)
        except Exception as e:
            print(e)
            return 1
        
        if not key:
            print("ERROR IN SENDING MESSAGE")
            return 1
        
        try: 
            encr_message = helper.encryptStringKey(key, message).hex() #TODO change if hex is appropriate.
        except Exception as e:
            print(e)
            return 1
            
        #encr_message = helper.encryptMessage(message, user_pubkey)
        ud = database.getUserHashes(self.username)
        loginserver_record = ud.get("loginrecord")       
        ts = str(time.time())
        message_bytes = bytes(loginserver_record+encr_message+ts, encoding='utf-8')
        signed = self.signing_key.sign(message_bytes, encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')

        payload = {
            "loginserver_record": loginserver_record,
            "groupkey_hash": target_group_hash,
            "group_message": encr_message,
            "sender_created_at": ts,
            "signature": signature_hex_str
        }
        pubkey_hex = self.signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder)
        try:
            self_encrypted_message = helper.encryptMessage(message, pubkey_hex)
        except Exception as e: 
            print("failed to encrypt sent message.")
            print(e)
            return 1
        
        print(target_group_hash)

        target_users = database.getGroupUsers(target_group_hash)
        database.addsentMessages(self.username, target_group_hash, self_encrypted_message, ts, "group")

        for tg in target_users:
            username = tg.get("username")
            user = database.getUserData(username)
            user_address = user.get("address", None)
            user_status = user.get("status", None)
            if user_address is None or user_status != "online":
                continue
            url = "http://" + user_address + "/api/rx_groupmessage"
            print(url)

            try:
                JSON_object = helper.postJson(payload, headers, url)
                print(JSON_object)
                response = JSON_object.get("response", None)
                if response == "ok":
                    print("message sent")
                    print("url")
                else:
                    print("response not OK")
            except:
                print("FAILED TO sent group message!")
Esempio n. 14
0
    def createGroupChatP2p(self, target_usernames):
        headers = self.createAuthorisedHeader(False)
        print("creating group chats")
        error = 0
        #generating symmetric keys to be stored
        key = helper.generateRandomSymmetricKey()
        key_str = key.hex()
        try: 
            helper.addToPrivateData(self.logserv, "prikeys", key_str)
        except Exception as e:
            print(e)
            return 1

        #create a group invite
        ud = database.getUserHashes(self.username)
        loginserver_record = ud.get("loginrecord")
        try: 
            groupkey_hash = helper.getShaHash(key)
        except Exception as e:
            print(e)
            return 1

        groupkey_hash_str = groupkey_hash.decode('utf-8')
        database.addGroupChatReceived(groupkey_hash_str, self.username)

        #encr = helper.getEncryptionKey(self.logserv, groupkey_hash)

        for username in target_usernames:
            
            user = database.getUserData(username)
            user_address = user.get("address", None)
            user_location = user.get("location", None)
            user_pubkey = user.get("pubkey", None)
            try: 
                encr_groupkey = helper.encryptMessage(key, user_pubkey)
            except Exception as e:
                print(e)
                return 1
            ts = str(time.time())

            message_bytes = bytes(loginserver_record+groupkey_hash_str+user_pubkey+username+encr_groupkey+ts, encoding='utf-8')
            
            signed = self.signing_key.sign(message_bytes, encoder=nacl.encoding.HexEncoder)
            signature_hex_str = signed.signature.decode('utf-8')

            payload = {
                "loginserver_record": loginserver_record,
                "groupkey_hash": groupkey_hash_str,
                "target_pubkey": user_pubkey,
                "target_username": username,
                "encrypted_groupkey": encr_groupkey,
                "sender_created_at": ts,
                "signature": signature_hex_str
            }

            if user_address is None:
                continue
            url = "http://" + user_address + "/api/rx_groupinvite"
            print(url)

            try:
                JSON_object = helper.postJson(payload, headers, url)
                print(JSON_object)
                response = JSON_object.get("response", None)
                if response == "ok":
                    print("group invite sent successfully")
                    database.addGroupChatReceived(groupkey_hash_str, username)
                else:
                    print("response not OK")
            except Exception as e:
                print("FAILED TO SEND!")
                print(e)
                error = 1
        return error, groupkey_hash_str
Esempio n. 15
0
    def sendPrivateMessage(self, message, send_user):
        headers = self.createAuthorisedHeader(False)

        user = database.getUserData(send_user)
        user_address = user.get("address", None)
        user_pubkey = user.get("pubkey", None)
        user_status = user.get("status", None)
        try: 
            encr_message = helper.encryptMessage(message, user_pubkey)
        except Exception as e:
            print(e)
            print("failed to encrypt message")
            return 1
        ud = database.getUserHashes(self.username)
        loginserver_record = ud.get("loginrecord")        
        ts = str(time.time())
        message_bytes = bytes(loginserver_record+user_pubkey+send_user+encr_message+ts, encoding='utf-8')
        signed = self.signing_key.sign(message_bytes, encoder=nacl.encoding.HexEncoder)
        signature_hex_str = signed.signature.decode('utf-8')

        pubkey_hex = self.signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder)
        try:
            self_encrypted_message = helper.encryptMessage(message, pubkey_hex)
        except Exception as e: 
            print("failed to encrypt sent message.")
            print(e)
            return 1
        msg = database.addsentMessages(self.username, send_user, self_encrypted_message, ts, "user")
        if msg["response"] == "error":
            return 1
        
        payload = {
            "loginserver_record": loginserver_record,
            "target_pubkey": user_pubkey,
            "encrypted_message": encr_message,
            "target_username": send_user,
            "sender_created_at": ts,
            "signature": signature_hex_str
        }
        
        if user_status == "online":
            user = database.getUserData(send_user)
            user_address = user.get("address", None)
            user_status = user.get("status", None)
            url = "http://" + user_address + "/api/rx_privatemessage"
            
            try:
                JSON_object = helper.postJson(payload, headers, url)
                response = JSON_object.get("response", None)
                if response == "ok":
                    print("pm sent successfully")
                    return 0
                else:
                    raise Exception("error sending private message")
            except Exception as e:
                print("FAILED TO SEND MESAGE")
                print(e)

                all_users = database.getAllUsers()
                #sending offline message.
                for user in all_users:
                    user_address = user.get("address", None)
                    user_status = user.get("status", None)
                    if user_address is None or user_status != "online":
                        continue
                    url = "http://" + user_address + "/api/rx_privatemessage"                    
                    try:
                        JSON_object = helper.postJson(payload, headers, url)
                        response = JSON_object.get("response", None)
                        if response == "ok":
                            print("pm sent successfully sent")
                        else:
                            raise Exception("error sending private message")
                    except Exception as e:
                        print(e)