[comp.unix.wizards] 2 way serial lines

hyc@starbarlounge.cc.umich.edu (Howard Chu) (01/05/88)

In article <179@laura.UUCP> hmm@laura.UUCP (Hans-Martin Mosner) writes:
%In article <1505@saturn.ucsc.edu> haynes@ucscc.ucsc.edu (Jim Haynes - Computer Center) writes:
%>  I'm wondering if there is any reason not to modify getty and login
%>to strip out any funny characters in the login name.
%
%I think that modifying getty & login is relatively safe.  We have done
%it here on our uucp machine where the incoming lines are connected
%to a x.25 PAD.  The PAD sends an XON when it gets an incoming call,
%which has to be ignored by getty.  I know, in this case we could just
%tell our uucp partners to change their L.sys entries for unido,
%but there are so many of them...
%
%	Hans-Martin
%-- 
%Hans-Martin Mosner		| Don't tell Borland about Smalltalk - |
%hmm@unido.{uucp,bitnet}		| they might invent Turbo Smalltalk !  |
%------------------------------------------------------------------------
%Disclaimer: Turbo Smalltalk may already be a trademark of Borland...

On BSD systems you simply set the boolean flag 'ig' in the gettytab
entry, and the getty will ignore control characters (less than ASCII 32,
greater than ASCII 126, with BS, CR, LF, and DEL still being recognized...).

Somewhat along these lines, I've just finished a bit of getty/uucp hacking
here, to allow turning a line around without having to use that acucntrl
stuff that's part of the UUCP on the 4.3 tape. *I* think the scheme is a
lot nicer than acucntrl, which runs a bunch of shell and editor scripts to
convince the init process that a getty should or shouldn't be running...
(acucntrl also will not always work on a Sun, I discovered quite by accident -
init doesn't always respond to the HUP signal telling it to reread /etc/ttys
and enact any chages made therein. Thus, acucntrl is rather worthless, in
reality.)

So here's the scheme: (please mail comments; questions are always welcome...)

I'm working from the sources to the 4.3 getty, by the way. In main.c, many
things are done, including chown'ing the particular tty to root, and setting
the access on the tty. This is done regardless of whether init prepared the
device, or if getty must do it itself. Instead, I have it chown the device
to UUCP, and create a modifed UUCP lock file in the UUCP locking directory.
After the chown, the getty does a setreuid to change its effective uid to
that of UUCP as well. The getty also has a new signal handler installed,
(I used SIGUSR1, I don't think it really mattered...) which is really the
key to the scheme. The lock file now contains the getty's PID and an extra
flag byte - this is used to distinguish between a lock held by a getty and a
lock held by an actual outbound UUCP process (cu, kermit, tip, or uucico...).
If a SIGUSR1 signal is caught, it drops into a handler that calls sleep with
a time of 24 hours, and then calls exit.

The locking code in UUCP must also be changed to take advantage of this...
An unmodified UUCP (or tip, or whatever) will just see a weird lock file
when trying to grab the line, and will give up. The modifications are to
check an existing lock file to see if the flag byte is present; if it indicates
a UUCP, or is missing, then that's a "genuine" UUCP lock. If it indicates a
getty, a signal is sent to the getty process. If the kill() returns an error,
then either the getty has been replaced by an actual login, or for some
reason the sender and getty's uids don't match. In either case, the lock
attempt will fail. If the kill is successful, however, then the UUCP is
free to use the line. It rewrites the lock file to have its PID and a different
flag byte, and appends the old contents of the lock file to it. (Preserving
the getty's PID...)

When the UUCP finishes, and wants to get rid of the lock file, it checks for
the existence of the getty flag. If present, it sends a SIGALRM to the getty,
then replaces the lock file with the original getty lock data. The ALRM wakes
the getty from its sleep, and all is fine. The lock file only refers to the
getty process. If the signal fails, there's nothing the UUCP can do about it,
and the lock file is removed.

Originally, I had wanted to avoid as much as possible having to kill a getty
outright and force init to start a new one, but with the default signal
handling in BSD4.2 Unix, things don't work so good. The original signal
handler I had in the getty would simply sleep then return. This only works
to stop the getty the first time. For some reason, even though later signalling
of the getty will invoke the signal handler properly, the line becomes "busy"
when the signaller tries to use it. (gcore of the getty at various times
showed the process blocked on a read. The program counter looked identical
both before and after the successful and failed attempts to grab the line.
Must be something fishy about 4.2's system call restart behavior...) If the
getty read just one character, then things would free up till the next UUCP
succeeded and finished. In any case, rather than muck with the siginterrupt
feature, I decided to just call exit and let init start things over again.

My test system was a Sun running SunOS 3.4. (Since I only had access to our
Mt Xinu 4.3 Vax sources though, I hacked on the 4.3 releases of getty, tip,
and UUCP... Interesting to note that the 4.3 getty claims to understand the
invocation that the 4.2 init uses, but it doesn't work as shipped because of
an inverted boolean expression in the argvec processing...) The changes were
really trivial though. (Too bad it's taking so long to describe them, but due
to licensing restrictions, I obviously can't post the diffs and let the code
speak for itself, eh?) Having getty run as uucp instead of root is no
problem either, since it invokes /bin/login for actual logins, which runs
setuid to root, and again chown's the tty & such...

It *does* make things look different, of course. Now instead of just having
a lock file for an active UUCP connection, you have them lying around at
all times. P'raps a better name would be status file instead of lock file.
But for a system that relies on serial lines for communications, it's not
bad. Especially if that system is a Sun or Apollo, with only one or two
serial ports. If you have access to 4.3 sources, it's really a pretty nice
way to do things. Also, the 4.3 tip is much better than the 4.2 release -
properly restores terminal state on exit, for one thing. I also modified the
tip 'connect' command so it passes descriptors 0 and 1 to the spawned job,
instead of the 3 & 4 it did before. (What good is handing off 3 & 4??) Now
I can use Zmodem over these lines a little more easily... Of course, being
a Vax release, I *did* run into a couple byte ordering problems that made
things worthless on a Sun or Apollo, but they were trivially fixed as well.
(Sure is strange to see a 4.3 banner come up on a Sun login too!)

So far I've tested this on both an in and outbound modem line and a hardwired
line (to Merit, our statewide packet-switching network...) with no problems.
So, down to the bottom line - I'm pretty pleased with this setup; if you've
ever lamented the monodirectional nature of your serial lines, you might
want to look into it. Now, if someone can tell me that I won't be in massive
violation of any copyright or trade secret agreements by doing so, I could
make my sources publically available. I suppose that's the advantage of using
the acucntrl scripts, though with the loads our machines have to cope with,
that advantage is outweighed by the waste involved.

  /        University of Michigan 
 /_ , ,_.     Computing Center   
/ /(_/(__       Unix Project
    /                       
   '