How do I input a password from a makefile or system( ) call?

Viewed 44

I'm working on a C project that commonly involves making connections to remote servers. Commonly, this involves using some small terminal macros I've added to my makefile to scp an executable to that remote server. While convenient, the only part of this I've not been able to readily streamline is the part where I need to enter the password.

Additionally, in my code, I'm already using system() calls to accomplish some minor terminal commands (like sort). I'd ALSO like to be able to enter a password if necessary here. For instance, if I wanted to build a string in my code to scp a local file to my remote server, it'd be really nice to have my code pull (and use) a password from somewhere so it can actually access that server.

Does anyone a little more experienced with Make know a way to build passwords into a makefile and/or a system() call in C? Bonus points if I can do it without any third-party software/libraries. I'm trying to keep this as self-contained as possible.

Edit: In reading responses, it's looking like the best strategy is to establish a preexisting ssh key relationship with the server to avoid the login process via something more secure. More work up front for less work in the future, by the sound of it, with additional security.

Thanks for the suggestions, all.

2 Answers

The solution is to not use a password. SSH, and thus SCP, has, among many many others, public key authentication, which is described all over the internet. Use that.

Generally, the problem you're trying to solve is called secret management, and the takeaway is that your authentication tokens (passwords, public keys, API keys…) should not be owned by your application software, but by something instructing the authenticating layer. In other words, the way forward really is that you enable SSH to connect on its own without you entering a password by choosing something that happens to not be an interactive authentication method. So, using a password here is less elegant than just using the generally favorable method of using a public key to authenticate with your server.

Passing passwords as command line option is generally a bad idea – that leaks these passwords into things like process listings, potentially log entries and so on. Don't do it.

Running ssh-keygen to create the keys. Then, adding/appending the local system's (e.g) .ssh/id_rsa.pub file to the remote's .ssh/authorized_keys file is the best way to go.

But, I had remote systems to access without passwords but the file was not installed on the remote (needing ssh-keygen to be run on the remote). Or, the remote .ssh/authorized_keys files did not have the public key from my local system in it.

I wanted a one-time automated/unattended script to add it. A chicken-and-the-egg problem.

I found sshpass

It will work like ssh and provide the password (similar to what expect does).

I installed it once on the local system.

Using this, the script would:

  1. run ssh-keygen on the remote [if necessary]
  2. Append the local .ssh/id_rsa.pub public key file to the remote's .ssh/authorized_keys
  3. Copy back the remote's .ssh/id_rsa.pub file to the local system's .ssh/authorized_keys file [if desired]

Then, ssh etc. worked without any passwords.


UPDATE:

ssh_copy_id is your fried, too.

I had forgotten about that. But, when I was doing this, I had more complex requirements.

The aforementioned script would merge/combine all the public keys and update all the authorized_keys files on all the systems. This would be repeated anytime any new system was added to the mix.

you never need to run ssh-keygen on a remote host, especially not to generate an authorized_keys file. – Marcus Müller

I think that was inferred but not implied as a requirement [particularly in context]. I hope the answer wasn't -1 for that.

Note that (1) ssh-keygen is needed for (3) copy back the public key.

Ironically, one of the tutorial pages for ssh-copy-id says run ssh-keygen first ...

It's been my exerience when setting up certain types of systems/clusters (e.g. a development host/PC and several remote/target/test ones), if one wants to do local-to-remote actions, invariably one wants to do:

  1. remote-to-local actions -- (e.g.) I'm ssh'ed into a remote system and want to do rcp back to the development system.
  2. The remote system needs to do a git clone/pull from [and, sometimes, git push to] the local git server.
  3. remote-to-remote -- copying/streaming data between target systems.

This requires that each system have a private/public key pair and all systems have an authorized_keys file that has the public keys of all the other systems.

When I've not set up the systems that way it usually comes back to haunt me [usually late at night when I'm tired]. So, I just [axiomatically] set it up that way at the outset.

One of the reasons that I developed the script in the first place. Also, since we didn't want to have to maintain a fork of a given system/distro installer for production systems, we would:

  1. Use the stock/standard distro installer CD/USB
  2. Use the script to add the extra/custom config, S/W, drivers, etc.
Related