cant break the loop in my socket properly - python

I've created a socket with a login system. The code below is my login class on my client system. it receives the message login successful or username/password incorrect. the print statement shows that this is getting through fine from the server so my issue isn't there or on the server part. when a password is wrong it starts back to login which is what I want it to do.the issue is when it's a correct login. the server will send login successfully and that will print but it won't break out of the loop and will just continue to ask for my username and password.
def login():
username = str(input("Please enter your username to login: "))
password = str(input("Please enter your password to login: "))
joint =(username+password)
message = hashPW(joint)
s.send(message.encode())
ls = s.recv(1024)
print(ls)
while ls != "Login successfull":
login()
else:
after_choice()
server code: I don't think this is where the problem lies. I'm pretty sure it's with the client and me being unable to break it out of the loop properly or something but I figured id add it anyway to help.
def recive():
password = c.recv(1024).decode()#reciving the password
print("Password from client: ", password)
PWcheck()
def PWcheck():
f= open("passwords.txt")
f1=f.readlines()
if password in f1:
print("Login successfull")
ls =("Login successfull")
c.send(ls.encode())
wait() #just the next class
else:
print("Username or password incorrect")
ls =("Username or password incorrect")
c.send(ls.encode())
recive()
if anyone needs more code adding i can. any help would be greatly appreciated.

Related

My login system will not work - regardless of any user passwords entered

My sign up and login authentication system is not working as it is supposed to. My signup issue was fixed, but my login has a problem. Either the code will let me go through and access the account, or it will not, depending on the code. But anytime I try to fix it, the output is one of the two options. ALWAYS, regardless of the password I enter.
The usernames and passwords are stored in a txt file, like this:
John Appleseed:hisSuperSecretPassword
JohnDoe:1234
The login code:
found = False
username = input("Enter your username:\n")
file = open("account.txt", "r+")
for line in file:
if line.split(':')[0] == username:
found = True
if found == True:
password = input("Enter your password:\n")
for counter, line in enumerate(file):
if line.strip() == username + ":" + password:
print("You have signed in.")
else:
print("Password incorrect. Program closing.")
sys.exit()
else:
print("Username not valid.")
sys.exit()
Can anyone help? Running Python 3.9.2.
Here is something I've adjusted to work....
import sys
found = False
username = input("Enter your username:\n")
file = open("account.txt", "r+")
for line in file:
if line.split(':')[0] == username:
account_details = line.split(':')
found = True
if found == True:
password = input("Enter your password:\n")
if account_details[1].strip() == password:
print("You have signed in.")
else:
print("Password incorrect. Program closing.")
sys.exit()
else:
print("Username not valid.")
sys.exit()
You are exiting the program as soon as you find a non-matching password, instead of comparing the password to the correct user. You also don't need to re-read the entire password file: you already found the expected password when you verified that the user name existed.
As an aside, there's no sense confirming for an attacker that they have correctly guessed a user name. Just get the user name and password first, then look for them in the password file.
username = input("Enter your username:\n")
password = input("Enter your password:\n")
with open("account.txt") as fh:
if any(f'{username}:{password}' == line.strip() for line in fh):
print("You have signed in.")
else:
print("Invalid username or password, exiting")
sys.exit()

How can I fix this infinite loop caused by my function in Python?

