Can't write in a .spp file remotely - c

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 :(

Related

Print CMD output to .txt with C

does anyone have an idea how to save a CMD output to a .txt with C? I would like to do a ping and tracert and then ask if the result should be saved. Should it be saved, the result should be saved in a .txt.
My code is like this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main ()
{
char Testprint1[100],Testprint2[100];
sprintf(Testprint2, "ping 127.0.0.1");
system(Testprint2);
sprintf(Testprint2, "tracert 127.0.0.1");
system(Testprint2);
printf("\nDo you want to save the output? (y)Yes / (n)No: ");
if (Answer=='j')
{
FILE *Test;
Test = fopen("Test_Log.txt", "w");
fprintf(Test, "Ping:\n%s\n\nTracert:\n%s\n",Testprint1,Testprint2);
if(Pinglog == NULL)
{
printf("Log could not be saved.\n");
system("\n\npause\n");
}
else
{
printf("Log has been saved.");
fclose(Pinglog);
system("cls");
}
}
else if(Answer=='n')
{
system("cls");
system("\n\npause\n");
}
}
The txt includes:
Ping:
ping 127.0.0.1
Tracert:
tracert 127.0.0.1
It is plausible for me that only this comes out as a result, but I have no idea how I can change that and how I can save the CMD output e.g. in a variable and then save it in the .txt.
Your code is pretty unconventional, which should be a flag that the approach tends in a messy direction. You're using C for things that are normally scripted. I'm going to focus on the use of ping.exe.
The conventional approach in C would be to use APIs to accomplish your tasks (e.g. instead of ping.exe, call IcmpSendEcho).
Your code, on the other hand, is launching a series of external processes to do your tasks, and attempting to orchestrate them. That's something scripting languages are great at, and C is rather bad at.
While it's simple to just invoke ping.exe, the downside is you only get the control that ping.exe grants you. If you on the other hand use IcmpSendEcho, you have full control over the behavior and output.
It's possible however. ping.exe (et al) output to stdout, and scripting languages (.cmd, .sh) have natural methods of redirecting stdout. By default stdout goes to the console/shell window. You can redirect stdout by using > (e.g. ping >output.txt). You can also redirect stdout in your own application, however it's not as trivial as calling system().
At very least you will need to use CreateProcess.
There are many related questions on SO, like How do I redirect output to a file with CreateProcess?
A simple example that reads the command ping and saves it to a buffer
#include <stdio.h>
#define BUFSIZE 1000
#define CMDBUFSIZE 100
int main()
{
char buf[BUFSIZE] = {0}; // Will hold cmd output
char cmdbuf[CMDBUFSIZE]; // Used to format the cmd
char *ip = "google.com";
snprintf(cmdbuf, CMDBUFSIZE, "ping %s /n 1", ip);
FILE *p = _popen(cmdbuf, "r");
if (p == NULL) {
puts("popen failed");
return 1;
}
fread(buf, BUFSIZE - 1, 1, p);
printf("%s", buf);
_pclose(p); // Make sure to _pclose so that the cmd doesn't turn into a zombie process
}
The easiest way is, to save the output directly inside the CMD command
ping 127.0.0.1 > Test_Log.txt
This saves the output of ping 127.0.0.1 to the file named Test_Log.txt
which is exactly what you want.

Passing argument to system() in C

I want to find the number of context switches of a program. I know there is a file /proc/PID/status which reports the number of context switches continuously while the program is running. However, after the process is finished that file is deleted, so I am not able to check the content.
For this reason, in the following C code, I am trying to copying that file before and after the region of interest.
int pid_num = getpid();
system("sudo cp /proc/$pid_num/status start.txt");
// do
system("sudo cp /proc/$pid_num/status finish.txt");
As I run the program, I get this message
cp: cannot stat '/proc//status': No such file or directory
It seems that $pid_num in the system function is not correct. What is the correct form then?
C uses format specifiers equivalent to more generic $var shell counterpart. You need to prepare the command-string before invoking system() call.
#define START_FILE "start.txt"
#define END_FILE "finish.txt"
#define MAX_CMD_BUFFSIZE 256 // adjust as necessary
char cmdbuf[MAX_CMD_BUFFSIZE];
pid_t pid_num = getpid();
snprintf(cmdbuf, sizeof(cmdbuf), "sudo cp -f /proc/%d/status %s", pid_num, START_FILE);
int cmd_status = system(cmdbuf);
// verify
snprintf(cmdbuf, sizeof(cmdbuf), "sudo cp -f /proc/%d/status %s", pid_num, END_FILE);
cmd_status = system(cmdbuf);
// verify
use -f command option to replace target file if it already exists.
Also, you need to run this program with an user with sudo privileges; which is inviting trouble. If process status file is available for every user for reading, check if you can drop sudo from command.

c sshfs automatic connection thru bash using libexpect

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
}

How to use the pulseaudio API as root?

I am currently trying to use the pulseaudio simple API to record microphone data from my USB sound card with my raspberry pi 3. I used the example program parec-simple from pulseaudio in my own program and it works quite nice.
The program i used this code for is accessing gpio's so i need to run this as root. However, when i try to execute the program as root, i get the following errors:
Home directory not accessible: Permission denied
W: [pulseaudio] core-util.c: Failed to open configuration file '/root/.config/pulse//daemon.conf': Permission denied
W: [pulseaudio] daemon-conf.c: Failed to open configuration file: Permission denied
pa_simple_new() failed: Connection refused
the code is used is the following:
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 44100,
.channels = 1
};
pa_simple *s = NULL;
int ret = 1;
int error;
/* Create the recording stream */
if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
fprintf(stderr, "pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
while(1)
{
uint8_t buf[BUFSIZE];
/* Record some data ... */
if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
goto finish;
}
/* And write it to STDOUT */
if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {
fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
goto finish;
}
}
ret = 0;
finish:
if (s)
pa_simple_free(s);
return ret;
I already tried chown pi:pi /home/pi as suggested here to try to fix it but it doesn't work. changing the owner of /home/pi from pi to root didn't work for me either.
I also tried a clean reinstall of pulseaudio but unfortunately it didn't fix it.
So what can i do to fix these errors?
If you need to run your program as user root, then you must impersonate root. I don't know if pulseaudio looks at the username in order to find configuration files, or it looks at the $HOME variable. In the second case, maybe that by setting HOME to the home of a "working" user helps.
Anyway what you told about the situation is clear: pulseaudio does not find a file:
'/root/.config/pulse//daemon.conf'
Place a correct "daemon.conf" in that directory - probably you can copy it from somewhere (like /home/auser/.config/pulse/daemon.conf).
Consider that directories with name starting with a dot are normally hidden; if using a file manager you must enable "show hidden files", if you use the shell, ls -a can help.
Your first target is to confirm that the file is there, and your program should not complain about a missing/unreadable config file. Then, maybe other errors will show up but, one after another, you can eliminate them.
When you run process with sudo it does not change Home directory to /root - sudo echo $HOME # /home/username. You need to specify HOME directory with by running sudo HOME=/root executable.
When you want to access pulseaudio from root you need to run it system wide with command - sudo pulseaudio --system=true.
Then you will receive an error from pulseaudio:
W: [pulseaudio] protocol-native.c: Denied access to client with invalid authentication data.
Which can be solved by adding root user to audio-pulse group - sudo adduser root pulse-access.

what does this attempted trojan horse code do?

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.

Resources