
	Kfingerd-0.04 by Joel Katz (Stimpson@Panix.COM)

	OVERVIEW:

	This is the third public release of kfingerd, my in.fingerd
replacement. It has numerous features that the standard Berkeley version
does not have (and it doesn't have at least one bug that the Berkeley
version does).

	Unlike the standard version of in.fingerd, this version does not
call the local finger program to service its requests -- it handles the
requests internally. Also unlike the standard in.fingerd, this version must
run as root -- as soon as it investigates the request, it sets its
privileges appropriately.

	CAUTION:

	This release is still BETA. It has been checked rather thoroughly
for security holes, but not quite as thoroughly for proper operation. Use it
at your own risk.

	FEATURES:

	1) The system operator can easily create dummy accounts (just for
kfingerd) that finger as if they were real. This is useful for providing
information or updates easily.

	2) Users can determine what information they wish to disclose. If
they wish to keep confidential when they read their mail or how long they
stay connected, they may.

	3) Users can offer multiple pieces of information for access by
finger. The information can be selected based upon the origin host and/or a
'subname' that appears in the finger query after a '#' character.

	4) Users can keep their finger configurations and valid subnames
secret -- plan-type files do not need to be world readable.

	5) Users can opt to have a program provide the output. This allows
then to easily (with C code, bash scripts, perl scripts, whatever) tailor
the output or act on the request.

	6) Users can log how often they are fingered, where they are
fingered from, and which subnames were fingered.

	COMPILING:

	Just type 'make'. What could be easier?

	INSTALLING:

	For security reasons, before installing kfingerd, verify that a user
named 'nobody' exists and that the directory '/home/finger' exists, is
empty, and is not writable by untrusted persons. If these names create a
problem for your site, change their names in 'main.c'.

	Put kfingderd somewhere convenient like /usr/sbin and
edit inet.conf to pass finger requests to kfingerd as root. An example line
would be:

finger	stream	tcp	nowait	root	/usr/sbin/tcp	/usr/sbin/kfingerd

	Then run inetd if it's not running or "kill -1" it if it is running.

	REFINGER:

	kfingerd replaces in.fingerd. This means it only controls
'remote' fingers. Unless you replace your normal finger with a loopback
finger, local fingers will still be handled normally. For testing, always do
"finger username@localhost" to make sure the finger is handled as if it was
remote or install refinger as described below.

	A little script that simulates a loopback finger (called refinger)
is included. To use it, rename /usr/bin/finger to /usr/bin/finger.bsd and cp
refinger to /usr/bin/finger. YOU MUST INSTALL KFINGERD BEFORE INSTALLING
REFINGER AND YOU MUST REMOVE REFINGER IF YOU EVER REMOVE KFINGERD! You have
been warned.

	ADMINISTRATOR CONFIGURING:

	The system operator can create fake accounts just for fingering
(such as 'problems', 'updates', 'account-info', whatever) by creating files
or subdirectories of the finger directory (by default /home/finger).

	If someone fingers a non-account and a file exists with that name in
/home/finger, it is sent. If someone fingers a non-account and a directory
exists of that name, the default is to output the file with that name in
that directory unless a subname was specified that corresponds to a file
that exists in that directory, in which case the corresponding file is sent.

	For example, suppose you want to create a dummy account called
"problems" that tells people about problems with your system. Suppose
further that you have sub-screens that talk about problems with modems,
problems with mail, and so on. Create a subdirectory in /home/finger called
"problems" (readable and executable by "nobody") and create a file called
"problems" (readable by "nobody") there that reads:

	For information on modem problems, finger problems#modem@my.site
	For information on mail problems, finger problems#mail@my.site

	and so on. Put the file about modems in /home/finger/problems and
call it "modem". Do the same for mail and so on.
	
	Files and directories in /home/finger/ must be readable by user
