def get_arr_contacts_helper(hash) -> ([str], [str]):
    masterArrName = []
    masterArrEmail = []

    try:
        FileCredibility.fullStop("contacts.txt")
        contactFile = open("contacts.txt", "r")
    except:
        return (masterArrName, masterArrEmail)

    fernet = Fernet(encryption.calculateKey(hash)[0])
    line = contactFile.readline()[:-1]
    if (not line):
        return (masterArrName, masterArrEmail)

    while (line):
        name = fernet.decrypt(line.encode()).decode()
        line = contactFile.readline()[:-1]
        email = fernet.decrypt(line.encode()).decode()

        masterArrName.append(name)
        masterArrEmail.append(email)

        line = contactFile.readline()[:-1]

    contactFile.close()
    return (masterArrName, masterArrEmail)
def listContacts(hash):
    try:
        FileCredibility.fullStop("contacts.txt")
        contactFile = open("contacts.txt", "r")
    except:
        print("No contacts found. To add a contact write 'add'")
        return

    counter = 0
    fernet = Fernet(encryption.calculateKey(hash)[0])
    line = contactFile.readline()[:-1]
    if (not line):
        print("No contacts found. To add a contact write 'add'")
    while (line):
        counter = counter + 1
        print("\tContact " + str(counter))
        print("\tName:\t" + fernet.decrypt(line.encode()).decode())
        line = contactFile.readline()[:-1]
        print("\tEmail:\t" + fernet.decrypt(line.encode()).decode())
        line = contactFile.readline()[:-1]
        if (line):
            print()

    contactFile.close()

    print()
def removeContactHelper(hash, fullName, contactFile):
    try:
        FileCredibility.fullStop(contactFile)
        with open(contactFile, "r") as f:
            lines = f.readlines()
    except:
        print("No contacts found. To add a contact write 'add'")
        return

    fernet = Fernet(encryption.calculateKey(hash)[0])

    with open(contactFile, "w") as f:
        bFound = False
        bMarker = False
        for line in lines:
            trueTerm = fernet.decrypt(line[:-1].encode()).decode()
            if (trueTerm != fullName and bFound == False):
                f.write(line)
            else:
                bMarker = True
                if (bFound == True):
                    bFound = False
                else:
                    bFound = True
        FileCredibility.updateFiles([contactFile])

    if (bMarker):
        print("Successfully removed contact " + fullName + ".\n")
    else:
        print("Cannot find \"" + fullName + "\" in contact list.\n")

    return
def addContact(hash):
    # need to check if contact already exists

    list_of_contacts, list_of_emails = get_arr_contacts_helper(hash)

    fernet = Fernet(encryption.calculateKey(hash)[0])
    tempName = input("\tEnter Full Name: ").lower()
    while tempName in list_of_contacts:
        print("Duplicate Name! Sorry you already have", tempName, "with email",
              list_of_emails[list_of_contacts.index(tempName)],
              "saved as a contact")
        tempName = input("\tEnter Full Name or q to quit: ").lower()

    if tempName == 'q':
        print("Name iggnored ... returning back to SecureDrop")
        return

    tempEmail = input("\tEnter Email Address: ").lower()
    while tempEmail in list_of_emails:
        print("Duplicate Email! Sorry you already have",
              list_of_contacts[list_of_emails.index(tempEmail)], "with email",
              tempEmail, "saved as a contact")
        tempEmail = input("\tEnter Email Address or q to esc: ").lower()

    if tempEmail == 'q':
        print("Name and email iggnored ... returning back to SecureDrop")
        return
    addContactHelper(fernet, tempName, tempEmail)
