0

I am using execv to set environment variable by passing command line argument. how to set environment variable without passing command line argument.

std::vector<char*> arg;
arg.push_back("export MONGODB_HOSTNAME=" + mongodb_host + ";");
arg.push_back("export MONGODB_USERNAME=" + mongo_username + ";");
arg.push_back("export MONGODB_PASSWORD=" + mongo_passowrd + ";"); 
arg.push_back("NULL");
execv("/usr/bin/ssh", &arg.front());
Abhi
  • 15
  • 6
  • 1
    [setenv](http://man7.org/linux/man-pages/man3/setenv.3.html) from `stdlib.h` ? – pptaszni Jan 28 '20 at 08:26
  • 2
    You do know that the `exec` family of functions will ***replace*** your process? If successful, `execv` will not return, and your program doesn't exist anymore. – Some programmer dude Jan 28 '20 at 08:26
  • 1
    Also `"NULL"` is the *string* `"NULL"`, it's *not* a null pointer (which would be plain `NULL` or `nullptr`). – Some programmer dude Jan 28 '20 at 08:27
  • You cannot concatenate C-style strings like that. Use `std::string` or [How do I concatenate const/literal strings in C?](https://stackoverflow.com/questions/308695/how-do-i-concatenate-const-literal-strings-in-c) – Yksisarvinen Jan 28 '20 at 08:27
  • 2
    There's also no way to call SSH with `ssh export FOO=bar;`, it will just choke on that when parsing arguments. You probably meant `FOO=bar ssh ...`, but that requires interpretation by Bash or a POSIX shell. – Ulrich Eckhardt Jan 28 '20 at 08:33
  • 1
    That said, it doesn't help that your code isn't even close to a [mcve] and that its `args` and `arg`. – Ulrich Eckhardt Jan 28 '20 at 08:34
  • 4
    To summarize: It seems to us that you're just guessing about things and hoping for the best. Please take some time to do some research first next time, like reading about the functions you call and the commands you use. A quick search for e.g. `set environment variable c++` would have given you plenty of information, including quite a few links to here on Stack Overflow. – Some programmer dude Jan 28 '20 at 08:35
  • 1
    @UlrichEckhardt Instead of launching a full shell interpreter you could use `execvpe` to also pass the environment. – Konrad Rudolph Jan 28 '20 at 09:27

1 Answers1

0

Depending on your threat model, perhaps you can get away with setting environment variables via /usr/bin/env?

This would look something like the following:

std::vector<std::string> strArgs = {
    "ssh",
    "remote-server",
    "env",
    "MONGODB_USERNAME=" + mongo_username,
    "MONGODB_PASSWORD=" + mongo_password,
    "mongo"
};

// Convert std::vector<std::string> into char**
std::vector<char*> cArgs;
for (auto& str : strArgs) {
    cArgs.emplace_back(str.c_str());
}

execv("/usr/bin/ssh", (const char **)&cArgs.front());
Botje
  • 26,269
  • 3
  • 31
  • 41
  • Here we are passing string arg as command line argument to ssh, is there anyway to not pass as string arg as command line argument? – Abhi Jan 28 '20 at 11:15
  • You could upload a script that contains both `export` statements and invoke _that_ via SSH. – Botje Jan 28 '20 at 12:20