Initial revision
authorTheodore Tso <tytso@mit.edu>
Thu, 3 Jun 1993 19:29:40 +0000 (19:29 +0000)
committerTheodore Tso <tytso@mit.edu>
Thu, 3 Jun 1993 19:29:40 +0000 (19:29 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2611 dc483132-0cff-0310-8789-dd5450dbe970

150 files changed:
src/CHANGELOG [new file with mode: 0644]
src/IDEAS [new file with mode: 0644]
src/Link_src.sh [new file with mode: 0644]
src/Sandia-changes [new file with mode: 0644]
src/TODO [new file with mode: 0644]
src/appl/.rconf [new file with mode: 0644]
src/appl/bsd/defines.h [new file with mode: 0644]
src/appl/bsd/fieldbits.h [new file with mode: 0644]
src/appl/bsd/forward.c [new file with mode: 0644]
src/appl/bsd/setenv.c [new file with mode: 0644]
src/appl/popper/.rconf [new file with mode: 0644]
src/appl/popper/README [new file with mode: 0644]
src/appl/popper/orig-makefiles/Makefile.krb_passwd_hack [new file with mode: 0644]
src/appl/popper/pop3.rfc1081 [new file with mode: 0644]
src/appl/popper/pop3e.rfc1082 [new file with mode: 0644]
src/appl/popper/pop_dele.c [new file with mode: 0644]
src/appl/popper/pop_dropcopy.c [new file with mode: 0644]
src/appl/popper/pop_dropinfo.c [new file with mode: 0644]
src/appl/popper/pop_get_command.c [new file with mode: 0644]
src/appl/popper/pop_get_subcommand.c [new file with mode: 0644]
src/appl/popper/pop_last.c [new file with mode: 0644]
src/appl/popper/pop_list.c [new file with mode: 0644]
src/appl/popper/pop_log.c [new file with mode: 0644]
src/appl/popper/pop_lower.c [new file with mode: 0644]
src/appl/popper/pop_msg.c [new file with mode: 0644]
src/appl/popper/pop_parse.c [new file with mode: 0644]
src/appl/popper/pop_quit.c [new file with mode: 0644]
src/appl/popper/pop_rset.c [new file with mode: 0644]
src/appl/popper/pop_send.c [new file with mode: 0644]
src/appl/popper/pop_stat.c [new file with mode: 0644]
src/appl/popper/pop_updt.c [new file with mode: 0644]
src/appl/popper/pop_user.c [new file with mode: 0644]
src/appl/popper/pop_xmit.c [new file with mode: 0644]
src/appl/popper/pop_xtnd.c [new file with mode: 0644]
src/appl/popper/popper.M [new file with mode: 0644]
src/appl/popper/popper.h [new file with mode: 0644]
src/appl/popper/syslog_levels [new file with mode: 0644]
src/appl/popper/version.h [new file with mode: 0644]
src/appl/telnet/.rconf [new file with mode: 0644]
src/appl/telnet/Imakefile [new file with mode: 0644]
src/appl/telnet/libtelnet/Imakefile [new file with mode: 0644]
src/appl/telnet/libtelnet/gettytab.c [new file with mode: 0644]
src/appl/telnet/libtelnet/gettytab.h [new file with mode: 0644]
src/appl/telnet/telnet/Imakefile [new file with mode: 0644]
src/appl/telnet/telnetd/Imakefile [new file with mode: 0644]
src/config-files/Imakefile [new file with mode: 0644]
src/config/Imake.rules.foo [new file with mode: 0644]
src/config/Imake.tmpl-xcomp [new file with mode: 0644]
src/config/Makefile.ini [new file with mode: 0644]
src/config/ccimake [new file with mode: 0644]
src/config/ccimake.c [new file with mode: 0644]
src/config/doc/paper.ms [new file with mode: 0644]
src/config/ibmLib.rules [new file with mode: 0644]
src/config/imake [new file with mode: 0644]
src/config/imake.man [new file with mode: 0644]
src/config/imakemdep.h [new file with mode: 0644]
src/include/.rconf [new file with mode: 0644]
src/include/bsdlib.h [new file with mode: 0644]
src/include/bstring.h [new file with mode: 0644]
src/include/com_err.h [new file with mode: 0644]
src/include/kerberosIV/addr_comp.h [new file with mode: 0644]
src/include/kerberosIV/admin_server.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsd386i.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdapollo.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdibm032.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdm68k.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdsparc.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdtahoe.h [new file with mode: 0644]
src/include/kerberosIV/conf-bsdvax.h [new file with mode: 0644]
src/include/kerberosIV/conf-ibm370.h [new file with mode: 0644]
src/include/kerberosIV/conf-pc.h [new file with mode: 0644]
src/include/kerberosIV/conf-pyr.h [new file with mode: 0644]
src/include/kerberosIV/conf-ultmips2.h [new file with mode: 0644]
src/include/kerberosIV/conf.h [new file with mode: 0644]
src/include/kerberosIV/des.h [new file with mode: 0644]
src/include/kerberosIV/des_conf.h [new file with mode: 0644]
src/include/kerberosIV/highc.h [new file with mode: 0644]
src/include/kerberosIV/kadm.h [new file with mode: 0644]
src/include/kerberosIV/kdc.h [new file with mode: 0644]
src/include/kerberosIV/klog.h [new file with mode: 0644]
src/include/kerberosIV/krb.h [new file with mode: 0644]
src/include/kerberosIV/krb_db.h [new file with mode: 0644]
src/include/kerberosIV/lsb_addr_comp.h [new file with mode: 0644]
src/include/kerberosIV/mit-copyright.h [new file with mode: 0644]
src/include/kerberosIV/osconf.h [new file with mode: 0644]
src/include/kerberosIV/passwd_server.h [new file with mode: 0644]
src/include/kerberosIV/principal.h [new file with mode: 0644]
src/include/kerberosIV/prot.h [new file with mode: 0644]
src/include/krb5/.rconf [new file with mode: 0644]
src/include/krb5/asn.1/.rconf [new file with mode: 0644]
src/include/sys/syslog.h [new file with mode: 0644]
src/include/syslog.h [new file with mode: 0644]
src/kadmin/server/admin_acl_file [new file with mode: 0644]
src/kdc/.rconf [new file with mode: 0644]
src/kdc/.saberinit [new file with mode: 0644]
src/kdc/migration.doc [new file with mode: 0644]
src/krb524/Makefile [new file with mode: 0644]
src/krb524/README [new file with mode: 0644]
src/krb524/RELEASE_NOTES [new file with mode: 0644]
src/krb524/conv_creds.c [new file with mode: 0644]
src/krb524/conv_princ.c [new file with mode: 0644]
src/krb524/conv_tkt.c [new file with mode: 0644]
src/krb524/conv_tkt_skey.c [new file with mode: 0644]
src/krb524/encode.c [new file with mode: 0644]
src/krb524/getcred.c [new file with mode: 0644]
src/krb524/globals.c [new file with mode: 0644]
src/krb524/k524init.c [new file with mode: 0644]
src/krb524/krb524.h [new file with mode: 0644]
src/krb524/krb524_err.et [new file with mode: 0644]
src/krb524/krb524_prot [new file with mode: 0644]
src/krb524/krb524d.c [new file with mode: 0644]
src/krb524/misc.c [new file with mode: 0644]
src/krb524/sendmsg.c [new file with mode: 0644]
src/krb524/test.c [new file with mode: 0644]
src/lib/.rconf [new file with mode: 0644]
src/lib/crypto/des/.rconf [new file with mode: 0644]
src/lib/crypto/des/FUNCTIONS [new file with mode: 0644]
src/lib/crypto/des/doc/libdes.doc [new file with mode: 0644]
src/lib/crypto/des/keytest.data [new file with mode: 0644]
src/lib/crypto/md4/.rconf [new file with mode: 0644]
src/lib/crypto/md4/RFC1186.TXT [new file with mode: 0644]
src/lib/crypto/md4/RFC1186B.TXT [new file with mode: 0644]
src/lib/exports.crypto [new file with mode: 0644]
src/lib/exports.des425 [new file with mode: 0644]
src/lib/exports.kdb5 [new file with mode: 0644]
src/lib/exports.krb5 [new file with mode: 0644]
src/lib/glue4.c [new file with mode: 0644]
src/lib/gssapi/README [new file with mode: 0644]
src/lib/gssapi/sample/Imakefile [new file with mode: 0644]
src/lib/gssapi/sample/MAIL.KANNAN [new file with mode: 0644]
src/lib/gssapi/sample/Makefile.bak [new file with mode: 0644]
src/lib/gssapi/sample/gssapi.mail [new file with mode: 0644]
src/lib/gssapi/sample/kitest.c [new file with mode: 0644]
src/lib/gssapi/sample/logutil.c [new file with mode: 0644]
src/lib/krb5.saber.source [new file with mode: 0644]
src/lib/krb5.saber.warnings [new file with mode: 0644]
src/lib/krb5/asn.1/.rconf [new file with mode: 0644]
src/lib/krb5/asn.1/.saberinit [new file with mode: 0644]
src/lib/krb5/asn.1/glue2.c [new file with mode: 0644]
src/lib/krb5/asn.1/process.perl [new file with mode: 0644]
src/lib/krb5/ccache/file/.rconf [new file with mode: 0644]
src/lib/krb5/ccache/file/README [new file with mode: 0644]
src/lib/krb5/ccache/file/todo [new file with mode: 0644]
src/lib/krb5/ccache/stdio/.rconf [new file with mode: 0644]
src/lib/krb5/ccache/stdio/README [new file with mode: 0644]
src/lib/krb5/ccache/stdio/todo [new file with mode: 0644]
src/lib/krb5/error_tables/.rconf [new file with mode: 0644]
src/lib/krb5/rcache/.rconf [new file with mode: 0644]
src/lib/krb5/rcache/README [new file with mode: 0644]
src/lib/krb5/rcache/RELEASE [new file with mode: 0644]

diff --git a/src/CHANGELOG b/src/CHANGELOG
new file mode 100644 (file)
index 0000000..7da5b7f
--- /dev/null
@@ -0,0 +1,22 @@
+Changes up until now:
+
+       * Kerberos database format changed (but in a backwards compatible way).
+               Once you go forward, no going back.
+
+[tytso:19930304.2209EST]
+
+       Removed SERVER_MISMATCH error message.  Fixed bug in
+       validate_tgs_request() to handle forwarded tickets correctly.
+
+[tytso:19930309.2201EST]
+
+       Function prototype for krb5_sname_to_principal changing to
+       include use of name type.  This is an API Change.
+
+[tytso:19930316.0225EST]
+
+       (last week) --- fixed ASN.1 checksuming problem
+
+       Fixed get_cred() so that you don't get new credentials if the
+               second ticket matches.
+
diff --git a/src/IDEAS b/src/IDEAS
new file mode 100644 (file)
index 0000000..fb902ab
--- /dev/null
+++ b/src/IDEAS
@@ -0,0 +1,7 @@
+[tytso:19920921.1439EDT]
+
+Add debugging code to the free subroutines, such as
+krb5_free_keyblock() to catch cases when NULL is passed to them.  This
+should be a compile-time option, of course...
+
+
diff --git a/src/Link_src.sh b/src/Link_src.sh
new file mode 100644 (file)
index 0000000..b5d50de
--- /dev/null
@@ -0,0 +1,11 @@
+# make source-tree symlinks to generated source-files,
+# so that synctree-generated shadows of the source-tree will have access
+# to the generated files.
+# this should be run in the shadow-dir, after synctree completes.
+
+#attach krb5
+#synctree -s /mit/krb5/src -d .
+foreach f ( include/krb5/error_tables lib/error_tables kdc comerr ss)
+   ln -s /mit/krb5/build/@sys/${f}/*_err.[ch] ${f}
+   ls -ls ${f}/*_err.[ch]
+   end
diff --git a/src/Sandia-changes b/src/Sandia-changes
new file mode 100644 (file)
index 0000000..bf55a9c
--- /dev/null
@@ -0,0 +1,247 @@
+# This file containes the changes made to the kerberos code
+# for porting to various platforms:
+
+Date    System     File                  Changes
+10/?/91  all       cr_auth_rply.c        Added files to lib/krb425 so
+                   cr_err_reply.c        that the kdc could handle v4
+                   cr_ticket.c           AS and TGS requests.
+                   create_ciph.c
+                   month_sname.c
+                   log.c
+                   one.c
+                   stime.c
+
+10/2/91         hpux9000   com_err/compile_et.c  Added hpux to i386 to include 
+                                         strcasecmp routine which is not
+                                         in the hpux stdc library.
+
+10/2/91  hpux9000   com_err/et_lex.lex.l  Added hpux ifdef to use strrchr 
+                                         instead of rindex.
+
+10/2/91  hpux9000   ss/cmd_tbl.l         Added hpux ifdef to use strrchr
+                                          instead of rindex.
+
+10/2/91  hpux9000   ss/ss_internal.h     Added hpux ifdef to use strrchr
+                                          instead of rindex, strchr instead of
+                                         index, and memcpy of bcopy.
+
+10/7/91  hpux9000   ss/listen.c                  ifndef hpux to  "not" declare index().
+
+10/2/91          hpux9000  ss/mk_cmds.c          Changed mk_cmds to use "ss.h" instead
+                                         of <ss.h> i.e.
+                                 fputs("#include <ss.h>\n\n", output_file); =>
+                                 fputs("#include \"ss.h\"\n\n", output_file);
+
+10/3/91   hpux9000  include/fake-stdlib.h ifndef hpux on declaration of strlen
+                   usr2/krb5/isode-interim/include
+
+10/3/91   hpux9000  lib/os/gen_rname.c    ifndef hpux on include of
+                   kdc/do_as_req.c       <arpa/inet.h>
+                   kdc/do_tgs_req.c 
+                   kdc/kerberos_v4.c 
+                   kdc/network.c 
+                   slave/kpropd.c
+                   appl/popper/pop_init.c 
+                   appl/user-user/client.c 
+                   appl/user-user/server.c
+                   lib/krb425/mk_priv.c
+                   lib/krb425/rd_priv.c
+                   lib/krb425/mk_safe.c
+                   lib/krb425/rd_safe.c
+
+       -- Where is the declaration of inet_ntoa() and related functions
+          on HPUX?  --
+
+10/4/91          hpux9000  include/krb5/stock/config.h  Added ifdef SYSV which 
+                                                redefines random,srandom,
+                                                and utimes to rand,srand,
+                                                and utime
+
+       -- Are these functions sufficiently compatible?  The changes
+          should be in osconf.h, not config.h (or maybe somewhere else). --
+
+10/4/91   hpux9000  lib/des425/des.h   Added #include <krb5/asn1.h> to 
+                                       get bzero() and bcopy() defines.
+
+       -- Wrong fix.  --
+
+10/7/91   hpux9000  lib/os/strcasecmp.c Added routines strncasecmp() and
+                                       strcasecmp() into new file strcasecmp.c.
+                                       These routines are included if the
+                                       the variable NEED_STRCASECMP is defined.
+                                       For hpux this is defined into the
+                                       variable StandardDefines in 
+                                       site.def.hp9000.  The Imakefile file for
+                                       lib/os was also updated to build
+                                       strcasecmp.c
+
+       -- Maybe.  Should we instead fix the library not to use
+          strcasecmp()?  The only use appears to be in os/hst_realm.c.  */
+
+10/7/91   hpux9000  appl/movemail.c    Added #ifdef SYSV => to undefine
+                                       MAIL_USE_FLOCK since real system v uses
+                                       lockf or POSIX style file locks. Also
+                                       included <krb5/asn1.h> so that bcmp and
+                                       rindex are defined to something 
+                                       available on this platform.
+
+       -- Do SYSV systems want to avoid locking files, or do they want to
+          use lockf/fcntl to lock files?  <krb5/asn1.h> is the wrong file
+          to include. --
+
+10/7/91   hpux9000  appl/popper/popper.h  Ifdef SANDIA to include asn1.h to
+                                         define a system dependant bzero and 
+                                         index. Also defined a file_lock to 
+                                         replace the system dependent flock().
+
+                   appl/popper/pop_updt.c  Use file_lock defined in popper.h
+                   appl/popper/pop_dropcopy.c
+
+       -- Does lockf() work on POSIX, or do you need to use fcntl directly?
+          Including asn1.h is wrong.  */
+
+
+10/7/91   hpux9000  slave/kprop.c        Ifdef SANDIA to use file locking
+                                         routines in lib/os/lock_file.c, which
+                                         takes into account POSIX file locking
+                                         and does not blanketly use flock().
+
+       -- Already fixed in MIT source. --
+
+10/7/91   hpux9000  lib/krb425/des_sched.c  Ifndef SANDIA to remove the 
+        (BUG FIX)                          des_key_sched() routine from this
+         really                            file. It was a noop but is necessary
+                                           for the kdc to handle v4 kinits. By
+                                           removing, the "good" des_key_sched 
+                                           in lib/des425/key_sched.c will now 
+                                           be used.
+
+       -- Probably put off to post-beta.  --
+
+11/12/91  All      lib/krb/rd_req_dec.c:   BUG fix reset tktauthent->ticket to
+                                           0 after krb5_auth_to_rep call so 
+                                           that if cleanup is done req->ticket
+                                           is not freed up.
+
+       -- Similar fix installed.  --
+
+11/15/91 all        krb4_rd_req.c         Added file to lib/krb425 so
+                                          kdc would not use the krb_rd_req
+                                          routine in libkrb425.a. The rd_req
+                                          in libkrb425.a does not handle a
+                                          true version 4 mk_req.
+
+11/15/91 all        kdc/kerberos_v4.c     Ifdef SANDIA to call krb4_rd_req
+                                          instead of the rd_req in krb425.
+
+
+12/4/91          All       lib/krb425/425data.c        Setup the variables ky and 
+                   lib/krb425/krb4_rd_req.c    serv_key in 425data.c so that
+                   lib/krb425/set_key.c        the krb_set_key routine which
+                                               was located there could be 
+                                               replaced with the krb_set_key
+                                               routine in set_key.c. Set_key.c
+                                               which is used for lib425
+                                               krb_rd_req, uses a different
+                                               global service key than 
+                                               krb4_rd_req, so we added the
+                                               setting of ky and serv_key there
+                                               also so that the same routine
+                                               could be used for krb4_rd_req 
+                                               and (lib425) krb_rd_req.
+
+       -- ? --
+
+
+
+12/18/91  All       lib/krb/getcredswopt.c     Added new routines 
+                                               krb5_get_credentials_wkdcopt
+                                               krb5_get_cred_from_kdc_wkdcopt
+                                               krb5_get_cred_via_tgt_wkdcopt
+
+                                               which allow applications to 
+                                               implement forwarding/proxy and
+                                               other kdc options.
+
+       -- There is no such file in the archive.  --
+
+12/18/91  All       lib/krb/int-proto.h        Added calls for new routine
+                                               krb5_get_cred_via_tgt_wkdcopt.
+
+12/18/91  All       lib/krb/copy_addrs.c       Added routine :
+                                               krb5_append_addresses() which 
+                                               allows appending addresses to a
+                                               list of addresses. Used for
+                                               proxy and forwarding.
+
+       -- Modified version installed.  --
+
+12/18/91  All       lib/krb/copy_checksum.c    Renamed copy_checksum.c to
+                                               copy_cksum.c so that it would
+                                               fit into the 14 character limit
+                                               of the archive program ar.
+
+       -- Should do this for beta 2. --
+                                               
+12/18/91  All       lib/krb/Imakefile          Changed to add new name for
+                                               copy_checksum.c and to add the
+                                               file getcredswopt.c
+
+12/18/91  All       appl/sample/sserver/sserver.c   Added new checks for proxy
+                    appl/sample/sclient/sclient.c   and forwarded tickets.
+
+12/18/91  hpux       lib/syslog.c              Ifdefed out the syslog routines
+                                               for hpux and set vsyslog to
+                                               simply call hpuxs syslog library
+                                               routine.
+
+       -- Shouldn't this change go into a config file? --
+
+1/29/92          ALL         lib/krb/copy_auth.c       BUG fix : check for input 
+                                               reference ptr == 0, if so 
+                                               return 0. If not done suns
+                                               core dump.
+
+       -- Is this needed?  I've never had a NULL pointer core dump in this
+          code.  --
+
+2/13/92          ALL         lib/os/an_to_ln.c         For Sandia if /etc/aname does
+       (sandia only)                           not exist then use the "other"
+                                               krb5_aname_to_localname as if
+                                               USE_DBM_LNAME was not defined.
+
+2/18/92   ALL         lib/krb/copy_data.c      Modified so that the structure
+                                               assignment is not necessary. 
+                                               Also added some null pointer,
+                                               and zero length checks.
+                                       
+       -- Is this needed?  When will this function be called with a zero
+          length krb5_data structure?  --
+
+3/17/92          unicos and     lib/asn1/asn1glue.h     Changed xmalloc define so
+           sysvimp                               that if 0 len is passed 
+                                                 at least 1 byte is malloc'd.
+
+       -- asn.1 source is changed so that malloc is not called when
+          the size is 0, but NULL is returned unconditionally; this
+          fix is not needed.  --
+
+4/20/92           ALL  include/krb5/error_tables/krb5_err.h  Added error
+               lib/error_tables/krb5_err.et          KRB5KDC_ERR_KEY_EXPIRED
+               include/krb5/errors.h                 to explain expired
+                                                     passwords
+
+       -- This is a protocol change.  Can we do it?  --
+
+5/3/92 ALL             lib/asn.1/adat2kadat.c  Bug fix which allows passing
+                                               of ticket authoriztion info.
+
+       -- Simpler fix installed ("rv->next" should have been "rv"). --
+
+5/4/92 ALL             lib/os/read_pwd.c       Added better signal catching 
+                                               facilities. SunOS would core
+                                               dump on SIGQUIT signals when
+                                               in krb5_read_password().
+
+       -- What's wrong with that?  Dumping core is standard procedure
+          for SIGQUIT.  --
diff --git a/src/TODO b/src/TODO
new file mode 100644 (file)
index 0000000..f3f3f61
--- /dev/null
+++ b/src/TODO
@@ -0,0 +1,119 @@
+integrate new DES implementation               (after beta)
+
+eliminate ISODE dependence                     (after beta)
+
+look at sandia changes (contact gmachin@somnet.sandia.gov):
+
+       admin server
+
+       BSD applications
+
+       kdc/v4 changes
+
+specific coding items:
+----------------------
+
+new protocol revision
+
+principal type change (krb5_data ** -> struct)
+
+merge local changes into latest telnet 
+
+telnet client address checking (hard to get hold of the addr?)
+
+generalize walk realm tree, add to API
+
+uuserver adds a ticket to the credentials cache each time it runs,
+even if the client is using the same ticket.
+
+other XXX stuff in code
+
+
+KDC bulletproofing                             (after beta)
+
+KDC statistic gathering                                (after beta)
+
+admin server                                   (after beta)
+
+applications
+       nfs
+       discuss (?)
+       X11
+
+realm "quality" code and/or hooks (tytso)      (after beta?)
+
+alloca/tempalloc                               (after beta)
+
+test suites                                    (after beta)
+
+KDC transited field comma quoting
+
+verify that memcpy/memcmp is in use for principal names
+Make sure that all comparisons of principal components (realms, etc.)
+use memcmp instead of strcmp --- principal components can have nulls
+in them!  (Don't blame me, blame OSI!)
+       --> kdc realm transiting
+
+code boiling between scc_ and fcc_             (after beta)
+
+remove 32 bit dependencies (esp. in md4 and md5)       (after beta)
+
+documentation issues:
+--------------------
+
+manual pages (programs, library)
+
+Manual pages for appl/bsd need to be fixed!!!!
+
+what we depend on in the system (kprop, kdc: sockets; etc)
+
+build/installation doc:
+       document expected "warnings", how to build it, configuration options
+       picking up ss, com_err, makedepend, imake separately
+       unifdef: ftp.uu.net:/bsd-sources/pgrm/unifdef/
+
+
+operation doc
+       interrealm gotchas
+
+RFC
+       DES bit ordering
+       ap_rep vs. subsession keys
+       assign "no meaning" #s for others?
+       byte-wise comparison for principal names
+       DER, "Zulu" format timestamps
+
+API doc (tytso maintaining)
+
+bug list
+
+testing issues:
+--------------
+
+mprof/mnemosyne
+
+error paths
+
+DCE interoperability
+
+
+
+
+----------------------------------------------------------------
+
+library name problems: with shared libraries cryptoconf.o can't be
+replaced.  Change docs to require static linking.
+
+
+----------------------------------------------------------------
+
+
+Document new functions:
+
+krb5_free_address
+krb5_append_addresses
+krb5_gc_via_2tgt
+
+--------------------------------------------------------------
+
+Bad comment message in KRB5-aux.h (KRB5-types.c should be KRB5_tables.c)
diff --git a/src/appl/.rconf b/src/appl/.rconf
new file mode 100644 (file)
index 0000000..06f02e1
--- /dev/null
@@ -0,0 +1,4 @@
+ignore telnet.90.09.14
+ignore *.TXT
+link arpa
+ignore old-telnet
diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h
new file mode 100644 (file)
index 0000000..6a975d3
--- /dev/null
@@ -0,0 +1,2 @@
+#define OPTS_FORWARD_CREDS           0x00000002
+#define OPTS_FORWARDABLE_CREDS       0x00000001
diff --git a/src/appl/bsd/fieldbits.h b/src/appl/bsd/fieldbits.h
new file mode 100644 (file)
index 0000000..a11b948
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * $Source$
+ * $Author$
+ * $Id$
+ *
+ * Copyright 1989,1990 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America is assumed
+ *   to require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * Definitions for the field bits for Kerberos protocol
+ * version 5.
+ */
+
+
+#ifndef KRB5_FIELDBITS__
+#define KRB5_FIELDBITS__
+
+/* kdc_options for kdc_request */
+/* options is 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+/* #define     KDC_OPT_RESERVED        0x80000000 */
+#define        KDC_OPT_FORWARDABLE             0x40000000
+#define        KDC_OPT_FORWARDED               0x20000000
+#define        KDC_OPT_PROXIABLE               0x10000000
+#define        KDC_OPT_PROXY                   0x08000000
+#define        KDC_OPT_ALLOW_POSTDATE          0x04000000
+#define        KDC_OPT_POSTDATED               0x02000000
+/* #define     KDC_OPT_UNUSED          0x01000000 */
+#define        KDC_OPT_RENEWABLE               0x00800000
+/* #define     KDC_OPT_UNUSED          0x00400000 */
+/* #define     KDC_OPT_RESERVED        0x00200000 */
+/* #define     KDC_OPT_RESERVED        0x00100000 */
+/* #define     KDC_OPT_RESERVED        0x00080000 */
+/* #define     KDC_OPT_RESERVED        0x00040000 */
+/* #define     KDC_OPT_RESERVED        0x00020000 */
+/* #define     KDC_OPT_RESERVED        0x00010000 */
+/* #define     KDC_OPT_RESERVED        0x00008000 */
+/* #define     KDC_OPT_RESERVED        0x00004000 */
+/* #define     KDC_OPT_RESERVED        0x00002000 */
+/* #define     KDC_OPT_RESERVED        0x00001000 */
+/* #define     KDC_OPT_RESERVED        0x00000800 */
+/* #define     KDC_OPT_RESERVED        0x00000400 */
+/* #define     KDC_OPT_RESERVED        0x00000200 */
+/* #define     KDC_OPT_RESERVED        0x00000100 */
+/* #define     KDC_OPT_RESERVED        0x00000080 */
+/* #define     KDC_OPT_RESERVED        0x00000040 */
+/* #define     KDC_OPT_RESERVED        0x00000020 */
+#define        KDC_OPT_RENEWABLE_OK            0x00000010
+#define        KDC_OPT_ENC_TKT_IN_SKEY         0x00000008
+/* #define     KDC_OPT_UNUSED          0x00000004 */
+#define        KDC_OPT_RENEW                   0x00000002
+#define        KDC_OPT_VALIDATE                0x00000001
+
+/* fields common which can be masked and copied */
+/* Old mask = KDC_OPT_FORWARDABLE | KDC_OPT_FORWARDED  | KDC_OPT_PROXIABLE |
+              KDC_OPT_PROXY | KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED |
+             KDC_OPT_RENEWABLE */
+/*
+#define KDC_TKT_COMMON_MASK            0x7e800000
+*/
+/* New mask = KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE |
+              KDC_OPT_ALLOW_POSTDATE | KDC_OPT_RENEWABLE */
+
+#define KDC_TKT_COMMON_MASK            0x54800000
+
+/* definitions for ap_options fields */
+/* ap_options are 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+#define        AP_OPTS_RESERVED                0x80000000
+#define        AP_OPTS_USE_SESSION_KEY         0x40000000
+#define        AP_OPTS_MUTUAL_REQUIRED         0x20000000
+#define        AP_OPTS_FORWARD_CREDS           0x10000000
+#define        AP_OPTS_FORWARDABLE_CREDS       0x08000000
+/* #define     AP_OPTS_RESERVED        0x04000000 */
+/* #define     AP_OPTS_RESERVED        0x02000000 */
+/* #define     AP_OPTS_RESERVED        0x01000000 */
+/* #define     AP_OPTS_RESERVED        0x00800000 */
+/* #define     AP_OPTS_RESERVED        0x00400000 */
+/* #define     AP_OPTS_RESERVED        0x00200000 */
+/* #define     AP_OPTS_RESERVED        0x00100000 */
+/* #define     AP_OPTS_RESERVED        0x00080000 */
+/* #define     AP_OPTS_RESERVED        0x00040000 */
+/* #define     AP_OPTS_RESERVED        0x00020000 */
+/* #define     AP_OPTS_RESERVED        0x00010000 */
+/* #define     AP_OPTS_RESERVED        0x00008000 */
+/* #define     AP_OPTS_RESERVED        0x00004000 */
+/* #define     AP_OPTS_RESERVED        0x00002000 */
+/* #define     AP_OPTS_RESERVED        0x00001000 */
+/* #define     AP_OPTS_RESERVED        0x00000800 */
+/* #define     AP_OPTS_RESERVED        0x00000400 */
+/* #define     AP_OPTS_RESERVED        0x00000200 */
+/* #define     AP_OPTS_RESERVED        0x00000100 */
+/* #define     AP_OPTS_RESERVED        0x00000080 */
+/* #define     AP_OPTS_RESERVED        0x00000040 */
+/* #define     AP_OPTS_RESERVED        0x00000020 */
+/* #define     AP_OPTS_RESERVED        0x00000010 */
+/* #define     AP_OPTS_RESERVED        0x00000008 */
+/* #define     AP_OPTS_RESERVED        0x00000004 */
+/* #define     AP_OPTS_RESERVED        0x00000002 */
+/* #define     AP_OPTS_RESERVED        0x00000001 */
+
+/* definitions for ad_type fields. */
+#define        AD_TYPE_RESERVED        0x8000
+#define        AD_TYPE_EXTERNAL        0x4000
+#define        AD_TYPE_REGISTERED      0x2000
+
+#define AD_TYPE_FIELD_TYPE_MASK        0x1fff
+
+/* Ticket flags */
+/* flags are 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+/* #define     TKT_FLG_RESERVED        0x80000000 */
+#define        TKT_FLG_FORWARDABLE             0x40000000
+#define        TKT_FLG_FORWARDED               0x20000000
+#define        TKT_FLG_PROXIABLE               0x10000000
+#define        TKT_FLG_PROXY                   0x08000000
+#define        TKT_FLG_MAY_POSTDATE            0x04000000
+#define        TKT_FLG_POSTDATED               0x02000000
+#define        TKT_FLG_INVALID                 0x01000000
+#define        TKT_FLG_RENEWABLE               0x00800000
+#define        TKT_FLG_INITIAL                 0x00400000
+#define        TKT_FLG_PRE_AUTH                0x00200000
+#define        TKT_FLG_HW_AUTH                 0x00100000
+/* #define     TKT_FLG_RESERVED        0x00080000 */
+/* #define     TKT_FLG_RESERVED        0x00040000 */
+/* #define     TKT_FLG_RESERVED        0x00020000 */
+/* #define     TKT_FLG_RESERVED        0x00010000 */
+/* #define     TKT_FLG_RESERVED        0x00008000 */
+/* #define     TKT_FLG_RESERVED        0x00004000 */
+/* #define     TKT_FLG_RESERVED        0x00002000 */
+/* #define     TKT_FLG_RESERVED        0x00001000 */
+/* #define     TKT_FLG_RESERVED        0x00000800 */
+/* #define     TKT_FLG_RESERVED        0x00000400 */
+/* #define     TKT_FLG_RESERVED        0x00000200 */
+/* #define     TKT_FLG_RESERVED        0x00000100 */
+/* #define     TKT_FLG_RESERVED        0x00000080 */
+/* #define     TKT_FLG_RESERVED        0x00000040 */
+/* #define     TKT_FLG_RESERVED        0x00000020 */
+/* #define     TKT_FLG_RESERVED        0x00000010 */
+/* #define     TKT_FLG_RESERVED        0x00000008 */
+/* #define     TKT_FLG_RESERVED        0x00000004 */
+/* #define     TKT_FLG_RESERVED        0x00000002 */
+/* #define     TKT_FLG_RESERVED        0x00000001 */
+
+/* definitions for lr_type fields. */
+#define        LR_TYPE_THIS_SERVER_ONLY        0x8000
+
+#define LR_TYPE_INTERPRETATION_MASK    0x7fff
+
+/* definitions for ad_type fields. */
+#define        AD_TYPE_EXTERNAL        0x4000
+#define        AD_TYPE_REGISTERED      0x2000
+
+#define AD_TYPE_FIELD_TYPE_MASK        0x1fff
+#define AD_TYPE_INTERNAL_MASK  0x3fff
+
+/* definitions for msec direction bit for KRB_SAFE, KRB_PRIV */
+#define        MSEC_DIRBIT             0x8000
+#define        MSEC_VAL_MASK           0x7fff
+
+#endif /* KRB5_FIELDBITS__ */
+
+
diff --git a/src/appl/bsd/forward.c b/src/appl/bsd/forward.c
new file mode 100644 (file)
index 0000000..1e49129
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ *    $Source$
+ *    $Id$
+ */
+
+#ifndef lint
+static char *rcsid_forward_c =
+  "$Id$";
+#endif /* lint */
+#define LIBC_SCCS
+
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+/* General-purpose forwarding routines. These routines may be put into */
+/* libkrb5.a to allow widespread use */ 
+
+#ifdef KERBEROS
+#include <stdio.h>
+#include <pwd.h>
+#include <netdb.h>
+
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+#include <krb5/crc-32.h>
+#include <krb5/los-proto.h>
+#include <krb5/ext-proto.h>
+
+#define TGTNAME "krbtgt"            /* Else #include <krb5/kdb.h> */
+#define KRB5_DEFAULT_LIFE 60*60*8   /* 8 hours */
+/* helper function: convert flags to necessary KDC options */
+#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK)
+
+
+
+/* Get a TGT for use at the remote host */
+krb5_error_code
+get_for_creds(etype, sumtype, rhost, client, enc_key, forwardable, outbuf)
+     const krb5_enctype etype;
+     const krb5_cksumtype sumtype;
+     char *rhost;
+     krb5_principal client;
+     krb5_keyblock *enc_key;
+     int forwardable;      /* Should forwarded TGT also be forwardable? */
+     krb5_data *outbuf;
+{
+    struct hostent *hp;
+    krb5_address **addrs;
+    krb5_error_code retval;
+    krb5_data *scratch;
+    krb5_kdc_rep *dec_rep;
+    krb5_error *err_reply;
+    krb5_response tgsrep;
+    krb5_creds creds, tgt;
+    krb5_ccache cc;
+    krb5_flags kdcoptions;
+    krb5_timestamp now;
+    char *remote_host;
+    char **hrealms;
+    int i;
+
+    if (!rhost || !(hp = gethostbyname(rhost)))
+      return KRB5_ERR_BAD_HOSTNAME;
+
+    remote_host = malloc(strlen(hp->h_name)+1);
+    if (!remote_host)
+           return ENOMEM;
+    strcpy(remote_host, hp->h_name);
+
+    if (retval = krb5_get_host_realm(remote_host, &hrealms)) {
+       free(remote_host);
+       return retval;
+    }
+    if (!hrealms[0]) {
+       free(remote_host);
+       xfree(hrealms);
+       return KRB5_ERR_HOST_REALM_UNKNOWN;
+    }
+
+    /* Count elements */
+    for(i=0; hp->h_addr_list[i]; i++);
+
+    addrs = (krb5_address **) malloc ((i+1)*sizeof(*addrs));
+    if (!addrs)
+      return ENOMEM;
+    
+    for(i=0; hp->h_addr_list[i]; i++) {
+       addrs[i] = (krb5_address *) malloc(sizeof(krb5_address));
+       if (addrs[i]) {
+           addrs[i]->addrtype = hp->h_addrtype;
+           addrs[i]->length   = hp->h_length;
+           addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
+           if (!addrs[i]->contents) {
+               krb5_free_addresses(addrs);
+               return ENOMEM;
+           }
+           else
+             memcpy ((char *)addrs[i]->contents, hp->h_addr_list[i],
+                     addrs[i]->length);
+       }
+       else {
+           return ENOMEM;
+       }
+    }
+    addrs[i] = 0;
+
+    memset((char *)&creds, 0, sizeof(creds));
+    if (retval = krb5_copy_principal(client, &creds.client))
+      return retval;
+    
+    if (retval = krb5_build_principal_ext(&creds.server,
+                                         strlen(hrealms[0]),
+                                         hrealms[0],
+                                         sizeof(TGTNAME) - 1,
+                                         TGTNAME,
+                                         client->realm.length,
+                                         client->realm.data,
+                                         0))
+      return retval;
+       
+    creds.times.starttime = 0;
+    if (retval = krb5_timeofday(&now)) {
+       return retval;
+    }
+    creds.times.endtime = now + KRB5_DEFAULT_LIFE;
+    creds.times.renew_till = 0;
+    
+    if (retval = krb5_cc_default(&cc)) {
+       return retval;
+    }
+
+    /* fetch tgt directly from cache */
+    if (retval = krb5_cc_retrieve_cred (cc,
+                                       KRB5_TC_MATCH_SRV_NAMEONLY,
+                                       &creds,
+                                       &tgt)) {
+       return retval;
+    }
+
+    /* tgt->client must be equal to creds.client */
+    if (!krb5_principal_compare(tgt.client, creds.client))
+       return KRB5_PRINC_NOMATCH;
+
+    if (!tgt.ticket.length)
+       return(KRB5_NO_TKT_SUPPLIED);
+
+    kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED;
+
+    if (!forwardable) /* Reset KDC_OPT_FORWARDABLE */
+      kdcoptions &= ~(KDC_OPT_FORWARDABLE);
+
+    if (retval = krb5_send_tgs(kdcoptions, &creds.times, etype, sumtype,
+                              creds.server,
+                              addrs,
+                              creds.authdata,
+                              0,               /* no padata */
+                              0,               /* no second ticket */
+                              &tgt, &tgsrep))
+       return retval;
+
+#undef cleanup
+#define cleanup() free(tgsrep.response.data)
+
+    switch (tgsrep.message_type) {
+    case KRB5_TGS_REP:
+       break;
+    case KRB5_ERROR:
+    default:
+       if (!krb5_is_krb_error(&tgsrep.response)) {
+           retval = KRB5KRB_AP_ERR_MSG_TYPE;
+       } else
+           retval = decode_krb5_error(&tgsrep.response, &err_reply);
+       if (retval) {
+           cleanup();
+           return retval;              /* neither proper reply nor error! */
+       }
+
+       retval = err_reply->error + ERROR_TABLE_BASE_krb5;
+
+       krb5_free_error(err_reply);
+       cleanup();
+       return retval;
+    }
+    retval = krb5_decode_kdc_rep(&tgsrep.response,
+                                &tgt.keyblock,
+                                etype, /* enctype */
+                                &dec_rep);
+    
+    cleanup();
+    if (retval)
+       return retval;
+#undef cleanup
+#define cleanup() {\
+       memset((char *)dec_rep->enc_part2->session->contents, 0,\
+             dec_rep->enc_part2->session->length);\
+                 krb5_free_kdc_rep(dec_rep); }
+
+    if (dec_rep->msg_type != KRB5_TGS_REP) {
+       retval = KRB5KRB_AP_ERR_MSG_TYPE;
+       cleanup();
+       return retval;
+    }
+    
+    /* now it's decrypted and ready for prime time */
+
+    if (!krb5_principal_compare(dec_rep->client, tgt.client)) {
+       cleanup();
+       return KRB5_KDCREP_MODIFIED;
+    }
+
+    if (retval = mk_cred(dec_rep, 
+                        etype, 
+                        enc_key,
+                        0,
+                        0, 
+                        outbuf))
+      return retval;
+
+    krb5_free_kdc_rep(dec_rep);
+
+    return retval;
+#undef cleanup
+}
+
+
+
+/* Create asn.1 encoded KRB-CRED message from the kdc reply. */
+krb5_error_code
+mk_cred(dec_rep, etype, key, sender_addr, recv_addr, outbuf)
+krb5_kdc_rep *dec_rep;
+krb5_enctype etype;
+krb5_keyblock *key;
+krb5_address *sender_addr;
+krb5_address *recv_addr;
+krb5_data *outbuf;
+{
+    krb5_error_code retval;
+    krb5_encrypt_block eblock;
+    krb5_cred ret_cred;
+    krb5_cred_enc_part cred_enc_part;
+    krb5_data *scratch;
+
+    if (!valid_etype(etype))
+      return KRB5_PROG_ETYPE_NOSUPP;
+
+    ret_cred.tickets = (krb5_ticket **) calloc(2, sizeof(*ret_cred.tickets));
+    if (!ret_cred.tickets)
+      return ENOMEM;
+    ret_cred.tickets[0] = dec_rep->ticket;
+    ret_cred.tickets[1] = 0;
+
+    ret_cred.enc_part.etype = etype; 
+    ret_cred.enc_part.kvno = 0;
+
+    cred_enc_part.creds = (krb5_cred_enc_struct **) 
+      calloc(2, sizeof(*cred_enc_part.creds));
+    if (!cred_enc_part.creds) {
+       krb5_free_tickets(ret_cred.tickets);
+       return ENOMEM;
+    }
+    cred_enc_part.creds[0] = (krb5_cred_enc_struct *) 
+      malloc(sizeof(*cred_enc_part.creds[0]));
+    if (!cred_enc_part.creds[0]) {
+       krb5_free_tickets(ret_cred.tickets);
+       krb5_free_cred_enc_part(cred_enc_part);
+       return ENOMEM;
+    }
+    cred_enc_part.creds[0]->session = dec_rep->enc_part2->session;
+    cred_enc_part.creds[0]->nonce = 0;
+
+    if (retval = krb5_us_timeofday(&cred_enc_part.creds[0]->timestamp,
+                                  &cred_enc_part.creds[0]->usec))
+      return retval;
+
+    cred_enc_part.creds[0]->s_address = (krb5_address *)sender_addr;
+    cred_enc_part.creds[0]->r_address = (krb5_address *)recv_addr;
+    cred_enc_part.creds[0]->client = dec_rep->client;
+    cred_enc_part.creds[0]->server = dec_rep->enc_part2->server;
+    cred_enc_part.creds[0]->flags  = dec_rep->enc_part2->flags;
+    cred_enc_part.creds[0]->times  = dec_rep->enc_part2->times;
+    cred_enc_part.creds[0]->caddrs = dec_rep->enc_part2->caddrs;
+
+    cred_enc_part.creds[1] = 0;
+
+    /* start by encoding to-be-encrypted part of the message */
+
+    if (retval = encode_krb5_enc_cred_part(&cred_enc_part, &scratch))
+      return retval;
+
+#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); krb5_free_data(scratch); }
+
+    /* put together an eblock for this encryption */
+
+    krb5_use_cstype(&eblock, etype);
+    ret_cred.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length,
+                                               eblock.crypto_entry);
+    /* add padding area, and zero it */
+    if (!(scratch->data = realloc(scratch->data,
+                                 ret_cred.enc_part.ciphertext.length))) {
+       /* may destroy scratch->data */
+       xfree(scratch);
+       return ENOMEM;
+    }
+    memset(scratch->data + scratch->length, 0,
+         ret_cred.enc_part.ciphertext.length - scratch->length);
+    if (!(ret_cred.enc_part.ciphertext.data =
+         malloc(ret_cred.enc_part.ciphertext.length))) {
+        retval = ENOMEM;
+        goto clean_scratch;
+    }
+
+#define cleanup_encpart() {\
+       (void) memset(ret_cred.enc_part.ciphertext.data, 0, \
+            ret_cred.enc_part.ciphertext.length); \
+       free(ret_cred.enc_part.ciphertext.data); \
+       ret_cred.enc_part.ciphertext.length = 0; \
+       ret_cred.enc_part.ciphertext.data = 0;}
+
+    /* do any necessary key pre-processing */
+    if (retval = krb5_process_key(&eblock, key)) {
+        goto clean_encpart;
+    }
+
+#define cleanup_prockey() {(void) krb5_finish_key(&eblock);}
+
+    /* call the encryption routine */
+    if (retval = krb5_encrypt((krb5_pointer) scratch->data,
+                             (krb5_pointer)
+                             ret_cred.enc_part.ciphertext.data, 
+                             scratch->length, &eblock,
+                             0)) {
+        goto clean_prockey;
+    }
+    
+    /* private message is now assembled-- do some cleanup */
+    cleanup_scratch();
+
+    if (retval = krb5_finish_key(&eblock)) {
+        cleanup_encpart();
+        return retval;
+    }
+    /* encode private message */
+    if (retval = encode_krb5_cred(&ret_cred, &scratch))  {
+        cleanup_encpart();
+       return retval;
+    }
+
+    cleanup_encpart();
+
+    *outbuf = *scratch;
+    xfree(scratch);
+    return 0;
+
+ clean_prockey:
+    cleanup_prockey();
+ clean_encpart:
+    cleanup_encpart();
+ clean_scratch:
+    cleanup_scratch();
+
+    return retval;
+#undef cleanup_prockey
+#undef cleanup_encpart
+#undef cleanup_scratch
+}
+
+
+
+/* Decode, decrypt and store the forwarded creds in the local ccache. */
+krb5_error_code
+rd_and_store_for_creds(inbuf, ticket, lusername)
+     krb5_data *inbuf;
+     krb5_ticket *ticket;
+     char *lusername;
+{
+    krb5_encrypt_block eblock;
+    krb5_creds creds;
+    krb5_error_code retval;
+    char ccname[35];
+    krb5_ccache ccache = NULL;
+    struct passwd *pwd;
+
+    if (retval = rd_cred(inbuf, ticket->enc_part2->session, 
+                        &creds, 0, 0)) {
+       return(retval);
+    }
+    
+    if (!(pwd = (struct passwd *) getpwnam(lusername))) {
+       return -1;
+    }
+
+    sprintf(ccname, "FILE:/tmp/krb5cc_%d", pwd->pw_uid);
+
+    if (retval = krb5_cc_resolve(ccname, &ccache)) {
+       return(retval);
+    }
+
+    if (retval = krb5_cc_initialize(ccache,
+                                   ticket->enc_part2->client)) {
+       return(retval);
+    }
+
+    if (retval = krb5_cc_store_cred(ccache, &creds)) {
+       return(retval);
+    }
+
+    if (retval = chown(ccname+5, pwd->pw_uid, -1)) {
+       return(retval);
+    }
+
+    return retval;
+}
+
+
+
+extern krb5_deltat krb5_clockskew;   
+#define in_clock_skew(date) (abs((date)-currenttime) < krb5_clockskew)
+
+/* Decode the KRB-CRED message, and return creds */
+krb5_error_code
+rd_cred(inbuf, key, creds, sender_addr, recv_addr)
+const krb5_data *inbuf;
+const krb5_keyblock *key;
+krb5_creds *creds;                /* Filled in */
+const krb5_address *sender_addr;  /* optional */
+const krb5_address *recv_addr;    /* optional */
+{
+    krb5_error_code retval;
+    krb5_encrypt_block eblock;
+    krb5_cred *credmsg;
+    krb5_cred_enc_part *credmsg_enc_part;
+    krb5_data *scratch;
+    krb5_timestamp currenttime;
+
+    if (!krb5_is_krb_cred(inbuf))
+       return KRB5KRB_AP_ERR_MSG_TYPE;
+    
+    /* decode private message */
+    if (retval = decode_krb5_cred(inbuf, &credmsg))  {
+       return retval;
+    }
+    
+#define cleanup_credmsg() {(void)xfree(credmsg->enc_part.ciphertext.data); (void)xfree(credmsg);}
+
+    if (!(scratch = (krb5_data *) malloc(sizeof(*scratch)))) {
+       cleanup_credmsg();
+       return ENOMEM;
+    }
+
+#define cleanup_scratch() {(void)memset(scratch->data, 0, scratch->length); (void)xfree(scratch->data);}
+
+    if (retval = encode_krb5_ticket(credmsg->tickets[0], &scratch)) {
+       cleanup_credmsg();
+       cleanup_scratch();
+       return(retval);
+    }
+
+    creds->ticket = *scratch;
+    if (!(creds->ticket.data = malloc(scratch->length))) {
+       xfree(creds->ticket.data);
+       return ENOMEM;
+    }
+    memcpy((char *)creds->ticket.data, (char *) scratch->data, scratch->length);
+
+    cleanup_scratch();
+
+    if (!valid_etype(credmsg->enc_part.etype)) {
+       cleanup_credmsg();
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+
+    /* put together an eblock for this decryption */
+
+    krb5_use_cstype(&eblock, credmsg->enc_part.etype);
+    scratch->length = credmsg->enc_part.ciphertext.length;
+    
+    if (!(scratch->data = malloc(scratch->length))) {
+       cleanup_credmsg();
+        return ENOMEM;
+    }
+
+    /* do any necessary key pre-processing */
+    if (retval = krb5_process_key(&eblock, key)) {
+        cleanup_credmsg();
+       cleanup_scratch();
+       return retval;
+    }
+    
+#define cleanup_prockey() {(void) krb5_finish_key(&eblock);}
+    
+    /* call the decryption routine */
+    if (retval = krb5_decrypt((krb5_pointer) credmsg->enc_part.ciphertext.data,
+                             (krb5_pointer) scratch->data,
+                             scratch->length, &eblock,
+                             0)) {
+       cleanup_credmsg();
+       cleanup_scratch();
+        cleanup_prockey();
+       return retval;
+    }
+
+    /* cred message is now decrypted -- do some cleanup */
+
+    cleanup_credmsg();
+
+    if (retval = krb5_finish_key(&eblock)) {
+        cleanup_scratch();
+        return retval;
+    }
+
+    /*  now decode the decrypted stuff */
+    if (retval = decode_krb5_enc_cred_part(scratch, &credmsg_enc_part)) {
+       cleanup_scratch();
+       return retval;
+    }
+    cleanup_scratch();
+
+#define cleanup_mesg() {(void)xfree(credmsg_enc_part);}
+
+    if (retval = krb5_timeofday(&currenttime)) {
+       cleanup_mesg();
+       return retval;
+    }
+    if (!in_clock_skew(credmsg_enc_part->creds[0]->timestamp)) {
+       cleanup_mesg();  
+       return KRB5KRB_AP_ERR_SKEW;
+    }
+
+    if (sender_addr && credmsg_enc_part->creds[0]->s_address &&
+       !krb5_address_compare(sender_addr, 
+                             credmsg_enc_part->creds[0]->s_address)) {
+       cleanup_mesg();
+       return KRB5KRB_AP_ERR_BADADDR;
+    }
+    if (recv_addr && credmsg_enc_part->creds[0]->r_address &&
+       !krb5_address_compare(recv_addr, 
+                             credmsg_enc_part->creds[0]->r_address)) {
+       cleanup_mesg();
+       return KRB5KRB_AP_ERR_BADADDR;
+    }      
+
+    if (credmsg_enc_part->creds[0]->r_address) {
+       krb5_address **our_addrs;
+       
+       if (retval = krb5_os_localaddr(&our_addrs)) {
+           cleanup_mesg();
+           return retval;
+       }
+       if (!krb5_address_search(credmsg_enc_part->creds[0]->r_address, 
+                                our_addrs)) {
+           krb5_free_addresses(our_addrs);
+           cleanup_mesg();
+           return KRB5KRB_AP_ERR_BADADDR;
+       }
+       krb5_free_addresses(our_addrs);
+    }
+
+    if (retval = krb5_copy_principal(credmsg_enc_part->creds[0]->client,
+                                    &creds->client)) {
+       return(retval);
+    }
+
+    if (retval = krb5_copy_principal(credmsg_enc_part->creds[0]->server,
+                                    &creds->server)) {
+       return(retval);
+    }  
+
+    if (retval =
+       krb5_copy_keyblock_contents(credmsg_enc_part->creds[0]->session, 
+                                   &creds->keyblock)) {
+       return(retval);
+    }
+
+#undef clean
+#define clean() {\
+       memset((char *)creds->keyblock.contents, 0, creds->keyblock.length);}
+
+    creds->times = credmsg_enc_part->creds[0]->times;
+    creds->is_skey = FALSE;
+    creds->ticket_flags = credmsg_enc_part->creds[0]->flags;
+
+    if (retval = krb5_copy_addresses(credmsg_enc_part->creds[0]->caddrs,
+                                    &creds->addresses)) {
+       clean();
+       return(retval);
+    }
+
+    creds->second_ticket.length = 0;
+
+    creds->authdata = 0;
+
+    cleanup_mesg();
+    return 0;
+#undef clean
+#undef cleanup_credmsg
+#undef cleanup_scratch
+#undef cleanup_prockey
+#undef cleanup_mesg
+}
+
+#endif /* KERBEROS */
diff --git a/src/appl/bsd/setenv.c b/src/appl/bsd/setenv.c
new file mode 100644 (file)
index 0000000..08fa5f7
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setenv.c   5.2 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+/*
+ * setenv --
+ *     Set the value of the environmental variable "name" to be
+ *     "value".  If rewrite is set, replace any current value.
+ */
+setenv(name, value, rewrite)
+       register char *name, *value;
+       int rewrite;
+{
+       extern char **environ;
+       static int alloced;                     /* if allocated space before */
+       register char *C;
+       int l_value, offset;
+       char *malloc(), *realloc(), *_findenv();
+
+       if (*value == '=')                      /* no `=' in value */
+               ++value;
+       l_value = strlen(value);
+       if ((C = _findenv(name, &offset))) {    /* find if already exists */
+               if (!rewrite)
+                       return(0);
+               if (strlen(C) >= l_value) {     /* old larger; copy over */
+                       while (*C++ = *value++);
+                       return(0);
+               }
+       }
+       else {                                  /* create new slot */
+               register int    cnt;
+               register char   **P;
+
+               for (P = environ, cnt = 0; *P; ++P, ++cnt);
+               if (alloced) {                  /* just increase size */
+                       environ = (char **)realloc((char *)environ,
+                           (u_int)(sizeof(char *) * (cnt + 2)));
+                       if (!environ)
+                               return(-1);
+               }
+               else {                          /* get new space */
+                       alloced = 1;            /* copy old entries into it */
+                       P = (char **)malloc((u_int)(sizeof(char *) *
+                           (cnt + 2)));
+                       if (!P)
+                               return(-1);
+                       bcopy(environ, P, cnt * sizeof(char *));
+                       environ = P;
+               }
+               environ[cnt + 1] = NULL;
+               offset = cnt;
+       }
+       for (C = name; *C && *C != '='; ++C);   /* no `=' in name */
+       if (!(environ[offset] =                 /* name + `=' + value */
+           malloc((u_int)((int)(C - name) + l_value + 2))))
+               return(-1);
+       for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
+       for (*C++ = '='; *C++ = *value++;);
+       return(0);
+}
+
+/*
+ * unsetenv(name) --
+ *     Delete environmental variable "name".
+ */
+void
+unsetenv(name)
+       char    *name;
+{
+       extern  char    **environ;
+       register char   **P;
+       int     offset;
+       char    *_findenv();
+
+       while (_findenv(name, &offset))         /* if set multiple times */
+               for (P = &environ[offset];; ++P)
+                       if (!(*P = *(P + 1)))
+                               break;
+}
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getenv.c   5.5 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * getenv --
+ *     Returns ptr to value associated with name, if any, else NULL.
+ */
+char *
+getenv(name)
+       char *name;
+{
+       int offset;
+       char *_findenv();
+
+       return(_findenv(name, &offset));
+}
+
+/*
+ * _findenv --
+ *     Returns pointer to value associated with name, if any, else NULL.
+ *     Sets offset to be the offset of the name/value combination in the
+ *     environmental array, for use by setenv(3) and unsetenv(3).
+ *     Explicitly removes '=' in argument name.
+ *
+ *     This routine *should* be a static; don't use it.
+ */
+char *
+_findenv(name, offset)
+       register char *name;
+       int *offset;
+{
+       extern char **environ;
+       register int len;
+       register char **P, *C;
+
+       for (C = name, len = 0; *C && *C != '='; ++C, ++len);
+       for (P = environ; *P; ++P)
+               if (!strncmp(*P, name, len))
+                       if (*(C = *P + len) == '=') {
+                               *offset = P - environ;
+                               return(++C);
+                       }
+       return(NULL);
+}
diff --git a/src/appl/popper/.rconf b/src/appl/popper/.rconf
new file mode 100644 (file)
index 0000000..ca39b09
--- /dev/null
@@ -0,0 +1,5 @@
+ignore README
+ignore pop3.rfc1081
+ignore pop3e.rfc1082
+ignore orig-makefiles
+ignore syslog_levels
diff --git a/src/appl/popper/README b/src/appl/popper/README
new file mode 100644 (file)
index 0000000..43084cc
--- /dev/null
@@ -0,0 +1,318 @@
+@(#)README  1.6 7/13/90
+
+
+The Post Office Protocol Server:  Installation Guide
+
+
+
+Introduction
+
+The Post Office Protocol server runs on a variety of Unix[1] computers
+to manage electronic mail for Macintosh and MS-DOS computers.  The
+server was developed at the University of California at Berkeley and
+conforms fully to the specifications in RFC 1081[2] and RFC 1082[3].
+The Berkeley server also has extensions to send electronic mail on
+behalf of a client.
+
+This guide explains how to install the POP server on your Unix
+computer.  It assumes that you are not only familiar with Unix but also
+capable of performing Unix system administration.
+
+
+How to Obtain the Server
+
+The POP server is available via anonymous ftp from lilac.Berkeley.EDU
+(128.32.136.12).  It is in two files in the pub directory: a compressed
+tar file popper.tar.Z and a Macintosh StuffIt archive in BinHex format
+called MacPOP.sit.hqx.
+
+
+Contents of the Distribution
+
+The distribution contains the following:
+
++   All of the C source necessary to create the server program.
+
++   A visual representation of how the POP system works.
+
++   Reprints of RFC 1081 and RFC 1082.
+
++   A HyperCard stack POP client implementation using MacTCP.
+
++   A man page for the popper daemon.
+
++   This guide.
+
+
+Compatibility
+
+The Berkeley POP server has been successfully tested on the following
+Unix operating systems:
+
++   Berkeley Systems Distribution 4.3
+
++   Sun Microsystems Operating System versions 3.5 and 4.0
+
++   Ultrix version 2.3
+
+The following POP clients operate correctly with the Berkeley POP server:
+
++   The Berkeley HyperMail HyperCard stack for the Apple Macintosh 
+    (distributed with the server).
+
++   The Stanford University Macintosh Internet Protocol MacMH program.
+
++   The Stanford University Personal Computer Internet Protocol MH 
+    program.
+
++   The mh version 6.0 programs for Unix.
+
+
+Support
+
+The Berkeley POP server is not officially supported and is without any
+warranty, explicit or implied.  However, we are interested in your
+experiences using the server.  Bugs, comments and suggestions should be
+sent electronically to netinfo@garnet.Berkeley.EDU.
+
+
+Operational Characteristics
+
+The POP Transaction Cycle
+
+The Berkeley POP server is a single program (called popper) that is
+launched by inetd when it gets a service request on the POP TCP port.
+(The official port number specified in RFC 1081 for POP version 3 is
+port 110.  However, some POP3 clients attempt to contact the server at
+port 109, the POP version 2 port.  Unless you are running both POP2 and
+POP3 servers, you can simply define both ports for use by the POP3
+server.  This is explained in the installation instructions later on.)
+The popper program initializes and verifies that the peer IP address is
+registered in the local domain, logging a warning message when a
+connection is made to a client whose IP address does not have a
+canonical name.  For systems using BSD 4.3 bind, it also checks to see
+if a cannonical name lookup for the client returns the same peer IP
+address, logging a warning message if it does not.  The the server
+enters the authorization state, during which the client must correctly
+identify itself by providing a valid Unix userid and password on the
+server's host machine.  No other exchanges are allowed during this
+state (other than a request to quit.)  If authentication fails, a
+warning message is logged and the session ends.  Once the user is
+identified, popper changes its user and group ids to match that of the
+user and enters the transaction state.  The server makes a temporary
+copy of the user's maildrop (ordinarily in /usr/spool/mail) which is
+used for all subsequent transactions.  These include the bulk of POP
+commands to retrieve mail, delete mail, undelete mail, and so forth.  A
+Berkeley extension also allows the user to submit a mail parcel to the
+server who mails it using the sendmail program (this extension is
+supported in the HyperMail client distributed with the server).  When
+the client quits, the server enters the final update state during which
+the network connection is terminated and the user's maildrop is updated
+with the (possibly) modified temporary maildrop.
+
+
+Logging
+
+The POP server uses syslog to keep a record of its activities.  On
+systems with BSD 4.3 syslogging, the server logs (by default) to the
+"local0" facility at priority "notice" for all messages except
+debugging which is logged at priority "debug".  The default log file is
+/usr/spool/mqueue/POPlog.  These can be changed, if desired.  On
+systems with 4.2 syslogging all messages are logged to the local log
+file, usually /usr/spool/mqueue/syslog.
+
+
+Debugging
+
+The popper program will log debugging information when the -d parameter
+is specified after its invocation in the inetd.conf file.  Care should
+be exercised in using this option since it generates considerable
+output in the syslog file.  Alternatively, the "-t <file-name>" option
+will place debugging information into file "<file-name>" using fprintf
+instead of syslog.
+
+For SunOS version 3.5, the popper program is launched by inetd from
+/etc/servers.  This file does not allow you to specify command line
+arguments.  Therefore, if you want to enable debugging, you can specify
+a shell script in /etc/servers to be launched instead of popper and in
+this script call popper with the desired arguments.
+
+
+Installation
+
+1.  Examine this file for the latest information, warnings, etc.
+
+2.  Check the Makefile for conformity with your system.
+
+3.  Issue the make command in the directory containing the popper 
+    source.
+
+4.  Issue the make install command in the directory containing the 
+    popper source to copy the program to /usr/etc.
+
+5.  Enable syslogging:
+
+    +   For systems with 4.3 syslogging:
+
+        Add the following line to the /etc/syslog.conf file:
+
+            local0.notice;local0.debug  /usr/spool/mqueue/POPlog
+
+        Create the empty file /usr/spool/mqueue/POPlog.
+
+        Kill and restart the syslogd daemon.
+
+    +   For systems with 4.2 syslogging:
+
+        Be sure that you are logging messages of priority 7 and higher.  
+        For example:
+
+            7/usr/spool/mqueue/syslog
+            9/dev/null
+
+6.  Update /etc/services:
+
+    Add the following line to the /etc/services file:
+
+        pop 110/tcp
+
+    Note:  This is the official port number for version 3 of the
+    Post Office Protocol as defined in RFC 1081.  However, some
+    POP3 clients use port 109, the port number for the previous
+    version (2) of POP.  Therefore you may also want to add the
+    following line to the /etc/services file:
+
+    pop2    109/tcp
+
+    For Sun systems running yp, also do the following:
+
+    +   Change to the /var/yp directory.
+
+    +   Issue the make services command.
+
+7.  Update the inetd daemon configuration.  Include the second line ONLY if you
+    are running the server at both ports.
+
+    +   On BSD 4.3 and SunOS 4.0 systems, add the following line to the 
+        /etc/inetd.conf file:
+
+        pop stream tcp nowait root /usr/etc/popper popper
+        pop2 stream tcp nowait root /usr/etc/popper popper
+
+    +   On Ultrix systems, add the following line to the 
+        /etc/inetd.conf file:
+
+        pop stream tcp nowait /usr/etc/popper popper
+        pop2 stream tcp nowait /usr/etc/popper popper
+
+    +   On SunOS 3.5 systems, add the following line to the 
+        /etc/servers file:
+
+        pop tcp /usr/etc/popper
+        pop2 tcp /usr/etc/popper
+
+        Kill and restart the inetd daemon.
+
+You can confirm that the POP server is running on Unix by telneting to
+port 110 (or 109 if you set it up that way).  For example:
+
+%telnet myhost 110
+Trying...
+Connected to myhost.berkeley.edu.
+Escape character is '^]'.
++OK UCB Pop server (version 1.6) at myhost starting.
+quit
+Connection closed by foreign host.
+
+
+Release Notes
+
+1.7     Extensive re-write of the maildrop processing code contributed by 
+        Viktor Dukhovni <viktor@math.princeton.edu> that greatly reduces the
+        possibility that the maildrop can be corrupted as the result of
+        simultaneous access by two or more processes.
+
+        Added "pop_dropcopy" module to create a temporary maildrop from
+        the existing, standard maildrop as root before the setuid and 
+        setgid for the user is done.  This allows the temporary maildrop
+        to be created in a mail spool area that is not world read-writable.
+
+        This version does *not* send the sendmail "From " delimiter line
+        in response to a TOP or RETR command.
+
+        Encased all debugging code in #ifdef DEBUG constructs.  This code can
+        be included by specifying the DEGUG compiler flag.  Note:  You still
+        need to use the -d or -t option to obtain debugging output.
+
+1.6     Corrects a bug that causes the server to crash on SunOS
+        4.0 systems.
+
+        Uses varargs and vsprintf (if available) in pop_log and
+        pop_msg.  This is enabled by the "HAVE_VSPRINTF"
+        compiler flag.
+
+        For systems with BSD 4.3 bind, performs a cannonical
+        name lookup and searches the returned address(es) for
+        the client's address, logging a warning message if it
+        is not located.  This is enabled by the "BIND43"
+        comiler flag.
+
+        Removed all the includes from popper.h and distributed
+        them throughout the porgrams files, as needed.
+
+        Reformatted the source to convert tabs to spaces and
+        shorten lines for display on 80-column terminals.
+
+1.5     Creates the temporary maildrop with mode "600" and
+        immediately unlinks it.
+
+        Uses client's IP address in lieu of a canonical name if
+        the latter cannot be obtained.
+
+        Added "-t <file-name>" option.  The presence of this
+        option causes debugging output to be placed in the file
+        "file-name" using fprintf instead of the system log
+        file using syslog.
+
+        Corrected maildrop parsing problem.
+
+1.4     Copies user's mail into a temporary maildrop on which
+        all subsequent activity is performed.
+
+        Added "pop_log" function and replaced "syslog" calls
+        throughout the code with it.
+
+1.3     Corrected updating of Status: header line.
+
+        Added strncasecmp for systems that do not have one.
+        Used strncasecmp in all appropriate places.  This is
+        enabled by the STRNCASECMP compiler flag.
+
+1.2     Support for version 4.2 syslogging added.  This is
+        enabled by the SYSLOG42 compiler flag.
+
+1.1     Several bugs fixed.
+
+
+Credits
+
+The POP server was written by Edward Moy and Austin Shelton with
+contributions from Robert Campbell (U.C. Berkeley) and Viktor Dukhovni
+(Princeton University).  Edward Moy wrote the HyperMail stack and drew
+the POP operation diagram.  This installation guide was written by
+Austin Shelton.
+
+
+Footnotes
+
+[1] Copyright (c) 1990 Regents of the University of California.
+    All rights reserved.  The Berkeley software License Agreement
+    specifies the terms and conditions for redistribution.  Unix is
+    a registered trademark of AT&T corporation.  HyperCard and
+    Macintosh are registered trademarks of Apple Corporation.
+
+[2] M. Rose, Post Office Protocol - Version 3.  RFC  1081, NIC, 
+    November 1988.
+
+[3] M. Rose, Post Office Protocol - Version 3 Extended Service 
+    Offerings.  RFC 1082, NIC, November 1988.
diff --git a/src/appl/popper/orig-makefiles/Makefile.krb_passwd_hack b/src/appl/popper/orig-makefiles/Makefile.krb_passwd_hack
new file mode 100644 (file)
index 0000000..c8a5c5c
--- /dev/null
@@ -0,0 +1,107 @@
+CSRCS          =       pop_dele.c pop_dropcopy.c pop_dropinfo.c \
+                       pop_get_command.c pop_get_subcommand.c pop_init.c \
+                       pop_last.c pop_list.c pop_log.c pop_lower.c \
+                       pop_msg.c pop_parse.c pop_pass.c pop_quit.c \
+                       pop_rset.c pop_send.c pop_stat.c pop_updt.c \
+                       pop_user.c pop_xtnd.c pop_xmit.c popper.c
+
+OBJS           =       pop_dele.o pop_dropcopy.o pop_dropinfo.o \
+                       pop_get_command.o pop_get_subcommand.o pop_init.o \
+                       pop_last.o pop_list.o pop_log.o pop_lower.o \
+                       pop_msg.o pop_parse.o pop_pass.o pop_quit.o \
+                       pop_rset.o pop_send.o pop_stat.o pop_updt.o \
+                       pop_user.o pop_xtnd.o pop_xmit.o popper.o
+
+SP_SRCS                =       pop_enter.c 
+SP_OBJS                =       pop_enter.o 
+
+DOCS           =       README pop3.rfc1081 pop3e.rfc1082 popper.8
+
+INCLUDES       =       popper.h version.h
+
+SRCS           =       ${CSRCS} ${INCLUDES}
+
+SCCS           =       /usr/ucb/sccs
+
+REL            =
+
+MAKEFILE       =       Makefile
+
+#               Options are:
+#               BIND43          -      If you are using BSD 4.3 domain 
+#                                      name service.
+#              DEBUG           -       Include the debugging code.  Note:  You
+#                                      still have to use the -d or -t flag to
+#                                      enable debugging.
+#               HAVE_VSPRINTF   -      If the vsprintf functions are available 
+#                                      on your system.
+#               SYSLOG42        -      For BSD 4.2 syslog (default is BSD 4.3 
+#                                      syslog).
+#               STRNCASECMP     -      If you do not have strncasecmp()
+#              KERBEROS        -       If you want authentication vis Kerberos
+#                                                                      (tm)
+
+CFLAGS         =       -O -DBIND43 -DKERBEROS_PASSWD_HACK
+
+TARGET         =       popper
+
+TAR            =       ${TARGET}.tar
+
+INSTALLDIR     =       /usr/etc
+
+MANPAGE                =       popper.8
+
+CATPAGE                =       popper.0
+
+MANDIR         =       /usr/local/man/cat8
+
+LIBS           =       -lkrb -ldes
+
+all: ${TARGET} spop
+
+spop:  ${SP_OBJS}
+       cc  ${SP_OBJS} -o spop ${LIBS}
+
+${TARGET}: ${OBJS}
+       cc  ${OBJS} -o ${TARGET} ${LIBS}
+
+tar: ${SRCS} ${DOCS} ${MAKEFILE}
+       rm -f ${TAR} *.Z*
+       tar -cvf ${TAR} ${SRCS} ${DOCS} ${MAKEFILE}
+       compress ${TAR}
+       uuencode ${TAR}.Z ${TAR}.Z > ${TAR}.Z.uuencoded
+       split -300 ${TAR}.Z.uuencoded
+       mv xaa ${TAR}.Z.uuencoded.xaa
+       mv xab ${TAR}.Z.uuencoded.xab
+       mv xac ${TAR}.Z.uuencoded.xac
+       mv xad ${TAR}.Z.uuencoded.xad
+       mv xae ${TAR}.Z.uuencoded.xae
+
+clean:
+       rm -f core *.o *.Z*
+       ${SCCS} clean
+
+install: ${TARGET}
+       install -c -m 700 -o root -g staff ${TARGET} ${INSTALLDIR}
+
+installman:
+       rm -f ${CATPAGE}
+       nroff -man ${MANPAGE} > ${CATPAGE}
+       install -c -m 644 -o root -g staff ${CATPAGE} ${MANDIR}
+
+edit:
+       ${SCCS} edit ${REL} ${SRCS}
+
+admin:
+       ${SCCS} admin -ft"Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n" ${SRCS}
+
+sources: ${SRCS}
+
+${SRCS}:
+       ${SCCS} get ${REL} $@ -p | expand -4 > $@
+
+${DOCS}:
+       ${SCCS} get README -p | expand -4 > README
+       ${SCCS} get popper.8 -p | expand -4 > popper.8
+       
+${OBJS}:    popper.h version.h
diff --git a/src/appl/popper/pop3.rfc1081 b/src/appl/popper/pop3.rfc1081
new file mode 100644 (file)
index 0000000..08ea6dd
--- /dev/null
@@ -0,0 +1,898 @@
+
+
+
+
+
+
+Network Working Group                                            M. Rose
+Request for Comments: 1081                                           TWG
+                                                           November 1988
+
+                    Post Office Protocol - Version 3
+
+
+Status of this Memo
+
+   This memo suggests a simple method for workstations to dynamically
+   access mail from a mailbox server.  This RFC specifies a proposed
+   protocol for the Internet community, and requests discussion and
+   suggestions for improvements.  Distribution of this memo is
+   unlimited.
+
+   This memo is based on RFC 918 (since revised as RFC 937).  Although
+   similar in form to the original Post Office Protocol (POP) proposed
+   for the Internet community, the protocol discussed in this memo is
+   similar in spirit to the ideas investigated by the MZnet project at
+   the University of California, Irvine.
+
+   Further, substantial work was done on examining POP in a PC-based
+   environment.  This work, which resulted in additional functionality
+   in this protocol, was performed by the ACIS Networking Systems Group
+   at Stanford University.  The author gratefully acknowledges their
+   interest.
+
+Introduction
+
+   On certain types of smaller nodes in the Internet it is often
+   impractical to maintain a message transport system (MTS).  For
+   example, a workstation may not have sufficient resources (cycles,
+   disk space) in order to permit a SMTP server and associated local
+   mail delivery system to be kept resident and continuously running.
+   Similarly, it may be expensive (or impossible) to keep a personal
+   computer interconnected to an IP-style network for long amounts of
+   time (the node is lacking the resource known as "connectivity").
+
+   Despite this, it is often very useful to be able to manage mail on
+   these smaller nodes, and they often support a user agent (UA) to aid
+   the tasks of mail handling.  To solve this problem, a node which can
+   support an MTS entity offers a maildrop service to these less endowed
+   nodes.  The Post Office Protocol - Version 3 (POP3) is intended to
+   permit a workstation to dynamically access a maildrop on a server
+   host in a useful fashion.  Usually, this means that the POP3 is used
+   to allow a workstation to retrieve mail that the server is holding
+   for it.
+
+
+
+
+Rose                                                            [Page 1]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+   For the remainder of this memo, the term "client host" refers to a
+   host making use of the POP3 service, while the term "server host"
+   refers to a host which offers the POP3 service.
+
+A Short Digression
+
+   This memo does not specify how a client host enters mail into the
+   transport system, although a method consistent with the philosophy of
+   this memo is presented here:
+
+      When the user agent on a client host wishes to enter a message
+      into the transport system, it establishes an SMTP connection to
+      its relay host (this relay host could be, but need not be, the
+      POP3 server host for the client host).
+
+   If this method is followed, then the client host appears to the MTS
+   as a user agent, and should NOT be regarded as a "trusted" MTS entity
+   in any sense whatsoever.  This concept, along with the role of the
+   POP3 as a part of a split-UA model is discussed later in this memo.
+
+   Initially, the server host starts the POP3 service by listening on
+   TCP port 110.  When a client host wishes to make use of the service,
+   it establishes a TCP connection with the server host.  When the
+   connection is established, the POP3 server sends a greeting.  The
+   client and POP3 server then exchange commands and responses
+   (respectively) until the connection is closed or aborted.
+
+   Commands in the POP3 consist of a keyword possibly followed by an
+   argument.  All commands are terminated by a CRLF pair.
+
+   Responses in the POP3 consist of a success indicator and a keyword
+   possibly followed by additional information.  All responses are
+   terminated by a CRLF pair.  There are currently two success
+   indicators: positive ("+OK") and negative ("-ERR").
+
+   Responses to certain commands are multi-line.  In these cases, which
+   are clearly indicated below, after sending the first line of the
+   response and a CRLF, any additional lines are sent, each terminated
+   by a CRLF pair.  When all lines of the response have been sent, a
+   final line is sent, consisting of a termination octet (decimal code
+   046, ".") and a CRLF pair.  If any line of the multi-line response
+   begins with the termination octet, the line is "byte-stuffed" by
+   pre-pending the termination octet to that line of the response.
+   Hence a multi-line response is terminated with the five octets
+   "CRLF.CRLF".  When examining a multi-line response, the client checks
+   to see if the line begins with the termination octet.  If so and if
+   octets other than CRLF follow, the the first octet of the line (the
+   termination octet) is stripped away.  If so and if CRLF immediately
+
+
+
+Rose                                                            [Page 2]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+   follows the termination character, then the response from the POP
+   server is ended and the line containing ".CRLF" is not considered
+   part of the multi-line response.
+
+   A POP3 session progresses through a number of states during its
+   lifetime.  Once the TCP connection has been opened and the POP3
+   server has sent the greeting, the session enters the AUTHORIZATION
+   state.  In this state, the client must identify itself to the POP3
+   server.  Once the client has successfully done this, the server
+   acquires resources associated with the client's maildrop, and the
+   session enters the TRANSACTION state.  In this state, the client
+   requests actions on the part of the POP3 server.  When the client has
+   finished its transactions, the session enters the UPDATE state.  In
+   this state, the POP3 server releases any resources acquired during
+   the TRANSACTION state and says goodbye.  The TCP connection is then
+   closed.
+
+The AUTHORIZATION State
+
+   Once the TCP connection has been opened by a POP3 client, the POP3
+   server issues a one line greeting.  This can be any string terminated
+   by CRLF.  An example might be:
+
+      S.  +OK dewey POP3 server ready (Comments to: PostMaster@UDEL.EDU)
+
+   Note that this greeting is a POP3 reply.  The POP3 server should
+   always give a positive response as the greeting.
+
+   The POP3 session is now in the AUTHORIZATION state.  The client must
+   now issue the USER command.  If the POP3 server responds with a
+   positive success indicator ("+OK"), then the client may issue either
+   the PASS command to complete the authorization, or the QUIT command
+   to terminate the POP3 session.  If the POP3 server responds with a
+   negative success indicator ("-ERR") to the USER command, then the
+   client may either issue a new USER command or may issue the QUIT
+   command.
+
+   When the client issues the PASS command, the POP3 server uses the
+   argument pair from the USER and PASS commands to determine if the
+   client should be given access to the appropriate maildrop.  If so,
+   the POP3 server then acquires an exclusive-access lock on the
+   maildrop.  If the lock is successfully acquired, the POP3 server
+   parses the maildrop into individual messages (read note below),
+   determines the last message (if any) present in the maildrop that was
+   referenced by the RETR command, and responds with a positive success
+   indicator.  The POP3 session now enters the TRANSACTION state.  If
+   the lock can not be acquired or the client should is denied access to
+   the appropriate maildrop or the maildrop can't be parsed for some
+
+
+
+Rose                                                            [Page 3]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+   reason, the POP3 server responds with a negative success indicator.
+   (If a lock was acquired but the POP3 server intends to respond with a
+   negative success indicator, the POP3 server must release the lock
+   prior to rejecting the command.)  At this point, the client may
+   either issue a new USER command and start again, or the client may
+   issue the QUIT command.
+
+                 NOTE: Minimal implementations of the POP3 need only be
+                 able to break a maildrop into its component messages;
+                 they need NOT be able to parse individual messages.
+                 More advanced implementations may wish to have this
+                 capability, for reasons discussed later.
+
+   After the POP3 server has parsed the maildrop into individual
+   messages, it assigns a message-id to each message, and notes the size
+   of the message in octets.  The first message in the maildrop is
+   assigned a message-id of "1", the second is assigned "2", and so on,
+   so that the n'th message in a maildrop is assigned a message-id of
+   "n".  In POP3 commands and responses, all message-id's and message
+   sizes are expressed in base-10 (i.e., decimal).
+
+   It sets the "highest number accessed" to be that of the last message
+   referenced by the RETR command.
+
+   Here are summaries for the three POP3 commands discussed thus far:
+
+           USER name
+               Arguments: a server specific user-id (required)
+               Restrictions: may only be given in the AUTHORIZATION
+                   state after the POP3 greeting or after an
+                   unsuccessful USER or PASS command
+               Possible Responses:
+                   +OK name is welcome here
+                   -ERR never heard of name
+               Examples:
+                   C:    USER mrose
+                   S:    +OK mrose is a real hoopy frood
+                     ...
+                   C:    USER frated
+                   S:    -ERR sorry, frated doesn't get his mail here
+
+           PASS string
+               Arguments: a server/user-id specific password (required)
+               Restrictions: may only be given in the AUTHORIZATION
+                   state after a successful USER command
+               Possible Responses:
+                   +OK maildrop locked and ready
+                   -ERR invalid password
+
+
+
+Rose                                                            [Page 4]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                   -ERR unable to lock maildrop
+               Examples:
+                   C:    USER mrose
+                   S:    +OK mrose is a real hoopy frood
+                   C:    PASS secret
+                   S:    +OK mrose's maildrop has 2 messages
+                         (320 octets)
+                     ...
+                   C:    USER mrose
+                   S:    +OK mrose is a real hoopy frood
+                   C:    PASS secret
+                   S:    -ERR unable to lock mrose's maildrop, file
+                         already locked
+
+           QUIT
+               Arguments: none
+               Restrictions: none
+               Possible Responses:
+                   +OK
+               Examples:
+                   C:    QUIT
+                   S:    +OK dewey POP3 server signing off
+
+
+The TRANSACTION State
+
+   Once the client has successfully identified itself to the POP3 server
+   and the POP3 server has locked and burst the appropriate maildrop,
+   the POP3 session is now in the TRANSACTION state.  The client may now
+   issue any of the following POP3 commands repeatedly.  After each
+   command, the POP3 server issues a response.  Eventually, the client
+   issues the QUIT command and the POP3 session enters the UPDATE state.
+
+   Here are the POP3 commands valid in the TRANSACTION state:
+
+           STAT
+               Arguments: none
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 The POP3 server issues a positive response with a line
+                 containing information for the maildrop.  This line is
+                 called a "drop listing" for that maildrop.
+
+                 In order to simplify parsing, all POP3 servers are
+                 required to use a certain format for drop listings.
+                 The first octets present must indicate the number of
+                 messages in the maildrop.  Following this is the size
+
+
+
+Rose                                                            [Page 5]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                 of the maildrop in octets.  This memo makes no
+                 requirement on what follows the maildrop size.
+                 Minimal implementations should just end that line of
+                 the response with a CRLF pair.  More advanced
+                 implementations may include other information.
+
+                      NOTE: This memo STRONGLY discourages
+                      implementations from supplying additional
+                      information in the drop listing.  Other,
+                      optional, facilities are discussed later on
+                      which permit the client to parse the messages
+                      in the maildrop.
+
+                 Note that messages marked as deleted are not counted in
+                 either total.
+
+               Possible Responses:
+                   +OK nn mm
+               Examples:
+                   C:    STAT
+                   S:    +OK 2 320
+
+           LIST [msg]
+               Arguments: a message-id (optionally)  If a message-id is
+                   given, it may NOT refer to a message marked as
+                   deleted.
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 If an argument was given and the POP3 server issues a
+                 positive response with a line containing information
+                 for that message.  This line is called a "scan listing"
+                 for that message.
+
+                 If no argument was given and the POP3 server issues a
+                 positive response, then the response given is
+                 multi-line.  After the initial +OK, for each message
+                 in the maildrop, the POP3 server responds with a line
+                 containing information for that message.  This line
+                 is called a "scan listing" for that message.
+
+                 In order to simplify parsing, all POP3 servers are
+                 required to use a certain format for scan listings.
+                 The first octets present must be the message-id of
+                 the message.  Following the message-id is the size of
+                 the message in octets.  This memo makes no requirement
+                 on what follows the message size in the scan listing.
+                 Minimal implementations should just end that line of
+
+
+
+Rose                                                            [Page 6]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                 the response with a CRLF pair.  More advanced
+                 implementations may include other information, as
+                 parsed from the message.
+
+                      NOTE: This memo STRONGLY discourages
+                      implementations from supplying additional
+                      information in the scan listing.  Other, optional,
+                      facilities are discussed later on which permit
+                      the client to parse the messages in the maildrop.
+
+                 Note that messages marked as deleted are not listed.
+
+               Possible Responses:
+                   +OK scan listing follows
+                   -ERR no such message
+               Examples:
+                   C:    LIST
+                   S:    +OK 2 messages (320 octets)
+                   S:    1 120
+                   S:    2 200
+                   S:    .
+                     ...
+                   C:    LIST 2
+                   S:    +OK 2 200
+                     ...
+                   C:    LIST 3
+                   S:    -ERR no such message, only 2 messages in
+                         maildrop
+
+           RETR msg
+               Arguments: a message-id (required)  This message-id may
+                   NOT refer to a message marked as deleted.
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 If the POP3 server issues a positive response, then the
+                 response given is multi-line.  After the initial +OK,
+                 the POP3 server sends the message corresponding to the
+                 given message-id, being careful to byte-stuff the
+                 termination character (as with all multi-line
+                 responses).
+
+                 If the number associated with this message is higher
+                 than the "highest number accessed" in the maildrop, the
+                 POP3 server updates the "highest number accessed" to
+                 the number associated with this message.
+
+
+
+
+
+Rose                                                            [Page 7]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+               Possible Responses:
+                   +OK message follows
+                   -ERR no such message
+               Examples:
+                   C:    RETR 1
+                   S:    +OK 120 octets
+                   S:    <the POP3 server sends the entire message here>
+                   S:    .
+
+           DELE msg
+               Arguments: a message-id (required)  This message-id
+                   may NOT refer to a message marked as deleted.
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 The POP3 server marks the message as deleted.  Any
+                 future reference to the message-id associated with the
+                 message in a POP3 command generates an error.  The POP3
+                 server does not actually delete the message until the
+                 POP3 session enters the UPDATE state.
+
+                 If the number associated with this message is higher
+                 than the "highest number accessed" in the maildrop,
+                 the POP3 server updates the "highest number accessed"
+                 to the number associated with this message.
+
+               Possible Responses:
+                   +OK message deleted
+                   -ERR no such message
+               Examples:
+                   C:    DELE 1
+                   S:    +OK message 1 deleted
+                     ...
+                   C:    DELE 2
+                   S:    -ERR message 2 already deleted
+
+           NOOP
+               Arguments: none
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 The POP3 server does nothing, it merely replies with a
+                 positive response.
+
+               Possible Responses:
+                   +OK
+
+
+
+
+
+Rose                                                            [Page 8]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+               Examples:
+                   C:    NOOP
+                   S:    +OK
+
+           LAST
+               Arguments: none
+               Restrictions: may only be issued in the TRANSACTION state.
+               Discussion:
+
+                 The POP3 server issues a positive response with a line
+                 containing the highest message number which accessed.
+                 Zero is returned in case no message in the maildrop has
+                 been accessed during previous transactions.  A client
+                 may thereafter infer that messages, if any, numbered
+                 greater than the response to the LAST command are
+                 messages not yet accessed by the client.
+
+             Possible Response:
+                   +OK nn
+
+             Examples:
+                   C:      STAT
+                   S:      +OK 4 320
+                   C:      LAST
+                   S:      +OK 1
+                   C:      RETR 3
+                   S:      +OK 120 octets
+                   S:      <the POP3 server sends the entire message
+                           here>
+                   S:      .
+                   C:      LAST
+                   S:      +OK 3
+                   C:      DELE 2
+                   S:      +OK message 2 deleted
+                   C:      LAST
+                   S:      +OK 3
+                   C:      RSET
+                   S:      +OK
+                   C:      LAST
+                   S:      +OK 1
+
+           RSET
+               Arguments: none
+               Restrictions: may only be given in the TRANSACTION
+                   state.
+               Discussion:
+
+                 If any messages have been marked as deleted by the POP3
+
+
+
+Rose                                                            [Page 9]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                 server, they are unmarked.  The POP3 server then
+                 replies with a positive response.  In addition, the
+                 "highest number accessed" is also reset to the value
+                 determined at the beginning of the POP3 session.
+
+               Possible Responses:
+                   +OK
+               Examples:
+                   C:    RSET
+                   S:    +OK maildrop has 2 messages (320 octets)
+
+
+
+The UPDATE State
+
+   When the client issues the QUIT command from the TRANSACTION state,
+   the POP3 session enters the UPDATE state.  (Note that if the client
+   issues the QUIT command from the AUTHORIZATION state, the POP3
+   session terminates but does NOT enter the UPDATE state.)
+
+           QUIT
+               Arguments: none
+               Restrictions: none
+               Discussion:
+
+                 The POP3 server removes all messages marked as deleted
+                 from the maildrop.  It then releases the
+                 exclusive-access lock on the maildrop and replies as
+                 to the success of
+                 these operations.  The TCP connection is then closed.
+
+               Possible Responses:
+                   +OK
+               Examples:
+                   C:    QUIT
+                   S:    +OK dewey POP3 server signing off (maildrop
+                         empty)
+                     ...
+                   C:    QUIT
+                   S:    +OK dewey POP3 server signing off (2 messages
+                         left)
+                     ...
+
+
+Optional POP3 Commands
+
+   The POP3 commands discussed above must be supported by all minimal
+   implementations of POP3 servers.
+
+
+
+Rose                                                           [Page 10]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+   The optional POP3 commands described below permit a POP3 client
+   greater freedom in message handling, while preserving a simple POP3
+   server implementation.
+
+                 NOTE: This memo STRONGLY encourages implementations to
+                 support these commands in lieu of developing augmented
+                 drop and scan listings.  In short, the philosophy of
+                 this memo is to put intelligence in the part of the
+                 POP3 client and not the POP3 server.
+
+           TOP msg n
+               Arguments: a message-id (required) and a number.  This
+                   message-id may NOT refer to a message marked as
+                   deleted.
+               Restrictions: may only be given in the TRANSACTION state.
+               Discussion:
+
+                 If the POP3 server issues a positive response, then
+                 the response given is multi-line.  After the initial
+                 +OK, the POP3 server sends the headers of the message,
+                 the blank line separating the headers from the body,
+                 and then the number of lines indicated message's body,
+                 being careful to byte-stuff the termination character
+                 (as with all multi-line responses).
+
+                 Note that if the number of lines requested by the POP3
+                 client is greater than than the number of lines in the
+                 body, then the POP3 server sends the entire message.
+
+               Possible Responses:
+                   +OK top of message follows
+                   -ERR no such message
+               Examples:
+                   C:    TOP 10
+                   S:    +OK
+                   S:    <the POP3 server sends the headers of the
+                          message, a blank line, and the first 10 lines
+                          of the body of the message>
+                   S:    .
+                     ...
+                   C:    TOP 100
+                   S:    -ERR no such message
+
+           RPOP user
+               Arguments: a client specific user-id (required)
+               Restrictions: may only be given in the AUTHORIZATION
+                   state after a successful USER command; in addition,
+                   may only be given if the client used a reserved
+
+
+
+Rose                                                           [Page 11]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                   (privileged) TCP port to connect to the server.
+               Discussion:
+
+                 The RPOP command may be used instead of the PASS
+                 command to authenticate access to the maildrop.  In
+                 order for this command to be successful, the POP3
+                 client must use a reserved TCP port (port < 1024) to
+                 connect tothe server.  The POP3 server uses the
+                 argument pair from the USER and RPOP commands to
+                 determine if the client should be given access to
+                 the appropriate maildrop.  Unlike the PASS command
+                 however, the POP3 server considers if the remote user
+                 specified by the RPOP command who resides on the POP3
+                 client host is allowed to access the maildrop for the
+                 user specified by the USER command (e.g., on Berkeley
+                 UNIX, the .rhosts mechanism is used).  With the
+                 exception of this differing in authentication, this
+                 command is identical to the PASS command.
+
+                 Note that the use of this feature has allowed much wider
+                 penetration into numerous hosts on local networks (and
+                 sometimes remote networks) by those who gain illegal
+                 access to computers by guessing passwords or otherwise
+                 breaking into the system.
+
+               Possible Responses:
+                   +OK maildrop locked and ready
+                   -ERR permission denied
+               Examples:
+                   C:    USER mrose
+                   S:    +OK mrose is a real hoopy frood
+                   C:    RPOP mrose
+                   S:    +OK mrose's maildrop has 2 messages (320
+                         octets)
+
+       Minimal POP3 Commands:
+           USER name               valid in the AUTHORIZATION state
+           PASS string
+           QUIT
+
+           STAT                    valid in the TRANSACTION state
+           LIST [msg]
+           RETR msg
+           DELE msg
+           NOOP
+           LAST
+           RSET
+
+
+
+
+Rose                                                           [Page 12]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+           QUIT                    valid in the UPDATE state
+
+       Optional POP3 Commands:
+           RPOP user               valid in the AUTHORIZATION state
+
+           TOP msg n               valid in the TRANSACTION state
+
+       POP3 Replies:
+           +OK
+           -ERR
+
+       Note that with the exception of the STAT command, the reply given
+       by the POP3 server to any command is significant only to "+OK"
+       and "-ERR".  Any text occurring after this reply may be ignored
+       by the client.
+
+Example POP3 Session
+
+    S: <wait for connection on TCP port 110>
+        ...
+    C: <open connection>
+    S:    +OK dewey POP3 server ready (Comments to: PostMaster@UDEL.EDU)
+    C:    USER mrose
+    S:    +OK mrose is a real hoopy frood
+    C:    PASS secret
+    S:    +OK mrose's maildrop has 2 messages (320 octets)
+    C:    STAT
+    S:    +OK 2 320
+    C:    LIST
+    S:    +OK 2 messages (320 octets)
+    S:    1 120
+    S:    2 200
+    S:    .
+    C:    RETR 1
+    S:    +OK 120 octets
+    S:    <the POP3 server sends message 1>
+    S:    .
+    C:    DELE 1
+    S:    +OK message 1 deleted
+    C:    RETR 2
+    S:    +OK 200 octets
+    S:    <the POP3 server sends message 2>
+    S:    .
+    C:    DELE 2
+    S:    +OK message 2 deleted
+    C:    QUIT
+
+
+
+
+
+Rose                                                           [Page 13]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+    S:    +OK dewey POP3 server signing off (maildrop empty)
+    C:  <close connection>
+    S:  <wait for next connection>
+
+Message Format
+
+   All messages transmitted during a POP3 session are assumed to conform
+   to the standard for the format of Internet text messages [RFC822].
+
+   It is important to note that the byte count for a message on the
+   server host may differ from the octet count assigned to that message
+   due to local conventions for designating end-of-line.  Usually,
+   during the AUTHORIZATION state of the POP3 session, the POP3 client
+   can calculate the size of each message in octets when it parses the
+   maildrop into messages.  For example, if the POP3 server host
+   internally represents end-of-line as a single character, then the
+   POP3 server simply counts each occurrence of this character in a
+   message as two octets.  Note that lines in the message which start
+   with the termination octet need not be counted twice, since the POP3
+   client will remove all byte-stuffed termination characters when it
+   receives a multi-line response.
+
+The POP and the Split-UA model
+
+   The underlying paradigm in which the POP3 functions is that of a
+   split-UA model.  The POP3 client host, being a remote PC based
+   workstation, acts solely as a client to the message transport system.
+   It does not provide delivery/authentication services to others.
+   Hence, it is acting as a UA, on behalf of the person using the
+   workstation.  Furthermore, the workstation uses SMTP to enter mail
+   into the MTS.
+
+   In this sense, we have two UA functions which interface to the
+   message transport system: Posting (SMTP) and Retrieval (POP3).  The
+   entity which supports this type of environment is called a split-UA
+   (since the user agent is split between two hosts which must
+   interoperate to provide these functions).
+
+                 ASIDE:  Others might term this a remote-UA instead.
+                 There are arguments supporting the use of both terms.
+
+   This memo has explicitly referenced TCP as the underlying transport
+   agent for the POP3.  This need not be the case.  In the MZnet split-
+   UA, for example, personal micro-computer systems are used which do
+   not have IP-style networking capability.  To connect to the POP3
+   server host, a PC establishes a terminal connection using some simple
+   protocol (PhoneNet).  A program on the PC drives the connection,
+   first establishing a login session as a normal user.  The login shell
+
+
+
+Rose                                                           [Page 14]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+   for this pseudo-user is a program which drives the other half of the
+   terminal protocol and communicates with one of two servers.  Although
+   MZnet can support several PCs, a single pseudo-user login is present
+   on the server host.  The user-id and password for this pseudo-user
+   login is known to all members of MZnet.  Hence, the first action of
+   the login shell, after starting the terminal protocol, is to demand a
+   USER/PASS authorization pair from the PC.  This second level of
+   authorization is used to ascertain who is interacting with the MTS.
+   Although the server host is deemed to support a "trusted" MTS entity,
+   PCs in MZnet are not.  Naturally, the USER/PASS authorization pair
+   for a PC is known only to the owner of the PC (in theory, at least).
+
+   After successfully verifying the identity of the client, a modified
+   SMTP server is started, and the PC posts mail with the server host.
+   After the QUIT command is given to the SMTP server and it terminates,
+   a modified POP3 server is started, and the PC retrieves mail from the
+   server host.  After the QUIT command is given to the POP3 server and
+   it terminates, the login shell for the pseudo-user terminates the
+   terminal protocol and logs the job out.  The PC then closes the
+   terminal connection to the server host.
+
+   The SMTP server used by MZnet is modified in the sense that it knows
+   that it's talking to a user agent and not a "trusted" entity in the
+   message transport system.  Hence, it does performs the validation
+   activities normally performed by an entity in the MTS when it accepts
+   a message from a UA.
+
+   The POP3 server used by MZnet is modified in the sense that it does
+   not require a USER/PASS combination before entering the TRANSACTION
+   state.  The reason for this (of course) is that the PC has already
+   identified itself during the second-level authorization step
+   described above.
+
+                 NOTE: Truth in advertising laws require that the author
+                 of this memo state that MZnet has not actually been
+                 fully implemented.  The concepts presented and proven
+                 by the project led to the notion of the MZnet
+                 split-slot model.  This notion has inspired the
+                 split-UA concept described in this memo, led to the
+                 author's interest in the POP, and heavily influenced
+                 the the description of the POP3 herein.
+
+   In fact, some UAs present in the Internet already support the notion
+   of posting directly to an SMTP server and retrieving mail directly
+   from a POP server, even if the POP server and client resided on the
+   same host!
+
+                 ASIDE: this discussion raises an issue which this memo
+
+
+
+Rose                                                           [Page 15]
+\f
+RFC 1081                          POP3                     November 1988
+
+
+                 purposedly avoids: how does SMTP know that it's talking
+                 to a "trusted" MTS entity?
+
+References
+
+     [MZnet]   Stefferud, E., J. Sweet, and T. Domae, "MZnet: Mail
+               Service for Personal Micro-Computer Systems",
+               Proceedings, IFIP 6.5 International Conference on
+               Computer Message Systems, Nottingham, U.K., May 1984.
+
+     [RFC821]  Postel, J., "Simple Mail Transfer Protocol",
+               USC/Information Sciences Institute, August 1982.
+
+     [RFC822]  Crocker, D., "Standard for the Format of ARPA-Internet
+               Text Messages", University of Delaware, August 1982.
+
+     [RFC937]  Butler, M., J. Postel, D. Chase, J. Goldberger, and J.
+               Reynolds, "Post Office Protocol - Version 2", RFC 937,
+               USC/Information Sciences Institute, February 1985.
+
+     [RFC1010] Reynolds, J., and J. Postel, "Assigned Numbers", RFC
+               1010, USC/Information Sciences Institute, May 1987.
+
+Author's Address:
+
+
+   Marshall Rose
+   The Wollongong Group
+   1129 San Antonio Rd.
+   Palo Alto, California 94303
+
+   Phone: (415) 962-7100
+
+   Email: MRose@TWG.COM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rose                                                           [Page 16]
diff --git a/src/appl/popper/pop3e.rfc1082 b/src/appl/popper/pop3e.rfc1082
new file mode 100644 (file)
index 0000000..36deae5
--- /dev/null
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group                                            M. Rose
+Request for Comments: 1082                                           TWG
+                                                           November 1988
+
+
+
+                    Post Office Protocol - Version 3
+                       Extended Service Offerings
+
+Status of This Memo
+
+   This memo suggests a simple method for workstations to dynamically
+   access mail from a discussion group server, as an extension to an
+   earlier memo which dealt with dynamically accessing mail from a
+   mailbox server using the Post Office Protocol -  Version 3 (POP3).
+   This RFC specifies a proposed protocol for the Internet community,
+   and requests discussion and suggestions for improvements.  All of the
+   extensions described in this memo to the POP3 are OPTIONAL.
+   Distribution of this memo is unlimited.
+
+Introduction and Motivation
+
+   It is assumed that the reader is familiar with RFC 1081 that
+   discusses the Post Office Protocol - Version 3 (POP3) [RFC1081].
+   This memo describes extensions to the POP3 which enhance the service
+   it offers to clients.  This additional service permits a client host
+   to access discussion group mail, which is often kept in a separate
+   spool area, using the general POP3 facilities.
+
+   The next section describes the evolution of discussion groups and the
+   technologies currently used to implement them.  To summarize:
+
+       o An exploder is used to map from a single address to
+       a list of addresses which subscribe to the list, and redirects
+       any subsequent error reports associated with the delivery of
+       each message.  This has two primary advantages:
+             - Subscribers need know only a single address
+             - Responsible parties get the error reports and not
+               the subscribers
+
+
+
+
+
+
+
+
+
+
+
+
+Rose                                                            [Page 1]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+       o Typically, each subscription address is not a person's private
+       maildrop, but a system-wide maildrop, which can be accessed
+       by more than one user.  This has several advantages:
+             - Only a single copy of each message need traverse the
+               net for a given site (which may contain several local
+               hosts).  This conserves bandwidth and cycles.
+             - Only a single copy of each message need reside on each
+               subscribing host.  This conserves disk space.
+             - The private maildrop for each user is not cluttered
+               with discussion group mail.
+
+   Despite this optimization of resources, further economy can be
+   achieved at sites with more than one host.  Typically, sites with
+   more than one host either:
+
+        1.  Replicate discussion group mail on each host.  This
+        results in literally gigabytes of disk space committed to
+        unnecessarily store redundant information.
+
+        2.  Keep discussion group mail on one host and give all users a
+        login on that host (in addition to any other logins they may
+        have).  This is usually a gross inconvenience for users who
+        work on other hosts, or a burden to users who are forced to
+        work on that host.
+
+   As discussed in [RFC1081], the problem of giving workstations dynamic
+   access to mail from a mailbox server has been explored in great
+   detail (originally there was [RFC918], this prompted the author to
+   write [RFC1081], independently of this [RFC918] was upgraded to
+   [RFC937]).  A natural solution to the problem outlined above is to
+   keep discussion group mail on a mailbox server at each site and
+   permit different hosts at that site to employ the POP3 to access
+   discussion group mail.  If implemented properly, this avoids the
+   problems of both strategies outlined above.
+
+        ASIDE:     It might be noted that a good distributed filesystem
+                   could also solve this problem.  Sadly, "good"
+                   distributed filesystems, which do not suffer
+                   unacceptable response time for interactive use, are
+                   few and far between these days!
+
+   Given this motivation, now let's consider discussion groups, both in
+   general and from the point of view of a user agent.  Following this,
+   extensions to the POP3 defined in [RFC1081] are presented.  Finally,
+   some additional policy details are discussed along with some initial
+   experiences.
+
+
+
+
+
+Rose                                                            [Page 2]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+What's in a Discussion Group
+
+   Since mailers and user agents first crawled out of the primordial
+   ARPAnet, the value of discussion groups have been appreciated,
+   (though their implementation has not always been well-understood).
+
+   Described simply, a discussion group is composed of a number of
+   subscribers with a common interest.  These subscribers post mail to a
+   single address, known as a distribution address.  From this
+   distribution address, a copy of the message is sent to each
+   subscriber.  Each group has a moderator, which is the person that
+   administrates the group.  The moderator can usually be reached at a
+   special address, known as a request address.  Usually, the
+   responsibilities of the moderator are quite simple, since the mail
+   system handles the distribution to subscribers automatically.  In
+   some cases, the interest group, instead of being distributed directly
+   to its subscribers, is put into a digest format by the moderator and
+   then sent to the subscribers.  Although this requires more work on
+   the part of the moderator, such groups tend to be better organized.
+
+   Unfortunately, there are a few problems with the scheme outlined
+   above.  First, if two users on the same host subscribe to the same
+   interest group, two copies of the message get delivered.  This is
+   wasteful of both processor and disk resources.
+
+   Second, some of these groups carry a lot of traffic.  Although
+   subscription to an group does indicate interest on the part of a
+   subscriber, it is usually not interesting to get 50 messages or so
+   delivered to the user's private maildrop each day, interspersed with
+   personal mail, that is likely to be of a much more important and
+   timely nature.
+
+   Third, if a subscriber on the distribution list for a group becomes
+   "bad" somehow, the originator of the message and not the moderator of
+   the group is notified.  It is not uncommon for a large list to have
+   10 or so bogus addresses present.  This results in the originator
+   being flooded with "error messages" from mailers across the Internet
+   stating that a given address on the list was bad.  Needless to say,
+   the originator usually could not care less if the bogus addresses got
+   a copy of the message or not.  The originator is merely interested in
+   posting a message to the group at large.  Furthermore, the moderator
+   of the group does care if there are bogus addresses on the list, but
+   ironically does not receive notification.
+
+   There are various approaches which can be used to solve some or all
+   of these problems.  Usually these involve placing an exploder agent
+   at the distribution source of the discussion group, which expands the
+   name of the group into the list of subscription addresses for the
+
+
+
+Rose                                                            [Page 3]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   group.  In the process, the exploder will also change the address
+   that receives error notifications to be the request address or other
+   responsible party.
+
+   A complementary approach, used in order to cut down on resource
+   utilization of all kinds, replaces all the subscribers at a single
+   host (or group of hosts under a single administration) with a single
+   address at that host.  This address maps to a file on the host,
+   usually in a spool area, which all users can access.  (Advanced
+   implementations can also implement private discussion groups this
+   way, in which a single copy of each message is kept, but is
+   accessible to only a select number of users on the host.)
+
+   The two approaches can be combined to avoid all of the problems
+   described above.
+
+   Finally, a third approach can be taken, which can be used to aid user
+   agents processing mail for the discussion group:  In order to speed
+   querying of the maildrop which contains the local host's copy of the
+   discussion group, two other items are usually associated with the
+   discussion group, on a local basis.  These are the maxima and the
+   last-date.  Each time a message is received for the group on the
+   local host, the maxima is increased by at least one.  Furthermore,
+   when a new maxima is generated, the current date is determined.  This
+   is called the last date.  As the message is entered into the local
+   maildrop, it is given the current maxima and last-date.  This permits
+   the user agent to quickly determine if new messages are present in
+   the maildrop.
+
+       NOTE:      The maxima may be characterized as a monotonically
+                  increasing quanity.  Although sucessive values of the
+                  maxima need not be consecutive, any maxima assigned
+                  is always greater than any previously assigned value.
+
+Definition of Terms
+
+   To formalize these notions somewhat, consider the following 7
+   parameters which describe a given discussion group from the
+   perspective of the user agent (the syntax given is from [RFC822]):
+
+
+
+
+
+
+
+
+
+
+
+
+Rose                                                            [Page 4]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+         NAME            Meaning: the name of the discussion group
+                         Syntax:  TOKEN (ALPHA *[ ALPHA / DIGIT / "-" ])
+                                  (case-insensitive recognition)
+                         Example: unix-wizards
+
+         ALIASES         Meaning: alternates names for the group, which
+                                  are locally meaningful; these are
+                                  typically used to shorten user typein
+                         Syntax:  TOKEN (case-insensitive recognition)
+                         Example: uwiz
+
+         ADDRESS         Meaning: the primary source of the group
+                         Syntax:  822 address
+                         Example: Unix-Wizards@BRL.MIL
+
+         REQUEST         Meaning: the primary moderator of the group
+                         Syntax:  822 address
+                         Example: Unix-Wizards-Request@BRL.MIL
+
+         FLAGS           Meaning: locally meaningful flags associated
+                                  with the discussion group; this memo
+                                  leaves interpretation of this
+                                  parameter to each POP3 implementation
+                         Syntax:  octal number
+                         Example: 01
+
+         MAXIMA          Meaning: the magic cookie associated with the
+                                  last message locally received for the
+                                  group; it is the property of the magic
+                                  cookie that it's value NEVER
+                                  decreases, and increases by at least
+                                  one each time a message is locally
+                                  received
+                         Syntax:  decimal number
+                         Example: 1004
+
+         LASTDATE        Meaning: the date that the last message was
+                                  locally received
+                         Syntax:  822 date
+                         Example: Thu, 19 Dec 85 10:26:48 -0800
+
+   Note that the last two values are locally determined for the maildrop
+   associated with the discussion group and with each message in that
+   maildrop.  Note however that the last message in the maildrop have a
+   different MAXIMA and LASTDATE than the discussion group.  This often
+   occurs when the maildrop has been archived.
+
+
+
+
+
+Rose                                                            [Page 5]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   Finally, some local systems provide mechanisms for automatically
+   archiving discussion group mail.  In some cases, a two-level archive
+   scheme is used:  current mail is kept in the standard maildrop,
+   recent mail is kept in an archive maildrop, and older mail is kept
+   off-line.  With this scheme, in addition to having a "standard"
+   maildrop for each discussion group, an "archive" maildrop may also be
+   available.  This permits a user agent to examine the most recent
+   archive using the same mechanisms as those used on the current mail.
+
+The XTND Command
+
+   The following commands are valid only in the TRANSACTION state of the
+   POP3.  This implies that the POP3 server has already opened the
+   user's maildrop (which may be empty).  This maildrop is called the
+   "default maildrop".  The phrase "closes the current maildrop" has two
+   meanings, depending on whether the current maildrop is the default
+   maildrop or is a maildrop associated with a discussion group.
+
+   In the former context, when the current maildrop is closed any
+   messages marked as deleted are removed from the maildrop currently in
+   use.  The exclusive-access lock on the maildrop is then released
+   along with any implementation-specific resources (e.g., file-
+   descriptors).
+
+   In the latter context, a maildrop associated with a discussion group
+   is considered to be read-only to the POP3 client.  In this case, the
+   phrase "closes the current maildrop" merely means that any
+   implementation-specific resources are released.  (Hence, the POP3
+   command DELE is a no-op.)
+
+   All the new facilities are introduced via a single POP3 command,
+   XTND.  All positive reponses to the XTND command are multi-line.
+
+   The most common multi-line response to the commands contains a
+   "discussion group listing" which presents the name of the discussion
+   group along with it's maxima.  In order to simplify parsing all POP3
+   servers are required to use a certain format for discussion group
+   listings:
+
+                              NAME SP MAXIMA
+
+   This memo makes no requirement on what follows the maxima in the
+   listing.  Minimal implementations should just end that line of the
+   response with a CRLF pair.  More advanced implementations may include
+   other information, as parsed from the message.
+
+       NOTE:      This memo STRONGLY discourages implementations from
+                  supplying additional information in the listing.
+
+
+
+Rose                                                            [Page 6]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   XTND BBOARDS [name]
+   Arguments: the name of a discussion group (optionally)
+   Restrictions: may only be given in the TRANSACTION state.
+   Discussion:
+
+   If an argument was given, the POP3 server closes the current
+   maildrop.  The POP3 server then validates the argument as the name of
+   a discussion group.  If this is successful, it opens the maildrop
+   associated with the group, and returns a multi-line response
+   containing the discussion group listing.  If the discussion group
+   named is not valid, or the associated archive maildrop is not
+   readable by the user, then an error response is returned.
+
+   If no argument was given, the POP3 server issues a multi-line
+   response.  After the initial +OK, for each discussion group known,
+   the POP3 server responds with a line containing the listing for that
+   discussion group.  Note that only world-readable discussion groups
+   are included in the multi-line response.
+
+   In order to aid user agents, this memo requires an extension to the
+   scan listing when an "XTND BBOARDS" command has been given.
+   Normally, a scan listing, as generated by the LIST, takes the form:
+
+          MSGNO SIZE
+
+   where MSGNO is the number of the message being listed and SIZE is the
+   size of the message in octets.  When reading a maildrop accessed via
+   "XTND BBOARDS", the scan listing takes the form
+
+          MSGNO SIZE MAXIMA
+
+   where MAXIMA is the maxima that was assigned to the message when it
+   was placed in the BBoard.
+
+   Possible Responses:
+       +OK XTND
+       -ERR no such bboard
+   Examples:
+       C:    XTND BBOARDS
+       S:    +OK XTND
+       S:    system 10
+       S:    mh-users 100
+       S:    .
+       C:    XTND BBOARDS system
+       S:    + OK XTND
+       S:    system 10
+       S:    .
+
+
+
+
+Rose                                                            [Page 7]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   XTND ARCHIVE name
+   Arguments: the name of a discussion group (required)
+   Restrictions: may only be given in the TRANSACTION state.
+   Discussion:
+
+   The POP3 server closes the current maildrop.  The POP3 server then
+   validates the argument as the name of a discussion group.  If this is
+   successful, it opens the archive maildrop associated with the group,
+   and returns a multi-line response containing the discussion group
+   listing.  If the discussion group named is not valid, or the
+   associated archive maildrop is not readable by the user, then an
+   error response is returned.
+
+   In addition, the scan listing generated by the LIST command is
+   augmented (as described above).
+
+   Possible Responses:
+       +OK XTND
+       -ERR no such bboard Examples:
+       C:    XTND ARCHIVE system
+       S:    + OK XTND
+       S:    system 3
+       S:    .
+
+   XTND X-BBOARDS name
+   Arguments: the name of a discussion group (required)
+   Restrictions: may only be given in the TRANSACTION state.
+   Discussion:
+
+   The POP3 server validates the argument as the name of a
+   discussion group.  If this is unsuccessful, then an error
+   response is returned.  Otherwise a multi-line response is
+   returned.  The first 14 lines of this response (after the
+   initial +OK) are defined in this memo.  Minimal implementations
+   need not include other information (and may omit certain
+   information, outputing a bare CRLF pair).  More advanced
+   implementations may include other information.
+
+           Line    Information (refer to "Definition of Terms")
+           ----    -----------
+             1     NAME
+             2     ALIASES, separated by SP
+             3     system-specific: maildrop
+             4     system-specific: archive maildrop
+             5     system-specific: information
+             6     system-specific: maildrop map
+             7     system-specific: encrypted password
+             8     system-specific: local leaders, separated by SP
+
+
+
+Rose                                                            [Page 8]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+             9     ADDRESS
+            10     REQUEST
+            11     system-specific: incoming feed
+            12     system-specific: outgoing feeds
+            13     FLAGS SP MAXIMA
+            14     LASTDATE
+
+   Most of this information is entirely too specific to the UCI Version
+   of the Rand MH Message Handling System [MRose85].  Nevertheless,
+   lines 1, 2, 9, 10, 13, and 14 are of general interest, regardless of
+   the implementation.
+
+           Possible Responses:
+               +OK XTND
+               -ERR no such bboard
+           Examples:
+               C:    XTND X-BBOARDS system
+               S:    + OK XTND
+               S:    system
+               S:    local general
+               S:    /usr/bboards/system.mbox
+               S:    /usr/bboards/archive/system.mbox
+               S:    /usr/bboards/.system.cnt
+               S:    /usr/bboards/.system.map
+               S:    *
+               S:    mother
+               S:    system@nrtc.northrop.com
+               S:    system-request@nrtc.northrop.com
+               S:
+               S:    dist-system@nrtc-gremlin.northrop.com
+               S:    01 10
+               S:    Thu, 19 Dec 85 00:08:49 -0800
+               S:    .
+
+Policy Notes
+
+   Depending on the particular entity administrating the POP3 service
+   host, two additional policies might be implemented:
+
+   1.  Private Discussion Groups
+
+   In the general case, discussion groups are world-readable, any user,
+   once logged in (via a terminal, terminal server, or POP3, etc.), is
+   able to read the maildrop for each discussion group known to the POP3
+   service host.  Nevertheless, it is desirable, usually for privacy
+   reasons, to implement private discussion groups as well.
+
+   Support of this is consistent with the extensions outlined in this
+
+
+
+Rose                                                            [Page 9]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   memo.  Once the AUTHORIZATION state has successfully concluded, the
+   POP3 server grants the user access to exactly those discussion groups
+   the POP3 service host permits the authenticated user to access.  As a
+   "security" feature, discussion groups associated with unreadable
+   maildrops should not be listed in a positive response to the XTND
+   BBOARDS command.
+
+   2.  Anonymous POP3 Users
+
+   In order to minimize the authentication problem, a policy permitting
+   "anonymous" access to the world-readable maildrops for discussion
+   groups on the POP3 server may be implemented.
+
+   Support of this is consistent with the extensions outlined in this
+   memo.  The POP3 server can be modified to accept a USER command for a
+   well-known pseudonym (i.e., "anonymous") which is valid with any PASS
+   command.  As a "security" feature, it is advisable to limit this kind
+   of access to only hosts at the local site, or to hosts named in an
+   access list.
+
+Experiences and Conclusions
+
+   All of the facilities described in this memo and in [RFC1081] have
+   been implemented in MH #6.1.  Initial experiences have been, on the
+   whole, very positive.
+
+   After the first implementation, some performance tuning was required.
+   This consisted primarily of caching the datastructures which describe
+   discussion groups in the POP3 server.  A second optimization
+   pertained to the client:  the program most commonly used to read
+   BBoards in MH was modified to retrieve messages only when needed.
+   Two schemes are used:
+
+         o If only the headers (and the first few lines of the body) of
+           the message are required (e.g., for a scan listing), then only
+           these are retrieved.  The resulting output is then cached, on
+           a per-message basis.
+
+         o If the entire message is required, then it is retrieved intact,
+            and cached locally.
+
+   With these optimizations, response time is quite adequate when the
+   POP3 server and client are connected via a high-speed local area
+   network.  In fact, the author uses this mechanism to access certain
+   private discussion groups over the Internet.  In this case, response
+   is still good.  When a 9.6Kbps modem is inserted in the path,
+   response went from good to almost tolerable (fortunately the author
+   only reads a few discussion groups in this fashion).
+
+
+
+Rose                                                           [Page 10]
+\f
+RFC 1082                 POP3 Extended Service             November 1988
+
+
+   To conclude: the POP3 is a good thing, not only for personal mail but
+   for discussion group mail as well.
+
+
+References
+
+     [RFC1081] Rose, M., "Post Office Protocol - Verison 3 (POP3)", RFC
+               1081, TWG, November 1988.
+
+     [MRose85] Rose, M., and J. Romine, "The Rand MH Message Handling
+               System: User's Manual", University of California, Irvine,
+               November 1985.
+
+     [RFC822]  Crocker, D., "Standard for the Format of ARPA-Internet
+               Text Messages", RFC 822, University of Delaware, August
+               1982.
+
+     [RFC918]  Reynolds, J., "Post Office Protocol", RFC 918,
+               USC/Information Sciences Institute, October 1984.
+
+     [RFC937]  Butler, M., J. Postel, D. Chase, J. Goldberger, and J.
+               Reynolds, "Post Office Protocol - Version 2", RFC 937,
+               USC/Information Sciences Institute, February 1985.
+
+Author's Address:
+
+
+   Marshall Rose
+   The Wollongong Group
+   1129 San Antonio Rd.
+   Palo Alto, California 94303
+
+   Phone: (415) 962-7100
+
+   Email: MRose@TWG.COM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rose                                                           [Page 11]
+\f
\ No newline at end of file
diff --git a/src/appl/popper/pop_dele.c b/src/appl/popper/pop_dele.c
new file mode 100644 (file)
index 0000000..e148d71
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_dele.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include "popper.h"
+
+/* 
+ *  dele:   Delete a message from the POP maildrop
+ */
+pop_dele (p)
+POP     *   p;
+{
+    MsgInfoList     *   mp;         /*  Pointer to message info list */
+    int                 msg_num;
+
+    /*  Convert the message number parameter to an integer */
+    msg_num = atoi(p->pop_parm[1]);
+
+    /*  Is requested message out of range? */
+    if ((msg_num < 1) || (msg_num > p->msg_count))
+        return (pop_msg (p,POP_FAILURE,"Message %d does not exist.",msg_num));
+
+    /*  Get a pointer to the message in the message list */
+    mp = &(p->mlp[msg_num-1]);
+
+    /*  Is the message already flagged for deletion? */
+    if (mp->del_flag)
+        return (pop_msg (p,POP_FAILURE,"Message %d has already been deleted.",
+            msg_num));
+
+    /*  Flag the message for deletion */
+    mp->del_flag = TRUE;
+
+#ifdef DEBUG
+    if(p->debug)
+        pop_log(p,POP_DEBUG,"Deleting message %u at offset %u of length %u\n",
+            mp->number,mp->offset,mp->length);
+#endif DEBUG
+
+    /*  Update the messages_deleted and bytes_deleted counters */
+    p->msgs_deleted++;
+    p->bytes_deleted += mp->length;
+
+    /*  Update the last-message-accessed number if it is lower than 
+        the deleted message */
+    if (p->last_msg < msg_num) p->last_msg = msg_num;
+
+    return (pop_msg (p,POP_SUCCESS,"Message %d has been deleted.",msg_num));
+}
diff --git a/src/appl/popper/pop_dropcopy.c b/src/appl/popper/pop_dropcopy.c
new file mode 100644 (file)
index 0000000..feaf698
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_dropcopy.c  1.2 7/13/90";
+#endif not lint
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include "popper.h"
+
+extern int      errno;
+extern int      sys_nerr;
+extern char    *sys_errlist[];
+
+#define LOCK_RETRY 3
+#define LOCK_WAIT  5
+
+/* 
+ *  dropcopy:   Make a temporary copy of the user's mail drop and 
+ *  save a stream pointer for it.
+ */
+
+pop_dropcopy(p)
+POP     *   p;
+{
+    int                     mfd;                    /*  File descriptor for 
+                                                        the user's maildrop */
+    int                     dfd;                    /*  File descriptor for 
+                                                        the SERVER maildrop */
+    char                    buffer[BUFSIZ];         /*  Read buffer */
+    long                    offset;                 /*  Old/New boundary */
+    int                     nchar;                  /*  Bytes written/read */
+    int                     locked;                 /*  if drop is loced */
+    int                     retry = 0;              /*  times to retry lock */
+
+    /*  Create a temporary maildrop into which to copy the updated maildrop */
+    (void)sprintf(p->temp_drop,POP_DROP,p->user);
+
+#ifdef DEBUG
+    if(p->debug)
+        pop_log(p,POP_DEBUG,"Creating temporary maildrop '%s'",
+            p->temp_drop);
+#endif DEBUG
+
+    /* Open for append,  this solves the crash recovery problem */
+    if ((dfd = open(p->temp_drop,O_RDWR|O_APPEND|O_CREAT,0666)) == -1){
+        pop_log(p,POP_ERROR,
+            "%s: (%s) unable to create temporary maildrop: %s",
+               p->client, p->temp_drop,
+                (errno < sys_nerr) ? sys_errlist[errno] : "") ;
+        return (POP_FAILURE);
+    }
+
+    /*  Lock the temporary maildrop. Try a few times if it doesn't succeed. */
+    
+    locked = 1;
+    while(locked) {
+        if ( flock (dfd, LOCK_EX|LOCK_NB) == -1 )            
+           switch(errno) {
+           case EWOULDBLOCK:
+             if(retry++ < LOCK_RETRY)  {
+                 sleep(LOCK_WAIT);
+                 continue;
+             }
+             pop_log(p, POP_PRIORITY, "%s: (%s) maildrop locked", 
+                     p->client, p->temp_drop);
+             return pop_msg(p,POP_FAILURE,
+                "Maildrop for %s is busy. Please try again in a few moments.",
+                            p->user);
+             /* NOTREACHED */
+
+           default:
+             pop_log(p, POP_PRIORITY, "%s: (%s) flock: %s", p->client, 
+                     p->temp_drop,
+                     (errno < sys_nerr) ? sys_errlist[errno] : "");
+             return pop_msg(p,POP_FAILURE,"flock: '%s': %s", p->temp_drop,
+                            (errno < sys_nerr) ? sys_errlist[errno] : "");
+             /* NOTREACHED */
+           }
+       else
+         locked = 0;
+    }
+
+    /* May have grown or shrunk between open and lock! */
+    offset = lseek(dfd,0,L_XTND);
+
+    /*  Open the user's maildrop, If this fails,  no harm in assuming empty */
+    if ((mfd = open(p->drop_name,O_RDWR)) > 0) {
+
+        /*  Lock the maildrop */
+        if (flock (mfd,LOCK_EX) == -1) {
+            (void)close(mfd) ;
+           pop_log(p, POP_PRIORITY, "%s: (%s) flock: %s", p->client, 
+                   p->drop_name,(errno < sys_nerr) ? sys_errlist[errno] : "");
+            return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
+                (errno < sys_nerr) ? sys_errlist[errno] : "");
+        }
+
+        /*  Copy the actual mail drop into the temporary mail drop */
+        while ( (nchar=read(mfd,buffer,BUFSIZ)) > 0 )
+            if ( nchar != write(dfd,buffer,nchar) ) {
+                nchar = -1 ;
+                break ;
+            }
+
+        if ( nchar != 0 ) {
+            /* Error adding new mail.  Truncate to original size,
+               and leave the maildrop as is.  The user will not 
+               see the new mail until the error goes away.
+               Should let them process the current backlog,  in case
+               the error is a quota problem requiring deletions! */
+            (void)ftruncate(dfd,(int)offset) ;
+        } else {
+            /* Mail transferred!  Zero the mail drop NOW,  that we
+               do not have to do gymnastics to figure out what's new
+              and what is old later */
+            (void)ftruncate(mfd,0) ;
+        }
+
+        /*  Close the actual mail drop */
+        (void)close (mfd);
+    }
+
+    /*  Acquire a stream pointer for the temporary maildrop */
+    if ( (p->drop = fdopen(dfd,"a+")) == NULL ) {
+        (void)close(dfd) ;
+       pop_log(p, POP_PRIORITY, "%s: (%s) fdopen: %s", p->client, 
+               p->temp_drop, (errno < sys_nerr) ? sys_errlist[errno] : "");
+        return pop_msg(p,POP_FAILURE,"Cannot assign stream for %s",
+            p->temp_drop);
+    }
+
+    rewind (p->drop);
+
+#ifdef DEBUG
+    if (!p->debug)
+        unlink (p->temp_drop);
+#endif DEBUG
+
+    return(POP_SUCCESS);
+}
diff --git a/src/appl/popper/pop_dropinfo.c b/src/appl/popper/pop_dropinfo.c
new file mode 100644 (file)
index 0000000..0210820
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * compatibility with mail files stored with mh (tom)
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_dropinfo.c  1.4 8/16/90";
+#endif not lint
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include "popper.h"
+
+extern int      errno;
+extern int      sys_nerr;
+extern char    *sys_errlist[];
+
+/* 
+ *  dropinfo:   Extract information about the POP maildrop and store 
+ *  it for use by the other POP routines.
+ */
+
+pop_dropinfo(p)
+POP     *   p;
+{
+    char                    buffer[BUFSIZ];         /*  Read buffer */
+    MsgInfoList         *   mp;                     /*  Pointer to message 
+                                                        info list */
+    register int            msg_num;                /*  Current message 
+                                                        counter */
+    int                     nchar;                  /*  Bytes written/read */
+    int                     end;                    /*  eom */
+
+    /*  Initialize maildrop status variables in the POP parameter block */
+    p->msg_count = 0;
+    p->msgs_deleted = 0;
+    p->last_msg = 0;
+    p->bytes_deleted = 0;
+    p->drop_size = 0;
+    end = 1;
+
+    /*  Allocate memory for message information structures */
+    p->msg_count = ALLOC_MSGS;
+    p->mlp = (MsgInfoList *)calloc((unsigned)p->msg_count,sizeof(MsgInfoList));
+    if (p->mlp == NULL){
+        (void)fclose (p->drop);
+        p->msg_count = 0;
+       pop_log(p, POP_ERROR, "%s: (%s) no memory.", p->client, p->user);
+        return pop_msg (p,POP_FAILURE,
+            "Can't build message list for '%s': Out of memory", p->user);
+    }
+
+    rewind (p->drop);
+
+    /*  Scan the file, loading the message information list with 
+        information about each message */
+
+    for (msg_num = p->drop_size = 0, mp = p->mlp - 1;
+             fgets(buffer,MAXMSGLINELEN,p->drop);) {
+
+        nchar  = strlen(buffer);
+       if((strncmp(buffer,"\001\001\001\001",4) == 0) && (end == 0)) {
+           end = 1;
+           continue;
+       }
+       
+        if (is_msg_boundary(buffer)) {
+           end = 0;
+            if (++msg_num > p->msg_count) {
+                p->mlp=(MsgInfoList *) realloc(p->mlp,
+                    (p->msg_count+=ALLOC_MSGS)*sizeof(MsgInfoList));
+                if (p->mlp == NULL){
+                    (void)fclose (p->drop);
+                    p->msg_count = 0;
+                   pop_log(p, POP_ERROR, "%s: (%s) no memory.", 
+                           p->client, p->user);
+                    return pop_msg (p,POP_FAILURE,
+                        "Can't build message list for '%s': Out of memory",
+                            p->user);
+                }
+                mp = p->mlp + msg_num - 2;
+            }
+#ifdef DEBUG
+            if(p->debug)
+                pop_log(p,POP_DEBUG,
+                    "Msg %d at offset %d is %d octets long and has %u lines.",
+                        mp->number,mp->offset,mp->length,mp->lines);
+#endif DEBUG
+            ++mp;
+            mp->number = msg_num;
+            mp->length = 0;
+            mp->lines = 0;
+            mp->offset = ftell(p->drop) - nchar;
+            mp->del_flag = FALSE;
+            mp->retr_flag = FALSE;
+#ifdef DEBUG
+            if(p->debug)
+                pop_log(p,POP_DEBUG, "Msg %d being added to list", mp->number);
+#endif DEBUG
+       }
+        mp->length += nchar;
+        p->drop_size += nchar;
+        mp->lines++;
+    }
+    p->msg_count = msg_num;
+
+#ifdef DEBUG
+    if(p->debug && msg_num > 0) {
+        register    i;
+        for (i = 0, mp = p->mlp; i < p->msg_count; i++, mp++)
+            pop_log(p,POP_DEBUG,
+                "Msg %d at offset %d is %d octets long and has %u lines.",
+                    mp->number,mp->offset,mp->length,mp->lines);
+    }
+#endif DEBUG
+
+    return(POP_SUCCESS);
+}
+
+
diff --git a/src/appl/popper/pop_get_command.c b/src/appl/popper/pop_get_command.c
new file mode 100644 (file)
index 0000000..fe5d22e
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_get_command.c   1.9 8/16/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "popper.h"
+
+/* 
+ *  get_command:    Extract the command from an input line form a POP client
+ */
+
+static state_table states[] = {
+        auth1,  "user", 1,  1,  pop_user,   {auth1, auth2},
+        auth2,  "pass", 1,  1,  pop_pass,   {auth1, trans},
+#ifdef RPOP
+        auth2,  "rpop", 1,  1,  pop_rpop,   {auth1, trans},
+#endif RPOP
+        auth1,  "quit", 0,  0,  pop_quit,   {halt,  halt},
+        auth2,  "quit", 0,  0,  pop_quit,   {halt,  halt},
+        trans,  "stat", 0,  0,  pop_stat,   {trans, trans},
+        trans,  "list", 0,  1,  pop_list,   {trans, trans},
+        trans,  "retr", 1,  1,  pop_send,   {trans, trans},
+        trans,  "dele", 1,  1,  pop_dele,   {trans, trans},
+        trans,  "noop", 0,  0,  NULL,       {trans, trans},
+        trans,  "rset", 0,  0,  pop_rset,   {trans, trans},
+        trans,  "top",  2,  2,  pop_send,   {trans, trans},
+        trans,  "last", 0,  0,  pop_last,   {trans, trans},
+        trans,  "xtnd", 1,  99, pop_xtnd,   {trans, trans},
+        trans,  "quit", 0,  0,  pop_updt,   {halt,  halt},
+        (state) 0,  NULL,   0,  0,  NULL,       {halt,  halt},
+};
+
+state_table *pop_get_command(p,mp)
+POP             *   p;
+register char   *   mp;         /*  Pointer to unparsed line 
+                                    received from the client */
+{
+    state_table     *   s;
+    char                buf[MAXMSGLINELEN];
+
+    /*  Save a copy of the original client line */
+#ifdef DEBUG
+    if(p->debug) strcpy (buf,mp);
+#endif DEBUG
+
+    /*  Parse the message into the parameter array */
+    if ((p->parm_count = pop_parse(p,mp)) < 0) return(NULL);
+
+    /*  Do not log cleartext passwords */
+#ifdef DEBUG
+    if(p->debug){
+        if(strcmp(p->pop_command,"pass") == 0)
+            pop_log(p,POP_DEBUG,"Received: \"%s xxxxxxxxx\"",p->pop_command);
+        else {
+            /*  Remove trailing <LF> */
+            buf[strlen(buf)-2] = '\0';
+            pop_log(p,POP_DEBUG,"Received: \"%s\"",buf);
+        }
+    }
+#endif DEBUG
+
+    /*  Search for the POP command in the command/state table */
+    for (s = states; s->command; s++) {
+
+        /*  Is this a valid command for the current operating state? */
+        if (strcmp(s->command,p->pop_command) == 0
+             && s->ValidCurrentState == p->CurrentState) {
+
+            /*  Were too few parameters passed to the command? */
+            if (p->parm_count < s->min_parms)
+                return((state_table *)pop_msg(p,POP_FAILURE,
+                    "Too few arguments for the %s command.",p->pop_command));
+
+            /*  Were too many parameters passed to the command? */
+            if (p->parm_count > s->max_parms)
+                return((state_table *)pop_msg(p,POP_FAILURE,
+                    "Too many arguments for the %s command.",p->pop_command));
+
+            /*  Return a pointer to the entry for this command in 
+                the command/state table */
+            return (s);
+        }
+    }
+    /*  The client command was not located in the command/state table */
+    return((state_table *)pop_msg(p,POP_FAILURE,
+        "Unknown command: \"%s\".",p->pop_command));
+}
diff --git a/src/appl/popper/pop_get_subcommand.c b/src/appl/popper/pop_get_subcommand.c
new file mode 100644 (file)
index 0000000..c77af80
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_get_subcommand.c    1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "popper.h"
+
+/* 
+ *  get_subcommand: Extract a POP XTND subcommand from a client input line
+ */
+
+static xtnd_table subcommands[] = {
+        "xmit",     0,  0,  pop_xmit,
+        NULL
+};
+
+xtnd_table *pop_get_subcommand(p)
+POP     *   p;
+{
+    xtnd_table      *   s;
+
+    /*  Search for the POP command in the command/state table */
+    for (s = subcommands; s->subcommand; s++) {
+
+        if (strcmp(s->subcommand,p->pop_subcommand) == 0) {
+
+            /*  Were too few parameters passed to the subcommand? */
+            if ((p->parm_count-1) < s->min_parms)
+                return((xtnd_table *)pop_msg(p,POP_FAILURE,
+                    "Too few arguments for the %s %s command.",
+                        p->pop_command,p->pop_subcommand));
+
+            /*  Were too many parameters passed to the subcommand? */
+            if ((p->parm_count-1) > s->max_parms)
+                return((xtnd_table *)pop_msg(p,POP_FAILURE,
+                    "Too many arguments for the %s %s command.",
+                        p->pop_command,p->pop_subcommand));
+
+            /*  Return a pointer to the entry for this subcommand 
+                in the XTND command table */
+            return (s);
+        }
+    }
+    /*  The client subcommand was not located in the XTND command table */
+    return((xtnd_table *)pop_msg(p,POP_FAILURE,
+        "Unknown command: \"%s %s\".",p->pop_command,p->pop_subcommand));
+}
diff --git a/src/appl/popper/pop_last.c b/src/appl/popper/pop_last.c
new file mode 100644 (file)
index 0000000..6298b76
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_last.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  last:   Display the last message touched in a POP session
+ */
+
+int pop_last (p)
+POP     *   p;
+{
+    return (pop_msg(p,POP_SUCCESS,"%u is the last message seen.",p->last_msg));
+}
diff --git a/src/appl/popper/pop_list.c b/src/appl/popper/pop_list.c
new file mode 100644 (file)
index 0000000..a79f5d1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_list.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  list:   List the contents of a POP maildrop
+ */
+
+int pop_list (p)
+POP     *   p;
+{
+    MsgInfoList         *   mp;         /*  Pointer to message info list */
+    register int            i;
+    register int            msg_num;
+
+    /*  Was a message number provided? */
+    if (p->parm_count > 0) {
+        msg_num = atoi(p->pop_parm[1]);
+
+        /*  Is requested message out of range? */
+        if ((msg_num < 1) || (msg_num > p->msg_count))
+            return (pop_msg (p,POP_FAILURE,
+                "Message %d does not exist.",msg_num));
+
+        /*  Get a pointer to the message in the message list */
+        mp = &p->mlp[msg_num-1];
+
+        /*  Is the message already flagged for deletion? */
+        if (mp->del_flag)
+            return (pop_msg (p,POP_FAILURE,
+                "Message %d has been deleted.",msg_num));
+
+        /*  Display message information */
+        return (pop_msg(p,POP_SUCCESS,"%u %u",msg_num,mp->length));
+    }
+    
+    /*  Display the entire list of messages */
+    pop_msg(p,POP_SUCCESS,
+        "%u messages (%u octets)",
+            p->msg_count-p->msgs_deleted,p->drop_size-p->bytes_deleted);
+
+    /*  Loop through the message information list.  Skip deleted messages */
+    for (i = p->msg_count, mp = p->mlp; i > 0; i--, mp++) {
+        if (!mp->del_flag) 
+            (void)fprintf(p->output,"%u %u\r\n",mp->number,mp->length);
+    }
+
+    /*  "." signals the end of a multi-line transmission */
+    (void)fprintf(p->output,".\r\n");
+    (void)fflush(p->output);
+
+    return(POP_SUCCESS);
+}
diff --git a/src/appl/popper/pop_log.c b/src/appl/popper/pop_log.c
new file mode 100644 (file)
index 0000000..a647161
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_log.c   1.7 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <varargs.h>
+#include "popper.h"
+
+/* 
+ *  log:    Make a log entry
+ */
+
+static char msgbuf[MAXLINELEN];
+
+pop_log(va_alist)
+va_dcl
+{
+    va_list     ap;
+    POP     *   p;
+    int         stat;
+    char    *   format;
+
+    va_start(ap);
+    p = va_arg(ap,POP *);
+    stat = va_arg(ap,int);
+    format = va_arg(ap,char *);
+    va_end(ap);
+
+#ifdef HAVE_VSPRINTF
+        vsprintf(msgbuf,format,ap);
+#else
+        (void)sprintf (msgbuf,format,((int *)ap)[0],((int *)ap)[1],((int *)ap)[2],
+                ((int *)ap)[3],((int *)ap)[4],((int *)ap)[5]);
+#endif HAVE_VSPRINTF
+
+    if (p->debug && p->trace) {
+        (void)fprintf(p->trace,"%s\n",msgbuf);
+        (void)fflush(p->trace);
+    }
+    else {
+        syslog (stat,"%s",msgbuf);
+    }
+
+    return(stat);
+}
diff --git a/src/appl/popper/pop_lower.c b/src/appl/popper/pop_lower.c
new file mode 100644 (file)
index 0000000..45fb4e4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_lower.c 1.6 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <ctype.h>
+
+/* 
+ *  lower:  Convert a string to lowercase
+ */
+
+pop_lower (buf)
+char        *   buf;
+{
+    char        *   mp;
+
+    for (mp = buf; *mp; mp++)
+        if (isupper(*mp) && isupper(*mp)) *mp = (char)tolower((int)*mp);
+}
diff --git a/src/appl/popper/pop_msg.c b/src/appl/popper/pop_msg.c
new file mode 100644 (file)
index 0000000..366c515
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_msg.c   1.7 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <varargs.h>
+#include "popper.h"
+
+/* 
+ *  msg:    Send a formatted line to the POP client
+ */
+
+pop_msg(va_alist)
+va_dcl
+{
+    POP             *   p;
+    int                 stat;               /*  POP status indicator */
+    char            *   format;             /*  Format string for the message */
+    va_list             ap;
+    register char   *   mp;
+    char                message[MAXLINELEN];
+
+    va_start(ap);
+    p = va_arg(ap, POP *);
+    stat = va_arg(ap, int);
+    format = va_arg(ap, char *);
+    va_end(ap);
+
+    /*  Point to the message buffer */
+    mp = message;
+
+    /*  Format the POP status code at the beginning of the message */
+    if (stat == POP_SUCCESS)
+        (void)sprintf (mp,"%s ",POP_OK);
+    else
+        (void)sprintf (mp,"%s ",POP_ERR);
+
+    /*  Point past the POP status indicator in the message message */
+    mp += strlen(mp);
+
+    /*  Append the message (formatted, if necessary) */
+    if (format) 
+#ifdef HAVE_VSPRINTF
+        vsprintf(mp,format,ap);
+#else
+        (void)sprintf(mp,format,((int *)ap)[0],((int *)ap)[1],((int *)ap)[2],
+                ((int *)ap)[3],((int *)ap)[4]);
+#endif HAVE_VSPRINTF
+    
+    /*  Log the message if debugging is turned on */
+#ifdef DEBUG
+    if (p->debug && stat == POP_SUCCESS)
+        pop_log(p,POP_DEBUG,"%s",message);
+#endif DEBUG
+
+    /*  Append the <CR><LF> */
+    (void)strcat(message, "\r\n");
+        
+    /*  Send the message to the client */
+    (void)fputs(message,p->output);
+    (void)fflush(p->output);
+
+    return(stat);
+}
diff --git a/src/appl/popper/pop_parse.c b/src/appl/popper/pop_parse.c
new file mode 100644 (file)
index 0000000..05b42a4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_parse.c 1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include "popper.h"
+
+/* 
+ *  parse:  Parse a raw input line from a POP client 
+ *  into null-delimited tokens
+ */
+
+pop_parse(p,buf)
+POP         *   p;
+char        *   buf;        /*  Pointer to a message containing 
+                                the line from the client */
+{
+    char            *   mp;
+    register int        i;
+    
+    /*  Loop through the POP command array */
+    for (mp = buf, i = 0; ; i++) {
+    
+        /*  Skip leading spaces and tabs in the message */
+        while (isspace(*mp))mp++;
+
+        /*  Are we at the end of the message? */
+        if (*mp == 0) break;
+
+        /*  Have we already obtained the maximum allowable parameters? */
+        if (i >= MAXPARMCOUNT) {
+            pop_msg(p,POP_FAILURE,"Too many arguments supplied.");
+            return(-1);
+        }
+
+        /*  Point to the start of the token */
+        p->pop_parm[i] = mp;
+
+        /*  Search for the first space character (end of the token) */
+        while (!isspace(*mp) && *mp) mp++;
+
+        /*  Delimit the token with a null */
+        if (*mp) *mp++ = 0;
+    }
+
+    /*  Were any parameters passed at all? */
+    if (i == 0) return (-1);
+
+    /*  Convert the first token (POP command) to lower case */
+    pop_lower(p->pop_command);
+
+    /*  Return the number of tokens extracted minus the command itself */
+    return (i-1);
+    
+}
diff --git a/src/appl/popper/pop_quit.c b/src/appl/popper/pop_quit.c
new file mode 100644 (file)
index 0000000..2cfe901
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_quit.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  quit:   Terminate a POP session
+ */
+
+int pop_quit (p)
+POP     *   p;
+{
+    /*  Release the message information list */
+    if (p->mlp) free ((char *)p->mlp);
+
+    return(POP_SUCCESS);
+}
diff --git a/src/appl/popper/pop_rset.c b/src/appl/popper/pop_rset.c
new file mode 100644 (file)
index 0000000..2c97527
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_rset.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  rset:   Unflag all messages flagged for deletion in a POP maildrop
+ */
+
+int pop_rset (p)
+POP     *   p;
+{
+    MsgInfoList     *   mp;         /*  Pointer to the message info list */
+    register int        i;
+
+    /*  Unmark all the messages */
+    for (i = p->msg_count, mp = p->mlp; i > 0; i--, mp++)
+        mp->del_flag = FALSE; 
+    
+    /*  Reset the messages-deleted and bytes-deleted counters */
+    p->msgs_deleted = 0;
+    p->bytes_deleted = 0;
+    
+    /*  Reset the last-message-access flag */
+    p->last_msg = 0;
+
+    return (pop_msg(p,POP_SUCCESS,"Maildrop has %u messages (%u octets)",
+        p->msg_count,p->drop_size));
+}
diff --git a/src/appl/popper/pop_send.c b/src/appl/popper/pop_send.c
new file mode 100644 (file)
index 0000000..2de7ffa
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * mh compatibility (tom)
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_send.c  1.7 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "popper.h"
+
+/* 
+ *  send:   Send the header and a specified number of lines 
+ *          from a mail message to a POP client.
+ */
+
+pop_send(p)
+POP     *   p;
+{
+    MsgInfoList         *   mp;         /*  Pointer to message info list */
+    register int            msg_num;
+    register int            msg_lines;
+    char                    buffer[MAXMSGLINELEN];
+
+    /*  Convert the first parameter into an integer */
+    msg_num = atoi(p->pop_parm[1]);
+
+    /*  Is requested message out of range? */
+    if ((msg_num < 1) || (msg_num > p->msg_count))
+        return (pop_msg (p,POP_FAILURE,"Message %d does not exist.",msg_num));
+
+    /*  Get a pointer to the message in the message list */
+    mp = &p->mlp[msg_num-1];
+
+    /*  Is the message flagged for deletion? */
+    if (mp->del_flag)
+        return (pop_msg (p,POP_FAILURE,
+            "Message %d has been deleted.",msg_num));
+
+    /*  If this is a TOP command, get the number of lines to send */
+    if (strcmp(p->pop_command,"top") == 0) {
+        /*  Convert the second parameter into an integer */
+        msg_lines = atoi(p->pop_parm[2]);
+    }
+    else {
+        /*  Assume that a RETR (retrieve) command was issued */
+        msg_lines = -1;
+        /*  Flag the message as retreived */
+        mp->retr_flag = TRUE;
+    }
+    
+    /*  Display the number of bytes in the message */
+    pop_msg(p,POP_SUCCESS,"%u octets",mp->length);
+
+    /*  Position to the start of the message */
+    (void)fseek(p->drop,mp->offset,0);
+
+    /*  Skip the first line (the sendmail "From" line) */
+    (void)fgets (buffer,MAXMSGLINELEN,p->drop);
+
+    /*  Send the header of the message followed by a blank line */
+    while (fgets(buffer,MAXMSGLINELEN,p->drop)) {
+        pop_sendline (p,buffer);
+        /*  A single newline (blank line) signals the 
+            end of the header.  sendline() converts this to a NULL, 
+            so that's what we look for. */
+        if (*buffer == 0) break;
+    }
+    /*  Send the message body */
+    while (fgets(buffer,MAXMSGLINELEN,p->drop)) {
+        /*  Look for the start of the next message */
+        if (is_msg_boundary(buffer)) break;
+        /*  Decrement the lines sent (for a TOP command) */
+        if (msg_lines >= 0 && msg_lines-- == 0) break;
+        pop_sendline(p,buffer);
+    }
+    /*  "." signals the end of a multi-line transmission */
+    (void)fputs(".\r\n",p->output);
+    (void)fflush(p->output);
+
+    return(POP_SUCCESS);
+}
+
+/*
+ *  sendline:   Send a line of a multi-line response to a client.
+ */
+pop_sendline(p,buffer)
+POP         *   p;
+char        *   buffer;
+{
+    char        *   bp;
+
+    /*  Byte stuff lines that begin with the temirnation octet */
+    if (*buffer == POP_TERMINATE) (void)fputc(POP_TERMINATE,p->output);
+
+    /*  Look for a <NL> in the buffer */
+    if (bp = index(buffer,NEWLINE)) *bp = 0;
+
+    /*  Send the line to the client */
+    (void)fputs(buffer,p->output);
+
+#ifdef DEBUG
+    if(p->debug)pop_log(p,POP_DEBUG,"Sending line \"%s\"",buffer);
+#endif DEBUG
+
+    /*  Put a <CR><NL> if a newline was removed from the buffer */
+    if (bp) (void)fputs ("\r\n",p->output);
+}
diff --git a/src/appl/popper/pop_stat.c b/src/appl/popper/pop_stat.c
new file mode 100644 (file)
index 0000000..20f9442
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_stat.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  stat:   Display the status of a POP maildrop to its client
+ */
+
+int pop_stat (p)
+POP     *   p;
+{
+    return (pop_msg (p,POP_SUCCESS,
+        "%u %u",p->msg_count-p->msgs_deleted,p->drop_size-p->bytes_deleted));
+}
diff --git a/src/appl/popper/pop_updt.c b/src/appl/popper/pop_updt.c
new file mode 100644 (file)
index 0000000..ebedb0f
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * code for mh compatibility (tom) 
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_updt.c  1.9 8/16/90";
+#endif not lint
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include "popper.h"
+
+extern int      errno;
+
+static char standard_error[] =
+    "Error updating primary drop. Mailbox unchanged.";
+
+/* 
+ *  updt:   Apply changes to a user's POP maildrop
+ */
+
+int pop_updt (p)
+POP     *   p;
+{
+    FILE                *   md;                     /*  Stream pointer for 
+                                                        the user's maildrop */
+    int                     mfd;                    /*  File descriptor for
+                                                        above */
+    char                    buffer[BUFSIZ];         /*  Read buffer */
+
+    MsgInfoList         *   mp;                     /*  Pointer to message 
+                                                        info list */
+    register int            msg_num;                /*  Current message 
+                                                        counter */
+    register int            status_written;         /*  Status header field 
+                                                        written */
+    int                     nchar;                  /*  Bytes read/written */
+
+    long                    offset;                 /*  New mail offset */
+    
+    int                     begun;                  /*  Sanity check */
+
+#ifdef DEBUG
+    if (p->debug) {
+        pop_log(p,POP_DEBUG,"Performing maildrop update...");
+        pop_log(p,POP_DEBUG,"Checking to see if all messages were deleted");
+    }
+#endif DEBUG
+
+    if (p->msgs_deleted == p->msg_count) {
+        /* Truncate before close, to avoid race condition,  DO NOT UNLINK!
+           Another process may have opened,  and not yet tried to lock */
+        (void)ftruncate ((int)fileno(p->drop),0);
+        (void)fclose(p->drop) ;
+        return (POP_SUCCESS);
+    }
+
+#ifdef DEBUG
+    if (p->debug) 
+        pop_log(p,POP_DEBUG,"Opening mail drop \"%s\"",p->drop_name);
+#endif DEBUG
+
+    /*  Open the user's real maildrop */
+    if (((mfd = open(p->drop_name,O_RDWR|O_CREAT,0666)) == -1 ) ||
+        ((md = fdopen(mfd,"r+")) == NULL)) {
+        return pop_msg(p,POP_FAILURE,"%s %s", 
+                      p->drop_name, sys_errlist[errno]);
+    }
+
+    /*  Lock the user's real mail drop */
+    if ( flock(mfd,LOCK_EX) == -1 ) {
+        (void)fclose(md) ;
+        return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
+            (errno < sys_nerr) ? sys_errlist[errno] : "");
+    }
+
+    /* Go to the right places */
+    offset = lseek((int)fileno(p->drop),0,L_XTND) ; 
+
+    /*  Append any messages that may have arrived during the session 
+        to the temporary maildrop */
+    while ((nchar=read(mfd,buffer,BUFSIZ)) > 0)
+        if ( nchar != write((int)fileno(p->drop),buffer,nchar) ) {
+            nchar = -1;
+            break ;
+        }
+    if ( nchar != 0 ) {
+        (void)fclose(md) ;
+        (void)ftruncate((int)fileno(p->drop),(int)offset) ;
+        (void)fclose(p->drop) ;
+        return pop_msg(p,POP_FAILURE,standard_error);
+    }
+
+    rewind(md);
+    (void)ftruncate(mfd,0) ;
+
+    /* Synch stdio and the kernel for the POP drop */
+    rewind(p->drop);
+    (void)lseek((int)fileno(p->drop),0,L_SET);
+
+    /*  Transfer messages not flagged for deletion from the temporary 
+        maildrop to the new maildrop */
+#ifdef DEBUG
+    if (p->debug) 
+        pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"",
+                p->drop_name,p->temp_drop);
+#endif DEBUG
+    
+    for (msg_num = 0; msg_num < p->msg_count; ++msg_num) {
+
+        int doing_body;
+      
+        /*  Get a pointer to the message information list */
+        mp = &p->mlp[msg_num];
+
+        if (mp->del_flag) {
+#ifdef DEBUG
+            if(p->debug)
+                pop_log(p,POP_DEBUG,
+                    "Message %d flagged for deletion.",mp->number);
+#endif DEBUG
+            continue;
+        }
+       
+        (void)fseek(p->drop,mp->offset,0);
+
+#ifdef DEBUG
+        if(p->debug)
+            pop_log(p,POP_DEBUG,"Copying message %d.",mp->number);
+#endif DEBUG
+
+       begun = 0;
+
+        for(status_written = doing_body = 0 ;
+            fgets(buffer,MAXMSGLINELEN,p->drop);) {
+
+            if (doing_body == 0) { /* Header */
+
+               /* panic, I'm tired and can't think contorted. */
+               if(is_msg_boundary(buffer) && begun) {  
+                 pop_log(p, POP_ERROR,
+                         "%s: mailbox detonation has begun!",  p->user);
+                 (void)ftruncate(mfd,0);
+                 (void)fclose(md);
+                 (void)fclose(p->drop);
+                 return(pop_msg(p, POP_FAILURE, "Unable to close mailbox door. Contact the postmaster to repair it."));
+               }
+
+               begun = 1;
+
+                /*  Update the message status */
+                if (strncasecmp(buffer,"Status:",7) == 0) {
+                    if (mp->retr_flag)
+                        (void)fputs("Status: RO\n",md);
+                    else
+                        (void)fputs(buffer, md);
+                    status_written++;
+                    continue;
+                }
+                /*  A blank line signals the end of the header. */
+                if (*buffer == '\n') {
+                    doing_body = 1;
+
+#ifndef NOSTATUS
+                    if (status_written == 0) {
+                        if (mp->retr_flag)
+                            (void)fputs("Status: RO\n\n",md);
+                        else
+                            (void)fputs("Status: U\n\n",md);
+                    }
+                   else
+#endif /* NOSTATUS */
+                    (void)fputs ("\n", md);
+                    continue;
+                }
+                /*  Save another header line */
+                (void)fputs (buffer, md);
+           }
+           else { /* Body */ 
+               if (strncmp(buffer,"\001\001\001\001",4) == 0) {
+                   (void)fputs (buffer, md);
+                   break;
+               }
+               if(is_msg_boundary(buffer))
+                 break;
+                (void)fputs (buffer, md);
+           }
+       }
+    }
+
+    /* flush and check for errors now!  The new mail will writen
+       without stdio,  since we need not separate messages */
+
+    (void)fflush(md) ;
+    if (ferror(md)) {
+        (void)ftruncate(mfd,0) ;
+        (void)fclose(md) ;
+        (void)fclose(p->drop) ;
+        return pop_msg(p,POP_FAILURE,standard_error);
+    }
+
+    /* Go to start of new mail if any */
+    (void)lseek((int)fileno(p->drop),offset,L_SET);
+
+    while((nchar=read((int)fileno(p->drop),buffer,BUFSIZ)) > 0)
+        if ( nchar != write(mfd,buffer,nchar) ) {
+            nchar = -1;
+            break ;
+        }
+    if ( nchar != 0 ) {
+        (void)ftruncate(mfd,0) ;
+        (void)fclose(md) ;
+        (void)fclose(p->drop) ;
+        return pop_msg(p,POP_FAILURE,standard_error);
+    }
+
+    /*  Close the maildrop and empty temporary maildrop */
+    (void)fclose(md);
+    (void)ftruncate((int)fileno(p->drop),0);
+    (void)fclose(p->drop);
+
+    return(pop_quit(p));
+}
+
+
+
+
+is_msg_boundary(line)
+     char *line;
+{
+  if(strncmp(line, "\001\001\001\001", 4) == 0) 
+    return(1);
+  
+  if(strncmp(line, "From ", 5) != 0) 
+    return(0);
+  
+  line += 5;
+  while((*line != ' ') && (*line != '\0'))
+    ++line;
+
+  if(*line++ != ' ')
+    return(0);
+  
+  if(strlen(line) < 28)
+    return(0);
+
+  /* Tue */
+  line += 3;
+  if(*line++ != ' ')
+    return(0);
+
+  /* Jan */
+  line += 3;
+  if(*line++ != ' ')
+    return(0);
+  
+  /* 22 */  
+  line += 2;
+  if(*line++ != ' ')
+    return(0);
+
+  /* 18:21:34 */
+  line += 2;
+  if(*line++ != ':')
+    return(0);
+
+  line += 2;
+  if(*line++ != ':')
+    return(0);
+
+  line += 2;
+  if(*line++ != ' ')
+    return(0);
+
+  return(1);
+}
+
diff --git a/src/appl/popper/pop_user.c b/src/appl/popper/pop_user.c
new file mode 100644 (file)
index 0000000..dee41ed
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_user.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "popper.h"
+
+/* 
+ *  user:   Prompt for the user name at the start of a POP session
+ */
+
+int pop_user (p)
+POP     *   p;
+{
+#ifndef KERBEROS
+    /*  Save the user name */
+    (void)strcpy(p->user, p->pop_parm[1]);
+#endif /* KERBEROS */
+
+    /*  Tell the user that the password is required */
+    return (pop_msg(p,POP_SUCCESS,"Password required for %s.",p->user));
+}
diff --git a/src/appl/popper/pop_xmit.c b/src/appl/popper/pop_xmit.c
new file mode 100644 (file)
index 0000000..4096f30
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_xmit.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include "popper.h"
+
+/*
+ *  xmit:   POP XTND function to receive a message from 
+ *          a client and send it in the mail
+ */
+
+pop_xmit (p)
+POP     *   p;
+{
+    FILE                *   tmp;                    /*  File descriptor for 
+                                                        temporary file */
+    char                    buffer[MAXLINELEN];     /*  Read buffer */
+    char                    temp_xmit[MAXDROPLEN];  /*  Name of the temporary 
+                                                        filedrop */
+    union   wait            stat;
+    int                     id, pid;
+
+    /*  Create a temporary file into which to copy the user's message */
+    (void)mktemp((char *)strcpy(temp_xmit,POP_TMPXMIT));
+#ifdef DEBUG
+    if(p->debug)
+        pop_log(p,POP_DEBUG,
+            "Creating temporary file for sending a mail message \"%s\"\n",
+                temp_xmit);
+#endif DEBUG
+    if ((tmp = fopen(temp_xmit,"w+")) == NULL)
+        return (pop_msg(p,POP_FAILURE,
+            "Unable to create temporary message file \"%s\", errno = %d",
+                temp_xmit,errno));
+
+    /*  Tell the client to start sending the message */
+    pop_msg(p,POP_SUCCESS,"Start sending the message.");
+
+    /*  Receive the message */
+#ifdef DEBUG
+    if(p->debug)pop_log(p,POP_DEBUG,"Receiving mail message");
+#endif DEBUG
+    while (fgets(buffer,MAXLINELEN,p->input)){
+        /*  Look for initial period */
+#ifdef DEBUG
+        if(p->debug)pop_log(p,POP_DEBUG,"Receiving: \"%s\"",buffer);
+#endif DEBUG
+        if (*buffer == '.') {
+            /*  Exit on end of message */
+            if (strcmp(buffer,".\r\n") == 0) break;
+        }
+        (void)fputs (buffer,tmp);
+    }
+    (void)fclose (tmp);
+
+#ifdef DEBUG
+    if(p->debug)pop_log(p,POP_DEBUG,"Forking for \"%s\"",MAIL_COMMAND);
+#endif DEBUG
+    /*  Send the message */
+    switch (pid = fork()) {
+        case 0:
+            (void)fclose (p->input);
+            (void)fclose (p->output);       
+            (void)close(0);
+            if (open(temp_xmit,O_RDONLY,0) < 0) (void)_exit(1);
+            (void)execl (MAIL_COMMAND,"send-mail","-t","-oem",NULLCP);
+            (void)_exit(1);
+        case -1:
+#ifdef DEBUG
+            if (!p->debug) (void)unlink (temp_xmit);
+#endif DEBUG
+            return (pop_msg(p,POP_FAILURE,
+                "Unable to execute \"%s\"",MAIL_COMMAND));
+        default:
+            while((id = wait(&stat)) >=0 && id != pid);
+            if (!p->debug) (void)unlink (temp_xmit);
+            if (stat.w_retcode)
+                return (pop_msg(p,POP_FAILURE,"Unable to send message"));
+            return (pop_msg (p,POP_SUCCESS,"Message sent successfully"));
+    }
+
+}
diff --git a/src/appl/popper/pop_xtnd.c b/src/appl/popper/pop_xtnd.c
new file mode 100644 (file)
index 0000000..29aaed8
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+static char SccsId[] = "@(#)pop_xtnd.c  1.5 7/13/90";
+#endif not lint
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "popper.h"
+
+/* 
+ *  xtnd:   Handle extensions to the POP protocol suite
+ */
+
+extern  xtnd_table  *   pop_get_subcommand();
+
+int pop_xtnd (p)
+POP     *   p;
+{
+    xtnd_table  *   x;
+
+    /*  Convert the XTND subcommand to lower case */
+    pop_lower(p->pop_subcommand);
+
+    /*  Search for the subcommand in the XTND command table */
+    if ((x = pop_get_subcommand(p)) == NULL) return(POP_FAILURE);
+
+    /*  Call the function associated with this subcommand */
+    if (x->function) return((*x->function)(p));
+
+    /*  Otherwise assume NOOP */
+    return (pop_msg(p,POP_SUCCESS,NULL));
+}
diff --git a/src/appl/popper/popper.M b/src/appl/popper/popper.M
new file mode 100644 (file)
index 0000000..4270d0e
--- /dev/null
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1980 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that this notice is preserved and that due credit is given
+.\" to the University of California at Berkeley. The name of the University
+.\" may not be used to endorse or promote products derived from this
+.\" software without specific prior written permission. This software
+.\" is provided ``as is'' without express or implied warranty.
+.\"
+.\" @(#)popper.8    1.3    (CCS)   9/15/90     Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n
+.\"
+.TH popper 8 "August 1990"
+.UC 6
+.ad
+.SH NAME
+popper \- pop 3 server
+.SH SYNOPSIS
+.B /usr/etc/popper
+[ -d ]
+[ -t trace-file]
+.SH DESCRIPTION
+.I Popper
+is an implementation of the Post Office Protocol server that runs on a
+variety of Unix computers to manage electronic mail for Macintosh
+and MS-DOS computers.  The server was developed at the University of
+California at Berkeley and conforms fully to the specifications in RFC
+1081 and RFC 1082.  The Berkeley server also has extensions to
+send electronic mail on behalf of a client.
+.PP
+The 
+.B \-d
+flag sets the socket to debugging and turns on debugging.  All debugging
+information is saved using syslog(8).  The 
+.B \-t trace\-file
+flag turns on debugging and saves the trace information in
+.I trace\-file
+using fprintf(s).
+.SH HOW TO OBTAIN THE SERVER
+.PP
+The POP server is available via anonymous ftp from lilac.Berkeley.EDU
+(128.32.136.12).  It is in two files in the pub directory: a compressed
+tar file popper.tar.Z and a Macintosh StuffIt archive in BinHex format
+called MacPOP.sit.hqx.
+.SH THE POP TRANSACTION CYCLE
+.PP
+The Berkeley POP server is a single program (called popper) that is
+launched by inetd when it gets a service request on the POP TCP port.
+(The official port number specified in RFC 1081 for POP version 3 is
+port 110.  However, some POP3 clients attempt to contact the server at
+port 109, the POP version 2 port.  Unless you are running both POP2 and
+POP3 servers, you can simply define both ports for use by the POP3
+server.  This is explained in the installation instructions later on.)
+The popper program initializes and verifies that the peer IP address is
+registered in the local domain, logging a warning message when a
+connection is made to a client whose IP address does not have a
+canonical name.  For systems using BSD 4.3 bind, it also checks to see
+if a cannonical name lookup for the client returns the same peer IP
+address, logging a warning message if it does not.  The the server
+enters the authorization state, during which the client must correctly
+identify itself by providing a valid Unix userid and password on the
+server's host machine.  No other exchanges are allowed during this
+state (other than a request to quit.)  If authentication fails, a
+warning message is logged and the session ends.  Once the user is
+identified, popper changes its user and group ids to match that of the
+user and enters the transaction state.  The server makes a temporary
+copy of the user's maildrop (ordinarily in /usr/spool/mail) which is
+used for all subsequent transactions.  These include the bulk of POP
+commands to retrieve mail, delete mail, undelete mail, and so forth.  A
+Berkeley extension also allows the user to submit a mail parcel to the
+server who mails it using the sendmail program (this extension is
+supported in the HyperMail client distributed with the server).  When
+the client quits, the server enters the final update state during which
+the network connection is terminated and the user's maildrop is updated
+with the (possibly) modified temporary maildrop.
+.SH LOGGING
+.PP
+The POP server uses syslog to keep a record of its activities.  On
+systems with BSD 4.3 syslogging, the server logs (by default) to the
+"local0" facility at priority "notice" for all messages except
+debugging which is logged at priority "debug".  The default log file is
+/usr/spool/mqueue/POPlog.  These can be changed, if desired.  On
+systems with 4.2 syslogging all messages are logged to the local log
+file, usually /usr/spool/mqueue/syslog.
+.SH DEBUGGING
+.PP
+The popper program will log debugging information when the -d parameter
+is specified after its invocation in the inetd.conf file.  Care should
+be exercised in using this option since it generates considerable
+output in the syslog file.  Alternatively, the "-t <file-name>" option
+will place debugging information into file "<file-name>" using fprintf
+instead of syslog.
+.PP
+For SunOS version 3.5, the popper program is launched by inetd from
+/etc/servers.  This file does not allow you to specify command line
+arguments.  Therefore, if you want to enable debugging, you can specify
+a shell script in /etc/servers to be launched instead of popper and in
+this script call popper with the desired arguments.
+.PP
+You can confirm that the POP server is running on Unix by telneting to
+port 110 (or 109 if you set it up that way).  For example:
+.PP
+.nf
+%telnet myhost 110
+Trying...
+Connected to myhost.berkeley.edu.
+Escape character is '^]'.
++OK UCB Pop server (version 1.6) at myhost starting.
+quit
+Connection closed by foreign host.
+.fi
+.SH VERSION 1.7 RELEASE NOTES
+Extensive re-write of the maildrop processing code contributed by 
+Viktor Dukhovni <viktor@math.princeton.edu> that greatly reduces the
+possibility that the maildrop can be corrupted as the result of
+simultaneous access by two or more processes.
+.PP
+Added "pop_dropcopy" module to create a temporary maildrop from
+the existing, standard maildrop as root before the setuid and 
+setgid for the user is done.  This allows the temporary maildrop
+to be created in a mail spool area that is not world read-writable.
+.PP
+This version does *not* send the sendmail "From " delimiter line
+in response to a TOP or RETR command.
+.PP
+Encased all debugging code in #ifdef DEBUG constructs.  This code can
+be included by specifying the DEGUG compiler flag.  Note:  You still
+need to use the -d or -t option to obtain debugging output.
+.SH FILES
+.nf
+/usr/spool/mail         mail files
+/etc/inetd.conf         pop program invocation
+/etc/syslog.conf        logging specifications
+.fi
+.SH "SEE ALSO"
+inetd(8), 
+RFC1081, 
+RFC1082
+.SH AUTHORS
+Bob Campbell, Edward Moy, Austin Shelton, Marshall T Rose, and cast of
+thousands at Rand, UDel, UCI, and elsewhere.
+Kerberos authentication added by Tom Coppeto - MIT Network Services.
diff --git a/src/appl/popper/popper.h b/src/appl/popper/popper.h
new file mode 100644 (file)
index 0000000..5c9db41
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+ * static char SccsId[] = "@(#)popper.h 1.10  7/13/90";
+ *
+ */
+
+/*  LINTLIBRARY */
+
+/* 
+ *  Header file for the POP programs
+ */
+
+#include <syslog.h>
+#include "version.h"
+
+#define NULLCP          ((char *) 0)
+#define SPACE           32
+#define TAB             9
+#define TRUE            1
+#define FALSE           0
+#define NEWLINE         '\n'
+
+#define MAXHOSTNAMELEN  256
+#define MAXUSERNAMELEN  65
+#define MAXDROPLEN      296  /* was 65: kerberos name + max path size - tom */
+#define MAXLINELEN      1024
+#define MAXMSGLINELEN   1024
+#define MAXCMDLEN       4
+#define MAXPARMCOUNT    5
+#define MAXPARMLEN      10
+#define ALLOC_MSGS  20
+#define MAIL_COMMAND    "/usr/lib/sendmail"
+
+#define POP_FACILITY    LOG_LOCAL0
+#define POP_ERROR       LOG_ERR
+#define POP_WARNING     LOG_WARNING
+#define POP_PRIORITY    LOG_NOTICE
+#define POP_INFO        LOG_INFO
+#define POP_DEBUG       LOG_DEBUG
+#define POP_LOGOPTS     0
+#define POP_MAILDIR     "/usr/spool/pop"
+#define POP_PASSFILE    "/usr/spool/pop/POP"
+#define POP_DROP        "/usr/spool/pop/.%s.temp"
+#define POP_TMPXMIT     "/tmp/xmitXXXXXX"
+#define POP_OK          "+OK"
+#define POP_ERR         "-ERR"
+#define POP_SUCCESS     1
+#define POP_FAILURE     0
+#define POP_TERMINATE   '.'
+
+extern int              errno;
+extern int              sys_nerr;
+extern char         *   sys_errlist[];
+extern char         *   sys_siglist[];
+
+#define pop_command         pop_parm[0]     /*  POP command is first token */
+#define pop_subcommand      pop_parm[1]     /*  POP XTND subcommand is the 
+                                                second token */
+
+typedef enum {                              /*  POP processing states */
+    auth1,                                  /*  Authorization: waiting for 
+                                                USER command */
+    auth2,                                  /*  Authorization: waiting for 
+                                                PASS command */
+    trans,                                  /*  Transaction */
+    update,                                 /*  Update:  session ended, 
+                                                process maildrop changes */
+    halt,                                   /*  (Halt):  stop processing 
+                                                and exit */
+    error                                   /*  (Error): something really 
+                                                bad happened */
+} state;
+
+typedef struct {                                /*  State information for 
+                                                    each POP command */
+    state       ValidCurrentState;              /*  The operating state of 
+                                                    the command */
+    char   *    command;                        /*  The POP command */
+    int         min_parms;                      /*  Minimum number of parms 
+                                                    for the command */
+    int         max_parms;                      /*  Maximum number of parms 
+                                                    for the command */
+    int         (*function) ();                 /*  The function that process 
+                                                    the command */
+    state       result[2];                      /*  The resulting state after 
+                                                    command processing */
+#define success_state   result[0]               /*  State when a command 
+                                                    succeeds */
+} state_table;
+
+typedef struct {                                /*  Table of extensions */
+    char   *    subcommand;                     /*  The POP XTND subcommand */
+    int         min_parms;                      /*  Minimum number of parms for
+                                                    the subcommand */
+    int         max_parms;                      /*  Maximum number of parms for
+                                                    the subcommand */
+    int         (*function) ();                 /*  The function that processes 
+                                                    the subcommand */
+} xtnd_table;
+
+typedef struct {                                /*  Message information */
+    int         number;                         /*  Message number relative to 
+                                                    the beginning of list */
+    long        length;                         /*  Length of message in 
+                                                    bytes */
+    int         lines;                          /*  Number of (null-terminated)                                                     lines in the message */
+    long        offset;                         /*  Offset from beginning of 
+                                                    file */
+    int         del_flag;                       /*  Flag indicating if message 
+                                                    is marked for deletion */
+    int         retr_flag;                      /*  Flag indicating if message 
+                                                    was retrieved */
+} MsgInfoList;
+
+typedef struct  {                               /*  POP parameter block */
+    int                 debug;                  /*  Debugging requested */
+    char            *   myname;                 /*  The name of this POP 
+                                                    daemon program */
+    char                myhost[MAXHOSTNAMELEN]; /*  The name of our host 
+                                                    computer */
+    char            *   client;                 /*  Canonical name of client 
+                                                    computer */
+    char            *   ipaddr;                 /*  Dotted-notation format of 
+                                                    client IP address */
+    unsigned short      ipport;                 /*  Client port for privileged 
+                                                    operations */
+    char                user[MAXUSERNAMELEN];   /*  Name of the POP user */
+    state               CurrentState;           /*  The current POP operational                                                     state */
+    MsgInfoList     *   mlp;                    /*  Message information list */
+    int                 msg_count;              /*  Number of messages in 
+                                                    the maildrop */
+    int                 msgs_deleted;           /*  Number of messages flagged 
+                                                    for deletion */
+    int                 last_msg;               /*  Last message touched by 
+                                                    the user */
+    long                bytes_deleted;          /*  Number of maildrop bytes 
+                                                    flagged for deletion */
+    char                drop_name[MAXDROPLEN];  /*  The name of the user's 
+                                                    maildrop */
+    char                temp_drop[MAXDROPLEN];  /*  The name of the user's 
+                                                    temporary maildrop */
+    long                drop_size;              /*  Size of the maildrop in
+                                                    bytes */
+    FILE            *   drop;                   /*  (Temporary) mail drop */
+    FILE            *   input;                  /*  Input TCP/IP communication 
+                                                    stream */
+    FILE            *   output;                 /*  Output TCP/IP communication                                                     stream */
+    FILE            *   trace;                  /*  Debugging trace file */
+    char            *   pop_parm[MAXPARMCOUNT]; /*  Parse POP parameter list */
+    int                 parm_count;             /*  Number of parameters in 
+                                                    parsed list */
+} POP;
+
+extern int  pop_dele();
+extern int  pop_last();
+extern int  pop_list();
+extern int  pop_pass();
+extern int  pop_quit();
+extern int  pop_rset();
+extern int  pop_send();
+extern int  pop_stat();
+extern int  pop_updt();
+extern int  pop_user();
+extern int  pop_xtnd();
+extern int  pop_xmit();
+
diff --git a/src/appl/popper/syslog_levels b/src/appl/popper/syslog_levels
new file mode 100644 (file)
index 0000000..a6980fd
--- /dev/null
@@ -0,0 +1,5 @@
+debug   - debugging information
+info    - logs connections
+notice  - errors (ie: locked maildrop, broken pipe)
+warning - authentication/authorization errors
+error   - bigger errors (ie: no resources)
diff --git a/src/appl/popper/version.h b/src/appl/popper/version.h
new file mode 100644 (file)
index 0000000..4512cb4
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
+ * static char SccsId[] = "@(#)version.h    1.11  9/15/90";
+ *
+ */
+
+/*
+ *  Current version of this POP implementation
+ */
+
+#define VERSION         "1.7"
diff --git a/src/appl/telnet/.rconf b/src/appl/telnet/.rconf
new file mode 100644 (file)
index 0000000..e98c016
--- /dev/null
@@ -0,0 +1 @@
+ignore */*.0
diff --git a/src/appl/telnet/Imakefile b/src/appl/telnet/Imakefile
new file mode 100644 (file)
index 0000000..fd863ae
--- /dev/null
@@ -0,0 +1,24 @@
+all:
+       cd libtelnet; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) 
+       cd telnet; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) 
+       cd telnetd; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) 
+
+clean::
+       cd libtelnet; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) clean
+       cd telnet; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) clean
+       cd telnetd; make CC="${CC}" TELNET_OPSYS=$(TELNET_OPSYS) clean
+
+install::
+       cd libtelnet; make CC="${CC}" DESTDIR=$(DESTDIR) \
+               TELNET_OPSYS=$(TELNET_OPSYS) install
+       cd telnet; make CC="${CC}" DESTDIR=$(DESTDIR) \
+               TELNET_OPSYS=$(TELNET_OPSYS) install
+       cd telnetd; make CC="${CC}" DESTDIR=$(DESTDIR) \
+               TELNET_OPSYS=$(TELNET_OPSYS) install
+
+SUBDIRS=libtelnet telnet telnetd
+
+MakefileSubdirs($(SUBDIRS))
+
+depend:
+       @echo "We don't calculate dependencies below this point."
diff --git a/src/appl/telnet/libtelnet/Imakefile b/src/appl/telnet/libtelnet/Imakefile
new file mode 100644 (file)
index 0000000..fcffba7
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 1991 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted provided
+# that: (1) source distributions retain this entire copyright notice and
+# comment, and (2) distributions including binaries display the following
+# acknowledgement:  ``This product includes software developed by the
+# University of California, Berkeley and its contributors'' in the
+# documentation or other materials provided with the distribution and in
+# all advertising materials mentioning features or use of this software.
+# Neither the name of the University nor the names of its contributors may
+# be used to endorse or promote products derived from this software without
+# specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+#      @(#)Makefile    5.5 (Berkeley) 3/1/91
+#
+
+#
+# Everything happens in ../Makefile.config and Makefile.generic
+#
+
+all:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+               make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+       else \
+               echo make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+       fi
+
+Makefiles::
+       @echo "Do nothing!"
+
+.DEFAULT:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       else \
+               echo make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       fi
+
diff --git a/src/appl/telnet/libtelnet/gettytab.c b/src/appl/telnet/libtelnet/gettytab.c
new file mode 100644 (file)
index 0000000..0705325
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gettytab.c 5.1 (Berkeley) 4/29/85";
+#endif not lint
+
+#include <ctype.h>
+
+#define        TABBUFSIZ       512
+
+static char *tbuf;
+int    hopcount;       /* detect infinite loops in termcap, init 0 */
+char   *skip();
+char   *getstr();
+char   *decode();
+
+/*
+ * Get an entry for terminal name in buffer bp,
+ * from the termcap file.  Parse is very rudimentary;
+ * we just notice escaped newlines.
+ */
+getent(bp, name)
+       char *bp, *name;
+{
+       register char *cp;
+       register int c;
+       register int i = 0, cnt = 0;
+       char ibuf[TABBUFSIZ];
+       char *cp2;
+       int tf;
+
+       tbuf = bp;
+       tf = open("/etc/gettytab", 0);
+       if (tf < 0)
+               return (-1);
+       for (;;) {
+               cp = bp;
+               for (;;) {
+                       if (i == cnt) {
+                               cnt = read(tf, ibuf, TABBUFSIZ);
+                               if (cnt <= 0) {
+                                       close(tf);
+                                       return (0);
+                               }
+                               i = 0;
+                       }
+                       c = ibuf[i++];
+                       if (c == '\n') {
+                               if (cp > bp && cp[-1] == '\\'){
+                                       cp--;
+                                       continue;
+                               }
+                               break;
+                       }
+                       if (cp >= bp+TABBUFSIZ) {
+                               write(2,"Gettytab entry too long\n", 24);
+                               break;
+                       } else
+                               *cp++ = c;
+               }
+               *cp = 0;
+
+               /*
+                * The real work for the match.
+                */
+               if (namatch(name)) {
+                       close(tf);
+                       return(nchktc());
+               }
+       }
+}
+
+/*
+ * tnchktc: check the last entry, see if it's tc=xxx. If so,
+ * recursively find xxx and append that entry (minus the names)
+ * to take the place of the tc=xxx entry. This allows termcap
+ * entries to say "like an HP2621 but doesn't turn on the labels".
+ * Note that this works because of the left to right scan.
+ */
+#define        MAXHOP  32
+nchktc()
+{
+       register char *p, *q;
+       char tcname[16];        /* name of similar terminal */
+       char tcbuf[TABBUFSIZ];
+       char *holdtbuf = tbuf;
+       int l;
+
+       p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
+       while (*--p != ':')
+               if (p<tbuf) {
+                       write(2, "Bad gettytab entry\n", 19);
+                       return (0);
+               }
+       p++;
+       /* p now points to beginning of last field */
+       if (p[0] != 't' || p[1] != 'c')
+               return(1);
+       strcpy(tcname,p+3);
+       q = tcname;
+       while (q && *q != ':')
+               q++;
+       *q = 0;
+       if (++hopcount > MAXHOP) {
+               write(2, "Getty: infinite tc= loop\n", 25);
+               return (0);
+       }
+       if (getent(tcbuf, tcname) != 1)
+               return(0);
+       for (q=tcbuf; *q != ':'; q++)
+               ;
+       l = p - holdtbuf + strlen(q);
+       if (l > TABBUFSIZ) {
+               write(2, "Gettytab entry too long\n", 24);
+               q[TABBUFSIZ - (p-tbuf)] = 0;
+       }
+       strcpy(p, q+1);
+       tbuf = holdtbuf;
+       return(1);
+}
+
+/*
+ * Tnamatch deals with name matching.  The first field of the termcap
+ * entry is a sequence of names separated by |'s, so we compare
+ * against each such name.  The normal : terminator after the last
+ * name (before the first field) stops us.
+ */
+namatch(np)
+       char *np;
+{
+       register char *Np, *Bp;
+
+       Bp = tbuf;
+       if (*Bp == '#')
+               return(0);
+       for (;;) {
+               for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
+                       continue;
+               if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
+                       return (1);
+               while (*Bp && *Bp != ':' && *Bp != '|')
+                       Bp++;
+               if (*Bp == 0 || *Bp == ':')
+                       return (0);
+               Bp++;
+       }
+}
+
+/*
+ * Skip to the next field.  Notice that this is very dumb, not
+ * knowing about \: escapes or any such.  If necessary, :'s can be put
+ * into the termcap file in octal.
+ */
+static char *
+skip(bp)
+       register char *bp;
+{
+
+       while (*bp && *bp != ':')
+               bp++;
+       if (*bp == ':')
+               bp++;
+       return (bp);
+}
+
+/*
+ * Return the (numeric) option id.
+ * Numeric options look like
+ *     li#80
+ * i.e. the option string is separated from the numeric value by
+ * a # character.  If the option is not found we return -1.
+ * Note that we handle octal numbers beginning with 0.
+ */
+long
+getnum(id)
+       char *id;
+{
+       register long i, base;
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (*bp == 0)
+                       return (-1);
+               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+                       continue;
+               if (*bp == '@')
+                       return(-1);
+               if (*bp != '#')
+                       continue;
+               bp++;
+               base = 10;
+               if (*bp == '0')
+                       base = 8;
+               i = 0;
+               while (isdigit(*bp))
+                       i *= base, i += *bp++ - '0';
+               return (i);
+       }
+}
+
+/*
+ * Handle a flag option.
+ * Flag options are given "naked", i.e. followed by a : or the end
+ * of the buffer.  Return 1 if we find the option, or 0 if it is
+ * not given.
+ */
+getflag(id)
+       char *id;
+{
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (!*bp)
+                       return (-1);
+               if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
+                       if (!*bp || *bp == ':')
+                               return (1);
+                       else if (*bp == '!')
+                               return (0);
+                       else if (*bp == '@')
+                               return(-1);
+               }
+       }
+}
+
+/*
+ * Get a string valued option.
+ * These are given as
+ *     cl=^Z
+ * Much decoding is done on the strings, and the strings are
+ * placed in area, which is a ref parameter which is updated.
+ * No checking on area overflow.
+ */
+char *
+getstr(id, area)
+       char *id, **area;
+{
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (!*bp)
+                       return (0);
+               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+                       continue;
+               if (*bp == '@')
+                       return(0);
+               if (*bp != '=')
+                       continue;
+               bp++;
+               return (decode(bp, area));
+       }
+}
+
+/*
+ * Tdecode does the grung work to decode the
+ * string capability escapes.
+ */
+static char *
+decode(str, area)
+       register char *str;
+       char **area;
+{
+       register char *cp;
+       register int c;
+       register char *dp;
+       int i;
+
+       cp = *area;
+       while ((c = *str++) && c != ':') {
+               switch (c) {
+
+               case '^':
+                       c = *str++ & 037;
+                       break;
+
+               case '\\':
+                       dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
+                       c = *str++;
+nextc:
+                       if (*dp++ == c) {
+                               c = *dp++;
+                               break;
+                       }
+                       dp++;
+                       if (*dp)
+                               goto nextc;
+                       if (isdigit(c)) {
+                               c -= '0', i = 2;
+                               do
+                                       c <<= 3, c |= *str++ - '0';
+                               while (--i && isdigit(*str));
+                       }
+                       break;
+               }
+               *cp++ = c;
+       }
+       *cp++ = 0;
+       str = *area;
+       *area = cp;
+       return (str);
+}
diff --git a/src/appl/telnet/libtelnet/gettytab.h b/src/appl/telnet/libtelnet/gettytab.h
new file mode 100644 (file)
index 0000000..a96dcf3
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)gettytab.h  5.2 (Berkeley) 1/7/86
+ */
+
+/*
+ * Getty description definitions.
+ */
+struct gettystrs {
+       char    *field;         /* name to lookup in gettytab */
+       char    *defalt;        /* value we find by looking in defaults */
+       char    *value;         /* value that we find there */
+};
+
+struct gettynums {
+       char    *field;         /* name to lookup */
+       long    defalt;         /* number we find in defaults */
+       long    value;          /* number we find there */
+       int     set;            /* we actually got this one */
+};
+
+struct gettyflags {
+       char    *field;         /* name to lookup */
+       char    invrt;          /* name existing in gettytab --> false */
+       char    defalt;         /* true/false in defaults */
+       char    value;          /* true/false flag */
+       char    set;            /* we found it */
+};
+
+/*
+ * String values.
+ */
+#define        NX      gettystrs[0].value
+#define        CL      gettystrs[1].value
+#define IM     gettystrs[2].value
+#define        LM      gettystrs[3].value
+#define        ER      gettystrs[4].value
+#define        KL      gettystrs[5].value
+#define        ET      gettystrs[6].value
+#define        PC      gettystrs[7].value
+#define        TT      gettystrs[8].value
+#define        EV      gettystrs[9].value
+#define        LO      gettystrs[10].value
+#define HN     gettystrs[11].value
+#define HE     gettystrs[12].value
+#define IN     gettystrs[13].value
+#define QU     gettystrs[14].value
+#define XN     gettystrs[15].value
+#define XF     gettystrs[16].value
+#define BK     gettystrs[17].value
+#define SU     gettystrs[18].value
+#define DS     gettystrs[19].value
+#define RP     gettystrs[20].value
+#define FL     gettystrs[21].value
+#define WE     gettystrs[22].value
+#define LN     gettystrs[23].value
+
+/*
+ * Numeric definitions.
+ */
+#define        IS      gettynums[0].value
+#define        OS      gettynums[1].value
+#define        SP      gettynums[2].value
+#define        ND      gettynums[3].value
+#define        CD      gettynums[4].value
+#define        TD      gettynums[5].value
+#define        FD      gettynums[6].value
+#define        BD      gettynums[7].value
+#define        TO      gettynums[8].value
+#define        F0      gettynums[9].value
+#define        F0set   gettynums[9].set
+#define        F1      gettynums[10].value
+#define        F1set   gettynums[10].set
+#define        F2      gettynums[11].value
+#define        F2set   gettynums[11].set
+#define        PF      gettynums[12].value
+
+/*
+ * Boolean values.
+ */
+#define        HT      gettyflags[0].value
+#define        NL      gettyflags[1].value
+#define        EP      gettyflags[2].value
+#define        EPset   gettyflags[2].set
+#define        OP      gettyflags[3].value
+#define        OPset   gettyflags[2].set
+#define        AP      gettyflags[4].value
+#define        APset   gettyflags[2].set
+#define        EC      gettyflags[5].value
+#define        CO      gettyflags[6].value
+#define        CB      gettyflags[7].value
+#define        CK      gettyflags[8].value
+#define        CE      gettyflags[9].value
+#define        PE      gettyflags[10].value
+#define        RW      gettyflags[11].value
+#define        XC      gettyflags[12].value
+#define        LC      gettyflags[13].value
+#define        UC      gettyflags[14].value
+#define        IG      gettyflags[15].value
+#define        PS      gettyflags[16].value
+#define        HC      gettyflags[17].value
+#define UB     gettyflags[18].value
+#define AB     gettyflags[19].value
+#define DX     gettyflags[20].value
+#define RM     gettyflags[21].value
+
+int    getent();
+long   getnum();
+int    getflag();
+char   *getstr();
+
+extern struct gettyflags gettyflags[];
+extern struct gettynums gettynums[];
+extern struct gettystrs gettystrs[];
+extern int hopcount;
diff --git a/src/appl/telnet/telnet/Imakefile b/src/appl/telnet/telnet/Imakefile
new file mode 100644 (file)
index 0000000..fd3fdf1
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 1991 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted provided
+# that: (1) source distributions retain this entire copyright notice and
+# comment, and (2) distributions including binaries display the following
+# acknowledgement:  ``This product includes software developed by the
+# University of California, Berkeley and its contributors'' in the
+# documentation or other materials provided with the distribution and in
+# all advertising materials mentioning features or use of this software.
+# Neither the name of the University nor the names of its contributors may
+# be used to endorse or promote products derived from this software without
+# specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+#      @(#)Makefile    5.5 (Berkeley) 3/1/91
+#
+
+#
+# Everything happens in ../Makefile.config and Makefile.generic
+#
+
+all:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+               make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+       else \
+               echo make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+       fi
+
+.DEFAULT:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       else \
+               echo make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       fi
+
diff --git a/src/appl/telnet/telnetd/Imakefile b/src/appl/telnet/telnetd/Imakefile
new file mode 100644 (file)
index 0000000..fd3fdf1
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 1991 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted provided
+# that: (1) source distributions retain this entire copyright notice and
+# comment, and (2) distributions including binaries display the following
+# acknowledgement:  ``This product includes software developed by the
+# University of California, Berkeley and its contributors'' in the
+# documentation or other materials provided with the distribution and in
+# all advertising materials mentioning features or use of this software.
+# Neither the name of the University nor the names of its contributors may
+# be used to endorse or promote products derived from this software without
+# specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+#      @(#)Makefile    5.5 (Berkeley) 3/1/91
+#
+
+#
+# Everything happens in ../Makefile.config and Makefile.generic
+#
+
+all:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+               make -f ../Config.local WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)"; \
+       else \
+               echo make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT="" CC="${CC}" \
+                       KLIB="$(KLIB)" DEPKLIB="$(DEPKLIB)" $(TELNET_OPSYS); \
+       fi
+
+.DEFAULT:
+       @-if [ -f ../Config.local ]; \
+       then \
+               echo make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.local WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       else \
+               echo make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+               make -f ../Config.generic WHAT=$@ CC="${CC}" \
+                       DESTDIR=$(DESTDIR) DEST=$(DEST) $(TELNET_OPSYS); \
+       fi
+
diff --git a/src/config-files/Imakefile b/src/config-files/Imakefile
new file mode 100644 (file)
index 0000000..5fab6f7
--- /dev/null
@@ -0,0 +1,6 @@
+all::
+
+Krb5InstallManPage(krb.conf,$(FILE_MANDIR),$(FILE_MANSUFFIX))
+Krb5InstallManPage(krb.realms,$(FILE_MANDIR),$(FILE_MANSUFFIX))
+
+depend::
diff --git a/src/config/Imake.rules.foo b/src/config/Imake.rules.foo
new file mode 100644 (file)
index 0000000..dbea023
--- /dev/null
@@ -0,0 +1,272 @@
+***************
+*** 1,119 ****
+! /**/# $Source$
+! /**/# $Author$
+! /**/# $Id$
+! /**/#
+! 
+! /**/###########################################################################
+! /**/# Imake rules for building libraries, programs, scripts, and data files
+! /**/# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
+  
+  /*
+   *              MACHINE-INDEPENDENT RULES; DO NOT MODIFY
+   *
+!  * Warning, when defining rules: make sure you don't include both a trailing
+   * backslash and double ampersand backslash or else you will get an extra
+   * backslash in the Makefile.
+   * 
+!  * These macros are defined for the various templates and Imakefiles (for a 
+!  * list of the applicable make variables, see the template files):
+   * 
+!  *      SaberProgramTarget          (program,srclist,objlist,locallibs,syslibs)
+!  *      RemoveTargetProgram                      (program)
+!  *      BuildIncludes                            (srclist,dstdir)
+!  *           NormalProgramTarget         (program,objects,deplibs,locallibs,syslibs)
+!  *           SimpleProgramTarget                      (program)
+!  *           ComplexProgramTarget                     (program)
+!  *           ComplexProgramTarget_1                   (program,locallib,syslib)
+!  *           ComplexProgramTarget_2                   (program,locallib,syslib)
+!  *           ComplexProgramTarget_3                   (program,locallib,syslib)
+!  *           ServerTarget                     (server,subdirs,objects,libs,syslibs)
+!  *           InstallLibrary                           (libname,dest)
+!  *           InstallSharedLibrary                     (libname,rev,dest)
+!  *           InstallLibraryAlias                      (libname,alias,dest)
+!  *           InstallLintLibrary                       (libname,dest)
+!  *           InstallManPageLong                       (file,destdir,dest)
+!  *           InstallManPage                           (file,dest)
+!  *           InstallNonExec                           (file,dest)
+!  *           InstallProgram                           (program,dest)
+!  *      InstallProgramWithFlags                  (program,dest,flags)
+!  *           InstallScript                            (program,dest)
+!  *      LinkFileList                             (step,list,dir,sub)
+!  *      InstallMultipleDestFlags                 (step,list,dest,flags)
+!  *      InstallMultipleDest                      (step,list,dest)
+!  *           InstallMultiple                          (list,dest)
+!  *      InstallMultipleFlags                     (list,dest,flags)
+!  *      InstallMultipleMan                       (list,dest)
+!  *           InstallAppDefaults                       (class)
+!  *      DependDependency                         ()
+!  *           DependTarget                             ()
+!  *           CleanTarget                              ()
+!  *           TagsTarget                               ()
+!  *      ImakeDependency                          (target)
+!  *           BuildMakefileTarget                      (imakefile,imakeflags)
+!  *      MakefileTarget                           ()
+!  *           NormalLibraryObjectRule                  ()
+!  *           ProfiledLibraryObjectRule                ()
+!  *           DebuggedLibraryObjectRule                ()
+!  *           DebuggedAndProfiledLibraryObjectRule     ()
+!  *      SharedLibraryObjectRule                  ()
+!  *      SharedAndDebuggedLibraryObjectRule       ()
+!  *      SpecialObjectRule                        (objs,depends,options)
+!  *           SpecialProfiledObjectRule                (objs,depends,options)
+!  *           SpecialDebuggedObjectRule                (objs,depends,options)
+!  *           SpecialDebuggedAndProfiledObjectRule     (objs,depends,options)
+!  *           NormalLibraryTarget                      (libname,objlist)
+!  *      NormalSharedLibraryTarget                (libname,rev,solist,salist)
+!  *           NormalLibraryTarget2                     (libname,objlist1,objlist2)
+!  *           ProfiledLibraryTarget                    (libname,objlist)
+!  *           DebuggedLibraryTarget                    (libname,objlist)
+!  *           AliasedLibraryTarget                     (libname,alias)
+!  *           NormalRelocatableTarget                  (objname,objlist)
+!  *           ProfiledRelocatableTarget                (objname,objlist)
+!  *           DebuggedRelocatableTarget                (objname,objlist)
+!  *           LintLibraryTarget                        (libname,srclist)
+!  *      NormalLintTarget                         (srclist)
+!  *      LintTarget                               ()
+!  *      MakeSubincludesForBuild                  (step,dir,srclist)
+!  *      NamedTargetSubdirs                       (name,dirs,verb,flags,subname)
+!  *      MakeSubdirs                              (dirs)
+!  *      NamedMakeSubdirs                         (name,dirs)
+!  *      DependSubdirs                            (dirs)
+!  *      InstallSubdirs                           (dirs)
+!  *      InstallManSubdirs                        (dirs)
+!  *      NamedIncludesSubdirs                     (name,dirs)
+!  *      IncludesSubdirs                             (dirs)
+!  *      NamedCleanSubdirs                        (name,dirs)
+!  *      CleanSubdirs                             (dirs)
+!  *      NamedTagSubdirs                          (name,dirs)
+!  *      TagSubdirs                               (dirs)
+!  *      MakeLintSubdirs                          (dirs,target,subtarget)
+!  *      LintSubdirs                              (dirs)
+!  *      MakeLintLibSubdirs                       (dirs)
+!  *      MakeMakeSubdirs                          (dirs,target)
+!  *      MakeNsubdirMakefiles                     ()
+!  *      MakefileSubdirs                          (dirs)
+!  *      CppScriptTarget                          (dst,src,defs,deplist)
+!  *      MakeScriptFromCpp                        (name,defs)
+!  *      MakeDirectories                          (step,dirs)
+!  *      MakeFonts                                ()
+!  *      InstallFonts                             (dest)
+!  *      InstallFontAliases                       (dest)
+!  *      FontTarget                               (basename)
+!  *      CompressedFontTarget                     (basename)
+!  *      AllTarget                                (depends)
+!  *   DoRanlib                                 (flags,files)
+!  * 
+!  * 
+!  * The general linking for building programs is:
+   * 
+!  *      program-objects programlibs syslibs EXTRA_LIBRARIES systemlibs \
+!  *              EXTRA_LOAD_FLAGS
+   *
+!  * where programlibs is LOCAL_LIBRARIES for ComplexProgramTarget
+!  * and EXTRA comes with syslibs from the LDLIBS
+   */
+  
+  
+  
+  /*
+   * SaberProgramTarget - generate rules to make Saber-C read in sources and
+--- 1,150 ----
+! XCOMM -------------------------------------------------------------------------
+! XCOMM Imake rules for building libraries, programs, scripts, and data files
+! XCOMM rules:  $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+  
+  /*
+   *              MACHINE-INDEPENDENT RULES; DO NOT MODIFY
+   *
+!  * Warning, when defining rules: make sure you do not include both a trailing
+   * backslash and double ampersand backslash or else you will get an extra
+   * backslash in the Makefile.
+   * 
+!  * The following macros are defined for the various templates and Imakefiles
+!  * (for a list of the applicable make variables, see the template files):
+   * 
+!  * SaberProgramTarget                (program,srclist,objlist,locallibs,syslibs)
+!  * RemoveTargetProgram               (program)
+!  * MakeDir                   (dir)
+!  * BuildIncludes             (srclist,dstsubdir,dstupdir)
+!  * NormalProgramTarget               (program,objects,deplibs,locallibs,syslibs)
+!  * SetUIDProgramTarget               (program,objects,deplibs,locallibs,syslibs)
+!  * SingleProgramTarget               (program,objects,locallibs,syslibs)
+!  * SimpleProgramTarget               (program)
+!  * ComplexProgramTarget              (program)
+!  * ComplexProgramTarget_1    (program,locallib,syslib)
+!  * ComplexProgramTarget_2    (program,locallib,syslib)
+!  * ComplexProgramTarget_3    (program,locallib,syslib)
+!  * ServerTarget                      (server,subdirs,objects,libs,syslibs)
+!  * RanLibrary                        (args)
+!  * InstallLibrary            (libname,dest)
+!  * MergeIntoInstalledLibrary (tolib,fromlib)
+!  * InstallLibraryAlias               (libname,alias,dest)
+!  * InstallLintLibrary                (libname,dest)
+!  * InstallManPageLong                (file,destdir,dest)
+!  * InstallManPage            (file,destdir)
+!  * InstallManPageAliases     (file,destdir,aliases)
+!  * InstallNamedNonExec               (srcname,dstname,dest)
+!  * InstallNonExecFile                (file,dest)
+!  * InstallNonExec            (file,dest)
+!  * InstallProgramWithFlags   (program,dest,flags)
+!  * InstallProgram            (program,dest)
+!  * InstallScript             (program,dest)
+!  * InstallNamedProg          (srcname,dstname,dest)
+!  * LinkFileList                      (step,list,dir,sub)
+!  * InstallMultipleDestFlags  (step,list,dest,flags)
+!  * InstallMultipleDest               (step,list,dest)
+!  * InstallMultiple           (list,dest)
+!  * InstallMultipleFlags              (list,dest,flags)
+!  * InstallMultipleMan                (list,dest)
+!  * InstallAppDefaults                (class)
+!  * InstallAppDefaultsLong    (file,class)
+!  * DependDependency          ()
+!  * DependTarget                      ()
+!  * DependTarget3             (srcs1,srcs2,srcs3)
+!  * CleanTarget                       ()
+!  * TagsTarget                        ()
+!  * ImakeDependency           (target)
+!  * BuildMakefileTarget               (notused,imakeflags)
+!  * MakefileTarget            ()
+!  * LibMkdir                  (dir)
+!  * LibCleanDir                       (dir)
+!  * ObjectCompile             (options)
+!  * NormalLibObjCompile               (options)
+!  * NormalSharedLibObjCompile (options)
+!  * LibObjCompile             (dir,options)
+!  * DebuggedLibObjCompile     (options)
+!  * ProfiledLibObjCompile     (options)
+!  * SharedLibObjCompile               (options)
+!  * NormalLibraryObjectRule   ()
+!  * NormalFortranObjectRule   ()
+!  * ObjectFromSpecialSource   (dst,src,flags)
+!  * SpecialObjectRule         (objs,depends,options)
+!  * NormalLibraryTarget               (libname,objlist)
+!  * NormalLibraryTarget2              (libname,objlist1,objlist2)
+!  * NormalLibraryTarget3              (libname,objlist1,objlist2,objlist3)
+!  * NormalDepLibraryTarget    (libname,deplist,objlist)
+!  * SubdirLibraryRule         (objlist)
+!  * ProfiledLibraryTarget     (libname,objlist)
+!  * DebuggedLibraryTarget     (libname,objlist)
+!  * AliasedLibraryTarget              (libname,alias)
+!  * NormalRelocatableTarget   (objname,objlist)
+!  * ProfiledRelocatableTarget (objname,objlist)
+!  * DebuggedRelocatableTarget (objname,objlist)
+!  * LintLibraryTarget         (libname,srclist)
+!  * NormalLintTarget          (srclist)
+!  * LintTarget                        ()
+!  * LinkSourceFile            (src,dir)
+!  * LinkFile                  (tofile,fromfile)
+!  * MakeSubincludesForBuild   (step,dir,srclist)
+!  * NamedTargetSubdirs                (name,dirs,verb,flags,subname)
+!  * NamedMakeSubdirs          (name,dirs)
+!  * MakeSubdirs                       (dirs)
+!  * DependSubdirs             (dirs)
+!  * ForceSubdirs                      (dirs)
+!  * InstallSubdirs            (dirs)
+!  * InstallManSubdirs         (dirs)
+!  * IncludesSubdirs           (dirs)
+!  * NamedCleanSubdirs         (name,dirs)
+!  * CleanSubdirs                      (dirs)
+!  * NamedTagSubdirs           (name,dirs)
+!  * TagSubdirs                        (dirs)
+!  * MakeLintSubdirs           (dirs,target,subtarget)
+!  * LintSubdirs                       (dirs)
+!  * MakeLintLibSubdirs                (dirs)
+!  * MakeMakeSubdirs           (dirs,target)
+!  * MakeNsubdirMakefiles              ()
+!  * MakefileSubdirs           (dirs)
+!  * CppScriptTarget           (dst,src,defs,deplist)
+!  * MakeScriptFromCpp         (name,defs)
+!  * CppFileTarget             (dst,src,defs,deplist)
+!  * MakeDirectories           (step,dirs)
+!  * MakeFontsDir                      (deplist)
+!  * MakeFonts                 ()
+!  * InstallFontObjs           (objs,dest)
+!  * InstallFonts                      (dest)
+!  * InstallFontAliases                (dest)
+!  * FontSrc                   (basename)
+!  * FontBaseObj                       (basename)
+!  * InstallFontScale          (dest)
+!  * UncompressedFontTarget    (basename)
+!  * UncompressedFontTarget    (basename)
+!  * CompressedFontTarget              (basename)
+!  * FontTarget                        (basename)
+!  * FontObj                   (basename)
+!  * AllTarget                 (depends)
+!  *
+!  *
+!  * The following are in Imake.tmpl:
+!  *
+!  * Concat                    (a,b)
+!  * Concat3                   (a,b,c)
+   * 
+!  *
+!  * The following are in specific <os>Lib.rules:
+   *
+!  * SharedLibraryTarget               (libname,rev,solist,down,up)
+!  * SharedLibraryDataTarget   (libname,rev,salist)
+!  * InstallSharedLibrary              (libname,rev,dest)
+!  * InstallSharedLibraryData  (libname,rev,dest)
+!  * 
+   */
+  
++ #define NullParameter
+  
++ /* if [ -d ] or [ ! -d ] causes make to fail, define this as - */
++ #ifndef DirFailPrefix
++ #define DirFailPrefix
++ #endif
+  
+  /*
+   * SaberProgramTarget - generate rules to make Saber-C read in sources and
diff --git a/src/config/Imake.tmpl-xcomp b/src/config/Imake.tmpl-xcomp
new file mode 100644 (file)
index 0000000..807bb1c
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * generic imake template
+ */
+
+/**/# $Source$
+/**/# $Author$
+/**/# $Id$
+/**/#
+
+/**/###########################################################################
+/**/# Makefile generated from IMAKE_TEMPLATE and INCLUDE_IMAKEFILE
+/**/# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
+/**/#
+/**/# Platform-specific parameters may be set in the appropriate .cf
+/**/# configuration files.  Site-wide parameters may be set in the file
+/**/# site.def.  Full rebuilds are recommended if any parameters are changed.
+/**/#
+/**/# If your C preprocessor doesn't define any unique symbols, you'll need
+/**/# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+/**/# "make Makefile", "make Makefiles", or "make World").
+/**/#
+/**/# If you absolutely can't get imake to work, you'll need to set the 
+/**/# variables at the top of each Makefile as well as the dependencies at the
+/**/# bottom (makedepend will do this automatically).
+/**/#
+
+
+#define        YES     1
+#define NO     0
+
+
+/*
+ * To add support for another platform:
+ * 
+ *     1.  Identify a machine-specific cpp symbol.  If your preprocessor 
+ *         doesn't have any built in, you'll need to add the symbol to the
+ *         cpp_argv table in config/imake.c and rebuild imake with the
+ *         BOOTSTRAPCFLAGS variable set (see the macII for an example).
+ *
+ *     [ignore this for now...no makedepend with Kerberos V5 (yet...)]
+ *     2.  Add all machine-specific cpp symbols (either defined by you or by
+ *         the preprocessor or compiler) to the predefs table in 
+ *         config/makedepend/main.c.
+ *
+ *     3.  But a new #ifdef block below that defines MacroIncludeFile and
+ *         MacroFile for your new platform and then #undefs the machine-
+ *         specific preprocessor symbols (to avoid problems with file names).
+ *
+ *     4.  Create a .cf file with the name given by MacroFile.  See
+ *        existing .cf files for examples of what to put there.
+ */
+
+#define MacroIncludeFile <vaxbsd.cf>
+#define MacroFile vaxbsd.cf
+#undef vax
+#define VaxArchitecture
+
+
+#ifndef MacroIncludeFile
+/**/# WARNING:  Imake.tmpl not configured; guessing at definitions!!!
+/**/# This might mean that BOOTSTRAPCFLAGS wasn't set when building imake.
+#define MacroIncludeFile <generic.cf>
+#define MacroFile generic.cf
+#endif
+
+/*****************************************************************************
+ *                                                                           *
+ *                       DO NOT MODIFY BELOW THIS LINE                       *
+ *                                                                           *
+ *****************************************************************************/
+
+
+/**/###########################################################################
+/**/# platform-specific configuration parameters - edit MacroFile to change
+#include MacroIncludeFile
+
+/**/###########################################################################
+/**/# site-specific configuration parameters - edit site.def to change
+#include <site.def>
+
+/*
+ * defaults for various generic parameters; set in site.def if needed
+ */
+
+#ifndef SystemV
+#ifdef SYSV
+#define SystemV                        YES     /* need system 5 style */
+#else
+#define SystemV                        NO      /* bsd */
+#endif
+#endif
+#ifndef OSMajorVersion
+#define OSMajorVersion          0
+#endif
+#ifndef OSMinorVersion
+#define OSMinorVersion          0
+#endif
+#ifndef UnalignedReferencesAllowed
+#define UnalignedReferencesAllowed NO  /* if arbitrary deref is okay */
+#endif
+#ifndef ExecableScripts
+#ifdef SYSV
+#define ExecableScripts                NO
+#else
+#define ExecableScripts                YES     /* kernel exec() can handle #! */
+#endif
+#endif
+
+#ifndef BourneShell                    /* to force shell in makefile */
+#define BourneShell            /bin/sh
+#endif
+#ifndef ConstructMFLAGS
+#if SystemV
+#define ConstructMFLAGS                YES     /* build MFLAGS from MAKEFLAGS */
+#else
+#define ConstructMFLAGS                NO      /* build MFLAGS from MAKEFLAGS */
+#endif
+#endif
+
+#ifndef HasLargeTmp
+#define HasLargeTmp            NO      /* be paranoid */
+#endif
+#ifndef HasSockets
+#if SystemV
+#define HasSockets             NO      /* not yet... */
+#else
+#define HasSockets             YES     /* bsd does have them */
+#endif
+#endif
+#ifndef HasVFork
+#if SystemV
+#define HasVFork               NO      /* not yet... */
+#else
+#define HasVFork               YES
+#endif
+#endif
+#ifndef HasPutenv
+#define HasPutenv              NO      /* assume not */
+#endif
+#ifndef HasVoidSignalReturn
+#if SystemV
+#define HasVoidSignalReturn    YES
+#else
+#define HasVoidSignalReturn    NO      /* may or may not be true */
+#endif
+#endif
+#ifndef HasBsearch
+#if SystemV
+#define HasBsearch             YES
+#else
+#define HasBsearch             NO      /* stupid systems */
+#endif
+#endif
+#ifndef HasSaberC
+#define HasSaberC              NO      /* for people unclear on the concept */
+#endif
+#ifndef HasFortran
+#define HasFortran             NO
+#endif
+#ifndef HasNdbm
+#define HasNdbm                        NO
+#endif
+#ifndef HasDESLibrary
+#define HasDESLibrary          NO      /* if you have any DES library */
+#endif
+#ifndef NeedFunctionPrototypes
+#define NeedFunctionPrototypes NO
+#endif
+#ifndef NeedWidePrototypes
+#define NeedWidePrototypes     YES     /* mix and match ANSI-C, non-ANSI */
+#endif
+
+#ifndef HasSunOSSharedLibraries
+#define HasSunOSSharedLibraries NO
+#endif
+
+#ifndef SharedCodeDef
+#if HasSunOSSharedLibraries
+#define SharedCodeDef -DSHAREDCODE
+#else
+#define SharedCodeDef /**/
+#endif
+#endif
+#ifndef SharedLibraryDef
+#if HasSunOSSharedLibraries
+#define SharedLibraryDef -DSUNSHLIB    /* eventually will be SVR4SHLIB... */
+#ifndef HasSharedLibraries
+#define HasSharedLibraries YES
+#endif
+#else
+#define SharedLibraryDef /**/
+#ifndef HasSharedLibraries
+#define HasSharedLibraries NO
+#endif
+#endif
+#else
+#ifndef HasSharedLibraries
+#define HasSharedLibraries NO
+#endif
+#endif
+
+#ifndef StripInstalledPrograms
+#define StripInstalledPrograms NO      /* leave symbol table just in case */
+#endif
+
+#ifndef DestDir
+#define DestDir /* as nothing */
+#endif
+#ifndef UsrLibDir                      /* if changed under SunOS with shared */
+#define UsrLibDir $(DESTDIR)/usr/lib   /* libs, then need to run ldconfig */
+#endif                                 /* as root */
+#ifndef IncRoot
+#define IncRoot $(DESTDIR)/usr/include
+#endif
+#ifndef UNCOMPRESSPATH
+#define UNCOMPRESSPATH /usr/ucb/uncompress
+#endif
+#ifndef OptimizedCDebugFlags
+#define OptimizedCDebugFlags -O
+#endif
+#ifndef DebuggableCDebugFlags
+#define DebuggableCDebugFlags -g
+#endif
+#ifndef NoOpCDebugFlags
+#define NoOpCDebugFlags /* as nothing */
+#endif
+#ifndef DefaultCDebugFlags
+#define DefaultCDebugFlags OptimizedCDebugFlags
+#endif
+#ifndef LibraryCDebugFlags
+#define LibraryCDebugFlags OptimizedCDebugFlags
+#endif
+#ifndef DefaultCCOptions
+#define DefaultCCOptions /* as nothing: this is for floating point, etc. */
+#endif
+#ifndef LibraryCCOptions
+#define LibraryCCOptions DefaultCCOptions
+#endif
+#ifndef ServerCCOptions
+#define ServerCCOptions DefaultCCOptions
+#endif
+#ifndef PexCDebugFlags
+#define PexCDebugFlags -g
+#endif
+#ifndef InstPgmFlags
+#define InstPgmFlags
+#endif
+#ifndef InstScrFlags
+#define InstScrFlags
+#endif
+#ifndef InstBinFlags
+#define InstBinFlags -m 0755
+#endif
+#ifndef InstUidFlags
+#define InstUidFlags -m 4755
+#endif
+#ifndef InstLibFlags
+#define InstLibFlags -m 0664
+#endif
+#ifndef InstIncFlags
+#define InstIncFlags -m 0444
+#endif
+#ifndef InstManFlags
+#define InstManFlags -m 0444
+#endif
+#ifndef InstDatFlags
+#define InstDatFlags -m 0444
+#endif
+#ifndef InstKmemFlags
+#define InstKmemFlags InstUidFlags    /* put -g kmem -m 2755 in site.def... */
+#endif
+#ifndef ArCmd
+#if HasLargeTmp
+#define ArCmd ar cq    /* use /tmp for temp files */
+#else
+#define ArCmd ar clq   /* use local dir for temp files */
+#endif
+#endif
+#ifndef BootstrapCFlags
+#define BootstrapCFlags /**/
+#endif
+#ifndef CcCmd
+#define CcCmd cc
+#endif
+#ifndef HasGcc
+#define HasGcc NO
+#endif
+#ifndef ServerCcCmd
+#define ServerCcCmd CcCmd
+#endif
+#ifndef LibraryCcCmd
+#define LibraryCcCmd CcCmd
+#endif
+#if HasFortran
+#ifndef FortranCmd                     /* for xgks */
+#define FortranCmd f77
+#endif
+#ifndef FortranFlags
+#define FortranFlags /**/
+#endif
+#ifndef FortranDebugFlags
+#define FortranDebugFlags /**/         /* for -O or -g */
+#endif
+#endif
+#ifndef AsCmd
+#define AsCmd as
+#endif
+#ifndef CompressCmd
+#define CompressCmd compress
+#endif
+#ifndef CppCmd
+#define CppCmd /lib/cpp
+#endif
+#ifndef PreProcessCmd
+#define PreProcessCmd CcCmd -E
+#endif
+#ifndef InstallCmd
+#if SystemV
+#define InstallCmd $(SCRIPTSRC)/bsdinst.sh     /* hack should be in project */
+#else
+#define InstallCmd install
+#endif
+#endif
+#ifndef LdCmd
+#define LdCmd ld
+#endif
+#ifndef LintCmd
+#define LintCmd lint
+#endif
+#ifndef LintLibFlag
+#if SystemV
+#define LintLibFlag -o
+#else
+#define LintLibFlag -C
+#endif
+#endif
+#ifndef LintOpts
+#if SystemV
+#define LintOpts -ax
+#else
+#define LintOpts -axz
+#endif
+#endif
+#ifndef CpCmd
+#define CpCmd cp -p
+#endif
+#ifndef LnCmd
+#if SystemV
+#define LnCmd ln /* or even cp */
+#else
+#define LnCmd ln -s
+#endif
+#endif
+#ifndef MakeCmd
+#define MakeCmd make
+#endif
+#ifndef MvCmd
+#define MvCmd mv
+#endif
+#if !defined(RanlibCmd) && !SystemV
+#define RanlibCmd ranlib
+#endif
+#ifndef RanlibInstFlags
+#define RanlibInstFlags /**/
+#endif
+#ifndef RmCmd
+#define RmCmd rm -f
+#endif
+#ifndef StandardCppDefines
+#if SystemV
+#define StandardCppDefines -DSYSV
+#else
+#define StandardCppDefines /**/
+#endif
+#endif
+#ifndef StandardIncludes
+#define StandardIncludes /**/                  /* for platform-specifics */
+#endif
+#ifndef StandardDefines
+#if SystemV
+#define StandardDefines -DSYSV
+#else
+#define StandardDefines /**/
+#endif
+#endif
+#ifndef SaberDefines
+#define SaberDefines /**/
+#endif
+#ifndef NdbmDefines
+#if HasNdbm
+#define NdbmDefines -DNDBM
+#else
+#define NdbmDefines /**/
+#endif
+#endif
+#ifndef ExtraLibraries
+#define ExtraLibraries /**/
+#endif
+#ifndef ExtraLoadFlags
+#define ExtraLoadFlags /**/
+#endif
+#ifndef LdCombineFlags
+#define LdCombineFlags -X -r
+#endif
+#ifndef LdLibLocations
+#define LdLibLocations /**/
+#endif
+#ifndef CompatibilityFlags
+#define CompatibilityFlags /**/
+#endif
+#ifndef TagsCmd
+#define TagsCmd ctags
+#endif
+#ifndef EtagsCmd
+#define EtagsCmd etags
+#endif
+#ifndef LoaderLibPrefix
+#define LoaderLibPrefix /**/                   /* cray does -l libX11.a */
+#endif
+#ifndef TOPDIR
+#define TOPDIR .
+#endif
+#ifndef CURDIR
+#define CURDIR .
+#endif
+#ifndef FilesToClean
+#define FilesToClean *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut 
+#endif
+#ifndef STDCTopIncludes
+#define STDCTopIncludes /**/  
+#endif
+#ifndef MakeDependFlags
+#define MakeDependFlags /**/  
+#endif
+
+#ifdef SourceTop
+           SRCDIR = SourceTop/CURDIR/
+            VPATH = SourceTop/CURDIR
+           SRCTOP = SourceTop
+       SRCINCLUDE = -I/**/SourceTop/CURDIR
+#endif
+            SHELL = BourneShell
+
+              TOP = TOPDIR
+      CURRENT_DIR = CURDIR
+
+               AR = ArCmd
+  BOOTSTRAPCFLAGS = BootstrapCFlags    /* set if cpp doesn't have uniq sym */
+               CC = CcCmd
+#if HasFortran
+               FC = FortranCmd
+      FDEBUGFLAGS = FortranDebugFlags
+          FCFLAGS = FortranFlags $(FDEBUGFLAGS)
+#endif
+         COMPRESS = CompressCmd
+              CPP = CppCmd $(STD_CPP_DEFINES)          /* simple filters */
+    PREPROCESSCMD = PreProcessCmd $(STD_CPP_DEFINES)   /* prefered; mdep */
+          INSTALL = InstallCmd
+               LD = LdCmd
+      LDLOCATIONS = LdLibLocations
+             LINT = LintCmd
+      LINTLIBFLAG = LintLibFlag
+         LINTOPTS = LintOpts
+               LN = LnCmd
+             MAKE = MakeCmd
+               MV = MvCmd
+               CP = CpCmd
+#ifdef RanlibCmd
+           RANLIB = RanlibCmd
+#else
+           RANLIB = \:
+#endif
+  RANLIBINSTFLAGS = RanlibInstFlags
+               RM = RmCmd
+     STD_INCLUDES = StandardIncludes
+  STD_CPP_DEFINES = StandardCppDefines
+      STD_DEFINES = StandardDefines
+    SABER_DEFINES = SaberDefines
+ EXTRA_LOAD_FLAGS = ExtraLoadFlags
+  EXTRA_LIBRARIES = ExtraLibraries
+             TAGS = TagsCmd
+            ETAGS = EtagsCmd
+STDC_TOP_INCLUDES = STDCTopIncludes
+
+#if ConstructMFLAGS
+           MFLAGS = -$(MAKEFLAGS)
+#endif
+#if HasSharedLibraries
+    SHAREDCODEDEF = SharedCodeDef
+         SHLIBDEF = SharedLibraryDef
+#endif
+#if !HasVoidSignalReturn
+   SIGNAL_DEFINES = -DSIGNALRETURNSINT
+#endif
+#if StripInstalledPrograms
+     INSTPGMFLAGS = InstPgmFlags -s    /* install flags for stripping */
+#else
+     INSTPGMFLAGS = InstPgmFlags       /* install flags without stripping */
+#endif
+     INSTSCRFLAGS = InstScrFlags       /* install flags without stripping */
+     INSTBINFLAGS = InstBinFlags       /* install flags for programs */
+     INSTUIDFLAGS = InstUidFlags       /* install flags for setuid programs */
+     INSTLIBFLAGS = InstLibFlags       /* install flags for libraries */
+     INSTINCFLAGS = InstIncFlags       /* install flags for headers */
+     INSTMANFLAGS = InstManFlags       /* install flags for man pages */
+     INSTDATFLAGS = InstDatFlags       /* install flags for data files */
+    INSTKMEMFLAGS = InstKmemFlags      /* install flags for /dev/kmem progs */
+
+          DESTDIR = DestDir            /* root of install */
+#ifdef UseInstalled
+     TOP_INCLUDES = -I$(INCROOT)       /* def: for alternative /usr/include */
+#else
+     TOP_INCLUDES = -I$(TOP)           /* def: for builds within tree */
+#endif
+      CDEBUGFLAGS = DefaultCDebugFlags
+        CCOPTIONS = DefaultCCOptions   /* to distinguish from param flags */
+      COMPATFLAGS = CompatibilityFlags
+/*
+ * STD_INCLUDES contains system-specific includes
+ * TOP_INCLUDES specifies how to get to /usr/include or its build substitute
+ * EXTRA_INCLUDES contains project-specific includes set in project incfiles
+ * INCLUDES contains client-specific includes set in Imakefile
+ */
+      ALLINCLUDES = $(INCLUDES) $(STD_INCLUDES) $(TOP_INCLUDES) $(EXTRA_INCLUDES) 
+       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
+           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LDLOCATIONS)
+   LDCOMBINEFLAGS = LdCombineFlags
+          MDFLAGS = MakeDependFlags
+
+        MACROFILE = MacroFile
+           RM_CMD = $(RM) FilesToClean
+
+    IMAKE_DEFINES = /* leave blank, for command line use only */
+#ifdef UseInstalled
+         IRULESRC = $(CONFIGDIR)       /* used in rules file */
+        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+#else
+         IRULESRC = $(CONFIGSRC)
+#ifdef UseImakeInstalled
+        IMAKE_CMD = $(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES)
+#else
+        IMAKE_CMD = $(NEWTOP)$(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES)
+#endif
+#endif
+     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+                       $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+                       $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+
+/*
+ * get project-specific configuration and rules
+ */
+
+#include <Project.tmpl>
+
+
+
+#include <Imake.rules>
+
+/**/###########################################################################
+/**/# start of Imakefile
+#include INCLUDE_IMAKEFILE
+
+/**/###########################################################################
+/**/# common rules for all Makefiles - do not edit
+/*
+ * These need to be here so that rules in Imakefile occur first;  the blank
+ * all is to make sure that an empty Imakefile doesn't default to make clean.
+ */
+emptyrule::
+
+CleanTarget()
+
+#ifndef IHaveSpecialMakefileTarget
+MakefileTarget()
+#endif
+
+TagsTarget()
+#ifdef MakefileAdditions
+MakefileAdditions()
+#endif
+
+#if HasSaberC
+saber:
+       /**/#load $(ALLDEFINES) $(SABER_DEFINES) $(SRCS)
+       /**/#setopt load_flags $(ALLDEFINES) $(SABER_DEFINES)
+
+osaber:
+       /**/#load $(ALLDEFINES) $(OBJS)
+#endif
+
+
+#ifdef IHaveSubdirs
+/**/###########################################################################
+/**/# rules for building in SUBDIRS - do not edit
+
+InstallSubdirs($(SUBDIRS))
+InstallManSubdirs($(SUBDIRS))
+CleanSubdirs($(SUBDIRS))
+TagSubdirs($(SUBDIRS))
+MakefileSubdirs($(SUBDIRS))
+IncludesSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+
+#else
+/**/###########################################################################
+/**/# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+       @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+       @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+#endif /* if subdirectory rules are needed */
+
+/**/###########################################################################
+/**/# dependencies generated by makedepend
diff --git a/src/config/Makefile.ini b/src/config/Makefile.ini
new file mode 100644 (file)
index 0000000..4c46c67
--- /dev/null
@@ -0,0 +1,51 @@
+#
+#   WARNING    WARNING    WARNING    WARNING    WARNING    WARNING    WARNING
+#
+# This is NOT an automatically generated Makefile!  It is hand-crafted as a 
+# bootstrap, may need editing for your system.  The BOOTSTRAPCFLAGS variable
+# may be given at the top of the build tree for systems that do not define
+# any machine-specific preprocessor symbols.
+#
+
+BOOTSTRAPCFLAGS = 
+    CDEBUGFLAGS = -O
+         CFLAGS = $(BOOTSTRAPCFLAGS) $(CDEBUGFLAGS)
+          SHELL = /bin/sh
+             RM = rm -f
+           MAKE = make
+         RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
+                       tags TAGS make.log
+          NPROC = 1
+
+imake::
+       @echo "making imake with BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)"
+
+imake:: ccimake imake.c
+       $(CC) -o imake $(CFLAGS) imake.c `./ccimake`
+
+ccimake: ccimake.c
+       $(CC) -o ccimake $(CFLAGS) ccimake.c
+
+relink:
+       $(RM) imake
+       $(MAKE) $(MFLAGS) imake
+
+clean:
+       $(RM) ccimake imake
+       $(RM_CMD) \#*
+
+depend:
+
+
+# for manual use
+
+Makefile: imake
+       imake -DNEWTOP=../
+
+tags:
+
+install:
+
+install.man:
+
+Makefiles:
diff --git a/src/config/ccimake b/src/config/ccimake
new file mode 100644 (file)
index 0000000..9146bfc
Binary files /dev/null and b/src/config/ccimake differ
diff --git a/src/config/ccimake.c b/src/config/ccimake.c
new file mode 100644 (file)
index 0000000..6f13d64
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * $XConsortium: ccimake.c,v 1.12 89/10/16 12:09:23 jim Exp $
+ * 
+ * Warning:  This file must be kept as simple as posible so that it can 
+ * compile without any special flags on all systems.  Do not touch it unless
+ * you *really* know what you're doing.  Make changes in imakemdep.h, not here.
+ */
+
+#define CCIMAKE                        /* only get imake_ccflags definitions */
+#include "imakemdep.h"         /* things to set when porting imake */
+
+#ifndef imake_ccflags
+#define imake_ccflags "-O"
+#endif
+
+main()
+{
+       write(1, imake_ccflags, sizeof(imake_ccflags) - 1);
+       exit(0);
+}
+
diff --git a/src/config/doc/paper.ms b/src/config/doc/paper.ms
new file mode 100644 (file)
index 0000000..ea0c7af
--- /dev/null
@@ -0,0 +1,623 @@
+.\" macros ripped off from Rosenthal and Lemke's paper
+.\"    refer -e -n -p vis.refs -s vis.nr | eqn | pic | psroff -ms
+.\.EQ
+.\delim $$
+.\.EN
+.ds CH
+.de Ip
+.IP \(bu 3
+..
+.de Qp
+.nr PS -2
+.nr VS -2
+.QP
+..
+.de Qe
+.nr PS +2
+.nr VS +2
+..
+.de RQ
+.br
+.di
+.nr NF 0
+.if \\n(dn-\\n(.t .nr NF 1
+.if \\n(TC .nr NF 1
+.if !\\n(NF .if \\n(TB .nr TB 0
+.nf
+.rs
+.nr TC 5
+.in 0
+.ls 1
+.if !\\n(TB \{\
+.      ev
+.      br
+.      ev 2
+.      KK
+.\}
+.ls
+.ce 0
+.if !\\n(TB .rm KK
+.if \\n(TB .da KJ
+.if \\n(TB \!.KD \\n(dn
+.if \\n(TB .KK
+.if \\n(TB .di
+.nr TC \\n(TB
+.if \\n(KN .fi
+.in
+.ev
+..
+.\"    These macros should select a typewriter font if you have one.
+.de LS
+.LP
+.KS
+.LD
+.ft L
+.ta .6i 1.2i 1.8i 2.4i 3i 3.6i 4.2i
+..
+.de LE
+.ft P
+.DE
+.KE
+..
+.de Ls
+.nr PS -4
+.nr VS -6
+.LS
+..
+.de Le
+.LE
+.nr PS +4
+.nr VS +6
+.LP
+..
+.nr PO 1.25i
+.TL
+Configuration Management in the X Window System
+.AU
+Jim Fulton
+.AI
+X Consortium
+MIT Laboratory for Computer Science
+545 Technology Square
+Cambridge, MA  02139
+.AB
+The X Window System\(dg has become an industry standard for network window
+technology in part because of the
+portability of the sample implementation from MIT.  Although many systems are
+designed to reuse source code across different platforms, X is 
+unusual in its
+portability across software build environments.  This paper describes several
+mechanisms used in the MIT release of the X Window System to obtain such
+flexibility, and summarizes some of the lessons learned in trying to support
+X on a number of different platforms.
+.AE
+.NH 1
+Introduction
+.LP
+The X Window System\f(d is a portable, network transparent window system 
+originally developed at MIT.  It is intended for use on raster display
+devices ranging from simple monochrome frame buffers to deep,
+true color graphics processors.  Because of its client/server architecture,
+the non-proprietary nature of its background, and the portability of the
+sample implementation from MIT, the X Window System has rapidly grown to 
+become an industry standard.  This portability is the result of several
+factors: a system architecture that isolates operating system and
+device-specifics at several levels; a slow, but machine-independent, graphics
+package that may be used for an initial port and to handle cases that
+the underlying graphics hardware does not support; and the use of a few,
+higher-level tools for managing the build process itself.
+.FS
+\(dg X Window System is a trademark of MIT; DECnet is a trademark of 
+Digital Equipment Corporation; UNIX is a registered trademark of AT&T.
+.sp
+Copyright \(co\ 1989 by the Massachusetts Institute of Technology.
+.sp
+Permission to use, copy, modify, and distribute this
+document for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+the software described herein for any purpose.  It is provided "as is"
+without express or implied warranty.
+.FE
+.NH 2
+Summary of X Window System Architecture
+.LP
+The X Window System is the result of a combined effort between MIT Project 
+Athena and the MIT Laboratory for Computer Science.  Since its inception 
+in 1984, X has been redesigned three times, culminating in Version 11 which
+has since become an industry standard (see [Scheifler 88] for a more detailed
+history).  X uses the client/server model of 
+limiting interactions with the physical display hardware to a single program
+(the \fIserver\fP) and providing a way for applications (the \fIclients\fP)
+to send messages (known as \fIrequests\fP) to the server to ask it to perform
+graphics operations on the client's behalf.  These messages are sent along
+a reliable, sequenced, duplex byte stream using whatever underlying transport
+mechanisms the operating system provides.  If connections 
+using network virtual circuits (such as TCP/IP or DECnet) are supported,
+clients may be run
+on any remote machine (including ones of differing architectures) while still
+displaying on the local server.
+.LP
+The details of how the client establishes and maintains connections with the
+server are typically hidden in a subroutine package (known as a \fIlanguage
+binding\fP) which provides a function call interface to the X protocol.  Higher
+level toolkits and user interface management systems are then built on top of 
+the binding library, as shown in Figure 1 for the C programming language.
+Since only the underlying
+operating system networking interface of the binding (shown in \fIitalics\fP)
+need be changed when 
+porting to a new platform, well-written applications can simply be recompiled.
+.sp 1
+.DS C
+.TS
+box tab (/) ;
+cB    s    s    s 
+_     lB   lB   lB 
+cBe | le   le   le
+_     s    lB   lB
+cB    s |  lB   lB
+_     s    s    lB
+cB    s    s |  lB
+_     s    s    s
+cB    s    s    s
+_     lB   lB   _
+cI    s    s    s .
+application///
+///
+UIMS///
+///
+widgets///
+///
+toolkit///
+///
+Xlib///
+///
+os
+.TE
+.sp 1
+\fBFigure 1:\fP  architecture of a typical C language client program
+.DE
+.sp 1
+.LP
+The server takes care of clipping of graphics output and routing keyboard and
+pointer input
+to the appropriate applications.  Unlike many previous window systems, 
+moving and resizing of windows are handled outside the server
+by special X applications called
+\fIwindow managers\fP.  Different user interface policies can be selected 
+simply by running a different window manager.
+.LP
+The MIT sample server can be divided into three sections: a device-independent
+layer called \fIdiX\fP for managing the various shared resources (windows, 
+pixmaps, colormaps, fonts, cursors, etc.), an operating system layer called
+\fIos\fP for performing machine-specific operations (managing
+connections to clients, dealing with timers, reading color and font name 
+databases, and memory allocation), and a device-specific
+layer called \fIddX\fP for drawing on the display and getting input from the 
+keyboard and pointer.  Only the \fIos\fP and \fIddX\fP portions of the server
+need to be changed when porting X to a new device.
+.LP
+Although this is still
+a substantial amount of work, a collection of pixel-oriented drawing packages
+that only require device-specific routines (refered to as \fIspans\fP) 
+to read and write rows of pixels are provided
+to allow initial ports of X to be done in a very short time.  A server
+developer can then concentrate on replacing those operations that can be
+implemented more efficiently by the hardware.  Figure 2 shows the relative
+layering of the various packages within the sample server from MIT.  The
+\fImi\fP library provides highly portable, machine-independent routines that
+may be used on a wide variety of displays.  The \fImfb\fP and \fIcfb\fP 
+libraries contain versions of the graphics routines for monochrome and
+color frame buffers, respectively.  Finally, the \fIsnf\fP library can be
+used to read fonts stored in Server Natural Format.  Typically, only the 
+sections printed in \fIitalics\fP need be changed when moving to a new 
+platform.
+.sp 1
+.DS C
+.TS
+allbox tab (/) ;
+cB s s s s
+cI s s s cI
+cB cB cB cB cB
+cI s s s cB .
+diX
+ddX/os
+mi/mfb/cfb/snf/\^
+spans/\^
+.TE
+.sp 1
+\fBFigure 2:\fP  architecture of the MIT sample server
+.DE
+.sp 1
+.LP
+By splitting out the device-specific code (by separating clients from servers
+and \fIdiX\fP from \fIddX\fP) and then providing portable utility libraries 
+(\fImi\fP, \fImfb\fP, \fIcfb\fP, and \fIcfb\fP) that may be used to 
+implement the non-portable portions
+of the system, much of the code can be reused across many platforms, ranging
+from personal computers to supercomputers.
+.NH 1
+Configuring the Software Build Process
+.LP
+In practice, porting X to a new platform typically requires adding support 
+in the operating system-specific networking routines and mixing together
+pieces of machine-independent and device-specific code to access the
+input and output hardware.  Although this approach is very portable, it
+increases the complexity of the build process as different implementations 
+require different subsets.  One solution is to litter the 
+source code with machine-specific compiler directives controlling which 
+modules areas get built on a given platform.  However, this rapidly leads to 
+sources that are hard to understand and even harder to maintain.
+.LP
+A more serious problem with this approach is that it requires 
+configuration information to be replicated in almost every module.  In
+addition to being highly prone to error, modifying or adding a new 
+configuration becomes extremely difficult.  In contrast, collecting the 
+various options and parameters in a single location makes it possible for
+someone to reconfigure the system without having to 
+understand how all of the modules fit together.
+.LP
+Although sophisticated software management systems are very useful, they 
+tend to be found only on specific platforms.  Since the configuration system 
+must be working before a build can begin, the MIT releases try to adhere to
+the following principles:
+.RS .5in
+.Ip
+Use existing tools to do the build (e.g. \fImake\fP) where possible; writing
+complicated new tools simply adds to the amount of software that has to be
+bootstrapped.
+.Ip
+Keep it simple.  Every platform has a different set of extensions and bugs.
+Plan for the least common denominator by only using 
+the core features of known tools; don't rely on vendor-specific features.
+.Ip
+Providing sample implementations of simple tools that are not available on
+all platforms (e.g. a BSD-compatible \fIinstall\fP script for System V) is
+very useful.
+.Ip
+Machine-dependencies should be centralized to make reconfiguration easy.
+.Ip
+Site-wide options (e.g. default parameters such as directory names, 
+file permissions, and enabling particular features) should be stored in
+only one location.
+.Ip
+Rebuilding within the source tree without losing any of the configuration
+information must be simple.
+.Ip
+It should be possible to configure external software without requiring 
+access to the source tree.
+.RE
+.LP
+One approach is to add certain programming constructs (particularly 
+conditionals and iterators) to the utility used to actually build the 
+software (usually \fImake\fP; see [Lord 88]).  Although this an attractive
+solution, limits on time and personnel made implementing and maintaining
+such a system impractical for X.
+.LP
+The MIT releases of X employ a less ambitious approach that uses existing tools
+(particularly \fImake\fP and \fIcpp\fP).  \fIMakefiles\fP
+are generated automatically by a small,
+very simple program named \fIimake\fP (written by Todd Brunhoff of Tektronix)
+that combines a template listing variables and rules
+that are common to all 
+\fIMakefiles\fP, a machine- and a site-specific configuration file,
+a set of rule functions written as \fIcpp\fP macros,
+and simple specifications of targets and sources called \fIImakefiles\fP.
+Since the descriptions of the inputs and outputs of the build are separated
+from the commands that implement them, machine dependencies such as the
+following can be controlled from a single location:
+.RS .5in
+.Ip
+Some versions of \fImake\fP require that the variable SHELL to be set to the
+name of the shell that should be used to execute \fImake\fP commands.
+.Ip
+The names of various special \fImake\fP variables (e.g. MFLAGS vs. MAKEFLAGS) 
+differ between versions.
+.Ip
+Special directives to control interaction with source code maintenance systems
+are required by some versions of \fImake\fP.
+.Ip
+Rules for building targets (e.g. \fIranlib\fP,
+lint options, executable shell scripts, selecting alternate compilers)
+differ among platforms.
+.Ip
+Some systems require special compiler options (e.g. increased internal
+table sizes, floating point options) for even simple programs.
+.Ip
+Some systems require extra libraries when linking programs.
+.Ip
+Not all systems need to compile all sources.
+.Ip
+Configuration parameters may need to be passed to some (such as -DDNETCONN
+to compile in DECnet support) or all (such as -DSYSV to select System V code)
+programs as preprocessor symbols.
+.Ip
+Almost all systems organize header files differently, making
+static dependencies in \fIMakefiles\fP impossible to generate.
+.RE
+.LP
+By using the C preprocessor, \fIimake\fP provides a familiar set of interfaces
+to conditionals, macros, and symbolic constants.  Common operations, such as
+compiling programs, creating libraries,        creating shell scripts, and
+managing subdirectories, can be described in a concise, simple way.  
+Figure 3 shows the \fIImakefile\fP used to build a manual page browser
+named \fIxman\fP (written by Chris Peterson program of the MIT X Consortium,
+based on an implementation for X10 by Barry Shein):
+.sp 1
+.KF
+.RS 1in
+.nf
+.ft L
+DEFINES =  -DHELPFILE=\e"$(LIBDIR)$(PATHSEP)xman.help\e"
+LOCAL_LIBRARIES =  $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
+SRCS =  ScrollByL.c handler.c man.c pages.c buttons.c help.c menu.c search.c \e
+        globals.c main.c misc.c tkfuncs.c
+OBJS =  ScrollByL.o handler.o man.o pages.o buttons.o help.o menu.o search.o \e
+        globals.o main.o misc.o tkfuncs.o
+INCLUDES =  -I$(TOOLKITSRC) -I$(TOP)
+
+ComplexProgramTarget (xman)
+InstallNonExec (xman.help, $(LIBDIR))
+
+.ft P
+.fi
+.RE
+.DS C
+.sp 1
+\fBFigure 3:\fP  \fIImakefile\fP used by a typical client program
+.DE
+.KE
+.sp 1
+.LP
+This application requires the name of the directory in which its help file is
+installed (which is a configuration parameter), several libraries, and 
+various X header files.  The macro
+\fIComplexProgramTarget\fP generates the appropriate rules to build
+the program, install it, compute dependencies, and remove old versions of
+the program and its object files.  The \fIInstallNonExec\fP macro generates
+rules to install \fIxman\fP's help file with appropriate permissions.
+.NH 1
+Generating Makefiles
+.LP
+Although \fIimake\fP is a fairly powerful tool, it is a very simple program.
+All of the real work is performed by the template, rule, and configuration
+files.  The version currently used at MIT (which differs somewhat from the 
+version supplied in the last release of X)
+uses symbolic constants for all configuration 
+parameters so that they may be overridden or used by other parameters.
+General build issues (such as the command to execute to run the compiler) 
+are isolated from X issues (such as where should application default files be
+installed) by splitting the template as shown in Figure 4.
+.KF
+.sp 1
+.DS C
+.TS
+box tab (%) ;
+l s s
+l   _   l
+l | l | l
+l   _   l
+l   _   l
+l | l | l
+l   _   l
+l   _   l
+l | l | l
+l   _   l
+l   _   l
+l | l | l
+l   _   l
+l   _   l
+l | l | l
+l   _   l .
+Imake.tmpl
+ %
+%#include "\fImachine\fP.cf"%
+ %
+ %
+%#include "site.def"%
+ %
+ %
+%#include "Project.tmpl"%
+ %
+ %
+%#include "Imake.rules"%
+ %
+ %
+%#include "./Imakefile"%
+ %
+.TE
+.sp 1
+\fBFigure 4:\fP  structure of \fIimake\fP template used by X
+.DE
+.sp 1
+.KE
+.LP
+This template instructs \fIimake\fP to perform the following steps when
+creating a \fIMakefile\fP:
+.RS .5in
+.IP 1.
+Using conditionals, \fIImake.tmpl\fP determines the machine for which the
+build is being configured and includes a machine-specific configuration file 
+(usually named \fImachine\fP.cf).  Using the C preprocessor to define various
+symbols, this configuration file sets the major and minor version 
+numbers of the operating system, the names of any servers 
+to build, and any special programs (such as alternate compilers)
+or options (usually to increase internal table sizes) that
+need to be used during the build.  Defaults are provided for
+all parameters, so .cf files need only describe how this particular
+platform differs from ``generic'' UNIX System V or BSD UNIX.
+Unlike previous versions of the \fIimake\fP configuration files,
+when new parameters are added, only the systems which are
+effected by them need to be updated.
+.IP 2.
+Next, a site-specific file (named \fIsite.def\fP) is included so
+that parameters from the .cf files may be overridden or
+defaults for other options provided.  This is typically used
+by a site administrator to set the names of the various
+directories into which the software should be installed.
+Again, all of the standard \fIcpp\fP constructs may be used.
+.IP 3.
+A project-specific file (named \fIProject.tmpl\fP) is 
+included to set various parameters used by the particular
+software package being configured.  By separating the 
+project parameters (such as directories, options, etc.)
+from build parameters (such as compilers, utilities, etc.),
+the master template and the .cf files can be shared among various development
+efforts.  
+.IP 4.
+A file containing the set of \fIcpp\fP rules (named \fIImake.rules\fP)
+is included.  This is where the various macro functions used
+in the master template and the per-directory description
+files (named \fIImakefile\fP) are defined.  These rules typically
+make very heavy use of the \fImake\fP variables defined in
+\fIImake.tmpl\fP so that a build's configuration may be changed without
+having to edit this file.
+.IP 5.
+The \fIImakefile\fP describing the input files and output targets 
+for the current directory is included.  This file is supplied
+by the programmer instead of a \fIMakefile\fP.  The functions that
+it invokes are translated by \fIcpp\fP into series of \fImake\fP 
+rules and targets.
+.IP 6.
+Finally, \fImake\fP rules for recreating the \fIMakefile\fP and managing
+subdirectories are appended, and the result is written out as the
+new \fIMakefile\fP.
+.RE
+.LP
+\fIImake\fP, along with a separate tool (named \fImakedepend\fP, also 
+written by
+Brunhoff) that generates \fIMakefile\fP dependencies
+between object files and the source files used to build them, allows
+properly configured \fIMakefiles\fP to be regenerated quickly and correctly.  
+By isolating the machine- and site-specifics from the programmer,
+\fIimake\fP is much like a well-developed text formatter: both allow 
+the writer to concentrate on the content, rather than the production, of a 
+document.
+.NH 1
+How X uses \fIimake\fP
+.LP
+Development of X at MIT is currently done on more than half a dozen 
+different platforms, each of which is running a different operating system.
+A common source pool is shared across those machines that support
+symbolic links and NFS by creating trees of links pointing
+back to the master sources (similar to the object trees of [Harrison 88]).
+Editing and source code control is done in the master sources and builds are 
+done in the link trees.  
+.LP
+.ne 4
+A full build is done by creating a fresh link tree and invoking a
+simple, stub top-level \fIMakefile\fP which:
+.RS .5in
+.IP 1.
+compiles \fIimake\fP.
+.IP 2.
+builds the real top-level \fIMakefile\fP.
+.IP 3.
+builds the rest of the \fIMakefiles\fP using the new top-level \fIMakefile\fP.
+.IP 4.
+removes any object files left over from the previous build.
+.IP 5.
+builds the header file tree, and
+computes and appends the list of dependencies between object files and sources
+to the appropriate \fIMakefiles\fP.
+.IP 6.
+and finally, compiles all of the sources.
+.RE
+.LP
+If the build completes successfully, programs, libraries, data files, and
+manual pages may then be installed.  By keeping object files out of the master
+source tree, backups and releases can be done easily and efficiently.  By
+substituting local copies of particular files for the appropriate links, 
+developers can work without disturbing others.
+.NH 1
+Limitations
+.LP
+Although the system described here is very useful, it isn't perfect.  
+Differences
+between utilities on various systems places a restriction on how well
+existing tools can be used.  One of the reasons why \fIimake\fP is a program
+instead of a trivial invocation of the C preprocessor is that some \fIcpp\fP's
+collapse tabs into spaces while others do not.  Since \fImake\fP uses
+tabs to separate commands from targets, \fIimake\fP must sometimes reformat
+the output from \fIcpp\fP so that a valid \fIMakefile\fP is generated.
+.LP
+Since \fIcpp\fP only provides global 
+scoping of symbolic constants, parameters
+are visible to the whole configuration system.  For larger projects, this
+approach will probably prove unwieldy both to the people trying to maintain 
+them and to the preprocessors that keep the entire symbol table in memory.
+.LP
+The macro facility provided by \fIcpp\fP is convenient because it is available
+on every platform and it is familar to most people.  However, a better
+language with real programming constructs might provide a better interface.
+The notions of describing one platform in terms of another and providing
+private configuration parameters map intriguingly well into the models used
+in object management systems.
+.NH 1
+Summary and Observations
+.LP
+The sample implementation of the X Window System from MIT takes advantage
+of a system architecture that goes to great lengths to isolate
+device-dependencies.  By selectively using portable versions of
+the device-specific functions, a developer moving X to a new platform can
+quickly get an initial port up and running very quickly.
+.LP
+To manage the various combinations of modules and to cope with the 
+differing requirements of every platform and site, X uses a
+utility named \fIimake\fP
+to separate the description of sources and targets from the
+details of how the software is actually built.  Using as few external
+tools as possible, this mechanism allows support for new platforms to be
+added with relatively little effort.
+.LP
+Although the approaches taken by MIT will not work for everyone, several of
+its experiences may be useful in other projects:
+.RS .5in
+.Ip
+Even if portability isn't a goal now, it probably will become one sooner
+than expected.
+.Ip
+Just as in other areas, it frequently pays to periodically stand back 
+from a problem and see whether or not a simple tool will help.  With
+luck and the right amount of abstracting it may even solve several
+problems at once.  
+.Ip
+Be wary of anything that requires manual intervention.
+.Ip
+And finally, there is no such thing as portable software, only software that
+has been ported.
+.RE
+.NH 1
+References
+.LP
+.IP "\[Harrison 88\]"
+.br
+``Rtools: Tools for Software Management in a Distributed Computing
+Environment,'' Helen E. Harrison, Stephen P. Schaefer, Terry S. Yoo,
+\fIProceedings of the Usenix Association Summer Conference\fP, 
+June 1988, 85-94.
+.IP "\[Lord 88\]"
+.br
+``Tools and Policies for the Hierarchical Management of Source Code 
+Development,'' Thomas Lord, \fIProceedings of the Usenix Association
+Summer Conference\fP, June 1988, 95-106.
+.IP "\[Scheifler 88\]"
+.br
+\fIX Window System: C Library and Protocol Reference\fP, Robert Scheifler, 
+James Gettys, and Ron Newman, Digital Press, Bedford, MA, 1988.
+
+
+.\
+.\XXX - Xos.h:
+.\     o  12 character file names
+.\     o  isolate system calls
+.\     o  avoid tricky coding
+.\     o  index vs. strchr
+.\     o  bcopy
+.\     o  test on as wide a range of systems as possible
+.\
diff --git a/src/config/ibmLib.rules b/src/config/ibmLib.rules
new file mode 100644 (file)
index 0000000..26c22f1
--- /dev/null
@@ -0,0 +1,37 @@
+/* Rules to generate an AIX 3 shared library.  */
+
+/* Generate a null rule for libfoo.a so that "make libfoo.a" will work
+   on all systems to bring libfoo.a up to date (BSD systems would run
+   ranlib).  */
+
+#define        IBMSharedLibraryTarget(tdeps,libname,ldeps)                     @@\
+lib/**/libname.a::                                                     @@\
+libname.o: tdeps                                                       @@\
+       $(RM) libname.o                                                 @@\
+       ld -o libname.o lib/**/libname.a -H512 -T512 -bM\:SRE -bE\:$(SRCDIR)exports.libname ldeps -lc @@\
+       $(RM) shared/lib/**/libname.a                                   @@\
+       $(ARADD) shared/lib/**/libname.a libname.o                      @@\
+clean::                                                                        @@\
+       $(RM) lib/**/libname.a shared/lib/**/libname.a libname.o
+
+#define        RanlibLibraryTarget(libname,deps)                               @@\
+AllTarget(lib/**/libname.a)                                            @@\
+IBMSharedLibraryTarget(foo/**/libname,libname,deps)
+
+#define        AdditiveLibraryTarget(libname,objlist,deps)                     @@\
+AllTarget(lib/**/libname.a)                                            @@\
+AllTarget(libname.o)                                                   @@\
+AllTarget(foo/**/libname)                                              @@\
+DependTarget()                                                         @@\
+                                                                       @@\
+foo/**/libname: objlist                                                        @@\
+       $(ARADD) lib/**/libname.a objlist                               @@\
+       $(TOUCH) foo/**/libname                                         @@\
+IBMSharedLibraryTarget(lib/**/libname.a,libname,deps)                  @@\
+clean::                                                                        @@\
+       $(RM_CMD) foo/**/libname
+
+
+#define        SharedLibraryTarget(libname,ldeps)                              @@\
+IBMSharedLibraryTarget(lib/**/libname.a,libname,ldeps)
+
diff --git a/src/config/imake b/src/config/imake
new file mode 100644 (file)
index 0000000..3662f52
Binary files /dev/null and b/src/config/imake differ
diff --git a/src/config/imake.man b/src/config/imake.man
new file mode 100644 (file)
index 0000000..c6e10e4
--- /dev/null
@@ -0,0 +1,179 @@
+.TH IMAKE 1 "Release 4" "X Version 11"
+.SH NAME
+imake \- C preprocessor interface to the make utility
+.SH SYNOPSIS
+\fBimake \fP[-D\fIdefine\fP] [-I\fIdir\fP] [-T\fItemplate\fP]
+[-f \fIfilename\fP] [-s \fIfilename\fP] [-e] [-v]
+.SH DESCRIPTION
+.I Imake
+is used to 
+generate \fIMakefiles\fP from a template, a set of \fIcpp\fP macro functions,
+and a per-directory input file called an \fIImakefile\fP.  This allows machine
+dependencies (such has compiler options, alternate command names, and special
+\fImake\fP rules) to be kept separate from the descriptions of the
+various items to be built.
+.SH OPTIONS
+The following command line options may be passed to \fIimake\fP:
+.TP 8
+.B \-D\fIdefine\fP
+This option is passed directly to \fIcpp\fP.  It is typically used to set
+directory-specific variables.  For example, the X Window System uses this
+flag to set \fITOPDIR\fP to the name of the directory containing the top
+of the core distribution and \fICURDIR\fP to the name of the current 
+directory, relative to the top.
+.TP 8
+.B \-I\fIdirectory\fP
+This option is passed directly to \fIcpp\fP.  It is typically used to 
+indicate the directory in which the \fIimake\fP template and configuration
+files may be found.
+.TP 8
+.B \-T\fItemplate\fP
+This option specifies the name of the master template file (which is usually
+located in the directory specified with \fI\-I\fP) used by \fIcpp\fP.
+The default is \fIImake.tmpl\fP.
+.TP 8
+.B \-f \fIfilename\fP
+This option specifies the name of the per-directory input file.  The default
+is \fIImakefile\fP.
+.TP 8
+.B \-s \fIfilename\fP
+This option specifies the name of the \fImake\fP description file to be 
+generated but \fImake\fP should not be invoked.
+If the \fIfilename\fP is a dash (-), the 
+output is written to \fIstdout\fP.  The default is to generate, but
+not execute, a \fIMakefile\fP.
+.TP 8
+.B \-e
+This option indicates the \fIimake\fP should execute the generated
+\fIMakefile\fP.  The default is to leave this to the user.
+.TP 8
+.B \-v
+This option indicates that \fIimake\fP should print the \fIcpp\fP command line 
+that it is using to generate the \fIMakefile\fP.
+.SH "HOW IT WORKS"
+\fIImake\fP invokes \fIcpp\fP with any \fI\-I\fP or \fI-D\fP flags passed
+on the command line and passes it the following 3 lines:
+.sp
+.nf
+               #define IMAKE_TEMPLATE "Imake.tmpl"
+               #define INCLUDE_IMAKEFILE "Imakefile"
+               #include IMAKE_TEMPLATE
+.fi
+.sp
+where \fIImake.tmpl\fP and \fIImakefile\fP may be overridden by the 
+\fI\-T\fP and \fI\-f\fP command options, respectively.  If the 
+\fIImakefile\fP contains any lines beginning with a '#' character
+that is not followed by a \fIcpp\fP directive (\fB#include\fP,
+\fB#define\fP, \fB#undef\fP, \fB#ifdef\fP, \fB#else\fP, \fB#endif\fP,
+or \fB#if\fP), \fIimake\fP will make a temporary \fImakefile\fP in
+which the '#' lines are prepended with the string ``/**/'' (so that
+\fIcpp\fP will copy the line into the \fIMakefile\fP as a comment).
+.PP
+The \fIImakefile\fP reads in file containing machine-dependent parameters 
+(specified as \fIcpp\fP symbols), a site-specific parameters file, a file
+containing \fIcpp\fP macro functions for generating \fImake\fP rules, and
+finally the \fIImakefile\fP (specified by INCLUDE_IMAKEFILE) in the current 
+directory.  The \fIImakefile\fP uses the macro functions to indicate what
+targets should be built; \fIimake\fP takes care of generating the appropriate
+rules.
+.PP
+The rules file (usually named \fIImake.rules\fP in the configuration
+directory) contains a variety of \fIcpp\fP macro functions that are
+configured according to the current platform.  \fIImake\fP replaces 
+any occurrences of the string ``@@'' with a newline to allow macros that
+generate more than one line of \fImake\fP rules.  
+For example, the macro
+.ta .8i 1.6i 5i
+.nf
+
+#define        program_target(program, objlist)        @@\e
+program:       objlist         @@\e
+       $(CC) -o $@ objlist $(LDFLAGS)
+
+.fi
+when called with
+.I "program_target(foo, foo1.o foo2.o)"
+will expand to
+.nf
+
+foo:   foo1.o foo2.o
+       $(CC) -o $@ foo1.o foo2.o $(LDFLAGS)
+
+.fi
+.PP
+On systems whose \fIcpp\fP reduces multiple tabs and spaces to a single
+space, \fIimake\fP attempts to put back any necessary tabs (\fImake\fP is
+very picky about the difference between tabs and spaces).  For this reason,
+colons (:) in command lines must be preceded by a backslash (\\).
+.SH "USE WITH THE X WINDOW SYSTEM"
+The X Window System uses \fIimake\fP extensively, for both full builds within
+the source tree and external software.  As mentioned above, two special
+variables, \fITOPDIR\fP and \fICURDIR\fP set to make referencing files
+using relative path names easier.  For example, the following command is
+generated automatically to build the \fIMakefile\fP in the directory
+\fIlib/X/\fP (relative to the top of the sources):
+.sp
+.nf
+       %  ../.././config/imake  -I../.././config \\
+               -DTOPDIR=../../. -DCURDIR=./lib/X
+.fi
+.sp
+When building X programs outside the source tree, a special symbol
+\fIUseInstalled\fP is defined and \fITOPDIR\fP and
+\fICURDIR\fP are omitted.  If the configuration files have been
+properly installed, the script \fIxmkmf(1)\fP may be used to specify
+the proper options:
+.sp
+.nf
+       %  xmkmf
+.fi
+.sp
+The command \fImake Makefiles\fP can then be used to generate \fIMakefiles\fP
+in any subdirectories.
+.SH FILES
+.ta 3i
+/usr/tmp/tmp-imake.\fInnnnnn\fP        temporary input file for cpp
+.br
+/usr/tmp/tmp-make.\fInnnnnn\fP temporary input file for make
+.br
+/lib/cpp       default C preprocessor
+.DT
+.SH "SEE ALSO"
+make(1)
+.br
+S. I. Feldman
+.I
+Make \- A Program for Maintaining Computer Programs
+.SH "ENVIRONMENT VARIABLES"
+The following environment variables may be set, however their use is not
+recommended as they introduce dependencies that are not readily apparent
+when \fIimake\fP is run:
+.TP 5
+.B IMAKEINCLUDE
+If defined, this should be a valid include argument for the
+C preprocessor.  E.g. ``-I/usr/include/local''.
+Actually, any valid
+.I cpp
+argument will work here.
+.TP 5
+.B IMAKECPP
+If defined, this should be a valid path to a preprocessor program.
+E.g. ``/usr/local/cpp''.
+By default,
+.I imake
+will use /lib/cpp.
+.TP 5
+.B IMAKEMAKE
+If defined, this should be a valid path to a make program.
+E.g. ``/usr/local/make''.
+By default,
+.I imake
+will use whatever
+.I make
+program is found using
+.I execvp(3).
+.SH "BUGS"
+Comments should be preceded by ``/**/#'' to protect them from \fIcpp\fP.
+.SH "AUTHOR"
+Todd Brunhoff, Tektronix and MIT Project Athena; Jim Fulton, MIT X Consortium
+
diff --git a/src/config/imakemdep.h b/src/config/imakemdep.h
new file mode 100644 (file)
index 0000000..6b26fbb
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * $XConsortium: imakemdep.h,v 1.10 89/12/18 16:56:38 jim Exp $
+ * 
+ * This file contains machine-dependent constants for the imake utility.  When
+ * porting imake, read each of the steps below and add in any necessary
+ * definitions.  Do *not* edit ccimake.c or imake.c!
+ */
+
+#ifdef CCIMAKE
+/*
+ * Step 1:  imake_ccflags
+ *     Define any special flags that will be needed to get imake.c to compile.
+ *     These will be passed to the compile along with the contents of the
+ *     make variable BOOTSTRAPCFLAGS.
+ */
+#ifdef hpux
+#define imake_ccflags "-Wc,-Nd4000,-Ns3000 -DSYSV"
+#endif
+
+#ifdef macII
+#define imake_ccflags "-DSYSV"
+#endif
+
+#ifdef stellar
+#define imake_ccflags "-DSYSV"
+#endif
+
+#ifdef att
+#define imake_ccflags "-DSYSV -DUSG"
+#endif
+
+#ifdef CRAY
+#define imake_ccflags "-DSYSV -DUSG"
+#endif
+
+#ifdef aix
+#define imake_ccflags "-Daix -DSYSV"
+#endif
+
+#ifdef umips
+#ifdef SYSTYPE_SYSV
+#define imake_ccflags "-DSYSV -I../../lib/X/mips -I/usr/include/bsd ../../lib/X/mips/mipssysvc.c -lbsd"
+#endif
+#endif
+
+#else /* not CCIMAKE */
+#ifndef MAKEDEPEND
+/*
+ * Step 2:  dup2
+ *     If your OS doesn't have a dup2() system call to duplicate one file
+ *     descriptor onto another, define such a mechanism here (if you don't
+ *     already fall under the existing category(ies).
+ */
+#if defined(SYSV) && !defined(CRAY)
+#define        dup2(fd1,fd2)   ((fd1 == fd2) ? fd1 : (close(fd2), \
+                                              fcntl(fd1, F_DUPFD, fd2)))
+#endif
+
+
+/*
+ * Step 3:  FIXUP_CPP_WHITESPACE
+ *     If your cpp collapses tabs macro expansions into a single space and
+ *     replaces escaped newlines with a space, define this symbol.  This will
+ *     cause imake to attempt to patch up the generated Makefile by looking
+ *     for lines that have colons in them (this is why the rules file escapes
+ *     all colons).  One way to tell if you need this is to see whether or not
+ *     your Makefiles have no tabs in them and lots of @@ strings.
+ */
+#if defined(sun) || defined(SYSV)
+#define FIXUP_CPP_WHITESPACE
+#endif
+
+
+/*
+ * Step 4:  DEFAULT_CPP
+ *     If the C preprocessor does not live in /lib/cpp, set this symbol to 
+ *     the appropriate location.
+ */
+#ifdef apollo
+#define DEFAULT_CPP "/usr/lib/cpp"
+#endif
+
+
+/*
+ * Step 5:  cpp_argv
+ *     The following table contains the cpp flags that should be passed to 
+ *     cpp whenever a Makefile is being generated.  If your preprocessor 
+ *     doesn't predefine any unique symbols, choose one and add it to the
+ *     end of this table.  Then, do the following:
+ * 
+ *         a.  Use this symbol at the top of Imake.tmpl when setting MacroFile.
+ *         b.  Put this symbol in the definition of BootstrapCFlags in your
+ *             <platform>.cf file.
+ *         c.  When doing a make World, always add "BOOTSTRAPCFLAGS=-Dsymbol" 
+ *             to the end of the command line.
+ * 
+ *     Note that you may define more than one symbols (useful for platforms 
+ *     that support multiple operating systems).
+ */
+
+#define        ARGUMENTS 50    /* number of arguments in various arrays */
+char *cpp_argv[ARGUMENTS] = {
+       "cpp",          /* replaced by the actual cpp program to exec */
+       "-I.",          /* add current directory to include path */
+#ifdef unix
+       "-Uunix",       /* remove unix symbol so that filename unix.c okay */
+#endif
+#ifdef M4330
+       "-DM4330",      /* Tektronix */
+#endif
+#ifdef M4310
+       "-DM4310",      /* Tektronix */
+#endif
+#ifdef macII
+       "-DmacII",      /* Apple A/UX */
+#endif
+#ifdef att
+       "-Datt",        /* AT&T products */
+#endif
+#ifdef aix
+       "-Daix",        /* AIX instead of AOS */
+#ifndef ibm
+#define ibm            /* allow BOOTSTRAPCFLAGS="-Daix" */
+#endif
+#endif
+#ifdef ibm
+       "-Dibm",        /* IBM PS/2 and RT under both AOS and AIX */
+#endif
+};
+#else /* else MAKEDEPEND */
+/*
+ * Step 6:  predefs
+ *     If your compiler and/or preprocessor define any specific symbols, add
+ *     them to the the following table.  The definition of struct symtab is
+ *     in util/makedepend/main.c.
+ */
+struct symtab  predefs[] = {
+#ifdef apollo
+       {"apollo", "1"},
+#endif
+#ifdef ibm032
+       {"ibm032", "1"},
+#endif
+#ifdef ibm
+       {"ibm", "1"},
+#endif
+#ifdef aix
+       {"aix", "1"},
+#endif
+#ifdef sun
+       {"sun", "1"},
+#endif
+#ifdef hpux
+       {"hpux", "1"},
+#endif
+#ifdef vax
+       {"vax", "1"},
+#endif
+#ifdef VMS
+       {"VMS", "1"},
+#endif
+#ifdef cray
+       {"cray", "1"},
+#endif
+#ifdef CRAY
+       {"CRAY", "1"},
+#endif
+#ifdef att
+       {"att", "1"},
+#endif
+#ifdef mips
+       {"mips", "1"},
+#endif
+#ifdef ultrix
+       {"ultrix", "1"},
+#endif
+#ifdef stellar
+       {"stellar", "1"},
+#endif
+#ifdef mc68000
+       {"mc68000", "1"},
+#endif
+#ifdef mc68020
+       {"mc68020", "1"},
+#endif
+#ifdef __GNUC__
+       {"__GNUC__", "1"},
+#endif
+#ifdef __STDC__
+       {"__STDC__", "1"},
+#endif
+#ifdef __HIGHC__
+       {"__HIGHC__", "1"},
+#endif
+#ifdef CMU
+       {"CMU", "1"},
+#endif
+       /* add any additional symbols before this line */
+       {NULL, NULL}
+};
+
+#endif /* MAKEDEPEND */
+#endif /* CCIMAKE */
diff --git a/src/include/.rconf b/src/include/.rconf
new file mode 100644 (file)
index 0000000..cbaf0c2
--- /dev/null
@@ -0,0 +1,2 @@
+copy syslog.h
+link kerberosIV
diff --git a/src/include/bsdlib.h b/src/include/bsdlib.h
new file mode 100644 (file)
index 0000000..60e203e
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * generic #include file for BSD libc functions which have no other logical
+ * home.
+ */
+#ifndef __BSDLIB__
+#define __BSDLIB__
+#ifdef __STDC__
+/* compat-4.3 */
+extern char *ecvt  (double , int , int *, int *);
+extern char *fcvt  (double , int , int *, int *);
+extern char *gcvt  (double , int , char *);
+
+/* compat-4.1 */
+extern int getpw  (int , char []);
+extern int nice  (int );
+extern int pause  (void );
+extern int srand  (unsigned );
+extern int rand  (void );
+extern long tell  (int );
+extern int utime  (char *, const int []);
+extern int vlimit  (int , int );
+
+
+/* compat-sys5 */
+extern int getopt  (int , const char * const *, const char *);
+#ifdef FILE
+/* XXX depends on stdio #define of FILE */
+extern FILE *tmpfile (void);
+#endif
+
+
+extern char *tmpnam  (char *);
+extern char *tempnam  (const char *, const char *);
+
+
+/* other random stuff-- some goes into stdlib.h? */
+int abort  (void );
+int alarm  (int );
+int atoi  (const char *);
+long atol  (const char *);
+
+int setkey  (const char *);
+int encrypt  (char *, int );
+char *crypt  (const char *, const char *);
+
+int ffs  (long );
+
+char *getenv  (const char *);
+int setenv  (const char *, const char *, int );
+void unsetenv  (const char *);
+
+char *getlogin  (void );
+char *getpass  (const char *);
+char *getwd  (char *);
+
+char *getusershell  (void );
+int endusershell  (void );
+int setusershell  (void );
+
+int initgroups  (const char *, int );
+
+struct qelem {
+    struct qelem *q_forw;
+    struct qelem *q_back;
+    char q_data[1];
+};
+
+int insque  (struct qelem *, struct qelem *); 
+int remque  (struct qelem *); 
+
+int isatty  (int );
+
+int mkstemp  (char *);
+char *mktemp  (char *);
+
+int qsort  (char *, int, int, int (*)(char *, char *));
+
+int srandom  (unsigned );
+char *initstate  (unsigned , char *, int );
+char *setstate  (char *);
+long random  (void );
+
+char *re_comp  (const char *);
+int re_exec  (const char *);
+int backref  (int , const char *);
+int cclass  (const char *, int , int );
+
+int setegid  (int );
+int seteuid  (int );
+int setgid  (int );
+int setrgid  (int );
+int setruid  (int );
+int setuid  (int );
+
+int sleep  (unsigned );
+
+int swab  (char *, char *, int );
+
+int system  (const char *);
+
+char *ttyname  (int );
+int ttyslot  (void );
+
+unsigned ualarm  (unsigned , unsigned );
+int usleep  (unsigned );
+#else /* STDC */
+/* compat-4.3 */
+extern char *ecvt  ();
+extern char *fcvt  ();
+extern char *gcvt  ();
+
+/* compat-4.1 */
+extern int getpw  ();
+extern int nice  ();
+extern int pause  ();
+extern int srand  ();
+extern int rand  ();
+extern long tell  ();
+extern int utime  ();
+extern int vlimit  ();
+
+/* compat-sys5 */
+extern int getopt  ();
+#ifdef FILE
+/* XXX depends on stdio #define of FILE */
+extern FILE *tmpfile ();
+#endif
+extern char *tmpnam  ();
+extern char *tempnam  ();
+
+/* other random stuff-- some goes into stdlib.h? */
+int abort  ();
+int alarm  ();
+int atoi  ();
+long atol  ();
+
+int setkey  ();
+int encrypt  ();
+char *crypt  ();
+
+int ffs  ();
+
+char *getenv  ();
+int setenv  ();
+void unsetenv  ();
+
+char *getlogin  ();
+char *getpass  ();
+char *getwd  ();
+
+char *getusershell  ();
+int endusershell  ();
+int setusershell  ();
+
+int initgroups  ();
+
+int insque  (); 
+int remque  (); 
+
+int isatty  ();
+
+int mkstemp  ();
+char *mktemp  ();
+
+int qsort  ();
+
+int srandom  ();
+char *initstate  ();
+char *setstate  ();
+long random  ();
+
+char *re_comp  ();
+int re_exec  ();
+int backref  ();
+int cclass  ();
+
+int setegid  ();
+int seteuid  ();
+int setgid  ();
+int setrgid  ();
+int setruid  ();
+int setuid  ();
+
+int sleep  ();
+
+int swab  ();
+
+int system  ();
+
+char *ttyname  ();
+int ttyslot  ();
+
+unsigned ualarm  ();
+int usleep  ();
+#endif /* STDC */
+
+#endif /* __BSDLIB__ */
diff --git a/src/include/bstring.h b/src/include/bstring.h
new file mode 100644 (file)
index 0000000..33d0ba6
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * #include file for bstring(3) & sys5 version functions
+ * home.
+ */
+#ifndef __BSTRING__
+#define __BSTRING__
+#ifdef __STDC__
+/* compat-sys5 */
+/* these are in <string.h> */
+extern int bcmp  (const char *, const char *, int );
+extern int bcopy  (const char *, char *, int );
+extern int bzero  (char *, int );
+#else /* STDC */
+/* compat-sys5 */
+extern char *memccpy  ();
+extern char *memchr  ();
+extern int memcmp  ();
+extern char *memcpy  ();
+extern char *memset  ();
+
+extern int bcmp  ();
+extern int bcopy  ();
+extern int bzero  ();
+
+#endif /* STDC */
+#endif /* __BSTRING__ */
diff --git a/src/include/com_err.h b/src/include/com_err.h
new file mode 100644 (file)
index 0000000..7bea010
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+#ifdef __STDC__
+#ifndef __HIGHC__              /* gives us STDC but not stdarg */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+/* ANSI C -- use prototypes etc */
+void com_err (const char *, long, const char *, ...);
+char const *error_message (long);
+void (*com_err_hook) (const char *, long, const char *, va_list);
+void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
+    (const char *, long, const char *, va_list);
+void (*reset_com_err_hook ()) (const char *, long, const char *, va_list);
+#else
+/* no prototypes */
+void com_err ();
+char *error_message ();
+void (*com_err_hook) ();
+void (*set_com_err_hook ()) ();
+void (*reset_com_err_hook ()) ();
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */
diff --git a/src/include/kerberosIV/addr_comp.h b/src/include/kerberosIV/addr_comp.h
new file mode 100644 (file)
index 0000000..43e6547
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for address comparison macros.
+ */
+
+#include <mit-copyright.h>
+
+#ifndef ADDR_COMP_DEFS
+#define ADDR_COMP_DEFS
+
+/*
+** Look boys and girls, a big kludge
+** We need to compare the two internet addresses in network byte order, not
+**   local byte order.  This is a *really really slow way of doing that*
+** But.....
+**         .....it works
+** so we run with it
+**
+** long_less_than gets fed two (u_char *)'s....
+*/
+
+#define u_char_comp(x,y) \
+        (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
+
+#define long_less_than(x,y) \
+        (u_char_comp((x)[0],(y)[0])?u_char_comp((x)[0],(y)[0]): \
+        (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+         (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \
+          (u_char_comp((x)[3],(y)[3])))))
+
+#endif /* ADDR_COMP_DEFS */
diff --git a/src/include/kerberosIV/admin_server.h b/src/include/kerberosIV/admin_server.h
new file mode 100644 (file)
index 0000000..b065710
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos administration server. 
+ */
+
+#include <mit-copyright.h>
+
+#ifndef ADMIN_SERVER_DEFS
+#define ADMIN_SERVER_DEFS
+
+#define PW_SRV_VERSION          2      /* version number */
+
+#define INSTALL_NEW_PW         (1<<0)  /*
+                                        * ver, cmd, name, password,
+                                        * old_pass, crypt_pass, uid
+                                        */
+
+#define ADMIN_NEW_PW           (2<<1)  /*
+                                        * ver, cmd, name, passwd,
+                                        * old_pass
+                                        * (grot), crypt_pass (grot)
+                                        */
+
+#define ADMIN_SET_KDC_PASSWORD (3<<1)  /* ditto */
+#define ADMIN_ADD_NEW_KEY      (4<<1)  /* ditto */
+#define ADMIN_ADD_NEW_KEY_ATTR (5<<1)  /*
+                                        * ver, cmd, name, passwd,
+                                        * inst, attr (grot)
+                                        */
+#define INSTALL_REPLY          (1<<1)  /* ver, cmd, name, password */
+#define        RETRY_LIMIT              1
+#define        TIME_OUT                30
+#define USER_TIMEOUT           90
+#define MAX_KPW_LEN            40
+
+#define KADM   "changepw"              /* service name */
+
+#endif /* ADMIN_SERVER_DEFS */
diff --git a/src/include/kerberosIV/conf-bsd386i.h b/src/include/kerberosIV/conf-bsd386i.h
new file mode 100644 (file)
index 0000000..4cda8fe
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: Sun 386i using SunOS (~BSD)
+ */
+
+#include <mit-copyright.h>
+
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+
diff --git a/src/include/kerberosIV/conf-bsdapollo.h b/src/include/kerberosIV/conf-bsdapollo.h
new file mode 100644 (file)
index 0000000..693728f
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Description.
+ */
+
+#include <mit-copyright.h>
+
+#define BSDUNIX
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define DES_SHIFT_SHIFT
+/*
+ * As of SR10, the C compiler claims to be __STDC__, but doesn't support
+ * const.  Sigh.
+ */
+#define const
+
+       
diff --git a/src/include/kerberosIV/conf-bsdibm032.h b/src/include/kerberosIV/conf-bsdibm032.h
new file mode 100644 (file)
index 0000000..ce77a07
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: IBM 032 (RT/PC)
+ */
+
+#include <mit-copyright.h>
+
+#define BSDUNIX
+#define IBMWS
+#define IBMWSASM
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define MUSTALIGN
diff --git a/src/include/kerberosIV/conf-bsdm68k.h b/src/include/kerberosIV/conf-bsdm68k.h
new file mode 100644 (file)
index 0000000..12b9dda
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: 68000 with BSD Unix, e.g. SUN
+ */
+
+#include <mit-copyright.h>
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
+
diff --git a/src/include/kerberosIV/conf-bsdsparc.h b/src/include/kerberosIV/conf-bsdsparc.h
new file mode 100644 (file)
index 0000000..c9cdf4c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: SPARC with BSD Unix, e.g. SUN-4
+ */
+
+#include <mit-copyright.h>
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
+#define MUSTALIGN
+
diff --git a/src/include/kerberosIV/conf-bsdtahoe.h b/src/include/kerberosIV/conf-bsdtahoe.h
new file mode 100644 (file)
index 0000000..f4818f0
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1989 by the Regents of the University of California
+ *
+ * Machine Description : TAHOE.
+ */
+
+#include <mit-copyright.h>
+
+#define        TAHOE
+#define BSDUNIX
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define        MUSTALIGN
+#define        NOASM
diff --git a/src/include/kerberosIV/conf-bsdvax.h b/src/include/kerberosIV/conf-bsdvax.h
new file mode 100644 (file)
index 0000000..0441666
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: VAX
+ */
+
+#include <mit-copyright.h>
+
+#define VAX
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+
+#ifndef __STDC__
+#ifndef NOASM
+#define VAXASM
+#endif /* no assembly */
+#endif /* standard C */
diff --git a/src/include/kerberosIV/conf-ibm370.h b/src/include/kerberosIV/conf-ibm370.h
new file mode 100644 (file)
index 0000000..1fd620d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: IBM 370
+ */
+
+#include <mit-copyright.h>
+
+/* What else? */
+#define BIG
+#define NONASCII
+#define SHORTNAMES
diff --git a/src/include/kerberosIV/conf-pc.h b/src/include/kerberosIV/conf-pc.h
new file mode 100644 (file)
index 0000000..09cc2d8
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: IBM PC 8086
+ */
+
+#include <mit-copyright.h>
+
+#define IBMPC
+#define BITS16
+#define CROSSMSDOS
+#define LSBFIRST
diff --git a/src/include/kerberosIV/conf-pyr.h b/src/include/kerberosIV/conf-pyr.h
new file mode 100644 (file)
index 0000000..08cd0e6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: Pyramid
+ */
+
+#include <mit-copyright.h>
+
+#define BITS32
+#define BIG
+#define MSBFIRST
+#define BSDUNIX
diff --git a/src/include/kerberosIV/conf-ultmips2.h b/src/include/kerberosIV/conf-ultmips2.h
new file mode 100644 (file)
index 0000000..cc14c76
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Machine-type definitions: DECstation 3100 (MIPS R2000)
+ */
+#include <mit-copyright.h>
+#define MIPS2
+#define BITS32
+#define BIG
+#define LSBFIRST
+#define BSDUNIX
+#define MUSTALIGN
diff --git a/src/include/kerberosIV/conf.h b/src/include/kerberosIV/conf.h
new file mode 100644 (file)
index 0000000..a438a72
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Configuration info for operating system, hardware description,
+ * language implementation, C library, etc.
+ *
+ * This file should be included in (almost) every file in the Kerberos
+ * sources, and probably should *not* be needed outside of those
+ * sources.  (How do we deal with /usr/include/des.h and
+ * /usr/include/krb.h?)
+ */
+
+#ifndef _CONF_H_
+
+#include <mit-copyright.h>
+
+#include "osconf.h"
+
+#ifdef SHORTNAMES
+#include "names.h"
+#endif
+
+/*
+ * Language implementation-specific definitions
+ */
+
+/* special cases */
+#ifdef __HIGHC__
+/* broken implementation of ANSI C */
+#undef __STDC__
+#endif
+
+#ifndef __STDC__
+#define const
+#define volatile
+#define signed
+typedef char *pointer;         /* pointer to generic data */
+#define PROTOTYPE(p) ()
+#else
+typedef void *pointer;
+#define PROTOTYPE(p) p
+#endif
+
+/* Does your compiler understand "void"? */
+#ifdef notdef
+#define void int
+#endif
+
+/*
+ * A few checks to see that necessary definitions are included.
+ */
+
+/* byte order */
+
+#ifndef MSBFIRST
+#ifndef LSBFIRST
+/* #error byte order not defined */
+Error: byte order not defined.
+#endif
+#endif
+
+/* machine size */
+#ifndef BITS16
+#ifndef BITS32
+Error: how big is this machine anyways?
+#endif
+#endif
+
+/* end of checks */
+
+#endif /* _CONF_H_ */
diff --git a/src/include/kerberosIV/des.h b/src/include/kerberosIV/des.h
new file mode 100644 (file)
index 0000000..ce1f67f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$ 
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file for the Data Encryption Standard library.
+ */
+
+/* only do the whole thing once         */
+#ifndef DES_DEFS
+#define DES_DEFS
+
+#include <mit-copyright.h>
+
+typedef unsigned char des_cblock[8];   /* crypto-block size */
+/* Key schedule */
+typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
+
+#define DES_KEY_SZ     (sizeof(des_cblock))
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#ifndef NCOMPAT
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define key_sched des_key_sched
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define C_Block_print des_cblock_print
+#define quad_cksum des_quad_cksum
+typedef struct des_ks_struct bit_64;
+#endif
+
+#define des_cblock_print(x) des_cblock_print_file(x, stdout)
+
+#endif /* DES_DEFS */
diff --git a/src/include/kerberosIV/des_conf.h b/src/include/kerberosIV/des_conf.h
new file mode 100644 (file)
index 0000000..673eb93
--- /dev/null
@@ -0,0 +1,2 @@
+This file is obsolete and should not be used any more.
+Use "conf.h" instead.
diff --git a/src/include/kerberosIV/highc.h b/src/include/kerberosIV/highc.h
new file mode 100644 (file)
index 0000000..a217b01
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Known breakage in the version of Metaware's High C compiler that
+ * we've got available....
+ */
+
+#include <mit-copyright.h>
+
+#define const
+/*#define volatile*/
+
+/*
+ * Some builtin functions we can take advantage of for inlining....
+ */
+
+#define abs                    _abs
+/* the _max and _min builtins accept any number of arguments */
+#undef MAX
+#define MAX(x,y)               _max(x,y)
+#undef MIN
+#define MIN(x,y)               _min(x,y)
+/*
+ * I'm not sure if 65535 is a limit for this builtin, but it's
+ * reasonable for a string length.  Or is it?
+ */
+/*#define strlen(s)            _find_char(s,65535,0)*/
+#define bzero(ptr,len)         _fill_char(ptr,len,'\0')
+#define bcmp(b1,b2,len)                _compare(b1,b2,len)
diff --git a/src/include/kerberosIV/kadm.h b/src/include/kerberosIV/kadm.h
new file mode 100644 (file)
index 0000000..f139340
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Definitions for Kerberos administration server & client
+ */
+
+#ifndef KADM_DEFS
+#define KADM_DEFS
+
+#include <mit-copyright.h>
+/*
+ * kadm.h
+ * Header file for the fourth attempt at an admin server
+ * Doug Church, December 28, 1989, MIT Project Athena
+ */
+
+/* for those broken Unixes without this defined... should be in sys/param.h */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+/* The global structures for the client and server */
+typedef struct {
+  struct sockaddr_in admin_addr;
+  struct sockaddr_in my_addr;
+  int my_addr_len;
+  int admin_fd;                        /* file descriptor for link to admin server */
+  char sname[ANAME_SZ];                /* the service name */
+  char sinst[INST_SZ];         /* the services instance */
+  char krbrlm[REALM_SZ];
+} Kadm_Client;
+
+typedef struct {               /* status of the server, i.e the parameters */
+   int inter;                  /* Space for command line flags */
+   char *sysfile;              /* filename of server */
+} admin_params;                        /* Well... it's the admin's parameters */
+
+/* Largest password length to be supported */
+#define MAX_KPW_LEN    128
+
+/* Largest packet the admin server will ever allow itself to return */
+#define KADM_RET_MAX 2048
+
+/* That's right, versions are 8 byte strings */
+#define KADM_VERSTR    "KADM0.0A"
+#define KADM_ULOSE     "KYOULOSE"      /* sent back when server can't
+                                          decrypt client's msg */
+#define KADM_VERSIZE strlen(KADM_VERSTR)
+
+/* the lookups for the server instances */
+#define PWSERV_NAME  "changepw"
+#define KADM_SNAME   "kerberos_master"
+#define KADM_SINST   "kerberos"
+
+/* Attributes fields constants and macros */
+#define ALLOC        2
+#define RESERVED     3
+#define DEALLOC      4
+#define DEACTIVATED  5
+#define ACTIVE       6
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ        4
+
+typedef struct {
+    u_char         fields[FLDSZ];     /* The active fields in this struct */
+    char           name[ANAME_SZ];
+    char           instance[INST_SZ];
+    unsigned long  key_low;
+    unsigned long  key_high;
+    unsigned long  exp_date;
+    unsigned short attributes;
+    unsigned char  max_life;
+} Kadm_vals;                    /* The basic values structure in Kadm */
+
+/* Kadm_vals structure for passing db fields into the server routines */
+#define FLDSZ        4
+
+/* Need to define fields types here */
+#define KADM_NAME       31
+#define KADM_INST       30
+#define KADM_EXPDATE    29
+#define KADM_ATTR       28
+#define KADM_MAXLIFE    27
+#define KADM_DESKEY     26
+
+/* To set a field entry f in a fields structure d */
+#define SET_FIELD(f,d)  (d[3-(f/8)]|=(1<<(f%8)))
+
+/* To set a field entry f in a fields structure d */
+#define CLEAR_FIELD(f,d)  (d[3-(f/8)]&=(~(1<<(f%8))))
+
+/* Is field f in fields structure d */
+#define IS_FIELD(f,d)   (d[3-(f/8)]&(1<<(f%8)))
+
+/* Various return codes */
+#define KADM_SUCCESS    0
+
+#define WILDCARD_STR "*"
+
+enum acl_types {
+ADDACL,
+GETACL,
+MODACL
+};
+
+/* Various opcodes for the admin server's functions */
+#define CHANGE_PW    2
+#define ADD_ENT      3
+#define MOD_ENT      4
+#define GET_ENT      5
+
+extern long kdb_get_master_key();      /* XXX should be in krb_db.h */
+extern long kdb_verify_master_key();   /* XXX ditto */
+
+extern long krb_mk_priv(), krb_rd_priv(); /* XXX should be in krb.h */
+extern void krb_set_tkt_string();      /* XXX ditto */
+
+extern unsigned long quad_cksum();     /* XXX should be in des.h */
+
+/* XXX This doesn't belong here!!! */
+char *malloc(), *realloc();
+#ifdef POSIX
+typedef void sigtype;
+#else
+typedef int sigtype;
+#endif
+
+#endif KADM_DEFS
diff --git a/src/include/kerberosIV/kdc.h b/src/include/kerberosIV/kdc.h
new file mode 100644 (file)
index 0000000..393fb0e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos Key Distribution Center. 
+ */
+
+#include <mit-copyright.h>
+
+#ifndef KDC_DEFS
+#define KDC_DEFS
+
+#define S_AD_SZ                sizeof(struct sockaddr_in)
+
+#define max(a,b)       (a>b ? a : b)
+#define min(a,b)       (a<b ? a : b)
+
+#define TRUE           1
+#define FALSE          0
+
+#define MKEYFILE       "/.k"
+#define K_LOGFIL       "/kerberos/kpropd.log"
+#define KS_LOGFIL      "/kerberos/kerberos_slave.log"
+#define KRB_ACL                "/kerberos/kerberos.acl"
+#define KRB_PROG       "./kerberos"
+
+#define ONE_MINUTE     60
+#define FIVE_MINUTES   (5 * ONE_MINUTE)
+#define ONE_HOUR       (60 * ONE_MINUTE)
+#define ONE_DAY                (24 * ONE_HOUR)
+#define THREE_DAYS     (3 * ONE_DAY)
+
+#endif /* KDC_DEFS */
+
diff --git a/src/include/kerberosIV/klog.h b/src/include/kerberosIV/klog.h
new file mode 100644 (file)
index 0000000..b795386
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This file defines the types of log messages logged by klog.  Each
+ * type of message may be selectively turned on or off. 
+ */
+
+#include <mit-copyright.h>
+
+#ifndef KLOG_DEFS
+#define KLOG_DEFS
+
+#define KRBLOG                 "/kerberos/kerberos.log"  /* master server  */
+#define KRBSLAVELOG    "/kerberos/kerberos_slave.log"  /* master server  */
+#define        NLOGTYPE        100     /* Maximum number of log msg types  */
+
+#define L_NET_ERR        1     /* Error in network code            */
+#define L_NET_INFO       2     /* Info on network activity         */
+#define L_KRB_PERR       3     /* Kerberos protocol errors         */
+#define L_KRB_PINFO      4     /* Kerberos protocol info           */
+#define L_INI_REQ        5     /* Request for initial ticket       */
+#define L_NTGT_INTK       6    /* Initial request not for TGT      */
+#define L_DEATH_REQ       7    /* Request for server death         */
+#define L_TKT_REQ        8     /* All ticket requests using a tgt  */
+#define L_ERR_SEXP       9     /* Service expired                  */
+#define L_ERR_MKV       10     /* Master key version incorrect     */
+#define L_ERR_NKY       11     /* User's key is null               */
+#define L_ERR_NUN       12     /* Principal not unique             */
+#define L_ERR_UNK       13     /* Principal Unknown                */
+#define L_ALL_REQ       14     /* All requests                     */
+#define L_APPL_REQ      15     /* Application requests (using tgt) */
+#define L_KRB_PWARN      16    /* Protocol warning messages        */
+
+char   *klog();
+
+#endif /* KLOG_DEFS */
diff --git a/src/include/kerberosIV/krb.h b/src/include/kerberosIV/krb.h
new file mode 100644 (file)
index 0000000..78e406a
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$ 
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos library. 
+ */
+
+/* Only one time, please */
+#ifndef        KRB_DEFS
+#define KRB_DEFS
+
+#include <mit-copyright.h>
+
+/* Need some defs from des.h    */
+#include <des.h>
+
+/* Text describing error codes */
+#define                MAX_KRB_ERRORS  256
+extern char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* These are not defined for at least SunOS 3.3 and Ultrix 2.2 */
+#if defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)
+#define FD_ZERO(p)  ((p)->fds_bits[0] = 0)
+#define FD_SET(n, p)   ((p)->fds_bits[0] |= (1 << (n)))
+#define FD_ISSET(n, p)   ((p)->fds_bits[0] & (1 << (n)))
+#endif /* ULTRIX022 || SunOS */
+
+/* General definitions */
+#define                KSUCCESS        0
+#define                KFAILURE        255
+
+#ifdef NO_UIDGID_T
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+#endif /* NO_UIDGID_T */
+
+/*
+ * Kerberos specific definitions 
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database.  The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server.  Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm. 
+ */
+
+#ifdef notdef
+this is server - only, does not belong here;
+#define        KRBLOG          "/kerberos/kerberos.log"
+are these used anyplace '?';
+#define                VX_KRB_HSTFILE  "/etc/krbhst"
+#define                PC_KRB_HSTFILE  "\\kerberos\\krbhst"
+#endif
+
+#define                KRB_CONF        "/etc/krb.conf"
+#define                KRB_RLM_TRANS   "/etc/krb.realms"
+#define                KRB_MASTER      "kerberos"
+#define                KRB_HOST         KRB_MASTER
+#define                KRB_REALM       "ATHENA.MIT.EDU"
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define        ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+/* include space for '.' and '@' */
+#define                MAX_K_NAME_SZ   (ANAME_SZ + INST_SZ + REALM_SZ + 2)
+#define                KKEY_SZ         100
+#define                VERSION_SZ      1
+#define                MSG_TYPE_SZ     1
+#define                DATE_SZ         26      /* RTI date output */
+
+#define                MAX_HSTNM       100
+
+#ifndef DEFAULT_TKT_LIFE               /* allow compile-time override */
+#define                DEFAULT_TKT_LIFE        96 /* default lifetime for krb_mk_req
+                                             & co., 8 hrs */
+#endif
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+    int     length;            /* Length of the text */
+    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */
+    unsigned long mbz;         /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define        CLIENT_KRB_TIMEOUT      4       /* time between retries */
+#define CLIENT_KRB_RETRY       5       /* retry this many times */
+#define        CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define        R_TKT_FIL       0
+#define        W_TKT_FIL       1
+
+/* Definitions for cl_get_tgt */
+#ifdef PC
+#define CL_GTGT_INIT_FILE              "\\kerberos\\k_in_tkts"
+#else
+#define CL_GTGT_INIT_FILE              "/etc/k_in_tkts"
+#endif /* PC */
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define        CLOCK_SKEW      5*60
+/* Filename for readservkey */
+#define                KEYFILE         "/etc/srvtab"
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+    unsigned char k_flags;     /* Flags from ticket */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* His Instance */
+    char    prealm[REALM_SZ];  /* His Realm */
+    unsigned long checksum;    /* Data checksum (opt) */
+    C_Block session;           /* Session Key */
+    int     life;              /* Life of ticket */
+    unsigned long time_sec;    /* Time ticket issued */
+    unsigned long address;     /* Address in ticket */
+    KTEXT_ST reply;            /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+    char    service[ANAME_SZ]; /* Service name */
+    char    instance[INST_SZ]; /* Instance */
+    char    realm[REALM_SZ];   /* Auth domain */
+    C_Block session;           /* Session key */
+    int     lifetime;          /* Lifetime */
+    int     kvno;              /* Key version number */
+    KTEXT_ST ticket_st;                /* The ticket itself */
+    long    issue_date;                /* The issue time */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+    unsigned char *app_data;   /* pointer to appl data */
+    unsigned long app_length;  /* length of appl data */
+    unsigned long hash;                /* hash to lookup replay */
+    int     swap;              /* swap bytes? */
+    long    time_sec;          /* msg timestamp seconds */
+    unsigned char time_5ms;    /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+
+/* Location of ticket file for save_cred and get_cred */
+#ifdef PC
+#define TKT_FILE        "\\kerberos\\ticket.ses"
+#else
+#define TKT_FILE        tkt_string()
+#define TKT_ROOT        "/tmp/tkt"
+#endif /* PC */
+
+/* Error codes returned from the KDC */
+#define                KDC_OK          0       /* Request OK */
+#define                KDC_NAME_EXP    1       /* Principal expired */
+#define                KDC_SERVICE_EXP 2       /* Service expired */
+#define                KDC_AUTH_EXP    3       /* Auth expired */
+#define                KDC_PKT_VER     4       /* Protocol version unknown */
+#define                KDC_P_MKEY_VER  5       /* Wrong master key version */
+#define                KDC_S_MKEY_VER  6       /* Wrong master key version */
+#define                KDC_BYTE_ORDER  7       /* Byte order unknown */
+#define                KDC_PR_UNKNOWN  8       /* Principal unknown */
+#define                KDC_PR_N_UNIQUE 9       /* Principal not unique */
+#define                KDC_NULL_KEY   10       /* Principal has null key */
+#define                KDC_GEN_ERR    20       /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define                GC_OK           0       /* Retrieve OK */
+#define                RET_OK          0       /* Retrieve OK */
+#define                GC_TKFIL       21       /* Can't read ticket file */
+#define                RET_TKFIL      21       /* Can't read ticket file */
+#define                GC_NOTKT       22       /* Can't find ticket or TGT */
+#define                RET_NOTKT      22       /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req         */
+#define                MK_AP_OK        0       /* Success */
+#define                MK_AP_TGTEXP   26       /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define                RD_AP_OK        0       /* Request authentic */
+#define                RD_AP_UNDEC    31       /* Can't decode authenticator */
+#define                RD_AP_EXP      32       /* Ticket expired */
+#define                RD_AP_NYV      33       /* Ticket not yet valid */
+#define                RD_AP_REPEAT   34       /* Repeated request */
+#define                RD_AP_NOT_US   35       /* The ticket isn't for us */
+#define                RD_AP_INCON    36       /* Request is inconsistent */
+#define                RD_AP_TIME     37       /* delta_t too big */
+#define                RD_AP_BADD     38       /* Incorrect net address */
+#define                RD_AP_VERSION  39       /* protocol version mismatch */
+#define                RD_AP_MSG_TYPE 40       /* invalid msg type */
+#define                RD_AP_MODIFIED 41       /* message stream modified */
+#define                RD_AP_ORDER    42       /* message out of order */
+#define                RD_AP_UNAUTHOR 43       /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define                GT_PW_OK        0       /* Got password changing tkt */
+#define                GT_PW_NULL     51       /* Current PW is null */
+#define                GT_PW_BADPW    52       /* Incorrect current password */
+#define                GT_PW_PROT     53       /* Protocol Error */
+#define                GT_PW_KDCERR   54       /* Error returned by KDC */
+#define                GT_PW_NULLTKT  55       /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define                SKDC_OK         0       /* Response received */
+#define                SKDC_RETRY     56       /* Retry count exceeded */
+#define                SKDC_CANT      57       /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define                INTK_OK         0       /* Ticket obtained */
+#define                INTK_W_NOTALL  61       /* Not ALL tickets returned */
+#define                INTK_BADPW     62       /* Incorrect password */
+#define                INTK_PROT      63       /* Protocol Error */
+#define                INTK_ERR       70       /* Other error */
+
+/* Values returned by get_adtkt */
+#define         AD_OK           0      /* Ticket Obtained */
+#define         AD_NOTGT       71      /* Don't have tgt */
+
+/* Error codes returned by ticket file utilities */
+#define                NO_TKT_FIL      76      /* No ticket file found */
+#define                TKT_FIL_ACC     77      /* Couldn't access tkt file */
+#define                TKT_FIL_LCK     78      /* Couldn't lock ticket file */
+#define                TKT_FIL_FMT     79      /* Bad ticket file format */
+#define                TKT_FIL_INI     80      /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define                KNAME_FMT       81      /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define                SAFE_PRIV_ERROR -1      /* syscall error */
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad  0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_long  0-->3, 1-->2, 2-->1, 3-->0
+ * u_short 0-->1, 1-->0
+ */
+
+#define     swap_u_16(x) {\
+ unsigned long   _krb_swap_tmp[4];\
+ swab(((char *) x) +0, ((char *)  _krb_swap_tmp) +14 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +12 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +8  ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +12,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +14,((char *)  _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,16);\
+                            }
+
+#define     swap_u_12(x) {\
+ unsigned long   _krb_swap_tmp[4];\
+ swab(( char *) x,     ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +0 ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,12);\
+                            }
+
+#define     swap_C_Block(x) {\
+ unsigned long   _krb_swap_tmp[4];\
+ swab(( char *) x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)x,8);\
+                            }
+#define     swap_u_quad(x) {\
+ unsigned long   _krb_swap_tmp[4];\
+ swab(( char *) &x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) &x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ bcopy((char *)_krb_swap_tmp,(char *)&x,8);\
+                            }
+
+#define     swap_u_long(x) {\
+ unsigned long   _krb_swap_tmp[4];\
+ swab((char *)  &x,    ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp),2); \
+ x = _krb_swap_tmp[0];   \
+                           }
+
+#define     swap_u_short(x) {\
+ unsigned short        _krb_swap_sh_tmp; \
+ swab((char *)  &x,    ( &_krb_swap_sh_tmp) ,2); \
+ x = (unsigned short) _krb_swap_sh_tmp; \
+                            }
+
+/* Kerberos ticket flag field bit definitions */
+#define K_FLAG_ORDER    0       /* bit 0 --> lsb */
+#define K_FLAG_1                /* reserved */
+#define K_FLAG_2                /* reserved */
+#define K_FLAG_3                /* reserved */
+#define K_FLAG_4                /* reserved */
+#define K_FLAG_5                /* reserved */
+#define K_FLAG_6                /* reserved */
+#define K_FLAG_7                /* reserved, bit 7 --> msb */
+
+#ifndef PC
+char *tkt_string();
+#endif /* PC */
+
+#ifdef OLDNAMES
+#define krb_mk_req     mk_ap_req
+#define krb_rd_req     rd_ap_req
+#define krb_kntoln     an_to_ln
+#define krb_set_key    set_serv_key
+#define krb_get_cred   get_credentials
+#define krb_mk_priv    mk_private_msg
+#define krb_rd_priv    rd_private_msg
+#define krb_mk_safe    mk_safe_msg
+#define krb_rd_safe    rd_safe_msg
+#define krb_mk_err     mk_appl_err_msg
+#define krb_rd_err     rd_appl_err_msg
+#define krb_ck_repl    check_replay
+#define        krb_get_pw_in_tkt       get_in_tkt
+#define krb_get_svc_in_tkt     get_svc_in_tkt
+#define krb_get_pw_tkt         get_pw_tkt
+#define krb_realmofhost                krb_getrealm
+#define krb_get_phost          get_phost
+#define krb_get_krbhst         get_krbhst
+#define krb_get_lrealm         get_krbrlm
+#endif /* OLDNAMES */
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define        KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define        KOPT_DO_MUTUAL   0x00000002 /* do mutual auth */
+
+#define        KOPT_DONT_CANON  0x00000004 /*
+                                    * don't canonicalize inst as
+                                    * a hostname
+                                    */
+
+#define        KRB_SENDAUTH_VLEN 8         /* length for version strings */
+
+#ifdef ATHENA_COMPAT
+#define        KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */
+#endif /* ATHENA_COMPAT */
+
+#endif /* KRB_DEFS */
diff --git a/src/include/kerberosIV/krb_db.h b/src/include/kerberosIV/krb_db.h
new file mode 100644 (file)
index 0000000..3a37906
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$ 
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * spm         Project Athena  8/85 
+ *
+ * This file defines data structures for the kerberos
+ * authentication/authorization database. 
+ *
+ * They MUST correspond to those defined in *.rel 
+ */
+
+#include <mit-copyright.h>
+
+#ifndef KRB_DB_DEFS
+#define KRB_DB_DEFS
+
+#define KERB_M_NAME            "K"     /* Kerberos */
+#define KERB_M_INST            "M"     /* Master */
+#define KERB_DEFAULT_NAME      "default"
+#define KERB_DEFAULT_INST      ""
+#define        DBM_FILE                "/kerberos/principal"
+
+/* this also defines the number of queue headers */
+#define KERB_DB_HASH_MODULO 64
+
+
+/* Arguments to kerb_dbl_lock() */
+
+#define KERB_DBL_EXCLUSIVE 1
+#define KERB_DBL_SHARED 0
+
+/* arguments to kerb_db_set_lockmode() */
+
+#define KERB_DBL_BLOCKING 0
+#define KERB_DBL_NONBLOCKING 1
+
+/* Principal defines the structure of a principal's name */
+
+typedef struct {
+    char    name[ANAME_SZ];
+    char    instance[INST_SZ];
+
+    unsigned long key_low;
+    unsigned long key_high;
+    unsigned long exp_date;
+    char    exp_date_txt[DATE_SZ];
+    unsigned long mod_date;
+    char    mod_date_txt[DATE_SZ];
+    unsigned short attributes;
+    unsigned char max_life;
+    unsigned char kdc_key_ver;
+    unsigned char key_version;
+
+    char    mod_name[ANAME_SZ];
+    char    mod_instance[INST_SZ];
+    char   *old;               /* cast to (Principal *); not in db,
+                                * ptr to old vals */
+}
+        Principal;
+
+typedef struct {
+    long    cpu;
+    long    elapsed;
+    long    dio;
+    long    pfault;
+    long    t_stamp;
+    long    n_retrieve;
+    long    n_replace;
+    long    n_append;
+    long    n_get_stat;
+    long    n_put_stat;
+}
+        DB_stat;
+
+/* Dba defines the structure of a database administrator */
+
+typedef struct {
+    char    name[ANAME_SZ];
+    char    instance[INST_SZ];
+    unsigned short attributes;
+    unsigned long exp_date;
+    char    exp_date_txt[DATE_SZ];
+    char   *old;       /*
+                        * cast to (Dba *); not in db, ptr to
+                        * old vals
+                        */
+}
+        Dba;
+
+extern int kerb_get_principal();
+extern int kerb_put_principal();
+extern int kerb_db_get_stat();
+extern int kerb_db_put_stat();
+extern int kerb_get_dba();
+extern int kerb_db_get_dba();
+
+#endif /* KRB_DB_DEFS */
diff --git a/src/include/kerberosIV/lsb_addr_comp.h b/src/include/kerberosIV/lsb_addr_comp.h
new file mode 100644 (file)
index 0000000..80b9b36
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Comparison macros to emulate LSBFIRST comparison results of network
+ * byte-order quantities
+ */
+
+#include <mit-copyright.h>
+#ifndef LSB_ADDR_COMP_DEFS
+#define LSB_ADDR_COMP_DEFS
+
+#include "osconf.h"
+
+#ifdef LSBFIRST
+#define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#else
+/* MSBFIRST */
+#define u_char_comp(x,y) \
+        (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
+/* This is gross, but... */
+#define lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y)
+#define lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y)
+
+#define long_less_than(x,y) \
+        (u_char_comp((x)[3],(y)[3])?u_char_comp((x)[3],(y)[3]): \
+        (u_char_comp((x)[2],(y)[2])?u_char_comp((x)[2],(y)[2]): \
+         (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+          (u_char_comp((x)[0],(y)[0])))))
+#define short_less_than(x,y) \
+         (u_char_comp((x)[1],(y)[1])?u_char_comp((x)[1],(y)[1]): \
+          (u_char_comp((x)[0],(y)[0])))
+
+#endif /* LSBFIRST */
+
+#endif /*  LSB_ADDR_COMP_DEFS */
diff --git a/src/include/kerberosIV/mit-copyright.h b/src/include/kerberosIV/mit-copyright.h
new file mode 100644 (file)
index 0000000..cd30580
--- /dev/null
@@ -0,0 +1,20 @@
+/* 
+  Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+   Export of this software from the United States of America is assumed
+   to require a specific license from the United States Government.
+   It is the responsibility of any person or organization contemplating
+   export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+  */
diff --git a/src/include/kerberosIV/osconf.h b/src/include/kerberosIV/osconf.h
new file mode 100644 (file)
index 0000000..9d6a9bb
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Athena configuration.
+ */
+
+#include <mit-copyright.h>
+
+#ifdef tahoe
+#include "conf-bsdtahoe.h"
+#else /* !tahoe */
+#ifdef vax
+#include "conf-bsdvax.h"
+#else /* !vax */
+#if defined(mips) && defined(ultrix)
+#include "conf-ultmips2.h"
+#else /* !Ultrix MIPS-2 */
+#ifdef ibm032
+#include "conf-bsdibm032.h"
+#else /* !ibm032 */
+#ifdef apollo
+#include "conf-bsdapollo.h"
+#else /* !apollo */
+#ifdef sun
+#ifdef sparc
+#include "conf-bsdsparc.h"
+#else /* sun but not sparc */
+#ifdef i386
+#include "conf-bsd386i.h"
+#else /* sun but not (sparc or 386i) */
+#include "conf-bsdm68k.h"
+#endif /* i386 */
+#endif /* sparc */
+#else /* !sun */
+#ifdef pyr
+#include "conf-pyr.h"
+#endif /* pyr */
+#endif /* sun */
+#endif /* apollo */
+#endif /* ibm032 */
+#endif /* mips */
+#endif /* vax */
+#endif /* tahoe */
diff --git a/src/include/kerberosIV/passwd_server.h b/src/include/kerberosIV/passwd_server.h
new file mode 100644 (file)
index 0000000..08bb297
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$ 
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for password server
+ */
+
+#include <mit-copyright.h>
+
+#ifndef PASSWD_SERVER_DEFS
+#define PASSWD_SERVER_DEFS
+
+#define PW_SRV_VERSION 2       /* version number */
+#define        RETRY_LIMIT     1
+#define        TIME_OUT        30
+#define USER_TIMEOUT   90
+#define MAX_KPW_LEN    40      /* hey, seems like a good number */
+
+#define INSTALL_NEW_PW (1<<0)  /*
+                                * ver, cmd, name, password, old_pass,
+                                * crypt_pass, uid
+                                */
+
+#define INSTALL_REPLY  (1<<1)  /* ver, cmd, name, password */
+
+#endif /* PASSWD_SERVER_DEFS */
diff --git a/src/include/kerberosIV/principal.h b/src/include/kerberosIV/principal.h
new file mode 100644 (file)
index 0000000..f114942
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Definitions for principal names.
+ */
+
+#include <mit-copyright.h>
+
+#ifndef PRINCIPAL_DEFS
+#define PRINCIPAL_DEFS
+
+#define NAME_LEN       39
+#define INSTANCE_LEN   39
+
+#endif /* PRINCIPAL_DEFS */
diff --git a/src/include/kerberosIV/prot.h b/src/include/kerberosIV/prot.h
new file mode 100644 (file)
index 0000000..ff79271
--- /dev/null
@@ -0,0 +1,97 @@
+
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file with authentication protocol information.
+ */
+
+#include <mit-copyright.h>
+
+#include <krb_conf.h>
+
+#ifndef PROT_DEFS
+#define PROT_DEFS
+
+#define                KRB_PORT                750     /* PC's don't have
+                                                * /etc/services */
+#define                KRB_PROT_VERSION        4
+#define        MAX_PKT_LEN             1000
+#define                MAX_TXT_LEN             1000
+#define                TICKET_GRANTING_TICKET  "krbtgt"
+
+/* Macro's to obtain various fields from a packet */
+
+#define pkt_version(packet)  (unsigned int) *(packet->dat)
+#define pkt_msg_type(packet) (unsigned int) *(packet->dat+1)
+#define pkt_a_name(packet)   (packet->dat+2)
+#define pkt_a_inst(packet)   \
+       (packet->dat+3+strlen((char *)pkt_a_name(packet)))
+#define pkt_a_realm(packet)  \
+       (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet)))
+
+/* Macro to obtain realm from application request */
+#define apreq_realm(auth)     (auth->dat + 3)
+
+#define pkt_time_ws(packet) (char *) \
+        (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+#define pkt_no_req(packet) (unsigned short) \
+        *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+         strlen((char *)pkt_a_inst(packet)) + \
+         strlen((char *)pkt_a_realm(packet)))
+#define pkt_x_date(packet) (char *) \
+        (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+#define pkt_err_code(packet) ( (char *) \
+        (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet))))
+#define pkt_err_text(packet) \
+        (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+/* Routines to create and read packets may be found in prot.c */
+
+KTEXT create_auth_reply();
+KTEXT create_death_packet();
+KTEXT pkt_cipher();
+
+/* Message types , always leave lsb for byte order */
+
+#define                AUTH_MSG_KDC_REQUEST                     1<<1
+#define        AUTH_MSG_KDC_REPLY                       2<<1
+#define                AUTH_MSG_APPL_REQUEST                    3<<1
+#define                AUTH_MSG_APPL_REQUEST_MUTUAL             4<<1
+#define                AUTH_MSG_ERR_REPLY                       5<<1
+#define                AUTH_MSG_PRIVATE                         6<<1
+#define                AUTH_MSG_SAFE                            7<<1
+#define                AUTH_MSG_APPL_ERR                        8<<1
+#define        AUTH_MSG_DIE                            63<<1
+
+/* values for kerb error codes */
+
+#define                KERB_ERR_OK                              0
+#define                KERB_ERR_NAME_EXP                        1
+#define                KERB_ERR_SERVICE_EXP                     2
+#define                KERB_ERR_AUTH_EXP                        3
+#define                KERB_ERR_PKT_VER                         4
+#define                KERB_ERR_NAME_MAST_KEY_VER               5
+#define                KERB_ERR_SERV_MAST_KEY_VER               6
+#define                KERB_ERR_BYTE_ORDER                      7
+#define                KERB_ERR_PRINCIPAL_UNKNOWN               8
+#define                KERB_ERR_PRINCIPAL_NOT_UNIQUE            9
+#define                KERB_ERR_NULL_KEY                       10
+
+#endif /* PROT_DEFS */
diff --git a/src/include/krb5/.rconf b/src/include/krb5/.rconf
new file mode 100644 (file)
index 0000000..0278baf
--- /dev/null
@@ -0,0 +1,5 @@
+ignore README.encryption
+copy error_tables
+link stock
+ignore config.h
+ignore osconf.h
diff --git a/src/include/krb5/asn.1/.rconf b/src/include/krb5/asn.1/.rconf
new file mode 100644 (file)
index 0000000..6715bf4
--- /dev/null
@@ -0,0 +1 @@
+ignore KRB5-types.h
diff --git a/src/include/sys/syslog.h b/src/include/sys/syslog.h
new file mode 100644 (file)
index 0000000..ff91205
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)syslog.h    7.10 (Berkeley) 6/27/88
+ */
+
+/*
+ * RCS Info    
+ *     $Header$
+ *     $Locker$
+ */
+
+/*
+ *  Facility codes
+ */
+
+#define LOG_KERN       (0<<3)  /* kernel messages */
+#define LOG_USER       (1<<3)  /* random user-level messages */
+#define LOG_MAIL       (2<<3)  /* mail system */
+#define LOG_DAEMON     (3<<3)  /* system daemons */
+#define LOG_AUTH       (4<<3)  /* security/authorization messages */
+#define LOG_SYSLOG     (5<<3)  /* messages generated internally by syslogd */
+#define LOG_LPR                (6<<3)  /* line printer subsystem */
+#define LOG_NEWS       (7<<3)  /* network news subsystem */
+#define LOG_UUCP       (8<<3)  /* UUCP subsystem */
+       /* other codes through 15 reserved for system use */
+#define LOG_LOCAL0     (16<<3) /* reserved for local use */
+#define LOG_LOCAL1     (17<<3) /* reserved for local use */
+#define LOG_LOCAL2     (18<<3) /* reserved for local use */
+#define LOG_LOCAL3     (19<<3) /* reserved for local use */
+#define LOG_LOCAL4     (20<<3) /* reserved for local use */
+#define LOG_LOCAL5     (21<<3) /* reserved for local use */
+#define LOG_LOCAL6     (22<<3) /* reserved for local use */
+#define LOG_LOCAL7     (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES        24      /* maximum number of facilities */
+#define LOG_FACMASK    0x03f8  /* mask to extract facility part */
+
+#define LOG_FAC(p)     (((p) & LOG_FACMASK) >> 3)      /* facility of pri */
+
+/*
+ *  Priorities (these are ordered)
+ */
+
+#define LOG_EMERG      0       /* system is unusable */
+#define LOG_ALERT      1       /* action must be taken immediately */
+#define LOG_CRIT       2       /* critical conditions */
+#define LOG_ERR                3       /* error conditions */
+#define LOG_WARNING    4       /* warning conditions */
+#define LOG_NOTICE     5       /* normal but signification condition */
+#define LOG_INFO       6       /* informational */
+#define LOG_DEBUG      7       /* debug-level messages */
+
+#define LOG_PRIMASK    0x0007  /* mask to extract priority part (internal) */
+#define LOG_PRI(p)     ((p) & LOG_PRIMASK)     /* extract priority */
+
+#define        LOG_MAKEPRI(fac, pri)   (((fac) << 3) | (pri))
+
+#ifdef KERNEL
+#define LOG_PRINTF     -1      /* pseudo-priority to indicate use of printf */
+#endif
+
+/*
+ * arguments to setlogmask.
+ */
+#define        LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
+#define        LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
+
+/*
+ *  Option flags for openlog.
+ *
+ *     LOG_ODELAY no longer does anything; LOG_NDELAY is the
+ *     inverse of what it used to be.
+ */
+#define        LOG_PID         0x01    /* log the pid with each message */
+#define        LOG_CONS        0x02    /* log on the console if errors in sending */
+#define        LOG_ODELAY      0x04    /* delay open until syslog() is called */
+#define LOG_NDELAY     0x08    /* don't delay open */
+#define LOG_NOWAIT     0x10    /* if forking to log on console, don't wait() */
+
+#ifndef KERNEL
+#if defined(__STDC__) || defined(KRB5_PROVIDE_PROTOTYPES)
+extern void syslog  (int , const char *, ... );
+#ifdef va_start                                
+/* XXX depending on #define of va_start in <stdarg.h> */
+extern void vsyslog  (int , const char *, va_list );
+#endif
+extern void openlog  (const char *, int , int );
+extern void closelog  (void );
+extern int setlogmask  (int );
+#else /* STDC */
+extern void syslog  ();
+extern void vsyslog  ();
+extern void openlog  ();
+extern void closelog  ();
+extern int setlogmask  ();
+#endif /* STDC */
+
+#endif
diff --git a/src/include/syslog.h b/src/include/syslog.h
new file mode 100644 (file)
index 0000000..ff91205
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)syslog.h    7.10 (Berkeley) 6/27/88
+ */
+
+/*
+ * RCS Info    
+ *     $Header$
+ *     $Locker$
+ */
+
+/*
+ *  Facility codes
+ */
+
+#define LOG_KERN       (0<<3)  /* kernel messages */
+#define LOG_USER       (1<<3)  /* random user-level messages */
+#define LOG_MAIL       (2<<3)  /* mail system */
+#define LOG_DAEMON     (3<<3)  /* system daemons */
+#define LOG_AUTH       (4<<3)  /* security/authorization messages */
+#define LOG_SYSLOG     (5<<3)  /* messages generated internally by syslogd */
+#define LOG_LPR                (6<<3)  /* line printer subsystem */
+#define LOG_NEWS       (7<<3)  /* network news subsystem */
+#define LOG_UUCP       (8<<3)  /* UUCP subsystem */
+       /* other codes through 15 reserved for system use */
+#define LOG_LOCAL0     (16<<3) /* reserved for local use */
+#define LOG_LOCAL1     (17<<3) /* reserved for local use */
+#define LOG_LOCAL2     (18<<3) /* reserved for local use */
+#define LOG_LOCAL3     (19<<3) /* reserved for local use */
+#define LOG_LOCAL4     (20<<3) /* reserved for local use */
+#define LOG_LOCAL5     (21<<3) /* reserved for local use */
+#define LOG_LOCAL6     (22<<3) /* reserved for local use */
+#define LOG_LOCAL7     (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES        24      /* maximum number of facilities */
+#define LOG_FACMASK    0x03f8  /* mask to extract facility part */
+
+#define LOG_FAC(p)     (((p) & LOG_FACMASK) >> 3)      /* facility of pri */
+
+/*
+ *  Priorities (these are ordered)
+ */
+
+#define LOG_EMERG      0       /* system is unusable */
+#define LOG_ALERT      1       /* action must be taken immediately */
+#define LOG_CRIT       2       /* critical conditions */
+#define LOG_ERR                3       /* error conditions */
+#define LOG_WARNING    4       /* warning conditions */
+#define LOG_NOTICE     5       /* normal but signification condition */
+#define LOG_INFO       6       /* informational */
+#define LOG_DEBUG      7       /* debug-level messages */
+
+#define LOG_PRIMASK    0x0007  /* mask to extract priority part (internal) */
+#define LOG_PRI(p)     ((p) & LOG_PRIMASK)     /* extract priority */
+
+#define        LOG_MAKEPRI(fac, pri)   (((fac) << 3) | (pri))
+
+#ifdef KERNEL
+#define LOG_PRINTF     -1      /* pseudo-priority to indicate use of printf */
+#endif
+
+/*
+ * arguments to setlogmask.
+ */
+#define        LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
+#define        LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
+
+/*
+ *  Option flags for openlog.
+ *
+ *     LOG_ODELAY no longer does anything; LOG_NDELAY is the
+ *     inverse of what it used to be.
+ */
+#define        LOG_PID         0x01    /* log the pid with each message */
+#define        LOG_CONS        0x02    /* log on the console if errors in sending */
+#define        LOG_ODELAY      0x04    /* delay open until syslog() is called */
+#define LOG_NDELAY     0x08    /* don't delay open */
+#define LOG_NOWAIT     0x10    /* if forking to log on console, don't wait() */
+
+#ifndef KERNEL
+#if defined(__STDC__) || defined(KRB5_PROVIDE_PROTOTYPES)
+extern void syslog  (int , const char *, ... );
+#ifdef va_start                                
+/* XXX depending on #define of va_start in <stdarg.h> */
+extern void vsyslog  (int , const char *, va_list );
+#endif
+extern void openlog  (const char *, int , int );
+extern void closelog  (void );
+extern int setlogmask  (int );
+#else /* STDC */
+extern void syslog  ();
+extern void vsyslog  ();
+extern void openlog  ();
+extern void closelog  ();
+extern int setlogmask  ();
+#endif /* STDC */
+
+#endif
diff --git a/src/kadmin/server/admin_acl_file b/src/kadmin/server/admin_acl_file
new file mode 100644 (file)
index 0000000..77bddcc
--- /dev/null
@@ -0,0 +1,12 @@
+#      Administrator Access Control List
+#      Format:
+#      Name    Privileges      Comments
+#      Where Privileges is a string containing one or more of
+#              "a"             Add New Principals
+#              "c"             Change Passwords
+#              "d"             Delete Current Principals
+#              "i"             Inquire About Existing Principals
+#              "m"             Modify Existing Principals
+#              "*"             All Privileges
+#jqsample/admin@realm  *
+#tomjones/admin@realm  acim    # Note - May Not Delete
diff --git a/src/kdc/.rconf b/src/kdc/.rconf
new file mode 100644 (file)
index 0000000..ae50e63
--- /dev/null
@@ -0,0 +1,5 @@
+ignore rtest.c
+ignore rtscript
+ignore .saberinit
+ignore don.log
+ignore rtest.good
diff --git a/src/kdc/.saberinit b/src/kdc/.saberinit
new file mode 100644 (file)
index 0000000..2c5e565
--- /dev/null
@@ -0,0 +1,36 @@
+suppress 223
+suppress 285
+suppress 33 on v4_klog
+suppress 34 on v4_klog
+suppress 36 on sendto
+suppress 35
+suppress 287 on usage
+suppress 287 on rcsid_kerberos_c
+suppress 287 on sin
+suppress 349 on krb_err_txt
+suppress 349 on krbONE
+suppress 349 on _ctype_
+suppress 340
+suppress 341
+suppress 346
+suppress 226 on error
+load -G main.o kdc5_err.o kdc_util.o network.o policy.o        -I../include
+load -G do_as_req.o do_tgs_req.o extern.o      -I../include
+make SRCS=dispatch.c saber
+load -G kerberos_v4.c -DBACKWARD_COMPAT -DVARARGS -I../include/kerberosIV -I../include -I../include/stdc-incl
+cd  /site/Don/krb5/kdc
+load -G ../lib/kdb/libkdb.a ../lib/libkrb5.a
+load -G ../lib/des/libdes.a ../lib/os-4.3/libos.a ../lib/crc-32/libcrc32.a
+load -G /mit/isode/isode-6.0/@sys/lib/libisode.a
+load -G -lkrb -ldes -lcom_err
+setopt load_flags -I/mit/krb5/vax-cc/include
+link
+unload /site/Don/krb5/lib/kdb/libkdb.a(decrypt_key.o)
+cd     /site/Don/krb5/lib/kdb
+make SRCS=decrypt_key.c saber
+unload /site/Don/krb5/lib/des/libdes.a(enc_dec.o)
+unload /site/Don/krb5/lib/des/libdes.a(new_rn_key.o)
+cd     /site/Don/krb5/lib/des
+make SRCS=enc_dec.c saber
+make SRCS=new_rn_key.c saber
+run
diff --git a/src/kdc/migration.doc b/src/kdc/migration.doc
new file mode 100644 (file)
index 0000000..d3613ac
--- /dev/null
@@ -0,0 +1,59 @@
+This document describes the protocols & procedures necessary to allow
+a large krb4 site like MIT to migrate smoothly to krb5.
+
+The problem we have to solve is that v4 clients don't know about the v5
+string-to-key function, which incorporates the user's name, instance, and realm
+into his private key, along with his password.
+It happens that our solution also solves a related problem: the v5 str2key
+function prevents a site from changing its realm-name, as when the company gets
+bought by another.
+
+PROTOCOLS:
+
+The compatibilty kdc will mark v5-style entries with an attribute bit.
+
+the v5 get_in_tkt clients (kinit, login, etc) all will be able to perform
+v4 str2key; this will allow users with v4 passwords to gain v5 tickets.
+When a user's entry contains a v5-style password, and he uses v5 kinit,
+the kinit protocol will have the kdc send a cleartext realm-unique string
+(initially null) along with the (password+realm)-encrypted tgt.
+When such a user runs v4 kinit, he loses.
+
+Mapping the realm-name to a realm-id string happens in a kdc-configuration file,
+possibly in the first line of krb.conf .
+
+These things will not happen until we deploy a kpasswd that can replace
+v4-style passwords with v5-style ones.
+It would be nice to provide a "convert" flag, that allows you to upgrade
+without having to change your password's text.
+
+PROCEDURES:
+
+Initially, administrators should deploy the v5 kdc (with its built-in
+v4 compatibility), a v4 kadmin server, and a v5 kadmin server.
+The v5 kadmin server will at this time continue to use the v4 str2key function,
+so all of the passwords in the database will be v4 compatible.
+
+the compatibility versions of the get_in_tkt clients (kinit, login, etc)
+should be deployed when most of the campus' software can handle v5.
+When a v4 user runs v5 kinit, he gets v5 tickets unawares.
+Vice-versa, the user loses.
+
+The users are then weaned from v4 in three (two?) steps:
+   first, we change kpasswd to convert v4-style passwords to v5-style,
+   once the site converts most of its various clients and daemons to v5 krb.
+   the kdc now needs to be able to send a non-null realm-id string to kinit.
+
+   second, we turn off the v4 kadmin server (simultaneous with 1 or 3?).
+
+   third, but optionally, we turn off the v4-compatibility glue in the kdc.
+
+Every user who runs the converting kpasswd becomes unable to run v4 clients
+thereafter; we assume that a user who converts has continued access to
+other v5 clients. the conversion code can warn him.
+
+We continue to run the v4 kadmin because users of v4 kpasswd may not yet have
+ready access to v5 clients.
+
+Note that the database's conversion commences gradually with the deployment
+of the converting kpasswd, so this deployment doesn't have to be instantaneous.
diff --git a/src/krb524/Makefile b/src/krb524/Makefile
new file mode 100644 (file)
index 0000000..6b4a4f1
--- /dev/null
@@ -0,0 +1,75 @@
+# Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+# 
+# Export of this software from the United States of America is assumed
+# to require a specific license from the United States Government.  It
+# is the responsibility of any person or organization contemplating
+# export to obtain such a license before exporting.
+# 
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of Geer Zolot Associates not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  Geer Zolot Associates makes no
+# representations about the suitability of this software for any
+# purpose.  It is provided "as is" without express or implied warranty.
+# 
+# $Id$
+
+KRB5TOP = /ua/software/build/sun4/krb5.src.B2/src
+
+# Library sources
+SRCS   = conv_creds.c conv_princ.c conv_tkt.c conv_tkt_skey.c \
+       encode.c misc.c globals.c sendmsg.c krb524_err.et
+OBJS   = conv_creds.o conv_princ.o conv_tkt.o conv_tkt_skey.o \
+       encode.o misc.o globals.o sendmsg.o krb524_err.o
+
+GENS   = krb524_err.c krb524_err.h
+
+# Server stuff.
+LDFLAGS= -L. -L/usr/local/lib
+LIBS   = -lkrb524 -lkdb5 -lkrb5 -lkrb -lcrypto /usr/local/lib/libdes.a \
+       -lisode -lcom_err
+
+CL_LIBS        = -lkrb524 -lkrb5 -lcrypto -lisode -lkrb -lcom_err
+
+CC     = gcc
+CFLAGS         = -g -DUSE_MASTER -I. -I/usr/local/include
+
+all: libkrb524.a krb524d test k524init
+
+libkrb524.a: $(OBJS)
+       ar cru libkrb524.a $(OBJS)
+       ranlib libkrb524.a
+
+test: libkrb524.a test.o
+       $(CC) -o test $(LDFLAGS) test.o $(LIBS)
+
+krb524d: libkrb524.a krb524d.o
+       $(CC) -o krb524d krb524d.o $(LDFLAGS) $(LIBS)
+
+k524init: libkrb524.a k524init.o
+       $(CC) -o k524init $(LDFLAGS) k524init.o $(CL_LIBS)
+
+krb524d.o: krb524d.c
+       $(CC) -c $(CFLAGS) -I$(KRB5TOP)/include $*.c
+
+test.o: test.c
+       $(CC) -c $(CFLAGS) -I$(KRB5TOP)/include $*.c
+
+depend: $(GENS)
+       makedepend -- $(CFLAGS) -I$(KRB5TOP)/include -- $(SRCS) \
+               test.c krb524d.c
+
+clean:
+       -rm -f libkrb524.a $(OBJS) $(GENS) core *~ *.bak #*
+       -rm -f test krb524d k524init test.o krb524d.o k524init.o
+
+krb524_err.c krb524_err.h: krb524_err.et
+       compile_et krb524_err.et
+
+.SUFFIXES: .et
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/src/krb524/README b/src/krb524/README
new file mode 100644 (file)
index 0000000..6f82931
--- /dev/null
@@ -0,0 +1,120 @@
+Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+
+Export of this software from the United States of America is assumed
+to require a specific license from the United States Government.  It
+is the responsibility of any person or organization contemplating
+export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of Geer Zolot Associates not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  Geer Zolot Associates makes no
+representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied warranty.
+
+$Id$
+
+Kerberos V5 to Kerberos V4 Credentials Converting Service, ALPHA RELEASE
+========================================================================
+
+krb524 is a service that converts Kerberos V5 credentials into
+Kerberos V4 credentials suitable for use with applications that for
+whatever reason do not use V5 directly.  The service consists of a
+server that has access to the secret key of the Kerberos service for
+which credentials will be converted, and a library for use by client
+programs that wish to use the server.
+
+The protocol is simple.  Suppose that a client C wishes to obtain V4
+credentials for a V5 service S by using the krb524 server.  The
+notation {C,S}_n represents a Vn service ticket for S for use by C.
+
+(1) C obtains V5 credentials, including a ticket {C,S}_5, for S by the
+normal V5 means.
+
+(2) C transmits {C,S}_5 to KRB524.
+
+(3) KRB524 converts {C,S}_5 into {C,S}_4.
+
+(4) KRB524 transmits {C,S}_4 to C.
+
+(5) C creates a V4 credentials strucuture from the plaintext
+information in the V5 credential and {C,S}_4.
+
+Steps (2) through (4) are encapsulated in a single function call in
+the krb524 library.
+
+Obviously, not all V5 credentials can be completely converted to V4
+credentials, since the former is a superset of the latter.  The
+precise semantics of the conversion function are still undecided.
+UTSL.
+
+Programs contained in this release
+======================================================================
+
+krb524d [-m[aster]] [-k[eytab]]
+
+The krb524 server.  It accepts UDP requests on the krb524 service
+port, specified in /etc/services, or on port 4444 by default.  (A
+request for an official port assignment is underway.)  The -m argument
+causes krb524d to access the KDC master database directly; the -k
+argument causes krb524d to use the default keytab (and therefore only
+be able to convert tickets for services in the keytab).  Only one of
+-m or -k can be specified.
+
+test -remote server client service
+
+A test program that obtains a V5 credential for {client,service},
+converts it to a V4 credential, and prints out the entire contents of
+both versions.  It prompts for service's secret key, which it needs to
+decrypt both tickets in order to print them out.  Enter it as an eight
+digit ASCII hex number.
+
+k524init [-n] [-p principal]
+
+Convert a V5 credential into a V4 credential and store it in a V4
+ticket file.  The client is 'principal', or krbtgt at the V5 ccache's
+default principal's realm if not specified.  The -n argument causes
+the new ticket to be added to the existing ticket file; otherwise, the
+ticket file is initialized.
+
+Using libkrb524.a
+======================================================================
+
+To use libkrb524.a, #include <krb524.h>, link against libkrb524.a,
+call krb524_init_ets() at the beginning of your program, and call one
+of the following two functions:
+
+int krb524_convert_creds_addr(krb5_creds *v5creds, CREDENTIALS *v4creds,
+                        struct sockaddr *saddr)
+
+int krb524_convert_creds_kdc(krb5_creds *v5creds, CREDENTIALS *v4creds)
+
+Both convert the V5 credential in v5creds into a V4 credential in
+v4creds.  One assumes krb524d is running on the KDC, the other uses an
+explicit host.  You only need to specify the address for saddr; the
+port is filled in automatically.
+
+Unresolved issues / Bugs
+======================================================================
+
+o krb524d requires access to the secret key of any service to be
+converted.  Should krb524d run on the KDC or on individual server
+machines?  The latter is more paranoid, since it prevents bugs in
+krb524d from provided unauthorized access to the master database.
+However, it also requires the client to provide the address of the
+server to be used.  The client will usually have this information
+(since presumably it will be sending the converted V4 credentials to
+the same server) but it may not be in a convenient form.  It seems
+"cleaner" to have krb524d run on the KDC.
+
+o Even if krb524d uses keytabs on server machines, it needs to be more
+flexible.  You only want to run one krb524d per host, so it has to be
+able to scan multiple keytabs.  This might get logistically messy.
+
+o This code is of alpha quality.  Bugs, omissions, memory leaks, and
+perhaps security holes still remain.  Do not use it (yet) in a
+production environment.
diff --git a/src/krb524/RELEASE_NOTES b/src/krb524/RELEASE_NOTES
new file mode 100644 (file)
index 0000000..cd462b6
--- /dev/null
@@ -0,0 +1,17 @@
+$Id$
+
+Kerberos V5 to Kerberos V4 Credentials Converting Service, ALPHA RELEASE
+========================================================================
+
+This is the ALPHA RELEASE of krb524.  Treat it accordingly.
+
+Soon, krb524 will be integrated into the standard MIT Kerberos 5
+distribution.  krb524's existence as a distinct distribution is
+temporary.
+
+If you have any questions, contact
+
+Barry Jaspan, bjaspan@gza.com
+Geer Zolot Associates
+(617) 374-3700
+
diff --git a/src/krb524/conv_creds.c b/src/krb524/conv_creds.c
new file mode 100644 (file)
index 0000000..ce36f30
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+int krb524_convert_creds_addr(krb5_creds *v5creds, CREDENTIALS *v4creds,
+                        struct sockaddr *saddr)
+{
+     int ret;
+
+     if (ret = krb524_convert_creds_plain(v5creds, v4creds))
+         return ret;
+
+     return krb524_convert_tkt(v5creds->server, &v5creds->ticket,
+                              &v4creds->ticket_st,
+                              &v4creds->kvno,
+                              saddr);
+}
+
+int krb524_convert_creds_kdc(krb5_creds *v5creds, CREDENTIALS *v4creds)
+{
+     struct sockaddr_in *addrs;
+     int ret, naddrs;
+
+     if (ret = krb5_locate_kdc(&v5creds->server->realm, &addrs, &naddrs))
+         return ret;
+     if (naddrs == 0)
+         ret = KRB5_KDC_UNREACH;
+     else {
+         addrs[0].sin_port = 0; /* use krb524 default port */
+         ret = krb524_convert_creds_addr(v5creds, v4creds,
+                                         (struct sockaddr *) &addrs[0]);
+     }
+     
+     free(addrs);
+     return ret;
+}
+
+int krb524_convert_creds_plain(krb5_creds *v5creds, CREDENTIALS *v4creds)
+{
+     unsigned long addr;
+     krb5_data *comp;
+     int ret;
+     
+     bzero((char *) v4creds, sizeof(CREDENTIALS));
+
+     if (ret = krb524_convert_princs(v5creds->client, v5creds->server,
+                                    v4creds->pname, v4creds->pinst,
+                                    v4creds->realm, v4creds->service,
+                                    v4creds->instance))
+         return ret;
+
+     /* Check keytype too */
+     if (v5creds->keyblock.length != sizeof(C_Block)) {
+         if (krb524_debug)
+              fprintf(stderr, "v5 session keyblock length %d != "
+                      "C_Block size %d\n", v5creds->keyblock.length,
+                      sizeof(C_Block));
+         return KRB524_BADKEY;
+     } else
+         bcopy((char *) v5creds->keyblock.contents, v4creds->session,
+               sizeof(C_Block));
+
+     /* V4 has no concept of authtime or renew_till, so ignore them */
+     /* V4 lifetime is 1 byte, in 5 minute increments */
+     v4creds->lifetime = 0xff &
+         ((v5creds->times.endtime - v5creds->times.starttime) / 300);
+     v4creds->issue_date = v5creds->times.starttime;
+
+     /* XXX perhaps we should use the addr of the client host if */
+     /* v5creds contains more than one addr.  Q: Does V4 support */
+     /* non-INET addresses? */
+     if (!v5creds->addresses || !v5creds->addresses[0] ||
+        v5creds->addresses[0]->addrtype != ADDRTYPE_INET ||
+        v5creds->addresses[0]->length != sizeof(addr)) {
+         if (krb524_debug)
+              fprintf(stderr, "Invalid v5creds address information.\n");
+         return KRB524_BADADDR;
+     } else
+         bcopy(v5creds->addresses[0]->contents, (char *) &addr,
+               sizeof(addr));
+
+     return 0;
+}
diff --git a/src/krb524/conv_princ.c b/src/krb524/conv_princ.c
new file mode 100644 (file)
index 0000000..82d589b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+int krb524_convert_princs(krb5_principal client, krb5_principal
+                         server, char *pname, char *pinst, char
+                         *prealm, char *sname, char *sinst)
+{
+     char dummy[REALM_SZ];
+     int ret;
+     
+     if (ret = krb5_524_conv_principal(client, pname, pinst, prealm))
+         return ret;
+     
+     return krb5_524_conv_principal(server, sname, sinst, dummy);
+}
diff --git a/src/krb524/conv_tkt.c b/src/krb524/conv_tkt.c
new file mode 100644 (file)
index 0000000..1332a23
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * krb524_convert_tkt.  Open a network connection to krb524d, send it
+ * the V5 ticket, receive the V4 ticket in response.
+ */
+int krb524_convert_tkt(krb5_principal server, krb5_data *v5tkt,
+                      KTEXT_ST *v4tkt,
+                      int *kvno,
+                      struct sockaddr_in *saddr)
+{
+     char *p;
+     krb5_data reply;
+     struct servent *serv;
+     int ret, status;
+
+     reply.data = NULL;
+
+     if (saddr->sin_port == 0) {
+         serv = getservbyname(KRB524_SERVICE, "udp");
+         if (serv)
+              saddr->sin_port = serv->s_port;
+         else
+              saddr->sin_port = htons(KRB524_PORT);
+     }
+
+     if (ret = krb524_send_message(saddr, v5tkt, &reply))
+         goto fail;
+     
+     p = reply.data;
+     status = ntohl(*((krb5_error_code *) p));
+     p += sizeof(krb5_error_code);
+     reply.length -= sizeof(krb5_error_code);
+     if (status) {
+         ret = status;
+         goto fail;
+     }
+     *kvno = ntohl(*((krb5_error_code *) p));
+     p += sizeof(int);
+     reply.length -= sizeof(int);
+     ret = decode_v4tkt(v4tkt, p, &reply.length);
+
+fail:
+     if (ret) {
+         if (reply.data) 
+              free(reply.data);
+         reply.data = NULL;
+         reply.length = 0;
+     }
+
+     return ret;
+}
+
diff --git a/src/krb524/conv_tkt_skey.c b/src/krb524/conv_tkt_skey.c
new file mode 100644 (file)
index 0000000..ac6a1b9
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * Convert a v5 ticket for server to a v4 ticket, using service key
+ * skey for both.
+ */
+int krb524_convert_tkt_skey(krb5_ticket *v5tkt, KTEXT_ST *v4tkt,
+                           krb5_keyblock *skey)
+{
+     char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+     char sname[ANAME_SZ], sinst[INST_SZ];
+     krb5_enc_tkt_part *v5etkt;
+     krb5_data *comp;
+     int ret, lifetime;
+
+     v5tkt->enc_part2 = NULL;
+     if (ret = krb5_decrypt_tkt_part(skey, v5tkt)) {
+         krb5_free_ticket(v5tkt);
+         return ret;
+     }
+     v5etkt = v5tkt->enc_part2;
+
+     if (ret = krb524_convert_princs(v5etkt->client, v5tkt->server,
+                                    pname, pinst, prealm, sname,
+                                    sinst)) {
+         krb5_free_enc_tkt_part(v5etkt);
+         v5tkt->enc_part2 = NULL;
+         return ret;
+     }
+     
+     if (v5etkt->session->keytype != KEYTYPE_DES ||
+        v5etkt->session->length != sizeof(C_Block)) {
+         if (krb524_debug)
+              fprintf(stderr, "v5 session keyblock type %d length %d != "
+                      "C_Block size %d\n", v5etkt->session->keytype,
+                      v5etkt->session->length,
+                      sizeof(C_Block));
+         krb5_free_enc_tkt_part(v5etkt);
+         v5tkt->enc_part2 = NULL;
+         return KRB524_BADKEY;
+     }
+     
+     /* V4 has no concept of authtime or renew_till, so ignore them */
+     /* V4 lifetime is 1 byte, in 5 minute increments */
+     if (v5etkt->times.starttime == 0)
+         v5etkt->times.starttime = v5etkt->times.authtime;
+     lifetime = 0xff &
+         ((v5etkt->times.endtime - v5etkt->times.authtime) / 300);
+
+     /* XXX perhaps we should use the addr of the client host if */
+     /* v5creds contains more than one addr.  Q: Does V4 support */
+     /* non-INET addresses? */
+     if (!v5etkt->caddrs || !v5etkt->caddrs[0] ||
+        v5etkt->caddrs[0]->addrtype != ADDRTYPE_INET) {
+         if (krb524_debug)
+              fprintf(stderr, "Invalid v5creds address information.\n");
+         krb5_free_enc_tkt_part(v5etkt);
+         v5tkt->enc_part2 = NULL;
+         return KRB524_BADADDR;
+     }
+     
+     if (krb524_debug)
+       printf("startime = %ld, authtime = %ld, lifetime = %ld\n",
+              (long) v5etkt->times.starttime,
+              (long) v5etkt->times.authtime,
+              (long) lifetime);
+
+     /* XXX are there V5 flags we should map to V4 equivalents? */
+     ret = krb_create_ticket(v4tkt,
+                            0, /* flags */                          
+                            pname,
+                            pinst,
+                            krb5_princ_realm(v5etkt->client),
+                            *((unsigned long *)v5etkt->caddrs[0]->contents),
+                            v5etkt->session->contents,
+                            lifetime,
+                            /* issue_data */
+                            v5etkt->times.starttime,
+                            sname,
+                            sinst,
+                            skey->contents);
+
+     krb5_free_enc_tkt_part(v5etkt);
+     v5tkt->enc_part2 = NULL;
+     if (ret == KSUCCESS)
+         return 0;
+     else
+         return KRB524_V4ERR;
+}
diff --git a/src/krb524/encode.c b/src/krb524/encode.c
new file mode 100644 (file)
index 0000000..f14fa6d
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * I'm sure that this is reinventing the wheel, but I don't know where
+ * the wheel is hidden.
+ */
+
+int  encode_v4tkt(KTEXT_ST *, char *, int *),
+     encode_ktext(char **, int *, KTEXT_ST *),
+     encode_bytes(char **, int *, char *, int),
+     encode_int32(char **, int *, krb5_int32 *);
+
+int  decode_v4tkt(KTEXT_ST *, char *, int *),
+     decode_ktext(char **, int *, KTEXT_ST *),
+     decode_bytes(char **, int *, char *, int),
+     decode_int32(char **, int *, krb5_int32 *);
+
+int encode_bytes(char **out, int *outlen, char *in, int len)
+{
+     if (len > *outlen)
+         return KRB524_ENCFULL;
+     bcopy(in, *out, len);
+     *out += len;
+     *outlen -= len;
+     return 0;
+}
+
+int encode_int32(char **out, int *outlen, krb5_int32 *v)
+{
+     int ret;
+     int nv;
+
+     nv = htonl(*v);
+     return encode_bytes(out, outlen, (char *) &nv, sizeof(nv));
+}
+
+int encode_v4tkt(KTEXT_ST *v4tkt, char *buf, int *encoded_len)
+{
+     int buflen, ret;
+
+     buflen = *encoded_len;
+
+     if (ret = encode_int32(&buf, &buflen, &v4tkt->length))
+         return ret;
+     if (ret = encode_bytes(&buf, &buflen, v4tkt->dat, MAX_KTXT_LEN))
+         return ret;
+     if (ret = encode_int32(&buf, &buflen, &v4tkt->mbz))
+         return ret;
+
+     *encoded_len -= buflen;
+     return 0;
+}
+
+/* decode functions */
+
+int decode_bytes(char **out, int *outlen, char *in, int len)
+{
+     if (len > *outlen)
+         return KRB524_DECEMPTY;
+     bcopy(*out, in, len);
+     *out += len;
+     *outlen -= len;
+     return 0;
+}
+
+int decode_int32(char **out, int *outlen, krb5_int32 *v)
+{
+     int ret;
+     int nv;
+
+     if (ret = decode_bytes(out, outlen, (char *) &nv, sizeof(nv)))
+         return ret;
+     *v = ntohl(nv);
+     return 0;
+}
+
+int decode_v4tkt(KTEXT_ST *v4tkt, char *buf, int *encoded_len)
+{
+     int buflen, ret;
+
+     buflen = *encoded_len;
+     if (ret = decode_int32(&buf, &buflen, &v4tkt->length))
+         return ret;
+     if (ret = decode_bytes(&buf, &buflen, v4tkt->dat, MAX_KTXT_LEN))
+         return ret;
+     if (ret = decode_int32(&buf, &buflen, &v4tkt->mbz))
+         return ret;
+     *encoded_len -= buflen;
+     return 0;
+}
+
diff --git a/src/krb524/getcred.c b/src/krb524/getcred.c
new file mode 100644 (file)
index 0000000..e81ef25
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+main(int argc, char **argv)
+{
+     krb5_principal client, server;
+     krb5_ccache cc;
+     krb5_creds v5creds;
+     CREDENTIALS v4creds;
+     int i, ret;
+
+     krb524_init_ets();
+
+     if (ret = krb5_parse_name(argv[1], &client)) {
+         com_err("getcred", ret, "parsing client name");
+         exit(1);
+     }
+     if (ret = krb5_parse_name(argv[2], &server)) {
+         com_err("getcred", ret, "parsing server name");
+         exit(1);
+     }
+     if (ret = krb5_cc_default(&cc)) {
+         com_err("getcred", ret, "opening default credentials cache");
+         exit(1);
+     }
+
+     bzero((char *) &v5creds, sizeof(v5creds));
+     v5creds.client = client;
+     v5creds.server = server;
+     v5creds.times.endtime = 0;
+     v5creds.keyblock.keytype = KEYTYPE_DES;
+     if (ret = krb5_get_credentials(0, cc, &v5creds)) {
+         com_err("getcred", ret, "getting V5 credentials");
+         exit(1);
+     }
+
+     if (ret = krb524_convert_creds_kdc(&v5creds, &v4creds)) {
+         com_err("getcred", ret, "converting to V4 credentials");
+         exit(1);
+     }
+     
+     return 0;
+}
diff --git a/src/krb524/globals.c b/src/krb524/globals.c
new file mode 100644 (file)
index 0000000..eb7884a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+int krb524_debug = 0;
diff --git a/src/krb524/k524init.c b/src/krb524/k524init.c
new file mode 100644 (file)
index 0000000..39045e5
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+extern int optind;
+extern char *optarg;
+
+#if !defined(lint) && !defined(SABER)
+const char rcsid[] = "$Id$";
+#endif
+
+main(int argc, char **argv)
+{
+     krb5_principal client, server;
+     krb5_ccache cc;
+     krb5_creds v5creds;
+     CREDENTIALS v4creds;
+     int code;
+     int option;
+     char *princ = NULL;
+     int nodelete = 0;
+     int lose = 0;
+
+     while((option =  getopt(argc, argv, "p:n")) != EOF) {
+        switch(option) {
+          case 'p':
+            princ = optarg;
+            break;
+          case 'n':
+            nodelete++;
+            break;
+          default:
+            lose++;
+            break;
+        }
+     }
+
+     if (lose || (argc - optind > 1)) {
+        fprintf(stderr, "Usage: k524init [-p principal]\n");
+        exit(1);
+     }
+
+     krb524_init_ets();
+
+     if (code = krb5_cc_default(&cc)) {
+         com_err("k524init", code, "opening default credentials cache");
+         exit(1);
+     }
+
+     if (code = krb5_cc_get_principal(cc, &client)) {
+        com_err("k524init", code, "while retrieving user principal name");
+        exit(1);
+     }
+
+     if (princ) {
+        if (code = krb5_parse_name(princ, &server)) {
+            com_err("k524init", code, "while parsing service principal name");
+            exit(1);
+        }
+     } else {
+        if (code = krb5_build_principal(&server, 
+                                        krb5_princ_realm(client)->length,
+                                        krb5_princ_realm(client)->data,
+                                        "krbtgt",
+                                        krb5_princ_realm(client)->data,
+                                        NULL)) {
+            com_err("k524init", code, "while creating service principal name");
+            exit(1);
+        }
+     }
+
+     bzero((char *) &v5creds, sizeof(v5creds));
+     v5creds.client = client;
+     v5creds.server = server;
+     v5creds.times.endtime = 0;
+     v5creds.keyblock.keytype = KEYTYPE_DES;
+     if (code = krb5_get_credentials(0, cc, &v5creds)) {
+         com_err("k524init", code, "getting V5 credentials");
+         exit(1);
+     }
+
+     if (code = krb524_convert_creds_kdc(&v5creds, &v4creds)) {
+         com_err("k524init", code, "converting to V4 credentials");
+         exit(1);
+     }
+     
+     /* this is stolen from the v4 kinit */
+
+     if (!nodelete) {
+       /* initialize ticket cache */
+       if (code = in_tkt(v4creds.pname,v4creds.pinst) != KSUCCESS) {
+          com_err("k524init", code, "trying to create the V4 ticket file");
+          exit(1);
+       }
+     }
+
+     /* stash ticket, session key, etc. for future use */
+     if (code = save_credentials(v4creds.service, v4creds.instance,
+                                v4creds.realm, v4creds.session,
+                                v4creds.lifetime, v4creds.kvno,
+                                &(v4creds.ticket_st), v4creds.issue_date)) {
+        com_err("k524init", code, "trying to save the V4 ticket");
+        exit(1);
+     }
+
+     exit(0);
+}
diff --git a/src/krb524/krb524.h b/src/krb524/krb524.h
new file mode 100644 (file)
index 0000000..2b9a3b6
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __KRB524_H__
+#define __KRB524_H__
+
+/*
+ * $Id$
+ */
+
+#define KRB524_SERVICE "krb524"
+#define KRB524_PORT 4444
+
+#include <krb524_err.h>
+
+extern int krb524_debug;
+
+#endif /* __KRB524_H__ */
diff --git a/src/krb524/krb524_err.et b/src/krb524/krb524_err.et
new file mode 100644 (file)
index 0000000..237d084
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+# 
+# Export of this software from the United States of America is assumed
+# to require a specific license from the United States Government.  It
+# is the responsibility of any person or organization contemplating
+# export to obtain such a license before exporting.
+# 
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of Geer Zolot Associates not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  Geer Zolot Associates makes no
+# representations about the suitability of this software for any
+# purpose.  It is provided "as is" without express or implied warranty.
+# 
+# $Id$
+
+error_table k524
+
+error_code KRB524_BADKEY, "Cannot convert V5 keyblock"
+error_code KRB524_BADADDR, "Cannot convert V5 address information"
+error_code KRB524_BADPRINC, "Cannot convert V5 principal"
+error_code KRB524_BADREALM, "V5 realm name longer than V4 maximum"
+error_code KRB524_V4ERR, "Kerberos V4 error"
+error_code KRB524_ENCFULL, "Encoding too large"
+error_code KRB524_DECEMPTY, "Decoding out of data"
+error_code KRB524_NOTRESP, "Service not responding"
+
+end
diff --git a/src/krb524/krb524_prot b/src/krb524/krb524_prot
new file mode 100644 (file)
index 0000000..f83854d
--- /dev/null
@@ -0,0 +1,11 @@
+Protocol:
+
+       -> ASN.1 encoded V5 ticket
+       <- int status_code, [int kvno, encode_v4tkt encoded KTEXT_ST]
+
+kvno and V4 ticket are only included if status_code is zero.
+
+The kvno for the converted ticket is sent explicitly because the field
+is ASN.1 encoded in the krb5_creds structure; the client would have to
+decode (but not decrypt) the entire krb5_ticket structure to get it,
+which would be inefficient.
diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c
new file mode 100644 (file)
index 0000000..c681758
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+#include <krb5/kdb.h>
+#include <krb5/kdb_dbm.h>
+#ifdef PROVIDE_DES_CBC_CRC
+#include <krb5/mit-des.h>
+#endif
+#include <krb.h>
+
+#include "krb524.h"
+
+#define TIMEOUT 60
+#define TKT_BUFSIZ 2048
+#define MSGSIZE 8192
+
+char *whoami;
+int signalled = 0;
+static int debug = 0;
+
+int use_keytab;
+char *keytab = NULL;
+krb5_keytab kt;
+
+int use_master;
+krb5_principal master_princ;
+krb5_encrypt_block master_encblock;
+krb5_keyblock master_keyblock;
+
+void init_keytab(), init_master();
+krb5_error_code do_connection(), lookup_service_key(), kdc_get_server_key();
+
+void usage()
+{
+     fprintf(stderr, "Usage: %s [-m[aster]] [-k[eytab]]\n", whoami);
+     cleanup_and_exit(1);
+}
+
+int request_exit()
+{
+     signalled = 1;
+}
+
+int krb5_free_keyblock_contents(krb5_keyblock *key)
+{
+     memset(key->contents, 0, key->length);
+     xfree(key->contents);
+     return 0;
+}
+
+main(int argc, char **argv)
+{
+     struct servent *serv;
+     struct sockaddr_in saddr;
+     struct timeval timeout;
+     int ret, s, conn;
+     fd_set rfds;
+     
+     krb5_init_ets();
+
+     whoami = ((whoami = strrchr(argv[0], '/')) ? whoami + 1 : argv[0]);
+
+     argv++; argc--;
+     use_master = use_keytab = 0;
+     while (argc) {
+         if (strncmp(*argv, "-k", 2) == 0)
+              use_keytab = 1;
+         else if (strncmp(*argv, "-m", 2) == 0)
+              use_master = 1;
+         else
+              break;
+         argv++; argc--;
+     }
+     if (argc || use_keytab + use_master > 1 ||
+        use_keytab + use_master == 0)
+         usage();
+     
+     signal(SIGINT, request_exit);
+     signal(SIGHUP, request_exit);
+     signal(SIGTERM, request_exit);
+
+     if (use_keytab)
+         init_keytab();
+     if (use_master)
+         init_master();
+
+     bzero((char *) &saddr, sizeof(struct sockaddr_in));
+     saddr.sin_family = AF_INET;
+     saddr.sin_addr.s_addr = INADDR_ANY;
+     serv = getservbyname(KRB524_SERVICE, "udp");
+     if (serv == NULL) {
+         com_err(whoami, 0, "service entry not found, using %d", KRB524_PORT);
+         saddr.sin_port = htons(KRB524_PORT);
+     } else
+         saddr.sin_port = serv->s_port;
+         
+     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+         com_err(whoami, errno, "creating main socket");
+         cleanup_and_exit(1);
+     }
+     if ((ret = bind(s, (struct sockaddr *) &saddr,
+                    sizeof(struct sockaddr_in))) < 0) {
+         com_err(whoami, errno, "binding main socket");
+         cleanup_and_exit(1);
+     }
+     
+     timeout.tv_sec = TIMEOUT;
+     timeout.tv_usec = 0;
+     while (1) {
+         FD_ZERO(&rfds);
+         FD_SET(s, &rfds);
+
+         ret = select(s+1, &rfds, NULL, NULL, &timeout);
+         if (signalled)
+              cleanup_and_exit(0);
+         else if (ret == 0) {
+              if (use_master) {
+                   ret = krb5_dbm_db_fini();
+                   if (ret && ret != KRB5_KDB_DBNOTINITED) {
+                        com_err(whoami, ret, "closing kerberos database");
+                        cleanup_and_exit(1);
+                   }
+              }
+         } else if (ret < 0 && errno != EINTR) {
+              com_err(whoami, errno, "in select");
+              cleanup_and_exit(1);
+         } else if (FD_ISSET(s, &rfds)) {
+              if (debug)
+                   printf("received packet\n");
+              if (ret = do_connection(s)) {
+                   com_err(whoami, ret, "handling packet");
+              }
+         } else
+              com_err(whoami, 0, "impossible situation occurred!");
+     }
+
+     return cleanup_and_exit(0);
+}
+
+int cleanup_and_exit(int ret)
+{
+     if (use_master) {
+         krb5_finish_key(&master_encblock);
+         memset((char *)&master_encblock, 0, sizeof(master_encblock));
+         (void) krb5_db_fini();
+     }
+     exit(ret);
+}
+
+void init_keytab()
+{
+     int ret;
+     if (keytab == NULL) {
+         if (ret = krb5_kt_default(&kt)) {
+              com_err(whoami, ret, "while opening default keytab");
+              cleanup_and_exit(1);
+         }
+     } else {
+         if (ret = krb5_kt_resolve(keytab, &kt)) {
+              com_err(whoami, ret, "while resolving keytab %s",
+                      keytab);
+              cleanup_and_exit(1);
+         }
+     }
+}
+
+void init_master()
+{
+     int ret;
+     char *realm;
+     
+     if (ret = krb5_get_default_realm(&realm)) {
+         com_err(whoami, ret, "getting default realm");
+         cleanup_and_exit(1);
+     }
+     if (ret = krb5_db_setup_mkey_name(NULL, realm, (char **) 0,
+                                      &master_princ)) {
+         com_err(whoami, ret, "while setting up master key name");
+         cleanup_and_exit(1);
+     }
+
+#ifdef PROVIDE_DES_CBC_CRC
+     master_encblock.crypto_entry = &mit_des_cryptosystem_entry;
+#else
+     error(You gotta figure out what cryptosystem to use in the KDC);
+#endif
+
+     master_keyblock.keytype = KEYTYPE_DES;
+     if (ret = krb5_db_fetch_mkey(master_princ, &master_encblock,
+                                 FALSE, /* non-manual type-in */
+                                 FALSE, /* irrelevant, given prev. arg */
+                                 0, &master_keyblock)) {
+         com_err(whoami, ret, "while fetching master key");
+         cleanup_and_exit(1);
+     }
+
+     if (ret = krb5_db_init()) {
+         com_err(whoami, ret, "while initializing master database");
+         cleanup_and_exit(1);
+     }
+     if (ret = krb5_process_key(&master_encblock, &master_keyblock)) {
+         krb5_db_fini();
+         com_err(whoami, ret, "while processing master key");
+         cleanup_and_exit(1);
+     }
+}
+
+krb5_error_code do_connection(int s)
+{
+     struct sockaddr saddr;
+     krb5_ticket *v5tkt;
+     KTEXT_ST v4tkt;
+     krb5_keyblock service_key;
+     krb5_data msgdata, tktdata;
+     char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p;
+     int n, ret, saddrlen;
+     
+     msgdata.data = msgbuf;
+     msgdata.length = MSGSIZE;
+
+     saddrlen = sizeof(struct sockaddr);
+     ret = recvfrom(s, msgdata.data, msgdata.length, 0, &saddr, &saddrlen);
+     if (ret < 0) {
+         ret = errno;
+         goto error;
+     }
+     if (debug)
+         printf("message received\n");
+
+     if (ret = decode_krb5_ticket(&msgdata, &v5tkt))
+         goto error;
+     if (debug)
+         printf("V5 ticket decoded\n");
+     
+     if (ret = lookup_service_key(v5tkt->server, &service_key))
+         goto error;
+     if (debug)
+         printf("service key retrieved\n");
+
+     ret = krb524_convert_tkt_skey(v5tkt, &v4tkt, &service_key);
+     if (ret)
+         goto error;
+     krb5_free_keyblock_contents(&service_key);
+     krb5_free_ticket(v5tkt);
+     if (debug)
+         printf("credentials converted\n");
+
+     tktdata.data = tktbuf;
+     tktdata.length = TKT_BUFSIZ;
+     ret = encode_v4tkt(&v4tkt, tktdata.data, &tktdata.length);
+     if (ret)
+         goto error;
+     if (debug)
+         printf("v4 credentials encoded\n");
+
+error:
+     /* create the reply */
+     p = msgdata.data;
+     msgdata.length = 0;
+     
+     n = htonl(ret);
+     memcpy(p, (char *) &n, sizeof(int));
+     p += sizeof(int);
+     msgdata.length += sizeof(int);
+
+     if (ret)
+         goto write_msg;
+
+     n = htonl(v5tkt->enc_part.kvno);
+     memcpy(p, (char *) &n, sizeof(int));
+     p += sizeof(int);
+     msgdata.length += sizeof(int);
+
+     memcpy(p, tktdata.data, tktdata.length);
+     p += tktdata.length;
+     msgdata.length += tktdata.length;
+
+write_msg:
+     if (ret)
+         (void) sendto(s, msgdata.data, msgdata.length, 0, &saddr, saddrlen);
+     else
+         if (sendto(s, msgdata.data, msgdata.length, 0, &saddr, saddrlen)<0)
+              ret = errno;
+     if (debug)
+         printf("reply written\n");
+              
+     return ret;
+}
+
+krb5_error_code lookup_service_key(krb5_principal p, krb5_keyblock *key)
+{
+     int ret;
+     krb5_keytab_entry entry;
+
+     if (use_keytab) {
+         if (ret = krb5_kt_get_entry(kt, p, 0, &entry))
+              return ret;
+         bcopy((char *) &entry.key, key, sizeof(krb5_keyblock));
+         return 0;
+     } else if (use_master) {
+         if (ret = krb5_dbm_db_init())
+              return ret;
+         return kdc_get_server_key(p, key, NULL);
+     }
+}
+
+/* taken from kdc/kdc_util.c, and modified somewhat */
+krb5_error_code kdc_get_server_key(service, key, kvno)
+   krb5_principal service;
+   krb5_keyblock *key;
+   krb5_kvno *kvno;
+{
+     krb5_error_code ret;
+     int nprincs;
+     krb5_db_entry server;
+     krb5_boolean more;
+
+     nprincs = 1;
+     if (ret = krb5_db_get_principal(service, &server, &nprincs, &more)) 
+         return(ret);
+     
+     if (more) {
+         krb5_db_free_principal(&server, nprincs);
+         return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
+     } else if (nprincs != 1) {
+         krb5_db_free_principal(&server, nprincs);
+         return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+     }
+
+     /*
+      * convert server.key into a real key (it is encrypted in the
+      * database)
+      */
+     ret = KDB_CONVERT_KEY_OUTOF_DB(&server.key, key);
+     if (kvno)
+         *kvno = server.kvno;
+     krb5_db_free_principal(&server, nprincs);
+     return ret;
+}
diff --git a/src/krb524/misc.c b/src/krb524/misc.c
new file mode 100644 (file)
index 0000000..75a2755
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include "krb524.h"
+
+void krb524_init_ets()
+{
+     krb5_init_ets();
+     initialize_k524_error_table();
+}
diff --git a/src/krb524/sendmsg.c b/src/krb524/sendmsg.c
new file mode 100644 (file)
index 0000000..9b21082
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America is assumed
+ *   to require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ * Send a packet to a service and await a reply, using an exponential
+ * backoff retry algorithm.  This is based on krb5_sendto_kdc.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <krb5/los-proto.h>
+
+#ifdef _AIX
+#include <sys/select.h>
+#endif
+
+#include "krb524.h"
+
+/*
+ * Send the formatted request 'message' to the host/port specified in
+ * addr and return the response (if any) in 'reply'.
+ *
+ * If the message is sent and a response is received, 0 is returned,
+ * otherwise an error code is returned.
+ *
+ * The storage for 'reply' is allocated and should be freed by the caller
+ * when finished.
+ */
+
+extern int krb5_max_dgram_size;
+extern int krb5_max_skdc_timeout;
+extern int krb5_skdc_timeout_shift;
+extern int krb5_skdc_timeout_1;
+
+int krb524_send_message (DECLARG(const struct sock addr *, addr),
+                        DECLARG(const krb5_data *, message),
+                        DECLARG(krb5_data *, reply))
+   OLDDECLARG(const struct sockaddr *, addr)
+   OLDDECLARG(const krb5_data *, message)
+   OLDDECLARG(krb5_data *, reply)
+{
+    register int timeout;
+    int nready, received;
+    krb5_error_code retval;
+    fd_set readable;
+    struct timeval waitlen;
+    int s, cc;
+    
+    if ((reply->data = malloc(krb5_max_dgram_size)) == NULL)
+       return ENOMEM;
+    reply->length = krb5_max_dgram_size;
+
+    /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the */
+    /* socket creation here will work properly... */
+    s = socket(addr->sa_family, SOCK_DGRAM, 0);
+    if (s == -1) {
+        retval = errno;
+        goto out;
+    }
+    
+    /*
+     * On BSD systems, a connected UDP socket will get connection
+     * refused and net unreachable errors while an unconnected socket
+     * will time out, so use connect, send, recv instead of sendto,
+     * recvfrom.  The connect here may return an error if the
+     * destination host is known to be unreachable.
+     */
+    if (connect(s, addr, sizeof(struct sockaddr)) == -1) {
+        retval = errno;
+        goto out;
+    }
+        
+    /*
+     * Send the message, and wait for a reply, using an exponential
+     * backoff.  Use the kdc timeout values, just for consistency.
+     */
+
+    received = 0;
+    for (timeout = krb5_skdc_timeout_1;
+        timeout < krb5_max_skdc_timeout;
+        timeout <<= krb5_skdc_timeout_shift) {
+        
+        if (send(s, message->data, message->length, 0) != message->length) {
+             retval = errno;
+             goto out;
+        }
+        
+        waitlen.tv_usec = 0;
+        waitlen.tv_sec = timeout;
+        FD_ZERO(&readable);
+        FD_SET(s, &readable);
+        nready = select(1 + s, &readable, 0, 0, &waitlen);
+        if (nready < 0) {
+             retval = errno;
+             goto out;
+        } else if (nready == 1) {
+             if ((cc = recv(s, reply->data, reply->length, 0)) == -1) { 
+                  retval = errno;
+                  goto out;
+             }
+
+             /*
+              * We might consider here verifying that the reply came
+              * from the host specified, but that check can be fouled
+              * by some implementations of some network types which
+              * might show a loopback return address, for example, if
+              * the server is on the same host as the client.
+              *
+              * Besides, reply addresses can be spoofed, and we don't
+              * want to provide a false sense of security.
+              */
+             reply->length = cc;
+             retval = 0;
+             goto out;
+        }
+        /* else timeout, try again */
+    }
+
+    /* If the loop exits normally, the max timeout expired without */
+    /* a reply having arrived.  */
+    retval = KRB524_NOTRESP;
+
+out:
+    (void) close(s);
+    if (retval) {
+        free(reply->data);
+        reply->data = 0;
+        reply->length = 0;
+    }
+    return retval;
+}
diff --git a/src/krb524/test.c b/src/krb524/test.c
new file mode 100644 (file)
index 0000000..56a675d
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates.  All Rights Reserved.
+ * 
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.  It
+ * is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <des.h>
+#include <krb.h>
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+
+#include "krb524.h"
+
+#define KEYSIZE 8
+#define CRED_BUFSIZ 2048
+
+#define krb5_print_addrs
+
+void do_local(krb5_creds *, krb5_keyblock *),
+     do_remote(krb5_creds *, char *, krb5_keyblock *);
+
+void print_key(char *msg, char *key)
+{
+     printf("%s: ", msg);
+     C_Block_print(key);
+     printf("\n");
+}
+
+void print_time(char *msg, int t)
+{
+     printf("%s: %d, %s", msg, t, ctime(&t));
+}
+
+void krb5_print_times(char *msg, krb5_ticket_times *t)
+{
+     printf("%s: Start: %d, %s", msg, t->starttime, ctime(&t->starttime));
+     printf("%s: End: %d, %s", msg, t->endtime, ctime(&t->endtime));
+     printf("%s: Auth: %d, %s", msg, t->authtime, ctime(&t->authtime));
+     printf("%s: Renew: %d, %s", msg, t->renew_till, ctime(&t->renew_till));
+}
+
+void krb5_print_keyblock(char *msg, krb5_keyblock *key)
+{
+     printf("%s: Keytype: %d\n", msg, key->keytype);
+     printf("%s: Length: %d\n", msg, key->length);
+     printf("%s: Key: ", msg);
+     C_Block_print(key->contents);
+     printf("\n");
+}
+
+void krb5_print_ticket(krb5_data *ticket_data, krb5_keyblock *key)
+{
+     char *p;
+     krb5_ticket *tkt;
+     int ret;
+
+     if (ret = decode_krb5_ticket(ticket_data, &tkt)) {
+         com_err("test", ret, "decoding ticket");
+         exit(1);
+     }
+     if (ret = krb5_decrypt_tkt_part(key, tkt)) {
+         com_err("test", ret, "decrypting V5 ticket for print");
+         exit(1);
+     }
+     
+     krb5_unparse_name(tkt->server, &p);
+     printf("Ticket: Server: %s\n", p);
+     free(p);
+     printf("Ticket: EType: %d\n", tkt->enc_part.etype);
+     printf("Ticket: kvno: %d\n", tkt->enc_part.kvno);
+     printf("Ticket: Flags: 0x%08x\n", tkt->enc_part2->flags);
+     krb5_print_keyblock("Ticket: Session Keyblock",
+                        tkt->enc_part2->session);
+     krb5_unparse_name(tkt->enc_part2->client, &p);
+     printf("Ticket: Client: %s\n", p);
+     free(p);
+     krb5_print_times("Ticket: Times", &tkt->enc_part2->times);
+     printf("Ticket: Address 0: %08x\n",
+           *((unsigned long *) tkt->enc_part2->caddrs[0]->contents));
+     
+     krb5_free_ticket(tkt);
+}
+
+void krb5_print_creds(krb5_creds *creds, krb5_keyblock *secret_key)
+{
+     char *p, buf[BUFSIZ];
+     
+     krb5_unparse_name(creds->client, &p);
+     printf("Client: %s\n", p);
+     free(p);
+     krb5_unparse_name(creds->server, &p);
+     printf("Server: %s\n", p);
+     free(p);
+     krb5_print_keyblock("Session key", &creds->keyblock);
+     krb5_print_times("Times", &creds->times);
+     printf("is_skey: %s\n", creds->is_skey ? "True" : "False");
+     printf("Flags: 0x%08x\n", creds->ticket_flags);
+     krb5_print_addrs(creds->addresses);
+     krb5_print_ticket(&creds->ticket, secret_key);
+     /* krb5_print_ticket(&creds->second_ticket, secret_key); */
+}
+
+void krb4_print_ticket(KTEXT ticket, krb5_keyblock *secret_key)
+{
+     char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+     char sname[ANAME_SZ], sinst[INST_SZ];
+     unsigned char flags;
+     unsigned long addr, issue_time;
+     C_Block session_key;
+     int life;
+     Key_schedule keysched;
+     
+     int ret;
+     
+     if (des_key_sched(secret_key->contents, keysched)) {
+         fprintf(stderr, "Bug in DES key somewhere.\n");
+         exit(1);
+     }
+     
+     ret = decomp_ticket(ticket, &flags, pname, pinst, prealm, &addr,
+                        session_key, &life, &issue_time, sname,
+                        sinst,  secret_key->contents, keysched);
+     if (ret != KSUCCESS) {
+         fprintf(stderr, "krb4 decomp_ticket failed\n");
+         exit(1);
+     }
+     printf("Ticket: Client: %s.%s@%s\n", pname, pinst, prealm);
+     printf("Ticket: Service: %s.%s%\n", sname, sinst);
+     printf("Ticket: Address: %08x\n", addr);
+     print_key("Ticket: Session Key", session_key);
+     printf("Ticket: Lifetime: %d\n", life);
+     printf("Ticket: Issue Date: %d, %s", issue_time, ctime(&issue_time));
+}
+
+void krb4_print_creds(CREDENTIALS *creds, krb5_keyblock *secret_key)
+{
+     printf("Client: %s.%s@%s\n", creds->pname, creds->pinst,
+           creds->realm);
+     printf("Service: %s.%s@%s\n", creds->service, creds->instance,
+           creds->realm);
+     print_key("Session key", creds->session);
+     printf("Lifetime: %d\n", creds->lifetime);
+     printf("Key Version: %d\n", creds->kvno);
+     print_time("Issue Date", creds->issue_date);
+     krb4_print_ticket(&creds->ticket_st, secret_key);
+}
+
+usage()
+{
+     fprintf(stderr, "Usage: test [-remote server] client service\n");
+     exit(1);
+}
+
+main(int argc, char **argv)
+{
+     krb5_principal client, server;
+     krb5_ccache cc;
+     krb5_creds v5creds;
+     krb5_keyblock key;
+     char keybuf[KEYSIZE], buf[BUFSIZ];
+     int i, ret, local;
+     char *remote;
+
+     krb524_debug = 1;
+
+     krb524_init_ets();
+
+     local = 0;
+     remote = NULL;
+     argc--; argv++;
+     while (argc) {
+         if (strcmp(*argv, "-local") == 0)
+              local++;
+         else if (strcmp(*argv, "-remote") == 0) {
+              argc--; argv++;
+              if (!argc)
+                   usage();
+              remote = *argv;
+         }
+         else
+              break;
+         argc--; argv++;
+     }
+     if (argc != 2)
+         usage();
+
+     if (ret = krb5_parse_name(argv[0], &client)) {
+         com_err("test", ret, "parsing client name");
+         exit(1);
+     }
+     if (ret = krb5_parse_name(argv[1], &server)) {
+         com_err("test", ret, "parsing server name");
+         exit(1);
+     }
+     if (ret = krb5_cc_default(&cc)) {
+         com_err("test", ret, "opening default credentials cache");
+         exit(1);
+     }
+     
+     bzero((char *) &v5creds, sizeof(v5creds));
+     v5creds.client = client;
+     v5creds.server = server;
+     v5creds.times.endtime = 0;
+     v5creds.keyblock.keytype = KEYTYPE_DES;
+     if (ret = krb5_get_credentials(0, cc, &v5creds)) {
+         com_err("test", ret, "getting V5 credentials");
+         exit(1);
+     }
+
+     /* We need the service key in order to locally decrypt both */
+     /* tickets for testing */
+     printf("Service's key: ");
+     fflush(stdout);
+     fgets(buf, BUFSIZ, stdin);
+     for (i = 0; i < 8; i++) {
+         unsigned char c;
+         c = buf[2*i];
+         if (c >= '0' && c <= '9')
+              c -= '0';
+         else if (c >= 'a' && c <= 'z')
+              c = c - 'a' + 0xa;
+         keybuf[i] = c << 4;
+         c = buf[2*i+1];
+         if (c >= '0' && c <= '9')
+              c -= '0';
+         else if (c >= 'a' && c <= 'z')
+              c = c - 'a' + 0xa;
+         keybuf[i] += c;
+     }
+     
+     key.keytype = KEYTYPE_DES;
+     key.length = KEYSIZE; /* presumably */
+     key.contents = keybuf;
+
+     do_remote(&v5creds, remote, &key);
+}
+
+void do_remote(krb5_creds *v5creds, char *server, krb5_keyblock *key)
+{
+     struct sockaddr_in saddr;
+     struct hostent *hp;
+     CREDENTIALS v4creds;
+     int ret;
+
+     printf("\nV5 credentials:\n");
+     krb5_print_creds(v5creds, key);
+
+     if (strcmp(server, "kdc") != 0) {
+         hp = gethostbyname(server);
+         if (hp == NULL) {
+              fprintf(stderr, "test: host %s does not exist.\n", server);
+              exit(1);
+         }
+         bzero((char *) &saddr, sizeof(struct sockaddr_in));
+         saddr.sin_family = AF_INET;
+         bcopy(hp->h_addr, (char *) &saddr.sin_addr.s_addr,
+               sizeof(struct in_addr));
+         
+         if (ret = krb524_convert_creds_addr(v5creds, &v4creds, &saddr)) {
+              com_err("test", ret, "converting credentials on %s",
+                      server);
+              exit(1);
+         }
+     } else {
+         if (ret = krb524_convert_creds_kdc(v5creds, &v4creds)) {
+              com_err("test", ret, "converting credentials via kdc");
+              exit(1);
+         }
+     }
+     
+     printf("\nV4 credentials:\n");
+     krb4_print_creds(&v4creds, key);
+}
diff --git a/src/lib/.rconf b/src/lib/.rconf
new file mode 100644 (file)
index 0000000..0be003a
--- /dev/null
@@ -0,0 +1,2 @@
+ignore des.old
+ignore FOO
diff --git a/src/lib/crypto/des/.rconf b/src/lib/crypto/des/.rconf
new file mode 100644 (file)
index 0000000..b886964
--- /dev/null
@@ -0,0 +1,8 @@
+ignore fp.c
+ignore ip.c
+ignore key_perm.h
+ignore odd.h
+ignore p.c
+ignore p_table.h
+ignore s_table.h
+ignore doc
diff --git a/src/lib/crypto/des/FUNCTIONS b/src/lib/crypto/des/FUNCTIONS
new file mode 100644 (file)
index 0000000..7ed082e
--- /dev/null
@@ -0,0 +1,26 @@
+File           Function                                Where?
+
+weak_key.c     mit_des_is_weak_key                     crypto
+string2key.c   mit_des_string_to_key                   ?
+random_key.c   mit_des_random_key                      ?
+process_ky.c   mit_des_process_key                     ?
+new_rn_key.c   mit_des_new_random_key                  ?
+               mit_des_init_random_number_generator    ?
+               mit_des_set_random_generator_seed       ?
+               mit_des_set_sequence_number             ?
+               mit_des_generate_random_block           ?
+krb_glue.c     mit_des_encrypt_func                    ?
+               mit_des_decrypt_func                    ?
+key_sched.c    mit_des_key_sched                       crypto
+key_parity.c   mit_des_fixup_key_parity                crypto
+               mit_des_check_key_parity                crypto
+init_rkey.c    mit_des_init_random_key                 crypto
+finish_key.c   mit_des_finish_key                      crypto
+fin_rndkey.c   mit_des_finish_random_key               crypto
+enc_dec.c      mit_des_cbc_encrypt                     crypto
+des.c          mit_des_ecb_encrypt                     crypto
+cs_entry.c     (var) mit_des_cryptosystem_entry        krb5
+               (var) krb5_des_cst_entry                krb5
+               (var) mit_des_cbc_cksumtable_entry      krb5
+cksum.c                mit_des_cbc_cksum                       crypto
+cbc_cksum.c    mit_des_cbc_checksum                    crypto
diff --git a/src/lib/crypto/des/doc/libdes.doc b/src/lib/crypto/des/doc/libdes.doc
new file mode 100644 (file)
index 0000000..70f9f33
--- /dev/null
@@ -0,0 +1,208 @@
+
+       How to use the Kerberos encryption library.
+
+                       Revised         10/15/85        spm
+
+1)     The following include file is needed:
+       
+       /projects/auth/include/des.h    (VAX)
+       ---------------                                 (PC8086)
+
+2)     The encryption library that should be linked to is:
+       
+       /projects/auth/lib/libdes.a             (VAX)
+|      /projects/auth/ibm/lib/libdes.a (PC8086 cross-compilation environment)
+
+3)     For each key that may be simultaneously active,
+       allocate (either compile or malloc) a "Key_schedule" struct, 
+       defined in "des.h"
+
+4)     Create key schedules, as needed, prior to using the encryption
+       routines, via "des_set_key()".
+
+5)  Setup the input and output areas.  Make sure to note the restrictions
+       on lengths being multiples of eight bytes.
+
+6)     Invoke the encryption/decryption routines, "ecb_encrypt()"
+        or "cbc_encrypt()"
+
+7)     To generate a cryptographic checksum, use "cbc_cksum()"
+/*     ----------------------------------------------------------------        */
+       
+       Routine Interfaces--
+
+/*     -----------------------------------------------------------------       */
+
+int
+       des_set_key(k,schedule)
+               C_Block                 *k;
+               Key_schedule    schedule;
+
+       Calculates a key schedule from (all) eight bytes of the input key, and
+       puts it into the indicated "Key_schedule" struct;
+
+       Make sure to pass valid eight bytes, no padding or other processing
+       it done.
+
+       The key schedule is then used in subsequent encryption/decryption
+       operations.  Many key schedules may be created and cached for later
+       use.
+
+       The user is responsible to clear keys and schedules no longer needed
+       to prevent their disclosure.
+
+|      Checks the parity of the key provided, to make sure it is odd per
+|      FIPS spec.  Returns 0 value for key ok, 1 for key_parity error.
+
+/*     ----------------------------------------------------------------        */
+       
+int
+       ecb_encrypt(input,output,schedule,encrypt)
+               C_Block                 *input;         /* ptr to eight byte input value */
+               C_Block                 *output;        /* ptr to eight byte output value */
+               int                             encrypt;        /* 0 ==> decrypt, else encrypt */
+               Key_schedule    schedule;       /* addr of key schedule */
+
+This is the low level routine that encrypts or decrypts a single 8-byte
+block in electronic code book mode.  Always transforms the input
+data into the output data.
+
+If encrypt is non-zero, the input (cleartext) is encrypted into the
+output (ciphertext) using the specified key_schedule, pre-set via "des_set_key".
+
+If encrypt is zero, the input (now ciphertext) is decrypted into
+the output (now cleartext).
+
+Input and output may be the same space.
+
+Does not return any meaningful value.  Void is not used for compatibility
+with other compilers.
+
+/*     --------------------------------------------------------------  */
+
+int    
+       cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+
+               C_Block                 *input;         /* ptr to input data */
+               C_Block                 *output;        /* ptr to output data */
+               int                             length;         /* desired length, in bytes */
+               Key_schedule    schedule;               /* addr of precomputed schedule */
+               C_Block                 *ivec;          /* pointer to 8 byte initialization
+                                                                        * vector
+                                                                        */
+               int                             encrypt         /* 0 ==> decrypt; else encrypt*/
+
+
+       If encrypt is non-zero, the routine cipher-block-chain encrypts
+       the INPUT (cleartext) into the OUTPUT (ciphertext) using the provided
+       key schedule and initialization vector.  If the length is not an integral
+       multiple of eight bytes, the last block is copied to a temp and zero 
+       filled (highest addresses).  The output is ALWAYS an integral multiple
+       of eight bytes.
+
+       If encrypt is zero, the routine cipher-block chain decrypts the INPUT
+       (ciphertext) into the OUTPUT (cleartext) using the provided key schedule
+       and     initialization vector.  Decryption ALWAYS operates on integral
+       multiples of 8 bytes, so will round the length provided up to the
+       appropriate     multiple. Consequently, it will always produce the rounded-up
+       number of bytes of output cleartext. The application must determine if
+       the output cleartext was zero-padded due to cleartext lengths not integral
+       multiples of 8.
+
+       No errors or meaningful value are returned.  Void is not used for
+       compatibility with other compilers.
+
+
+/* cbc checksum (MAC) only routine  ---------------------------------------- */
+int    
+       cbc_cksum(input,output,length,schedule,ivec)
+
+       C_Block                 *input;         /* >= length bytes of inputtext  */
+       C_Block                 *output;        /* >= length bytes of outputtext */
+       int                             length;         /* in bytes                                             */
+       Key_schedule    schedule;       /* precomputed key schedule        */
+       C_Block                 *ivec;          /* 8 bytes of ivec                         */
+
+
+       Produces a cryptographic checksum, 8 bytes, by cipher-block-chain
+       encrypting the input, discarding the ciphertext output, and only retaining
+       the last ciphertext 8-byte block.  Uses the provided key schedule and ivec.
+       The input is effectively zero-padded to an integral multiple of
+       eight bytes, though the original input is not modified.
+
+       No meaningful value is returned.  Void is not used for compatibility
+       with other compilers.
+
+
+/*     random_key ----------------------------------------*/
+int
+       random_key(key)
+
+       C_Block *key;
+
+       The start for the random number generated is set from the current time
+       in microseconds, then the random number generator is invoked
+       to create an eight byte output key (not a schedule).  The key
+       generated is set to odd parity per FIPS spec.
+
+       The caller must supply space for the output key, pointed to 
+       by "*key", then after getting a new key, call the des_set_key() 
+       routine when needed.
+
+       No meaningfull value is returned.  Void is not used for compatibility
+       with other compilers.
+
+
+/* string_to_key --------------------------------------------*/
+
+int
+       string_to_key(str,key)
+       register char           *str;
+       register C_Block        *key;
+
+       This routines converts an arbitrary length, null terminated string
+       to an 8 byte DES key, with each byte parity set to odd, per FIPS spec.
+
+       The algorithm is as follows:
+
+|      Take the first 8 bytes and remove the parity (leaving 56 bits).
+|      Do the same for the second 8 bytes, and the third, etc.  Do this for
+|      as many sets of 8 bytes as necessary, filling in the remainder of the
+|      last set with nulls.  Fold the second set back on the first (i.e. bit
+|      0 over bit 55, and bit 55 over bit 0).  Fold the third over the second
+|      (bit 0 of the third set is now over bit 0 of the first set).  Repeat
+|      until you have done this to all sets.  Xor the folded sets.  Break the
+|      result into 8 7 bit bytes, and generate odd parity for each byte.  You
+|      now have 64 bits.  Note that DES takes a 64 bit key, and uses only the
+|      non parity bits.
+
+
+/* read_password -------------------------------------------*/
+
+read_password(k,prompt,verify)
+       C_Block *k;
+       char *prompt;
+       int     verify;
+
+This routine issues the supplied prompt, turns off echo, if possible, and
+reads an input string.  If verify is non-zero, it does it again, for use
+in applications such as changing a password. If verify is non-zero, both
+versions are compared, and the input is requested repeatedly until they
+match.  Then, the input string is mapped into a valid DES key, internally
+using the string_to_key routine.  The newly created key is copied to the
+area pointed to by parameter "k".  
+
+No meaningful value is returned.  If an error occurs trying to manipulate
+the terminal echo, the routine forces the process to exit.
+
+/* get_line ------------------------*/
+long get_line(p,max)
+       char    *p;
+       long    max;
+
+Reads input characters from standard input until either a newline appears or
+else the max length is reached.  The characters read are stuffed into
+the string pointed to, which will always be null terminated.  The newline
+is not inserted in the string.  The max parameter includes the byte needed
+for the null terminator, so allocate and pass one more than the maximum
+string length desired.
diff --git a/src/lib/crypto/des/keytest.data b/src/lib/crypto/des/keytest.data
new file mode 100644 (file)
index 0000000..7ff34ee
--- /dev/null
@@ -0,0 +1,171 @@
+0101010101010101 95F8A5E5DD31D900 8000000000000000
+0101010101010101 DD7F121CA5015619 4000000000000000
+0101010101010101 2E8653104F3834EA 2000000000000000
+0101010101010101 4BD388FF6CD81D4F 1000000000000000
+0101010101010101 20B9E767B2FB1456 0800000000000000
+0101010101010101 55579380D77138EF 0400000000000000
+0101010101010101 6CC5DEFAAF04512F 0200000000000000
+0101010101010101 0D9F279BA5D87260 0100000000000000
+0101010101010101 D9031B0271BD5A0A 0080000000000000
+0101010101010101 424250B37C3DD951 0040000000000000
+0101010101010101 B8061B7ECD9A21E5 0020000000000000
+0101010101010101 F15D0F286B65BD28 0010000000000000
+0101010101010101 ADD0CC8D6E5DEBA1 0008000000000000
+0101010101010101 E6D5F82752AD63D1 0004000000000000
+0101010101010101 ECBFE3BD3F591A5E 0002000000000000
+0101010101010101 F356834379D165CD 0001000000000000
+0101010101010101 2B9F982F20037FA9 0000800000000000
+0101010101010101 889DE068A16F0BE6 0000400000000000
+0101010101010101 E19E275D846A1298 0000200000000000
+0101010101010101 329A8ED523D71AEC 0000100000000000
+0101010101010101 E7FCE22557D23C97 0000080000000000
+0101010101010101 12A9F5817FF2D65D 0000040000000000
+0101010101010101 A484C3AD38DC9C19 0000020000000000
+0101010101010101 FBE00A8A1EF8AD72 0000010000000000
+0101010101010101 750D079407521363 0000008000000000
+0101010101010101 64FEED9C724C2FAF 0000004000000000
+0101010101010101 F02B263B328E2B60 0000002000000000
+0101010101010101 9D64555A9A10B852 0000001000000000
+0101010101010101 D106FF0BED5255D7 0000000800000000
+0101010101010101 E1652C6B138C64A5 0000000400000000
+0101010101010101 E428581186EC8F46 0000000200000000
+0101010101010101 AEB5F5EDE22D1A36 0000000100000000
+0101010101010101 E943D7568AEC0C5C 0000000080000000
+0101010101010101 DF98C8276F54B04B 0000000040000000
+0101010101010101 B160E4680F6C696F 0000000020000000
+0101010101010101 FA0752B07D9C4AB8 0000000010000000
+0101010101010101 CA3A2B036DBC8502 0000000008000000
+0101010101010101 5E0905517BB59BCF 0000000004000000
+0101010101010101 814EEB3B91D90726 0000000002000000
+0101010101010101 4D49DB1532919C9F 0000000001000000
+0101010101010101 25EB5FC3F8CF0621 0000000000800000
+0101010101010101 AB6A20C0620D1C6F 0000000000400000
+0101010101010101 79E90DBC98F92CCA 0000000000200000
+0101010101010101 866ECEDD8072BB0E 0000000000100000
+0101010101010101 8B54536F2F3E64A8 0000000000080000
+0101010101010101 EA51D3975595B86B 0000000000040000
+0101010101010101 CAFFC6AC4542DE31 0000000000020000
+0101010101010101 8DD45A2DDF90796C 0000000000010000
+0101010101010101 1029D55E880EC2D0 0000000000008000
+0101010101010101 5D86CB23639DBEA9 0000000000004000
+0101010101010101 1D1CA853AE7C0C5F 0000000000002000
+0101010101010101 CE332329248F3228 0000000000001000
+0101010101010101 8405D1ABE24FB942 0000000000000800
+0101010101010101 E643D78090CA4207 0000000000000400
+0101010101010101 48221B9937748A23 0000000000000200
+0101010101010101 DD7C0BBD61FAFD54 0000000000000100
+0101010101010101 2FBC291A570DB5C4 0000000000000080
+0101010101010101 E07C30D7E4E26E12 0000000000000040
+0101010101010101 0953E2258E8E90A1 0000000000000020
+0101010101010101 5B711BC4CEEBF2EE 0000000000000010
+0101010101010101 CC083F1E6D9E85F6 0000000000000008
+0101010101010101 D2FD8867D50D2DFE 0000000000000004
+0101010101010101 06E7EA22CE92708F 0000000000000002
+0101010101010101 166B40B44ABA4BD6 0000000000000001
+8001010101010101 0000000000000000 95A8D72813DAA94D
+4001010101010101 0000000000000000 0EEC1487DD8C26D5
+2001010101010101 0000000000000000 7AD16FFB79C45926
+1001010101010101 0000000000000000 D3746294CA6A6CF3
+0801010101010101 0000000000000000 809F5F873C1FD761
+0401010101010101 0000000000000000 C02FAFFEC989D1FC
+0201010101010101 0000000000000000 4615AA1D33E72F10
+0180010101010101 0000000000000000 2055123350C00858
+0140010101010101 0000000000000000 DF3B99D6577397C8
+0120010101010101 0000000000000000 31FE17369B5288C9
+0110010101010101 0000000000000000 DFDD3CC64DAE1642
+0108010101010101 0000000000000000 178C83CE2B399D94
+0104010101010101 0000000000000000 50F636324A9B7F80
+0102010101010101 0000000000000000 A8468EE3BC18F06D
+0101800101010101 0000000000000000 A2DC9E92FD3CDE92
+0101400101010101 0000000000000000 CAC09F797D031287
+0101200101010101 0000000000000000 90BA680B22AEB525
+0101100101010101 0000000000000000 CE7A24F350E280B6
+0101080101010101 0000000000000000 882BFF0AA01A0B87
+0101040101010101 0000000000000000 25610288924511C2
+0101020101010101 0000000000000000 C71516C29C75D170
+0101018001010101 0000000000000000 5199C29A52C9F059
+0101014001010101 0000000000000000 C22F0A294A71F29F
+0101012001010101 0000000000000000 EE371483714C02EA
+0101011001010101 0000000000000000 A81FBD448F9E522F
+0101010801010101 0000000000000000 4F644C92E192DFED
+0101010401010101 0000000000000000 1AFA9A66A6DF92AE
+0101010201010101 0000000000000000 B3C1CC715CB879D8
+0101010180010101 0000000000000000 19D032E64AB0BD8B
+0101010140010101 0000000000000000 3CFAA7A7DC8720DC
+0101010120010101 0000000000000000 B7265F7F447AC6F3
+0101010110010101 0000000000000000 9DB73B3C0D163F54
+0101010108010101 0000000000000000 8181B65BABF4A975
+0101010104010101 0000000000000000 93C9B64042EAA240
+0101010102010101 0000000000000000 5570530829705592
+0101010101800101 0000000000000000 8638809E878787A0
+0101010101400101 0000000000000000 41B9A79AF79AC208
+0101010101200101 0000000000000000 7A9BE42F2009A892
+0101010101100101 0000000000000000 29038D56BA6D2745
+0101010101080101 0000000000000000 5495C6ABF1E5DF51
+0101010101040101 0000000000000000 AE13DBD561488933
+0101010101020101 0000000000000000 024D1FFA8904E389
+0101010101018001 0000000000000000 D1399712F99BF02E
+0101010101014001 0000000000000000 14C1D7C1CFFEC79E
+0101010101012001 0000000000000000 1DE5279DAE3BED6F
+0101010101011001 0000000000000000 E941A33F85501303
+0101010101010801 0000000000000000 DA99DBBC9A03F379
+0101010101010401 0000000000000000 B7FC92F91D8E92E9
+0101010101010201 0000000000000000 AE8E5CAA3CA04E85
+0101010101010180 0000000000000000 9CC62DF43B6EED74
+0101010101010140 0000000000000000 D863DBB5C59A91A0
+0101010101010120 0000000000000000 A1AB2190545B91D7
+0101010101010110 0000000000000000 0875041E64C570F7
+0101010101010108 0000000000000000 5A594528BEBEF1CC
+0101010101010104 0000000000000000 FCDB3291DE21F0C0
+0101010101010102 0000000000000000 869EFD7F9F265A09
+1046913489980131 0000000000000000 88D55E54F54C97B4
+1007103489988020 0000000000000000 0C0CC00C83EA48FD
+10071034C8980120 0000000000000000 83BC8EF3A6570183
+1046103489988020 0000000000000000 DF725DCAD94EA2E9
+1086911519190101 0000000000000000 E652B53B550BE8B0
+1086911519580101 0000000000000000 AF527120C485CBB0
+5107B01519580101 0000000000000000 0F04CE393DB926D5
+1007B01519190101 0000000000000000 C9F00FFC74079067
+3107915498080101 0000000000000000 7CFD82A593252B4E
+3107919498080101 0000000000000000 CB49A2F9E91363E3
+10079115B9080140 0000000000000000 00B588BE70D23F56
+3107911598080140 0000000000000000 406A9A6AB43399AE
+1007D01589980101 0000000000000000 6CB773611DCA9ADA
+9107911589980101 0000000000000000 67FD21C17DBB5D70
+9107D01589190101 0000000000000000 9592CB4110430787
+1007D01598980120 0000000000000000 A6B7FF68A318DDD3
+1007940498190101 0000000000000000 4D102196C914CA16
+0107910491190401 0000000000000000 2DFA9F4573594965
+0107910491190101 0000000000000000 B46604816C0E0774
+0107940491190401 0000000000000000 6E7E6221A4F34E87
+19079210981A0101 0000000000000000 AA85E74643233199
+1007911998190801 0000000000000000 2E5A19DB4D1962D6
+10079119981A0801 0000000000000000 23A866A809D30894
+1007921098190101 0000000000000000 D812D961F017D320
+100791159819010B 0000000000000000 055605816E58608F
+1004801598190101 0000000000000000 ABD88E8B1B7716F1
+1004801598190102 0000000000000000 537AC95BE69DA1E1
+1004801598190108 0000000000000000 AED0F6AE3C25CDD8
+1002911598100104 0000000000000000 B3E35A5EE53E7B8D
+1002911598190104 0000000000000000 61C79C71921A2EF8
+1002911598100201 0000000000000000 E2F5728F0995013C
+1002911698100101 0000000000000000 1AEAC39A61F0A464
+7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
+0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
+07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
+3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
+04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
+0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
+0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
+43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
+07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
+04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
+37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
+1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
+584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
+025816164629B007 480D39006EE762F2 A1F9915541020B56
+49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
+4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
+49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
+018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
+1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
diff --git a/src/lib/crypto/md4/.rconf b/src/lib/crypto/md4/.rconf
new file mode 100644 (file)
index 0000000..de30fd8
--- /dev/null
@@ -0,0 +1,2 @@
+ignore RFC1186.TXT
+ignore RFC1186B.TXT
diff --git a/src/lib/crypto/md4/RFC1186.TXT b/src/lib/crypto/md4/RFC1186.TXT
new file mode 100644 (file)
index 0000000..5c0d941
--- /dev/null
@@ -0,0 +1,1011 @@
+
+
+
+
+
+
+Network Working Group                                         R. Rivest
+Request for Comments: 1186          MIT Laboratory for Computer Science
+                                                           October 1990
+
+
+                    The MD4 Message Digest Algorithm
+
+Status of this Memo
+
+   This RFC is the specification of the MD4 Digest Algorithm.  If you
+   are going to implement MD4, it is suggested you do it this way.  This
+   memo is for informational use and does not constitute a standard.
+   Distribution of this memo is unlimited.
+
+Table of Contents
+
+   1.  Abstract ....................................................    1
+   2.  Terminology and Notation ....................................    2
+   3.  MD4 Algorithm Description ...................................    2
+   4.  Extensions ..................................................    6
+   5.  Summary .....................................................    7
+   6.  Acknowledgements ............................................    7
+   APPENDIX - Reference Implementation .............................    7
+   Security Considerations..........................................   18
+   Author's Address.................................................   18
+
+1. Abstract
+
+   This note describes the MD4 message digest algorithm.  The algorithm
+   takes as input an input message of arbitrary length and produces as
+   output a 128-bit "fingerprint" or "message digest" of the input.  It
+   is conjectured that it is computationally infeasible to produce two
+   messages having the same message digest, or to produce any message
+   having a given prespecified target message digest.  The MD4 algorithm
+   is thus ideal for digital signature applications, where a large file
+   must be "compressed" in a secure manner before being signed with the
+   RSA public-key cryptosystem.
+
+   The MD4 algorithm is designed to be quite fast on 32-bit machines.
+   On a SUN Sparc station, MD4 runs at 1,450,000 bytes/second.  On a DEC
+   MicroVax II, MD4 runs at approximately 70,000 bytes/second.  On a
+   20MHz 80286, MD4 runs at approximately 32,000 bytes/second.  In
+   addition, the MD4 algorithm does not require any large substitution
+   tables; the algorithm can be coded quite compactly.
+
+   The MD4 algorithm is being placed in the public domain for review and
+   possible adoption as a standard.
+
+
+
+
+Rivest                                                          [Page 1]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+   (Note: The document supersedes an earlier draft.  The algorithm
+   described here is a slight modification of the one described in the
+   draft.)
+
+2.  Terminology and Notation
+
+   In this note a "word" is a 32-bit quantity and a byte is an 8-bit
+   quantity.  A sequence of bits can be interpreted in a natural manner
+   as a sequence of bytes, where each consecutive group of 8 bits is
+   interpreted as a byte with the high-order (most significant) bit of
+   each byte listed first.  Similarly, a sequence of bytes can be
+   interpreted as a sequence of 32-bit words, where each consecutive
+   group of 4 bytes is interpreted as a word with the low-order (least
+   significant) byte given first.
+
+   Let x_i denote "x sub i".  If the subscript is an expression, we
+   surround it in braces, as in x_{i+1}.  Similarly, we use ^ for
+   superscripts (exponentiation), so that x^i denotes x to the i-th
+   power.
+
+   Let the symbol "+" denote addition of words (i.e., modulo- 2^32
+   addition). Let X <<< s denote the 32-bit value obtained by circularly
+   shifting (rotating) X left by s bit positions.  Let not(X) denote the
+   bit-wise complement of X, and let X v Y denote the bit-wise OR of X
+   and Y.  Let X xor Y denote the bit-wise XOR of X and Y, and let XY
+   denote the bit-wise AND of X and Y.
+
+3.  MD4 Algorithm Description
+
+   We begin by supposing that we have a b-bit message as input, and that
+   we wish to find its message digest.  Here b is an arbitrary
+   nonnegative integer; b may be zero, it need not be a multiple of 8,
+   and it may be arbitrarily large.  We imagine the bits of the message
+   written down as follows:
+
+                m_0 m_1 ... m_{b-1} .
+
+   The following five steps are performed to compute the message digest
+   of the message.
+
+      Step 1. Append padding bits
+
+         The message is "padded" (extended) so that its length (in bits)
+         is congruent to 448, modulo 512.  That is, the message is
+         extended so that it is just 64 bits shy of being a multiple of
+         512 bits long.  Padding is always performed, even if the length
+         of the message is already congruent to 448, modulo 512 (in
+         which case 512 bits of padding are added).
+
+
+
+Rivest                                                          [Page 2]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+         Padding is performed as follows: a single "1" bit is appended
+         to the message, and then enough zero bits are appended so that
+         the length in bits of the padded message becomes congruent to
+         448, modulo 512.
+
+      Step 2. Append length
+
+         A 64-bit representation of b (the length of the message before
+         the padding bits were added) is appended to the result of the
+         previous step.  In the unlikely event that b is greater than
+         2^64, then only the low-order 64 bits of b are used.  (These
+         bits are appended as two 32-bit words and appended low-order
+         word first in accordance with the previous conventions.)
+
+         At this point the resulting message (after padding with bits
+         and with b) has a length that is an exact multiple of 512 bits.
+         Equivalently, this message has a length that is an exact
+         multiple of 16 (32-bit) words.  Let M[0 ... N-1] denote the
+         words of the resulting message, where N is a multiple of 16.
+
+      Step 3. Initialize MD buffer
+
+         A 4-word buffer (A,B,C,D) is used to compute the message
+         digest.  Here each of A,B,C,D are 32-bit registers.  These
+         registers are initialized to the following values in
+         hexadecimal, low-order bytes first):
+
+            word A:    01 23 45 67
+            word B:    89 ab cd ef
+            word C:    fe dc ba 98
+            word D:    76 54 32 10
+
+      Step 4. Process message in 16-word blocks
+
+         We first define three auxiliary functions that each take
+         as input three 32-bit words and produce as output one
+         32-bit word.
+
+            f(X,Y,Z)  =  XY v not(X)Z
+            g(X,Y,Z)  =  XY v XZ v YZ
+            h(X,Y,Z)  =  X xor Y xor Z
+
+         In each bit position f acts as a conditional: if x then y else
+         z.  (The function f could have been defined using + instead of
+         v since XY and not(X)Z will never have 1's in the same bit
+         position.)  In each bit position g acts as a majority function:
+         if at least two of x, y, z are on, then g has a one in that bit
+         position, else g has a zero. It is interesting to note that if
+
+
+
+Rivest                                                          [Page 3]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+         the bits of X, Y, and Z are independent and unbiased, the each
+         bit of f(X,Y,Z) will be independent and unbiased, and similarly
+         each bit of g(X,Y,Z) will be independent and unbiased.  The
+         function h is the bit-wise "xor" or "parity" function; it has
+         properties similar to those of f and g.
+
+         Do the following:
+
+         For i = 0 to N/16-1 do  /* process each 16-word block */
+                 For j = 0 to 15 do: /* copy block i into X */
+                   Set X[j] to M[i*16+j].
+                 end /* of loop on j */
+                 Save A as AA, B as BB, C as CC, and D as DD.
+
+                 [Round 1]
+                   Let [A B C D i s] denote the operation
+                         A = (A + f(B,C,D) + X[i]) <<< s  .
+                   Do the following 16 operations:
+                         [A B C D 0 3]
+                         [D A B C 1 7]
+                         [C D A B 2 11]
+                         [B C D A 3 19]
+                         [A B C D 4 3]
+                         [D A B C 5 7]
+                         [C D A B 6 11]
+                         [B C D A 7 19]
+                         [A B C D 8 3]
+                         [D A B C 9 7]
+                         [C D A B 10 11]
+                         [B C D A 11 19]
+                         [A B C D 12 3]
+                         [D A B C 13 7]
+                         [C D A B 14 11]
+                         [B C D A 15 19]
+
+                 [Round 2]
+                   Let [A B C D i s] denote the operation
+                         A = (A + g(B,C,D) + X[i] + 5A827999) <<< s .
+                   (The value 5A..99 is a hexadecimal 32-bit
+                   constant, written with the high-order digit
+                   first. This constant represents the square
+                   root of 2.  The octal value of this constant
+                   is 013240474631.  See Knuth, The Art of
+                   Programming, Volume 2 (Seminumerical
+                   Algorithms), Second Edition (1981),
+                   Addison-Wesley.  Table 2, page 660.)
+                   Do the following 16 operations:
+                         [A B C D 0  3]
+
+
+
+Rivest                                                          [Page 4]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+                         [D A B C 4  5]
+                         [C D A B 8  9]
+                         [B C D A 12 13]
+                         [A B C D 1  3]
+                         [D A B C 5  5]
+                         [C D A B 9  9]
+                         [B C D A 13 13]
+                         [A B C D 2  3]
+                         [D A B C 6  5]
+                         [C D A B 10 9]
+                         [B C D A 14 13]
+                         [A B C D 3  3]
+                         [D A B C 7  5]
+                         [C D A B 11 9]
+                         [B C D A 15 13]
+
+                 [Round 3]
+                   Let [A B C D i s] denote the operation
+                         A = (A + h(B,C,D) + X[i] + 6ED9EBA1) <<< s .
+                   (The value 6E..A1 is a hexadecimal 32-bit
+                   constant, written with the high-order digit
+                   first.  This constant represents the square
+                   root of 3.  The octal value of this constant
+                   is 015666365641.  See Knuth, The Art of
+                   Programming, Volume 2 (Seminumerical
+                   Algorithms), Second Edition (1981),
+                   Addison-Wesley.  Table 2, page 660.)
+                   Do the following 16 operations:
+                         [A B C D 0  3]
+                         [D A B C 8  9]
+                         [C D A B 4  11]
+                         [B C D A 12 15]
+                         [A B C D 2  3]
+                         [D A B C 10 9]
+                         [C D A B 6  11]
+                         [B C D A 14 15]
+                         [A B C D 1  3]
+                         [D A B C 9  9]
+                         [C D A B 5  11]
+                         [B C D A 13 15]
+                         [A B C D 3  3]
+                         [D A B C 11 9]
+                         [C D A B 7  11]
+                         [B C D A 15 15]
+
+         Then perform the following additions:
+                         A = A + AA
+                         B = B + BB
+
+
+
+Rivest                                                          [Page 5]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+                         C = C + CC
+                         D = D + DD
+         (That is, each of the four registers is incremented by
+         the value it had before this block was started.)
+
+         end /* of loop on i */
+
+      Step 5. Output
+
+         The message digest produced as output is A,B,C,D.  That is, we
+         begin with the low-order byte of A, and end with the high-order
+         byte of D.
+
+         This completes the description of MD4.  A reference
+         implementation in C is given in the Appendix.
+
+4.  Extensions
+
+   If more than 128 bits of output are required, then the following
+   procedure is recommended to obtain a 256-bit output.  (There is no
+   provision made for obtaining more than 256 bits.)
+
+   Two copies of MD4 are run in parallel over the input.  The first copy
+   is standard as described above.  The second copy is modified as
+   follows.
+
+   The initial state of the second copy is:
+                    word A:    00 11 22 33
+                    word B:    44 55 66 77
+                    word C:    88 99 aa bb
+                    word D:    cc dd ee ff
+
+   The magic constants in rounds 2 and 3 for the second copy of MD4 are
+   changed from sqrt(2) and sqrt(3) to cuberoot(2) and cuberoot(3):
+
+                                    Octal           Hex
+            Round 2 constant        012050505746    50a28be6
+            Round 3 constant        013423350444    5c4dd124
+
+   Finally, after every 16-word block is processed (including the last
+   block), the values of the A registers in the two copies are
+   exchanged.
+
+   The final message digest is obtaining by appending the result of the
+   second copy of MD4 to the end of the result of the first copy of MD4.
+
+
+
+
+
+
+Rivest                                                          [Page 6]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+5.  Summary
+
+   The MD4 message digest algorithm is simple to implement, and provides
+   a "fingerprint" or message digest of a message of arbitrary length.
+
+   It is conjectured that the difficulty of coming up with two messages
+   having the same message digest is on the order of 2^64 operations,
+   and that the difficulty of coming up with any message having a given
+   message digest is on the order of 2^128 operations.  The MD4
+   algorithm has been carefully scrutinized for weaknesses.  It is,
+   however, a relatively new algorithm and further security analysis is
+   of course justified, as is the case with any new proposal of this
+   sort.  The level of security provided by MD4 should be sufficient for
+   implementing very high security hybrid digital signature schemes
+   based on MD4 and the RSA public-key cryptosystem.
+
+6.  Acknowledgements
+
+   I'd like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle, and
+   Noam Nisan for numerous helpful comments and suggestions.
+
+APPENDIX - Reference Implementation
+
+This appendix contains the following files:
+
+         md4.h        -- header file for using MD4 implementation
+         md4.c        -- the source code for MD4 routines
+         md4driver.c  -- a sample "user" routine
+         session      -- sample results of running md4driver
+
+ /*
+ ** ********************************************************************
+ ** md4.h -- Header file for implementation of                        **
+ ** MD4 Message Digest Algorithm                                      **
+ ** Updated: 2/13/90 by Ronald L. Rivest                              **
+ ** (C) 1990 RSA Data Security, Inc.                                  **
+ ** ********************************************************************
+ */
+
+ /* MDstruct is the data structure for a message digest computation.
+ */
+ typedef struct {
+   unsigned int buffer[4]; /* Holds 4-word result of MD computation */
+   unsigned char count[8]; /* Number of bits processed so far */
+   unsigned int done;      /* Nonzero means MD computation finished */
+ } MDstruct, *MDptr;
+
+ /* MDbegin(MD)
+
+
+
+Rivest                                                          [Page 7]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ ** Input: MD -- an MDptr
+ ** Initialize the MDstruct prepatory to doing a message digest
+ ** computation.
+ */
+ extern void MDbegin();
+
+ /* MDupdate(MD,X,count)
+ ** Input: MD -- an MDptr
+ **        X -- a pointer to an array of unsigned characters.
+ **        count -- the number of bits of X to use (an unsigned int).
+ ** Updates MD using the first "count" bits of X.
+ ** The array pointed to by X is not modified.
+ ** If count is not a multiple of 8, MDupdate uses high bits of
+ ** last byte.
+ ** This is the basic input routine for a user.
+ ** The routine terminates the MD computation when count < 512, so
+ ** every MD computation should end with one call to MDupdate with a
+ ** count less than 512.  Zero is OK for a count.
+ */
+ extern void MDupdate();
+
+ /* MDprint(MD)
+ ** Input: MD -- an MDptr
+ ** Prints message digest buffer MD as 32 hexadecimal digits.
+ ** Order is from low-order byte of buffer[0] to high-order byte
+ ** of buffer[3].
+ ** Each byte is printed with high-order hexadecimal digit first.
+ */
+ extern void MDprint();
+
+ /*
+ ** End of md4.h
+ ****************************(cut)***********************************/
+
+ /*
+ ** ********************************************************************
+ ** md4.c -- Implementation of MD4 Message Digest Algorithm           **
+ ** Updated: 2/16/90 by Ronald L. Rivest                              **
+ ** (C) 1990 RSA Data Security, Inc.                                  **
+ ** ********************************************************************
+ */
+
+ /*
+ ** To use MD4:
+ **   -- Include md4.h in your program
+ **   -- Declare an MDstruct MD to hold the state of the digest
+ **          computation.
+ **   -- Initialize MD using MDbegin(&MD)
+
+
+
+Rivest                                                          [Page 8]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ **   -- For each full block (64 bytes) X you wish to process, call
+ **          MDupdate(&MD,X,512)
+ **      (512 is the number of bits in a full block.)
+ **   -- For the last block (less than 64 bytes) you wish to process,
+ **          MDupdate(&MD,X,n)
+ **      where n is the number of bits in the partial block. A partial
+ **      block terminates the computation, so every MD computation
+ **      should terminate by processing a partial block, even if it
+ **      has n = 0.
+ **   -- The message digest is available in MD.buffer[0] ...
+ **      MD.buffer[3].  (Least-significant byte of each word
+ **      should be output first.)
+ **   -- You can print out the digest using MDprint(&MD)
+ */
+
+ /* Implementation notes:
+ ** This implementation assumes that ints are 32-bit quantities.
+ ** If the machine stores the least-significant byte of an int in the
+ ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
+ ** should be set to TRUE.  Otherwise (e.g., SUNS), LOWBYTEFIRST
+ ** should be set to FALSE.  Note that on machines with LOWBYTEFIRST
+ ** FALSE the routine MDupdate modifies has a side-effect on its input
+ ** array (the order of bytes in each word are reversed).  If this is
+ ** undesired a call to MDreverse(X) can reverse the bytes of X back
+ ** into order after each call to MDupdate.
+
+ */
+ #define TRUE  1
+ #define FALSE 0
+ #define LOWBYTEFIRST FALSE
+
+ /* Compile-time includes
+ */
+ #include <stdio.h>
+ #include "md4.h"
+
+ /* Compile-time declarations of MD4 "magic constants".
+ */
+ #define I0  0x67452301       /* Initial values for MD buffer */
+ #define I1  0xefcdab89
+ #define I2  0x98badcfe
+ #define I3  0x10325476
+ #define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
+ #define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
+ /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+ ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+ ** Table 2, page 660.
+ */
+
+
+
+Rivest                                                          [Page 9]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ #define fs1  3               /* round 1 shift amounts */
+ #define fs2  7
+ #define fs3 11
+ #define fs4 19
+ #define gs1  3               /* round 2 shift amounts */
+ #define gs2  5
+ #define gs3  9
+ #define gs4 13
+ #define hs1  3               /* round 3 shift amounts */
+ #define hs2  9
+ #define hs3 11
+ #define hs4 15
+
+ /* Compile-time macro declarations for MD4.
+ ** Note: The "rot" operator uses the variable "tmp".
+ ** It assumes tmp is declared as unsigned int, so that the >>
+ ** operator will shift in zeros rather than extending the sign bit.
+ */
+ #define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
+ #define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
+ #define h(X,Y,Z)             (X^Y^Z)
+ #define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+ #define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
+ #define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
+ #define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+ /* MDprint(MDp)
+ ** Print message digest buffer MDp as 32 hexadecimal digits.
+ ** Order is from low-order byte of buffer[0] to high-order byte of
+ ** buffer[3].
+ ** Each byte is printed with high-order hexadecimal digit first.
+ ** This is a user-callable routine.
+ */
+ void
+ MDprint(MDp)
+ MDptr MDp;
+ { int i,j;
+   for (i=0;i<4;i++)
+     for (j=0;j<32;j=j+8)
+       printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+ }
+
+ /* MDbegin(MDp)
+ ** Initialize message digest buffer MDp.
+ ** This is a user-callable routine.
+ */
+ void
+ MDbegin(MDp)
+
+
+
+Rivest                                                         [Page 10]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ MDptr MDp;
+ { int i;
+   MDp->buffer[0] = I0;
+   MDp->buffer[1] = I1;
+   MDp->buffer[2] = I2;
+   MDp->buffer[3] = I3;
+   for (i=0;i<8;i++) MDp->count[i] = 0;
+   MDp->done = 0;
+ }
+
+ /* MDreverse(X)
+ ** Reverse the byte-ordering of every int in X.
+ ** Assumes X is an array of 16 ints.
+ ** The macro revx reverses the byte-ordering of the next word of X.
+ */
+ #define revx { t = (*X << 16) | (*X >> 16); \
+      *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
+ MDreverse(X)
+ unsigned int *X;
+ { register unsigned int t;
+   revx; revx; revx; revx; revx; revx; revx; revx;
+   revx; revx; revx; revx; revx; revx; revx; revx;
+ }
+
+ /* MDblock(MDp,X)
+ ** Update message digest buffer MDp->buffer using 16-word data block X.
+ ** Assumes all 16 words of X are full of data.
+ ** Does not update MDp->count.
+ ** This routine is not user-callable.
+ */
+ static void
+ MDblock(MDp,X)
+ MDptr MDp;
+ unsigned int *X;
+ {
+   register unsigned int tmp, A, B, C, D;
+ #if LOWBYTEFIRST == FALSE
+   MDreverse(X);
+ #endif
+   A = MDp->buffer[0];
+   B = MDp->buffer[1];
+   C = MDp->buffer[2];
+   D = MDp->buffer[3];
+   /* Update the message digest buffer */
+   ff(A , B , C , D ,  0 , fs1); /* Round 1 */
+   ff(D , A , B , C ,  1 , fs2);
+   ff(C , D , A , B ,  2 , fs3);
+   ff(B , C , D , A ,  3 , fs4);
+
+
+
+Rivest                                                         [Page 11]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+   ff(A , B , C , D ,  4 , fs1);
+   ff(D , A , B , C ,  5 , fs2);
+   ff(C , D , A , B ,  6 , fs3);
+   ff(B , C , D , A ,  7 , fs4);
+   ff(A , B , C , D ,  8 , fs1);
+   ff(D , A , B , C ,  9 , fs2);
+   ff(C , D , A , B , 10 , fs3);
+   ff(B , C , D , A , 11 , fs4);
+   ff(A , B , C , D , 12 , fs1);
+   ff(D , A , B , C , 13 , fs2);
+   ff(C , D , A , B , 14 , fs3);
+   ff(B , C , D , A , 15 , fs4);
+   gg(A , B , C , D ,  0 , gs1); /* Round 2 */
+   gg(D , A , B , C ,  4 , gs2);
+   gg(C , D , A , B ,  8 , gs3);
+   gg(B , C , D , A , 12 , gs4);
+   gg(A , B , C , D ,  1 , gs1);
+   gg(D , A , B , C ,  5 , gs2);
+   gg(C , D , A , B ,  9 , gs3);
+   gg(B , C , D , A , 13 , gs4);
+   gg(A , B , C , D ,  2 , gs1);
+   gg(D , A , B , C ,  6 , gs2);
+   gg(C , D , A , B , 10 , gs3);
+   gg(B , C , D , A , 14 , gs4);
+   gg(A , B , C , D ,  3 , gs1);
+   gg(D , A , B , C ,  7 , gs2);
+   gg(C , D , A , B , 11 , gs3);
+   gg(B , C , D , A , 15 , gs4);
+   hh(A , B , C , D ,  0 , hs1); /* Round 3 */
+   hh(D , A , B , C ,  8 , hs2);
+   hh(C , D , A , B ,  4 , hs3);
+   hh(B , C , D , A , 12 , hs4);
+   hh(A , B , C , D ,  2 , hs1);
+   hh(D , A , B , C , 10 , hs2);
+   hh(C , D , A , B ,  6 , hs3);
+   hh(B , C , D , A , 14 , hs4);
+   hh(A , B , C , D ,  1 , hs1);
+   hh(D , A , B , C ,  9 , hs2);
+   hh(C , D , A , B ,  5 , hs3);
+   hh(B , C , D , A , 13 , hs4);
+   hh(A , B , C , D ,  3 , hs1);
+   hh(D , A , B , C , 11 , hs2);
+   hh(C , D , A , B ,  7 , hs3);
+   hh(B , C , D , A , 15 , hs4);
+   MDp->buffer[0] += A;
+   MDp->buffer[1] += B;
+   MDp->buffer[2] += C;
+   MDp->buffer[3] += D;
+
+
+
+Rivest                                                         [Page 12]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ }
+
+ /* MDupdate(MDp,X,count)
+ ** Input: MDp -- an MDptr
+ **        X -- a pointer to an array of unsigned characters.
+ **        count -- the number of bits of X to use.
+ **          (if not a multiple of 8, uses high bits of last byte.)
+ ** Update MDp using the number of bits of X given by count.
+ ** This is the basic input routine for an MD4 user.
+ ** The routine completes the MD computation when count < 512, so
+ ** every MD computation should end with one call to MDupdate with a
+ ** count less than 512.  A call with count 0 will be ignored if the
+ ** MD has already been terminated (done != 0), so an extra call with
+ ** count 0 can be given as a "courtesy close" to force termination
+ ** if desired.
+ */
+ void
+ MDupdate(MDp,X,count)
+ MDptr MDp;
+ unsigned char *X;
+ unsigned int count;
+ { unsigned int i, tmp, bit, byte, mask;
+   unsigned char XX[64];
+   unsigned char *p;
+   /* return with no error if this is a courtesy close with count
+   ** zero and MDp->done is true.
+   */
+   if (count == 0 && MDp->done) return;
+   /* check to see if MD is already done and report error */
+   if (MDp->done)
+          { printf("\nError: MDupdate MD already done."); return; }
+   /* Add count to MDp->count */
+   tmp = count;
+   p = MDp->count;
+   while (tmp)
+     { tmp += *p;
+       *p++ = tmp;
+       tmp = tmp >> 8;
+     }
+   /* Process data */
+   if (count == 512)
+     { /* Full block of data to handle */
+       MDblock(MDp,(unsigned int *)X);
+     }
+   else if (count > 512) /* Check for count too large */
+     { printf("\nError: MDupdate called with illegal count value %d."
+              ,count);
+       return;
+
+
+
+Rivest                                                         [Page 13]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+     }
+   else /* partial block -- must be last block so finish up */
+     { /* Find out how many bytes and residual bits there are */
+       byte = count >> 3;
+       bit =  count & 7;
+       /* Copy X into XX since we need to modify it */
+       for (i=0;i<=byte;i++)   XX[i] = X[i];
+       for (i=byte+1;i<64;i++) XX[i] = 0;
+       /* Add padding '1' bit and low-order zeros in last byte */
+       mask = 1 << (7 - bit);
+       XX[byte] = (XX[byte] | mask) & ~( mask - 1);
+       /* If room for bit count, finish up with this block */
+       if (byte <= 55)
+         { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+           MDblock(MDp,(unsigned int *)XX);
+         }
+       else /* need to do two blocks to finish up */
+         { MDblock(MDp,(unsigned int *)XX);
+           for (i=0;i<56;i++) XX[i] = 0;
+           for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
+           MDblock(MDp,(unsigned int *)XX);
+         }
+       /* Set flag saying we're done with MD computation */
+       MDp->done = 1;
+     }
+ }
+
+ /*
+ ** End of md4.c
+ ****************************(cut)***********************************/
+
+ /*
+ ** ********************************************************************
+ ** md4driver.c -- sample routines to test                            **
+ ** MD4 message digest algorithm.                                     **
+ ** Updated: 2/16/90 by Ronald L. Rivest                              **
+ ** (C) 1990 RSA Data Security, Inc.                                  **
+ ** ********************************************************************
+ */
+
+ #include <stdio.h>
+ #include "md4.h"
+
+ /* MDtimetrial()
+ ** A time trial routine, to measure the speed of MD4.
+ ** Measures speed for 1M blocks = 64M bytes.
+ */
+ MDtimetrial()
+
+
+
+Rivest                                                         [Page 14]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ { unsigned int X[16];
+   MDstruct MD;
+   int i;
+   double t;
+   for (i=0;i<16;i++) X[i] = 0x01234567 + i;
+   printf
+   ("MD4 time trial. Processing 1 million 64-character blocks...\n");
+   clock();
+   MDbegin(&MD);
+   for (i=0;i<1000000;i++) MDupdate(&MD,X,512);
+   MDupdate(&MD,X,0);
+   t = (double) clock(); /* in microseconds */
+   MDprint(&MD); printf(" is digest of 64M byte test input.\n");
+   printf("Seconds to process test input:   %g\n,t/1e6);
+   printf("Characters processed per second: %ld.\n,(int)(64e12/t));
+ }
+
+ /* MDstring(s)
+ ** Computes the message digest for string s.
+ ** Prints out message digest, a space, the string (in quotes) and a
+ ** carriage return.
+ */
+ MDstring(s)
+ unsigned char *s;
+ { unsigned int i, len = strlen(s);
+   MDstruct MD;
+   MDbegin(&MD);
+   for (i=0;i+64<=len;i=i+64) MDupdate(&MD,s+i,512);
+   MDupdate(&MD,s+i,(len-i)*8);
+   MDprint(&MD);
+   printf(" \"%s\"\n",s);
+ }
+
+ /* MDfile(filename)
+ ** Computes the message digest for a specified file.
+ ** Prints out message digest, a space, the file name, and a
+ ** carriage return.
+ */
+ MDfile(filename)
+ char *filename;
+ { FILE *f = fopen(filename,"rb");
+   unsigned char X[64];
+   MDstruct MD;
+   int b;
+   if (f == NULL)
+      { printf("%s can't be opened.\n",filename); return; }
+   MDbegin(&MD);
+   while ((b=fread(X,1,64,f))!=0) MDupdate(&MD,X,b*8);
+
+
+
+Rivest                                                         [Page 15]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+   MDupdate(&MD,X,0);
+   MDprint(&MD);
+   printf(" %s\n",filename);
+   fclose(f);
+ }
+
+ /* MDfilter()
+ ** Writes the message digest of the data from stdin onto stdout,
+ ** followed by a carriage return.
+ */
+ MDfilter()
+ { unsigned char X[64];
+   MDstruct MD;
+   int b;
+   MDbegin(&MD);
+   while ((b=fread(X,1,64,stdin))!=0) MDupdate(&MD,X,b*8);
+   MDupdate(&MD,X,0);
+   MDprint(&MD);
+   printf("\n");
+ }
+
+ /* MDtestsuite()
+ ** Run a standard suite of test data.
+ */
+ MDtestsuite()
+ {
+   printf("MD4 test suite results:\n");
+   MDstring("");
+   MDstring("a");
+   MDstring("abc");
+   MDstring("message digest");
+   MDstring("abcdefghijklmnopqrstuvwxyz");
+   MDstring
+   ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+   MDfile("foo"); /* Contents of file foo are "abc" */
+ }
+
+ main(argc,argv)
+ int argc;
+ char *argv[];
+ { int i;
+   /* For each command line argument in turn:
+   ** filename          -- prints message digest and name of file
+   ** -sstring          -- prints message digest and contents of string
+   ** -t                -- prints time trial statistics for 64M bytes
+   ** -x                -- execute a standard suite of test data
+   ** (no args)         -- writes messages digest of stdin onto stdout
+   */
+
+
+
+Rivest                                                         [Page 16]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+   if (argc==1) MDfilter();
+   else
+     for (i=1;i<argc;i++)
+       if (argv[i][0]=='-' && argv[i][1]=='s') MDstring(argv[i]+2);
+       else if (strcmp(argv[i],"-t")==0)       MDtimetrial();
+       else if (strcmp(argv[i],"-x")==0)       MDtestsuite();
+       else                                    MDfile(argv[i]);
+ }
+
+ /*
+ ** end of md4driver.c
+ ****************************(cut)***********************************/
+
+
+ --------------------------------------------------------------------
+ --- Sample session.  Compiling and using MD4 on SUN Sparcstation ---
+ --------------------------------------------------------------------
+ >ls
+ total 66
+ -rw-rw-r--  1 rivest          3 Feb 14 17:40 abcfile
+ -rwxrwxr-x  1 rivest      24576 Feb 17 12:28 md4
+ -rw-rw-r--  1 rivest       9347 Feb 17 00:37 md4.c
+ -rw-rw-r--  1 rivest      25150 Feb 17 12:25 md4.doc
+ -rw-rw-r--  1 rivest       1844 Feb 16 21:21 md4.h
+ -rw-rw-r--  1 rivest       3497 Feb 17 12:27 md4driver.c
+ >
+ >cc -o md4 -O4 md4.c md4driver.c
+ md4.c:
+ md4driver.c:
+ Linking:
+ >
+ >md4 -x
+ MD4 test suite results:
+ 31d6cfe0d16ae931b73c59d7e0c089c0 ""
+ bde52cb31de33e46245e05fbdbd6fb24 "a"
+ a448017aaf21d8525fc10ae87aa6729d "abc"
+ d9130a8164549fe818874806e1c7014b "message digest"
+ d79e1c308aa5bbcdeea8ed63df412da9 "abcdefghijklmnopqrstuvwxyz"
+ 043f8582f241db351ce627e153e7f0e4
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ a448017aaf21d8525fc10ae87aa6729d abcfile
+ >
+ >md4 -sabc -shi
+ a448017aaf21d8525fc10ae87aa6729d "abc"
+ cfaee2512bd25eb033236f0cd054e308 "hi"
+ >
+ >md4 *
+ a448017aaf21d8525fc10ae87aa6729d abcfile
+
+
+
+Rivest                                                         [Page 17]
+\f
+RFC 1186              MD4 Message Digest Algorithm          October 1990
+
+
+ d316f994da0e951cf9502928a1f73300 md4
+ 379adb39eada0dfdbbdfdcd0d9def8c4 md4.c
+ 9a3f73327c65954198b1f45a3aa12665 md4.doc
+ 37fe165ac177b461ff78b86d10e4ff33 md4.h
+ 7dcba2e2dc4d8f1408d08beb17dabb2a md4.o
+ 08790161bfddc6f5788b4353875cb1c3 md4driver.c
+ 1f84a7f690b0545d2d0480d5d3c26eea md4driver.o
+ >
+ >cat abcfile | md4
+ a448017aaf21d8525fc10ae87aa6729d
+ >
+ >md4 -t
+ MD4 time trial. Processing 1 million 64-character blocks...
+ 6325bf77e5891c7c0d8104b64cc6e9ef is digest of 64M byte test input.
+ Seconds to process test input:   44.0982
+ Characters processed per second: 1451305.
+ >
+ >
+ ------------------------ end of sample session --------------------
+
+      Note:  A version of this document including the C source code is
+      available for FTP from THEORY.LSC.MIT.EDU in the file "md4.doc".
+
+Security Considerations
+
+   The level of security discussed in this memo by MD4 is considered to
+   be sufficient for implementing very high security hybrid digital
+   signature schemes based on MD4 and the RSA public-key cryptosystem.
+
+Author's Address
+
+   Ronald L. Rivest
+   Massachusetts Institute of Technology
+   Laboratory for Computer Science
+   NE43-324
+   545 Technology Square
+   Cambridge, MA 02139-1986
+
+   Phone: (617) 253-5880
+
+   EMail: rivest@theory.lcs.mit.edu
+
+
+
+
+
+
+
+
+
+
+Rivest                                                         [Page 18]
+\f
\ No newline at end of file
diff --git a/src/lib/crypto/md4/RFC1186B.TXT b/src/lib/crypto/md4/RFC1186B.TXT
new file mode 100644 (file)
index 0000000..6be1a29
--- /dev/null
@@ -0,0 +1,1041 @@
+*** Note: This is a revised version of "md4.doc", obtained as "md4.doc"
+*** by anonymous ftp from theory.lcs.mit.edu.  The original version is 
+*** still available as "md4.doc.old".  The MD4 algorithm is unchanged, but
+*** the newer version of the code is somewhat more portable, although slightly
+*** slower.                                    [Ronald L. Rivest 1/13/91]
+\f
+Network Working Group                                          R. Rivest
+Request for Comments: 1186B          MIT Laboratory for Computer Science
+Updates: RFC 1186                                               S. Dusse
+                                                 RSA Data Security, Inc.
+                                                          9 January 1991
+
+
+
+                    The MD4 Message Digest Algorithm
+
+
+STATUS OF THIS MEMO
+
+   This RFC is the specification of the MD4 Digest Algorithm.  If you
+   are going to implement MD4, it is suggested you do it this way.  This
+   memo is for informational use and does not constitute a standard.
+   Distribution of this memo is unlimited.
+
+Table of Contents
+
+   1.  Executive Summary                                               1
+   2.  Terminology and Notation                                        2
+   3.  MD4 Algorithm Description                                       2
+   4.  Extensions                                                      6
+   5.  Summary                                                         6
+   6.  Acknowledgements                                                7
+   Security Considerations                                             7
+   References                                                          7
+   APPENDIX - Reference Implementation                                 7
+
+1.  Executive Summary
+
+   This note describes the MD4 message digest algorithm.  The algorithm
+   takes as input an input message of arbitrary length and produces as
+   output a 128-bit "fingerprint" or "message digest" of the input.  It
+   is conjectured that it is computationally infeasible to produce two
+   messages having the same message digest, or to produce any message
+   having a given prespecified target message digest.  The MD4 algorithm
+   is thus ideal for digital signature applications, where a large file
+   must be "compressed" in a secure manner before being signed with the
+   RSA public-key cryptosystem.
+
+   The MD4 algorithm is designed to be quite fast on 32-bit machines.
+   In addition, the MD4 algorithm does not require any large
+   substitution tables; the algorithm can be coded quite compactly.
+
+   The MD4 algorithm is being placed in the public domain for review and
+   possible adoption as a standard.
+
+   This RFC is a revision of the October 1990 RFC 1186.  The main
+   difference is that the reference implementation of MD4 in the
+   appendix is more portable.
+
+
+Rivest                                                          [Page 1]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+2.  Terminology and Notation
+
+   In this note a "word" is a 32-bit quantity and a byte is an 8-bit
+   quantity.  A sequence of bits can be interpreted in a natural manner
+   as a sequence of bytes, where each consecutive group of 8 bits is
+   interpreted as a byte with the high-order (most significant) bit of
+   each byte listed first.  Similarly, a sequence of bytes can be
+   interpreted as a sequence of 32-bit words, where each consecutive
+   group of 4 bytes is interpreted as a word with the low-order (least
+   significant) byte given first.
+
+   Let x_i denote "x sub i".  If the subscript is an expression, we
+   surround it in braces, as in x_{i+1}.  Similarly, we use ^ for
+   superscripts (exponentiation), so that x^i denotes x to the i-th
+   power.
+
+   Let the symbol "+" denote addition of words (i.e., modulo- 2^32
+   addition).  Let X <<< s denote the 32-bit value obtained by
+   circularly shifting (rotating) X left by s bit positions.  Let not(X)
+   denote the bit-wise complement of X, and let X v Y denote the bit-
+   wise OR of X and Y.  Let X xor Y denote the bit-wise XOR of X and Y,
+   and let XY denote the bit-wise AND of X and Y.
+
+
+3.  MD4 Algorithm Description
+
+   We begin by supposing that we have a b-bit message as input, and that
+   we wish to find its message digest.  Here b is an arbitrary
+   nonnegative integer; b may be zero, it need not be a multiple of 8,
+   and it may be arbitrarily large.  We imagine the bits of the message
+   written down as follows:
+
+                    m_0 m_1 ... m_{b-1} .
+
+   The following five steps are performed to compute the message digest
+   of the message.
+
+
+3.1 Step 1. Append padding bits
+
+   The message is "padded" (extended) so that its length (in bits) is
+   congruent to 448, modulo 512.  That is, the message is extended so
+   that it is just 64 bits shy of being a multiple of 512 bits long.
+   Padding is always performed, even if the length of the message is
+   already congruent to 448, modulo 512 (in which case 512 bits of
+   padding are added).
+
+   Padding is performed as follows: a single "1" bit is appended to the
+   message, and then enough zero bits are appended so that the length in
+   bits of the padded message becomes congruent to 448, modulo 512.
+
+
+
+
+Rivest                                                          [Page 2]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+3.2 Step 2. Append length
+
+   A 64-bit representation of b (the length of the message before the
+   padding bits were added) is appended to the result of the previous
+   step.  In the unlikely event that b is greater than 2^64, then only
+   the low-order 64 bits of b are used.  (These bits are appended as two
+   32-bit words and appended low-order word first in accordance with the
+   previous conventions.)
+
+   At this point the resulting message (after padding with bits and with
+   b) has a length that is an exact multiple of 512 bits.  Equivalently,
+   this message has a length that is an exact multiple of 16 (32-bit)
+   words.  Let M[0 ... N-1] denote the words of the resulting message,
+   where N is a multiple of 16.
+
+
+3.3 Step 3. Initialize MD buffer
+
+   A 4-word buffer (A,B,C,D) is used to compute the message digest.
+   Here each of A,B,C,D are 32-bit registers.  These registers are
+   initialized to the following values in hexadecimal, low-order bytes
+   first):
+
+                    word A: 01 23 45 67
+                    word B: 89 ab cd ef
+                    word C: fe dc ba 98
+                    word D: 76 54 32 10
+
+
+3.4 Step 4. Process message in 16-word blocks
+
+   We first define three auxiliary functions that each take as input
+   three 32-bit words and produce as output one 32-bit word.
+
+                    f(X,Y,Z)  =  XY v not(X)Z
+                    g(X,Y,Z)  =  XY v XZ v YZ
+                    h(X,Y,Z)  =  X xor Y xor Z
+
+   In each bit position f acts as a conditional: if x then y else z.
+   (The function f could have been defined using + instead of v since XY
+   and not(X)Z will never have 1's in the same bit position.)  In each
+   bit position g acts as a majority function: if at least two of x, y,
+   z are on, then g has a one in that bit position, else g has a zero.
+   It is interesting to note that if the bits of X, Y, and Z are
+   independent and unbiased, the each bit of f(X,Y,Z) will be
+   independent and unbiased, and similarly each bit of g(X,Y,Z) will be
+   independent and unbiased.  The function h is the bit-wise "xor" or
+   "parity" function; it has properties similar to those of f and g.
+
+   Do the following:
+
+   For i = 0 to N/16-1 do:  /* process each 16-word block */
+       For j = 0 to 15 do:  /* copy block i into X */
+           Set X[j] to M[i*16+j].
+Rivest                                                          [Page 3]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+       end /* of loop on j */
+       Save A as AA, B as BB, C as CC, and D as DD.
+
+       [Round 1]
+         Let [A B C D i s] denote the operation
+             A = (A + f(B,C,D) + X[i]) <<< s .
+
+         Do the following 16 operations:
+             [A B C D 0 3]
+             [D A B C 1 7]
+             [C D A B 2 11]
+             [B C D A 3 19]
+             [A B C D 4 3]
+             [D A B C 5 7]
+             [C D A B 6 11]
+             [B C D A 7 19]
+             [A B C D 8 3]
+             [D A B C 9 7]
+             [C D A B 10 11]
+             [B C D A 11 19]
+             [A B C D 12 3]
+             [D A B C 13 7]
+             [C D A B 14 11]
+             [B C D A 15 19]
+
+       [Round 2]
+         Let [A B C D i s] denote the operation
+             A = (A + g(B,C,D) + X[i] + 5A827999) <<< s .
+
+         (The value 5A..99 is a hexadecimal 32-bit
+         constant, written with the high-order digit
+         first. This constant represents the square
+         root of 2.  The octal value of this constant
+         is 013240474631.  See Knuth, The Art of
+         Programming, Volume 2 (Seminumerical
+         Algorithms), Second Edition (1981),
+         Addison-Wesley.  Table 2, page 660.)
+
+         Do the following 16 operations:
+             [A B C D 0  3]
+             [D A B C 4  5]
+             [C D A B 8  9]
+             [B C D A 12 13]
+             [A B C D 1  3]
+             [D A B C 5  5]
+             [C D A B 9  9]
+             [B C D A 13 13]
+             [A B C D 2  3]
+             [D A B C 6  5]
+             [C D A B 10 9]
+             [B C D A 14 13]
+             [A B C D 3  3]
+             [D A B C 7  5]
+             [C D A B 11 9]
+Rivest                                                          [Page 4]             [B C D A 15 13]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+
+       [Round 3]
+         Let [A B C D i s] denote the operation
+             A = (A + h(B,C,D) + X[i] + 6ED9EBA1) <<< s .
+
+         (The value 6E..A1 is a hexadecimal 32-bit
+         constant, written with the high-order digit
+         first.  This constant represents the square
+         root of 3.  The octal value of this constant
+         is 015666365641.  See Knuth, The Art of
+         Programming, Volume 2 (Seminumerical
+         Algorithms), Second Edition (1981),
+         Addison-Wesley.  Table 2, page 660.)
+
+         Do the following 16 operations:
+             [A B C D 0  3]
+             [D A B C 8  9]
+             [C D A B 4  11]
+             [B C D A 12 15]
+             [A B C D 2  3]
+             [D A B C 10 9]
+             [C D A B 6  11]
+             [B C D A 14 15]
+             [A B C D 1  3]
+             [D A B C 9  9]
+             [C D A B 5  11]
+             [B C D A 13 15]
+             [A B C D 3  3]
+             [D A B C 11 9]
+             [C D A B 7  11]
+             [B C D A 15 15]
+
+         Then perform the following additions:
+             A = A + AA
+             B = B + BB
+             C = C + CC
+             D = D + DD
+
+         (That is, each of the four registers is
+         incremented by the value it had before
+         this block was started.)
+
+   end /* of loop on i */
+
+
+3.5 Step 5. Output
+
+   The message digest produced as output is A,B,C,D.  That is, we begin
+   with the low-order byte of A, and end with the high-order byte of D.
+
+   This completes the description of MD4.  A reference implementation in
+   C is given in the Appendix.
+
+
+Rivest                                                          [Page 5]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+4.  Extensions
+
+   If more than 128 bits of output are required, then the following
+   procedure is recommended to obtain a 256-bit output.  (There is no
+   provision made for obtaining more than 256 bits.)
+
+   Two copies of MD4 are run in parallel over the input.  The first copy
+   is standard as described above.  The second copy is modified as
+   follows.
+
+   The initial state of the second copy is:
+
+                    word A: 00 11 22 33
+                    word B: 44 55 66 77
+                    word C: 88 99 aa bb
+                    word D: cc dd ee ff
+
+   The magic constants in rounds 2 and 3 for the second copy of MD4 are
+   changed from sqrt(2) and sqrt(3) to cuberoot(2) and cuberoot(3):
+
+                           Octal             Hex
+      Round 2 constant     012050505746      50a28be6
+      Round 3 constant     013423350444      5c4dd124
+
+   Finally, after every 16-word block is processed (including the last
+   block), the values of the A registers in the two copies are
+   exchanged.
+
+   The final message digest is obtaining by appending the result of the
+   second copy of MD4 to the end of the result of the first copy of MD4.
+
+
+5.  Summary
+
+   The MD4 message digest algorithm is simple to implement, and provides
+   a "fingerprint" or message digest of a message of arbitrary length.
+   It is conjectured that the difficulty of coming up with two messages
+   having the same message digest is on the order of 2^64 operations,
+   and that the difficulty of coming up with any message having a given
+   message digest is on the order of 2^128 operations.  The MD4
+   algorithm has been carefully scrutinized for weaknesses.  It is,
+   however, a relatively new algorithm and further security analysis is
+   of course justified, as is the case with any new proposal of this
+   sort.  The level of security provided by MD4 should be sufficient for
+   implementing very high security hybrid digital signature schemes
+   based on MD4 and the RSA public-key cryptosystem.
+
+
+6.  Acknowledgements
+
+   We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
+   and Noam Nisan for numerous helpful comments and suggestions.
+
+
+Rivest                                                          [Page 6]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+Security Considerations
+
+   The level of security discussed in this memo by MD4 is considered to
+   be sufficient for implementing very high security hybrid digital
+   signature schemes based on MD4 and the RSA public-key cryptosystem.
+
+
+Authors' Addresses
+
+   Ronald L. Rivest
+   Massachusetts Institute of Technology
+   Laboratory for Computer Science
+   NE43-324
+   545 Technology Square
+   Cambridge, MA 02139-1986
+   Phone: (617) 253-5880
+   EMail: rivest@theory.lcs.mit.edu
+
+   Steve Dusse
+   RSA Data Security, Inc.
+   10 Twin Dolphin Dr.
+   Redwood City, CA 94065
+   Phone: (415) 595-8782
+   EMail: dusse@rsa.com
+
+
+References
+
+   [1] Rivest, R.L. The MD4 message digest algorithm. Presented at
+   CRYPTO '90 (Santa Barbara, CA, August 11-15, 1990).
+
+
+APPENDIX - Reference Implementation
+
+   This appendix contains the following files:
+
+     md4.h -- header file for using MD4 implementation
+
+     md4.c -- the source code for MD4 routines
+
+     md4driver.c -- a sample "user" routine
+
+     session -- sample results of running md4driver
+
+   The implementation of MD4 given in this appendix differs from the one
+   given in [1] and again in RFC 1186.  The main difference is that this
+   version should compile and run correctly on more platforms than the
+   other ones.  We have sacrificed performance for portability.  MD4
+   speeds given in [1] and RFC 1186 are not necessarily the same as
+   those one might obtain with this reference implementation.  However,
+   it is not difficult to improve this implementation on particular
+   platforms, an exercise left to the reader.  Following are some
+   suggestions:
+
+Rivest                                                          [Page 7]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+     1. Change MD4Block so that the context is not used at all if
+        it is empty (mdi == 0) and 64 or more bytes remain (inLen
+        >= 64). In other words, call Transform with inBuf in this
+        case. (This requires that byte ordering is correct in
+        inBuf.)
+
+     2. Implement a procedure MD4BlockLong modeled after MD4Block
+        where inBuf is UINT4 * instead of unsigned char *.
+        MD4BlockLong would call Transform directly with 16 word
+        blocks from inBuf.  Call this instead of MD4Block in
+        general. This works well if you have an I/O procedure that
+        can read long words from a file.
+
+     3. On "little-endian" platforms where the lowest-address byte
+        in a long word is the least significant (and there are no
+        alignment restrictions), change MD4Block to call Transform
+        directly with 64-byte blocks from inBuf (casted to a UINT4
+        *).
+
+/*
+ **********************************************************************
+ ** md4.h -- Header file for implementation of MD4                   **
+ ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
+ ** Created: 2/17/90 RLR                                             **
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version              **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** License to copy and use this software is granted provided that   **
+ ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function.                                       **
+ **                                                                  **
+ ** License is also granted to make and use derivative works         **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
+ ** material mentioning or referencing the derived work.             **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+ */
+
+/* typedef a 32 bit type */
+typedef unsigned long int UINT4;
+Rivest                                                          [Page 8]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+
+/* Data structure for MD4 (Message Digest) computation */
+typedef struct {
+  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
+  UINT4 buf[4];                                    /* scratch buffer */
+  unsigned char in[64];                              /* input buffer */
+  unsigned char digest[16];     /* actual digest after MD4Final call */
+} MD4_CTX;
+
+void MD4Init ();
+void MD4Update ();
+void MD4Final ();
+
+/*
+ **********************************************************************
+ ** End of md4.h                                                     **
+ ******************************* (cut) ********************************
+ */
+
+/*
+ **********************************************************************
+ ** md4.c                                                            **
+ ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
+ ** Created: 2/17/90 RLR                                             **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** License to copy and use this software is granted provided that   **
+ ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function.                                       **
+ **                                                                  **
+ ** License is also granted to make and use derivative works         **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
+ ** material mentioning or referencing the derived work.             **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+ */
+
+#include "md4.h"
+
+Rivest                                                          [Page 9]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+/* forward declaration */
+static void Transform ();
+
+static unsigned char PADDING[64] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G and H are basic MD4 functions: selection, majority, parity */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s) \
+  {(a) += F ((b), (c), (d)) + (x); \
+   (a) = ROTATE_LEFT ((a), (s));}
+#define GG(a, b, c, d, x, s) \
+  {(a) += G ((b), (c), (d)) + (x) + (UINT4)013240474631; \
+   (a) = ROTATE_LEFT ((a), (s));}
+#define HH(a, b, c, d, x, s) \
+  {(a) += H ((b), (c), (d)) + (x) + (UINT4)015666365641; \
+   (a) = ROTATE_LEFT ((a), (s));}
+
+void MD4Init (mdContext)
+MD4_CTX *mdContext;
+{
+  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
+
+  /* Load magic initialization constants.
+   */
+  mdContext->buf[0] = (UINT4)0x67452301;
+  mdContext->buf[1] = (UINT4)0xefcdab89;
+  mdContext->buf[2] = (UINT4)0x98badcfe;
+  mdContext->buf[3] = (UINT4)0x10325476;
+}
+
+void MD4Update (mdContext, inBuf, inLen)
+MD4_CTX *mdContext;
+unsigned char *inBuf;
+unsigned int inLen;
+{
+  UINT4 in[16];
+  int mdi;
+Rivest                                                         [Page 10]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+  unsigned int i, ii;
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* update number of bits */
+  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+    mdContext->i[1]++;
+  mdContext->i[0] += ((UINT4)inLen << 3);
+  mdContext->i[1] += ((UINT4)inLen >> 29);
+
+  while (inLen--) {
+    /* add new character to buffer, increment mdi */
+    mdContext->in[mdi++] = *inBuf++;
+
+    /* transform if necessary */
+    if (mdi == 0x40) {
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)
+        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+                (((UINT4)mdContext->in[ii+2]) << 16) |
+                (((UINT4)mdContext->in[ii+1]) << 8) |
+                ((UINT4)mdContext->in[ii]);
+      Transform (mdContext->buf, in);
+      mdi = 0;
+    }
+  }
+}
+
+void MD4Final (mdContext)
+MD4_CTX *mdContext;
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+  unsigned int padLen;
+
+  /* save number of bits */
+  in[14] = mdContext->i[0];
+  in[15] = mdContext->i[1];
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* pad out to 56 mod 64 */
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+  MD4Update (mdContext, PADDING, padLen);
+
+  /* append length in bits and transform */
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)
+    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+            (((UINT4)mdContext->in[ii+2]) << 16) |
+            (((UINT4)mdContext->in[ii+1]) << 8) |
+            ((UINT4)mdContext->in[ii]);
+  Transform (mdContext->buf, in);
+Rivest                                                         [Page 11]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+
+  /* store buffer in digest */
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+    mdContext->digest[ii+1] =
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+    mdContext->digest[ii+2] =
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+    mdContext->digest[ii+3] =
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+  }
+}
+
+/* Basic MD4 step. Transform buf based on in.
+ */
+static void Transform (buf, in)
+UINT4 *buf;
+UINT4 *in;
+{
+  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+  /* Round 1 */
+  FF (a, b, c, d, in[ 0],  3);
+  FF (d, a, b, c, in[ 1],  7);
+  FF (c, d, a, b, in[ 2], 11);
+  FF (b, c, d, a, in[ 3], 19);
+  FF (a, b, c, d, in[ 4],  3);
+  FF (d, a, b, c, in[ 5],  7);
+  FF (c, d, a, b, in[ 6], 11);
+  FF (b, c, d, a, in[ 7], 19);
+  FF (a, b, c, d, in[ 8],  3);
+  FF (d, a, b, c, in[ 9],  7);
+  FF (c, d, a, b, in[10], 11);
+  FF (b, c, d, a, in[11], 19);
+  FF (a, b, c, d, in[12],  3);
+  FF (d, a, b, c, in[13],  7);
+  FF (c, d, a, b, in[14], 11);
+  FF (b, c, d, a, in[15], 19);
+
+  /* Round 2 */
+  GG (a, b, c, d, in[ 0],  3);
+  GG (d, a, b, c, in[ 4],  5);
+  GG (c, d, a, b, in[ 8],  9);
+  GG (b, c, d, a, in[12], 13);
+  GG (a, b, c, d, in[ 1],  3);
+  GG (d, a, b, c, in[ 5],  5);
+  GG (c, d, a, b, in[ 9],  9);
+  GG (b, c, d, a, in[13], 13);
+  GG (a, b, c, d, in[ 2],  3);
+  GG (d, a, b, c, in[ 6],  5);
+  GG (c, d, a, b, in[10],  9);
+  GG (b, c, d, a, in[14], 13);
+  GG (a, b, c, d, in[ 3],  3);
+  GG (d, a, b, c, in[ 7],  5);
+Rivest                                                         [Page 12]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+  GG (c, d, a, b, in[11],  9);
+  GG (b, c, d, a, in[15], 13);
+
+  /* Round 3 */
+  HH (a, b, c, d, in[ 0],  3);
+  HH (d, a, b, c, in[ 8],  9);
+  HH (c, d, a, b, in[ 4], 11);
+  HH (b, c, d, a, in[12], 15);
+  HH (a, b, c, d, in[ 2],  3);
+  HH (d, a, b, c, in[10],  9);
+  HH (c, d, a, b, in[ 6], 11);
+  HH (b, c, d, a, in[14], 15);
+  HH (a, b, c, d, in[ 1],  3);
+  HH (d, a, b, c, in[ 9],  9);
+  HH (c, d, a, b, in[ 5], 11);
+  HH (b, c, d, a, in[13], 15);
+  HH (a, b, c, d, in[ 3],  3);
+  HH (d, a, b, c, in[11],  9);
+  HH (c, d, a, b, in[ 7], 11);
+  HH (b, c, d, a, in[15], 15);
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+/*
+ **********************************************************************
+ ** End of md4.c                                                     **
+ ******************************* (cut) ********************************
+ */
+
+/*
+ **********************************************************************
+ ** md4driver.c -- sample routines to test                           **
+ ** RSA Data Security, Inc. MD4 message digest algorithm.            **
+ ** Created: 2/16/90 RLR                                             **
+ ** Updated: 1/91 SRD                                                **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+Rivest                                                         [Page 13]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <string.h>
+#include "md4.h"
+
+/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
+   Order is from low-order byte to high-order byte of digest.
+   Each byte is printed with high-order hexadecimal digit first.
+ */
+static void MDPrint (mdContext)
+MD4_CTX *mdContext;
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    printf ("%02x", mdContext->digest[i]);
+}
+
+/* size of test block */
+#define TEST_BLOCK_SIZE 1000
+
+/* number of blocks to process */
+#define TEST_BLOCKS 2000
+
+/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
+static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
+
+/* A time trial routine, to measure the speed of MD4.
+   Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
+   characters.
+ */
+static void MDTimeTrial ()
+{
+  MD4_CTX mdContext;
+  time_t endTime, startTime;
+  unsigned char data[TEST_BLOCK_SIZE];
+  unsigned int i;
+
+  /* initialize test data */
+  for (i = 0; i < TEST_BLOCK_SIZE; i++)
+    data[i] = (unsigned char)(i & 0xFF);
+
+  /* start timer */
+  printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES);
+  time (&startTime);
+
+  /* digest data in TEST_BLOCK_SIZE byte blocks */
+  MD4Init (&mdContext);
+  for (i = TEST_BLOCKS; i > 0; i--)
+    MD4Update (&mdContext, data, TEST_BLOCK_SIZE);
+  MD4Final (&mdContext);
+Rivest                                                         [Page 14]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+
+  /* stop timer, get time difference */
+  time (&endTime);
+  MDPrint (&mdContext);
+  printf (" is digest of test input.\n");
+  printf
+    ("Seconds to process test input: %ld\n", (long)(endTime-startTime));
+  printf
+    ("Characters processed per second: %ld\n",
+     TEST_BYTES/(endTime-startTime));
+}
+
+/* Computes the message digest for string inString.
+   Prints out message digest, a space, the string (in quotes) and a
+   carriage return.
+ */
+static void MDString (inString)
+char *inString;
+{
+  MD4_CTX mdContext;
+  unsigned int len = strlen (inString);
+
+  MD4Init (&mdContext);
+  MD4Update (&mdContext, inString, len);
+  MD4Final (&mdContext);
+  MDPrint (&mdContext);
+  printf (" \"%s\"\n\n", inString);
+}
+
+/* Computes the message digest for a specified file.
+   Prints out message digest, a space, the file name, and a carriage
+   return.
+ */
+static void MDFile (filename)
+char *filename;
+{
+  FILE *inFile = fopen (filename, "rb");
+  MD4_CTX mdContext;
+  int bytes;
+  unsigned char data[1024];
+
+  if (inFile == NULL) {
+    printf ("%s can't be opened.\n", filename);
+    return;
+  }
+
+  MD4Init (&mdContext);
+  while ((bytes = fread (data, 1, 1024, inFile)) != 0)
+    MD4Update (&mdContext, data, bytes);
+  MD4Final (&mdContext);
+  MDPrint (&mdContext);
+  printf (" %s\n", filename);
+  fclose (inFile);
+}
+Rivest                                                         [Page 15]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+
+/* Writes the message digest of the data from stdin onto stdout,
+   followed by a carriage return.
+ */
+static void MDFilter ()
+{
+  MD4_CTX mdContext;
+  int bytes;
+  unsigned char data[16];
+
+  MD4Init (&mdContext);
+  while ((bytes = fread (data, 1, 16, stdin)) != 0)
+    MD4Update (&mdContext, data, bytes);
+  MD4Final (&mdContext);
+  MDPrint (&mdContext);
+  printf ("\n");
+}
+
+/* Runs a standard suite of test data.
+ */
+static void MDTestSuite ()
+{
+  printf ("MD4 test suite results:\n\n");
+  MDString ("");
+  MDString ("a");
+  MDString ("abc");
+  MDString ("message digest");
+  MDString ("abcdefghijklmnopqrstuvwxyz");
+  MDString
+    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+  MDString
+    ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+  /* Contents of file foo are "abc" */
+  MDFile ("foo");
+}
+
+void main (argc, argv)
+int argc;
+char *argv[];
+{
+  int i;
+
+  /* For each command line argument in turn:
+  ** filename          -- prints message digest and name of file
+  ** -sstring          -- prints message digest and contents of string
+  ** -t                -- prints time trial statistics for 1M characters
+  ** -x                -- execute a standard suite of test data
+  ** (no args)         -- writes messages digest of stdin onto stdout
+  */
+  if (argc == 1)
+    MDFilter ();
+  else
+    for (i = 1; i < argc; i++)
+Rivest                                                         [Page 16]\f
+
+
+RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
+
+
+
+      if (argv[i][0] == '-' && argv[i][1] == 's')
+        MDString (argv[i] + 2);
+      else if (strcmp (argv[i], "-t") == 0)
+        MDTimeTrial ();
+      else if (strcmp (argv[i], "-x") == 0)
+        MDTestSuite ();
+      else MDFile (argv[i]);
+}
+
+/*
+ **********************************************************************
+ ** End of md4driver.c                                               **
+ ******************************* (cut) ********************************
+ */
+
+-----------------------------------------------------------------------
+-- Sample session output obtained by running md4driver test suite    --
+-----------------------------------------------------------------------
+
+  MD4 test suite results:
+
+  31d6cfe0d16ae931b73c59d7e0c089c0 ""
+
+  bde52cb31de33e46245e05fbdbd6fb24 "a"
+
+  a448017aaf21d8525fc10ae87aa6729d "abc"
+
+  d9130a8164549fe818874806e1c7014b "message digest"
+
+  d79e1c308aa5bbcdeea8ed63df412da9 "abcdefghijklmnopqrstuvwxyz"
+
+  043f8582f241db351ce627e153e7f0e4 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij
+  klmnopqrstuvwxyz0123456789"
+
+  e33b4ddc9c38f2199c3e7b164fcc0536 "123456789012345678901234567890123456
+  78901234567890123456789012345678901234567890"
+
+  a448017aaf21d8525fc10ae87aa6729d foo
+
+
+-----------------------------------------------------------------------
+-- End of sample session                                             --
+-------------------------------- (cut) --------------------------------
+
+
+   Note: A version of this document including the C source code is
+   available for FTP from RSA.COM in the file "md4.doc".
+
+
+
+
+
+
+
+Rivest                                                         [Page 17]\f
+
+
+
+\1f
diff --git a/src/lib/exports.crypto b/src/lib/exports.crypto
new file mode 100644 (file)
index 0000000..6f70f18
--- /dev/null
@@ -0,0 +1,29 @@
+mit_des_cbc_cksum
+mit_des_ecb_encrypt
+mit_des_cbc_checksum
+mit_des_cryptosystem_entry
+mit_des_cbc_cksumtable_entry
+krb5_des_cst_entry
+mit_des_cbc_encrypt
+mit_des_encrypt_func
+mit_des_decrypt_func
+mit_des_finish_key
+mit_des_finish_random_key
+mit_des_init_random_key
+mit_des_process_key
+mit_des_random_key
+mit_des_string_to_key
+mit_des_fixup_key_parity
+mit_des_check_key_parity
+mit_des_key_sched
+mit_des_new_random_key
+mit_des_init_random_number_generator
+mit_des_set_random_generator_seed
+mit_des_set_sequence_number
+mit_des_generate_random_block
+mit_des_is_weak_key
+rsa_md4_cksumtable_entry
+rsa_md4_des_cksumtable_entry
+rsa_md5_cksumtable_entry
+rsa_md5_des_cksumtable_entry
+crc32_cksumtable_entry
diff --git a/src/lib/exports.des425 b/src/lib/exports.des425
new file mode 100644 (file)
index 0000000..b1d93d1
--- /dev/null
@@ -0,0 +1,17 @@
+des_cbc_cksum
+des_ecb_encrypt
+des_cbc_encrypt
+des_fixup_key_parity
+des_check_key_parity
+des_key_sched
+des_new_random_key
+des_init_random_number_generator
+des_set_random_generator_seed
+des_set_sequence_number
+des_generate_random_block
+des_pcbc_encrypt
+des_quad_cksum
+des_random_key
+des_read_password
+des_string_to_key
+des_is_weak_key
diff --git a/src/lib/exports.kdb5 b/src/lib/exports.kdb5
new file mode 100644 (file)
index 0000000..22d0e6e
--- /dev/null
@@ -0,0 +1,26 @@
+krb5_kdb_encrypt_key
+krb5_kdb_decrypt_key
+krb5_db_init
+krb5_db_fini
+krb5_db_open_database
+krb5_db_close_database
+krb5_db_set_name
+krb5_db_get_age
+krb5_db_lock
+krb5_db_unlock
+krb5_db_create
+kdb5_db_destroy
+krb5_db_rename
+krb5_db_get_principal
+krb5_db_free_principal
+krb5_db_put_principal
+krb5_db_delete_principal
+krb5_db_iterate
+krb5_db_set_lockmode
+krb5_db_verify_master_key
+krb5_mkey_pwd_prompt1
+krb5_mkey_pwd_prompt2
+krb5_db_fetch_mkey
+krb5_db_setup_mkey_name
+krb5_db_store_mkey
+
diff --git a/src/lib/exports.krb5 b/src/lib/exports.krb5
new file mode 100644 (file)
index 0000000..baea62b
--- /dev/null
@@ -0,0 +1,312 @@
+krb5_cc_register
+krb5_cc_resolve
+krb5_cc_default
+krb5_cc_dfl_ops
+krb5_config_file
+krb5_trans_file
+krb5_defkeyname
+krb5_lname_file
+krb5_max_dgram_size
+krb5_max_skdc_timeout
+krb5_skdc_timeout_shift
+krb5_skdc_timeout_1
+krb5_kdc_udp_portname
+krb5_default_pwd_prompt1
+krb5_default_pwd_prompt2
+krb5_init_ets
+krb5_ticket2KRB5_Ticket
+krb5_tgs_rep2KRB5_KDC__REP
+krb5_kdc_req2KRB5_KDC__REQ__BODY
+krb5_kdc_req2KRB5_KDC__REQ
+krb5_transited2KRB5_TransitedEncoding
+krb5_safe2KRB5_KRB__SAFE
+krb5_priv2KRB5_KRB__PRIV
+krb5_principal2KRB5_PrincipalName
+krb5_priv_enc_part2KRB5_EncKrbPrivPart
+krb5_pa_data2KRB5_PA__DATA
+krb5_last_req2KRB5_LastReq
+krb5_keyblock2KRB5_EncryptionKey
+krb5_kdc_rep2KRB5_KDC__REP
+krb5_enc_tkt_part2KRB5_EncTicketPart
+krb5_error2KRB5_KRB__ERROR
+krb5_enc_kdc_rep_part2KRB5_EncKDCRepPart
+krb5_enc_data2KRB5_EncryptedData
+krb5_checksum2KRB5_Checksum
+krb5_authenticator2KRB5_Authenticator
+krb5_ap_rep_enc_part2KRB5_EncAPRepPart
+krb5_ap_req2KRB5_AP__REQ
+krb5_ap_rep2KRB5_AP__REP
+krb5_addr2KRB5_HostAddress
+krb5_address2KRB5_HostAddresses
+krb5_authdata2KRB5_AuthorizationData
+krb5_flags2KRB5_TicketFlags
+krb5_decode_generic
+krb5_encode_generic
+krb5_fcc_close_file
+krb5_fcc_open_file
+krb5_fcc_interpret
+krb5_cc_file_ops
+krb5_fcc_set_flags
+krb5_fcc_write
+krb5_fcc_store_principal
+krb5_fcc_store_addrs
+krb5_fcc_store_keyblock
+krb5_fcc_store_addr
+krb5_fcc_store_data
+krb5_fcc_store_int32
+krb5_fcc_store_ui_2
+krb5_fcc_store_keytype
+krb5_fcc_store_int
+krb5_fcc_store_bool
+krb5_fcc_store_times
+krb5_fcc_store_flags
+krb5_fcc_store_authdata
+krb5_fcc_store_authdatum
+krb5_fcc_ops
+krb5_fcc_skip_principal
+krb5_fcc_store
+krb5_fcc_start_seq_get
+krb5_fcc_retrieve
+krb5_fcc_resolve
+krb5_fcc_read
+krb5_fcc_read_principal
+krb5_fcc_read_addrs
+krb5_fcc_read_keyblock
+krb5_fcc_read_data
+krb5_fcc_read_addr
+krb5_fcc_read_int32
+krb5_fcc_read_ui_2
+krb5_fcc_read_keytype
+krb5_fcc_read_int
+krb5_fcc_read_bool
+krb5_fcc_read_times
+krb5_fcc_read_flags
+krb5_fcc_read_authdata
+krb5_fcc_read_authdatum
+krb5_fcc_next_cred
+krb5_fcc_initialize
+krb5_fcc_get_principal
+krb5_fcc_get_name
+krb5_fcc_generate_new
+krb5_fcc_end_seq_get
+krb5_fcc_destroy
+krb5_fcc_close
+krb5_scc_interpret
+krb5_cc_stdio_ops
+krb5_scc_set_flags
+krb5_scc_write
+krb5_scc_store_principal
+krb5_scc_store_addrs
+krb5_scc_store_keyblock
+krb5_scc_store_addr
+krb5_scc_store_data
+krb5_scc_store_int32
+krb5_scc_store_ui_2
+krb5_scc_store_keytype
+krb5_scc_store_int
+krb5_scc_store_bool
+krb5_scc_store_times
+krb5_scc_store_flags
+krb5_scc_store_authdata
+krb5_scc_store_authdatum
+krb5_scc_ops
+krb5_scc_skip_principal
+krb5_scc_store
+krb5_scc_start_seq_get
+krb5_scc_retrieve
+krb5_scc_resolve
+krb5_scc_read
+krb5_scc_read_principal
+krb5_scc_read_addrs
+krb5_scc_read_keyblock
+krb5_scc_read_data
+krb5_scc_read_addr
+krb5_scc_read_int32
+krb5_scc_read_ui_2
+krb5_scc_read_keytype
+krb5_scc_read_int
+krb5_scc_read_bool
+krb5_scc_read_times
+krb5_scc_read_flags
+krb5_scc_read_authdata
+krb5_scc_read_authdatum
+krb5_scc_next_cred
+krb5_scc_initialize
+krb5_scc_get_principal
+krb5_scc_get_name
+krb5_scc_generate_new
+krb5_scc_end_seq_get
+krb5_scc_destroy
+krb5_scc_close
+krb5_kt_dfl_ops
+krb5_ktfile_wresolve
+krb5_ktf_writable_ops
+krb5_ktf_ops
+krb5_ktfileint_openr
+krb5_ktfileint_openw
+krb5_ktfileint_close
+krb5_ktfileint_read_entry
+krb5_ktfileint_write_entry
+krb5_ktfile_start_seq_get
+krb5_ktfile_remove
+krb5_ktfile_resolve
+krb5_ktfile_get_next
+krb5_ktfile_get_name
+krb5_ktfile_get_entry
+krb5_ktfile_end_get
+krb5_ktfile_close
+krb5_ktfile_add
+krb5_kt_read_service_key
+krb5_kt_remove_entry
+krb5_kt_free_entry
+krb5_kt_default
+krb5_kt_register
+krb5_kt_resolve
+krb5_kt_add_entry
+krb5_walk_realm_tree
+krb5_unparse_name_ext
+krb5_unparse_name
+krb5_tgtname
+krb5_get_server_rcache
+krb5_send_tgs
+krb5_sendauth
+krb5_recvauth
+krb5_rd_safe
+krb5_rd_req_decoded
+krb5_rd_req_simple
+krb5_rd_req
+krb5_rd_rep
+krb5_rd_priv
+krb5_rd_error
+krb5_principal_compare
+krb5_principal2salt
+krb5_parse_name
+krb5_mk_safe
+krb5_mk_req_extended
+krb5_mk_req
+krb5_mk_rep
+krb5_mk_priv
+krb5_mk_error
+krb5_clockskew
+krb5_kdc_req_sumtype
+krb5_kdc_default_options
+krb5_kdc_rep_decrypt_proc
+krb5_get_in_tkt_with_skey
+krb5_get_in_tkt_with_password
+krb5_get_in_tkt
+krb5_get_credentials
+krb5_generate_subkey
+krb5_generate_seq_number
+krb5_get_cred_via_2tgt
+krb5_get_cred_via_tgt
+krb5_get_cred_from_kdc
+krb5_fulladdr_order
+krb5_free_realm_tree
+krb5_encrypt_tkt_part
+krb5_encode_kdc_rep
+krb5_decrypt_tkt_part
+krb5_decode_kdc_rep
+krb5_copy_keyblock_contents
+krb5_copy_ticket
+krb5_copy_principal
+krb5_copy_keyblock
+krb5_copy_data
+krb5_copy_creds
+krb5_copy_checksum
+krb5_copy_authenticator
+krb5_copy_authdata
+krb5_copy_addresses
+krb5_build_principal_va
+krb5_build_principal
+krb5_build_principal_ext
+krb5_address_search
+krb5_address_order
+krb5_address_compare
+krb5_auth_to_rep
+krb5_rc_dfl_ops
+krb5_rc_io_creat
+krb5_rc_io_open
+krb5_rc_io_move
+krb5_rc_io_write
+krb5_rc_io_read
+krb5_rc_io_close
+krb5_rc_io_destroy
+krb5_rc_io_mark
+krb5_rc_io_unmark
+krb5_rc_dfl_get_name
+krb5_rc_dfl_get_span
+krb5_rc_dfl_init
+krb5_rc_dfl_close
+krb5_rc_dfl_destroy
+krb5_rc_dfl_resolve
+krb5_rc_dfl_recover
+krb5_rc_dfl_store
+krb5_rc_dfl_expunge
+krb5_rc_register_type
+krb5_rc_resolve_type
+krb5_rc_get_type
+krb5_rc_default_type
+krb5_rc_default_name
+krb5_rc_default
+krb5_rc_resolve_full
+krb5_free_tkt_authent
+krb5_free_tgt_creds
+krb5_free_tickets
+krb5_free_ticket
+krb5_free_safe
+krb5_free_priv_enc_part
+krb5_free_priv
+krb5_free_principal
+krb5_free_pa_data
+krb5_free_last_req
+krb5_free_keyblock
+krb5_free_kdc_req
+krb5_free_kdc_rep
+krb5_free_error
+krb5_free_enc_tkt_part
+krb5_free_enc_kdc_rep_part
+krb5_free_cred_contents
+krb5_free_creds
+krb5_free_checksum
+krb5_free_authenticator
+krb5_free_authdata
+krb5_free_ap_rep_enc_part
+krb5_free_ap_req
+krb5_free_ap_rep
+krb5_free_addresses
+krb5_free_address
+krb5_write_message
+krb5_us_timeofday
+krb5_unlock_file
+krb5_timeofday
+krb5_sname_to_principal
+krb5_sendto_kdc
+krb5_read_password
+krb5_read_message
+krb5_random_confounder
+krb5_unpack_full_ipaddr
+krb5_net_write
+krb5_net_read
+krb5_lock_file
+krb5_locate_kdc
+krb5_os_localaddr
+krb5_kuserok
+krb5_kt_default_name
+krb5_get_host_realm
+krb5_gen_replay_name
+krb5_gen_portaddr
+krb5_get_krbhst
+krb5_make_full_ipaddr
+krb5_free_host_realm
+krb5_free_krbhst
+krb5_cc_default_name
+krb5_get_default_realm
+krb5_aname_to_localname
+krb5_csarray
+krb5_max_cryptosystem
+krb5_keytype_array
+krb5_max_keytype
+krb5_cksumarray
+krb5_max_cksum
+krb5_scc_close_file
+krb5_scc_open_file
diff --git a/src/lib/glue4.c b/src/lib/glue4.c
new file mode 100644 (file)
index 0000000..08566f0
--- /dev/null
@@ -0,0 +1,19 @@
+#include <krb5/krb5.h>
+
+krb5_data string_list[3] = {
+{11, "FOO.MIT.EDU"},
+{6, "jtkohl"},
+};
+
+krb5_data *princ[] = {&string_list[0], &string_list[1], 0};
+
+krb5_data string_list2[3] = {
+{11, "FOO.MIT.EDU"},
+{4, "rcmd"},
+{13, "lycus.mit.edu"},
+};
+
+krb5_data *princ2[] = {&string_list2[0], &string_list2[1], &string_list2[2], 0};
+                                  
+krb5_last_req_entry lrentries[] = { {32000, 1}, {0, 3}, {10, 2} };
+krb5_last_req_entry *lrfoo1[] = {&lrentries[0], &lrentries[1], &lrentries[2], 0};
diff --git a/src/lib/gssapi/README b/src/lib/gssapi/README
new file mode 100644 (file)
index 0000000..dd1a074
--- /dev/null
@@ -0,0 +1,8 @@
+WARNING!  The contents of this directory are Alpha-test quality at
+best.  The definition of the GSS API is still in flux, and this code
+has not really been tested due to a lack of an implementation to link
+against.
+
+Look in doc/gss/* for more information.
+
+
diff --git a/src/lib/gssapi/sample/Imakefile b/src/lib/gssapi/sample/Imakefile
new file mode 100644 (file)
index 0000000..045f87e
--- /dev/null
@@ -0,0 +1,59 @@
+#      $Source$
+#      $Author$
+#      $Id$
+#
+#  Copyright 1991 by the Massachusetts Institute of Technology.
+#  All Rights Reserved.
+# 
+#  For copying and distribution information, please see the file
+#  <krb5/copyright.h>.
+# 
+
+        DEPLIBS = ../libgssapi.a $(DEPKLIB) 
+LOCAL_LIBRARIES = ../libgssapi.a $(KLIB) 
+        DEFINES = -DDEBUG
+
+SRCS = flogin.c fcmd.c flogind.c fsh.c fcp.c login.c logutil.c 
+OBJS = flogin.o fcmd.o flogind.o fsh.o fcp.o login.o logutil.o 
+
+FLOGINSRCS = flogin.c fcmd.c
+FLOGINOBJS = flogin.o fcmd.o
+
+LOGINSRCS = login.c logutil.c
+LOGINOBJS = login.o logutil.o
+
+FLOGINDSRCS = flogind.c logutil.c
+FLOGINDOBJS = flogind.o logutil.o
+
+FSHSRCS = fsh.c fcmd.c
+FSHOBJS = fsh.o fcmd.o
+
+FSHDSRCS = fshd.c 
+FSHDOBJS = fshd.o
+
+FCPSRCS = fcp.c fcmd.c
+FCPOBJS = fcp.o fcmd.o
+
+all:: flogin login.gssapi flogind
+
+NormalProgramTarget(flogin,$(FLOGINOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(login.gssapi,$(LOGINOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(flogind,$(FLOGINDOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fsh,$(FSHOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fshd,$(FSHDOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fcp,$(FCPOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+
+SaberProgramTarget(flogin, $(FLOGINSRCS), $(FLOGINOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(login.gssapi, $(LOGINSRCS), $(LOGINOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(flogind, $(FLOGINDSRCS), $(FLOGINDOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fsh, $(FSHSRCS), $(FSHOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fshd, $(FSHDSRCS), $(FSHDOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fcp, $(FCPSRCS), $(FCPOBJS), 
+       $(DEPLIBS) $(LOCAL_LIBRARIES),)
+
+DependTarget()
diff --git a/src/lib/gssapi/sample/MAIL.KANNAN b/src/lib/gssapi/sample/MAIL.KANNAN
new file mode 100644 (file)
index 0000000..0bd0f0a
--- /dev/null
@@ -0,0 +1,114 @@
+Received: by E40-PO.MIT.EDU (5.45/4.7) id AA17675; Fri, 24 May 91 14:58:47 EDT
+Received: from uucp-gw-1.pa.dec.com by ATHENA.MIT.EDU with SMTP
+       id AA18573; Fri, 24 May 91 14:58:33 EDT
+Received: by uucp-gw-1.pa.dec.com; id AA01785; Fri, 24 May 91 11:56:31 -0700
+Received: by sejour.lkg.dec.com (5.57/Ultrix4.0)
+       id AA15569; Fri, 24 May 91 15:00:01 -0400
+Message-Id: <9105241900.AA15569@sejour.lkg.dec.com>
+To: tytso@ATHENA.MIT.EDU
+Cc: kannan@sejour.lkg.dec.com
+Subject: GSS API for SPX ready for testing
+Date: Fri, 24 May 91 15:00:00 EDT
+From: kannan@sejour.lkg.dec.com
+
+Ted,
+
+I have completed the initial implementation of the GSS API for the SPX
+mechanism and I've modified the flogin program to use this new
+interface.  My "standard" GSS library includes the following routines:
+
+/*
+ * Offering "standard" GSS API for following mechanism(s) :  SPX
+ *
+ * Supported jacket routines :
+ *
+ *     gss_acquire_cred             Assume a global identity
+ *
+ *     gss_release_cred             Discard credentials
+ *
+ *     gss_init_sec_context         Initiate a security context with a
+ *                                  peer application
+ *
+ *     gss_accept_sec_context       Accept a security context from a
+ *                                  peer application
+ *
+ *     gss_display_status           Convert an API status code to text
+ *
+ *     gss_indicate_mechs           Determine underlying mechanism
+ *
+ *     gss_display_name             Convert opaque name to text
+ *
+ *     gss_import_name              Convert a textual name to API-format
+ *
+ *     gss_release_name             Deallocate API internal name
+ *
+ *     gss_release_buffer           Deallocate a buffer descriptor
+ *
+ *     gss_release_oid_set          Deallocate a set of object identifiers
+ *
+ * Unofficial jacket routines :
+ *
+ *     gss__stash_default_cred      Bind credential handle as default
+ *
+ *     gss__check_authorization     Check authorization rights for principal
+ *
+ */
+
+As you can tell, I have two unofficial routines referred to as "gss__"
+instead of "gss_".
+
+The first, gss__stash_default_cred will set the specified credential as
+the default for a process.  After calling this routine, GSS_C_NULL_CREDENTIAL
+can be used by the calling application to reference the stashed credentials.
+Note, if GSS_C_NULL_CREDENTIAL is passed to this routine, success is returned.
+
+/*
+ * WARNING:  UNOFFICIAL GSSAPI ROUTINE!!
+ *
+ * gss__stash_default_cred() - Allows remote peer to bind delegated credential
+ *   handle with remote application.  Called by applications to set the
+ *   delegated credentials as the default credentials for a process.
+ *
+ *   OM_uint32    *minor_status  (output) - mechanism specific status code
+ *   gss_cred_id_t delegated_cred_handle (input) - handle for credentials
+ *                                         received from context initiator.
+ *
+ */
+
+The second, gss__check_authorization is a bit more controversial.  This
+routine will check access rights for a principal against an ACL file.
+I've added a few additional arguments to make this routine more robust
+so that access control decisions can be based on a per service and
+possible per resource basis.
+
+/*
+ * WARNING:  UNOFFICIAL GSSAPI ROUTINE!!
+ *
+ * gss__check_authorization() - Check authorization rights for principal
+ *   using the ACL file specified.
+ *
+ *   OM_uint32    *minor_status  (output) - mechanism specific status code
+ *   gss_buffer_t fullname_buffer (input) - principal's printable name
+ *   gss_buffer_t luser_buffer   (input)  - local user name
+ *   gss_buffer_t acl_file_buffer (input) - acl file name
+ *   gss_buffer_t service_buffer (input)  - service name
+ *   int          access_mode    (input)  - type of access (rwx, etc.)
+ *   gss_buffer_t resource_buffer (input) - resource name
+ *
+ */
+
+I've also defined 3 unofficial constants to describe the access modes.
+
+#define GSS_C_READ       (1 << 0)
+#define GSS_C_WRITE      (1 << 1)
+#define GSS_C_EXECUTE    (1 << 2)
+
+You look at the application source code to see how these routines are
+being used.  The next message will contain the following files:
+
+       - Makefile, flogin.c fcmd.c flogind.c login.c
+
+Talk to you later.
+
+       -kannan
+
diff --git a/src/lib/gssapi/sample/Makefile.bak b/src/lib/gssapi/sample/Makefile.bak
new file mode 100644 (file)
index 0000000..3dd42fb
--- /dev/null
@@ -0,0 +1,396 @@
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+###########################################################################
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.002934>
+# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
+#
+# Platform-specific parameters may be set in the appropriate .cf
+# configuration files.  Site-wide parameters may be set in the file
+# site.def.  Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor doesn't define any unique symbols, you'll need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make Makefile", "make Makefiles", or "make World").
+#
+# If you absolutely can't get imake to work, you'll need to set the
+# variables at the top of each Makefile as well as the dependencies at the
+# bottom (makedepend will do this automatically).
+#
+
+###########################################################################
+# platform-specific configuration parameters - edit vaxbsd.cf to change
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+###########################################################################
+# site-specific configuration parameters - edit site.def to change
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
+
+            SHELL =    /bin/sh
+
+              TOP = ../../../.
+      CURRENT_DIR = ./lib/gssapi/sample
+
+               AR = ar cq
+  BOOTSTRAPCFLAGS =
+               CC = gcc -fstrength-reduce -fpcc-struct-return -pedantic -ansi -Wall -Dunix -Dvax
+
+         COMPRESS = compress
+              CPP = /lib/cpp $(STD_CPP_DEFINES)
+    PREPROCESSCMD = gcc -fstrength-reduce -fpcc-struct-return -pedantic -ansi -Wall -Dunix -Dvax -E $(STD_CPP_DEFINES)
+          INSTALL = install
+               LD = ld
+      LDLOCATIONS =
+             LINT = lint
+      LINTLIBFLAG = -C
+         LINTOPTS = -axz
+               LN = ln -s
+             MAKE = make
+               MV = mv
+               CP = cp
+           RANLIB = ranlib
+  RANLIBINSTFLAGS =
+               RM = rm -f
+     STD_INCLUDES =
+  STD_CPP_DEFINES =
+      STD_DEFINES =
+    SABER_DEFINES = -I/mit/gnu/vaxlib/gcc-include -Dconst=
+ EXTRA_LOAD_FLAGS = -Z
+  EXTRA_LIBRARIES =
+             TAGS = ctags
+            ETAGS = etags
+STDC_TOP_INCLUDES = -I$(TOP)/include/stdc-incl
+
+   SIGNAL_DEFINES = -DSIGNALRETURNSINT
+
+     INSTPGMFLAGS =  -s
+
+     INSTSCRFLAGS =
+     INSTBINFLAGS = -m 0755
+     INSTUIDFLAGS = -o root -m 4755
+     INSTLIBFLAGS = -m 0664
+     INSTINCFLAGS = -m 0444
+     INSTMANFLAGS = -m 0444
+     INSTDATFLAGS = -m 0444
+    INSTKMEMFLAGS = -o root -m 4755
+
+          DESTDIR =
+
+     TOP_INCLUDES = -I$(TOP)
+
+      CDEBUGFLAGS = -O
+        CCOPTIONS =
+      COMPATFLAGS =
+
+      ALLINCLUDES = $(INCLUDES) $(STD_INCLUDES) $(TOP_INCLUDES) $(EXTRA_INCLUDES)
+       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
+           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LDLOCATIONS)
+   LDCOMBINEFLAGS = -X -r
+          MDFLAGS = -D__STDC__ -I/mit/gnu/vaxlib/gcc-include
+
+        MACROFILE = vaxbsd.cf
+           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+    IMAKE_DEFINES =
+
+         IRULESRC = $(CONFIGSRC)
+
+        IMAKE_CMD = $(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES)
+
+     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+                       $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+                       $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# Kerberos version 5 Build Parameters
+#
+# $Source$
+# $Author$
+# $Id$
+
+P_TERMIOS=-UHasPosixTermiosTrue
+
+P_FLOCKS=-UHasPosixFileLocksTrue
+
+P_TYPES=-UHasPosixTypesTrue
+
+P_SIGTYPE=-UHasVoidSignalReturnTrue
+
+P_STRINGH=-DHasStringHTrue
+
+P_BITSIZE=-DBitsize32 -UBitsize16 -UBitsize64
+
+P_DBM=-DHasNdbmTrue
+
+P_INET=-DHasInetTrue
+
+P_STDLIBH=-UHasStdlibHTrue -UForceStdlibH
+
+P_TIME_DEFS=-DUseSysTimeH -UUseTimeH
+
+P_PROTOS=-UProvidePrototypes
+
+P_NPROTO=-UUseNarrowPrototypes
+
+P_STDARG=-UUseStdarg
+
+            ARADD = ar cruv
+     TOP_INCLUDES = -I$(TOP)/include $(STDC_TOP_INCLUDES)
+        CONFIGSRC = $(TOP)/config
+            ISODE = /mit/isode/isode-6.8
+         PSYFLAGS = -f -h0 -a -s
+            PEPSY = $(ISODE)/@sys/bin/pepsy
+            TOUCH = touch
+            IMAKE = imake
+           DEPEND = makedepend
+          UNIFDEF = unifdef
+          HESDEFS = -DHESIOD
+          HESLIBS = -lhesiod
+
+  PROCESS_DEFINES = $(P_TERMIOS) $(P_FLOCKS) $(P_TYPES) $(P_SIGTYPE) $(P_STRINGH) $(P_BITSIZE) $(P_DBM) $(P_INET) $(P_STDLIBH) $(P_TIME_DEFS) $(P_PROTOS) $(P_NPROTO) $(P_STDARG) -DUnifdefRan
+       DESDEFINES = -DBIG -DLSBFIRST
+          TOPLIBD = $(TOP)/lib
+            OSLIB = os
+         OSDEPLIB = $(TOPLIBD)/libos.a
+           DESLIB = des5
+        DESDEPLIB = $(TOPLIBD)/libdes5.a
+        RSAMD4LIB = md4
+     RSAMD4DEPLIB = $(TOPLIBD)/libmd4.a
+          KRB5LIB = krb5
+       KRB5DEPLIB = $(TOPLIBD)/libkrb5.a
+           CRCLIB = crc32
+        CRCDEPLIB = $(TOPLIBD)/libcrc32.a
+         ISODELIB = -L/mit/isode/isode-6.8/@sys/lib -lisode
+
+           DBMLIB =
+          DEPKLIB = $(KRB5DEPLIB) $(DESDEPLIB) $(OSDEPLIB)
+          KLIBLOC = -L$(TOPLIBD)
+             KLIB = $(KLIBLOC) -l$(KRB5LIB) -l$(DESLIB) -l$(OSLIB) $(ISODELIB) $(COMERRLIB) $(DBMLIB)
+        KDBDEPLIB = $(TOPLIBD)/libkdb.a
+           KDBLIB = $(KLIBLOC) -lkdb
+     KRB425DEPLIB = $(TOPLIBD)/libkrb425.a
+        KRB425LIB = krb425
+     DES425DEPLIB = $(TOPLIBD)/libdes425.a
+        DES425LIB = des425
+          KRB4LIB = -lkrb $(KLIBLOC) -l$(DES425LIB)
+     KRB4INCLUDES = -I$(TOP)/include/kerberosIV
+       KRB4DEPLIB = $(DES425DEPLIB)
+
+            SSLIB = -lss
+          MK_CMDS = mk_cmds
+        COMERRLIB = -lcom_err
+       COMPILE_ET = compile_et
+
+     ADMIN_BINDIR = /krb5/admin
+  ADMIN_MANSUFFIX = 8
+     ADMIN_MANDIR = /krb5/man/man8
+    SERVER_BINDIR = /krb5/sbin
+ SERVER_MANSUFFIX = 8
+    SERVER_MANDIR = /krb5/man/man8
+    CLIENT_BINDIR = /krb5/bin
+ CLIENT_MANSUFFIX = 1
+    CLIENT_MANDIR = /krb5/man/man1
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+###########################################################################
+# Imake rules for building libraries, programs, scripts, and data files
+# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
+
+###########################################################################
+# start of Imakefile
+
+#      $Source$
+#      $Author$
+#      $Id$
+#
+#  Copyright 1991 by the Massachusetts Institute of Technology.
+#  All Rights Reserved.
+#
+#  For copying and distribution information, please see the file
+#  <krb5/copyright.h>.
+#
+
+        DEPLIBS = $(DEPKLIB) ../libgssapi.a
+LOCAL_LIBRARIES = $(KLIB) ../libgssapi.a
+        DEFINES = -DDEBUG
+
+SRCS = flogin.c fcmd.c flogind.c fsh.c fcp.c login.c logutil.c
+OBJS = flogin.o fcmd.o flogind.o fsh.o fcp.o login.o logutil.o
+
+FLOGINSRCS = flogin.c fcmd.c
+FLOGINOBJS = flogin.o fcmd.o
+
+LOGINSRCS = login.c logutil.c
+LOGINOBJS = login.o logutil.o
+
+FLOGINDSRCS = flogind.c logutil.c
+FLOGINDOBJS = flogind.o logutil.o
+
+FSHSRCS = fsh.c fcmd.c
+FSHOBJS = fsh.o fcmd.o
+
+FSHDSRCS = fshd.c
+FSHDOBJS = fshd.o
+
+FCPSRCS = fcp.c fcmd.c
+FCPOBJS = fcp.o fcmd.o
+
+all:: flogin login.gssapi flogind
+
+flogin: $(FLOGINOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(FLOGINOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) flogin
+
+login.gssapi: $(LOGINOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(LOGINOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) login.gssapi
+
+flogind: $(FLOGINDOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(FLOGINDOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) flogind
+
+fsh: $(FSHOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(FSHOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) fsh
+
+fshd: $(FSHDOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(FSHDOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) fshd
+
+fcp: $(FCPOBJS) $(DEPLIBS)
+        $(RM) $@
+       $(CC) -o $@ $(FCPOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS)  $(EXTRA_LOAD_FLAGS)
+
+clean::
+       $(RM) fcp
+
+saber_flogin:
+       #load $(ALLDEFINES)  $(FLOGINSRCS)      $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_flogin:
+       #load $(ALLDEFINES)  $(FLOGINOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_login.gssapi:
+       #load $(ALLDEFINES)  $(LOGINSRCS)       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_login.gssapi:
+       #load $(ALLDEFINES)  $(LOGINOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_flogind:
+       #load $(ALLDEFINES)  $(FLOGINDSRCS)     $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_flogind:
+       #load $(ALLDEFINES)  $(FLOGINDOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fsh:
+       #load $(ALLDEFINES)  $(FSHSRCS)         $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fsh:
+       #load $(ALLDEFINES)  $(FSHOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fshd:
+       #load $(ALLDEFINES)  $(FSHDSRCS)        $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fshd:
+       #load $(ALLDEFINES)  $(FSHDOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fcp:
+       #load $(ALLDEFINES)  $(FCPSRCS)         $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fcp:
+       #load $(ALLDEFINES)  $(FCPOBJS)
+       $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+SRCS=$(SERVERSRCS) $(CLIENTSRCS)
+
+depend::
+       $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) $(MDFLAGS) -- $(SRCS)
+
+###########################################################################
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+       $(RM_CMD) \#*
+
+Makefile:: Imakefile
+       $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)   -s Makefile.new
+       $(MAKE) -f Makefile.new noop
+       -@if [ -f Makefile ]; then \
+               echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
+               $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+       fi
+       $(MV) Makefile.new Makefile
+
+noop::
+
+tags::
+       $(TAGS) -w *.[ch]
+       $(ETAGS) *.[ch]
+
+saber:
+       #load $(ALLDEFINES) $(SABER_DEFINES) $(SRCS)
+       #setopt load_flags $(ALLDEFINES) $(SABER_DEFINES)
+
+osaber:
+       #load $(ALLDEFINES) $(OBJS)
+
+###########################################################################
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+       @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+       @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+###########################################################################
+# dependencies generated by makedepend
+
+# DO NOT DELETE
diff --git a/src/lib/gssapi/sample/gssapi.mail b/src/lib/gssapi/sample/gssapi.mail
new file mode 100644 (file)
index 0000000..fce9209
--- /dev/null
@@ -0,0 +1,54 @@
+BABYL OPTIONS:
+Version: 5
+Labels:
+Note:   This is the header of an rmail file.
+Note:   If you are seeing it in rmail,
+Note:    it means the file has no messages in it.
+\1f\f
+1,,
+Received: by E40-PO.MIT.EDU (5.45/4.7) id AA21631; Fri, 31 May 91 18:18:51 EDT
+Received: from uucp-gw-1.pa.dec.com by ATHENA.MIT.EDU with SMTP
+       id AA27178; Fri, 31 May 91 18:16:24 EDT
+Received: by uucp-gw-1.pa.dec.com; id AA17698; Fri, 31 May 91 10:48:08 -0700
+Received: by sejour.lkg.dec.com (5.57/Ultrix4.0)
+       id AA11377; Fri, 31 May 91 13:51:46 -0400
+Message-Id: <9105311751.AA11377@sejour.lkg.dec.com>
+To: tytso@ATHENA.MIT.EDU
+Cc: kannan@sejour.lkg.dec.com
+Subject: Re: testing GSS API 
+In-Reply-To: Your message of Thu, 30 May 91 18:25:28 -0400.
+             <9105302225.AA24140@tsx-11.MIT.EDU> 
+Date: Fri, 31 May 91 13:51:44 EDT
+From: kannan@sejour.lkg.dec.com
+
+*** EOOH ***
+To: tytso@ATHENA.MIT.EDU
+Cc: kannan@sejour.lkg.dec.com
+Subject: Re: testing GSS API 
+In-Reply-To: Your message of Thu, 30 May 91 18:25:28 -0400.
+             <9105302225.AA24140@tsx-11.MIT.EDU> 
+Date: Fri, 31 May 91 13:51:44 EDT
+From: kannan@sejour.lkg.dec.com
+
+Here is the new rlogin code.  BTW, it is also being distributed with
+the SPX v2.1 kit.
+
+I'm sending you the following files:
+
+  Makefile, flogin.c, flogind.c, and login.c
+
+> The real test is whether or not the application runs.
+
+I agree.  Does this mean that you will implement the "unofficial" GSS API
+routines used in the flogin code?
+
+       -kannan
+
+========== Makefile ======================
+
+=====================  flogin.c ========================
+
+===================== flogind.c ================
+
+===================== login.c ======================
+\1f
\ No newline at end of file
diff --git a/src/lib/gssapi/sample/kitest.c b/src/lib/gssapi/sample/kitest.c
new file mode 100644 (file)
index 0000000..0ec048c
--- /dev/null
@@ -0,0 +1,742 @@
+/*                            KITEST-MASTER.C                              */
+/*                                                                         */
+/* Program to build GSSAPI-compliant Kerberos authentication packets, using */
+/* the Kerberos V5 (Beta 2) GSSAPI implementation, and attempt to          */
+/* authenticate to a DCE/GSSAPI implementation.                                    */
+/*                                                                         */
+/* Since both GSSAPI implementations share the same routine names, two     */
+/* executables are built by linking against either the DCE/GSSAPI or the    */
+/* Kerberos V5 GSSAPI library.  This file is compiled with the preprocessor */
+/* name KERBEROS defined if it is to invoke the Kerberos API, and with DCE  */
+/* defined if it is to link against the DCE/GSSAPI.                        */
+/*                                                                         */
+/* Invocation should specify two parameters -                              */
+/* 1) Name of initiating principal                                         */
+/* 2) Name of accepting principal                                          */
+/*                                                                         */
+/* A flag '-S' is used to specify the name of the file that process will    */
+/* activate as a slave.                                                            */
+/*                                                                         */
+/* So to test, for example, Kerberos against Kerberos, and assuming that    */
+/* the executable is called kitest-krb, you'd set up a Kerberos credential  */
+/* for <client-name> using kinit, and arrange for a server Kerberos         */
+/* credential for <server-name> to be available in a keytable, and issue    */
+/* the command:                                                             */
+/*       kitest-krb -S kitest-krb <client-name> <server-name>               */
+/*                                                                          */
+/* The original process becomes the context initiator, while the spawned    */
+/* subprocess (running the executable specified after the -S flag) is       */
+/* expected to act as the context acceptor.                                 */
+
+#if defined(KERBEROS) && defined(DCE)
+#error "Both KERBEROS and DCE specified"
+#endif
+
+#if !defined(KERBEROS) && !defined(DCE)
+#error "Neither KERBEROS nor DCE defined"
+#endif 
+
+/* You need to create links from krb-gssapi.h to the Kerberos gssapi.h, and  */
+/* from dce-gssapi.h to the DCE gssapi.h.                                    */
+#ifdef KERBEROS
+#include "krb-gssapi.h"
+#endif
+
+#ifdef DCE
+#include "dce-gssapi.h"
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+#ifndef GSS_ERROR
+#define GSS_ERROR(x) (x & 0xffff0000)
+/* The Kerberos gssapi.h doesn't define this macro.                         */
+#endif
+
+#define DOWN_CHANNEL 3
+/* Don't understand why stdin doesn't work here, but channel 3 seems to     */
+/* work fine.                                                               */
+
+#define INITIAL_CHILD_MESSAGES 7
+
+extern int errno;
+
+int master = 0;
+int inpipe[2];
+int outpipe[2];
+int errpipe[2];
+
+gss_name_t source_internal_name;
+gss_name_t target_internal_name;
+gss_name_t source_authenticated_name;
+gss_buffer_desc source_name_buffer;
+gss_buffer_desc target_name_buffer;
+
+gss_cred_id_t my_cred_handle;
+gss_cred_id_t delegated_cred_handle;
+gss_ctx_id_t my_ctx_handle;
+gss_OID_set actual_cred_mech_set;
+gss_OID actual_ctx_mech_type;
+OM_uint32 actual_cred_time_rec;
+OM_uint32 actual_ctx_time_rec;
+gss_buffer_desc token_to_send;
+gss_buffer_desc token_received;
+int actual_ret_flags;
+struct gss_channel_bindings_struct my_channel_bindings;
+
+char source_name[512];        
+char target_name[512];        
+
+char my_host_name[50];
+char my_internet_address[4];
+struct hostent * my_hostent;
+
+unsigned char received_token_buffer[2048];
+unsigned received_length;
+
+OM_uint32 major_status;
+OM_uint32 kept_status;
+OM_uint32 minor_status;
+
+int subprocess_pid = 0;
+
+char line_buffer[128];    
+int chars_read;
+
+void indicate_data(void) {
+    fprintf(stderr, "\a\n");
+    fflush(stderr);    
+}
+
+void send_data(void * ptr, unsigned length) {
+    unsigned char length_buf[2];
+    unsigned char * char_ptr;
+    int data_sent;
+    
+    char_ptr = (unsigned char *)ptr;
+    
+    length_buf[0] = length & 0xff;
+    length_buf[1] = (length & 0xff00) >> 8;
+
+    if (master) {
+/* Data is sent via inpipe.                                                */
+       errno = 0;
+       if ((data_sent = write(inpipe[1], length_buf, 2)) != 2) {
+           fprintf(stderr,
+                   "Write of length sent %d bytes, expected 2\n",
+                   data_sent);
+           fflush(stderr);
+           if (data_sent == -1) {
+               fprintf(stderr,
+                       "Errno: %d\n",
+                       errno);
+               fflush(stderr);
+           };
+       };
+       errno = 0;
+       if ((data_sent =write(inpipe[1], ptr, length)) != length) {
+           fprintf(stderr,
+                   "Write of length sent %d bytes, expected 2\n",
+                   data_sent);
+           fflush(stderr);
+           if (data_sent == -1) {
+               fprintf(stderr,
+                       "Errno: %d\n",
+                       errno);
+               fflush(stderr);
+           };
+       };
+       fprintf(stderr, "Sending data (length = %d):\n", length);
+       fprintf(stderr, "  %2.2X %2.2X %2.2X %2.2X %2.2X...\n",
+               char_ptr[0], char_ptr[1], char_ptr[2],
+               char_ptr[3], char_ptr[4]);
+    } else {
+/* Data is sent via stdout, and a data indication on stderr.               */
+       fwrite(length_buf, 2, 1, stdout);
+       fwrite(ptr, length, 1, stdout);
+       fflush(stdout);
+       indicate_data();
+    };
+}
+
+void receive_data(void * ptr, unsigned * length) {
+    unsigned char length_buf[2];
+    unsigned char * char_ptr;
+    int data_read;
+    
+    char_ptr = (unsigned char *)ptr;
+    
+    if (master) {
+/* Data is received via outpipe.  A data indication is assumed to have been */
+/* received on errpipe, otherwise this routine will hang.                  */
+       read(outpipe[0], length_buf, 2);
+       *length = length_buf[0] | (length_buf[1]<<8);
+       read(outpipe[0], ptr, *length);
+    } else {
+/* Data is received on fd3                                                 */
+       errno = 0;
+       if ((data_read = read(DOWN_CHANNEL, length_buf, 2)) != 2) {
+           fprintf(stderr,
+                   "Error: received %d bytes for length, expecting 2\n",
+                   data_read);
+           fflush(stderr);
+           if (data_read == -1) {
+               fprintf(stderr, "errno: %d\n", errno);
+               fflush(stderr);
+           };
+       };
+
+       *length = length_buf[0] | (length_buf[1]<<8);
+
+       errno = 0;
+       if ((data_read = read(DOWN_CHANNEL, ptr, *length)) != *length) {
+           fprintf(stderr,
+                   "Error: received %d bytes for data, expecting %d\n",
+                   data_read, *length);
+           fflush(stderr);
+           if (data_read == -1) {
+               fprintf(stderr, "errno: %d\n", errno);
+               fflush(stderr);
+           };
+       };
+
+       fprintf(stderr, "Received data (length = %d):\n", *length);
+       fprintf(stderr, "  %2.2X %2.2X %2.2X %2.2X %2.2X...\n",
+               char_ptr[0], char_ptr[1], char_ptr[2],
+               char_ptr[3], char_ptr[4]);
+
+    };
+}
+
+int read_subproc_line(char * ptr, unsigned buf_length) {
+/* Returns length of data read, or zero if binary data waiting.                    */
+    int bytes_read = 0;
+    int finished = 0;
+    if (!master) {
+       fprintf(stderr, "Error: Child called read_subproc_data\n");
+       fflush(stderr);
+       exit(2);
+    } else {
+       while (!finished) {
+           read(errpipe[0], &ptr[bytes_read], 1);
+           if (ptr[bytes_read] == '\n') finished = 1;
+           if (bytes_read >= buf_length) finished = 1;
+           bytes_read ++;
+       };
+       if (bytes_read == 2 && ptr[0] == '\a') return 0;
+       else return bytes_read;
+    };
+}
+
+void display_error(char * where, OM_uint32 maj_stat, OM_uint32 min_stat) {
+    int context = 0;
+    OM_uint32 major_status, minor_status;
+    gss_buffer_desc message_buffer;
+
+    fprintf(stderr, "Error: %s\n", where);
+    fprintf(stderr, "Major status (%d) (min = %d):\n", maj_stat, min_stat);
+    fflush(stderr);
+    do {
+       message_buffer.length = 0;
+       message_buffer.value = NULL;
+       major_status = gss_display_status(&minor_status,
+                                         maj_stat,
+                                         GSS_C_GSS_CODE,
+                                         GSS_C_NULL_OID,
+                                         &context,
+                                         &message_buffer);
+       fprintf(stderr, 
+           " message_buffer.length = %u, message_buffer.value = %p\n",
+           message_buffer.length, message_buffer.value);
+       fflush(stderr);
+       if (message_buffer.length = 0) {
+           fprintf(stderr,
+                   " %.*s\n",
+                   message_buffer.length,
+                   message_buffer.value);
+           major_status = gss_release_buffer(&minor_status, &message_buffer);
+       } else {
+           fprintf(stderr, "-- no message --\n");
+            /* If we've been asked to translate an invalid status code */
+       };
+       fflush(stderr);
+
+    } while (context != 0);
+    fprintf(stderr, "Minor status:\n");
+    fflush(stderr);
+    major_status = gss_display_status(&minor_status,
+                                     min_stat,
+                                     GSS_C_MECH_CODE,
+                                     GSS_C_NULL_OID,
+                                     &context,
+                                     &message_buffer);
+    fprintf(stderr,
+           " %.*s\n",
+           message_buffer.length,
+           message_buffer.value);
+    fflush(stderr);
+    
+    major_status = gss_release_buffer(&minor_status, &message_buffer);
+
+}
+
+void import_names(void) {
+
+    source_name_buffer.value = (void *)&source_name[0];
+    source_name_buffer.length = strlen(source_name);
+
+    major_status = gss_import_name(&minor_status,
+                                  &source_name_buffer,
+                                  GSS_C_NULL_OID,
+                                  &source_internal_name);
+
+    if (major_status != GSS_S_COMPLETE)
+       display_error("Importing source principal", major_status, minor_status);
+
+    target_name_buffer.value = (void *)&target_name[0];
+    target_name_buffer.length = strlen(target_name);
+
+    major_status = gss_import_name(&minor_status,
+                                  &target_name_buffer,
+                                  GSS_C_NULL_OID,
+                                  &target_internal_name);
+
+    if (major_status != GSS_S_COMPLETE)
+       display_error("Importing target principal", major_status, minor_status);
+
+}
+
+
+void alarm_handler(int sig) {
+    fprintf(stderr, "SIGALRM received, terminating subprocess\n");
+    fflush(stderr);
+    kill(subprocess_pid, SIGTERM);
+    exit(0);
+}
+
+
+void flush_subprocess_message_queue_and_exit(void) {
+
+    signal(SIGALRM, alarm_handler);
+    alarm(10);     
+
+    do {
+       chars_read = read_subproc_line(line_buffer,
+                                      sizeof(line_buffer));
+       if (chars_read == 0) {
+           fprintf(stderr,
+                   "Unexpected binary data received from child\n");
+           fflush(stderr);
+           receive_data(received_token_buffer,
+                        &received_length);
+       } else {
+           fprintf(stderr,"CHILD> %.*s", chars_read, line_buffer);
+       };
+       fflush(stderr);
+    } while (1);
+}
+
+void sigpipe_handler(int sig) {
+    fprintf(stderr, "SIGPIPE received, flushing subprocess message queue\n");
+    fflush(stderr);
+    flush_subprocess_message_queue_and_exit();
+}
+
+int main(int argc, char *argv[]) {
+
+    int c;
+    int errflg = 0;
+    char * image_name;
+    int pid;
+
+    int i;
+    
+    extern int optind, opterr;
+    extern char * optarg;
+
+    int blocking;
+    
+    while ((c = getopt(argc, argv, "S:")) != EOF) {
+       switch (c) {
+       case 'S' : master = 1;
+                  image_name = optarg;
+                  break;
+       case '?' : errflg++;
+                  break;
+       };
+    };
+
+    if (optind < argc) {
+       strncpy(source_name, argv[optind++], sizeof(source_name)-1);
+    } else {
+       fprintf(stderr, "Error: Source name (prin-1) missing\n");
+       errflg++;
+    };
+
+    if (optind < argc) {
+       strncpy(target_name, argv[optind++], sizeof(source_name)-1);
+    } else {
+       fprintf(stderr, "Error: Target name (prin-2) missing\n");
+       errflg++;
+    };
+
+    if (optind < argc) {
+       fprintf(stderr, "Error: too many parameters\n");
+       errflg++;
+    };
+
+    if (errflg) {
+       fprintf(stderr, "Usage: %s -S <subprocess> <princ-1> <princ-2>\n", argv[0]);
+       exit(2);
+    };
+
+    gethostname(my_host_name, sizeof(my_host_name));
+    my_hostent = gethostbyname(my_host_name);
+    memcpy(&my_internet_address, my_hostent->h_addr_list[0], 4);
+
+    fprintf(stderr,"Host: '%s', %u.%u.%u.%u\n", 
+           my_host_name, 
+           my_internet_address[0],
+           my_internet_address[1],
+           my_internet_address[2],
+           my_internet_address[3]);
+
+    my_channel_bindings.initiator_addrtype = GSS_C_AF_INET;
+    my_channel_bindings.initiator_address.length = 4;
+    my_channel_bindings.initiator_address.value = my_internet_address;
+
+    my_channel_bindings.acceptor_addrtype = GSS_C_AF_INET;
+    my_channel_bindings.acceptor_address.length = 4;
+    my_channel_bindings.acceptor_address.value = my_internet_address;
+
+    my_channel_bindings.application_data.length = 0;
+    my_channel_bindings.application_data.value = NULL;
+
+    my_ctx_handle = GSS_C_NO_CONTEXT;
+
+    if (!master) {
+
+/* Subprocess.                                                             */
+
+       fprintf(stderr, "Importing names\n");
+       fflush(stderr);
+
+       import_names();
+
+       fprintf(stderr, "Calling acquire_cred\n");
+       fflush(stderr);
+
+       major_status = gss_acquire_cred(&minor_status,
+                                       target_internal_name,
+                                       60 * 60 * 24,
+                                       GSS_C_NULL_OID_SET,
+                                       GSS_C_ACCEPT,
+                                       &my_cred_handle,
+                                       &actual_cred_mech_set,
+                                       &actual_cred_time_rec);
+
+       if (major_status != GSS_S_COMPLETE) {
+           display_error("Acquiring ACCEPT credential for target principal",
+                          major_status, minor_status);
+           while (1) ;
+       };
+       
+       fprintf(stderr, "Returned from acquire_cred, waiting for token from parent\n");
+       fflush(stderr);
+
+       do {
+
+           receive_data(received_token_buffer,
+                        &received_length);
+           token_received.value = (void *)received_token_buffer; 
+           token_received.length = received_length; 
+           
+           fprintf(stderr, "Got token, calling accept_sec_context\n");
+           fflush(stderr);
+
+           major_status = gss_accept_sec_context(&minor_status,
+                                                &my_ctx_handle,
+                                                my_cred_handle,
+                                                &token_received,
+                                                &my_channel_bindings,
+                                                &source_authenticated_name,
+                                                &actual_ctx_mech_type,
+                                                &token_to_send,
+                                                &actual_ret_flags,
+                                                &actual_ctx_time_rec,
+                                                &delegated_cred_handle);
+           kept_status = major_status;
+
+           if (GSS_ERROR(major_status)) {
+               display_error("ACCEPT_SEC_CONTEXT",
+                              major_status, minor_status);
+               while (1) ;
+           };
+               
+           if (token_to_send.length != 0) {
+               send_data(token_to_send.value, token_to_send.length);
+               major_status = gss_release_buffer(&minor_status,
+                                                 &token_to_send);
+           };
+
+           if (kept_status & GSS_S_CONTINUE_NEEDED) {
+               receive_data(received_token_buffer,
+                            &received_length);
+               token_received.value = (void *)received_token_buffer; 
+               token_received.length = received_length; 
+           };
+
+       } while (kept_status & GSS_S_CONTINUE_NEEDED);  
+
+       if (!GSS_ERROR(kept_status)) {
+           fprintf(stderr, "Authenticated context established\n");
+       } else {
+           fprintf(stderr, "Context not established\n");
+       };
+       fflush(stderr);
+       while (1) ;
+    } else {
+/* We need to create three pipes - inpipe, outpipe and errpipe, to which    */
+/* the subprocess will connect its fd3, stdout and stderr channels.        */
+
+       if (pipe(inpipe) < 0) {
+           fprintf(stderr, "Error: Can't make inpipe\n");
+           exit(2);
+       };
+       if (pipe(outpipe) < 0) {
+           fprintf(stderr, "Error: Can't make outpipe\n");
+           exit(2);
+       };
+       if (pipe(errpipe) < 0) {
+           fprintf(stderr, "Error: Can't make errpipe\n");
+           exit(2);
+       };
+
+       if ((subprocess_pid = fork()) == 0) {
+/* This is the slave subprocess in a two-process chain.  Connect inpipe,    */
+/* outpipe and errpipe to fd3, stderr and stdout, and then exec the slave */
+/* image.                                                                  */
+           fprintf(stderr, "CHILD: forked, closing pipes\n");
+           fflush(stderr);
+
+           close(inpipe[1]);  /* Close write end of inpipe                 */
+           close(outpipe[0]); /* Close read end of outpipe                 */
+           close(errpipe[0]); /* Close read end of errpipe                 */
+
+
+           write (errpipe[1],
+                   "Child process forked (write to errpipe[1])\n",
+                   strlen("Child process forked (write to errpipe[1])\n")
+                 );
+
+           if (dup2(inpipe[0], DOWN_CHANNEL) == -1) {
+               fprintf(stderr, "CHILD: Can't dup2 inpipe[0]\n");
+               fflush(stderr);
+           };
+               /* Attach inpipe to fd3             */
+           if (dup2(outpipe[1], 1) == -1) {
+               fprintf(stderr, "CHILD: Can't dup2 outpipe[1]\n");
+               fflush(stderr);
+           };
+               /* Attach outpipe to stdout                 */
+           if (dup2(errpipe[1], 2) == -1) {
+               fprintf(stderr, "CHILD: Can't dup2 errpipe[1]\n");
+               fflush(stderr);
+           };
+                /* Attach errpipe to stderr                */
+           
+           write (2,
+                   "Child process forked (write to fd2)\n",
+                   strlen("Child process forked (write to fd2)\n")
+                 );
+                   
+           fprintf(stderr, "Execing %s\n", image_name);
+           fflush(stderr);
+
+           execl(image_name, image_name, source_name, target_name,  (char *)0);
+
+           fprintf(stderr, "Error: Couldn't exec %s\n", image_name);
+           exit(2);
+
+       } else if (subprocess_pid < 0) {
+           fprintf(stderr, "Error: Fork returned %d\n", subprocess_pid);
+           exit(2);
+       } else {
+/* This is the master process in a two-process chain.  The slave process    */
+/* has connected inpipe, outpipe and errpipe to its fd3, stdout and        */
+/* stderr.  We have to use the other ends.                                 */
+
+
+           close(inpipe[0]);  /* Close read end of inpipe                  */
+           close(outpipe[1]); /* Close write end of outpipe                */
+           close(errpipe[1]); /* Close write end of errpipe                */
+
+/* A simple protocol will be used between master and slave processes.  The  */
+/* subprocess (slave) will always expect that data received on its inpipe   */
+/* will be binary messages, preceeded by a two-byte count.  Messages from   */
+/* slave to master will be sent on the errpipe channel if they are text            */
+/* messages, and on outpipe if they are binary data (preceeded as above by  */
+/* a two-byte count field).  The presence of a binary message in the       */
+/* outpipe will be indicated by writing the sequence "\a\n" to errpipe.            */
+/* This protocol is implemented in the master by the routine               */
+/* read_subproc_line, which reads a single line of text from the           */
+/* subprocess, returning either its length, or zero to indicate that binary */
+/* data is waiting.  Binary data is received by either process by invoking  */
+/* the receive_data routine, and sent by invoking the send_data routine.    */
+/* The receive_data routine will block until the data is available, so     */
+/* care should be taken in the master not to call this routine unless a            */
+/* data indication has already been received.                              */
+
+/* Master:                                                                 */
+           signal(SIGPIPE, sigpipe_handler);
+
+/* The child will send us messages on start-up (at least                    */
+/* INITIAL_CHILD_MESSAGES of them), so we'll read them here to make sure we */
+/* catch a sleepy child early.                                              */
+
+           fprintf(stderr, "Parent waiting for wake-up call from child...\n");
+           fflush(stderr);
+
+           signal(SIGALRM, alarm_handler);
+           alarm(10);      
+
+           for (i=0; i<INITIAL_CHILD_MESSAGES; i++) {
+               chars_read = read_subproc_line(line_buffer,
+                                              sizeof(line_buffer));
+
+               if (chars_read == 0) {
+                   fprintf(stderr,
+                           "Unexpected binary data received from child\n");
+                   fflush(stderr);
+                   receive_data(received_token_buffer,
+                                &received_length);
+               } else {
+                   fprintf(stderr,"CHILD> %.*s", chars_read, line_buffer);
+               };
+               fflush(stderr);
+
+           };
+           
+           alarm(0);
+
+           fprintf(stderr, "Parent continuing, importing names...\n");
+           fflush(stderr);
+
+           import_names();
+                                      
+           fprintf(stderr, "Parent got names...\n");
+           fflush(stderr);
+
+#ifdef KERBEROS
+
+/* This version of the acquire_cred code requests the client credential     */
+/* explicitly by name; the DCE version uses no name, meaning "give me a     */
+/* to the default credential.                                               */
+
+           fprintf(stderr, "Parent calling acquire_cred...\n");
+           fflush(stderr);
+
+           major_status = gss_acquire_cred(&minor_status,
+                                           source_internal_name,
+                                           60 * 60 * 24,
+                                           GSS_C_NULL_OID_SET,
+                                           GSS_C_INITIATE,
+                                           &my_cred_handle,
+                                           &actual_cred_mech_set,
+                                           &actual_cred_time_rec);
+
+           fprintf(stderr, "Parent returned from acquire_cred.\n");
+           fflush(stderr);
+
+#endif
+#ifdef DCE
+           major_status = gss_acquire_cred(&minor_status,
+                                           GSS_C_NO_NAME,
+                                           60 * 60 * 24,
+                                           GSS_C_NULL_OID_SET,
+                                           GSS_C_INITIATE,
+                                           &my_cred_handle,
+                                           &actual_cred_mech_set,
+                                           &actual_cred_time_rec);
+#endif
+           if (major_status != GSS_S_COMPLETE)
+               display_error("Acquiring INITIATE credential for source principal",
+                              major_status, minor_status);
+
+
+           token_received.length = 0;
+           token_received.value = NULL;
+           
+           do {
+
+               fprintf(stderr, "Parent calling init_sec_ctx...\n");
+               fflush(stderr);
+
+               major_status = gss_init_sec_context(&minor_status,
+                                                   my_cred_handle,
+                                                   &my_ctx_handle,
+                                                   target_internal_name,
+                                                   GSS_C_NULL_OID,
+                                                   GSS_C_MUTUAL_FLAG,
+                                                   60 * 60 * 23,
+                                                   &my_channel_bindings,
+                                                   &token_received,
+                                                   &actual_ctx_mech_type,
+                                                   &token_to_send,
+                                                   &actual_ret_flags,
+                                                   &actual_ctx_time_rec);
+
+               fprintf(stderr, "Parent returned from init_sec_ctx...\n");
+               fflush(stderr);
+
+               kept_status = major_status;
+    
+               if (GSS_ERROR(major_status))
+                   display_error("INIT_SEC_CONTEXT",
+                                  major_status, minor_status);
+               
+               if (token_to_send.length != 0) {
+
+                   fprintf(stderr, "Parent transmitting token...\n");
+                   fflush(stderr);
+
+                   send_data(token_to_send.value, token_to_send.length);
+                   major_status = gss_release_buffer(&minor_status,
+                                                     &token_to_send);
+               };
+
+               if (kept_status & GSS_S_CONTINUE_NEEDED) {
+                   signal(SIGALRM, alarm_handler);
+                   alarm(30);
+                   while ((chars_read = read_subproc_line(line_buffer,
+                                                         sizeof(line_buffer))
+                          ) != 0) {
+                       fprintf(stderr, "CHILD> %.*s", chars_read, line_buffer);
+                   };
+                   alarm(0);
+                   receive_data(received_token_buffer,
+                                &received_length);
+                   token_received.value = (void *)received_token_buffer; 
+                   token_received.length = received_length; 
+               };
+
+           } while (kept_status & GSS_S_CONTINUE_NEEDED);      
+
+           if (!GSS_ERROR(kept_status)) {
+               fprintf(stderr, "Authenticated context established\n");
+           } else {
+               fprintf(stderr, "Context not established\n");
+           };
+           fflush(stderr);
+
+           flush_subprocess_message_queue_and_exit();
+   
+       };
+    };
+}
diff --git a/src/lib/gssapi/sample/logutil.c b/src/lib/gssapi/sample/logutil.c
new file mode 100644 (file)
index 0000000..d1a5350
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)login.c    5.1 (Berkeley) 9/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <utmp.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#define        UTMPFILE        "/etc/utmp"
+#define        WTMPFILE        "/usr/adm/wtmp"
+
+void
+login(ut)
+       struct utmp *ut;
+{
+       register int fd;
+       int tty;
+       off_t lseek();
+
+       tty = ttyslot();
+       if (tty > 0 && (fd = open(UTMPFILE, O_WRONLY, 0)) >= 0) {
+               (void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
+               (void)write(fd, (char *)ut, sizeof(struct utmp));
+               (void)close(fd);
+       }
+       if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) >= 0) {
+               (void)write(fd, (char *)ut, sizeof(struct utmp));
+               (void)close(fd);
+       }
+}
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)logout.c   5.1 (Berkeley) 8/31/88";
+#endif /* LIBC_SCCS and not lint */
+
+logout(line)
+       register char *line;
+{
+       register FILE *fp;
+       struct utmp ut;
+       int rval;
+       time_t time();
+
+       if (!(fp = fopen(UTMPFILE, "r+")))
+               return(0);
+       rval = 1;
+       while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
+               if (!ut.ut_name[0] ||
+                   strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
+                       continue;
+               bzero(ut.ut_name, sizeof(ut.ut_name));
+               bzero(ut.ut_host, sizeof(ut.ut_host));
+               (void)time(&ut.ut_time);
+               (void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
+               (void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
+               (void)fseek(fp, (long)0, L_INCR);
+               rval = 0;
+       }
+       (void)fclose(fp);
+       return(rval);
+}
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)logwtmp.c  5.2 (Berkeley) 9/20/88";
+#endif /* LIBC_SCCS and not lint */
+
+logwtmp(line, name, host)
+       char *line, *name, *host;
+{
+       struct utmp ut;
+       struct stat buf;
+       int fd;
+       time_t time();
+       char *strncpy();
+
+       if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
+               return;
+       if (!fstat(fd, &buf)) {
+               (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+               (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+               (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+               (void)time(&ut.ut_time);
+               if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
+                   sizeof(struct utmp))
+                       (void)ftruncate(fd, buf.st_size);
+       }
+       (void)close(fd);
+}
diff --git a/src/lib/krb5.saber.source b/src/lib/krb5.saber.source
new file mode 100644 (file)
index 0000000..a4c374a
--- /dev/null
@@ -0,0 +1,18 @@
+setopt load_flags  -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES
+load  /mit/krb5/src/lib/cryptoconf.c   /mit/krb5/src/lib/syslog.c  /mit/krb5/src/lib/strdup.c
+
+load         /mit/krb5/src/lib/krb/addr_comp.c  /mit/krb5/src/lib/krb/addr_order.c      /mit/krb5/src/lib/krb/addr_srch.c       /u2/krb5/lib/krb/bld_pr_ext.o /u2/krb5/lib/krb/bld_princ.o      /mit/krb5/src/lib/krb/conv_princ.c      /mit/krb5/src/lib/krb/copy_addrs.c      /mit/krb5/src/lib/krb/copy_auth.c       /mit/krb5/src/lib/krb/copy_athctr.c     /mit/krb5/src/lib/krb/copy_checksum.c  /mit/krb5/src/lib/krb/copy_creds.c       /mit/krb5/src/lib/krb/copy_data.c       /mit/krb5/src/lib/krb/copy_key.c        /mit/krb5/src/lib/krb/copy_princ.c      /mit/krb5/src/lib/krb/copy_tick.c       /mit/krb5/src/lib/krb/cp_key_cnt.c      /mit/krb5/src/lib/krb/decode_kdc.c      /mit/krb5/src/lib/krb/decrypt_tk.c      /mit/krb5/src/lib/krb/encode_kdc.c      /mit/krb5/src/lib/krb/encrypt_tk.c      /mit/krb5/src/lib/krb/free_rtree.c      /mit/krb5/src/lib/krb/faddr_ordr.c      /mit/krb5/src/lib/krb/gc_frm_kdc.c      /mit/krb5/src/lib/krb/gc_via_tgt.c      /mit/krb5/src/lib/krb/gc_2tgt.c         /mit/krb5/src/lib/krb/gen_seqnum.c      /mit/krb5/src/lib/krb/gen_subkey.c      /mit/krb5/src/lib/krb/get_creds.c       /mit/krb5/src/lib/krb/get_in_tkt.c      /mit/krb5/src/lib/krb/in_tkt_pwd.c      /mit/krb5/src/lib/krb/in_tkt_sky.c      /mit/krb5/src/lib/krb/kdc_rep_dc.c      /mit/krb5/src/lib/krb/krbconfig.c       /mit/krb5/src/lib/krb/mk_error.c        /mit/krb5/src/lib/krb/mk_priv.c         /mit/krb5/src/lib/krb/mk_rep.c  /mit/krb5/src/lib/krb/mk_req.c  /mit/krb5/src/lib/krb/mk_req_ext.c      /mit/krb5/src/lib/krb/mk_safe.c         /mit/krb5/src/lib/krb/parse.c   /mit/krb5/src/lib/krb/pr_to_salt.c      /mit/krb5/src/lib/krb/princ_comp.c      /mit/krb5/src/lib/krb/rd_error.c        /mit/krb5/src/lib/krb/rd_priv.c         /mit/krb5/src/lib/krb/rd_rep.c  /mit/krb5/src/lib/krb/rd_req.c  /mit/krb5/src/lib/krb/rd_req_sim.c      /mit/krb5/src/lib/krb/rd_req_dec.c      /mit/krb5/src/lib/krb/rd_safe.c         /mit/krb5/src/lib/krb/recvauth.c        /mit/krb5/src/lib/krb/sendauth.c        /mit/krb5/src/lib/krb/send_tgs.c        /mit/krb5/src/lib/krb/srv_rcache.c      /mit/krb5/src/lib/krb/tgtname.c         /mit/krb5/src/lib/krb/unparse.c         /mit/krb5/src/lib/krb/walk_rtree.c
+
+load -DPEPSY_LINKABLE_FUNCS   -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES  /u2/krb5/src/lib/asn.1/KRB5_tables.c        /mit/krb5/src/lib/asn.1/encode.c        /mit/krb5/src/lib/asn.1/decode.c        /mit/krb5/src/lib/asn.1/adat2kadat.c    /mit/krb5/src/lib/asn.1/addr2kaddr.c    /mit/krb5/src/lib/asn.1/adr2kadr.c      /mit/krb5/src/lib/asn.1/aprp2kaprp.c    /mit/krb5/src/lib/asn.1/aprq2kaprq.c    /mit/krb5/src/lib/asn.1/arep2karep.c    /mit/krb5/src/lib/asn.1/auth2kauth.c    /mit/krb5/src/lib/asn.1/cvt_flags.c     /mit/krb5/src/lib/asn.1/ck2kck.c        /mit/krb5/src/lib/asn.1/edat2kedat.c    /mit/krb5/src/lib/asn.1/ekrp2kekrp.c    /mit/krb5/src/lib/asn.1/enck2kkey.c     /mit/krb5/src/lib/asn.1/err2kerr.c      /mit/krb5/src/lib/asn.1/etpt2ketpt.c    /mit/krb5/src/lib/asn.1/g2unix.c        /mit/krb5/src/lib/asn.1/kadat2adat.c    /mit/krb5/src/lib/asn.1/kaddr2addr.c    /mit/krb5/src/lib/asn.1/kadr2adr.c      /mit/krb5/src/lib/asn.1/kaprp2aprp.c    /mit/krb5/src/lib/asn.1/kaprq2aprq.c    /mit/krb5/src/lib/asn.1/karep2arep.c    /mit/krb5/src/lib/asn.1/kauth2auth.c    /mit/krb5/src/lib/asn.1/kck2ck.c        /mit/krb5/src/lib/asn.1/kdcr2kkdcr.c    /mit/krb5/src/lib/asn.1/kdcr2ktgsr.c    /mit/krb5/src/lib/asn.1/kedat2edat.c    /mit/krb5/src/lib/asn.1/kekrp2ekrp.c    /mit/krb5/src/lib/asn.1/kerr2err.c      /mit/krb5/src/lib/asn.1/ketpt2etpt.c    /mit/krb5/src/lib/asn.1/kkdcr2kdcr.c    /mit/krb5/src/lib/asn.1/kkey2enck.c     /mit/krb5/src/lib/asn.1/klsrq2lsrq.c    /mit/krb5/src/lib/asn.1/kprep2prep.c    /mit/krb5/src/lib/asn.1/kprin2prin.c    /mit/krb5/src/lib/asn.1/kpriv2priv.c    /mit/krb5/src/lib/asn.1/ksafe2safe.c    /mit/krb5/src/lib/asn.1/ktran2tran.c    /mit/krb5/src/lib/asn.1/ktgrq2tgrq.c    /mit/krb5/src/lib/asn.1/ktgsr2kdcr.c    /mit/krb5/src/lib/asn.1/ktkt2tkt.c      /mit/krb5/src/lib/asn.1/lsrq2klsrq.c    /mit/krb5/src/lib/asn.1/prep2kprep.c    /mit/krb5/src/lib/asn.1/prin2kprin.c    /mit/krb5/src/lib/asn.1/priv2kpriv.c    /mit/krb5/src/lib/asn.1/qbuf2data.c     /mit/krb5/src/lib/asn.1/safe2ksafe.c    /mit/krb5/src/lib/asn.1/tran2ktran.c    /mit/krb5/src/lib/asn.1/tgrq2ktgrq.c    /mit/krb5/src/lib/asn.1/tkt2ktkt.c      /mit/krb5/src/lib/asn.1/u2gen.c         /mit/krb5/src/lib/asn.1/kasrp2kdcr.c    /mit/krb5/src/lib/asn.1/kpwd2pwd.c      /mit/krb5/src/lib/asn.1/kpwds2pwds.c    /mit/krb5/src/lib/asn.1/pwd2kpwd.c      /mit/krb5/src/lib/asn.1/pwds2kpwds.c
+
+load        /mit/krb5/src/lib/free/f_addr.c     /mit/krb5/src/lib/free/f_address.c      /mit/krb5/src/lib/free/f_arep_enc.c     /mit/krb5/src/lib/free/f_ap_rep.c       /mit/krb5/src/lib/free/f_ap_req.c       /mit/krb5/src/lib/free/f_authdata.c     /mit/krb5/src/lib/free/f_authent.c      /mit/krb5/src/lib/free/f_cksum.c        /mit/krb5/src/lib/free/f_creds.c        /mit/krb5/src/lib/free/f_cred_cnt.c     /mit/krb5/src/lib/free/f_enc_kdc.c      /mit/krb5/src/lib/free/f_enc_tkt.c      /mit/krb5/src/lib/free/f_error.c        /mit/krb5/src/lib/free/f_kdc_rep.c      /mit/krb5/src/lib/free/f_kdc_req.c      /mit/krb5/src/lib/free/f_keyblock.c     /mit/krb5/src/lib/free/f_last_req.c     /mit/krb5/src/lib/free/f_padata.c       /mit/krb5/src/lib/free/f_princ.c        /mit/krb5/src/lib/free/f_priv.c         /mit/krb5/src/lib/free/f_priv_enc.c     /mit/krb5/src/lib/free/f_safe.c         /mit/krb5/src/lib/free/f_ticket.c       /mit/krb5/src/lib/free/f_tickets.c      /mit/krb5/src/lib/free/f_tgt_cred.c     /mit/krb5/src/lib/free/f_tkt_auth.c
+
+load        /mit/krb5/src/lib/keytab/ktadd.c    /mit/krb5/src/lib/keytab/ktbase.c       /mit/krb5/src/lib/keytab/ktdefault.c    /mit/krb5/src/lib/keytab/ktfr_entry.c   /mit/krb5/src/lib/keytab/ktremove.c     /mit/krb5/src/lib/keytab/read_servi.c
+
+load   /mit/krb5/src/lib/keytab/file/ktf_add.c  /mit/krb5/src/lib/keytab/file/ktf_endget.c  /mit/krb5/src/lib/keytab/file/ktf_next.c  /mit/krb5/src/lib/keytab/file/ktf_resolv.c  /mit/krb5/src/lib/keytab/file/ktf_wops.c  /mit/krb5/src/lib/keytab/file/ktf_close.c  /mit/krb5/src/lib/keytab/file/ktf_get_en.c  /mit/krb5/src/lib/keytab/file/ktf_ops.c  /mit/krb5/src/lib/keytab/file/ktf_ssget.c  /mit/krb5/src/lib/keytab/file/ktf_wreslv.c  /mit/krb5/src/lib/keytab/file/ktf_defops.c  /mit/krb5/src/lib/keytab/file/ktf_get_na.c  /mit/krb5/src/lib/keytab/file/ktf_remove.c  /mit/krb5/src/lib/keytab/file/ktf_util.c
+
+load  /mit/krb5/src/lib/ccache/ccbase.c  /mit/krb5/src/lib/ccache/ccdefault.c  /mit/krb5/src/lib/ccache/ccdefops.c
+
+load     /mit/krb5/src/lib/ccache/file/fcc_close.c /mit/krb5/src/lib/ccache/file/fcc_destry.c /mit/krb5/src/lib/ccache/file/fcc_eseq.c  /mit/krb5/src/lib/ccache/file/fcc_gennew.c /mit/krb5/src/lib/ccache/file/fcc_getnam.c /mit/krb5/src/lib/ccache/file/fcc_gprin.c  /mit/krb5/src/lib/ccache/file/fcc_init.c /mit/krb5/src/lib/ccache/file/fcc_nseq.c /mit/krb5/src/lib/ccache/file/fcc_read.c       /mit/krb5/src/lib/ccache/file/fcc_reslv.c /mit/krb5/src/lib/ccache/file/fcc_retrv.c /mit/krb5/src/lib/ccache/file/fcc_sseq.c     /mit/krb5/src/lib/ccache/file/fcc_store.c /mit/krb5/src/lib/ccache/file/fcc_skip.c /mit/krb5/src/lib/ccache/file/fcc_ops.c       /mit/krb5/src/lib/ccache/file/fcc_write.c /mit/krb5/src/lib/ccache/file/fcc_sflags.c /mit/krb5/src/lib/ccache/file/fcc_defops.c  /mit/krb5/src/lib/ccache/file/fcc_errs.c /mit/krb5/src/lib/ccache/file/fcc_maybe.c
+
+load -I.    -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES      /mit/krb5/src/lib/rcache/rc_base.c        /mit/krb5/src/lib/rcache/rc_dfl.c       /mit/krb5/src/lib/rcache/rc_io.c        /mit/krb5/src/lib/rcache/rcdef.c        /mit/krb5/src/lib/rcache/rc_conv.c
diff --git a/src/lib/krb5.saber.warnings b/src/lib/krb5.saber.warnings
new file mode 100644 (file)
index 0000000..9fa9d2e
--- /dev/null
@@ -0,0 +1,294 @@
+----------------
+"/mit/krb5/src/lib/krb/gc_via_tgt.c":119, krb5_get_cred_via_tgt(), Statement not reached (Warning #529)
+   118:         return retval;
+ * 119:         break;                          /* not strictly necessary... */   120:     }
+( while sourcing "/tmp/saber.source":4 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/krb/in_tkt_sky.c":48, skey_keyproc(), Unused formal parameter (Warning #590)
+    47:  */
+ *  48: static krb5_error_code
+    49: skey_keyproc(DECLARG(const krb5_keytype, type),
+( while sourcing "/tmp/saber.source":4 )
+Formal parameter 'padata' was not used.
+----------------
+"/mit/krb5/src/lib/krb/rd_priv.c":63, krb5_rd_priv(), Unused formal parameter (Warning #590)
+    62:
+ *  63: krb5_error_code
+    64: krb5_rd_priv(DECLARG(const krb5_data *, inbuf),
+( while sourcing "/tmp/saber.source":4 )
+Formal parameter 'recv_addr' was not used.
+----------------
+"/usr/include/unistd.h":182, Function redeclared (Warning #701)
+   181:
+ * 182: extern unsigned int
+   183:         alarm(),
+( while sourcing "/tmp/saber.source":4 )
+Function 'alarm' was previously declared as:
+    extern int alarm();
+----------------
+"/usr/include/unistd.h":198, Function redeclared (Warning #701)
+   197:
+ * 198: extern void
+   199:         _exit();
+( while sourcing "/tmp/saber.source":4 )
+Function '_exit' was previously declared as:
+    extern int _exit();
+----------------
+"/mit/krb5/src/lib/asn.1/kpwd2pwd.c":75, krb5_pwd_seq2KRB5_PWD__SEQ(), Functionredeclared (Warning #701)
+    74:                 sizeof(struct type_KRB5_PasswdSequence))) == NULL) {
+ *  75:         com_err("kpwd2pwd", 0, "Unable to Allocate PasswdSequence");
+    76:         *error = ENOMEM;
+( while sourcing "/tmp/saber.source":6 )
+Function 'com_err' was previously declared as:
+    extern void com_err();
+----------------
+"/mit/krb5/src/lib/keytab/file/ktf_util.c":601, krb5_ktfileint_size_entry(), Unused automatic variable (Warning #591)
+   600: {
+ * 601:     krb5_int16 count, size;
+   602:     krb5_int32 total_size, i;
+( while sourcing "/tmp/saber.source":12 )
+Automatic variable 'size' was not used.
+----------------
+"/mit/krb5/src/lib/keytab/file/ktf_util.c":757, krb5_ktfileint_find_slot(), Unused label (Warning #593)
+( while sourcing "/tmp/saber.source":12 )
+Label 'abend' was not used.
+----------------
+"/mit/krb5/src/lib/ccache/file/fcc_gennew.c":40, Unknown directive (Warning #471)
+    39: #else
+    40:  #error find some way to use net-byte-order file version numbers.
+          ^
+    41: #endif
+( while sourcing "/tmp/saber.source":16 )
+Directive 'error' is undefined.
+
+----------------
+"/mit/krb5/src/lib/ccache/file/fcc_gennew.c":77, krb5_fcc_generate_new(), Function redeclared (Warning #701)
+    76:      (void) strcat(scratch, "XXXXXX");
+ *  77:      mktemp(scratch);
+    78:
+( while sourcing "/tmp/saber.source":16 )
+Function 'mktemp' was previously declared as:
+    extern char *mktemp();
+----------------
+"/mit/krb5/src/lib/ccache/file/fcc_maybe.c":41, Unknown directive (Warning #471)
+    40: #else
+    41:  #error find some way to use net-byte-order file version numbers.
+          ^
+    42: #endif
+( while sourcing "/tmp/saber.source":16 )
+Directive 'error' is undefined.
+Warning: 1 module currently not loaded.
+Loading: -I. /mit/krb5/src/lib/rcache/rc_base.c
+
+----------------
+"/mit/krb5/src/lib/rcache/rc_base.h":13, Cannot read file (Error #400)
+    12: #define KRB5_RC_H
+ *  13: #include <krb5/krb5.h>
+    14: #include <krb5/ext-proto.h>
+( while sourcing "/tmp/saber.source":18 )
+Cannot open 'krb5/krb5.h' for input.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":335, krb5_rc_dfl_recover(), Unused automatic variable (Warning #591)
+   334:  struct dfl_data *t = (struct dfl_data *)id->data;
+ * 335:  int i;
+   336:  krb5_donot_replay *rep;
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":402, krb5_rc_dfl_recover(), Unused label (Warning #593)
+( while sourcing "/tmp/saber.source":18 )
+Label 'end_loop' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":443, krb5_rc_dfl_store(), Statement not reached (Warning #529)
+   442:    case CMP_MALLOC:
+ * 443:        return KRB5_RC_MALLOC; break;
+   444:    case CMP_REPLAY:
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":445, krb5_rc_dfl_store(), Statement not reached (Warning #529)
+   444:    case CMP_REPLAY:
+ * 445:        return KRB5KRB_AP_ERR_REPEAT; break;
+   446:    case 0: break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":438, krb5_rc_dfl_store(), Unused automatic variable (Warning #591)
+   437:  struct dfl_data *t = (struct dfl_data *)id->data;
+ * 438:  int i;
+   439:
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":525, krb5_rc_dfl_expunge(), Benign argumentmismatch (Warning #68)
+   524:   {
+ * 525:         if (krb5_rc_io_store (&tmp, &q->rep))
+   526:      return KRB5_RC_IO;
+( while sourcing "/tmp/saber.source":18 )
+Benign type mismatch in call to function 'krb5_rc_io_store':
+Argument #1 has type (struct krb5_rc_iostuff *) but type (struct dfl_data *) was expected.
+Defined/declared in "/mit/krb5/src/lib/rcache/rc_dfl.c":404
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":473, krb5_rc_dfl_expunge(), Unused automatic variable (Warning #591)
+   472:  struct dfl_data *t = (struct dfl_data *)id->data;
+ * 473:  int i;
+   474: #ifdef NOIOSTUFF
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":33, Unknown directive (Warning #471)
+    32: #else
+    33:  #error find some way to use net-byte-order file version numbers.
+          ^
+    34: #endif
+( while sourcing "/tmp/saber.source":18 )
+Directive 'error' is undefined.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":73, krb5_rc_io_creat(), Constant in conditional (Warning #558)
+    72:
+ *  73:  GETDIR;
+    74:  if (fn && *fn)
+( while sourcing "/tmp/saber.source":18 )
+The conditional expression for 'do/while' is always false.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":156, krb5_rc_io_open(), Constant in conditional (Warning #558)
+   155:
+ * 156:  GETDIR;
+   157:  if (!(d->fn = malloc(strlen(fn) + dirlen + 1)))
+( while sourcing "/tmp/saber.source":18 )
+The conditional expression for 'do/while' is always false.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":165, krb5_rc_io_open(), Function redeclared (Warning #701)
+   164:
+ * 165:      me = getuid();
+   166:      /* must be owned by this user, to prevent some security problems with
+( while sourcing "/tmp/saber.source":18 )
+Function 'getuid' was previously declared as:
+    extern short getuid();
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":238, krb5_rc_io_write(), Statement not reached (Warning #529)
+   237:     {
+ * 238:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+   239:      case EFBIG: return KRB5_RC_IO_SPACE; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":239, krb5_rc_io_write(), Statement not reached (Warning #529)
+   238:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 239:      case EFBIG: return KRB5_RC_IO_SPACE; break;
+   240: #ifdef EDQUOT
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":241, krb5_rc_io_write(), Statement not reached (Warning #529)
+   240: #ifdef EDQUOT
+ * 241:      case EDQUOT: return KRB5_RC_IO_SPACE; break;
+   242: #endif
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":243, krb5_rc_io_write(), Statement not reached (Warning #529)
+   242: #endif
+ * 243:      case ENOSPC: return KRB5_RC_IO_SPACE; break;
+   244:      case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":244, krb5_rc_io_write(), Statement not reached (Warning #529)
+   243:      case ENOSPC: return KRB5_RC_IO_SPACE; break;
+ * 244:      case EIO: return KRB5_RC_IO_IO; break;
+   245:      default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":245, krb5_rc_io_write(), Statement not reached (Warning #529)
+   244:      case EIO: return KRB5_RC_IO_IO; break;
+ * 245:      default: return KRB5_RC_IO_UNKNOWN; break;
+   246:     }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":256, krb5_rc_io_sync(), Statement not reached (Warning #529)
+   255:       {
+ * 256:       case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+   257:       case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":257, krb5_rc_io_sync(), Statement not reached (Warning #529)
+   256:       case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 257:       case EIO: return KRB5_RC_IO_IO; break;
+   258:       default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":258, krb5_rc_io_sync(), Statement not reached (Warning #529)
+   257:       case EIO: return KRB5_RC_IO_IO; break;
+ * 258:       default: return KRB5_RC_IO_UNKNOWN; break;
+   259:       }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":273, krb5_rc_io_read(), Statement not reached (Warning #529)
+   272:     {
+ * 273:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+   274:      case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":274, krb5_rc_io_read(), Statement not reached (Warning #529)
+   273:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 274:      case EIO: return KRB5_RC_IO_IO; break;
+   275:      default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":275, krb5_rc_io_read(), Statement not reached (Warning #529)
+   274:      case EIO: return KRB5_RC_IO_IO; break;
+ * 275:      default: return KRB5_RC_IO_UNKNOWN; break;
+   276:     }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":298, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   297:     {
+ * 298:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+   299:      case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":299, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   298:      case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 299:      case EIO: return KRB5_RC_IO_IO; break;
+   300:      case EPERM: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":300, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   299:      case EIO: return KRB5_RC_IO_IO; break;
+ * 300:      case EPERM: return KRB5_RC_IO_PERM; break;
+   301:      case EBUSY: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":301, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   300:      case EPERM: return KRB5_RC_IO_PERM; break;
+ * 301:      case EBUSY: return KRB5_RC_IO_PERM; break;
+   302:      case EROFS: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":302, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   301:      case EBUSY: return KRB5_RC_IO_PERM; break;
+ * 302:      case EROFS: return KRB5_RC_IO_PERM; break;
+   303:      default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":303, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+   302:      case EROFS: return KRB5_RC_IO_PERM; break;
+ * 303:      default: return KRB5_RC_IO_UNKNOWN; break;
+   304:     }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
diff --git a/src/lib/krb5/asn.1/.rconf b/src/lib/krb5/asn.1/.rconf
new file mode 100644 (file)
index 0000000..abd9419
--- /dev/null
@@ -0,0 +1,8 @@
+ignore KRB5-types.c
+ignore KRB5-types.h
+ignore KRB5-types.py
+ignore TAGS
+ignore KRB5.ph
+ignore Makefile.jtk
+ignore glue2.c
+ignore process.perl
diff --git a/src/lib/krb5/asn.1/.saberinit b/src/lib/krb5/asn.1/.saberinit
new file mode 100644 (file)
index 0000000..d14fddb
--- /dev/null
@@ -0,0 +1,4 @@
+alias hex print (unsigned)
+setopt load_flags -I../include
+load -lisode
+alias reload load
diff --git a/src/lib/krb5/asn.1/glue2.c b/src/lib/krb5/asn.1/glue2.c
new file mode 100644 (file)
index 0000000..3267de1
--- /dev/null
@@ -0,0 +1,31 @@
+#include <krb5/krb5.h>
+
+krb5_data string_list[3] = {
+{14, "ATHENA.MIT.EDU"},
+{6, "jtkohl"},
+{4, "root"},
+};
+
+krb5_data *princ[] = {&string_list[0], &string_list[1], &string_list[2], 0};
+
+krb5_data string_list2[3] = {
+{14, "ATHENA.MIT.EDU"},
+{6, "krbtgt"},
+{14, "ATHENA.MIT.EDU"},
+};
+
+krb5_data *princ2[] = {&string_list2[0], &string_list2[1], &string_list2[2], 0};
+                                  
+krb5_last_req_entry lrentries[] = { {32000, 1}, {0, 3}, {10, 2} };
+krb5_last_req_entry *lrfoo1[] = {&lrentries[0], &lrentries[1], &lrentries[2], 0};
+
+krb5_authdata adarr1[] = { {3, 7, "authdat"}, {2,4,"foob"}, {257,9,"jtkohlxxx"}};
+krb5_authdata *authdats[] = {&adarr1[0],&adarr1[1],&adarr1[2],0};
+
+krb5_pa_data authdarr1[] = { {3, 7, "authdat"}, {2,4,"foob"}, {257,9,"jtkohlxxx"}};
+krb5_pa_data *padats[] = {&authdarr1[0],&authdarr1[1],&authdarr1[2],0};
+
+krb5_address adrarr1[] = { {ADDRTYPE_INET,4,"abcd"},
+                          {ADDRTYPE_ISO,10,"6176432831"},
+                          {ADDRTYPE_INET,4,"efgh"} };
+krb5_address *addrs[] = {&adrarr1[0],&adrarr1[1],&adrarr1[2],0};
diff --git a/src/lib/krb5/asn.1/process.perl b/src/lib/krb5/asn.1/process.perl
new file mode 100644 (file)
index 0000000..ce3e84b
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# usage: perl process <input-c-file> <output-prefix> <c-flist> <o-flist>
+#
+$header = "";
+$count = 0;
+$pepyid = "";
+$extrainclude = '#include <krb5/asn.1/KRB5-types-aux.h>' . "\n";
+
+if ($#ARGV != 3) {die "Usage: process input-file.c output-prefix cflist-file oflist-file";}
+
+print "processing ", $ARGV[0], "\n";
+open(CFILE, "< $ARGV[0]") || die "can't open $ARGV[0]";
+open(CFLIST, "> $ARGV[2]") || die "can't open $ARGV[2]";
+open(OFLIST, "> $ARGV[3]") || die "can't open $ARGV[2]";
+
+mainloop: while (<CFILE>) {
+       next mainloop if /^# line/;
+       if (/pepyid/) {
+               $pepyid = $_;
+       } elsif (/^\/\* ARGS|^free/) {
+               print "processing output from $pepyid" if ($count == 0);
+               close(OUTFILE);
+               $ofile = "$ARGV[1]" . $count . ".c";
+               open(OUTFILE, ">$ofile" ) || die "can't open file $ofile";
+               print OUTFILE $pepyid if ($count == 0);
+               print $ofile, "\n";
+               @clist = (@clist, " " . $ofile);
+               $count++;
+               print OUTFILE $header;
+               print OUTFILE $extrainclude;
+               print OUTFILE $_;
+       } elsif ($count == 0) {
+               $header .= $_;
+       } else {
+               print OUTFILE $_;
+       }
+}
+close(OUTFILE);
+print CFLIST "TYPESSRCS= ", @clist, "\n";
+close(CFLIST);
+while ($cfile = shift(@clist))  {
+       $cfile =~ s/.c$/.o/;
+       @olist = (@olist, $cfile);
+}
+print OFLIST "TYPESOBJS=", @olist, "\n";
+close(OFLIST);
+#
+#      $Source$
+#      $Author$
+#      $Id$
diff --git a/src/lib/krb5/ccache/file/.rconf b/src/lib/krb5/ccache/file/.rconf
new file mode 100644 (file)
index 0000000..55ab262
--- /dev/null
@@ -0,0 +1 @@
+ignore fcc_test.c
diff --git a/src/lib/krb5/ccache/file/README b/src/lib/krb5/ccache/file/README
new file mode 100644 (file)
index 0000000..e1aa6de
--- /dev/null
@@ -0,0 +1,33 @@
+If OPENCLOSE is defined, ecah of the functions opens and closes the
+file whenever it needs to access it.  Otherwise, the file is opened
+once in initialize and closed once is close.
+
+This library depends on UNIX-like file descriptors, and UNIX-like
+behavior from the functions: open, close, read, write, lseek.
+
+The quasi-BNF grammar for a credentials cache:
+
+file ::= 
+       principal list-of-credentials
+
+credential ::=
+       client (principal)
+       server (principal)
+       keyblock (keyblock)
+       times (ticket_times)
+       is_skey (boolean)
+       ticket_flags (flags)
+       ticket (data)
+       second_ticket (data)
+
+principal ::= 
+       number of components (int32)
+       component 1 (data)
+       component 2 (data)
+       ...
+       
+data ::=
+       length (int32)
+       string of length bytes
+
+etc.
diff --git a/src/lib/krb5/ccache/file/todo b/src/lib/krb5/ccache/file/todo
new file mode 100644 (file)
index 0000000..ed1ddb8
--- /dev/null
@@ -0,0 +1,7 @@
+Make sure that each time a function returns KRB5_NOMEM, everything
+allocated earlier in the function and stack tree is freed.
+
+File locking
+
+fcc_nseq.c and fcc_read don't check return values a lot.
+
diff --git a/src/lib/krb5/ccache/stdio/.rconf b/src/lib/krb5/ccache/stdio/.rconf
new file mode 100644 (file)
index 0000000..874fb07
--- /dev/null
@@ -0,0 +1 @@
+ignore x
diff --git a/src/lib/krb5/ccache/stdio/README b/src/lib/krb5/ccache/stdio/README
new file mode 100644 (file)
index 0000000..a986543
--- /dev/null
@@ -0,0 +1,39 @@
+If OPENCLOSE is defined, ecah of the functions opens and closes the
+file whenever it needs to access it.  Otherwise, the file is opened
+once in initialize and closed once is close.
+
+This library depends on ANSI C library routines for file handling.  It
+may also have some implicit assumptions about UNIX, but we'll get
+those out as much as possible.
+
+If you are running a UNIX system, you probably want to use the
+UNIX-based "file" cache package instead of this.
+
+The quasi-BNF grammar for a credentials cache:
+
+file ::= 
+       format-vno principal list-of-credentials
+
+credential ::=
+       client (principal)
+       server (principal)
+       keyblock (keyblock)
+       times (ticket_times)
+       is_skey (boolean)
+       ticket_flags (flags)
+       ticket (data)
+       second_ticket (data)
+
+principal ::= 
+       number of components (int32)
+       component 1 (data)
+       component 2 (data)
+       ...
+       
+data ::=
+       length (int32)
+       string of length bytes
+
+format-vno ::= <int16>
+
+etc.
diff --git a/src/lib/krb5/ccache/stdio/todo b/src/lib/krb5/ccache/stdio/todo
new file mode 100644 (file)
index 0000000..56a423f
--- /dev/null
@@ -0,0 +1,9 @@
+Make sure that each time a function returns KRB5_NOMEM, everything
+allocated earlier in the function and stack tree is freed.
+
+Overwrite cache file with nulls before removing it.
+
+Check return values and sanity-check parameters more thoroughly.  This
+code was derived from UNIX file I/O code, and the conversion of
+error-trapping may be incomplete.  Probably lots of bugs dealing with
+end-of-file versus other errors.
diff --git a/src/lib/krb5/error_tables/.rconf b/src/lib/krb5/error_tables/.rconf
new file mode 100644 (file)
index 0000000..9adf82b
--- /dev/null
@@ -0,0 +1,4 @@
+ignore *.h
+ignore *.c
+ignore .rconf
+link init_ets.c
diff --git a/src/lib/krb5/rcache/.rconf b/src/lib/krb5/rcache/.rconf
new file mode 100644 (file)
index 0000000..54e912b
--- /dev/null
@@ -0,0 +1,2 @@
+ignore README
+ignore RELEASE
diff --git a/src/lib/krb5/rcache/README b/src/lib/krb5/rcache/README
new file mode 100644 (file)
index 0000000..99187cc
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+Copyright 1990, Daniel J. Bernstein. All rights reserved.
+
+Please address any questions or comments to the author at brnstnd@acf10.nyu.edu.
+*/
+
+The #include's should be rewritten.
+
+All functions return 0 on success.
+
+Environment variables: KRB5RCACHETYPE, KRB5RCACHENAME, KRB5RCACHEDIR,
+and TMPDIR. Obsolete: KRB5RCACHE.
+
+All header files are both ANSI-compatible and K&R-compatible. The .c files
+are only ANSI compatible. Everything passes gcc -Wall -ansi -pedantic.
+
+Strings are freed using FREE(), which is defined in terms of free(). 
+
+The error header files should be redone.
+
+The header files don't use __ because that's reserved.
+
+Each .c file assumes <malloc.h>. rc_io.c assumes fsync() and a gaggle of
+error codes. These assumptions are not as portable as the code itself.
+
+
+rcache.c:
+
+The rcache.c compatibility interface's type registration is a no-op; it
+simply passes the type name on to rc_base.h. rcache.h is obsolete; use
+rc_base.h if possible.
+
+There are some slight differences between rcache.c and the prototypes I
+saw in krb/func-proto.h. Don't look at me, it's your interface.
+
+rcache.c's get_name doesn't fill with zeros unless strncpy does.
+
+
+rc_base.c:
+
+If SEMAPHORE is defined and <semaphore.h> exists when rc_base.c is
+compiled, all access to the type list will be protected by appropriate
+semaphore ups and downs. This is untested.
+
+It doesn't take linker magic to preregister types. Just change the
+typehead initialization in rc_base.c, with an appropriate include file
+setting the ops.
+
+
+rc_dfl.c:
+
+If NOIOSTUFF is defined when rc_dfl.c is compiled, all dfl rcaches will
+be per-process. This is untested.
+
+Provided that separate threads use separate rcaches, rc_dfl.c is safe
+for multithreading.
+
+Getting the name of a cache is only valid after it is created and before
+it is closed. Recovering a cache is only valid after it has been created.
+
+krb5_unparse_name had better produce a zero-terminated string.
+
+rc_dfl.c isn't smart enough to try expunge/retry upon a malloc error.
+Then again, such an error indicates that the whole system's about to die;
+without real memory management there's no good solution.
+
+HASHSIZE can be defined at compile time. It defaults to 997 in rc_dfl.c.
+EXCESSREPS can be defined at compile time. It defaults to 30 in rc_dfl.c.
+
+Hopefully adding a deltat to a time to compare to another time cannot
+overflow.
+
+In rc_dfl's struct dfl_data, the name field is never freed, even though
+it may be malloced by io_creat on a generate-name call. This should not
+be a problem: a single process should not be opening and closing many
+rcaches. One fix would be another field to indicate whether the string
+was malloced or not; normally this is an unstated characteristic of a
+char pointer, but here it would have to be explicit.
+
+
+rc_io.c:
+
+rc_io.c assumes that siginterrupt() is not set. If siginterrupt() is set
+and a signal occurs during, say, close(), then the close will fail.
+
+On a machine without fsync() you might as well not use the disk at all.
diff --git a/src/lib/krb5/rcache/RELEASE b/src/lib/krb5/rcache/RELEASE
new file mode 100644 (file)
index 0000000..21a4624
--- /dev/null
@@ -0,0 +1,17 @@
+Text of Mr. Bernstein's release:
+
+"I" henceforth refers to Daniel J. Bernstein.
+
+"rcshar" henceforth refers to the attached document, as sent from Daniel
+J. Bernstein to Project Athena on 11 March 1990
+
+I am the author of and sole copyright holder upon rcshar.
+
+I hereby waive copyright upon rcshar.  rcshar is hereby public domain.
+
+I hereby also waive copyright upon any works that are (1) derived from
+rcshar and (2) prepared between 11 March 1990 and 1 January 1991.
+
+Daniel J. Bernstein
+
+<signature>, dated 7 July 1990