def registerUser():
    tempFile = input("Enter Full Name: ") + '\n'
    tempFile += input("Enter Email Address: ").lower()

    numTries = 3
    while (numTries > 0):
        print(
            "Password must:\n\tBE:  \t8 to 25 chars\n\tHAVE:\tAt least one uppercase letter\n\tHAVE:\tAt least one lowercase letter\n\tHAVE:\tAt least one diget"
        )

        pswd1, len_and_contains_up_low_dig = encryption.calculateKey(
            stdiomask.getpass(prompt='Enter Password: '******'That password is missing or failing one or more of the requirements...\n'
            )
            continue

        if pswd1 != encryption.calculateKey(
                stdiomask.getpass(prompt='Re-Enter Password: '******'userData.encrypted'
    with open(user_file, 'wb') as uf:
        uf.write(bytes_object)
    FileCredibility.updateFiles([user_file])

    print("User registered.\n")
def login():
    email = ""
    numGuesses = 5
    sal, pep = HashPasswords.getCondiments()

    files = ['pickle.encrypted', 'userData.encrypted', 'userData.psw']
    for file in files:
        FileCredibility.fullStop(file)

    curHash = HashPasswords.calcPeperHash('pswd'.encode(), sal, pep)
    print('\n*Email is NOT case-sensitive*', end='')
    while (numGuesses > 0):
        email = input("\nEnter Email Address: ")
        if email.lower() == 'quit':
            inp = input("You enterd " + email +
                        " ... are you trying to quit the program? (y/n) ")
            while inp != 'n' and inp != 'y':
                print(inp + " is not 'y' or 'n'")
                inp = input("You enterd " + email +
                            " ... are you trying to quit the program? (y/n) ")
            if inp == 'y':
                img.bye()
                leave(False)

        usrin = encryption.calculateKey(
            stdiomask.getpass(prompt='Enter Password: '******'userData', email.lower())
        if not login_success:
            numGuesses -= 1
            if (numGuesses > 0):
                print("Incorrect email or password, please try again.")
            else:
                print(
                    "Too many incorrect email and password attempts. Exiting SecureDrop."
                )
                img.bye()
                leave(False)
            continue

        curHash = HashPasswords.calcPeperHash(usrin, sal, pep)
        break

    return curHash, og_name, og_email
def composite(userin, hash) -> bool:
    try:
        args = userin.replace('  ', ' ').split(' ')
        if len(args) < 2:
            return False

        if args[0] == "add" and len(args) < 4:
            name, email = args[1], args[2]
            list_of_contacts, list_of_emails = get_arr_contacts_helper(hash)
            if name in list_of_contacts:
                print("Duplicate Name! Sorry you already have", name,
                      "with email",
                      list_of_emails[list_of_contacts.index(name)],
                      "saved as a contact")
                addContact(hash)
                return True
            if email in list_of_emails:
                print("Duplicate Email! Sorry you already have",
                      list_of_contacts[list_of_emails.index(email)],
                      "with email", email, "saved as a contact")
                addContact(hash)
                return True
            addContactHelper(Fernet(encryption.calculateKey(hash)[0]), name,
                             email)
            return True

        if args[0] == "remove":
            contactFile = "contacts.txt"
            if not exists(contactFile) or os.stat(contactFile).st_size == 0:
                print("No contacts found. To add a contact write 'add'")
                return False

            counter = 1
            print('')
            while counter < len(args):
                removeContactHelper(hash, args[counter], contactFile)
                counter += 1
            return True
    except:
        return False

    return False
예제 #8
0
def sendFile(hash, usr_email):
    # server info
    IP = socket.gethostbyname(socket.gethostname())
    PORT = 4455
    ADDR = (IP, PORT)
    FORMAT = "utf-8"
    SIZE = 1024

    # see if there are any contacts
    try:
        FileCredibility.fullStop("contacts.txt")
        with open("contacts.txt", "r") as f:
            contactData = f.readlines()
    except:
        print(
            "No contacts found. Sending a file requires having at least one contact. To add a contact type 'add'\n"
        )
        return

    # create a TCP socket
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        # connect to the server
        client.connect(ADDR)
    except:
        print("There are no contacts online. Returning to SecureDrop menu.\n")
        client.close()
        return

    # send my info to the contact
    client.send(usr_email.encode(FORMAT))

    try:
        # get contacts that are online
        onlineContact = client.recv(SIZE).decode(FORMAT)
    except:
        print("\nLost connection to server. Returning to SecureDrop menu.\n")
        client.close()
        return

    # check if online contact is in contact list
    fernet = Fernet(encryption.calculateKey(hash)[0])
    contactFound = False
    marker = False
    for line in contactData:
        if (fernet.decrypt(line[:-1].encode()).decode()
                == onlineContact) and marker:
            contactFound = True
            break
        else:
            marker = True

    # if not in contacts return
    if (contactFound == False):
        print(
            "Someone who is not in your contacts is trying to receive your file. Returning to SecureDrop menu.\n"
        )
        client.close()
        return

    print("The following contacts are online:\n  * " + onlineContact)

    contact = input(
        "\nPlease enter the email of the contact you wish to send a file to>> "
    )

    # check if contact is in contact list
    fernet = Fernet(encryption.calculateKey(hash)[0])
    contactFound = False
    marker = False
    for line in contactData:
        if (fernet.decrypt(line[:-1].encode()).decode() == contact) and marker:
            contactFound = True
            break
        else:
            marker = True

    # if not in contacts return
    if (contactFound == False):
        print(
            "Contact not found in contacts list. Returning to SecureDrop menu.\n"
        )
        client.close()
        return

    # check if contact entered is actually online
    if (onlineContact != contact):
        print("That contact is not online. Returning to SecureDrop menu.\n")
        client.close()
        return

    filename = input("Please enter the name of the file you wish to send>> ")
    if wishToLeave(filename):
        client.close()
        return

    while not os.path.exists(filename):
        print("Cannot find file '" + filename + "'.\n")
        print('You may enter \'quit\' or \'exit\' to leave this prompt.')
        filename = input(
            "Please re-enter the name of the file you wish to send>> ")
        if wishToLeave(filename):
            client.close()
            return

    FileCredibility.updateFiles([filename])

    client.send("ready".encode(FORMAT))
    print("\nWaiting for contact to accept file transfer...")

    try:
        # receive message from server about accepted transfer request
        msg = client.recv(SIZE).decode(FORMAT)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # if message doesnt actually come from the contact you tried sending to
    if contact not in msg:
        print(
            "The response was not from your contact. Returning to SecureDrop menu.\n"
        )
        client.close()
        return

    print(msg)

    # return to main if contact declines the file
    if "declined" in msg:
        print("Returning to SecureDrop menu.\n")
        client.close()
        return

    try:
        # receive the key file name and data
        keyFilename = client.recv(SIZE).decode(FORMAT)
        keyData = client.recv(SIZE).decode(FORMAT)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # save key data
    with open(keyFilename, "w") as keyFile:
        keyFile.write(keyData)
    FileCredibility.updateFiles([keyFilename])

    # print("\nReceiver public key file has been received.")

    # let contact know that key file has been received
    client.send(
        "Receiver public key file has been successfully transferred.".encode(
            FORMAT))

    try:
        # receive signature file name and data
        sigFilename = client.recv(SIZE).decode(FORMAT)
        sigData = client.recv(SIZE)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # save signature data
    with open(sigFilename, "wb") as sigFile:
        sigFile.write(sigData)
    FileCredibility.updateFiles([sigFilename])

    # system auto authenticates

    # let client know that the authentication was successful
    client.send(
        "Receiver signature file has been transferred and authenticated.".
        encode(FORMAT))

    # predict file size:
    predicted_size = predictFileSize(filename)
    client.send(f'size={predicted_size}'.encode(FORMAT))
    large_file = False
    if predicted_size > MAX_RECEIVE_SIZE:
        large_file = True
        print(
            "\nThe file you are encrypting is large. This may take a moment...",
            end='\r')

    # generate sender public key file and encrypt the message filename
    fn = filename.split('.')[0]
    extension = '.' + filename.split('.')[1]
    try:
        sym_key = EncMsg.gen_sender_key_file()
    except cryptography.exceptions.InvalidSignature:
        print(
            '\nr.pub is a forgery! The receiver is not who they say they are!')
        print("Returning to SecureDrop menu.\n")
        client.close()
        return

    if type(sym_key) == int and sym_key == -1:
        print("\ncertificate authority declined to sign public key file")
        print("Returning to SecureDrop menu.\n")
        client.close()
        return
    if EncMsg.gen_send_file(sym_key, fn, extension):
        if large_file:
            print(
                "The file you are encrypting is large. This may take a moment... Success!"
            )
    else:
        print("Failed to encrypt the file. ERROR_26: file too large")

    # send the sender public key filename
    client.send("s.pub".encode(FORMAT))

    # get key data
    FileCredibility.fullStop("s.pub")
    with open("s.pub", "rb") as sender_public_key_file:
        sender_public_key_data = sender_public_key_file.read()

    # send the sender public key data
    client.send(sender_public_key_data)

    try:
        # receive message about successfull public key file transfer
        msg = client.recv(SIZE).decode(FORMAT)
        # print(msg)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # send the sender signature filename
    client.send("s.sig".encode(FORMAT))

    # get signature file data
    FileCredibility.fullStop("s.sig")
    with open("s.sig", "rb") as sender_sig_file:
        sender_sig_data = sender_sig_file.read()

    # send sig file data
    client.send(sender_sig_data)

    try:
        # receive message about successful transfer of sig file
        msg = client.recv(SIZE).decode(FORMAT)
        # print(msg)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # send enc-message filename to server
    client.send(filename.encode(FORMAT))

    # send enc-message file size to server
    filesize = getFileSize(filename.split('.')[0] + '.zok')
    client.send(f'size={filesize}'.encode(FORMAT))

    # get encrypted message data
    fenc = filename.split(".")[0] + ".zok"
    FileCredibility.fullStop(fenc)
    file = open(fenc, "rb")
    data = file.read()
    file.close()

    try:
        decision = client.recv(SIZE).decode(FORMAT)
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return
    if decision == 'n':
        print("\n" + contact +
              " has declined the large file. Returning to SecureDrop menu.\n")
        client.close()
        return

    print(f'\n{filename} sending...', end='\r')
    # send encrypted message data
    client.sendall(data)

    # receive message from server about successful file transfer
    try:
        msg = client.recv(SIZE).decode(FORMAT)
        if ' has been successfully transferred.' in msg:
            print(f'{filename} has been successfully transferred!\n')
        else:
            print("\n" + msg + "\n")
    except:
        print("\n" + contact +
              " has closed the connection. Returning to SecureDrop menu.\n")
        client.close()
        return

    # end connection from server
    client.close()

    return