input hidden string via sys.argv in python - python

I need to input the password via the command line and use it in the program via sys.argv[2].
The problem with CLI is that the password is displayed in clear text.
Below is the code :
import sys
user_args = sys.argv[1:]
username, password = user_args
print username
print password
Take a look :

You can use the getpass module (https://docs.python.org/3.5/library/getpass.html)
import getpass
password = getpass.getpass('Enter password: ')

Related

How to change the text being inputted turn to '*' in python?

how do I change the text to * while it is being inputted, like:
#Think that the code below is running in the console and I am
#inputting in it
Password: Example # How do make it turn it to '*******' while it is still being written?
Yup, i am not forced to only input, I can type in any command, please just tell me how to.
And you can tell tk code too
use the getpass module -
import getpass
getpass.getpass("Enter your password: ")
For tkinter entry, use the option show. Here is a code:
import tkinter as tk
root = tk.Tk()
passw = tk.Entry(root,show="*")
passw.grid(row=0,column=0)
passb = tk.Button(root,text="Print Password",command=lambda :print(passw.get()))
passb.grid(row=1,column=0)
root.mainloop()
To get password in console, you will have to modify the module getpass (Try at your own risk). Go to your python folder and open folder Lib. Open the file getpass.py and go to line 98 (there will be a function naming win_getpass)
Replace the whole function (win_getpass) with (lines:98-119) (Updated):
def win_getpass(prompt='Password: ', stream=None,show=""):
"""Prompt for password with echo off, using Windows getch()."""
if sys.stdin is not sys.__stdin__:
return fallback_getpass(prompt, stream)
for c in prompt:
msvcrt.putwch(c)
pw = ""
while True:
c = msvcrt.getwch()
if c == '\r' or c == '\n':
break
if c == '\003':
raise KeyboardInterrupt
if c == '\b':
pw = pw[:-1]
if pw != "":msvcrt.putwch("\b");msvcrt.putwch(" ");msvcrt.putwch("\b")
else:
pw = pw + c
msvcrt.putwch(show)
msvcrt.putwch('\r')
msvcrt.putwch('\n')
return pw
Now you can use the getpass function as:
import getpass
getpass.getpass("Enter your password: ",show="*")
You can change the value of show to whatever you want to show. Default is empty (means hide).
Note:
getpass will only work in console. It will raise error in IDLE.
Screenshot:

pexpect - how to pass in password using events

In this snipper I'm trying to pass the password as an event, why does the following not work?
password = input("INPUT PASSWORD: ")
pexpect.run("ssh -lX user#gmail.com 'ls -l'",
events={'(?i)password':' \n'}, password)
Based on the examples provided by the documentation for pexpect, it looks like you should be passing the password on as part of the value of '(?i)password'.
from pexpect import *
run('scp foo user#example.com:.', events={'(?i)password': mypassword})
In your case this would translate to this.
pexpect.run(
"ssh -lX eandersson#my-server.com 'ls -l'",
events={'(?i)password': '%s\n' % password}
)
A more complete example using getpass to hide the password would look like this.
import pexpect
import getpass
password = getpass.getpass('Password: ')
print pexpect.run(
"ssh -lX eandersson#10.0.1.1 'ls -l'",
events={'(?i)password': '%s\n' % password}
)

Python:Hide Password

everytime it shows my PASS in this way cmd 'PASS XXXXXX'.How can I stop it showing my PASS? Here is my code.Everyone knows how to do it?
import os, sys, string
import poplib
import getpass
host = "pop3.163.com"
username = raw_input('Username:')
pp = poplib.POP3(host)
pp.set_debuglevel(1)
pp.user(username)
pp.pass_(getpass.getpass())
action =""
if len(sys.argv) > 1:
action = sys.argv[1]
if action == 'stat':
ret = pp.stat()
print ret
# sys.exit()
else:
print "I dont know this command"
Quite simply, it's because you've asked the POP3 lib to give you debugging output. Some of what it's included appears to be the password that's being sent to the server. To avoid this, you should simply omit your log level set (the documentation says the default level is 0 -> no output), or explicitly set it to 0.
When you use getpass you need to save it in a variable or else, in the command line at least, it will print out the password:
>>> import getpass
>>> getpass.getpass()
Password:
'password'
>>> pword = getpass.getpass()
Password:
>>> pword
'password'

Python prompt for user with echo and password without echo

Following code prompts for user and password, when run in console:
import getpass
user = getpass.getpass("Username:")
passwd = getpass.getpass("Password for " + user + ":")
print "Got", user, passwd
The obvious problem with above is, user name is not echoed as it is typed.
Now getpass documentation says "On Unix it defaults to using /dev/tty before falling back to sys.stdin and sys.stderr."
Question: How to ask for both username and password, so that they are read from same source, and username is echoed normally, while password is not?
Why not just use raw_input for the username:
import getpass
user = raw_input("Username:")
passwd = getpass.getpass("Password for " + user + ":")
print("Got", user, passwd)
Demo:
Username:iCodez
Password for iCodez:
('Got', 'iCodez', 'secret')
There is another alternative, which I found documented here. Detect whether the input stream is a TTY, and change your input method based on that information.
I used something like this:
#!/usr/bin/python
import sys
import getpass
if sys.stdin.isatty():
print "Enter credentials"
username = raw_input("Username: ")
password = getpass.getpass("Password: ")
else:
username = sys.stdin.readline().rstrip()
password = sys.stdin.readline().rstrip()
print "Username: [%s], password [%s]" % (username, password)
This works fine from a terminal:
bash> ./mytest.py
Enter credentials
Username: one
Password:
Username: [one], password [two]
for piped input:
bash> echo "one
> two" | ./mytest.py
Username: [one], password [two]
for input from a file:
bash> echo "one" > input
bash> echo "two" >> input
bash> ./mytest.py < input
Username: [one], password [two]
and also for a heredoc:
bash> ./mytest.py << EOF
> one
> two
> EOF
Username: [one], password [two]
Personally, that covers all of my needs.
In Python 2.x, use raw_input (input in Python 3.x) instead of getpass.getpass for username.
user = raw_input("Username:")
It would be possible to use raw_input (input in Python 3) but as already mentioned in the question, getpass is using /dev/tty before falling back to sys.stdin and sys.stderr. This means that in some situations getpass and raw_input is using different sources.
On linux, you might see the difference by executing the application with the following command:
my_app.py < /path/to/some/file
The function raw_input would read from the file while getpass would still use the terminal. Even if it is not documented explicitly, the same is happening on Windows.
I have not found a function that is doing something like getpass without hiding the input. I think you have to implement it yourself or search for a library which is doing it. You can look at the current implementation of getpass in Python 3 and in Python 2.7 to get some inspiration.
I wrote an exmaple below. Basically, I used the implementation of Python 3 and removed everything that is related to hiding the input. Then, I made some changes to support Python 2.
def _raw_input(prompt, fin, fout):
if prompt:
try:
fout.write(prompt)
except UnicodeEncodeError:
# Replace characters that are not supported by the terminal
prompt = prompt.encode(fout.encoding, 'replace')
prompt = prompt.decode(fout.encoding)
fout.write(prompt)
fout.flush()
line = fin.readline()
return line[:-1] if line[-1] == '\n' else line
def _ttyinput_unix(prompt):
try:
fd = os.open("/dev/tty", os.O_RDWR, os.O_NOCTTY)
if sys.version_info < (3, 0):
with os.fdopen(fd, 'w+', 1) as tty:
return _raw_input(prompt, tty, tty)
with io.FileIO(fd, 'w+') as tty:
with io.TextIOWrapper(tty) as wrapper:
return _raw_input(prompt, wrapper, wrapper)
except (OSError, AttributeError) as e:
return _raw_input(prompt, sys.stdin, sys.stderr)
def _ttyinput_win(prompt):
if sys.stdin is not sys.__stdin__:
# I don't know why getpass is doing this.
return _raw_input(prompt, sys.stdin, sys.stderr)
if sys.version_info >= (3, 0):
getch = msvcrt.getwch
putch = msvcrt.putwch
else:
getch = msvcrt.getch
putch = msvcrt.putch
for c in prompt:
putch(c)
password = ""
while True:
c = getch()
if c == '\r' or c == '\n':
break
if c == '\003':
raise KeyboardInterrupt
if c == '\b':
if len(password) > 0:
password = password[:-1]
for x in "\b \b":
putch(x)
else:
password += c
putch(c)
putch('\r')
putch('\n')
return password
try:
import msvcrt
ttyinput = _ttyinput_win
except ImportError:
ttyinput = _ttyinput_unix
I tested my implementation with Python 2.7 on Windows and with Python 2.7 and 3.5 on Arch Linux.
try this:
user = raw_input("Username:")

is there a way to script in Python to change user passwords in Linux? if so, how?

I'm trying to write some scripts in Python and stumbled upon the need of making something to update the password of a given user in a Linux system...
UPDATE: the objective is to achieve the script to update the password automatically from a given data/algorithm. The important thing is to have no human intervention...
is there a way to achieve that? or should I search through other means?
Thanks!
You can use openssl and usermod:
#!/usr/bin/env python
import subprocess
login = 'username'
password = 'somepassword'
# OpenSSL doesn't support stronger hash functions, mkpasswd is preferred
#p = subprocess.Popen(('openssl', 'passwd', '-1', password), stdout=subprocess.PIPE)
p = subprocess.Popen(('mkpasswd', '-m', 'sha-512', password), stdout=subprocess.PIPE)
shadow_password = p.communicate()[0].strip()
if p.returncode != 0:
print 'Error creating hash for ' + login
r = subprocess.call(('usermod', '-p', shadow_password, login))
if r != 0:
print 'Error changing password for ' + login
You can use crypt to do the password hashing instead of using openssl passwd (where you are passing the password in plaintext in the command line)
Adapting Juliusz script:
#!/usr/bin/env python
import subprocess,crypt,random
login = 'username'
password = 'somepassword'
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
salt = ''.join(random.choice(ALPHABET) for i in range(8))
shadow_password = crypt.crypt(password,'$1$'+salt+'$')
r = subprocess.call(('usermod', '-p', shadow_password, login))
if r != 0:
print 'Error changing password for ' + login
This way, the password is only passed in the command line already hashed (to usermod).
I've tested this with ubuntu+python2.6.6+pycrypto2.5.
I just needed to do this again today, and below is my solution. It is fully automatic, and also uses standard system passwd binary, so system policies are respected.
#!/usr/bin/python3
username = 'joe'
# generate passphrase
pw_length = 6
phrase = subprocess.check_output(['pwgen', str(pw_length), '1'])
phrase = phrase.decode('utf-8').strip()
dev_null = open('/dev/null', 'w')
passwd = subprocess.Popen(['sudo', 'passwd', user], stdin=subprocess.PIPE,
stdout=dev_null.fileno(),
stderr=subprocess.STDOUT)
passwd.communicate( ((phrase + '\n')*2).encode('utf-8') )
if passwd.returncode != 0:
raise OSError('password setting failed')
(This generated the password too. Skip the first part if not useful.)
Use subprocess to invoke passwd.

Categories