ID:259304
 
In my latest creation, I call an external program to do some of the work. That program needs some information from the game, which is totally derived from input from the players. I was originally going to pass that information as arguments to the external program (shell("./program [inputfromplayer]")) until I realized that it posed a ssecurity risk. If some ev1l l33t hAx0rz discovered this, they could exploit it by typing certain shell metacharacters into their input, thereby making it possible for them to execute any program on the server as me. Not good.

I didn't want to have to search the string for all possible shell metacharacters. So I played it safe and I first write the player input to a temp file, then pass that filename as the only argument to the external program, giving it the job of reading that file back in. I could have also redirected stdin to the file and done it that way, certainly, but it's basically equivalent.

This got me thinking, why not make an optional second argument to shell(), which if true, tells it to execute the command given directly instead of passing it to /bin/sh or whatever (by the way - does it use /bin/sh or the user's default shell? just curious - I suppose if I needed a particular shell, I could always hardcode that into the command). In this case, the first argument could either be a string, which would execute that as the entire command name; or a list of strings, whose first element is the command name and any following elements are arguments.

Actually, if this were implemented, it would probably make more sense to switch shell() to exec() and do the transition similarly to prompt() -> input(). Of course, this is nothing urgent as I have a perfectly acceptable solution, just a suggestion in case you're bored one day and decide to do it. ;-)

While we're on the subject, here's something else for the not-urgent-but-would-be-kinda-nice-and-pretty-cool wishlist. An object similar to a savefile that executes an external program and communicates with it via a bi-directional pipe. Communication could be done with the << and >> operators as with savefiles. This, of course, would pretty much eliminate the need for a shell/exec proc, as it would handle those cases, plus eliminate the need to always redirect communications to/from files on the disk. Maybe in BYOND 3.x. ;-)
On 4/13/01 7:07 pm Air Mapster wrote:

This got me thinking, why not make an optional second argument to shell(), which if true, tells it to execute the command given directly instead of passing it to /bin/sh or whatever (by the way - does it use /bin/sh or the user's default shell? just curious - I suppose if I needed a particular shell, I could always hardcode that into the command). In this case, the first argument could either be a string, which would execute that as the entire command name; or a list of strings, whose first element is the command name and any following elements are arguments.

On unix, shell() just calls system(), which executes as /bin/sh I believe. In windows, it's a bit more convoluted. In fact, I don't think it actually goes through the shell right now because I was having problems avoiding the dos-console popup (the literal shell) without breaking other behavior. So I don't think redirection and pipes and such currently work for shell() in windows. That's on my list.

I like the exec() idea; that should be a trivial addition (but may not happen too soon as we are in a bit of a crunch .. we'll see).

While we're on the subject, here's something else for the not-urgent-but-would-be-kinda-nice-and-pretty-cool wishlist. An object similar to a savefile that executes an external program and communicates with it via a bi-directional pipe. Communication could be done with the << and >> operators as with savefiles. This, of course, would pretty much eliminate the need for a shell/exec proc, as it would handle those cases, plus eliminate the need to always redirect communications to/from files on the disk. Maybe in BYOND 3.x. ;-)

That is an excellent idea. It would make interprocess communication a lot more clean. But I think I agree with your evaluation: BYOND 3.x.

I was originally going to pass that information as arguments to the external program (shell("./program [inputfromplayer]")) until I realized that it posed a ssecurity risk.

One solution is to use list2params() to encode a list of key/value pairs as a parameter string, just like the parameter string that a web server passes to CGI programs. It is guaranteed to have all special characters % encoded.

Of course, that's only an option if you have control over how the external program parses its arguments.

--Dan
In response to Tom

That is an excellent idea. It would make interprocess communication a lot more clean. But I think I agree with your evaluation: BYOND 3.x.


only if byond 3.x means 3.0