예제 #1
0
def register_node(data, address, keys, dbkeys):
    #Determine if the public key sent by the node is in the system
    for i in keys:
        if str(
                base64.b64encode(
                    hashlib.sha256(i.key.exportKey("PEM")).digest()),
                'ascii') == data[0]:
            #open connection to node for challenge-response authentication
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.connect((address[0], 44432))

                #pick 2 numbers, one for the db key, and one for the decvice key
                sum1 = str(int.from_bytes(Random.get_random_bytes(4), "big"))
                sum2 = str(int.from_bytes(Random.get_random_bytes(4), "big"))

                #encrypt the first number with device public key and the second with db public key
                pay = aes_crypt.aes_enc(i.key, sum1)
                pay2 = aes_crypt.aes_enc(dbkeys[data[1]].key, sum2)

                sum1 = int(sum1)
                sum2 = int(sum2)

                #send the two payloads
                s.send(pay + b'::' + pay2)

                #recieve and check that valid data was recieved
                return_sums = aes_crypt.aes_dec(
                    rsa_encrypt.get_priv_key_auth(), s.recv(4096))

                #Return error if trouble decrypting message
                if return_sums == -2 or return_sums == -1:
                    return

                #Convert the sums to a list
                return_sums = str(return_sums, 'ascii').split(":")

                #convert the response to integer
                check1 = int(return_sums[0])
                check2 = int(return_sums[1])

                #validate that the node was able to read the data and modify it predictably
                if (sum1 + 1) == check1 and (sum2 + 1) == check2:
                    #log that the node was registered
                    i.db = data[1]

                    #grab timestamp from node
                    timestamp = aes_crypt.aes_dec(
                        rsa_encrypt.get_priv_key_auth(), s.recv(4096))

                    #validate data and convert timstamp to float
                    if timestamp == -1 or timestamp == -2:
                        return

                    timestamp = float(str(timestamp, "ascii"))

                    #start node database update and print results when finished
                    shamir_update_client.update(i, timestamp, s)
                    print("Node registered:   " + data[1])
예제 #2
0
def challenge():

    #create host object
    host = Host()

    #Create a hash of the node's public key to send to the auth node for identity verification
    keyhash = str(
        base64.b64encode(
            hashlib.sha256(
                rsa_encrypt.get_pub_key().exportKey("PEM")).digest()), 'ascii')

    #creates a payload of the message that identifies that this is a client node that needs to be updated
    payload = "imup" + ":" + str(
        comms_number) + ":" + keyhash + ":" + settings.ID

    #create a socket to communicate with the auth nodes
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #Create an empty data and address variable and a socket to recieve the data
        data = ""
        addr = 0
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as us:

            #set a timeout for if there is no auth node ready
            us.settimeout(1)
            us.bind(('0.0.0.0', 55551))

            #send the challenge tag to the auth nodes along with a public key to encrypt their return message with
            s.sendto(
                aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                  "who?:" + keyhash), ((host.host, host.port)))

            #Recv a number from the auth node to connect to
            try:
                data, addr = us.recvfrom(4096)
            #if it fails return an error
            except socket.timeout:
                us.close()
                return -1

        #Decrypt the recieved message
        data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), data)

        #if message is bad return error
        if data == -1 or data == -2:
            return -1

        #convert data to a string to return to the auth nodes along with the instruction payload
        data = str(data, 'ascii')

        #send payload and return expected address
        s.sendto(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                              "you!:" + data + ":" + payload),
            ((host.host, host.port)))
        return addr
예제 #3
0
def register(user, name, keys):
    payload = "usrW" + ":" + rsa_encrypt.get_auth_hash() + ":" + user + ":" + name + ":" + ":".join(keys)
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        payload = aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), payload)
        s.sendto(payload, (settings.MULT_ADDR, settings.MULT_PORT))
예제 #4
0
def contest_auth(address):

    #open a socket to the reciever
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:

        #send the number
        data = aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                 str(my_number))
        s.sendto(data, (address, 44443))