I've seemed to create a bank account log in system that works correctly. The only problem is that once a login is successful, the program would get stuck in a loop. For example: Say, I create my account and set my username as "Hello" and my password as "123".
The program will except these log in details but when I later try to log in with them, the infinite loop would happen.
I've tried amending this problem by plugging in return/global values for status and even put them in as many places in my program as possible but the infinite loop problem still persists. Could you please help me find why the loop keeps executing?
users = {}
status = ""
#--------------- Login menu -----------------#
def displayMenu():
global status
status = input("Are you a registered user? \n1 - Yes \n2 - No \nQ - Quit \n")
if status == '1':
oldUser()
elif status == '2':
newUser()
return status
def mainMenu():
print("Hello account holder", login,"what service would you like to use today?")
#---------- Screen for new users -------------#
def newUser():
createLogin = input("Create login name: ")
if createLogin in users: # check if login name exists
print ("\nLogin name already exists!\n")
else:
createPassw = input("Create password: ")
users[createLogin] = createPassw # add login and password
print("\nAccount created!\n")
#---------- Screen for old users -------------#
def oldUser():
global login
login = input("Enter login name: ")
passw = input("Enter password: ")
# check if user exists and login matches password
if login in users and users[login] == passw:
print("\nLogin successful!\n")
mainMenu()
else:
print("\nUser doesn't exist or wrong password!\n")
# Main -------------------------------------------------------------------------------------------------------------
while status != "q":
status = displayMenu()
Your code is working exactly as it is designed.
The main loop starts:
while status != "q":
status = displayMenu()
Note that your program will only ever "quit" if the user gives an input of "q" in the displayMenu(), rather than "Q". This can be fixed by checking status.lower() instead.
Then you specify that no, you are not a registered user by providing 2 as an input to the displayMenu().
This brings you to newUser(), where you create your new account.
You'll then get returned to displayMenu(), where you can this time select 1 to login as a registered user, bringing you to oldUser().
Once you enter your login credentials in oldUser(), you'll get brought to mainMenu(), where it will print the welcome message in mainMenu(), then return to oldUser(), then to displayMenu(), then back to the main loop.
Unless you're expecting something else to happen in mainMenu(), the only error here is that you're not normalizing the case of status before checking if it is "q".

How to fix bad input in this block of code?

I am writing a small login script at school, but I'm having trouble with a certain line of code. Here is the full thing:
I have asked my teacher but she isn't quite sure herself.
#!/bin/python3
def login ():
username = input ('username')
password = input ('password')
if username == 'TestAcc'*
if password == 'spectretest':
print ('Welcome to the SpectreOS developer test system')
else print ('invalid password')
else print ('invalid username')
*I get an error message on this line and I am not sure of the problem. Thanks for your help. :)
Your code has several syntax issues, use the following:
def login ():
username = input ('username')
password = input ('password')
if username == 'TestAcc':
if password == 'spectretest':
print ('Welcome to the SpectreOS developer test system')
else: print ('invalid password')
else:
print ('invalid username')
Keep in mind that indentation in Python matters a lot. I strongly suggest you check more about Python's syntax. You can check many tutorials (articles, videos) out there in the web.

Python - Help needed with file reading

