예제 #1
0
def check_pin(request, account):
    """:returns True on success, False on failure"""
    if request.card_pin != account.pin:
        eprint("wrong pin!")
        # eprint("expected '{}', but got '{}'".format(account.pin, request.card_pin))
        return False
    return True
예제 #2
0
def create_new_account(request):
    """:return True on success, False otherwise"""
    if request.account in accounts:
        eprint("account name '{}' already exists".format(request.account))
        return False
    if request.amount < Balance(10 * 100):
        eprint("initial balance {} must be at least 10.00".format(
            request.amount))
        return False
    accounts[request.account] = Account(request.card_pin, request.amount)
    return True
예제 #3
0
def deposit(request):
    """:return True on success, False otherwise"""
    if not check_account_name_exists(request.account):
        return False
    account = accounts[request.account]
    if not check_pin(request, account):
        return False
    if request.amount <= Balance(0):
        eprint("amount {} must be larger than 0.00".format(request.amount))
        return False
    account.balance += request.amount
    return True
예제 #4
0
def process_request(request):
    """:returns True on success, False on failure"""
    if request.command == "n":
        return accounting.create_new_account(request)
    if request.command == "g":
        return accounting.check_balance(request)
    if request.command == "w":
        return accounting.withdraw(request)
    if request.command == "d":
        return accounting.deposit(request)
    eprint("Invalid command '" + request.command +
           "'. This shouldn't happen...")
    return False  # this should never happen
예제 #5
0
def withdraw(request):
    """:return True on success, False otherwise"""
    if not check_account_name_exists(request.account):
        return False
    account = accounts[request.account]
    if not check_pin(request, account):
        return False
    if request.amount <= Balance(0):
        eprint("amount {} must be larger than 0.00".format(request.amount))
        return False
    if account.balance < request.amount:
        eprint("balance '{}' not sufficient to withdraw amount '{}'".format(
            account.balance, request.amount))
        return False
    account.balance -= request.amount
    return True
예제 #6
0
 def exit_gracefully(signum, frame):
     eprint("received SIGINT or SIGTERM, terminating gracefully...")
     if conn is not None:
         conn.close()
     s.close()
     sys.exit(0)
예제 #7
0
def input_error_exit():
    eprint("input error exit 255")
    sys.exit(255)
예제 #8
0
    if request.command == "g":
        return accounting.check_balance(request)
    if request.command == "w":
        return accounting.withdraw(request)
    if request.command == "d":
        return accounting.deposit(request)
    eprint("Invalid command '" + request.command +
           "'. This shouldn't happen...")
    return False  # this should never happen


if __name__ == '__main__':

    args = arguments.read_bank_arguments(sys.argv[1:])
    if args is None:
        eprint("parsing of bank arguments failed, terminating...")
        input_error_exit()
    (port, auth_filename) = args
    if port is None:
        port = constants.DEFAULT_PORT
    if auth_filename is None:
        auth_filename = "bank.auth"

    key = encryption.create_random_key()
    eprint("bank key (base64): " + base64.b64encode(key).decode("utf-8"))
    auth_file = open(auth_filename, "wb")
    auth_file.write(key)
    auth_file.close()
    myprint("created")

    conn = None
예제 #9
0
def check_account_name_exists(account_name):
    """:returns True on success, False on failure"""
    if account_name not in accounts:
        eprint("account name '{}' doesn't exists".format(account_name))
        return False
    return True
예제 #10
0
def main():
    args = arguments.read_atm_arguments(sys.argv[1:])
    if args is None:
        eprint("parsing ATM arguments failed. terminating...")
        input_error_exit()
    (auth_filename, ip_address, port, card_filename, account_name, command,
     amount) = args
    if ip_address is None:
        ip_address = "127.0.0.1"
    if port is None:
        port = constants.DEFAULT_PORT
    if card_filename is None:
        card_filename = account_name + ".card"
    if auth_filename is None:
        auth_filename = "bank.auth"
    pin, key = None, None

    try:
        if command != "n":
            card_file = open(card_filename, 'r')
            pin = card_file.read()
            card_file.close()
        else:
            if os.path.isfile(card_filename):
                eprint("card file already exists:", card_filename)
                input_error_exit()
            pin = my_base64encode(encryption.create_random_key())
        auth_file = open(auth_filename, 'rb')
        key = auth_file.read()
        eprint("atm key (base64): " + base64.b64encode(key).decode("utf-8"))
        auth_file.close()
    except IOError as e:
        eprint(e)
        input_error_exit()

    request = Request.Request(account_name, pin, command, amount)

    s = socket.socket()
    s.settimeout(10)

    try:
        s.connect((ip_address, port))
        data_to_send = str(request)
        eprint("atm, sending (decrypted): " + data_to_send)
        encrypted_data_to_send = encryption.encrypt_message(data_to_send, key)
        eprint("atm, sending " + str(len(encrypted_data_to_send)) +
               " bytes, (encrypted)")
        s.send(encrypted_data_to_send)
        received_data = s.recv(BUFFER_SIZE)
        if not received_data:
            s.close()
            protocol_error_exit()
        decrypted_data = encryption.decrypt_message(received_data, key)
        if decrypted_data is None:
            s.close()
            protocol_error_exit()
        else:
            if decrypted_data == constants.FAILURE:
                eprint("received FAILURE code from bank. terminating...")
                s.close()
                input_error_exit()
            else:  # success
                eprint("received JSON result from bank")
                myprint(decrypted_data)
                if command == "n":
                    card_file = open(card_filename, 'w')
                    card_file.write(pin)
                    card_file.close()
    except Exception as e:
        eprint("socket error:", e)
        s.close()
        protocol_error_exit()
예제 #11
0
def protocol_error_exit():
    eprint("protocol error exit 63")
    sys.exit(63)