I have modified the example python script:
service = 'passwd'
if len(sys.argv) == 3:
user = sys.argv[1]
password = sys.argv[2]
else:
print 'error'
auth = PAM.pam()
auth.start(service)
if user != None:
auth.set_item(PAM.PAM_USER, user)
auth.set_item(PAM.PAM_CONV, pam_conv)
try:
auth.authenticate()
auth.acct_mgmt()
except PAM.error, resp:
print 'Go away! (%s)' % resp
except:
print 'Internal error'
else:
print 'Good to go!'
This works, but asks me to input the password. I would like instead to verify the password which is passed as a parameter (sys.argv[2]). Documentation is non-existant, so how should I do it?
The example first lines are missing.
The provided 'pam_conv' function asks the password to the user.
You must define your own function returning a constant password:
def pam_conv(auth, query_list, userData):
return [(the_password,0)]
When I was finding solution for interactive password prompt, I only found this solution
python expect lib
Related
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.
I have a list of emails(mine) that I want to test against a list of passwords(All valid and some none valid of course) using imaplib library. Whenever I test the program ordinarily like in the code below, it works perfectly no errors.
import sys
import imaplib
# connect to host using SSL
imap_host = 'imap.server.com'
imap_port = '993'
imap_user = 'username#email'
imap_pass = 'RightPassword'
imap = imaplib.IMAP4_SSL(imap_host, imap_port)
## login to server
try:
login = imap.login(imap_user, imap_pass)
if login:
print login
except imaplib.IMAP4.error as error:
print error
#
But whenever I run the code such as to parsing credentials through a function to handle the authentication protocols such as the following code below, I get an error saying
"LOGIN command error: BAD ['Missing \'"\'']".
I have tried all sort of things I could find using google and non seem to handle it properly.
"""
E-mail Tester
NB: This is for educational purpose only.
"""
import sys
import imaplib
EMAILS_FILE = open('email_list.txt', 'r')
PASSWORD_FILE = open('pass_list.txt', 'r')
SUCCESS_FILE = open('success.txt', 'a')
EMAILS_FILE_LIST = []
def set_check(_emails):
email = str(_emails)
PASSWORD_FILE.seek(0)
for passwords in PASSWORD_FILE:
password = str(passwords)
# connect to host using SSL
imap_host = 'imap.server.com'
imap_port = '993'
imap = imaplib.IMAP4_SSL(imap_host, imap_port)
## login to server
try:
# print "%s%s" % (email,password)
# print "I got here so far"
# sys.exit()
print "Testing <--> E-mail: %s - Password: %s" % (email, password)
login = imap.login("%s","%s" % (email, password))
if login:
print login
print "OK <---> E-mail: %s\nPassword: %s" % (email, password)
except imaplib.IMAP4.error as error:
print error
for emails in EMAILS_FILE:
EMAILS_FILE_LIST.append(emails)
for email_count in range(0, len(EMAILS_FILE_LIST)):
set_check(EMAILS_FILE_LIST[email_count])
I have tried all kind of suggestions I could find on the internet but non has worked thus far.
I expect imap.login to handle the authentication without the mysterious error output
"LOGIN command error: BAD ['Missing \'"\'']"
login = imap.login("%s","%s" % (email, password))
does not work. It throws an error in Python: TypeError: not all arguments converted during string formatting, because you're providing two strings to one %s.
Why don't you just use imap.login(email, password)? It has the same effect as what you're trying to do.
And what does your password file look like? What is it actually sending? Please provide the log line before it crashes. (anonymizing if necessary, but leaving any punctuation in for help diagnosing)
Okay, so I actually got this fixed by removing trail lines from my strings.
email = str(_emails).rstrip()
PASSWORD_FILE.seek(0)
for passwords in PASSWORD_FILE:
password = str(passwords).rstrip()
the error is caused by trail lines in the strings.
I am trying to write a unit test in python that tests a username and password entry. I am using prompts for user input for both the username and password.
I have two separate functions that prompt the user for username and password. Both functions then check length. The password function also checks for exceptions, that were made by us, if the password length is zero. Are their ways to mock these exceptions?
I am struggling because I can get passed the username prompt but the pytest script holds after the username input. Is there a way to mock both username and password?
I am fairly new to python and I have looked through documentation but everything I have seen is usually for Python 3.x.x which we currently aren't implementing at this time. Any help would be much appreciated.
I think the init function is actually causing most of the headaches I am having. Is there a way around this?
class Login(object):
def __init__(self, args, env="test"):
created_token = self.login()
def login(self):
username = self.args.username
if len(username) == 0:
username = self._get_username()
password = self.args.password
if len(password) == 0:
password = self._get_password(username)
def _get_username(self):
return prompt('%s Username (%s): ' % (self.domain)
def _get_password(self):
if password is None:
password = prompt_sensitive('%s Password: ' % self.domain)
try:
except ParseError,e:
print "ParseError message"
except ClientError,e:
print "ClientError message"
You can use dependency injection to inject the prompt.
def password_function(input_func=None):
input_func = input_func or input
...
def test_password_function(self, ...):
fake_input = Mock()
...
result = password_function(fake_input)
This won't break existing code since the previous call signature is valid. e.g. password_function(). However if you don't have access to change the code then you can patch the input function.
import __builtin__
#mock.patch(__builtins__, 'input', return_value=...)
def test_password_function(self, mock_input):
Good Day.
Im trying to write a python script that will take a captured password then compare it
to the system shadowed password.
Im using Ubuntu 12.10 for this test. and running the script as sudo.
def login(user, password):
"Check if user would be able to login using password"
try:
pw1 = spwd.getspnam(user)[1]
allus = spwd.getspall()
print pw1
# pw2 = crypt.crypt(password, pw1[:2])
pw2 = crypt.crypt(password, '\$6\$SALTsalt\$')
print pw2
return pw1 == pw2
except KeyError:
return 0 # no such user
Now the above returns
2 diferent passwords but i do get the one from the shadowed.
So my question is how do i encrypt the supplied password so i can compare it to the
one retreived. Any Help would be awsome
Edit addon
def login(user, password):
"Check if user would be able to login using password"
try:
pw1 = spwd.getspnam(user)[1]
allus = spwd.getspall()
# print allus
print pw1
# pw2 = crypt.crypt(password, pw1[:2])
# pw2 = crypt.crypt(password, '\$6\$SALTsalt\$')
pw2 =hashlib.new()
pw2.update(password)
pw2.digest()
print pw2
return pw1 == pw2
except KeyError:
return 0 # no such user
That also did not work
How does one impliment the haslib to get the hash to match system password
I've made an example on how to authenticate using shadowed passwords. I added some comments to let the code speak for itself.
Some extra info:
https://en.wikipedia.org/wiki/Passwd#Shadow_file
http://docs.python.org/2/library/spwd.html
http://docs.python.org/2/library/crypt.html
Also note (from the crypt module docs):
This module implements an interface to the crypt(3) routine, which is a one-way hash function based upon a modified DES algorithm; see the Unix man page for further details. Possible uses include allowing Python scripts to accept typed passwords from the user, or attempting to crack Unix passwords with a dictionary.
Notice that the behavior of this module depends on the actual implementation of the crypt(3) routine in the running system. Therefore, any extensions available on the current implementation will also be available on this module.
This is also why you cannot use hashlib without problems.
import crypt # Interface to crypt(3), to encrypt passwords.
import getpass # To get a password from user input.
import spwd # Shadow password database (to read /etc/shadow).
def login(user, password):
"""Tries to authenticate a user.
Returns True if the authentication succeeds, else the reason
(string) is returned."""
try:
enc_pwd = spwd.getspnam(user)[1]
if enc_pwd in ["NP", "!", "", None]:
return "user '%s' has no password set" % user
if enc_pwd in ["LK", "*"]:
return "account is locked"
if enc_pwd == "!!":
return "password has expired"
# Encryption happens here, the hash is stripped from the
# enc_pwd and the algorithm id and salt are used to encrypt
# the password.
if crypt.crypt(password, enc_pwd) == enc_pwd:
return True
else:
return "incorrect password"
except KeyError:
return "user '%s' not found" % user
return "unknown error"
if __name__ == "__main__":
username = raw_input("Username:")
password = getpass.getpass()
status = login(username, password)
if status == True:
print("Logged in!")
else:
print("Login failed, %s." % status)
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()