I am trying to create a simple login system. What I'm doing is storing the login data in a text file called 'accounts.txt'
Now, when user tires to login, it first checks if the username given by the user is in the 'accounts.txt'. If it exists, then it asks for the password and then checks if password matches with the password in 'accounts.txt'
fr = open('accounts.txt', 'r')
while True:
username = input('Enter your username: ') # Ask for their username
if username in fr.read(): # Check if username exists
password = input('Enter password: ') # Ask for password if username exists
if username+password in fr.read():
print('Welcome ' + username)
break
else:
print('Wrong password')
Note, the password save in accounts.txt is in the format of usernamepassword so if username is jack and password is gate, the actual password in the txt file will be jackgate, hence im using username+password to check if password is correct.
The problem occuring is if the user enters correct username, then program moves ahead properly but even if the password entered is right, it still displays 'Wrong password' .When the second time user enters username, it even shows error for wrong username. I tried to play with the code for a long time but couldn't come up with a solution. I guess it has something to do with fr.read(). Can I use that 'fr' object only once?
Let me suggest some improvements with my answer to your question. I would read the accounts file in its entirety so you have an in-memory structure. If you do this as a dictionary in the form accounts[USER] -> PASS you can easily check for any account as per the code below.
Regarding my suggestions (they do not exactly only answer your questions, but IMHO the topic of writing login code should be treated with care):
I strongly recommend not to store passwords in plain text, regardless of application importance, always use hashes.
Do not store just the password hash, always use salting.
Do not tell the person trying to log in, if the username or the password was wrong, always just say "that's not the right combination", thus making it harder to break in.
Please find information about hashing functions in Python here: https://docs.python.org/3/library/hashlib.html#randomized-hashing
This site has a good introduction on salting ans securing passwords: https://crackstation.net/hashing-security.htm
Do you users a favor and treat the username as no case-sensitive. That is a totally valid approach, but it annoys me every time I have to use such a site (just like email addr are not case-sensitive)
As I am a total layman regarding password security, maybe one of the other Stackoverflow users can jump in with a comment and expand on this topic.
Anyway, here is my answer for your question on how to check for a login. I created a function check_account() that returns True or False, depending on wether the supplied credentials were correct or not.
import hashlib
import os
import binascii
def check_account(usr, pwd):
# read the accounts file, a simple CSV where
# username, salt value and password hash are
# stored in three columns separated by a pipe char
accounts = {}
fr = open('/users/armin/temp/test.csv', 'r')
for line in [x.strip().split("|") for x in fr.readlines()]:
accounts[line[0].lower()] = (line[1], line[2])
fr.close()
# now go looking if we do have the user account
# in the dictionary
if usr in accounts:
credentials = accounts[usr]
# credentials is a list with salt at index 0
# and pwd hash at index 1
# generate the hash form the functions parameters
# and compare with our account
h = hashlib.blake2b(salt=binascii.unhexlify(credentials[0]))
h.update(pwd.encode('utf-8'))
if credentials[1] == h.hexdigest():
return True
else:
return False
else:
return False
def main():
while True:
username = input('Enter your username: ') # Ask for their username
password = input('Enter password: ') # Ask for password if username exists
if check_account(username.lower(), password):
print("Welcome, {0}".format(username))
else:
print('Username or password unknown')
if __name__ == '__main__':
main()
To create the data for a user account, use may this code.
def create():
username = input('Enter your username: ').lower() # Ask for their username
password = input('Enter password: ') # Ask for password if username exists
salt = binascii.hexlify(os.urandom(hashlib.blake2b.SALT_SIZE))
print("SALT value:", salt)
h = hashlib.blake2b(salt=binascii.unhexlify(salt))
h.update(password.encode('utf-8'))
print("Pwd hash:", h.hexdigest())
You can use startswith and endswith:
fr = [i.strip('\n') for i in open('accounts.txt')]
while True:
username = input()
if any(i.startswith(username) for i in fr):
password = input('Enter password: ')
if any(username+password == i for i in fr):
print("welcome")
break
else:
print("wrong password")
I would do
if password in fr.read():
instead of
if username+password in fr.read():
This is because for it to get to the if password in fr.read loop it first has to pass the if username in fr.read loop. However, the only problem I find with this is that if they enter a correct username but enter the wrong password for that username but correct password for another username it will still pass.
That is why I think you should use a dictionary not a text file.
For example, if the usernames allowed is username and username1 and the password is username and username1, then in a different .py file, you can say.
username_password={'username':'username','username1':'username1'}
that makes a dictionary that has the username and passwords.
let's say you name that file stuff.py. Then in the second file that has to be in the same directory, you can do
from stuff import * #imports all values from stuff.py
while True:
username = input('Enter your username: ') #gets username
if username_password.has_key(username):
password = input('Enter password: ')
if password== username_password[username]:
print('Welcome '+username)
break
else:
print('Wrong password')
break
else:
print('Wrong username')
I still don't get why you have a while loop, but if you want it, it is fine. Also, I added an else loop just in case the username is wrong.

Python: matching user names w/ password ; prompted for password if incorrect ;

