ssh remote login to server using system(char * command), and excute commands? - c++

Someone familiar with SSH and System(const char * command) to execute shell command!??
Am trying to remotely login to multiple servers/machines from my C++ code, and i have to execute some commands remotely. To the best of my experience, i decided to use ssh. But, now i want to load and send all my commands through the System(const char * command). pls see my code below..
#include "all my headers"
int main()
{
system("ssh 172.10.10.1");//login to server_one, password=123
system("ssh 172.10.10.2");//login to server_two, password=1234
system("ssh 172.10.10.3");//login to server_three,password=12345
system("ssh 172.10.10.4");//login to server_four, password=123456
return 0;
}
Now,my Question is:
can i load and send the remote_ip of the servers and password at the
same time, something like: system("ssh 172.10.10.4 ,123456")
password=123456? if yes, how?
if am done with (1) above, i will have another question. thanks.

Calling system("ssh ...") will ONLY work if you have set up public keys for the machine you want to log in on.
The reason is that the system() does not allow you to interact with the process you started, it will just spawn a new shell and pass the relevant string to the shell for execution, and ssh does not itself have a way to pass the password to the application, you have to actually type it in (or send it to the stdin side of ssh if you use popen - but I would really suggest that public keys are the right way to go in an automated system).
If you still need to interact with the created process, you will need to use something like popen, which will allow you to read stdout or write to stdin on the - or even pipe() and fork() if you need the ability to do stuff to both stdin and stdout.

Related

set proxy configuration in c++ code

I have a raspberry running Yocto.
I'm making a code to setup de proxy configuration of the OS connection.
An example of the conde that I'm using is the following
int main(void)
{
system("unset http_proxy");
command = "export http_proxy=\"http://hostname.com\"";
system(command.c_str());
}
The solution on code is not working, however, if I input in a terminal the same command, it works.
What can be the problem?
What can be the problem?
system() creates a sub-process. So changing the http_proxyenvironment variable with a system call doesn't affect the calling process.
You may try to change the environment variable using setenv(), and then fork() and continue in the child process to do whatever you need with the new proxy settings.

Ssh command from Qt

