Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!cs.utexas.edu!samsung!think!ames!haven!adm!news From: reschly@BRL.MIL (Robert J. Reschly Jr.) Newsgroups: comp.unix.wizards Subject: Re: What should the password/security/userinfo/login system include? Message-ID: <21817@adm.BRL.MIL> Date: 19 Dec 89 15:57:06 GMT Sender: news@adm.BRL.MIL Lines: 108 Michael, Yes, what and when to log has been an interesting topic of discussion here as well. We have been working with some of the software likely to be in 4.4BSD; login and friends in particular. The code for login as it comes from Berkeley is a bit forgiving for our tastes. Comments in the code imply it is supposed to allow a user to make one mistake (if the mistake is not a valid username) without generating a log entry. Reading between the lines leads us to conclude this code is there to reduce the chance of accidentally catching a password in the logs -- something which happens more frequently than we would like in our experience. We protect our authorization failure logs, and shred old console printouts because of this, by the way. The code as received also allows 10 login attempts before aborting, delaying the next "login:" prompt by 5 additional seconds for each new prompt after the third failed attempt -- or so the comments indicate. In actuality, both code segments are flawed. First, the prompting delays do not kick in until after the fourth failed attempt -- a classic "off by one" bug. And the log suppression code is flawed in that it will allow any number (up to 10) of different attempts to be made without logging any of them as long as each of the failing attempts does not match any username or the (yes 'the', not 'any') previous attempt. If the final attempt is successful and the failing attempts meet the above restrictions, login will not generate any log entry at all. Before discussing our modifications, it is also worth noting that getty will hand login a username longer than login is willing to accept when it prompts for a username itself. I don't recall whether the stock login protects itself from overrun, but even if it does, I don't think allowing this mismatch is good practice (we found this one by just mashing a handful of keys while testing our mods :-)). After batting various options around for a while, we settled on having the login process store each failed attempt (reasonable since this is bounded by both username length and number of attempts) and calling badlogin() on each exit path -- including timeouts and hangups. Badlogin() itself expects to be handed a string. If this string is non-null, the string is the username associated with a successful login. If there were any failures badlogin() generates a syslog message listing each of the failures, and if there was ultimately a successful login, that username is included in parentheses at the end. Log entries now look like this: Dec 4 20:23:25 sem login: 4 FAILED from spark: this is a test (reschly) Note that this entry keeps all attempts from a session on a single line, giving a count of the number of failures, listing them ('this', 'is', 'a', and 'test') and finally listing the successuful login attempt in parentheses. Absent is the terminal information for network connections (this one came from host "spark" -- who cares if it came from ttyp0 or ttyp1?), and the amount of SHOUTING in the logfile has been reduced. The count of failures is included as a check on the list of failures -- since failures may contain any character including space, we just printed what we captured space separated and did not worry about it too much. The rationale for logging the successful login along with the failures is to allow us to catch someone "escaping" in a suspicious manner. For example, on many systems there are one or more "safe" passwordless accounts (e.g. a "sync" account which runs /bin/sync). It is easy to envision someone trying one or two usernames followed by "sync". If the unmodified login is run, no log entry will be made if the username is invalid; and the failed attempt count will not get high enough to trip the delays. Our changes do have their disadvantages as well. In the current implentation, all attempts are buffered up until login exits. This means we have no indication of an ongoing attempt. Since this seems like it may be useful information, but it is not normally needed in our environment, we will probably add code to syslog attempts at some lower level as they occur (auth.debug is the current favorite). In addition, we can now match passwords with a vengeance, since failures are all nicely lined up in a single log entry (and the log entry may even include the successful attempt). Given the contortions in the code as shipped aimed at avoiding logging passwords, we will give Berkeley back code to deal with this. Since the successful login proceeded by failures is the case we are concerned about, our current thinking involves running crypt over the failures and comparing the result against the successful login. If there is a match, badlogin() would not list that attempt in the log entry. In the event of a match, the log entry will probably still give an indication of how many matches occurred (or said another way, how many failed attempts were not listed). Finally -- and I mention these only for completness -- we also made minor modifications to some of the user messages. Army regulations do not permit us to return responses which would allow a user to determine the reason access was denied. This means that we have to return the same "Login incorrect" message for expired passwords or accounts, and for things like attempts to log in as "root" on non-secure terminals and invalid shells. We then added syslog's indicating the true reason for failure to preserve the system administrator's sanity. Later, Bob -------- Arpa: reschly@BRL.MIL (or BRL.ARMY.MIL) Phone: (301)278-6808 AV: 298 UUCP: ...!{{cmcl2,nlm-mcs,husc6}!adm,smoke}!reschly Postal: Robert J. Reschly Jr. U.S. Army Ballistic Research Laboratory Systems Engineering and Concepts Analysis Division Networking and Systems Development Team ATTN: SLCBR-SE-A (Reschly) APG, MD 21005-5066 (Hey, *I* don't make 'em up!) **** For a good time, call: (303) 499-7111. Seriously! ****