.Dd Sat Jan 19 22:09:40 EST 2008 .Dt MSHELL 1 .Sh NAME .Nm mshell .Nd a Unix menuing shell .Sh SYNOPSIS .Nm mshell .Op Fl s .Ar menuname .Sh DESCRIPTION Some random notes on mshell. 1. Startup. If the file .mshellrc exists in the users home, it is run via "sh". Useful to run some intro commands, but not set variables, etc. (Good for stty's though.) 2. Userlog. If you define LOGDIR (in Makefile) to an existing dir, then user activity will be logged. The dir should be mode 733 so users can't poke around. Every menu pick a user makes is appended to a file with their username; this file is never cleaned up - you do it yourself. 3. Environment vars. Work inside menu values, as does ~ for home dir. 4. Built ins. cd and setenv are built in. The command 'menu' invokes mshell recursively (within the same process, that is). 5. Command line parameters. One -- the name of the menu to run. If the name has a / in it, that is used as the path. If no /, then then MENUDIR/name is used as the menu. There is two options, -r and -s, see below re "security". 6. Security. If the -s (secure) option is given, then users can not do !unix_command (or type meta-characters in their answers to prompts). If -s is not given, then these are allowed. (Also, it helps to set the SHELL environment variable to something like /bin/true, or better yet, a command that echoes "You can't have a shell, sorry.".) Note that some programs, e.g., vi and rn, can be coaxed into giving a shell. .mshellrc is obviously a security risk too. Of course, if you don't tell anyone about it, and they'll never know it's there :-) I use a wrapper around the menu (menulogin) that removes .mshellrc, for example. Note that this shouldn't be trusted for genuine security, since it's nearly impossible to eliminate the ways one can get a shell (I gave it a good whack, modifying binaries of various programs, hacking on source for others, etc.; it's too much hassle and still can be circumvented). For that reason, I added the -r option, which limits menu options to only those found in the #define COMMAND_LIST file. These can be names only or paths, but in either case must match exactly what's in the menu file. This can be used to limit access to only specific commands (which, presumably, you trust -- beware!). I'd also grab a secure version of 'more' if you want users to be able to browse files with something other than 'cat' (namely, remove more's '!' and 'v' commands). The -r option also disallows responses to prompts in the menu (since these end up often verbatim in the command line). Any program that needs user input must prompt from within. Note that even with this, you must check each command allowed with great care. Most shell scripts can be subverted, for example, and many existing programs (more, mail, vi, just about anything with any sort of command mode). 7. Multiple commands on a line. If the user types pick1,pick2,pick3 then each will be executed as if the ',' were newlines. Use 'top,...' to get "absolute" picks, starting at the top of the menu tree. 8. Macros. You can create menu macros: create a file .mshellmac in your home directory, where you want to put lines like name=commands as in hist=top,i,h,x (top, info menu, 'h' for history, 'x' to exit menu back to main). And execute as #hist (including inside other macros or multi-command lines). 9. Help. Users can do 'help o' for some option 'o'. It'll print the man page for whatever man= or cmd= is set to. Format of menu file: screen layout ***** keyword \t description of action keyword will perform The top part of the screen is what the users sees -- it is just text, put whatever you want there. The bottom describes what commands have what action. action description - builds a command string as follows: cmd=name of command (like arg=, but no _ translation) prompt=prompt to print (will be followed by colon and space;) arg=literal argument to include at this posistion in command string. aarg=append literal (like arg=, but no space put before it; e.g., to append a filename extension) aprompt=prompts and appends to previous arg help=name of helpfile to print (printed immediately) man=name of manual entry if cmd= isn't interesting No = is the same as "arg=". In prompt= and arg= underscores will be translated to spaces on output and are mandatory in multi-word strings (i.e., if you have "prompt=foo bar" the prompt will be foo and bar will be looked on as the next action description word; instead do "prompt=foo_bar"). Tabs in strings don't work (could be handled similar to _ for space, but aren't at present). The result is put into a string; if it has any special characters that should be handled by a shell, then the result is fed to system() so the shell (csh in particular) can deal with it. Otherwise, mshell executes the command directly. If the first keyword listed is _init, this command will be executed upon entry into the menu (before any selection). At "Enter choice" prompt, a response beginning with ! causes the remainder of the line to be executed verbatim. (E.g., !who will run a who.) Recommendations: Use full pathnames for filenames. Use multiple main menus for different classes of users. You'll need various script files as wrappers around commands. Look on Nyx (nyx.cs.du.edu, login as 'new') for various examples. .Sh AUTHOR Andrew Burt, aburt@du.edu