This is my python function that creates the htpasswd file and adds the username and password in it .
def __adduser(self, passfile, username):
command=["htpasswd", "-c", passfile, username]
execute=subprocess.Popen(command, stdout=subprocess.PIPE)
result=execute.communicate()
if execute.returncode==0:
return True
else:
#will return the Exceptions instead
return False
It is working great but the only improvement I want is, how to
automate the password entry it ask for after running the scripts that should be set from some variable value
htpasswd has an -i option:
Read the password from stdin without verification (for script usage).
So:
def __adduser(self, passfile, username, password):
command = ["htpasswd", "-i", "-c", passfile, username]
execute = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
execute.communicate(input=password)
return execute.returncode == 0
Use bcrypt python module to create a password
import bcrypt
def encrypt_password(username, password):
bcrypted = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt(rounds=12)).decode("utf-8")
return f"{username}:{bcrypted}"
print(encrypt_password("client", "ClientO98"))
Read more from https://gist.github.com/zobayer1/d86a59e45ae86198a9efc6f3d8682b49
Related
Need help in calling .bat file via python in windows server.
Currently the .bat file is used to encrypt the password and generate password file .
when the admin run this .bat file, they ll execute below command
runbatch.bat filename
On executing the above it prompt us to enter password
....Enter the password to encrypt
On entering the password it generate the password file in the specified folder.
Now the requirement is to call this .bat file via python.
Reason behind this to create an API and give option to user to generate the password file from their end. When user tries to generate the password file it prompts for password and password file name and passes those parameters to python script which in return calls a .bat file
I am not sure how to echo password input as we do directly in cmd.
Echo password| runbatch.bat filename
In python I have defined .bat location on os.dir and using popen subprocess option to run the.bat` but not sure how to pass password to the command.
import sys
import os
import subprocess
sPassword = $Password
sPasswordFile = $PasswordFile
sInstance = "D:/API/bin" os.chdir(sInstance)
ScriptName = sInstance + "/encryptpassword.bat"
command = '%s "%s"' % (ScriptName, sPasswordFile)
p = subprocess.Popen(command) retcode = p.wait()
Any help will be highly appreciated.
I am trying to login as a user using pexpect and trying to print all the crons available :
import pexpect
import os, time
passwd = "mypass"
child = pexpect.spawn('su myuser')
child.expect('Password:')
child.sendline(passwd)
child.expect('$')
child.sendline('crontab -l')
i =child.expect(['%','.*$', '$' ])
print i # prints 1 here so, the shell is expected.
print child.before # this doesn't print anything though.
This code doesn't seem to be working and prints empty line.
Couldn't figure out the issue with this code
If there is any better way to list cron job of other user, given username and password
Any pointers or suggestions would be much appreciated.
If you can arrange to configure password-less sudo access, then the above simply becomes:
import subprocess
output = subprocess.check_output('sudo -u myuser crontab -l', shell=True)
If you need to continue using su, then you can pass it a command and avoid trying to parse shell prompts:
import pexpect
passwd = "mypass"
child = pexpect.spawn('su myuser -c "crontab -l"')
child.expect('Password:')
child.sendline(passwd)
child.expect(pexpect.EOF)
print child.before
Related questions that are essentially asking the same thing, but have answers that don't work for me:
Make python enter password when running a csh script
How to interact with ssh using subprocess module
How to execute a process remotely using python
I want to ssh into a remote machine and run one command. For example:
ssh <user>#<ipv6-link-local-addr>%eth0 sudo service fooService status
The problem is that I'm trying to do this through a python script with only the standard libraries (no pexpect). I've been trying to get this to work using the subprocess module, but calling communicate always blocks when requesting a password, even though I supplied the password as an argument to communicate. For example:
proc = subprocess.Popen(
[
"ssh",
"{testUser1}#{testHost1}%eth0".format(**locals()),
"sudo service cassandra status"],
shell=False,
stdin=subprocess.PIPE)
a, b = proc.communicate(input=testPasswd1)
print "a:", a, "b:", b
print "return code: ", proc.returncode
I've tried a number of variants of the above, as well (e.g., removing "input=", adding/removing subprocess.PIPE assignments to stdout and sterr). However, the result is always the same prompt:
ubuntu#<ipv6-link-local-addr>%eth0's password:
Am I missing something? Or is there another way to achieve this using the python standard libraries?
This answer is just an adaptation of this answer by Torxed, which I recommend you go upvote. It simply adds the ability to capture the output of the command you execute on the remote server.
import pty
from os import waitpid, execv, read, write
class ssh():
def __init__(self, host, execute='echo "done" > /root/testing.txt',
askpass=False, user='root', password=b'SuperSecurePassword'):
self.exec_ = execute
self.host = host
self.user = user
self.password = password
self.askpass = askpass
self.run()
def run(self):
command = [
'/usr/bin/ssh',
self.user+'#'+self.host,
'-o', 'NumberOfPasswordPrompts=1',
self.exec_,
]
# PID = 0 for child, and the PID of the child for the parent
pid, child_fd = pty.fork()
if not pid: # Child process
# Replace child process with our SSH process
execv(command[0], command)
## if we havn't setup pub-key authentication
## we can loop for a password promt and "insert" the password.
while self.askpass:
try:
output = read(child_fd, 1024).strip()
except:
break
lower = output.lower()
# Write the password
if b'password:' in lower:
write(child_fd, self.password + b'\n')
break
elif b'are you sure you want to continue connecting' in lower:
# Adding key to known_hosts
write(child_fd, b'yes\n')
else:
print('Error:',output)
# See if there's more output to read after the password has been sent,
# And capture it in a list.
output = []
while True:
try:
output.append(read(child_fd, 1024).strip())
except:
break
waitpid(pid, 0)
return ''.join(output)
if __name__ == "__main__":
s = ssh("some ip", execute="ls -R /etc", askpass=True)
print s.run()
Output:
/etc:
adduser.conf
adjtime
aliases
alternatives
apm
apt
bash.bashrc
bash_completion.d
<and so on>
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.
How do I create a user in Linux using Python? I mean, I know about the subprocess module and thought about calling 'adduser' and passing all the parameters at once, but the 'adduser' command asks some questions like password, full name, phone and stuff. How would I answer this questions using subprocess?
I've seen module called pexpect in this question: Can I use Python as a Bash replacement?. Is there any other standard module?
Use useradd, it doesn't ask any questions but accepts many command line options.
On Ubuntu, you could use the python-libuser package
import os
import crypt
password ="p#ssw0rd"
encPass = crypt.crypt(password,"22")
os.system("useradd -p "+encPass+" johnsmith")
You could just use the built-in binaries so just call useradd or something through the subprocess module, However I don't know if there's any other modules that hook into Linux to provide such functionality.
def createUser(name,username,password):
encPass = crypt.crypt(password,"22")
return os.system("useradd -p "+encPass+ " -s "+ "/bin/bash "+ "-d "+ "/home/" + username+ " -m "+ " -c \""+ name+"\" " + username)
This is a solution where shell is false.
#!/bin/env/python
import subprocess
import traceback
import sys
def user_add(username, user_dir=None):
if user_dir:
cmd = ["sudo", "useradd", "-d", user_dir, "-m", username]
else:
cmd = ["sudo", "useradd", username]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
output = output.strip().decode("utf-8")
error = error.decode("utf-8")
if p.returncode != 0:
print(f"E: {error}")
raise
return output
try:
username = "user"
output = user_add(username)
print(F"Success. {username} is added")
except:
traceback.print_exc()
sys.exit(1)