'nobody'. For security reasons, you _must_ make sure that such a user
exists. If you wish to user a different user name, change the define in
main.c.

	If a name maps to a directory, the file in that directory with the
same name as the directory is output unless the finger request specifies the
username followed by a '#' and the name of a file that exists in that
directory, in which case that file is passed.

	For security, subnames may not contain the '/' character or the '~'
character. Every '/' or '~' in the subname will be converted to an '_'.

	You can also put executables in /home/finger and in subdirectories
of /home/finger. This will cause the file to be executed and passed the
hostname and hostip of the originating connection. If there is a subname, it
will be passed as the third parameter.

	For fun, create a file called 'finger' (in /home/finger) that reads:

#/bin/bash
/usr/bin/finger $3

	and make it world executable. Then do "finger finger@localhost".
Then do "finger finger#root@localhost". You can even try 
"finger finger#stimpson@panix.com@localhost" (if you are an internet-connected
site). Then get rid of this script (unless you really like it).

	When user 0 is fingered (normally root), kfingerd will assume the
privileges of user "nobody" (if one exists). Dropping to the user's
privileges would, in this case, not drop any privileges and create a
possible security problem. This feature can be disabled with a compile
switch in main.c.

	The default handling of fingers for unknown users is to output
"finger: username: no such user". This can be changed by uncommenting the
defines of NOSUCHUSERPATH and NOSUCHUSERFNM in dummy.c and creating a file
called /etc/badfinger that is world executable. It takes one parameter (the
username fingered). A sample file is included (which you should not use
unless you are sure it's what you want).

	USER CONFIGURING:

	Users can control how remote finger requests are handled by
kfingerd. "~/.fingerrc" holds a script that controls how kfingerd behaves.
In the absence of such a file, the defaults kick in. These, more or less,
mimic the standard Berkeley fingerd.

	In this file, fields must be seperated by whitespace. Any line
beginning with either '#' or ' ' is considered a comment.

	The legal commands are: (commands are case insenstive, capitals
indicate meta-syntactic variables, parenthesis indicate optional items.)

	(no)mail		(don't) Provide mail info
	(no)remote		(don't) Provide remote site names
	(no)ttys		(don't) Provide tty names
	(no)idle		(don't) Provide idle time(s)
	(no)parm		(don't) Use subnames
	(no)log			(don't) Log the request in ~/.fingerlog
	(no)plan		(don't) Output a plan file
	(no)proj		(don't) Output a project file
	(no)auth		(don't) use ident to obtain user name
	projfnm	(FNM)		Specify a file to use for project
	planfnm	(FNM)		Specify a default plan file
	progfnm	(FNM)		Specify a program to call
	subdfnm	(SUB)		Specify a subdirectory for plan files

	The "log" command causes finger requests to be appended to a file
called "~/.fingerlog" If logging is enabled, the "auth" command causes
kfingerd to attempt to obtain the fingering user's name and OS using the
'ident' or 'authuser' protocol as specified in RFC1413. This information
should not be trusted -- some sites deliberately send back garbage.

	If any of the last four commands are called without a parameter, the
corresponding feature is disabled. If subdfnm is called with a parameter
that doesn't end with a '/', it is a prefix and not a subdirectory.

	For example, consider the following .fingerrc file

------------------------------------------

# disable project file
noproj
# enable subnames
parm
# subname plan files will be held in ~/finger
# the trailing / is mandatory
subdfnm finger/

-----------------------------------------

	These three commands disable project files, enable subnames, and
specify that the 'plan' files will be held in the directory "~/finger". Each
file in that subdirectory will correspond to one subname. A file in
"~/finger" with the same name as the user's login name will hold the default
plan file. These files need only be readable by their owner and "~/finger"
need only be readable and executable by its owner. This allows subnames to
be kept secret.

	Any command can be preceded by:

	IP=	qualifier
	IP!	qualifier
	HN=	qualifier
	HN!	qualifier

	which causes the command to be conditional upon the IP address or
hostname matching or not matching the qualifier. Case is not significant in
host name qualifiers or the commands themselves. Any command can also be
preceded by:

	SN=	qualifier
	SN!	qualifier
	SN1	dummy
	SN0	dummy

	which causes the command to be conditional upon the subname
(everything after the pound) matching or not matching the qualifier. 

	The last two cause the command to be conditional upon their being
(SN1) or not being (SN0) a subname. The dummy parameter is not used but is
required as a placeholder. Case is significant in the qualifiers.

	Thus someone who wants to, for example, keep secret what ttys he is
logged in on can still make this information available to his friends by
telling them a secret subname (say, "secret") and adding the two following
lines:

#disable output of tty names
nottys 
#then enable it for those who know the secret
#(the space after SN= is mandatory)
SN= secret ttys

	If his login name were 'joe' and his host was 'foo.bar', someone who
did 'finger joo@foo.bar' would not get his list of logged in ttys, but
someone who did 'finger joo#secret@foo.bar' would.

	The special commands

	HNR	old_name	new_name
	IPR	old_ip		new_ip

	cause the hostname or ip address to be replaced with the new value
if it equals the old value. This is useful for folding several commands for
several hosts into one set. These commands can be made conditional. Case is
not significant in the command itself but is significant in host names.

	A common use of these commands is to cause fingers from one host to
behave as if they came from another. A good example is my home site,
"Panix.com". I may want to give special information to people who finger me
from Panix. However, I must consider panix.panix.com, panix2.panix.com and
panix3.panix.com as local as well. I can do this by writing:

-----------------

# Example .fingerrc file to show
# mapping multiple site names into one
# and host-based selection of information to give
# as well as different plan files for different hosts

#first set defaults. No mail info, no tty info, no idle time info
nomail
nottys
noidle

#then remap several hosts to localhost
HNR	panix.com	 phost
HNR	panix.panix.com	 phost
HNR	panix2.panix.com phost
HNR	panix3.panix.com phost

#then set access for localhost
#the command executed last takes precedence
HN=	phost	ttys
HN=	phost	idle
HN=	phost	mail
HN=	phost	planfnm	.plan_local

--------------------

	Since the entire script is executed sequentially, later commands
take precedence over earlier ones. Thus, one should be sure to put defaults
first and override them later. The first three commands set the defaults.
The next four map all Panix's systems to "phost". Then I activate additional
information for local sites including giving them ".plan_local" instead of
".plan".

	Plan files are the standard way to respond to finger requests. The
default is to output the contents of "~/.plan". If "parm" is enabled and a
subdirectory is specified with "subd", multiplan mode will be enabled.

	In this mode, the subdirectory specified contains multiple plan
files. You should always specify either a plan subdirectory or a plan prefix
when using multiplan mode.

	The plan file corresponding to the subname specified will be sent
unless there is no subname or an illegal subname in which case a plan file
with the user's login name will be sent if one exists.

	If the subdirectory specified in "subd" does not end in '/' then it
is a file prefix instead. The command "subd .plan_" for the user "joe"
(assuming subname mode) will change the user's default plan file to
'.plan_joe' and '.plan_{subname}' when a subname is given.

	Project files are supported for compatibility with Berkeley finger.
It is recommended that they not be used. The command "noproj" or the command
"projfnm" with no paramater will do this.

	If projects are not disabled, a project file with the specified name
(defaults to "~/.project") will be output after the plan file (if any).
Project files are useful, however, if other mechanisms are providing a
varying output and a way to add some additional information that doesn't
vary is needed.

	Programmed response allows a user-written program to provide a
fingerer with a flexible response. The program file must exist in the user's
home directory and be executable.

	The program will be passed the calling hostname as its first
parameter, the calling ip address (in dotted quad notation) as the second
parameter, and, if parm is enabled and one is sent, the subname (everything
after a '#') as the third parameter. The program's stdout and stderr will be
directed to the fingerer.

	Actually, the program inherits the socket directly as its stdin,
stdout, and stderr. This means a responsive program can get input from the
fingerer if he accesses kfingerd with telnet. However, the program's process
group will not last long, so the user would have to answer fast.

	Site defined limits on subprocesses, virtual memory, cpu time, and
so on may be imposed upon such a program. The default is a ten second (clock
time) limit before a SIGINT is sent followed by a three second grace period
before a SIGKILL is sent.

	A conditional cannot itself be conditional in this version of
kfingerd, so the following is illegal: "HN= ftp.uu.net SN= secret MAIL". The
desired effect can be acheived with: 
"SN= secret HNR ftp.uu.net ftp.uu.net.foobar" followed by 
"HN= ftp.uu.net.foobar mail".

	SPECIAL NOTE:

	I am considering rewriting the .fingerrc syntax to be very c-like
for kfingerd-1.0. An example of this newer format might be:

	if(hostname=="epinet.com" && subname=="test")
 	{
         ttys nomail
        }
	else nottys

	If you want to vote in favor of this new syntax, finger
"c-like#yes@epinet.com". To vote against this new syntax, finger
"c-like#no@epinet.com". To get the tally of votes so far, finger
"c-like#results@epinet.com".

	A copy of the neat script that manages this vote is included as
'vote_script'. Feel free to use it to run your own votes -- it is far more
efficient than mail-based voting.

	VERSION HISTORY:

	Version 0.01 was the initial public release. Version 0.02 allows
psuedo accounts to contain executables and prevents accidental execution of
'backup' files by disallowing the '~' character in subnames. Also, an extra
security check prevents unintended effects on sites that (stupidly) include
'.' in their paths.

	Version 0.03 added authentication and conditional compilation for
executables. Also, when root is fingered, privileges are immediately dropped
to 'nobody'. The method the system uses to kill subprograms was improved.
Handling of blind fingers (finger @host) was improved. Case handling in
hostnames was also improved. Some minor bugs in the handling of dummyfinger
directories were fixed. Also, 'badfinger' support and the voting script was
added. In addition, a serious security loophole was closed.

	Version 0.04 fixed a smaller security loophole added while fixing
the larger security loophole.

	BUGS:

	None known, just quirks. (Duh. If there were known bugs, I'd fix
'em; wouldn't I?)

	Kfingerd drops privileges as soon as possible for security reasons.
Unfortunately, this means that when root is fingered, kfingerd doesn't have
root privileges when it goes to log. Thus, if root would like to log his
fingers, his ~/.fingerlog file must be writable by user 'nobody' (or
whatever ROOT_DROPS is defined to).

	Refinger will not rewrite local empty finger requests. This means
that someone who simply types "finger" will get idle and tty information for
all logged in users that kfingerd might not release due to user setups. Of
course, this same information could be obtained many other ways locally (run
finger.bsd, read utmp/wtmp, compile your own version of finger, 
"ls -l /dev/tty*", and so on) so this isn't really a problem.

	The included sample 'badfinger' file ouputs a full list of valid
accounts to anyone who fingers a non-existent username. Don't use this
script if this is not what you want! (You have to modify the source to
dummy.c and copy the 'badfinger' file to /etc. If you don't do that, ignore
this warning.)

	Kfingerd's use of the user 'nobody' may create a security problem in
connection with nfs' use of that same username. For this reason, finger
files kept in /home/finger should not be owned by 'nobody' on a system that
exports filesystems that might include /home/finger. In essence, remote
systems will have the same access to dummy finger files as kfingerd itself
does. If this is a problem, change ROOT_DROPS and DUMMYS_RUN to "kfingerd" in
main.c and create a user called "kfingerd" to own /home/finger.

	If inetd is not running, kfingerd will not work. If you are using
'refinger', this means local fingers will not work either.

	Some man pages are _still_ in order.