예제 #5
0
def challenge(my_number, kind):

    #Creates a host object for use in multicast socket
    host = Host()

    #Creates a multicast socket to communicate with all auth nodes at once
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #Creates a socket to recieve a unique number from the first auth node to respond to the contest
        data = ""
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as us:
            #sets a small timeout in case this is the first auth node in the system or the response is delayed
            us.settimeout(1)
            us.bind(('0.0.0.0', 55551))

            #Sends a messafe to the other auth nodes to start a contest
            s.sendto(
                aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                  "regA:" + str(my_number)),
                ((host.host, host.port)))

            #Recieves encrypted number from auth node
            data, address = us.recvfrom(4096)

        #Decrypt the recieved number using auth private key
        data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_auth(), data)

        #Check to make sure the message wasnt tampered with, return error if it was
        if data == -1 or data == -2:
            return 1

        #convert the number to a string
        data = str(data, 'ascii')

        #encrypt the number with the auth public key and send it back to the auth nodes, letting them know which one was chosen and what action to preform
        #in this case the asction is provising updates to the auth server
        s.sendto(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                              "you!:" + data + ":" + kind),
            ((host.host, host.port)))
        return address
예제 #6
0
def contest(address, pub, keys):

    #For each key
    for i in keys:

        #if the provided hash equals the key's hash
        if i.hash == pub:

            #send the node's number to the provided address, encrypted with their public key
            with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
                data = aes_crypt.aes_enc(i.key, str(my_number))
                s.sendto(data, (address, 44443))
예제 #7
0
def send_share(share, host):

    #Store the share as a string
    payload = "auth:" + share['id'] + ":" + share['x'] + ":" + share['y']

    #open a socket to the multicast address
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #encrypt the share with the auth public key and send it to the multicast address
        s.sendto(aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), payload),
                 ((host.host, host.port)))
예제 #8
0
def db_send(db, num):

    ts = str(time.time())

    comms.database_log([db, num, ts])

    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
        s.sendto(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                              "DBUP:" + db + ":" + num + ":" + ts),
            (settings.MULT_ADDR, settings.MULT_PORT))

    comms.send_clients()
예제 #9
0
def send_share(key, shares, s):
  
    #Joins the list of shares, encrypts them with the given public key, and sends them to the listening node 
    payload = aes_crypt.aes_enc(key, ':'.join(shares))
    s.send(payload)
예제 #10
0
def broadcast(uid):

    print("Sending New Share to other Auth Nodes")

    #instantiate a shares list
    shares = []

    #For each database
    for i in settings.DBS:

        #Open a connection to the db
        conn = sqlite3.connect(settings.DBdir + i + ".db")
        conn.row_factory = sqlite3.Row
        c = conn.cursor()

        #Grab the provided user's share from this database
        c.execute("SELECT * FROM enc_shares WHERE id = ?", [uid])

        #append the share to the list and close the connection
        shares.append(c.fetchone())
        conn.close()

    #Connect to the secrets database
    conn = sqlite3.connect(settings.DBdir + "secrets.db")
    conn.row_factory = sqlite3.Row
    c = conn.cursor()

    #Grab the user's secret entry
    c.execute("SELECT * FROM secrets WHERE id = ?", [uid])

    #append the secret to the list and close the connection
    shares.append(c.fetchone())
    conn.close()

    #Create an empty string to hold the data
    data = ""

    #For each share
    for i in range(len(shares) - 1):

        #Add no data if this is a delete message
        if shares[i] == None:
            data += "NONE||"

        else:
            #Append the share as a string to the data using the seperator ||
            data += (
                str(shares[i]['id']) + "|" +
                str(shares[i]['share'] + "|" + str(shares[i]['timestamp'])) +
                "||")

    #Append the secrets entry to the data string
    data += (str(shares[-1]['id']) + "|" + str(shares[-1]['name']) + "|" +
             str(shares[-1]['secret']) + "|" + str(shares[-1]['timestamp']))

    #Prepend a hash of the auth private key to the data
    data = (rsa_encrypt.get_auth_hash() + "||" + data)

    #Open a socket to the multicast address
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #Set the data header
        data = "here:" + str(my_number) + ":" + data

        #Encrypt the data and send it to the auth nodes
        payload = aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), data)
        s.sendto(payload, (settings.MULT_ADDR, settings.MULT_PORT))
