From: Theodore Tso Date: Thu, 3 Jun 1993 19:29:40 +0000 (+0000) Subject: Initial revision X-Git-Tag: krb5-1.0-beta3~227 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=746386f12e01102acbe5637aac6f1259c74bb552;p=krb5.git Initial revision git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2611 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/CHANGELOG b/src/CHANGELOG new file mode 100644 index 000000000..7da5b7f39 --- /dev/null +++ b/src/CHANGELOG @@ -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 index 000000000..fb902ab69 --- /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 index 000000000..b5d50de92 --- /dev/null +++ b/src/Link_src.sh @@ -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 index 000000000..bf55a9ce3 --- /dev/null +++ b/src/Sandia-changes @@ -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 i.e. + fputs("#include \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 + 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 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 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? 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 index 000000000..f3f3f61c7 --- /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 index 000000000..06f02e132 --- /dev/null +++ b/src/appl/.rconf @@ -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 index 000000000..6a975d3c1 --- /dev/null +++ b/src/appl/bsd/defines.h @@ -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 index 000000000..a11b94850 --- /dev/null +++ b/src/appl/bsd/fieldbits.h @@ -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 index 000000000..1e4912997 --- /dev/null +++ b/src/appl/bsd/forward.c @@ -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 +#include +#include + +#include +#include +#include +#include +#include + +#define TGTNAME "krbtgt" /* Else #include */ +#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(¤ttime)) { + 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 index 000000000..08fa5f7ea --- /dev/null +++ b/src/appl/bsd/setenv.c @@ -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 +#include + +/* + * 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 index 000000000..ca39b0959 --- /dev/null +++ b/src/appl/popper/.rconf @@ -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 index 000000000..43084cce5 --- /dev/null +++ b/src/appl/popper/README @@ -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 " option +will place debugging information into file "" 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 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 " 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 index 000000000..c8a5c5c87 --- /dev/null +++ b/src/appl/popper/orig-makefiles/Makefile.krb_passwd_hack @@ -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 index 000000000..08ea6dd14 --- /dev/null +++ b/src/appl/popper/pop3.rfc1081 @@ -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] + +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] + +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] + +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] + +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] + +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] + +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] + +RFC 1081 POP3 November 1988 + + + Possible Responses: + +OK message follows + -ERR no such message + Examples: + C: RETR 1 + S: +OK 120 octets + S: + 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] + +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: + 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] + +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] + +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: + 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] + +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] + +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: + ... + C: + 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: + S: . + C: DELE 1 + S: +OK message 1 deleted + C: RETR 2 + S: +OK 200 octets + S: + S: . + C: DELE 2 + S: +OK message 2 deleted + C: QUIT + + + + + +Rose [Page 13] + +RFC 1081 POP3 November 1988 + + + S: +OK dewey POP3 server signing off (maildrop empty) + C: + S: + +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] + +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] + +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 index 000000000..36deae545 --- /dev/null +++ b/src/appl/popper/pop3e.rfc1082 @@ -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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + \ 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 index 000000000..e148d71e8 --- /dev/null +++ b/src/appl/popper/pop_dele.c @@ -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 +#include +#include +#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 index 000000000..feaf698ab --- /dev/null +++ b/src/appl/popper/pop_dropcopy.c @@ -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 +#include +#include +#include +#include +#include +#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 index 000000000..021082020 --- /dev/null +++ b/src/appl/popper/pop_dropinfo.c @@ -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 +#include +#include +#include +#include +#include +#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 index 000000000..fe5d22e87 --- /dev/null +++ b/src/appl/popper/pop_get_command.c @@ -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 +#include +#include +#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 */ + 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 index 000000000..c77af80f0 --- /dev/null +++ b/src/appl/popper/pop_get_subcommand.c @@ -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 +#include +#include +#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 index 000000000..6298b7615 --- /dev/null +++ b/src/appl/popper/pop_last.c @@ -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 +#include +#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 index 000000000..a79f5d168 --- /dev/null +++ b/src/appl/popper/pop_list.c @@ -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 +#include +#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 index 000000000..a64716111 --- /dev/null +++ b/src/appl/popper/pop_log.c @@ -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 +#include +#include +#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 index 000000000..45fb4e4da --- /dev/null +++ b/src/appl/popper/pop_lower.c @@ -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 +#include +#include + +/* + * 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 index 000000000..366c5155c --- /dev/null +++ b/src/appl/popper/pop_msg.c @@ -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 +#include +#include +#include +#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 */ + (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 index 000000000..05b42a40c --- /dev/null +++ b/src/appl/popper/pop_parse.c @@ -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 +#include +#include +#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 index 000000000..2cfe9016a --- /dev/null +++ b/src/appl/popper/pop_quit.c @@ -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 +#include +#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 index 000000000..2c97527c6 --- /dev/null +++ b/src/appl/popper/pop_rset.c @@ -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 +#include +#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 index 000000000..2de7ffa0b --- /dev/null +++ b/src/appl/popper/pop_send.c @@ -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 +#include +#include +#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 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 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 index 000000000..20f94427e --- /dev/null +++ b/src/appl/popper/pop_stat.c @@ -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 +#include +#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 index 000000000..ebedb0fc9 --- /dev/null +++ b/src/appl/popper/pop_updt.c @@ -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 +#include +#include +#include +#include +#include +#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 index 000000000..dee41edd6 --- /dev/null +++ b/src/appl/popper/pop_user.c @@ -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 +#include +#include +#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 index 000000000..4096f3023 --- /dev/null +++ b/src/appl/popper/pop_xmit.c @@ -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 +#include +#include +#include +#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 index 000000000..29aaed8f7 --- /dev/null +++ b/src/appl/popper/pop_xtnd.c @@ -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 +#include +#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 index 000000000..4270d0e63 --- /dev/null +++ b/src/appl/popper/popper.M @@ -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 " option +will place debugging information into file "" 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 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 index 000000000..5c9db41eb --- /dev/null +++ b/src/appl/popper/popper.h @@ -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 +#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 index 000000000..a6980fde5 --- /dev/null +++ b/src/appl/popper/syslog_levels @@ -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 index 000000000..4512cb4a5 --- /dev/null +++ b/src/appl/popper/version.h @@ -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 index 000000000..e98c0164f --- /dev/null +++ b/src/appl/telnet/.rconf @@ -0,0 +1 @@ +ignore */*.0 diff --git a/src/appl/telnet/Imakefile b/src/appl/telnet/Imakefile new file mode 100644 index 000000000..fd863ae05 --- /dev/null +++ b/src/appl/telnet/Imakefile @@ -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 index 000000000..fcffba7f2 --- /dev/null +++ b/src/appl/telnet/libtelnet/Imakefile @@ -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 index 000000000..070532530 --- /dev/null +++ b/src/appl/telnet/libtelnet/gettytab.c @@ -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 + +#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 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 index 000000000..a96dcf31e --- /dev/null +++ b/src/appl/telnet/libtelnet/gettytab.h @@ -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 index 000000000..fd3fdf183 --- /dev/null +++ b/src/appl/telnet/telnet/Imakefile @@ -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 index 000000000..fd3fdf183 --- /dev/null +++ b/src/appl/telnet/telnetd/Imakefile @@ -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 index 000000000..5fab6f7b8 --- /dev/null +++ b/src/config-files/Imakefile @@ -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 index 000000000..dbea023ab --- /dev/null +++ b/src/config/Imake.rules.foo @@ -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 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 index 000000000..807bb1c19 --- /dev/null +++ b/src/config/Imake.tmpl-xcomp @@ -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 +#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 +#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 + +/* + * 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 + + + +#include + +/**/########################################################################### +/**/# 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 index 000000000..4c46c67b6 --- /dev/null +++ b/src/config/Makefile.ini @@ -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 index 000000000..9146bfc39 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 index 000000000..6f13d64cb --- /dev/null +++ b/src/config/ccimake.c @@ -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 index 000000000..ea0c7af25 --- /dev/null +++ b/src/config/doc/paper.ms @@ -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 index 000000000..26c22f189 --- /dev/null +++ b/src/config/ibmLib.rules @@ -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 index 000000000..3662f52b8 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 index 000000000..c6e10e459 --- /dev/null +++ b/src/config/imake.man @@ -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 index 000000000..6b26fbb8e --- /dev/null +++ b/src/config/imakemdep.h @@ -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 + * .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 index 000000000..cbaf0c296 --- /dev/null +++ b/src/include/.rconf @@ -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 index 000000000..60e203e57 --- /dev/null +++ b/src/include/bsdlib.h @@ -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 index 000000000..33d0ba606 --- /dev/null +++ b/src/include/bstring.h @@ -0,0 +1,26 @@ +/* + * #include file for bstring(3) & sys5 version functions + * home. + */ +#ifndef __BSTRING__ +#define __BSTRING__ +#ifdef __STDC__ +/* compat-sys5 */ +/* these are in */ +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 index 000000000..7bea01004 --- /dev/null +++ b/src/include/com_err.h @@ -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 +#else +#include +#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 index 000000000..43e6547ad --- /dev/null +++ b/src/include/kerberosIV/addr_comp.h @@ -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 + * . + * + * Include file for address comparison macros. + */ + +#include + +#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 index 000000000..b0657106d --- /dev/null +++ b/src/include/kerberosIV/admin_server.h @@ -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 + * . + * + * Include file for the Kerberos administration server. + */ + +#include + +#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 index 000000000..4cda8fe1d --- /dev/null +++ b/src/include/kerberosIV/conf-bsd386i.h @@ -0,0 +1,20 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: Sun 386i using SunOS (~BSD) + */ + +#include + +#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 index 000000000..693728f3a --- /dev/null +++ b/src/include/kerberosIV/conf-bsdapollo.h @@ -0,0 +1,27 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Description. + */ + +#include + +#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 index 000000000..ce77a0783 --- /dev/null +++ b/src/include/kerberosIV/conf-bsdibm032.h @@ -0,0 +1,22 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: IBM 032 (RT/PC) + */ + +#include + +#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 index 000000000..12b9ddaa6 --- /dev/null +++ b/src/include/kerberosIV/conf-bsdm68k.h @@ -0,0 +1,20 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: 68000 with BSD Unix, e.g. SUN + */ + +#include + +#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 index 000000000..c9cdf4c02 --- /dev/null +++ b/src/include/kerberosIV/conf-bsdsparc.h @@ -0,0 +1,21 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: SPARC with BSD Unix, e.g. SUN-4 + */ + +#include + +#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 index 000000000..f4818f063 --- /dev/null +++ b/src/include/kerberosIV/conf-bsdtahoe.h @@ -0,0 +1,19 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1989 by the Regents of the University of California + * + * Machine Description : TAHOE. + */ + +#include + +#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 index 000000000..04416661a --- /dev/null +++ b/src/include/kerberosIV/conf-bsdvax.h @@ -0,0 +1,26 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: VAX + */ + +#include + +#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 index 000000000..1fd620d1b --- /dev/null +++ b/src/include/kerberosIV/conf-ibm370.h @@ -0,0 +1,19 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: IBM 370 + */ + +#include + +/* 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 index 000000000..09cc2d874 --- /dev/null +++ b/src/include/kerberosIV/conf-pc.h @@ -0,0 +1,19 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: IBM PC 8086 + */ + +#include + +#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 index 000000000..08cd0e6fe --- /dev/null +++ b/src/include/kerberosIV/conf-pyr.h @@ -0,0 +1,19 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: Pyramid + */ + +#include + +#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 index 000000000..cc14c76ae --- /dev/null +++ b/src/include/kerberosIV/conf-ultmips2.h @@ -0,0 +1,21 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Machine-type definitions: DECstation 3100 (MIPS R2000) + */ + +#include + +#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 index 000000000..a438a7266 --- /dev/null +++ b/src/include/kerberosIV/conf.h @@ -0,0 +1,78 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * 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 + +#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 index 000000000..ce1f67f6d --- /dev/null +++ b/src/include/kerberosIV/des.h @@ -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 + * . + * + * Include file for the Data Encryption Standard library. + */ + +/* only do the whole thing once */ +#ifndef DES_DEFS +#define DES_DEFS + +#include + +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 index 000000000..673eb93fb --- /dev/null +++ b/src/include/kerberosIV/des_conf.h @@ -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 index 000000000..a217b0196 --- /dev/null +++ b/src/include/kerberosIV/highc.h @@ -0,0 +1,36 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Known breakage in the version of Metaware's High C compiler that + * we've got available.... + */ + +#include + +#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 index 000000000..f13934023 --- /dev/null +++ b/src/include/kerberosIV/kadm.h @@ -0,0 +1,141 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Definitions for Kerberos administration server & client + */ + +#ifndef KADM_DEFS +#define KADM_DEFS + +#include +/* + * 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 +#include +#include +#include + +/* 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 index 000000000..393fb0e20 --- /dev/null +++ b/src/include/kerberosIV/kdc.h @@ -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 + * . + * + * Include file for the Kerberos Key Distribution Center. + */ + +#include + +#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. + * + * This file defines the types of log messages logged by klog. Each + * type of message may be selectively turned on or off. + */ + +#include + +#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 index 000000000..78e406ac0 --- /dev/null +++ b/src/include/kerberosIV/krb.h @@ -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 + * . + * + * Include file for the Kerberos library. + */ + +/* Only one time, please */ +#ifndef KRB_DEFS +#define KRB_DEFS + +#include + +/* Need some defs from des.h */ +#include + +/* 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 index 000000000..3a3790624 --- /dev/null +++ b/src/include/kerberosIV/krb_db.h @@ -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 + * . + * + * 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 + +#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 index 000000000..80b9b36fb --- /dev/null +++ b/src/include/kerberosIV/lsb_addr_comp.h @@ -0,0 +1,43 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Comparison macros to emulate LSBFIRST comparison results of network + * byte-order quantities + */ + +#include +#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 index 000000000..cd30580ce --- /dev/null +++ b/src/include/kerberosIV/mit-copyright.h @@ -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 index 000000000..9d6a9bb06 --- /dev/null +++ b/src/include/kerberosIV/osconf.h @@ -0,0 +1,50 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Athena configuration. + */ + +#include + +#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 index 000000000..08bb2977e --- /dev/null +++ b/src/include/kerberosIV/passwd_server.h @@ -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 + * . + * + * Include file for password server + */ + +#include + +#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 index 000000000..f1149426e --- /dev/null +++ b/src/include/kerberosIV/principal.h @@ -0,0 +1,22 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Definitions for principal names. + */ + +#include + +#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 index 000000000..ff792715f --- /dev/null +++ b/src/include/kerberosIV/prot.h @@ -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 + * . + * + * Include file with authentication protocol information. + */ + +#include + +#include + +#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 index 000000000..0278bafa0 --- /dev/null +++ b/src/include/krb5/.rconf @@ -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 index 000000000..6715bf461 --- /dev/null +++ b/src/include/krb5/asn.1/.rconf @@ -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 index 000000000..ff9120583 --- /dev/null +++ b/src/include/sys/syslog.h @@ -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 */ +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 index 000000000..ff9120583 --- /dev/null +++ b/src/include/syslog.h @@ -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 */ +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 index 000000000..77bddccba --- /dev/null +++ b/src/kadmin/server/admin_acl_file @@ -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 index 000000000..ae50e63d8 --- /dev/null +++ b/src/kdc/.rconf @@ -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 index 000000000..2c5e56572 --- /dev/null +++ b/src/kdc/.saberinit @@ -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 index 000000000..d3613ac0d --- /dev/null +++ b/src/kdc/migration.doc @@ -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 index 000000000..6b4a4f162 --- /dev/null +++ b/src/krb524/Makefile @@ -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 index 000000000..6f829313d --- /dev/null +++ b/src/krb524/README @@ -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 , 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 index 000000000..cd462b6fd --- /dev/null +++ b/src/krb524/RELEASE_NOTES @@ -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 index 000000000..ce36f30c1 --- /dev/null +++ b/src/krb524/conv_creds.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 000000000..82d589b79 --- /dev/null +++ b/src/krb524/conv_princ.c @@ -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 +#include +#include + +#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 index 000000000..1332a23cd --- /dev/null +++ b/src/krb524/conv_tkt.c @@ -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 +#include +#include +#include +#include + +#include +#include + +#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 index 000000000..ac6a1b928 --- /dev/null +++ b/src/krb524/conv_tkt_skey.c @@ -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 +#include +#include + +#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 index 000000000..f14fa6d90 --- /dev/null +++ b/src/krb524/encode.c @@ -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 +#include +#include + +#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 index 000000000..e81ef2538 --- /dev/null +++ b/src/krb524/getcred.c @@ -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 +#include +#include + +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 index 000000000..eb7884a45 --- /dev/null +++ b/src/krb524/globals.c @@ -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 index 000000000..39045e54e --- /dev/null +++ b/src/krb524/k524init.c @@ -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 +#include +#include + +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 index 000000000..2b9a3b6f8 --- /dev/null +++ b/src/krb524/krb524.h @@ -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 + +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 index 000000000..237d084ac --- /dev/null +++ b/src/krb524/krb524_err.et @@ -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 index 000000000..f83854d77 --- /dev/null +++ b/src/krb524/krb524_prot @@ -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 index 000000000..c681758ce --- /dev/null +++ b/src/krb524/krb524d.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef PROVIDE_DES_CBC_CRC +#include +#endif +#include + +#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 index 000000000..75a275564 --- /dev/null +++ b/src/krb524/misc.c @@ -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 +#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 index 000000000..9b21082dc --- /dev/null +++ b/src/krb524/sendmsg.c @@ -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 +#include + +#include +#include +#include + +#include + +#ifdef _AIX +#include +#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 index 000000000..56a675d9e --- /dev/null +++ b/src/krb524/test.c @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 index 000000000..0be003a69 --- /dev/null +++ b/src/lib/.rconf @@ -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 index 000000000..b88696486 --- /dev/null +++ b/src/lib/crypto/des/.rconf @@ -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 index 000000000..7ed082e32 --- /dev/null +++ b/src/lib/crypto/des/FUNCTIONS @@ -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 index 000000000..70f9f336a --- /dev/null +++ b/src/lib/crypto/des/doc/libdes.doc @@ -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 index 000000000..7ff34eedc --- /dev/null +++ b/src/lib/crypto/des/keytest.data @@ -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 index 000000000..de30fd8c9 --- /dev/null +++ b/src/lib/crypto/md4/.rconf @@ -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 index 000000000..5c0d9414e --- /dev/null +++ b/src/lib/crypto/md4/RFC1186.TXT @@ -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] + +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] + +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] + +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] + +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] + +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] + +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] + +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] + +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 + #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] + +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<>(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] + +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] + +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] + +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] + +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 + #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] + +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] + +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] + +RFC 1186 MD4 Message Digest Algorithm October 1990 + + + if (argc==1) MDfilter(); + else + for (i=1;ils + 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] + +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] + \ 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 index 000000000..6be1a29eb --- /dev/null +++ b/src/lib/crypto/md4/RFC1186B.TXT @@ -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] + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +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] + + +RFC 1186B The MD4 Message Digest Algorithm 9 January 1991 + + + + */ + +#include +#include +#include +#include +#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] + + +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] + + +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] + + +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] + + + + diff --git a/src/lib/exports.crypto b/src/lib/exports.crypto new file mode 100644 index 000000000..6f70f18be --- /dev/null +++ b/src/lib/exports.crypto @@ -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 index 000000000..b1d93d158 --- /dev/null +++ b/src/lib/exports.des425 @@ -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 index 000000000..22d0e6ec4 --- /dev/null +++ b/src/lib/exports.kdb5 @@ -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 index 000000000..baea62b05 --- /dev/null +++ b/src/lib/exports.krb5 @@ -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 index 000000000..08566f0c1 --- /dev/null +++ b/src/lib/glue4.c @@ -0,0 +1,19 @@ +#include + +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 index 000000000..dd1a07459 --- /dev/null +++ b/src/lib/gssapi/README @@ -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 index 000000000..045f87eca --- /dev/null +++ b/src/lib/gssapi/sample/Imakefile @@ -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 +# . +# + + 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 index 000000000..0bd0f0a8c --- /dev/null +++ b/src/lib/gssapi/sample/MAIL.KANNAN @@ -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 index 000000000..3dd42fbb1 --- /dev/null +++ b/src/lib/gssapi/sample/Makefile.bak @@ -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 +# $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 +# . +# + + 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 index 000000000..fce920904 --- /dev/null +++ b/src/lib/gssapi/sample/gssapi.mail @@ -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. + +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 ====================== + \ 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 index 000000000..0ec048ce1 --- /dev/null +++ b/src/lib/gssapi/sample/kitest.c @@ -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 using kinit, and arrange for a server Kerberos */ +/* credential for to be available in a keytable, and issue */ +/* the command: */ +/* kitest-krb -S kitest-krb */ +/* */ +/* 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 +#include +#include +#include +#include +#include + +#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 \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 %.*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 index 000000000..d1a535010 --- /dev/null +++ b/src/lib/gssapi/sample/logutil.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 000000000..a4c374a33 --- /dev/null +++ b/src/lib/krb5.saber.source @@ -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 index 000000000..9fa9d2e15 --- /dev/null +++ b/src/lib/krb5.saber.warnings @@ -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 + 14: #include +( 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 index 000000000..abd941953 --- /dev/null +++ b/src/lib/krb5/asn.1/.rconf @@ -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 index 000000000..d14fddb66 --- /dev/null +++ b/src/lib/krb5/asn.1/.saberinit @@ -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 index 000000000..3267de1ca --- /dev/null +++ b/src/lib/krb5/asn.1/glue2.c @@ -0,0 +1,31 @@ +#include + +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 index 000000000..ce3e84b4d --- /dev/null +++ b/src/lib/krb5/asn.1/process.perl @@ -0,0 +1,50 @@ +# +# usage: perl process +# +$header = ""; +$count = 0; +$pepyid = ""; +$extrainclude = '#include ' . "\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 () { + 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 index 000000000..55ab262ea --- /dev/null +++ b/src/lib/krb5/ccache/file/.rconf @@ -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 index 000000000..e1aa6de00 --- /dev/null +++ b/src/lib/krb5/ccache/file/README @@ -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 index 000000000..ed1ddb8e6 --- /dev/null +++ b/src/lib/krb5/ccache/file/todo @@ -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 index 000000000..874fb0733 --- /dev/null +++ b/src/lib/krb5/ccache/stdio/.rconf @@ -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 index 000000000..a98654366 --- /dev/null +++ b/src/lib/krb5/ccache/stdio/README @@ -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 ::= + +etc. diff --git a/src/lib/krb5/ccache/stdio/todo b/src/lib/krb5/ccache/stdio/todo new file mode 100644 index 000000000..56a423f14 --- /dev/null +++ b/src/lib/krb5/ccache/stdio/todo @@ -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 index 000000000..9adf82b0c --- /dev/null +++ b/src/lib/krb5/error_tables/.rconf @@ -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 index 000000000..54e912bdd --- /dev/null +++ b/src/lib/krb5/rcache/.rconf @@ -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 index 000000000..99187cc05 --- /dev/null +++ b/src/lib/krb5/rcache/README @@ -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 . 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 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 index 000000000..21a462472 --- /dev/null +++ b/src/lib/krb5/rcache/RELEASE @@ -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 + +, dated 7 July 1990