tchrist@convex.COM (Tom Christiansen) (08/27/90)
In article <8319:Aug2617:20:3690@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >This is the correct behavior. The difficulties with locking up tty ports >are reflections of two different problems: first, that ptys aren't >dynamically allocated in 4BSD; and second, that standard ttys exist at >all. Hardwired /dev/tty* should be replaced with raw /dev/modem* and so >on; *all* tty use should go through a common interface provided by a >pseudo-terminal session manager. This would solve many problems at once. I think there is a crying need such a thing because the same code gets written again and again to do essentially the same thin How would you like to see a pty session manager work? I'm going to throw out some off-the-cuff ideas, plus a lot of for-thought questions, to see what the net thinks. I'd like to solve at least these problems: 1. getting the pty name right (varies system to system) 2. race condition between choosing a name and trying the open 3. the need to be suid to get a pty 4. the need to chown the pty appropriately 5. the need to properly update utmp and wtmp Many programs (script, window, xterm) would no longer need to be setuid to munge utmp or chown ptys, which would be a nice plus. Off the top of my head, here are some ideas that are implementable on a BSD system. I would make a daemon server that everyone talked to in order to get the session. You could instead put it in the kernel as a special "/dev/pty" pseudo-driver that did the allocation for you, but I don't see much that having it in the kernel might gain you considering the cost. How might it actually work? If we used a UNIX-domain UDP socket, we could pass file descriptors between processes. Let the daemon do all the work of finding, opening, and chowning the pty, plus the [wu]tmp munging. He could just call if (getpty(&master_fd, &slave_fd) != -1) { and have the fd's filled in. Would we want to know the name? If so, we could something like this do this: if ((ptyname = getpty(&master_fd, &slave_fd)) != (char *)0) { You say, but wait, you might want to be able to make this work for remote logins, so I can't use UNIX domain sockets. Perhaps this is a valid point: if we did that, could we get rid of rlogind, telnetd, Then how would the file-descriptor hand-off take place? What about urgent data and stderr? Can the pty model really be adopted to the socket and connect method? Since telnet, rlogin, DECNET-style sethost, and Sun's "on -i" program all use different protocols, I suspect this is infeasible. Maybe we better leave it as is and keep and rlogind and friends around, but this is mildly unsettling. How would the daemon know that when the pty was free so that it could return the pty to the free pool and fix up utmp and wtmp? Rlogind knows because the login process is his child whom he waits on, but the session manager deals with unrelated processes. If the function were to actually spawn a login-shell on a pty, then it could wait for the kid to do the cleanup, but that sort of behavior wouldn't always be appropriate. If we placed it in the kernel, I supposed the close routine could know to do the right thing, but I wouldn't like to have the kernel mucking with [wu]tmp files. Maybe a stronger interaction with the kernel, as in Suns' lock daemon and its kernel RPC calls. Do you ever NOT want an entry in utmp? Sometimes ptys are used to run processes that just want a tty but aren't really a login session. Should they be? xterm (sometimes) and emacs don't currently put lines there, but I'm not sure whether this is a feature or not. If we really wanted it, we could have either two entry points or else an extra parameter. Could this be made to work using non-BSD systems? Would it eventually go in a POSIX spec, and if so, which one? Certainly system calls and library functions, but what of networking or system administration? Has this been done yet? Attempted? Contemplated? --tom -- "UNIX was never designed to keep people from doing stupid things, because that policy would also keep them from doing clever things." [Doug Gwyn]
moss@cs.umass.edu (Eliot Moss) (08/27/90)
An additional feature I definitely want is for the session manager to retain a session for some user-selectable time (with a system chosen upper bound) if the remote end drops before logout. I lose modem connections because of noise frequently, and it is really annoying to have to reconstruct my whole job tree when that happens. (The VMS pty stuff keeps sessions around as described, and when you relogin you get the option of connecting to your abandoned job or creating a new one.) -- J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206; Moss@cs.umass.edu
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (08/27/90)
In article <105387@convex.convex.com> tchrist@convex.COM (Tom Christiansen) writes: > In article <8319:Aug2617:20:3690@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >This is the correct behavior. The difficulties with locking up tty ports > >are reflections of two different problems: first, that ptys aren't > >dynamically allocated in 4BSD; and second, that standard ttys exist at > >all. Hardwired /dev/tty* should be replaced with raw /dev/modem* and so > >on; *all* tty use should go through a common interface provided by a > >pseudo-terminal session manager. This would solve many problems at once. > I think there is a crying need such a thing because the same code gets > written again and again to do essentially the same thing I agree. That's why pty 3.001, the ultimate pseudo-terminal manager, is about to come out in c.s.unix. It provides every good feature that Steve Bellovin mentions for his session manager, without the fuss. It's already been reported to work on a huge variety of BSD-based machines. > How would you like > to see a pty session manager work? The way pty works, with some support of course. > I'd like to solve at least these problems: > 1. getting the pty name right (varies system to system) pty solves this basically by hiding it from the user. ptys should not be tied to the filesystem; they should be allocated dynamically. pty makes sure that the user doesn't have to depend on filesystem ptys or static ptys. Anyway, as is it supports any pty bank names, e.g., /dev/fooXY for the master and /dev/boinkXY for the slave, with X from [54y-!] and Y from [01234treuio]. > 2. race condition between choosing a name and trying the open pty solves this (along with a host of other pty security problems). See the code in getfreepty(). > 3. the need to be suid to get a pty pty solves this. (Of course, it can be compiled and installed by unprivileged users on current insecure systems; I wouldn't want to take this away.) > 4. the need to chown the pty appropriately pty solves this, with a host of related options. > 5. the need to properly update utmp and wtmp pty supports both utmp and wtmp, again with a host of configuration options. > Many programs (script, window, xterm) would no longer need to be > setuid to munge utmp or chown ptys, which would be a nice plus. An improved clone of script is provided along with pty. It's a tiny shell script. It's just one of twenty-one free public-domain utilities provided with pty. > I would make a daemon server that everyone talked to in order to get > the session. I disagree. The right interface is pty's program-based interface. As an illustration of the power of the interface, the pty package includes patches for telnetd. The patches integrate pty session support into telnetd, so that users can disconnect and reconnect sessions with no effort. The interface is so good that the patched telnetd is just as efficient as the original version, believe it or not. Under pty's interface, there could be such a daemon, but the user shouldn't care. Also, you cannot achieve security unless you have a separate (setuid) process. > You say, but wait, you might want to be able to make this work for remote > logins, so I can't use UNIX domain sockets. Perhaps this is a valid > point: if we did that, could we get rid of rlogind, telnetd, Then how > would the file-descriptor hand-off take place? What about urgent data and > stderr? I'm not sure what you're asking here. pty's telnet patches aren't enough? > How would the daemon know that when the pty was free so that it could > return the pty to the free pool and fix up utmp and wtmp? pty handles this by just waiting for the child to exit. Note that it keeps output around for a disconnected session until you get a chance to reconnect. > Rlogind knows because the login process is his child whom he waits on, but > the session manager deals with unrelated processes. If the function were > to actually spawn a login-shell on a pty, then it could wait for the kid > to do the cleanup, but that sort of behavior wouldn't always be > appropriate. True. In fact, the right model for logins is as follows: You connect to (say) telnetd; telnetd starts a login process, *without* a pty; if you get in, your shell is (say) ``pty /bin/csh'', so that you get a pty. > Do you ever NOT want an entry in utmp? Sometimes ptys are used to run > processes that just want a tty but aren't really a login session. My interpretation of utmp is that it should reflect interactive sessions only. My PD wall clone uses utmp this way, as do talk programs. Anyway, pty has -xu and -xU options to turn utmp on and off; the sysadmin can require or disable utmp use, of course. > Could this be made to work using non-BSD systems? Well, I'm (slowly) working on a streams-based version, but I've never been very close to System V. (Help?) The pty interface would remain almost exactly the same. > Would it eventually > go in a POSIX spec, and if so, which one? Certainly system calls and > library functions, but what of networking or system administration? None of the above: it should be a separate program. Hooray for program modularity! Hooray for interface design! > Has this been done yet? Attempted? Contemplated? Attempted and completed. pty.3.001.shar will appear on c.s.unix very soon. If you're desperate, complain at rsalz@bbn.com. If you're really desperate, anon ftp a copy from the pub/ directory on 128.122.128.22. To repeat the paragraph prompting this thread: Under pty, hardwired /dev/tty* should be replaced with /dev/modem* and so on. *All* pty use should go through the pty program. (Of course, administrators would have a special non-pty shell just in case something went wrong.) This provides a trusted path between incoming connections and the login program, with obvious methods; it makes all sessions disconnectable, as per Steve Bellovin's session manager; and so on. ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (08/27/90)
In article <MOSS.90Aug27081600@ibis.cs.umass.edu> moss@cs.umass.edu writes: > An additional feature I definitely want is for the session manager to retain a > session for some user-selectable time (with a system chosen upper bound) if > the remote end drops before logout. I agree, and pty does this too! It's very nice to be able to just flip my terminal off in case of trouble, then reconnect later from anywhere. I don't know how I lived without this feature. pty doesn't implement the time limit: I was thinking of including it in the code, but it's easy enough to do manually. (Under the session, check every once in a while through sesslist. If the session is disconnected and has the same signaller at two successive checks, kill -HUP all the processes and sesskill the session.) > I lose modem connections because of noise > frequently, and it is really annoying to have to reconstruct my whole job tree > when that happens. Agreed. pty also lets you manually disconnect. This machine had to be taken down a couple of days ago, but before that I had a single shell running for a month. I just disconnected and reconnected every time, saving on shell startup time, eliminating the need for vi -r, and generally reducing angst. > (The VMS pty stuff keeps sessions around as described, and > when you relogin you get the option of connecting to your abandoned job or > creating a new one.) I source this script early in my login sequence (before aliases): $HOME/links/sesslist $HOME/links/sesslist | grep -s disconnected \ && ( echo -n 'Reconnect to session (return to ignore): '; \ set reconnect="$<"; \ if ( a"$reconnect"b != ab ) exec sess reconnect "$reconnect"; \ ) Primitive, but it gets the job done. A few minutes ago I just typed qf and popped back into this session. Once again, pty 3.001, the ultimate pseudo-terminal manager (implemented for BSD variants only at the moment), will appear soon on c.s.unix. If you're desperate, ask rsalz@bbn.com. If you're really desperate, anon ftp to the pub/ directory on 128.122.128.22. ---Dan
mmcg@bruce.cs.monash.OZ.AU (Mike McGaughey) (08/28/90)
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >I agree, and pty does this too! [and a zillion other things] But do you get a free set of steak knives?
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (08/28/90)
In article <2976@bruce.cs.monash.OZ.AU> mmcg@bruce.cs.monash.OZ.AU (Mike McGaughey) writes: > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >I agree, and pty does this too! [and a zillion other things] > But do you get a free set of steak knives? Yes! Just call 1-900-PTY-STKN and order your set TODAY! :-) Seriously, I haven't yet mentioned (in this thread, anyway) that pty comes with twenty-one short public-domain utilities, including improved clones of script (utmp support, extra flexibility), u (sort bug gone), who (slightly faster, better who am i handling), write (fixes four distinct security holes), lock (various bugs fixed, more obnoxious upon failed password); straight clones of wall, tty, biff, mesg; and more! Get your AT&T-free public domain clones TODAY! ---Dan
boyd@necisa.ho.necisa.oz (Boyd Roberts) (08/28/90)
In article <105387@convex.convex.com> tchrist@convex.COM (Tom Christiansen) writes: > >I would make a daemon server that everyone talked to in order to get >the session. You could instead put it in the kernel as a special >"/dev/pty" pseudo-driver that did the allocation for you, but I don't >see much that having it in the kernel might gain you considering >the cost. > You can do this stuff with a `mounted process', the connection line discipline (conn_ld) and the message line discipline (mesg_ld) with V8/9/10. When "/dev/service" is opened your user mode process gets a message that something is requesting an open (via select() and read()) and you then pass a file descriptor back across the stream (with the right line discplines pushed) that refers to "/dev/serviceXX". Your process, mounted on "/dev/service", manages a table of "/dev/serviceXX" for some XX. And, of course, you can deny the service as well. The message you get tells you who's on the far end of the open -- but it's fairly UNIX specific (uid, gid, login name and process nice value -- from memory). I think its a lot simpler with the V9 ipc library, but I don't have my V9 manual to hand. But the library hides some of the intricacies of the implementation. It's nice. Hume will followup and catch me out -- just watch... Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''
davidb@Pacer.UUCP (David Barts) (08/29/90)
In article <105387@convex.convex.com>, tchrist@convex.COM (Tom Christiansen) writes: > : > : > I'd like to solve at least these problems: > > 1. getting the pty name right (varies system to system) > 2. race condition between choosing a name and trying the open > . . . I thought master pty's only allowed one open at a time (at least that's what the HP-UX docs say). So choosing a name is easy -- just read through the /dev directory (or wherever the ptys are). For each name that matches the naming convention of a master pty, try to open it. If the open succeeds, you have your pty pair. (You can't open a closed master pty whose slave is still open, because that will fail also.) The only possible problem that I see is if some other unwanted process opens your slave pty. But this can be solved by keeping all the ptys owned by root and not world read- or writable (to limit use of ptys to trusted programs that follow this opening protocol). So I can see where the need for suid programs and chown()ing comes in, but I can't see the race condition, since choosing the name and trying the open are the same step. Am I missing something here? (I looked in the man pages for our Solbourne system, and couldn't find anything as detailed as the rules laid out in the HP man pages for when a master pty will open.) Is this behavior of master pty's unique to HP-UX? The one time I wrote a program that used ptys, I used the above approach and it seemed to work just fine. -- David Barts Pacer Corporation, Bothell, WA davidb@pacer.uucp ...!uunet!pilchuck!pacer!davidb