In my C program I can set environmental variable via.. setenv
However setenv only allows me to setup an environmental variable via a string.
Currently in my environment I have the below setup in my bash profile...
export MY_PASSWORD=`java -jar decrpytpassword $ENCRYPTED_PASS`
where decryptpassword is a Java executable jar file which accepts encrypted password and prints out decrypted password.
I want to do something similar in my C program where I will pass the encrypted password via a string and decrypt it.
One way to do this would be:
Use popen to run the command and capture its output.
Read a string from that output (perhaps using fgets).
Put that new string in the environment using setenv.
P.S. If you use fgets in step 2, you may have to add a step 2a to strip the trailing \n.
Related
I want to call an URL in a C program which contains some "&". The system only recognices the URL until the "&" (https://chart.googleapis.com/chart?cht=qr) and tells me it doesnt know the command cht and chl. How can I make it to use the whole URL?
char get_qr[100];
sprintf (get_qr, "start https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl=Hello World!);
system (get_qr);
The issue isn’t the URL handling, it’s that you’re launching a shell command via system.
Shell commands need to be shell quoted. In particular, & is a special character of the shell. So put quotes around your shell command argument:
system("start \"https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl=Hello World!\"");
(In your code there’s no need for sprintf anyway. If your actual code requires sprintf, don’t just allocate a static buffer; allocate a dynamic buffer of the correct size!)
I want to test 2 C programs to check it's coverage (line coverage and branch coverage).
I am using gcovr in linux system.
To do this, I have written a Perl Script that will call gcc compiler and read input from the file, then gives test for the coverage of C program.
I have many test suites in the form of files that are given to C program, I am using Perl to automate the input and get the coverage using gcovr.
Of course I've used system command , and backtics in perl to call gcc and gcovr.
The first C program runs well, because the input to the program is read from arguments given.
But for the second C program, I got confused, because the program only accepts input from keyboard or simply put "it is using scanf".
So, how can we provide input to C programs that only accepts input from keyboard (scanf) through terminal linux or using perl with system command ?
scanf accepts input from stdin. You can redirect stdin to a file when you start your program and have the program get its input from that file.
Redirection is a feature of the OS, not a feature of a specific language.
Let's say you want to start your program and you know that this program will accept '10' 'y' and 'n' as input. All you have to do is to create a file with those lines in, by whatever way you can. Let's suppose that this file is named test_1.
You then start the program with tested_program < test_1 and the program will use '10', 'y' and 'n' as its input.
If using the Perl command system is not a strict requirement, you can consider using Open3 instead. It is more advanced than system, and you can specify what to use for STDIN, STDOUT and STDERR. So you can write the input to your C program in a text file, create a handle to that file, and use Open3 to call your C program specifying that file handle as first argument.
In case this is helpful, here's my environment: debian 8, gcc (with std = gnu99).
I am facing the following situation:
In my C program, I get a string (char* via a socket).
This string represents a bash command to execute (like 'ls ls').
This command can be any bash, as it may be complex (pipelines, lists, compound commands, coprocesses, shell function definitions ...).
I can not use system or popen to execute this command, so I use currently execve.
My concern is that I have to "filter" certain command.
For example, for the rm command, I can apply it only on the "/home/test/" directory. All other destinations is prohibited.
So I have to prevent the command "rm -r /" but also "ls ls && rm -r /".
So I have to parse the command line that is given me, to find all the command and apply filters on them.
And that's when I'm begin to be really lost.
The command can be of any complexity, so if I want to make pipelines (execve execute a command at a time) or if I want to find all commands for applying my filters, I'll have to develop parser identical to that of sh.
I do not like creating the wheel again, especially if I make it square.
So I wonder if there is a feature in the C library (or that of gnu) for that.
I have heard of wordexp, but I do not see how manage pipelines, redirection or other (in fact, this does not seem made for this) and i do not see how can I retrieve all the command inside the commande.
I read the man of sh(1) to see if I can use it to "parse" but not execute a command, but so far, I find nothing.
Do I need to code a parser from the beginning?
Thank for your reading, and I apologies for my bad english : it's not my motherlanguage (thanks google translate ...).
Your problem:
I am facing the following situation: In my C program, I get a string
(char* via a socket). This string represents a bash command to execute
(like 'ls ls'). This command can be any bash, as it may be complex
(pipelines, lists, compound commands, coprocesses, shell function
definitions ...).
How do you plan on authenticating who is at the other end of the socket connection?
You need to implement a command parser, with security considerations? Apparently to run commands remotely, as implied by "I get a string (char* via a socket)"?
The real solution:
How to set up SSH without passwords
Your aim
You want to use Linux and OpenSSH to automate your tasks. Therefore
you need an automatic login from host A / user a to Host B / user b.
You don't want to enter any passwords, because you want to call ssh
from a within a shell script.
Seriously.
That's how you solve this problem:
I receive on a socket a string that is a shell command and I have to
execute it. But before execute it, i have to ensure that there is not
a command in conflict with all the rules (like 'rm only inside this
directory, etc etc). For executing the command, I can't use system or
popen (I use execve). The rest is up to me.
Given
And that's when I'm begin to be really lost.
Because what you're being asked to do is implement security features and command parsing. Go look at the amount of code in SSH and bash.
Your OS comes with security features. SSH does authentication.
Don't try to reinvent those. You won't do it well - no one can. Look how long it's taken for bash and SSH to get where they are security-wise. (Hint: it's decades because there's literally decades of history and knowledge that were built into bash and SSH when they were first coded...)
I have one C program and one shell script and I'd like to "source" shell script using my C.
I tried use system() function, after it I can run script properly, but my colors doesn't work.
For example instead of CYAN - I defined it as:
CYAN='\e[96m'
it shows only \e[96m and some functions just failed with message:
./myscript.sh: 27: [: y: unexpected operator
Is there some solution?
A program that is not itself the shell cannot "source" a file of shell commands as the shell itself can do. A program can run such a file as a script, either directly or by invoking a shell to run it, but the script then gets its own environment, and any changes it applies to that environment do not propagate to the parent process's environment.
Programs receive their environment as a function of program startup. If you want a variable to be set in a program's environment then by far the easiest thing to do is arrange for it to be set when the program is invoked, either by exporting it from the parent process's environment or by wrapping program launch in a script that arranges for the same. There are additional alternatives on the process startup side, as well.
If a C program wants to alter its environment after startup, then it can use the setenv() and unsetenv() functions. Those are defined by POSIX, not C itself, but if we're talking about sourcing shell commands then it seems reasonable to assume a POSIX context.
Additionally, if you are trying to define CYAN as a shell variable whose contents are an ANSI escape sequence, then your syntax is wrong. No escape sequences at all are recognized within ordinary single quotes (even closing single quote cannot be escaped). Within double quotes the backslash does function as an escape character, but in a strict sense: C-style character codes are not supported there. If, again, you're processing that in the shell, as opposed to in C, then you appear to want
CYAN=$'\e[96m'
(Note the $, which is essential for \e to be recognized as representing the "escape" character, and which causes the shell to recognize a few other C-style escape sequences as well.)
I'm trying to use OpenGPG and when trying to decrypt something It opens up a prompt for the password. Now I'm trying to run this automatically therefore none to enter password. So My question is how do you pass in the password to this new prompt opened up by the exe I'm running form the batch file. Ive looked in gpg2.exe -help and there is no way to pass in the password as a parameter if anyone is familiar with OpenGPG or if there is a command I can run to pass the password into the new prompt, that would be great.
gpg2.exe -o output.txt -d series.txt.gpg
After many attempts at trying to get this working I, finally checked out the manual for gpg2.exe at http://linux.die.net/man/1/gpg2 and after adding the command line argument --batch the --passphrase is accepted by the application.
Not doing so results in the user being prompted.
Hope this helps anyone in the future attempting to do this hack.
echo password | gpg2.exe -o output.txt -d series.txt.gpg
GnuPG offers multiple ways to pass the passphrase non-interactively. Using the parameter --passphrase [password] is probably the most simple one, depending on your use case the others also could be of interest (for example if you do not want to store the passphrase within your application code).
From man gpg:
--passphrase-fd n
Read the passphrase from file descriptor n. Only the first line will be read
from file descriptor n. If you use 0 for n, the passphrase will be read from
STDIN. This can only be used if only one passphrase is supplied.
--passphrase-file file
Read the passphrase from file file. Only the first line will be read from
file file. This can only be used if only one passphrase is supplied. Obvi-
ously, a passphrase stored in a file is of questionable security if other
users can read this file. Don't use this option if you can avoid it.
--passphrase string
Use string as the passphrase. This can only be used if only one passphrase
is supplied. Obviously, this is of very questionable security on a multi-
user system. Don't use this option if you can avoid it.