예제 #11
0
def broadcast(uid):

    print("Sending New Share to other Auth Nodes")

    #grab auth hash for use
    auth_hash = rsa_encrypt.get_auth_hash()

    #instantiate a shares list
    shares = []

    #open socket to multicast address
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #For each database
        for i in settings.DBS:

            #Open a connection to the db
            conn = sqlite3.connect(settings.DBdir + i + ".db")
            conn.row_factory = sqlite3.Row
            c = conn.cursor()

            #Grab the provided user's share from this database
            c.execute("SELECT * FROM enc_shares WHERE id = ?", [uid])

            #append the share to the list and close the connection
            shares.append(c.fetchone())
            conn.close()

        #Connect to the secrets database
        conn = sqlite3.connect(settings.DBdir + "secrets.db")
        conn.row_factory = sqlite3.Row
        c = conn.cursor()

        #Grab the user's secret entry
        c.execute("SELECT * FROM secrets WHERE id = ?", [uid])

        #append the secret to the list and close the connection
        shares.append(c.fetchone())
        conn.close()

        #For each share
        for i in range(len(shares) - 1):

            #Add no data if this is an empty message
            if shares[i] == None:
                continue

            else:
                #Grab the data from current database as a string
                data = settings.DBS[i] + "||" + str(
                    shares[i]['id']) + "||" + str(
                        shares[i]['share']) + "||" + str(
                            shares[i]['timestamp'])

                #prepend header and send data
                data = "here:" + str(my_number) + ":" + auth_hash + "||" + data
                s.sendto(
                    aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), data),
                    ((settings.MULT_ADDR, settings.MULT_PORT)))

        #grab the data from the secrets database as a string
        data = "secrets||" + str(shares[-1]['id']) + "||" + str(
            shares[-1]['name']) + "||" + str(
                shares[-1]['secret']) + "||" + str(shares[-1]['timestamp'])

        #Prepend header and send data
        data = "here:" + str(my_number) + ":" + auth_hash + "||" + data
        s.sendto(aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), data),
                 ((settings.MULT_ADDR, settings.MULT_PORT)))
예제 #12
0
def register_node(data, address, keys, dbkeys):
    #Determine if the public key sent by the node is in the system

    #register update type
    comms_node = data[0]
    data = data[1:]

    for i in keys:
        if str(
                base64.b64encode(
                    hashlib.sha256(i.key.exportKey("PEM")).digest()),
                'ascii') == data[0]:

            #log databse name
            i.db = data[1]

            #add database to clients db and share it with wb uis
            db_send(data[1], comms_node)

            #open connection to node for challenge-response authentication
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.connect((address[0], 55550))

                #pick 2 numbers, one for the db key, and one for the decvice key
                sum1 = str(int.from_bytes(Random.get_random_bytes(4), "big"))
                sum2 = str(int.from_bytes(Random.get_random_bytes(4), "big"))

                #encrypt the first number with device public key and the second with db public key
                pay = aes_crypt.aes_enc(i.key, sum1)
                pay2 = aes_crypt.aes_enc(dbkeys[data[1]].key, sum2)

                sum1 = int(sum1)
                sum2 = int(sum2)

                #send the two payloads
                s.send(pay + b'::' + pay2)

                #recieve and check that valid data was recieved
                return_sums = aes_crypt.aes_dec(
                    rsa_encrypt.get_priv_key_auth(), s.recv(4096))

                #Return error if trouble decrypting message
                if return_sums == -2 or return_sums == -1:
                    return

                #Convert the sums to a list
                return_sums = str(return_sums, 'ascii').split(":")

                #convert the response to integer
                check1 = int(return_sums[0])
                check2 = int(return_sums[1])

                #validate that the node was able to read the data and modify it predictably
                if (sum1 + 1) == check1 and (sum2 + 1) == check2:

                    #grab timestamps from node
                    temp = b""
                    data = b""
                    try:
                        while 1 == 1:
                            temp = s.recv(4096)
                            if temp and len(temp) == 4096:
                                data += temp
                            else:
                                break
                        data += temp

                    #if connection dies
                    except:
                        return -1

                    #decrypt timestamps
                    timestamps = aes_crypt.aes_dec(
                        rsa_encrypt.get_priv_key_auth(), data)

                    #validate data and convert timstamp to float
                    if timestamps == -1 or timestamps == -2:
                        return -1

                    #split timestamps into list
                    timestamps = str(timestamps, "ascii").split("|")

                    #start node database update and print results when finished
                    shamir_update_client.update(i, timestamps, s)

                    print("Node updated:   " + i.db)
