I want to automate the mounting of a sshfs connection inside my C program (meant for linux) using only password for ssh. (I don't want to use public/private keys.)
It seems i could do it with libexpect. Based on this thread it seems possible to use libexpect to give the password when required. For example, i made a successful test program that creates a dir with sudo mkdir test and then provide the user password with libexpect. So that pipe seems really to be bidirectional. Thou, with sshfs and my simple function below, it doesn't work: i do have a sshfs mount produced by it, but it doesn't work and i can't see the files.
enum{ASKCONTINUE,ASKPWD};
int sshfs_connect (char data[10][200], char ip[]) {
char commandline[300];
sprintf(commandline,"sshfs %s#%s:%s %s -p %s -o ServerAliveInterval=15",
data[4],ip,data[6],data[5],data[7]);
bool shouldBreak = false;
FILE* fp = exp_popen(commandline);
while(shouldBreak == false)
{
switch(exp_fexpectl(fp,
//if asked for continuing (authenticity can't be established)
exp_glob, "ontinue connecting (yes/no)?", ASKCONTINUE,
//if asked for pwd
exp_glob, "s password:", ASKPWD,
exp_end)) //
{
case ASKCONTINUE:
printf("asked continue? !\n");
fprintf(fp,"%s\n","yes");
break;
case ASKPWD:
printf("asked pwd ! sending pwd: %s\n",data[8]);
fprintf(fp,"%s\n",data[8]);
shouldBreak = true;
break;
case EXP_TIMEOUT:
shouldBreak = true;
break;
case EXP_EOF:
shouldBreak = true;
break;
}
}
fclose(fp);
return 0;
}
It seems that expect (even the tcl version) cannot be used with sshfs, probably because the spawned process does not have a controlling tty and so the command tries to get the password from the user by other means, e.g. using a gui popup.
What works is adding the option -o password_stdin to ask sshfs to read the password from stdin. It does this without writing a prompt, so libexpect is a bit heavyweight, but nonetheless this should work for you: send the password and wait for eof (which would probably be within the default timeout of 10 seconds).
ssh = exp_popen("sshfs -o password_stdin user#host:/dir /mntpoint");
if(ssh==NULL)fatal("fail to spawn");
fprintf(ssh, "%s\n", password);
switch(exp_fexpectl(ssh,exp_end)) {
case EXP_EOF:
break; // ok
case EXP_TIMEOUT:
break; // fail
default:
break; // fail
}
Related
I have created a c program using expect to login a server using ssh, the following is the program
#include <sys/wait.h>
#include <tcl8.6/expect.h>
int main()
{
exp_is_debugging = 0;
exp_timeout = 60;
FILE *expect = exp_popen((char *) "ssh user#ip");
if (expect == 0) {
return 1;
}
enum { denied, invalid, command_not_found,
command_failed, prompt };
switch (exp_fexpectl(expect,
exp_glob, "password: ", prompt,
exp_end)) {
case prompt:
// continue
break;
case EXP_TIMEOUT:
return 1;
}
fprintf(expect, "%s\r","password");
switch (exp_fexpectl(expect,
exp_glob, "denied", denied, // 1 case
exp_glob, "invalid password", invalid, // another case
exp_glob, "#", prompt, // third case
exp_end)) {
case denied:
printf("denied %d",exp_glob);
break;
case invalid:
break;
case EXP_TIMEOUT:
printf("EXP_TIMEOUT");
break;
case prompt:
printf("loggedin");
break;
default:
//return 0;
break;
}
}
I am able to login to the server but it immediately gone to my terminal after this, what i am looking to login to the server and need to interact with that terminal. Now, it is showing my terminal after that, do anyone have any idea on this ? i need to stay on that logged server's terminal
I don't see any loop in your program. You just expect some output from your child process (ssh), reply accordingly, and finally terminate. When you terminate, your child process terminates as well. You'd have to indefinitely forward I/O between your stdin/stdout and the child process to achieve what you want.
That said, this whole idea is flawed. You just want to launch ssh and have the login done automatically, but use the shell interactively? There's no need to write code for that, have a look at ssh-agent and how to create an ssh key.
I have a custom shell, which runs in one process. I want to use the inbuilt ssh available in Linux. I want to redirect the user I/O from the custom CLI to the actual linux shell.
Here is what I have done to do ssh:
INT4 do_ssh(tCliHandle CliHandle, CHR1 *destIp)
{
FILE *writePipe = NULL;
char readbuff[1024];
char cmd[1024];
memset(cmd,'\0',sizeof(cmd));
sprintf(cmd,"/usr/bin/ssh %s",destIp);
printf("cmd = %s\r\n",cmd);
writePipe = popen(cmd,"w");
if(writePipe == NULL)
{
return -1;
}
while( fgets(readbuff,sizeof(readbuff) - 1, writePipe) != NULL)
{
CliPrintf(CliHandle,"%s\r\n", readbuff);
//printf("%s",readbuff);
}
printf("Closing writePipe\r\n");
pclose(writePipe);
return 0;
}
The problem, which I see is that after doing ssh I can't see the session anymore.
Here is the output:
cust# ssh 192.168.10.42
cmd = /usr/bin/ssh 192.168.10.42
Closing writePipe
Pseudo-terminal will not be allocated because stdin is not a terminal.
Could not create directory '/root/.ssh'.
root#192.168.10.42's password:
ssh 192.168.10.42
My expectation is to keep the session alive and let the user keep sending the command from the terminal and it should get printed on the terminal.
But, I see that after ssh the session is closed. I want to keep it open.
I want to close only when the window is closed or exit is passed.
What I should do? Any hints will be helpful.
I'm currently writing a program that will run multiple commands (in one line) in the CLI using C.
The first command that I need to run is sudo -s. So I run this command alone to test if the program is running, but the program hangs while running this command. I wanted to know if the problem is the program or the command, so I run ls. The program works perfectly when I run the ls command so I assume that something is wrong with sudo -s command, maybe I need to do something with that command so that it will run in the CLI.
Here's the function that accepts the command:
int executeCommand(char *command, char *result)
{
/*This function runs a command./*/
/*The return value is the output of command*/
int nSuccess = -1;
FILE * fp = NULL;
char buffer[1035];
if (command == NULL)
render("Command is null");
if (result == NULL)
render("result is null");
if (command!=NULL && result!=NULL)
{
fp=popen(command,"r");
if(fp!=NULL)
{
strcpy(result,"\0");
while(fgets(buffer, sizeof(buffer)-1,fp)!=NULL)
{
strcat(result,buffer);
}
pclose(fp);
} nSuccess=0;
}
return nSuccess;
}
BTW, I'm doing a web app, the user will write the command that he wants to execute. The input will be sent to server via ajax using a POST request. And the server runs on Linux.
sudo -s
will require the password so the program running this command may wait for password to be entered
sudo -s will prompt for a password and won't return a result immediately.
I don't know if somebody can help me with my problem, because I don't know if it is a programming issue or a networking issue. However, I will explain the whole suitation.
I am working on a mesh testbed, and I would like to run the pacifier protocol which is developed by someone for some reason.
The problem is that when I try to run the probing (which is a part of the configuration to run the pacifier) on the testbed nodes using the perl script “run_probing.pl”, the .spp file that contains the results didn’t created, but when I run the probing command manually on any two nodes for example using the command ./probing –a 10.1.1.26 -i 26, I got that .spp files.
The command sent from perl script using pssh service. I check the process id using the command ps aux, and I found that the command
$cmd ="/usr/bin/pssh -p 1 -t 120 -l amr -A -h temp_overlay.crap \"/map/more_pacifier/probing -a $allusnips[$sitecount] -i $allusnipids[$sitecount] > /dev/null 2>&1 & \" ";
is executed in the background for both devices since the process id for that command is in the process id list which means that there is no problem with the pssh service itself. But still I don't get any .spp file in the /map/more_pacifier directory which is specified in the probing.c code.
For the probing.c code, since it is very long (around 400 lines), so I will put the part corresponding to writing in the .spp file:
FILE *fl;
if(argc < 3) {
usage();
exit(-1);
}
while ((ch = getopt(argc, argv, "h:a:i:d:")) != -1)
switch (ch) {
case 'h':
help();
exit(0);
case 'a':
inaddr = inet_addr(optarg); // IP Address
memset((char*) &myip, 0x0, sizeof(myip));
bcopy((char*) &inaddr, (char*) &myip, sizeof(inaddr));
strcpy(myipstr, inet_ntoa(myip));
fprintf(stderr, "My IP is %s, %s\n", inet_ntoa(myip), myipstr);
break;
case 'i':
myipid = atoi(optarg);
fprintf(stderr, "My ID is %d\n", myipid);
break;
default:
usage();
exit(-1);
}
sprintf(lossfile, "/map/more_pacifier/%d.spp", myipid);
fl = fopen(lossfile, "w");
for(i=0; i<NUMNODES; i++)
ND.NHBR_Table[i].recvcount = 0;
ND.numProbePktsSent = 0;
I don't know why I'm not getting the .spp file when running the command via run_probing.pl script.
Is it something with the permission access for this file? but I use chmod 755 command to give the full access of the user.
I will really appreciate your help, It waste lots of time on this strange behavior without any result :(
It looks like this just sends a ping, but whats the point of that when you can just use ping?
/* WARNING: this is someone's attempt at writing a malware trojan. Do not
compile and *definitely* don't install. I added an exit as the
first line to avoid mishaps - msw */
int main (int argc, char *argv[])
{
exit(1);
unsigned int pid = 0;
char buffer[2];
char *args[] = {
"/bin/ping",
"-c",
"5",
NULL,
NULL
};
if (argc != 2)
return 0;
args[3] = strdup(argv[1]);
for (;;)
{
gets(buffer); /* FTW */
if (buffer[0] == 0x6e)
break;
switch (pid = fork())
{
case -1:
printf("Error Forking\n");
exit(255);
case 0:
execvp(args[0], args);
exit(1);
default:
break;
}
}
return 255;
}
It's a hack - or an attempt at a hack - to get arbitrary code run in a privileged mode. Ping needs to run SUID root to get a raw socket for an ICMP_ECHO_REQUEST and the intentional buffer overrun in gets(buffer) is intended to pass junk to ping.
I don't see how this could work in practice, but you shouldn't compile and run it.
It makes sure that ping is called with the arguments -c 5. Which is stupid, because a shell script or alias would be easier to read and faster to write.
This program basically emulates a simple shell program. A shell program is going to take the arguments of another program as input and launch that specified program in a new process. The program you have above is just hard coded for one specific program (ping in this case) and is very simple.
A shell program makes working with the operating system more user friendly by providing an interface to boot up programs.