There are two ways to limit access to your hierarchy. You can restrict access by hostname or IP address and you can restrict access to users whose name and password are in a file on your server (authentication). You can, of course, do both. To restrict access to an entire hierarchy you must restrict access to each of its subdirectories.
Warning: If access to a directory is restricted by either of the ways described here the restrictions affect only that one directory and not its subdirectories.
If you have opted to limit access to your server in this way you do so by
setting the value of the Accessfile=
in the index.wn
file for a directory.
In the directory directive part of an
index.wn
file, a line like:
Accessfile=~/dir/.access
specifies that the the access control file
wnroot/dir/.access
contains restrictions on what sites are
allowed to access this directory. The Accessfile=
directive
takes the value of a path to a file in different forms. If the path
begins with a '/
' or with '~/
' then it is
relative to the WN hierarchy root, and otherwise it is relative
to the directory containing the index.wn
file in which the
directive occurs. In particular the access file must be located within
your WN hierarchy.
Warning: If theAttributes=serveall
directive is used in a directory with restricted access be sure the access file is not serveable. You can do this by giving it a name starting with '.
' or ending with '~
', or better, put it in a directory from which nothing is served.
Also note that limiting access to this directory does not limit access to
subdirectories. The Accessfile=
line must
occur in the index.wn
file
of each directory you want restricted. Of course, they can all refer to
the same file. To use the same file for several directories be sure to
use the "Accessfile=~/dir/.access
"
form of the directive so the line can be the same for every index.wn
file.
This will limit access to the server to those clients with an IP address
or subnet address listed (and not excluded) in the file
.access
listed in the Accessfile=
directive.
If a recursive title search or keyword search is requested and some
directories have restricted access only those directories which have the
same access file as the directory where the search started will be
searched. In fact the path must be the same in the Accessfile=
directive
for both directories (and must necessarily be of the form "Accessfile=~/dir/.access
"
or "Accessfile=/dir/.access
"
rather than "Accessfile=.access
").
There are three possible formats for lines in the access file. First you
may list the domain names of the machines using wild cards provided the
machines all have proper PTR
DNS resource record. For
example the line:
dogbert.widget.com
allows access to one host. To allow access to all machines in the
widget.com
domain, use the line:
*.widget.com
Note that this will not allow access to a machine called
widget.com
if it exists. One would need to add in the line
widget.com
to allow it access.
You can also allow access by IP address and, in general, this is somewhat
more secure than using the hostnames. There are two line formats for IP
addresses. The first is to explicitly list an IP address like
129.111.222.123
or a subnet address like
129.111.222.
or 129.111.
. In case a subnet
address is listed it must end with a period like:
129.111.222.
or
132.123.
but complete IP addresses like 129.111.222.123
should not
end with a period. If a subnet address is listed any client with an IP
address beginning with that subnet address will be allowed access.
The second format for IP address restriction uses a net address, net mask
pair with the two parts separated by a '/
'. For example:
129.111.222.0/255.255.255.0
The presence of the '/
' indicates to the server that this
format is being used. The part before the '/
' is the "net
address" and the part after is the "net mask". The server will then take
the IP address of the remote client, do a logical "and" of each of its
four parts with the corresponding four parts of the net mask
(255.255.255.0
in this example) and check that the four
results agree with the four parts of the net address
(129.111.222.0
). So the access file line above will match
(and allow access to) precisely those machines with IP address of the
form 129.111.222.x
because the 'x
" part is
"anded" with 0
and hence becomes 0
, while the
first three parts are "anded" with 255
and hence unchanged,
so they must equal 129
, 111
, and
222
respectively.
Note that if you have #define NO_DNS_HOSTNAMES
in the config.h
file you
must use one of the IP address formats above and not the format using a
domain name. This is because #define NO_DNS_HOSTNAMES
causes WN never to convert IP addresses to hostnames.
You can also exclude IP addresses or domain names by prefixing them with
an '!
', so if the access file contained only the lines:
!speedy.acns.nwu.edu
*
Access would be permitted to every machine except speedy (the
*
matches, and allows access to, anything). Likewise:
!129.111.
!129.222.0.0/255.255.0.0
*
would allow access to everyone except those on subnet
129.111
or on subnet 129.222
. In general
prefixing a line (in any of the three formats) with '!
'
causes immediate denial of access to any matching host. The first
matching line (with or without leading '!
') for a host is
the one which takes effect. Once a match is found access will be granted
(or denied if a '!
' is present) and no subsequent lines in
the access file will be considered.
A line in an access file cannot exceed 255 characters in length and every
line must end with a newline (some editors don't guarantee this and the
last line of a file may not have a newline). A blank line at the end is
fine. If these conditions are not met an error of type "Access
file line overflow
" will be generated.
You may also designate "privileged sites" in your access files. If you
list a site in an access file with a '+
' prefix like:
+hopf.math.northwestern.edu
+123.123.123.1
+111.111.111.0/255.255.255.0
then requests from that site will be exempt from any password requirements (as described below). In other words, no username/password pair will be required for requests from these sites, even if they are required from other sites.
Obviously the '+
' and '!
' prefixes for access
file lines are mutually exclusive.
It is possible to specify a URL referring to a customized document intended as an error message when access is denied. The easiest way to do this is to place the line:
Access-denied-URL=http://host/dir/foo.html
or the line:
Access-denied-URL=/dir/foo.html
at the beginning of the access file. When this is done and a request is
denied because of failure to meet the restrictions in that access file,
the browser will be redirected to the URL
"http://host/dir/foo.html
" or "/dir/foo.html
".
Access-denied-URL=
is also a legal directory directive
which may be placed in an index.wn
file.
You can also maintain a password file (or files) on your system and restrict access to those users who can supply a valid user name and password. This is the so-called "Basic" authentication described in the HTTP/1.1 protocol.
Warning: I would strongly advise against using basic authentication described here to protect sensitive information on a server which runs on system on which untrusted users have accounts.
Notice that if none of the options -t
, -T
and -u
are used then a user
with his own home page can make a symbolic link to any file readable by
the server and that document will be served. This is true even if the
linked to document is in a password protected directory with limited
access or is outside the server data hierarchy.
The use of basic authentication with WN involves three additional
programs which can be found in the /bin
directory of the
distribution. The first of these is wn_mkpasswd
which is a
perl utility for creating and altering
password files. It should be run the first time with the command:
wn_mkpasswd -n filename
This prompts you for a realm, a username and password and then creates a
password file called "filename
" with that entry. On subsequent
uses the -n
argument should be omitted so that entries will be
added to the existing file instead of starting a new one (the
-n
is for "new"). If a subsequent entry is made with the
same user name the entry for that user will be replaced. If the
"filename
" argument is omitted then the default name of
wnpasswd
is used. There is another optional argument which
may be used with this program. The command:
wn_mkpasswd -D filename
causes a UNIX NDBM
database to be created or used instead of
a simple flat file. This is may be useful if you have a very large
number of password entries. Depending on your system, the database may
reside in the two files filename.dir
and
filename.pag
, or in a single file filename.db
.
The -n
option has no effect when combined with the
-D
option. To create a new database you must remove or
rename the .pag
and .dir
or .db
files. To remove a single entry from a password file use the command
"wn_mkpasswd -d filename
" or "wn_mkpasswd -D
filename
" for an NDBM
database.
The second is the perl script wn_md5passwd
which is
functionally the equivalent of wn_mkpasswd
but which
uses an MD5 hash of the password, the realm, and random data to encode
the password. The realm and random data are created when
wn_md5passwd
is run with the -n
option.
This is generally preferable as it is more secure and in particular passwords
with more than eight characters are significant. The options are
the same as those of wn_mkpasswd.
Note: To enable theNDBM
features ofwnauth
you will have to uncomment the lines inwnauth/Makefile
starting with#DBMFLAG
and#DBMLIB
and recompile thewnauth
program by running the UNIXmake(1)
utility in the/wnauth
directory.
Once you have created your password file and made sure that it is
readable by the user id under which the server will run, you are ready to
set up the WN authentication module, called wnauth
. This is done
on a per directory basis by three entries in directory record of the index.wn
file. Entries like:
Authorization-realm=myrealm@host.domain
Authorization-module=~/cgi-bin/wnauth "~/dir/wnpasswd"
Authorization-type=basic
in the directory record specify that the authentication module wnauth
is being used to
check user's passwords and that it should consult the password file
"wnpasswd
" in wnroot/dir/
. If instead of the
password file "wnpasswd
" you are using a NDBM
database "wnpasswd.dir
" and "wnpasswd.pag
"
created with "wn_mkpasswd -D
" as described above (or created
some other way), then you should use the line:
Authorization-module=~/cgi-bin/wnauth -D "~/dir/wnpasswd"
The password file can also be specified with the -P
option
as in:
Authorization-module=~/cgi-bin/wnauth -P wnpasswd
The name of the password file can be given in three different formats:
beginning with a '/
meaning it is relative to the system
root, beginning with '~/
' indicating it is relative to the
WN hierarchy root, or something else indicating it is relative
to the directory containing this index.wn
file. If you use the
'~/...
' form it is a good idea to put the file name in
double quotes as shown above to prevent the shell from trying to
interpret the '~
'.
A final option for wnauth
is the -l filname
option
as in:
Authorization-module=~/cgi-bin/wnauth -P wnpasswd -l /path2/logfile
With this option the wnauth
program will do its own logging
in the file logfile
, listing all transactions and any error
conditions. This is especially valuable for diagnosing problems in
authentication.
Warning: If theAttributes=serveall
directory directive is used in a directory with access restricted by password, be sure the password file is not serveable. You can do this by giving it a name starting with '.
' or ending with '~
', or better, put it in a directory from which nothing is served.
Note that if you designate a privileged site in your access control file then any users from that site will not be requested to supply a user name and password.
For security reasons when you use wnauth
or any Authorization-Module=
you are required to use either the -t
or -T
option or the -a
or -A
option when the
server is run and to have the index.cache
file in the
protected directory owned by the trusted user or group. This is to guard
against counterfeit authentication modules. Note that the four command
line arguments -a
, -A
, -t
and -T
all take a numeric
argument. Thus the command should be
"./wnsd -t 203
" and not
"./wnsd -t joe
" if user joe
has user
id 203
.
The Authorization-Realm=
line is to notify the client that for any document on this server with
the same realm as this one, the same username/password combination will
be valid, so the client need not ask the user for a username and
password, but can reuse the one supplied for the first document with this
realm. For security reasons it is a good idea to put your host and
domain name in the realm. This may at least discourage attempts at other
sites to forge your realm in order to collect user passwords. Your users
should also be warned never to enter their password if the realm
displayed when they are prompted for a password contains a different
hostname than the one in the URL they are trying to access.
If you use different realms on the same server you should be aware that popular browsers are somewhat cavalier in their treatment of realms. In particular once a username/password pair has been accepted a browser might well continue to use it on the same site without checking the realm until authentication fails. This practice of trying to guess the username/password is more efficient if the guess is correct and most of the time it is.
Also note that password protecting a directory does not protect its
subdirectories. The three "Authorization
" lines must
occur in the index.wn
file
of each directory you want to protect. Of course, these lines can all be
identical for different directories if you use the:
Authorization-module=~/cgi-bin/wnauth ~/dir/wnpasswd
form to specify locations relative to your WN root.
There is also support for a "group
" file with
authentication. This feature is invoked by using the -g
and
-G
options with the wnauth
authentication
module. The line:
Authorization-module=wnauth -g grpname -G foo -P wnpasswd
means to use the group name "grpname
" and the group file
"foo
". The group file is a file in the format of a UNIX group(5)
configuration file. That is, it has lines of the form:
grpname:*:99:user1,user3,user5
where the fields are separated by colons, the first field is a group
name, and the fourth field is a comma separated list of user names. wnauth
will ignore the
second and third fields. If the line above is in the file
foo
and wnauth
is invoked as
above then a user will be granted access provided the supplied password
matches that in the wnpasswd
file and the user's username is
in the list after the second ':
' in the line starting with
the group name. Thus, in this example users user1
,
user3
, and user5
will be given access if they
provide valid passwords and other users will not.
The format of a group file used by Apache is also supported. This format has lines of the form:
grpname: user1 user3 user5
which is the group name, a single colon and a space separated list of user names.
It is possible to specify a custom error message to be sent when password authentication fails because of an incorrect password or username as in:
Auth-denied-file=~/dir/foo.html
This specifies that any request for a document in this directory which is
denied because of an authorization module restriction results in the file
~/dir/foo.html
being sent instead. A default value for all
directories can be set by uncommenting the #define AUTH_DENIED_FILE
"
line in config.h
and
recompiling. Note that this is not a URL but the name of a file whose
content is to be sent as error text when authentication is denied. If
the file name starts with '~/
' as above it is assumed to be
relative to the WN root directory. Otherwise it is assumed to
be a path relative to the directory containing the index.wn
file.
The "Basic" authentication scheme is flawed in that it involves the transmission of essentially unencoded passwords over the network. It is relatively easy for unscrupulous people to obtain "sniffer" software which allows eavesdropping on all local network traffic. This means, in particular, that it is possible to intercept passwords.
This particular problem is remedied by the HTTP/1.1 Digest Authentication scheme. Digest authentication is supported experimentally by WN, but has the rather severe drawback that no publicly available clients currently support it. It is experimental, because I have no client to test it and hence it has barely been tested.