예제 #13
0
def updater(address):

    #Open a socket to send the shares from, connecting to the provided address
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((address, 55552))

        #create a random number for the challenge response authentication
        challenge = int.from_bytes(Random.get_random_bytes(10), 'big')

        #Send the number to the recieving node
        s.send(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), str(challenge)))

        #Get the number back, along with the updatee's timestamps
        #Recieve until done
        response = b""
        temp = b""
        try:
            while 1 == 1:
                temp = s.recv(4096)
                if temp and len(temp) == 4096:
                    response += temp
                else:
                    break
            response += temp

        #exit if connection breaks
        except:
            return -1

        #decrypt response
        response = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_auth(), response)

        #return error if data is corrupted
        if response == -1 or response == -2:
            return -1

        #split response into timestamp and the response number
        response = str(response, 'ascii').split(":")

        #confirm that the response is correct
        if (challenge + 1) == int(response[0], 0):

            #grab timestamp
            timestamps = response[1].split("|")

            #create holder for share information
            data = ""

            #for each database
            for i in settings.DBS:

                #set up connection
                conn = sqlite3.connect(settings.DBdir + i + ".db")
                conn.row_factory = sqlite3.Row
                c = conn.cursor()

                #Make sure table exists
                c.execute(
                    "CREATE TABLE IF NOT EXISTS enc_shares(id PRIMARY KEY, share, timestamp DOUBLE)"
                )

                #Grab all shares from the current database with timestamp greater than the client's timestamp
                c.execute("SELECT * FROM enc_shares")
                d = c.fetchall()

                shares = []
                #for each share
                for i in range(len(d)):
                    #Join the components into a string if they are needed by the updatee
                    if not str(d[i]['timestamp']) in timestamps:
                        shares.append(d[i]["id"] + "|" + d[i]["share"] + "|" +
                                      str(d[i]["timestamp"]))

                #Join each share together
                shares = "::".join(shares)

                #add the information from this database to the database string
                data += (shares + ":::")

                #close connection
                conn.close()

            #open the secrets db
            conn = sqlite3.connect(settings.DBdir + "secrets.db")
            conn.row_factory = sqlite3.Row
            c = conn.cursor()

            #make sure table exists
            c.execute(
                "CREATE TABLE IF NOT EXISTS secrets(id PRIMARY KEY, name, secret, timestamp DOUBLE)"
            )

            #Grab all shares past the client timestamp
            c.execute("SELECT * FROM secrets")
            d = c.fetchall()

            secrets = []
            #For each secret
            for i in range(len(d)):

                #convert the share to a string if it is needed by the updatee
                if not str(d[i]['timestamp']) in timestamps:
                    secrets.append(d[i]["id"] + "|" + d[i]["name"] + "|" +
                                   d[i]["secret"] + "|" +
                                   str(d[i]['timestamp']))

            #join all the shares and add them to the db string
            data += "::".join(secrets)

            #send the databases to the client and exit
            s.send(aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), data))
    return 0
예제 #14
0
def updateee(my_number):

    #open socket to recieve shares into
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('0.0.0.0', 55552))
        s.listen(5)
        address = 0

        #Attempt to update the node
        try:
            #make sure that challenge exits succesfully and grab host address
            address = challenge(my_number, "woke")
            while address == 1:
                address = challenge(my_number, "woke")

        #If socket times out then return, this is likely the first auth node to be activated
        except socket.timeout:
            print("No Auth Nodes Found")
            return

        #accept connection from the node that shares will be pulled from
        cli, addr = s.accept()
        while not addr[0] == address[0]:
            cli, addr = s.accept()

        #Challenge response authentication, the node recieves a number from the auth node responsible for the update
        #and sends the number + 1 to the other node

        data = cli.recv(1024)

        #decrypt number and increment it by one
        data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_auth(), data)
        data = str(data, 'ascii')
        data = str(int(data) + 1)

        #encrypt number and return it to the host
        #send the timestamp of the most recent share along with the number
        timestamps = grab_timestamps()
        cli.send(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                              data + ":" + timestamps))

        #Recv data until the sender is done
        data = b""
        temp = b""
        try:
            while 1 == 1:
                temp = cli.recv(4096)
                if temp and len(temp) == 4096:
                    data += temp
                else:
                    break
            data += temp

        #if the sender loses the connection then quit
        except:
            print("registered: 0 updates")
            return

        #Decrypt the data with the auth private key
        data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_auth(), data)

        #if the data is invalid return error
        if data == -2 or data == -1:
            return -1

        #if no databases hold data then return
        if data == b':::' * settings.TOTAL:
            print("registered: 0 updates")
            return

        #split the data into a list of databases
        data = str(data, 'ascii').split(":::")

        #for each database split the entries into a list
        for i in range(len(data)):
            data[i] = data[i].split("::")

        #store the list of db's into a disctonary
        #they are sent in the order they are listed in settings.py
        updates = {}
        for i in range(len(settings.DBS)):
            updates[settings.DBS[i]] = data[i]

        #store the secrets database into the dictionary
        updates['secrets'] = data[-1]

        #fill the databases
        fill_dbs(updates)

        #exit, ptinting the number of shares that were updated
        print("registered: " + str(len(updates['secrets'])) + " updates")
    return
