0

I want to send a certificate to the remote server automatically with ssh-copy-id. I chose the python subprocess library for this, but somehow it does not send the password to the terminal.

I am aware that I can do this with sshpass or paramiko, but I don't want to choose it unless I have to. Can you help me with this? My code is below.

from subprocess import run,PIPE

send_cert = run(['ssh-copy-id', '-i', '~/.ssh/id_rsa.pub','pardus'], stdout=PIPE, input=input_cert, encoding='utf-8')
input_cert = '1'

pardus is my remote host's name. You can replace user@IP .

enter image description here

2 Answers2

2

~ is replaced with the home directory by the shell, but you're not executing the command through a shell, so it's being interpreted literally.

You can use the os.path.expanduser() function to perform this substitution.

import os
from subprocess import run,PIPE

send_cert = run(['ssh-copy-id', '-i', os.path.expanduser('~/.ssh/id_rsa.pub'),'pardus'], stdout=PIPE, input=input_cert, encoding='utf-8')
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 2
    @flakes No, it's correct. You send the public keys to the remote host, the private keys stay. The man page says that if the filename doesn't end in `.pub`, it adds it. – Barmar Sep 01 '20 at 06:22
  • Ah my bad. I was just thinking normal `ssh` and not `ssh-copy-id`. – flakes Sep 01 '20 at 06:24
  • @ZekiAhmetBayar You're setting `input_cert` after you call the function. You need to set it before. – Barmar Sep 01 '20 at 06:24
  • @Barmar As you said, I define it first. I added a photo to the question. You can see the problem from there. I'm not getting any errors, just can't send the password to the command line. – Zeki Ahmet Bayar Sep 01 '20 at 06:27
  • `ssh-copy-id` probably tries to read the password from the terminal, not standard input. So you can't feed the password to it using `input=` – Barmar Sep 01 '20 at 06:30
  • Thank you very much for your help, I hope someone makes another suggestion. – Zeki Ahmet Bayar Sep 01 '20 at 06:32
  • Possible that the input is getting sent to quickly? Maybe something like pexpect is required? https://stackoverflow.com/questions/15166973/sending-a-password-over-ssh-or-scp-with-subprocess-popen – flakes Sep 01 '20 at 06:33
1

I solved.

    send_pass = 'PASSWORD' + '\n'
    send_cert = 'ssh-copy-id -i ' + 'CERT_PATH' + ' ' + 'USER@HOSTNAME'

    child = pexpect.spawn(send_cert,encoding='utf-8')
    child.expect('password:')
    child.sendline(send_pass)
    time.sleep(2)

Thanks all.