-2

I am developing a piece of software in C that needs to SSH to another machine and run commands as root.

Something that looks like this:

char* GetPasswd(void);

void run(char* apnSshCommand)
{
   FILE* lphSshFD = popen(apnSshCommand,"w");
   fprintf(lphSshFD,GetPasswd());
   fflush(lphSshFD);
   fprintf(lphSshFD,"#Command to run in shell");
   fflush(lphSshFD);
}

GetPasswd() would be a callback to a gui where the user has typed in the password

I know that the above code is not possible since SSH looks to it's own /dev/tty to provide the password for authentication.

I have read posts such as this that teases an answer using ioctl() and fcntl() but does not provide one. Along with this that shows it is possible from the command line however I have not been able to translate it.

Using expect is NOT an option

Using SSH keys are NOT an option

The SSH C library is NOT an option

Using sshpass is NOT an option

Without these, the only thing that I can think of is starting a new child process and redirect/close file descriptors to control what ssh has access to.

EDIT: These restrictions come from the fact that the system I am working on is extremely old and does not contain tools such as expect, sshpass and the SSH C library as well as being subject to multiple restrictions in regards to when sshkeys can be used

CodeSmith
  • 103
  • 5
  • 1
    `fprintf(lphSshFD,GetPasswd());` looks wrong. Where is the format string argument to `fprintf()`? – Barmar Oct 17 '17 at 18:27
  • 1
    How about using SSH public keys? – Barmar Oct 17 '17 at 18:29
  • `lpSshFD` looks wrong, are you programming Windows API? – Antti Haapala -- Слава Україні Oct 17 '17 at 18:29
  • You can run `ssh` in a child process and connect to it using a pseudo-tty. – Barmar Oct 17 '17 at 18:30
  • 1
    What's `sshpass` mentioned as a non-option? is that supposed to be `SSH_ASKPASS`? – dhke Oct 17 '17 at 18:31
  • You could allocate a pty, launch ssh with the pty as its input, and respond to the password prompt from ssh. You'd be reimplementing expect or sshpass. – Kenster Oct 17 '17 at 18:33
  • @Barmar, running ssh in a child process and connecting to it using a pseudo-tty sounds like a way forward, but I am unsure of how to do that. – CodeSmith Oct 17 '17 at 18:36
  • @dhke sshpass is a utility that can be used to pass the password to ssh in plaintext but it is unavailable to me – CodeSmith Oct 17 '17 at 18:36
  • @Kenster Can you provide a link to some place that shows me how to do this – CodeSmith Oct 17 '17 at 18:37
  • Search for the sshpass source code. – Kenster Oct 17 '17 at 18:39
  • And the password MUST be asked before the connection is made? Because otherwise, providing your own `SSH_ASKPASS` agent is probably the simplest approach. – dhke Oct 17 '17 at 18:39
  • Why not use something like `libssh` directly instead of using a subprocess? – chepner Oct 17 '17 at 18:40
  • @chepner Question says "The SSH C library is NOT an option" – Barmar Oct 17 '17 at 18:44
  • 4
    Where are all these restrictions coming from? These are all the usual methods to use SSH from a program, you're deliberately excluding them. – Barmar Oct 17 '17 at 18:45
  • https://stackoverflow.com/questions/8374000/how-to-use-pseudo-terminals-in-linux-with-c http://rachid.koucha.free.fr/tech_corner/pty_pdip.html – Barmar Oct 17 '17 at 18:47
  • *subject to multiple restrictions in regards to when sshkeys can be used* In other words, the people who wrote the restrictions don't understand security. They're forcing you to kludge up a solution for an already-solved problem, and your solution likely requires leaving the other account password available on disk. And that appears to be the other *root* password. – Andrew Henle Oct 17 '17 at 20:59
  • Possible duplicate of [Shell script to automate SSH login using password](https://stackoverflow.com/questions/43526330/shell-script-to-automate-ssh-login-using-password) – Kenster Oct 17 '17 at 22:37

2 Answers2

0

This works for me:

Create a script called pwd.sh that emits the password:

 #!/bin/bash                                                                                                                  
 echo -n mypassword

Run ssh in a new session like this:

 SSH_ASKPASS=/path/to/pwd.sh DISPLAY= setsid -w ssh root@192.168.1.10 <command>             

The effect of setsid is to run ssh detached from the controlling terminal, which is what is needed for it to respect SSH_ASKPASS.

I haven't tried, but I would expect to be able to run this command from C using system().

For the record, I tested this with OpenSSH_7.2p2 on Ubuntu.

Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
  • It's available for OpenSolaris, so that problem might not be insurmountable. If it is, it shouldn't be difficult to compile the ~40 lines of C that the `setsid` implementation requires. Or just use it as the basis for some other implementation of a wrapper for `ssh`. Or perhaps just cook up a similar effect using some combination of `nohup`, `&`, and redirection. – Kevin Boone Oct 18 '17 at 06:46
0

I was able to come up with a solution by looking at the source code for sshpass which I found here

CodeSmith
  • 103
  • 5