예제 #15
0
def register():

    #Create socket to recieve updates from
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(5)
        s.bind(("0.0.0.0", 55550))
        s.listen(5)

        #make sure that challenge executes correctly, else return error
        print("Looking for Auth Node")
        address = challenge()
        if address == -1:
            return -1

        #Create a connection with the auth node, if it is not the
        #expected address than continue waiting
        try:
            cli, addr = s.accept()
            while not addr[0] == address[0]:
                cli, addr = s.accept()
        except socket.timeout:
            return -1

        #Report
        print("Recieving Updates Now")

        #Recieve two sums for challenge response authentication
        #One for the database and one for the public key
        sums = cli.recv(2048).split(b"::")

        #Decrypt the sums using the node and db public keys
        sums[0] = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), sums[0])
        sums[1] = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_db(settings.ID),
                                    sums[1])

        #if there is an error in the communication of the sums return an error
        if sums[0] == -1 or sums[0] == -2 or sums[1] == -1 or sums[1] == -2:
            return 1

        #Increment the sums and return them via the auth public key
        sum1 = str(int(sums[0]) + 1)
        sum2 = str(int(sums[1]) + 1)

        #send the incremented sums back to proove node identity
        payload = aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                    sum1 + ":" + sum2)
        #Fill recv buffer
        cli.send(payload + b"\x00" * (4096 - len(payload)))

        #Grab the latest timestamp
        timestamps = grab_timestamps()

        #Send the timestamp encrypted with the auth public key
        cli.send(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), str(timestamps)))

        #Run the update process
        num_updates = shamir_updater.update(cli)

        #make number presentable
        if num_updates == -1:
            num_updates = 0

        #Report shares
        print("Registered: " + str(num_updates) + " updates")

        #clean up and exit
        cli.close()
    return
예제 #16
0
def updater(address):

    #Open a socket to send the shares from, connecting to the provided address
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((address, 44441))

        #create a random number for the challenge response authentication
        challenge = int.from_bytes(Random.get_random_bytes(10), 'big')

        #Send the number to the recieving node
        s.send(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), str(challenge)))

        #Get the number back, along with the most recent timestamp that the recieving server has
        response = s.recv(2048)

        #decrypt response
        response = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_auth(), response)

        #return error if data is corrupted
        if response == -1 or response == -2:
            return -1

        #split response into timestamp and the response number
        response = str(response, 'ascii').split(":")

        #confirm that the response is correct
        if (challenge + 1) == int(response[0], 0):

            #grab timestamp
            timestamp = response[1]

            #create holder for share information
            data = ""

            #for each database
            for i in settings.DBS:

                #set up connection
                conn = sqlite3.connect(settings.DBdir + i + ".db")
                conn.row_factory = sqlite3.Row
                c = conn.cursor()

                #Make sure table exists
                c.execute(
                    "CREATE TABLE IF NOT EXISTS enc_shares(id PRIMARY KEY, share, timestamp DOUBLE)"
                )

                #Grab all shares from the current database with timestamp greater than the client's timestamp
                c.execute("SELECT * FROM enc_shares WHERE timestamp > ?",
                          [float(timestamp)])
                d = c.fetchall()

                #for each share
                for i in range(len(d)):
                    #Join the components into a string
                    d[i] = d[i]["id"] + "|" + d[i]["share"] + "|" + str(
                        d[i]["timestamp"])

                #Join each share together
                d = "::".join(d)

                #add the information from this database to the database string
                data += (d + ":::")

                #close connection
                conn.close()

            #open the secrets db
            conn = sqlite3.connect(settings.DBdir + "secrets.db")
            conn.row_factory = sqlite3.Row
            c = conn.cursor()

            #make sure table exists
            c.execute(
                "CREATE TABLE IF NOT EXISTS secrets(id PRIMARY KEY, name, secret, timestamp DOUBLE)"
            )

            #Grab all shares past the client timestamp
            c.execute("SELECT * FROM secrets WHERE timestamp > ?",
                      [float(timestamp)])
            d = c.fetchall()

            #For each share
            for i in range(len(d)):

                #convert the share to a string
                d[i] = d[i]["id"] + "|" + d[i]["name"] + "|" + d[i][
                    "secret"] + "|" + str(d[i]['timestamp'])

            #join all the shares and add them to the db string
            data += "::".join(d)

            #send the databases to the client and exit
            s.send(aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), data))
    return 0