I have a problem with ssh in my Qt application. I need to run a command which removes a file on a remote server. I tried to use a QProcess class to achieve it. So I pass "ssh" as a name of command and necessary args. In common it looks like this:
QStringList params;
params.append(" user#" + ::host +
" \"rm /tmp/" + ::fileName + "\"");
d->impDelProcess->start("ssh", params);
But after all it keeps asking a password, though I generated ssh keys and copied a public key to the remote server. Moreover, when I run the command above in the terminal like this:
ssh user#host "rm /path/fileName"
it works perfect. The file is deleted and no password is asked. So, the problem is somwhere in QProcess. Is any way to get rid of asking a password? Thank you!
Those are separate arguments, when you use string list. Try this:
params.append("user#" + ::host");
params.append("rm /tmp/" + ::fileName);
That will make Qt pass two arguments for ssh, the login string and the command to execute at remote host.
Important note! Above assumes ::filename does not contain spaces or anything else nasty!. You can get around spaces with this:
params.append("rm '/tmp/" + ::fileName + "'");
But it won't help against wild cards or .. in path... Imagine if file name was ../home/user/* for example... So that is better be trusted input, or you need to sanitize it (but that is beyond scope of this answer).
What you do in the question code is to construct a single argument, equivalent to this shell command line:
ssh 'user#host "rm /path/filename"'

Funny characters returned from read function of Net_SSH2 library (phpseclib)

When I use the Net_SSH2 library and the read/write functions like this:
$ssh = new Net_SSH2($strServerIPAddress);
if(!$ssh->login($strServerUsername, $strServerPassword))
die("error");
$ssh->write(" service httpd reload\n");
$strApacheRestartResult = $ssh->read("[root#$strServerName ~]#");
$ssh->disconnect();
I get funny characters in the read function results ($strApacheRestartResult) that I dont see when running the same thing via Putty, see below:
service httpd reload
Reloading httpd: [60G[[0;31mFAILED[0;39m]
[root#server1 ~]#
Why are these [60G[[0;31m and [0;39m] in the return data from the read function?
They're ANSI control codes. Their purpose is to control the formatting of the text and the color and what not. To decode them properly you'd need a terminal emulator. phpseclib has one called File_ANSI:
http://phpseclib.sourceforge.net/ssh/examples.html#top
Here's your code rewritten to use it:
$ssh = new Net_SSH2($strServerIPAddress);
$ansi = new File_ANSI();
if(!$ssh->login($strServerUsername, $strServerPassword))
die("error");
$ssh->write(" service httpd reload\n");
$ansi->appendString($ssh->read("[root#$strServerName ~]#"));
echo $ansi->getScreen();
$ssh->disconnect();

zmq ventilator/worker/sink paradigm not working w/ subprocess

I am trying to replicate the ventilator/workers/sink paradigm described in the ZMQ guide. I have the same Python Ventilator, the same C++ worker as, and the same Python Sink as was described in the ZMQ examples. I want to launch the ventilator, workers, and sink from one main python script, so I created "class" wrappers around the ventilator & sink, and both of those classes subclass the Python module "multiprocessing.Process." Since the C++ is a binary, I launch it with Python's subprocess.Popen call.
The order of starting all of this up is as follows:
h = subprocess.Popen('test') # test is the name of the binary
time.sleep(1)
s = sinkObj.start()
time.sleep(1)
v = ventObj.start()
What I am finding is that no data is getting through the system when I start up the components like this. However, if I start the C++ binary in its own shell, and only start the sinkObj and ventObj from the main python script, it works fine.
I apologize in advance if this is more of a Python question than a ZMQ question, but I haven't run into issues like this w/ Python's subprocess. I have also tried using os.system() instead of the subprocess... but same issue. I put all the code on this website: https://github.com/kkarrancsu/zmqtest if anybody is curious to test it out. There is a readme on that git which tells you what the files are.
Any ideas on why this could be happening?
------------------------- UPDATE --------------------
I found that if I create a shell script which simply launches the C binary, and call that shell script w/ os.system('run_the_shell_script') it works! So this means that there is something wrong with the way that I am using subprocess.Popen(...), but can't seem to pinpoint what the issue is. I tried w/ the shell=True flag, but it still hangs with that...
It's the name of the worker binary file that causes the problem.
There two solutions:
Chang the name of the binary file test to test_new and do the same in your All.py file, and then it will work as you desire.
Substitute subprocess.Popen('./test', shell=True) for subprocess.Popen('test', shell=True).
test is Linux command. If you type the following in your shell
$ echo $PATH
You may see that . is at the last position. It means that until shell couldn't find the binary file to be executed in the directories that $PATH indicates, it will try to search for it in the current directory .
When you execute subprocess.Popen('test', shell=True), it could find it before trying the . directory and so it won't execute the workers.
As I see, the ventilator and sink bind() to ports 6557 and 6558, and the C++ app connect() to these ports. In this case, if you start the cpp app first, it will try to connect() to the endpoints, but as nothing is bound there, it will drop silently.
In ZeroMQ the basic principle is "First Bind, then Connect". So you should not connect() before you bind() something on the socket. Imagine bind() is the 'Server', and connect() is the client. You cannot connect client to non-existing server. Also, in ZeroMQ every socket can be 'Server', but you SHOULD HAVE only 1 bind()-ing socket per URL. And you can have multiple 'connect()'s.

execute and receive the output of mml command in c++

i have an interface where i use to execute the mml command in my solaris unix like below:
> eaw 0004
<RLTYP;
BSC SYSTEM TYPE DATA
GSYSTYPE
GSM1800
END
<
As soon as i do eaw <name> on the command line.It will start an interface where in i can execute mml commands and i can see the output of those commands executed.
My idea here is to parse the command output in c++.
I can do away with some logic for parsing.But to start with How can get the command to be executed inside c++ ? Is there any predefined way to do this.
This should be similar to executing sql queries inside c++.But we use other libraries to execute sql queries.I also donot want to run a shell script or create temporary files in between.
what i want is to execute the command inside c++ and get the output and even that in c++.
could anybody give me the right directions?
You have several options. From easiest and simplest to hardest and most complex to use:
Use the system() call to spawn a shell to run a command
Use the popen() call to spawn a subprocess and either write to its standard input stream or read from its standard output stream (but not both)
Use a combination of pipe(), fork(), dup()/dup2(), and exec*() to spawn a child process and set up pipes for a child process's standard input and output.
The below code is done with the sh command. This redirects stdout to a file named "out" which can be read later to process the output. Each command to the process can be written through the pipe.
#include <stdio.h>
int main()
{
FILE *fp;
fp = popen("sh > out", "w");
if (fp) {
fprintf(fp, "date\n");
fprintf(fp, "exit\n");
fclose(fp);
}
return 0;
}