brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/21/90)
In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: > Without source code to "vi" there is NO WAY to prevent this. Believe me. How fatalistic. It's easy to prevent shell escapes from vi. All you have to do is make sure that the : and ! characters aren't accessible from command mode. This takes one command: % pty -0 tr \:\! \?\? | pty vi Of course, you should have keyboard signal characters turned off. And you need to pick up a copy of pty, which hasn't yet been ported to System V. Under BSD, though, you don't need to do any coding work. A more polite solution is to convert : into <esc>a:, and convert ! into <esc>a!. In any case you should provide macros to exercise a limited subset of the functions of : and !---to let the user :set nu or nonu, for example. Can we stop discussing this problem now? It's solved. ---Dan
brad@looking.on.ca (Brad Templeton) (09/21/90)
Pretty drastic to forbid certain characters like :! in vi. I once set up my system with a special subdirectory that had a mini root filesystem on it. I then created a login shell that chroot'd the users into that directory and started up their shell there. They can play there all they want, and it is safe. As long as you keep permissions clean on the main subdirectories (ie. don't leave /etc and /dev and its important files unprotected) you are fine. You link in the files and binaries you want to give them. There are a few problems, of course: a) Unless you have symlinks, you can't link in files that are on a different filesystem. In general, you either want to create this mini system on the root FS (so you can link in stuff from /bin and /usr) or you have to waste a lot of disk space copying those binaries. b) Users can't change their passwords, unless you make some special program that looks at their fake password file and copies up passwords, which is risky. c) Unless the news spool happens to be inside the protected subtree, as well as the news library, users can't read news. *but*, you can run NNTP on the machine, the server running in the real world and the client in the protected world. Chroot plus symlinks would create the perfect secure mini-environment. You are fully protected unless the pesky users can figure out how to become root. Most tricks for doing this involve greek horses or fiddling with files used by suid programs. But this rarely works if all you have access to is the subdir. -- Brad Templeton, ClariNet Communications Corp. -- Waterloo, Ontario 519/884-7473
martin@mwtech.UUCP (Martin Weitzel) (09/22/90)
In article <11285:Sep2022:15:2090@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: Dan> X-Original-Subject: Protecting against downloads Dan> In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: > Without source code to "vi" there is NO WAY to prevent this. Believe me. Dan> How fatalistic. Dan> It's easy to prevent shell escapes from vi. All you have to do is make Dan> sure that the : and ! characters aren't accessible from command mode. Dan> This takes one command: Dan> % pty -0 tr \:\! \?\? | pty vi Maybe it's because I don't know exactly what `pty' does or I have missed a smiley, but - I can get an ex-promt from command mode also with "Q" and can type "sh" from there (seems that "Q" should be disabled as well) - I can `execute buffers' with the "@" - a less known but very useful feature (seems "@" would have to be disabled as well) Dan> Can we stop discussing this problem now? It's solved. Sure? Maybe there occur still some other possibilities. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
martin@mwtech.UUCP (Martin Weitzel) (09/23/90)
In article <1990Sep21.040106.14873@looking.on.ca> brad@looking.on.ca (Brad Templeton) writes: >Pretty drastic to forbid certain characters like :! in vi. (And it isn't sufficient, as I pointed out in another article.) > >I once set up my system with a special subdirectory that had a mini >root filesystem on it. > >I then created a login shell that chroot'd the users into that directory >and started up their shell there. Many systems today support an asterix in the login-shell field of /etc/passwd. In this case, the standard-login chroot-s to the home directory and re-executes itself. Ie. you can simply place /etc and /bin below the new root. Effectively, login becomes a two-step procedure now: First you must login to the chroot-environment (password controlled by standard /etc/passwd), then you login to your account within the mini-root (password controlled by the /etc/passwd *there*). >They can play there all they want, and it is safe. As long as you keep >permissions clean on the main subdirectories (ie. don't leave /etc and >/dev and its important files unprotected) you are fine. You link in >the files and binaries you want to give them. Despite the duplicated disk space I would rather copy files, as this makes them a bit more protected against infecting them with viruses, if - by accident - the permissions for the executable are not set right. >There are a few problems, of course: >a) Unless you have symlinks, you can't link in files that are on a >different filesystem. In general, you either want to create this mini >system on the root FS (so you can link in stuff from /bin and /usr) or >you have to waste a lot of disk space copying those binaries. See above. >b) Users can't change their passwords, unless you make some special >program that looks at their fake password file and copies up passwords, >which is risky. With the method describe in the beginning, users can't change the password for login to the mini-root, but hey *can* change the password for login into their account there! >c) Unless the news spool happens to be inside the protected subtree, as >well as the news library, users can't read news. *but*, you can run >NNTP on the machine, the server running in the real world and the client >in the protected world. Similar schemes could be set-up for other purposes. Eg. "rn" could be split in a "server" and a "client", which communicate through named pipes. The client is started from the protected subtree, the server sits on the other side in the normal environment. As data-transfer through named pipes can be considered reliable and doesn't involve all the nastynesses of transmission lines, an RPC-scheme could become amazingly simple (you need not provide for asynchronous events or lost or garbled messages). What would be necessary were to identify all the operations (esp. opening, reading and writing files) which must be executed in the original root (not the protrected sub-tree) and map them into calls to the server. It should suffice to copy a unique ID for the called function plus the unchanged parameters "upstream" to the server, read what comes back "downstream" and reassemble it as it would normally appear when the specific functions returns. The server could also be kept very simple: It must switch to the called function using the uniq ID, then assemble the bytes that come upstream from the client as function parameters, call the function, gather the result and copy it downstream to the client. >Chroot plus symlinks would create the perfect secure mini-environment. >You are fully protected unless the pesky users can figure out how to >become root. Most tricks for doing this involve greek horses or fiddling >with files used by suid programs. But this rarely works if all you have >access to is the subdir. Agreed. Breaking out from a chrooted environment would at least afford to become super-user and still isn't simple then - besides much knowledge about the specific system at least an editor for binary files were required. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
vtcqa@shamash.cdc.com (Jeff Comstock) (09/23/90)
In article <11285:Sep2022:15:2090@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >X-Original-Subject: Protecting against downloads > >In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: >> Without source code to "vi" there is NO WAY to prevent this. Believe me. > >How fatalistic. > >It's easy to prevent shell escapes from vi. All you have to do is make >sure that the : and ! characters aren't accessible from command mode. You gotta be kidding . What good is vi without : ? Might as well not even use it. It's like giving your son your car, but not letting him put gas in it. Whoop de doo.
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/24/90)
In article <924@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: > In article <11285:Sep2022:15:2090@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: [ that as long as : is available, you can get a shell ] > > >Without source code to "vi" there is NO WAY to prevent this. Believe me. > > How fatalistic. [ trash the colon with pty -0 tr \: \? | pty vi ] [ questions the solution ] I did mention that you have to set up appropriate macros as well, and turn off keyboard interrupts. The only thing that you can't completely control from within vi is the mapping of the colon---and my solution handles that. ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/24/90)
In article <26116@shamash.cdc.com> jrc%brainiac.uucp@shamash.cdc.com writes: > You gotta be kidding . What good is vi without : ? Might as well not > even use it. It's like giving your son your car, but not letting > him put gas in it. Whoop de doo. I said in another article that you should provide macros (not using the disabled characters) to give the user whatever functions he really needs. The only fundamental problem is that vi doesn't let you remap the colon---and pty tr \: \? | pty vi takes care of that. A more appropriate answer might be: ``You gotta be kidding . What good is UNIX without sh ? Might as well not even use it. It's like giving your son your car, but not letting him put gas in it. Whoop de doo.'' ---Dan
les@chinet.chi.il.us (Leslie Mikesell) (09/24/90)
In article <27387:Sep2320:07:3890@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > [ trash the colon with pty -0 tr \: \? | pty vi ] > >I did mention that you have to set up appropriate macros as well, and >turn off keyboard interrupts. The only thing that you can't completely >control from within vi is the mapping of the colon---and my solution >handles that. Umm... Well, there's 'Q' to go to ex mode and stay there while you type sh, or if the tmp file that you start out with contains the outlawed ":" and/or "!" characters (or you manage to read them in from some other file) you can just edit them into the construction you need, yank to a register and execute. Leaves something to be desired as a form of security.... Les Mikesell les@chinet.chi.il.us
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/24/90)
In article <1990Sep24.040745.10454@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: > In article <27387:Sep2320:07:3890@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > [ trash the colon with pty -0 tr \: \? | pty vi ] > >I did mention that you have to set up appropriate macros as well, and > >turn off keyboard interrupts. The only thing that you can't completely > >control from within vi is the mapping of the colon---and my solution > >handles that. > Umm... Well, there's 'Q' to go to ex mode and stay there while you > type sh, [ blah blah blah ] Read my lips: ``The only thing that you can't completely control from within vi is the mapping of the colon---and my solution handles that.'' You can map Q. You can map @. You can even map !---I didn't realize this at first. You can map every single f-ing character the user can type. Except the colon. > Leaves something to > be desired as a form of security.... RTFABYFU. ---Dan
greg@cheers.Bungi.COM (Greg Onufer) (09/25/90)
>There are a few problems, of course: >a) Unless you have symlinks, you can't link in files that are on a >different filesystem. In general, you either want to create this mini >system on the root FS (so you can link in stuff from /bin and /usr) or >you have to waste a lot of disk space copying those binaries. [[ ... stuff deleted ... ]] >Chroot plus symlinks would create the perfect secure mini-environment. Not really. Symlinks will not work in a chroot-ed environment since the files they "point" to are not accessible. You have to use hardlinks or copy the files. (I encountered this with SunOS 4.0 a while back). Cheers!greg
martin@mwtech.UUCP (Martin Weitzel) (09/26/90)
In article <1038:Sep2414:36:0390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <1990Sep24.040745.10454@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: >> In article <27387:Sep2320:07:3890@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> > [ trash the colon with pty -0 tr \: \? | pty vi ] [...] >> Umm... Well, there's 'Q' to go to ex mode and stay there while you >> type sh, > [ blah blah blah ] > >Read my lips: ``The only thing that you can't completely control from >within vi is the mapping of the colon---and my solution handles that.'' >You can map Q. You can map @. You can even map !---I didn't realize this >at first. You can map every single f-ing character the user can type. >Except the colon. Dan, calm down. I confess that after your first posting I had not understood your proposual to map all "dangerous" command from *within* vi and that mapping Q, @, and ! to <esc> so could effectively disable these commands. But playing a little with vi, to confirm if it could work, revealed other interesting things. If you have two minutes time, please try the following: 2000i-<esc> This should construct a line of 2000 characters, which is above the limits at least my vi (386/ix Rel 2.0.2) can handle. Then insert another character into this line ... and whoops, vi throws you into ex-mode. Nice feature - who would ever have thought? Possibly some user which you carefully tried to keep away from ex-prompts knows this little "feature" (who said it is a bug?). Vi wasn't designed for what you have in mind. It MUST be fixed in the vi-sources, if it should work reliable! I would never trust in any other solution. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
peter@ficc.ferranti.com (Peter da Silva) (09/27/90)
In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: > Without source code to "vi" there is NO WAY to prevent this. Believe me. adb -w /bin/vi Just zap the "/bin/sh" and the name of the "shell" variable. -- Peter da Silva. `-_-' +1 713 274 5180. 'U` peter@ferranti.com
wayne@dsndata.uucp (Wayne Schlitt) (09/27/90)
In article <PA06YE4@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes: > In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: > > Without source code to "vi" there is NO WAY to prevent this. Believe me. > > adb -w /bin/vi > > Just zap the "/bin/sh" and the name of the "shell" variable. ok, /bin/sh can be zapped easily, but i am not sure about the SHELL variable. what to you zap it to? changing "SHELL" to "XXXXX" just moves the problem, using unprintable characters probably wont solve it either. would zapping the 'S' to a '\0' really work? looking through the /bin/vi on our hp-ux system, there are also the strings "shell" and "sh"... are those for the :shell commands? do they need to be zapped? i havent try any of this, but without source, it would be hard to verify that all the holes are plugged. (note that i didnt say impossible, 'cause with adb, _anything_ is possible :-) -wayne
les@chinet.chi.il.us (Leslie Mikesell) (09/28/90)
In article <935@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >If you have two minutes time, please try the following: 2000i-<esc> >This should construct a line of 2000 characters, which is above the >limits at least my vi (386/ix Rel 2.0.2) can handle. Then insert >another character into this line ... and whoops, vi throws you into >ex-mode. >Nice feature - who would ever have thought? Possibly some user which >you carefully tried to keep away from ex-prompts knows this little >"feature" (who said it is a bug?). Yep, not to mention the "tmp file too large" problem that everyone that has ever used vi knows about. It just takes a little more work to make that one happen. Les Mikesell les@chinet.chi.il.us
bhh@hriso.ATT.COM (Brad Hansen) (09/28/90)
In article <935@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >If you have two minutes time, please try the following: 2000i-<esc> >This should construct a line of 2000 characters, which is above the >limits at least my vi (386/ix Rel 2.0.2) can handle. Then insert >another character into this line ... and whoops, vi throws you into >ex-mode. > >Nice feature - who would ever have thought? Possibly some user which >you carefully tried to keep away from ex-prompts knows this little >"feature" (who said it is a bug?). Fallback to 'ex' mode when vi hits something beyond its capabilities is a well known feature of vi and the other editors based on ex, although it is admittedly not in the man pages. What would you prefer, a core dump? Brad Hansen att!attmail!hansenb or brad.hansen@att.com
ant@brolga.cc.uq.oz.au (Anthony Murdoch) (09/28/90)
wayne@dsndata.uucp (Wayne Schlitt) writes: >In article <PA06YE4@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes: >> In article <1990Sep20.153105.28394@naitc.naitc.com> karl@bbs.naitc.com (Karl Denninger) writes: >> > Without source code to "vi" there is NO WAY to prevent this. Believe me. >> >> adb -w /bin/vi >> >> Just zap the "/bin/sh" and the name of the "shell" variable. >ok, /bin/sh can be zapped easily, but i am not sure about the SHELL >variable. what to you zap it to? changing "SHELL" to "XXXXX" just >moves the problem, using unprintable characters probably wont solve it >either. would zapping the 'S' to a '\0' really work? If you change SHELL to something and then make vi unreadable then surely that makes it secure enough for you (unless of course you don't want to allow root to have a shell ;-) ant -- V ant "It's great to be young and insane" \o/ ant@brolga.cc.uq.oz.au - Dream Team -O- Anthony Murdoch Prentice Computer Centre /0\ Phone (07) 3774078 University of Qld
zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) (09/29/90)
I suggest getting one of the PD or freely sharable vi or emacs clone editors and modifying the code to prevent shell escapes. -- Jon Zeeff (NIC handle JZ) zeeff@b-tech.ann-arbor.mi.us
ronald@robobar.co.uk (Ronald S H Khoo) (09/29/90)
ant@brolga.cc.uq.oz.au (Anthony Murdoch) writes: > If you change SHELL to something and then make vi unreadable then surely that > makes it secure enough for you (unless of course you don't want to allow root > to have a shell ;-) NO! Security through obscurity doesn't work. Just leave the normal copy of vi alone, and put the hacked copy of vi into your secure chrooted area. Oh, and *don't* call the copy "vi" -- sysadmins might get confused and link the original one back into the was-secure area, and anyway you don't want to accidentally invoke it -- it gets VERY annoying when *you* can't shell escape. -- ronald@robobar.co.uk | +44 81 991 1142 (O) | +44 71 229 7741 (H) | YELL! "Nothing sucks like a VAX" -- confirmed after recent radiator burst! Hit 'R' <RETURN> to continue .....
dylan@ibmpcug.co.uk (Matthew Farwell) (09/29/90)
In article <1990Sep27.215910.11192@hriso.ATT.COM> bhh@hriso.ATT.COM (Brad Hansen) writes: >In article <935@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >>If you have two minutes time, please try the following: 2000i-<esc> >>This should construct a line of 2000 characters, which is above the >>limits at least my vi (386/ix Rel 2.0.2) can handle. Then insert >>another character into this line ... and whoops, vi throws you into >>ex-mode. >> >>Nice feature - who would ever have thought? Possibly some user which >>you carefully tried to keep away from ex-prompts knows this little >>"feature" (who said it is a bug?). > >Fallback to 'ex' mode when vi hits something beyond its capabilities >is a well known feature of vi and the other editors based on ex, >although it is admittedly not in the man pages. What would you >prefer, a core dump? The 2000i-<ESC> thing doesn't actually put you back into ex mode on my version of vi (Xenix 2.3.1), but I agree that there are a lot more ways to do this. For instance, on this atari I'm sitting in front of, the shift 3 key (which is marked #) is actually mapped by the terminal emulation to '^\', which puts me into ex mode. Tell me how would you fix that without source? Taking out ex commands takes away half the powers of vi. I don't think I could live without :set + :s. All this means we come back to the statement: The ONLY way to make vi safe is to hack the source code. Dylan. -- Matthew J Farwell | Email: dylan@ibmpcug.co.uk The IBM PC User Group, PO Box 360,| ...!uunet!ukc!ibmpcug!dylan Harrow HA1 4LQ England | CONNECT - Usenet Access in the UK!! Phone: +44 81-863-1191 | Sun? Don't they make coffee machines?
wayne@dsndata.uucp (Wayne Schlitt) (09/29/90)
In article <1990Sep29.002328.27798@ibmpcug.co.uk> dylan@ibmpcug.co.uk (Matthew Farwell) writes: > [ ... ] > > All this means we come back to the statement: > > The ONLY way to make vi safe is to hack the source code. > and this statement is quite wrong. you _can_ make vi (or any other program that you can read the binary) secure by disassembling it and zapping various parts of the binary. source just makes life easier... -wayne
scs@lokkur.dexter.mi.us (Steve Simmons) (09/30/90)
In article <935@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >. . . . and whoops, vi throws you into ex-mode. >Nice feature - who would ever have thought? Possibly some user which >you carefully tried to keep away from ex-prompts knows this little >"feature" (who said it is a bug?). bhh@hriso.ATT.COM (Brad Hansen) writes: >Fallback to 'ex' mode when vi hits something beyond its capabilities >is a well known feature of vi and the other editors based on ex, >although it is admittedly not in the man pages. What would you >prefer, a core dump? Of course not. Please recall this thread is about whether or not it is possible to disable shell escapes in vi without source. The point of Weitzels comments is that is probably isn't. He correctly leaves the point open as to whether it's a bug or a feature; and for the sake of this discussion I will do the same. The end result is still "No, it's probably not possible."
dag@gorgon.uucp (Daniel A. Glasser) (10/01/90)
Maybe someone else has posted this solution, maybe not. I've not seen it mentioned. I've not tried it either. My suggestion is to write a wrapping routine which checks the users gid or uid (or whatever) and based on that either leaves the users PATH and SHELL alone (for those who should be allowed to shell out of vi) or changes both PATH and SHELL environment variables to something safe, (SHELL will point to something like 'main(){write(0,"No shell for you!\n");exit(1);}' and PATH to something which just has what vi might legitimately have to get at. This program will then exec the real vi. I've not tried this with vi, but I have with many games programs. I had one wrapper program which I linked (hard links) to the names of the protected executables, this program looked at argv[0] to determine what program to run (and in a few cases, what environment variables to change -- It would read in .game_FOO files and set environment variables from that file before running game FOO, thus simplifying the user's .profile/.login.) It seems to work. Daniel A. Glasser -- Daniel A. Glasser One of those things that goes dag%gorgon@persoft.com "BUMP! (ouch!)" in the night.
em@dce.ie (Eamonn McManus) (10/01/90)
In article <WAYNE.90Sep27073633@dsndata.uucp> wayne@dsndata.uucp (Wayne Schlitt) writes: >In article <PA06YE4@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes: ... >> Just zap the "/bin/sh" and the name of the "shell" variable. ... >ok, /bin/sh can be zapped easily, but i am not sure about the SHELL >variable. what to you zap it to? changing "SHELL" to "XXXXX" just >moves the problem, using unprintable characters probably wont solve it >either. would zapping the 'S' to a '\0' really work? Changing the string "shell" to a null string works. This string may occur twice, depending on the compiler: once for the :set shell option and once for the :shell command. You also want to get "sh" which is an allowed abbreviation for the shell option. >i havent try any of this, but without source, it would be hard to >verify that all the holes are plugged. I agree; if anyone is very concerned about security they should hack the source of some editor, not rely on patching binaries in the dark.
jik@athena.mit.edu (Jonathan I. Kamens) (10/02/90)
In article <1990Sep30.174404.6132@gorgon.uucp>, dag@gorgon.uucp (Daniel A. Glasser) writes: |> My suggestion is to write a wrapping routine which checks the users gid or |> uid (or whatever) and based on that either leaves the users PATH and SHELL |> alone (for those who should be allowed to shell out of vi) or changes both |> PATH and SHELL environment variables to something safe, (SHELL will point |> to something like 'main(){write(0,"No shell for you!\n");exit(1);}' |> and PATH to something which just has what vi might legitimately have to |> get at. This program will then exec the real vi. As someone else has already pointed out, it is possible to set the SHELL environment variable from inside vi, using a vi command. \begin{soapbox} Read the net before you post. RTFM before you post. \end{soapbox} -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
peter@ficc.ferranti.com (Peter da Silva) (10/02/90)
ant@brolga.cc.uq.oz.au (Anthony Murdoch) writes: > If you change SHELL to something and then make vi unreadable then surely that > makes it secure enough for you (unless of course you don't want to allow root > to have a shell ;-) No, you change shell (not SHELL) to the same name as another variable that gets found first in the search order (experiment to figure out what that order is). -- Peter da Silva. `-_-' +1 713 274 5180. 'U` peter@ferranti.com
jpr@jpradley.uucp (Jean-Pierre Radley) (10/02/90)
What follows is the oeuvre of the late, lamented Fred Buck: #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # rvi.c # rvish.c # rvi_install # This archive created: Tue Oct 4 20:35:03 1988 export PATH; PATH=/bin:$PATH if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' XBefore running the script 'rvi_install', read the introductory comments Xin both 'rvi.c' and 'rvi_install'. These comments will confer a feel Xfor what this package is intended to do and how it does it. X XAs distributed, 'rvi' allows users to reach an interactive RESTRICTED Xshell. If you don't want this to happen, then remove the files 'rsh' Xand 'sh' in the "rvi-directory". If you need further customization, Xread on: X X------------------------------------------- X XThe following material is intended for those who want or need to offer Xrestricted-'vi' users more flexibility than is provided by the bare editor, Xas for instance allowing access to specified filters to be used in Xprocessing text within the editor: X XThere's something you should know about the way 'vi' handles the ":!" Xand "!" shell escapes: the command you specify isn't invoked directly, Xinstead 'vi' calls *shell* to execute the command, with the syntax X X *shell* -c "<entire-command-line>" X XThe reason "*shell*" is enclosed in asterisks is that the shell we're Xtalking about is 'vi's own internal variable "shell", which is set via the X":set shell=whatever" command in 'vi'. This internal variable overrides Xthe environment variable $SHELL, although by default it starts out with Xthe value of $SHELL. X XIf all you're interested in is letting a restricted user have a fullscreen Xeditor, then no problem. However, if you want your restricted user to Xbe able to use 'vi's filtering capabilities, or if your restricted user Xmust be able to run shell programs from within 'vi', then be aware that Xincluded in this package is a counterfeit shell, called "./sh", that Xinvokes "./rsh" with the same arguments as were passed to "./sh". The Xeffect of all this is that a user's "!-escape" commands are executed Xas if they had been issued to /bin/rsh with the "-c" option-switch, Xalways. The user can't avoid the invocation of 'rsh' by his own action. XHowever, if the user's command is the name of a shell script, 'rsh' will Xexecute the script as if it were /bin/sh; be aware of this. If it all Xseems like doubletalk, read up on rsh(C) [or perhaps rsh(1)] and sh(C) X[sh(1)]. X XThe main thing to remember here is that if you absolutely, positively, Xwant to bar a restricted user from access to any sort of interactive Xshell, even the restricted shell, then you should remove the supplied Xprogram "sh" and undo the link or copy of "rsh" into the "rvi-directory". XIf you do this, then however the user won't be able to use 'vi's ability Xto filter text through external commands. SHAR_EOF chmod +x 'README' fi # end of overwriting check if test -f 'rvi.c' then echo shar: will not over-write existing file "'rvi.c'" else sed 's/^X//' << \SHAR_EOF > 'rvi.c' X/* File: rvi.c X * X * Name: X * rvi - restricted fullscreen text editor X * Syntax: X * rvi [filename] X * X * Description: X * 'rvi' remedies various security holes in the 'vi' fullscreen X * text editor. In 'vi', for example, it's impossible to prevent a X * user from invoking an interactive shell if the user chooses to X * do so, even if the user's running 'rsh' and the variable "SHELL" X * is set to "/bin/rsh" and is read-only, because 'vi' maintains X * its own internal "shell" variable and executes it via the ":sh" X * command. 'rvi' encapsulates the edit within a defined X * sub-universe within the filesystem so that the facilities X * accessible to the user are entirely within the control of the X * system administrator. X * X * Mechanics/Implementation: X * 'rvi' is invoked from a normal current-working-directory the X * same way that 'vi' would be, except that only one filename per X * invocation is acceptable. If a filename is specified, and if X * the specified filename exists and is writable by the user, or if X * the specified filename doesn't exist but the current working X * directory is writable by the user, 'rvi' links that filename to X * a temporary file within an "rvi-directory" (see below) and forks X * a child to edit the temporary file. The child chroot()'s to the X * "rvi-directory", so that nothing on the system outside that X * directory is further accessible and overlays itself with 'vi' to X * perform the edit. Programs available to the user are only those X * selected by the system administrator and linked (or copied) into X * the "rvi-directory" sub-hierarchy; in particular, interactive X * shells are inaccessible to the user unless /bin/sh (or some X * other shell) is/are linked (or copied) into the sub-hierarchy. X * X * If no filename is specified, 'rvi' creates a file called X * "btxtNNNNN" in the current directory, where "NNNNN" is the X * process ID number of the user's process. If that file has X * nonzero length on exit, the user is prompted for a new name for X * the file. The ":f" ex-escape command is available to the user X * from within 'vi', but is ineffectual if the "rvi-directory" is X * secured as the accompanying script 'rvi_install' secures it. X * Essentially the user is restricted to writing his specified edit X * file and no other file. X * X * The "rvi-directory" is an existing directory previously X * established by the system administrator, a directory that will X * mimic the root directory "/" during the edit. This directory X * must contain certain essential subdirectories, 'bin', 'tmp', X * 'etc', within which certain system files must be linked or X * copied. The accompanying script 'rvi_install' creates the X * "rvi-directory" hierarchy. X * X * 'rvi' looks first for an environment variable RVIDIR containing X * the pathname of the "rvi-directory"; if no such variable exists, X * 'rvi' looks for a pathname in the file "/etc/default/rvi" for X * the "rvi-directory"; if no such pathname exists in that file, or X * if that file doesn't exist, 'rvi' assumes that the X * "rvi-directory" is "/rvitmp". X * X * Copyright: X * X * This program was written by Fred Buck, who hereby releases it X * into the public domain and expressly relinquishes all copy- or X * other-rights regarding it. This code is public property. However, X * the author disclaims liability for any use of this code. X * X * NOTES/BUGS X * X * The filename displayed on the 'vi' status line will always be X * the name of the temporary file within the "rvi-directory", X * regardless of whether 'rvi' is invoked with or without a X * filename. Users should be warned about this. If the filename X * is changed with the ":f" ex-escape command, the user will be X * unable to write the results of his or her edit unless the X * filename is changed back to the name of the temporary file; X * users should be alerted to the ":f #" command to recover from X * such a circumstance, or else the system administrator may X * consider mapping an unused command key to the sequence ":f #^M" X * (see vi(1) or vi(C) for details). X * X * The shell variable TERM must be properly set before 'rvi' is X * called, or else the behavior of 'vi' will be erratic. 'rvi' is X * effective as well with 'ex' as with 'vi'; to call 'ex' X * specifically, change "vi" to "ex" in the code below, and link X * "/bin/ex" into the "rvi-directory". X * X * As noted above, the "rvi-directory" MUST reside on the same X * device as the user's current working directory. X * X * On SCO Xenix-286, DO NOT USE THE OPTIMIZING COMPILER SWITCH X * "-O" when compiling 'rvi'. The optimizer on SCO Xenix-286 is X * less than perfect, and chokes on this program. X */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <signal.h> X X#define BOZODIR "/rvitmp" /* default rvi-directory */ X#define READ 04 X#define WRITE 02 X#define EXECUTE 01 X#define OWNER 0100 X#define GROUP 010 X#define OTHER 01 X#define HIBYTE(x) (((x) >> 8) & 0xff) X#define LOBYTE(x) ((x) & 0xff) X#define WORD(x) ((x) & 0xffffL) X Xstatic struct stat buf; Xstatic char *progname; X X/* void Abort(): terminates execution with an error message. X * X * returns: nothing X */ XAbort(string1, string2) Xchar *string1, *string2; X{ X fprintf(stderr,"%s: ",progname); X fprintf(stderr,string1,string2); X exit(1); X} X X/* int perms_ok(): checks read, write or execute permission for real X * user or group ID X * X * returns: 1 if specified permission exists, 0 otherwise X */ Xperms_ok(statbuf, mode) Xstruct stat *statbuf; /* stat() buffer for file or directory */ Xint mode; /* READ, WRITE, or EXECUTE */ X{ X if (mode != READ && mode != WRITE && mode != EXECUTE) X return(0); X else if (getuid() == 0) X return(1); X else if ( statbuf->st_uid == getuid() X && (statbuf->st_mode & (mode * OWNER)) ) X return(1); X else if ( statbuf->st_gid == getgid() X && (statbuf->st_mode & (mode * GROUP)) ) X return(1); X else if ( statbuf->st_mode & (mode * OTHER) ) X eturn(1); X else return(0); X} X X/* main() X */ Xmain(argc, argv) Xint argc; char **argv; X{ X FILE *defalt; X char c, *bozodir; X int unnamed, newfile; X int kidstatus, kidpid; X static char tempname[80], filename[15]; X static char lastchance[80] = "/rvitmp"; X extern char *getenv(), *strchr(), *strrchr(), *strncpy(); X extern FILE *fopen(); X X newfile = unnamed = 0; X progname = argv[0]; X X /* establish which directory to use */ X if ((bozodir=getenv("RVIDIR"))!=0) X ; X else if ((defalt=fopen("/etc/default/rvi","r")) != (char *)0) { X fgets(lastchance,80,defalt); X *(strchr(lastchance,'\n')) = '\0'; X bozodir = lastchance; X if (*bozodir == '\0') bozodir = BOZODIR; X fclose(defalt); X } X else bozodir = BOZODIR; X X /* check permissions and initialize stuff */ X if (argc == 1) { /* no edit file specified */ X sprintf(filename,"btxt%d",getpid()); X newfile = unnamed = 1; X } X else { /* file specified */ X if (argc > 2) X Abort("only one filename allowed\n",""); X if (strchr(argv[1],'/')) X Abort("bad filename '%s' (not a basename)\n",argv[1]); X if (strlen(argv[1]) > 14) X Abort("bad filename '%s' (too long)\n",argv[1]); X strncpy(filename,argv[1],14); X if (stat(filename,&buf)==0) { /* file exists */ X if (!perms_ok(&buf,WRITE)) X Abort("can't write file '%s'\n",filename); X } X else newfile = 1; /* file doesn't exist */ X } X X if (newfile) { X if (stat(".",&buf) < 0) X Abort("can't stat working directory\n",""); X if (!perms_ok(&buf,WRITE)) X Abort("can't write in working directory\n",""); X /* let a kid create the file with the user's real uid/gid */ X /* (we could create it ourself as 'root', and chown(), but */ X /* this ensures that the creat() succeeds or fails by the */ X /* user's own real permissions). */ X if ((kidpid=fork())==0) { X if (setgid(getgid())<0 || setuid(getuid())<0) X exit(1); X else X exit(creat(filename,0644)<0); X } X wait(&kidstatus); X if ( kidpid < 0 X || LOBYTE(kidstatus) != 0 X || HIBYTE(kidstatus) != 0 ) X Abort("internal error (filename create)\n",""); X } X X /* link the file-to-edit to a made-up name in the temp directory */ X sprintf(tempname,"%s/btxt%d",bozodir,getpid()); X if (link(filename,tempname)<0) { X fprintf(stderr,"%s: ",argv[0]); X perror("system error"); X Abort("internal error (link failure)\n",""); X } X X /* fork a kid to do the edit */ X if ((kidpid=fork())==0) { /* this is the kid */ X if (chdir(bozodir)<0) X Abort("internal error (chdir failure)\n",""); X if (chroot(".")<0) X Abort("internal error (chroot failure)\n",""); X if (setgid(getgid())<0 || setuid(getuid())<0) X Abort("internal error (setgid/setuid)\n",""); X execl("vi","vi",strrchr(tempname,'/')+1,0); X exit(1); /* exec() failed */ X } X else { /* this is the parent */ X signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN); X wait(); X } X X /* the edit's over now, take care of supplementary housekeeping */ X link(tempname,filename); /* just in case */ X unlink(tempname); /* don't need it anymore */ X if (stat(filename,&buf)<0) /* weird case: file gone */ X exit(1); X if (buf.st_size==0) { /* if filesize zero, */ X if (newfile) /* kill it if new file, */ X unlink(filename); X exit(0); /* else just bail out */ X } X /* if the file's unnamed (i.e., "btxtNNNNN"), name it */ X if (kidpid > 0 && unnamed) { X printf("\nThe current filename is '%s'.\n",filename); X printf("Do you want to rename it? "); X c = getchar(); X while (getchar()!='\n'); X if (c!='y' && c!='Y') X exit(0); X else { X printf("New filename: "); X fgets(tempname,15,stdin); X *(strchr(tempname,'\n')) = '\0'; X if (strlen(tempname)==0) exit(0); X link(filename,tempname); X unlink(filename); X } X } X exit(0); X} SHAR_EOF chmod +x 'rvi.c' fi # end of overwriting check if test -f 'rvish.c' then echo shar: will not over-write existing file "'rvish.c'" else sed 's/^X//' << \SHAR_EOF > 'rvish.c' X/* File: rvish.c X * X * syntax: sh [arguments] X * X * Description: X * This program is intended solely for use as a dummy shell in X * connection with the 'rvi' restricted fullscreen editor. All it does X * is convert its arguments into arguments for 'rsh', the restricted X * shell. X * X * It should reside within the top level of the "rvi-directory". X */ X Xmain( argc, argv ) Xint argc; char **argv; X{ X *argv = "rsh"; X execv(*argv,argv); X} SHAR_EOF chmod +x 'rvish.c' fi # end of overwriting check if test -f 'rvi_install' then echo shar: will not over-write existing file "'rvi_install'" else sed 's/^X//' << \SHAR_EOF > 'rvi_install' X: X# rvi_install: installation script for 'rvi' (must be run as 'root'). X# X# READ THE FOLLOWING CAREFULLY: X# This script is invoked as "sh rvi_install <rvi-parent-directory>" where X# "<rvi-parent-directory>" is an existing directory underneath which you X# want the "rvi-directory" to reside. If you want the "rvi-directory" to X# be called something other than "rvitmp", change the definition of X# "rvidir" below. To install the "rvi-directory" as a sub-directory X# of your current directory, use "sh rvi_install ."; to install it as X# a sub-directory of some other directory, use "sh rvi_install <otherdir>" X# where "<otherdir>" is the name of that other directory. Note that X# for a user to run 'rvi', there must be an "rvi-directory" on the device X# or partition where the user's current directory is located, and if X# this "rvi-directory" isn't the one named in /etc/default/rvi, then X# the user's environment variable $RVIDIR must be set to the name of X# the "rvi-directory" on the user's local device or partition. X# X# Additional programs that you want to make accessible from within 'rvi' X# should be linked or copied into either the rvi-directory, or the X# 'bin' subdirectory of the rvi-directory. You must not have removed X# the distributed files 'rvi' or 'sh' in the "rvi-directory" if you want X# users to be able to reach external programs. X# X Xif [ $# -ne 1 ]; then X echo "$0: usage: $0 <rvi-parent-directory>" 1>&2 X exit 1 Xfi XRVIPRT=$1 Xrvidir="$RVIPRT/rvitmp" X Xif [ ! -f "rvi.c" ]; then X echo "$0: can't find file 'rvi.c'" 1>&2 X echo "$0: aborting..." 1>&2 X exit 1 Xelse X echo "$0: compiling 'rvi.c'....." X if cc -o rvi rvi.c; then X chown root rvi; chmod u+s rvi; chmod a+x rvi; X if [ $? -ne 0 ]; then X echo "$0: can't resecure 'rvi'; aborting..." 1>&2 X exit 1 X fi X else X echo "$0: got a problem compiling 'rvi.c'" 1>&2 X exit 1 X fi Xfi Xif [ -f "rvish.c" ]; then X echo "$0: compiling 'rvish.c'; this will eventually become" X echo " the program 'sh' in the 'rvi-directory'....." X cc -o rvish rvish.c X chown bin rvish; chmod 0755 rvish; Xfi Xecho "Now creating working directories, linking files, and so forth:" Xecho " $rvidir....." Xmkdir $rvidir; chown bin $rvidir; chmod 0755 $rvidir Xecho " $rvidir/tmp....." Xmkdir $rvidir/tmp; chown bin $rvidir/tmp; chmod 0777 $rvidir/tmp Xecho " $rvidir/etc....." Xmkdir $rvidir/etc; chown bin $rvidir/etc; chmod 0755 $rvidir/etc Xecho " $rvidir/bin....." Xmkdir $rvidir/bin; chown bin $rvidir/bin; chmod 0755 $rvidir/bin Xecho " $rvidir/usr....." Xmkdir $rvidir/usr; chown bin $rvidir/usr; chmod 0755 $rvidir/usr Xecho " $rvidir/usr/lib....." Xmkdir $rvidir/usr/lib; chown bin $rvidir/usr/lib; chmod 0755 $rvidir/usr/lib Xif [ $? -ne 0 ]; then echo "$0: aborting"; exit 1; fi Xecho "$0: linking stuff:" Xecho " /etc/termcap....." Xln /etc/termcap $rvidir/etc/termcap; if [ $? -ne 0 ] X then X echo "$0: can't 'ln', doing 'cp' instead..." X cp /etc/termcap $rvidir/etc/termcap; X fi Xecho " /usr/lib/ex3.7strings....." Xln /usr/lib/ex3.7strings $rvidir/usr/lib/ex3.7strings; if [ $? -ne 0 ] X then X echo "$0: can't 'ln', doing 'cp' instead..." X cp /usr/lib/ex3.7strings $rvidir/usr/lib/ex3.7strings X fi Xecho " /bin/vi....." Xln /bin/vi $rvidir/vi; if [ $? -ne 0 ] X then X echo "$0: can't 'ln', doing 'cp' instead..." X cp /bin/vi $rvidir/vi X fi Xecho " /bin/sh (don't worry, it's the restricted one)" Xln /bin/sh $rvidir/rsh; if [ $? -ne 0 ] X then X echo "$0: can't 'ln', doing 'cp' instead..." X cp /bin/sh $rvidir/rsh X fi Xln $rvidir/rsh $rvidir/bin/rsh Xln ./rvish $rvidir/sh; if [ $? -ne 0 ] X then X echo "$0: can't 'ln', doing 'cp' instead..." X cp ./rvish $rvidir/sh X fi Xln $rvidir/sh $rvidir/bin/sh Xecho "$0: writing /etc/default/rvi....." Xcd $rvidir; echo `pwd` >/etc/default/rvi; chmod 0644 /etc/default/rvi Xecho "$0: done" SHAR_EOF chmod +x 'rvi_install' fi # end of overwriting check # End of shell archive exit 0
dag@gorgon.uucp (Daniel A. Glasser) (10/09/90)
In article <1990Oct1.190141.29659@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes: > As someone else has already pointed out, it is possible to set the SHELL >environment variable from inside vi, using a vi command. > >\begin{soapbox} > Read the net before you post. RTFM before you post. >\end{soapbox} **** FLAME ON **** Okay, I just finished reading TFM. The only version of vi docs that I have on hand are from a SYS-III implementation. They make no mention of how to set an environment variable from within vi. I've checked the man page under the version of SYS-V that I am using (ISC V2.2), and that also gives no clue of how to go about changing an environment variable from within vi. I'll admit that I've hated vi from the day I first set eyes on it oh so many years ago, thus have never learned the backdoors, etc., that lurk within vi. I had read the entire thread up to that point as it had arrived at my site. I've read much of the thread that has followed. I still have not seen this. DO NOT ASSUME THAT ALL MESSAGES FROM ALL PLACES GET TO A SITE IN THE SAME ORDER AS THEY DO TO YOUR SITE. OR EVEN THAT THEY GET THERE AT ALL. In all likelyhood, I've been posting to the net longer than you've had access to any kind of unix system, possibly computer. I've been a Unix user from very early 7th edition days. I have written several programs like the one I've described under RSTS/E, VMS, Unix v7, SysIII, and System V. I've never had any problems with any of them. It may be that vi has a back door that I don't know about. That is no reason to assume that tone. I may sound like a complete jerk, but I don't like being talked down to. **** FLAME OFF **** -- Daniel A. Glasser One of those things that goes dag%gorgon@persoft.com "BUMP! (ouch!)" in the night.
jik@athena.mit.edu (Jonathan I. Kamens) (10/10/90)
In article <1990Oct09.010323.22960@gorgon.uucp>, dag@gorgon.uucp (Daniel A. Glasser) writes: |> Okay, I just finished reading TFM. The only version of vi docs that I have |> on hand are from a SYS-III implementation. It is not my fault if your documentation is out-of-date. In the rest of this posting I will quote from the document "Vi Command & Function Reference", dated April, 1986, from the standard 4.3 BSD USD documents (taken from /usr/doc/usd/15.vi/vi.apwh.ms on my system). |> They make no mention of how |> to set an environment variable from within vi. You can't set ANY environment variable, you can set the SHELL environment variable, which is what I said in my posting. Or, at least, you can set the shell option in a way that will make vi use that shell in the future, no matter what SHELL is set to when vi is started (I don't know whether or not vi actually goes ahead and changes the environment variable, or only stores the shell to use in variable somewhere, but that's an irrelevant distinction, since the end result is pretty much the same). |> I've checked the man page |> under the version of SYS-V that I am using (ISC V2.2), and that also gives |> no clue of how to go about changing an environment variable from within vi. The command you want is ":set shell=foo", e.g. ":set shell=/bin/sh". You probably couldn't find it because you weren't looking for what I said you could do. I said you could change SHELL, you tried to find out how to change an arbitrary environment variable. From the document I mentioned above: Vi has a number of internal variables and switches which can be set to achieve special affects. These options come in three forms, those that are switches, which toggle from off to on and back, those that require a numeric value, and those that require an alphanumeric string value. ... Commands requiring a value are set with a command of the form: :set option=value<nl> ... Most of the options have a long form and an abbrevia- tion. Both are listed in the following table as well as the normal default value. ... shell sh Default: sh=from environment SHELL or /bin/sh Type: string This is the name of the sh to be used for "escaped" commands. |> I'll admit that I've hated vi from the day I first set eyes on it oh so many |> years ago, thus have never learned the backdoors, etc., that lurk within |> vi. I had read the entire thread up to that point as it had arrived at |> my site. I've read much of the thread that has followed. I still have |> not seen this. |> |> DO NOT ASSUME THAT ALL MESSAGES FROM ALL PLACES GET TO A SITE IN THE SAME |> ORDER AS THEY DO TO YOUR SITE. OR EVEN THAT THEY GET THERE AT ALL. There has been an entire thread about nuking the string "shell" in the vi binary so that people cannot use ":set shell" to change it. There are currently five messages from that thread in my spool area before the message of mine to which you responded, and that's not including the message that started the thread and at least one other message in the thread that I can recall (which is the one I was thinking above when I wrote that it had already been mentioned). The earliest one in my spool area is dated September 26, and as I said, there were earlier ones than that. My message is dated October 1. That's seven messages which *I* got before I got the one I posted to which you are responding. They were posted several days before the message of mine to which you are responding. I doubt very much that you didn't see any of them. |> In all likelyhood, I've been posting to the net longer than you've had |> access to any kind of unix system, possibly computer. I've been a Unix |> user from very early 7th edition days. I have written several programs |> like the one I've described under RSTS/E, VMS, Unix v7, SysIII, and |> System V. I've never had any problems with any of them. It may be |> that vi has a back door that I don't know about. That is no reason |> to assume that tone. Give me a break. "I'm older [or more experienced] than you, so you have to respect me and talk nice to me." Hogwash. If you do something brain-damaged, you still did something brain-damaged, whether you've been using Unix for a month or fifteen years. -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
bbs@bluemoon.UUCP (BBS login) (10/13/90)
jik@athena.mit.edu (Jonathan I. Kamens) writes: > matter what SHELL is set to when vi is started (I don't know whether or not v > actually goes ahead and changes the environment variable, or only stores the > shell to use in variable somewhere, but that's an irrelevant distinction, > since the end result is pretty much the same). The vi that ISC sends out with 2.2 seems to do that later rather than the former, for what that is worth... --- Grant DeLorean ...osu-cis!n8emr!bluemoon!grant ...towers!bluemoon!grant grant@bluemoon ++Being self employed, my opinions are remarkably similar to my employers. "The couple that heaves together, cleaves together." --- Loiosh