horrendo has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks,

I want to modify the command line of a Perl program when it is viewed from 'ps'.

I realise I can change $0, but that only changes the program name which is not what I want. My program optionally takes a DB connect string on the command line and I was hoping to hide it from the world.

Is this possible?

Thanks

Replies are listed 'Best First'.
Re: Modifying command line
by grinder (Bishop) on May 11, 2008 at 21:53 UTC

    What platform are you on? FreeBSD will let you set the entire command line (although it will suffix it with (perl-5.8.8) or whatever).

    Be that as it may, if you are sufficiently paranoid to want to do this, remember that there will always be a race condition between the moment the kernel launches your program and the point in time at which you'll be able to set $0 to something else. Someone may manage to obtain the information you so desperately want to hide.

    Much better to adopt one of the approaches outlined by apl, and not have to worry about hiding it at all.

    • another intruder with the mooring in the heart of the Perl

      Thanks all for the advice. I guess I'll stick with the config file approach.
Re: Modifying command line
by apl (Monsignor) on May 11, 2008 at 21:43 UTC
    Rather than doing that, I'd suggest putting the DB connect string into a config file or environment variable. Then your program could get the information it needs, no one else will see it in a ps, and you won't have to work deep, dark magic on *nix.

    But then, I'm a coward...

      A config file would be a better idea than an environment variable. (Be sure your config file has 0400 permissions!)

      Environment variables are not always safe. For example, both Solaris 8 and 9 and Linux 2.6 have needed patches to keep other users from examining the contents of other users' environment variables.

      Thanks apl. I already do that. The command line is just one of several ways to get the info into the program. It is not the "recommended" way however for the casual user it is the most convenient.

      I was hoping it was as easy to manipulate the entire command line string as it is to manipulate $0, but if someone can suggest an approach - even if a degree of magic is involved, I'm willing to give it a go.

      Thanks again.
Re: Modifying command line
by turo (Friar) on May 12, 2008 at 00:58 UTC
    As grinder said: "there will always be a race condition between the moment the kernel launches your program and the point in time at which you'll be able to set $0 to something else.".

    Anyways If you still want to hide your command line, I have a solution for you :)
    It consists on saving the command line in an environment variable when the process start and then exec the same program without any arguments. Doing this, you will pass the arguments on the environment variable to the new process.
    Here I show you a little program, that you can execute (e.g. myprogram -arg1 -arg2 234 -private "secret"), and try to see if you can use ps -ef to show its command line arguments.
    #!/usr/bin/perl if (@ARGV) { print "Command line arguments detected ... \nHidding command l +ine ..."; my $cmdline = join " ", @ARGV; $ENV{MY_CMDLINE} = $cmdline; print "[done]\n"; exec ($0) or die "Exec: $!"; } print "\nHere is my real code baby!\n"; print "command line: $ENV{MY_CMDLINE}\n"; sleep 300;

    Hope it helps.


    perl -Te 'print map { chr((ord)-((10,20,2,7)[$i++])) } split //,"turo"'
Re: Modifying command line
by tachyon-II (Chaplain) on May 12, 2008 at 00:56 UTC

    You can do this from C but I don't know if you can from Perl. See this for how to do it in C. It is not secure due to the race condition. Neither is setting an environment variable and then executing your code. Taking the data from a file, stream or prompt are the only secure ways.

Re: Modifying command line
by roboticus (Chancellor) on May 12, 2008 at 12:28 UTC
    horrendo:

    How about detecting when you read the credentials from the command line, and in that case reinvoke the program without putting the credentials on the command line. (Put 'em in an environment variable, config file, or something else...) A kludge, but perhaps sufficient for your use...

    ...roboticus