I am trying to create a login.
I am not sure how to create/import a library of usernames and passwords; I am researching to find an answer at the moment but asked either way.
Match usernames with passwords (partially solved; need to add multiple usernames with matching passwords).
How to create a loop if password is incorrect? If incorrect password is entered the user needs to be prompted again to enter the password.
How to limit loop to certain number of attempts for password.
Below is what I have tried:
def check_password(user, password):
""" Return True if the user/pass combo is valid and False otherwise. """
# Code to lookup users and passwords goes here. Since the question
# was only about how to do a while loop, we have hardcoded usernames
# and passwords.
return user == "pi" and password == "123"
def login():
""" Prompt for username and password, repeatedly until it works.
Return True only if successful.
"""
try:
while True:
username = raw_input('username:')
password = raw_input('password:')
if check_password(username, password):
break
else:
print "Please try again"
print "Access granted"
return True
except:
return False
For testing: login().
This fixed lack of loop prompting if wrong password due to using return instead of print; and if instead of while.
def login():
#create login that knows all available user names and match to password ; if password is incorect returns try again and propmts for password again#
username = raw_input('username:')
if username !='pi':
#here is where I would need to import library of users and only accept those usernames; needs to be like 'pi' or 'bob' or 'tim'etc.
print'user not found'
username = raw_input('username')
password = raw_input('password:')
#how to match password with user? store in library ?
while password != '123':
print 'please try again' # You have to change the 'return' to 'print' here
password = raw_input('password')
return 'access granted'
#basically need to create loop saying 'try again' and prompting for password again; maybe smarter to ask limited number of
#times before returning 'you have reached limit of attempts#
if password == '123':
#again matching of passwords and users is required somehow
return 'access granted'
>>> login()
username:wronguser
user not found
usernamepi
password:wrongpass
please try again
password123
'access granted'
>>>
First attempt before updating thanks to Merigrim:
def login():
# Create login that knows all available user names and match to password;
# if password is incorect returns try again and propmts for password again#
username = raw_input('username:')
if username !='pi':
# Here is where I would need to import library of users and only
# accept those usernames; needs to be like 'pi' or 'bob' or 'tim'etc.
return 'user not found'
password = raw_input('password:')
# How to match password with user? store in library?
if password != '123':
return 'please try again'
password = raw_input('password:')
if password != '123':
return 'please try again'
# Basically need to create loop saying 'try again' and prompting
# for password again; maybe smarter to ask limited number of
# times before returning 'you have reached limit of attempts
elif password == '123':
# Again matching of passwords and users is required somehow
return 'access granted'
Here is how it currently works:
>>> login()
username:pi
password:123
'access granted'
>>> login()
username:pi
password:wrongpass
'please try again'
I need to create loop to prompt again for password.
What you want is the while statement.
Instead of nesting if-statements like this:
if password != '123':
return 'please try again'
password = raw_input('password:')
if password != '123':
return 'please try again'
elif password == '123':
return 'access granted'
You can do this:
while password != '123':
print 'please try again' # You have to change the 'return' to 'print' here
password = raw_input('password:')
return 'access granted'
This will continue prompting the user for a password until the right password is entered. If you want to become more familiar with the while statement, I suggest checking out some tutorials, like this one.
Please note that if you return something the function will exit there, so the user will never be prompted for a password. In the code above I changed the return to a print statement instead.
Here's another solution with the user name and password factored out, and an exception handler in case someone tries to abort the input.
Also, FYI it is best to take the user and password together so as not to let crackers know what is and is not a valid username.
def check_password(user, password):
""" Return True if the user/pass combo is valid and False otherwise. """
# Code to lookup users and passwords goes here. Since the question
# was only about how to do a while loop, we have hardcoded usernames
# and passwords.
return user == "pi" and password == "123"
def login():
""" Prompt for username and password, repeatedly until it works.
Return True only if successful.
"""
try:
while True:
username = raw_input('username:')
password = raw_input('password:')
if check_password(username, password):
break
else:
print "Please try again"
print "Access granted"
return True
except:
return False
# For testing
login()

Categories

Resources