I would like to use Fabric to set the password for a user on a remote server.
Let's say I have a user named 'john' and I want to set a default password '123' for him.
Ideally I would like to do this:
run 'passwd john' on remote machine
detect when linux prompts for 'Enter new UNIX password:'
automatically enters the password
detect when linux prompts for 'Retype new UNIX password:'
automatically reenters the password
This is what I have tried:
result = run('passwd {}'.format(username))
The problem with this statement is that 'result' does not capture when Linux prompts for entering password. It only returns after the passwords are entered.
Is there a way to automate interactive prompts like this?
you can use prompts
password = '123'
with settings(prompts={
'Enter new UNIX password: ': password,
'Retype new UNIX password: ': password
}):
run('passwd {}'.format(username))
You can use fexpect for interactive prompts.
Related
I had a problem entering the password directly through the python program
When I do something in PostgreSQL, it asks for a database password and here
How can I enter the database password through python so that it is entered in the requested field
pg_dump.exe -U dbuser -h localhost dbname >> s.sql
>>>Password:
I know that there is a .pgpass file, but there is a possibility of frequent password changes
i am trying to automate the log-in function for a device that i communicate with through serial. In order to reach the login: prompt i got to press enter while the device boots and then after sometime the login: prompt will show up, once it the program spots the 'login:' string it enter the username(or at least that's the plan). After entering the correct username the Password: prompt will show up, if i enter the correct password i successfully log-in to the device, if i enter the wrong password i have to start over(which means to enter the username again). Also if i fail to log-in in the first try the login: prompt changes to username:.
I have made this till now, but
import serial
import re
from time import sleep
import time
ser = serial.Serial('COM3', timeout=1)
ser.baudrate = 115200
def auto_login():
while True:
output = ser.read(10000).decode('utf-8', 'ignore')
testmode_command = ser.write("\r\n".encode())
print(output)
if "1 : press [Enter] for test mode / [Esc+Enter] for plain Linux" in output:
ser.write(testmode_command)
if " login:" in output:
break
def login_repeat():
login = b"root \r\n"
output = ser.read(10000).decode('utf-8', 'ignore')
print(output)
if " login:" in output:
ser.write(login)
if "Username:" in output:
ser.write(login)
def pass_word():
password = b"p \r\n"
time.sleep(0.1)
output = ser.read(10000).decode('utf-8', 'ignore')
print(output)
if "Password:" in output:
ser.write(password)
The result i am getting is :
Login incorrect
Username:
root
System starting up, please try later
Login incorrect
Username:
root
For some reason i looks like the enter is sent first the \r\n command instead of the username and then the command. Any idea how to resolve this?
Add time.sleep(0.1), before you send a command, like this :
time.sleep(0.1)
ser.write(b"root")
time.sleep(0.1)
ser.write('\r'.encode())
Just as a hunch, are you sure, you have no buffering issues. I don't know the serial module but it might be possible that the library sends the "Enter" together with the login information.
That would result in "Enter" as user name.
Quick searching brought up this answer: https://stackoverflow.com/a/12892221/4252584
You might try to explicitly flush the buffers.
On the other hand I am wondering why you get to the login prompt without prior "Enter" key on the serial line. Are you sure, you need the "Enter" key on the line?
I am trying to write a python script which uses scp to log into a HPC cluster (where I have an account) and transfer files from the cluster to my local system. I am able to os.system() to type the scp command. But, after that, I am a bit confused about what I must do when I am asked for the password (assume my password is password). I have tried os.system('password') and print 'password', but they don't work.
This is the python script that I have written:
import os
import sys
password = 'password'
clusterpath = 'myname#cluster.hpc1.cs.univ.edu:/Projects/re* '
localpath = 'Projects/.'
os.system('scp ' + clusterpath + localpath)
When I execute this script, I am asked for the password of my cluster. How can I enter the password of the cluster account through this python script?
Essentially, I need to access a computer, say machine A, which is only accessible via the internal network of my company. I used to be able to set up tcprelay port forwarding to accomplish this but that pipeline has been disabled due to some potential security flaws.
Let’s say my company general network is at
company#10.0.0.1
and the specific machine i want to work with is at
machine#10.0.0.3
Both accounts have password ‘password’
Via terminal and shell commands, I can just hop there using one single command:
https://askubuntu.com/a/311457
or, in steps, it would be:
[on my account] ssh company#10.0.0.1
[on my account] enter password
[on company network] ssh machine #10.0.0.3
[on company network] enter password again
And I’d be logged into the machine I need to communicate with.
However, after hacking away all afternoon I could not get this working with Paramiko. I tried setting up the connection then issuing a client.exec_command() but just cannot get a handle for the specific machine. The rest of my scripts relies on having a paramiko client that can receive commands and return responses, so it would be a very heavy overhead for me to go propagate all changes were I to switch to say fabric or subprocess.
The closest I got to was:
ssh.connect(’10.0.0.1', username=‘company', password=‘password’)
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.exec_command(‘ssh machine#10.0.0.3’)
print chan.recv(1024)
which returned the ‘enter password’ prompt, but running chan.send(‘password’) just ends with a hang.
I’m pulling my hair out at this point and am just reading through the documentation hoping to find what concept I’m missing.
If anyone can give some advice I’d really appreciate it.
Thanks!
Alternative way is to avoid entering password when login to another machine.
This can be done by using ssh-keygen.
Login to first machine (A) with user 'first':
$ ssh-keygen -t rsa
--> Don't enter any passphrase when requested
--> Note down the line "Your public key has been saved in /home/first/.ssh/"
--> This file is the public key of machine 'A'
Now login to second machine(B) using ssh.
Then check for ~/.ssh folder. If no folder, create one.
Create a file with name 'authorized_keys' under ~/.ssh/authorized_keys
Copy the content of file from 'first' user to the file 'authorized_keys'.
is a file with 'id_rsa.pub' from 'first' user login (under /home/first/.ssh/id_rsa.pub)
Now you can login to second machine from first without entering password thru your script.
I worked on a project where it had to log in using username/password over SSH then do the same thing again to another host. I had no control over networks ACLs and SSH keys were not allowed for some reason. You'll need to add paramiko_expect. Here's how I got it to work:
import paramiko
from paramiko_expect import SSHClientInteraction
user1 = 'admin'
pass1 = 'admin'
user2 = 'root'
pass2 = 'root'
# not needed for this example, but included for reference
user_prompt = '.*\$ '
# will match root user prompt
root_prompt = '.*$ '
# will match Password: or password:
pass_prompt = '.*assword: '
# SSH to host1
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
ssh_client.connect(hostname='host1', username=user1, password=pass1)
# Interact with SSH client
with SSHClientInteraction(ssh_client, display=True) as interact:
# Send the command to SSH as root to the final host
interact.send('ssh {}#host2'.format(user2)
# Expect the password prompt
interact.expect(pass_prompt)
# Send the root password
interact.send(pass2)
# Expect the root prompt
interact.expect(root_prompt)
ssh_client.close()
One caveat: if host1 has never connected to host2 using SSH it'll get a warning about host key checking and timeout. You can change the configuration on host1 or just SSH to host1 then from host1 SSH to host2 and type yes and press enter.
I need to connect to a remote server using a (non-python) script from terminal.
$./myscript <parameters>
Normally, I would need to enter the password. I have the following question, assuming a python script will run myscript:
How do I get the password from the user
How do I feed it into myscript?
If I understand the question correctly you would probably use the getpass function.
import getpass
password = getpass.getpass()
print 'You entered:', password
The major advantage is that the password will not be visible on the screen as the user enters it.
If you simply want to pass in arguments to your application you can use sys.argv.
import sys
if len(sys.argv) > 1:
print "First argument:", sys.argv[1]
If you need to pass on a password to a script executed by Python you can use subprocess call.
import getpass
import subprocess
password = getpass.getpass()
subprocess.call(["myscript", password ])