aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorTheodore Tso <tytso@mit.edu>1993-06-03 19:29:40 +0000
committerTheodore Tso <tytso@mit.edu>1993-06-03 19:29:40 +0000
commit746386f12e01102acbe5637aac6f1259c74bb552 (patch)
tree715df6527f739854dc978c588047607e1907e9e9 /src/lib
parentacbed92e113f54d33789d427e697a23a0f07ab64 (diff)
downloadkrb5-746386f12e01102acbe5637aac6f1259c74bb552.zip
krb5-746386f12e01102acbe5637aac6f1259c74bb552.tar.gz
krb5-746386f12e01102acbe5637aac6f1259c74bb552.tar.bz2
Initial revision
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2611 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/.rconf2
-rw-r--r--src/lib/crypto/des/.rconf8
-rw-r--r--src/lib/crypto/des/FUNCTIONS26
-rw-r--r--src/lib/crypto/des/doc/libdes.doc208
-rw-r--r--src/lib/crypto/des/keytest.data171
-rw-r--r--src/lib/crypto/md4/.rconf2
-rw-r--r--src/lib/crypto/md4/RFC1186.TXT1011
-rw-r--r--src/lib/crypto/md4/RFC1186B.TXT1041
-rw-r--r--src/lib/exports.crypto29
-rw-r--r--src/lib/exports.des42517
-rw-r--r--src/lib/exports.kdb526
-rw-r--r--src/lib/exports.krb5312
-rw-r--r--src/lib/glue4.c19
-rw-r--r--src/lib/gssapi/README8
-rw-r--r--src/lib/gssapi/sample/Imakefile59
-rw-r--r--src/lib/gssapi/sample/MAIL.KANNAN114
-rw-r--r--src/lib/gssapi/sample/Makefile.bak396
-rw-r--r--src/lib/gssapi/sample/gssapi.mail54
-rw-r--r--src/lib/gssapi/sample/kitest.c742
-rw-r--r--src/lib/gssapi/sample/logutil.c140
-rw-r--r--src/lib/krb5.saber.source18
-rw-r--r--src/lib/krb5.saber.warnings294
-rw-r--r--src/lib/krb5/asn.1/.rconf8
-rw-r--r--src/lib/krb5/asn.1/.saberinit4
-rw-r--r--src/lib/krb5/asn.1/glue2.c31
-rw-r--r--src/lib/krb5/asn.1/process.perl50
-rw-r--r--src/lib/krb5/ccache/file/.rconf1
-rw-r--r--src/lib/krb5/ccache/file/README33
-rw-r--r--src/lib/krb5/ccache/file/todo7
-rw-r--r--src/lib/krb5/ccache/stdio/.rconf1
-rw-r--r--src/lib/krb5/ccache/stdio/README39
-rw-r--r--src/lib/krb5/ccache/stdio/todo9
-rw-r--r--src/lib/krb5/error_tables/.rconf4
-rw-r--r--src/lib/krb5/rcache/.rconf2
-rw-r--r--src/lib/krb5/rcache/README86
-rw-r--r--src/lib/krb5/rcache/RELEASE17
36 files changed, 4989 insertions, 0 deletions
diff --git a/src/lib/.rconf b/src/lib/.rconf
new file mode 100644
index 0000000..0be003a
--- /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 0000000..b886964
--- /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 0000000..7ed082e
--- /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 0000000..70f9f33
--- /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 0000000..7ff34ee
--- /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 0000000..de30fd8
--- /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 0000000..5c0d941
--- /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 <stdio.h>
+ #include "md4.h"
+
+ /* Compile-time declarations of MD4 "magic constants".
+ */
+ #define I0 0x67452301 /* Initial values for MD buffer */
+ #define I1 0xefcdab89
+ #define I2 0x98badcfe
+ #define I3 0x10325476
+ #define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
+ #define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
+ /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+ ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+ ** Table 2, page 660.
+ */
+
+
+
+Rivest [Page 9]
+
+RFC 1186 MD4 Message Digest Algorithm October 1990
+
+
+ #define fs1 3 /* round 1 shift amounts */
+ #define fs2 7
+ #define fs3 11
+ #define fs4 19
+ #define gs1 3 /* round 2 shift amounts */
+ #define gs2 5
+ #define gs3 9
+ #define gs4 13
+ #define hs1 3 /* round 3 shift amounts */
+ #define hs2 9
+ #define hs3 11
+ #define hs4 15
+
+ /* Compile-time macro declarations for MD4.
+ ** Note: The "rot" operator uses the variable "tmp".
+ ** It assumes tmp is declared as unsigned int, so that the >>
+ ** operator will shift in zeros rather than extending the sign bit.
+ */
+ #define f(X,Y,Z) ((X&Y) | ((~X)&Z))
+ #define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
+ #define h(X,Y,Z) (X^Y^Z)
+ #define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+ #define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
+ #define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
+ #define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+ /* MDprint(MDp)
+ ** Print message digest buffer MDp as 32 hexadecimal digits.
+ ** Order is from low-order byte of buffer[0] to high-order byte of
+ ** buffer[3].
+ ** Each byte is printed with high-order hexadecimal digit first.
+ ** This is a user-callable routine.
+ */
+ void
+ MDprint(MDp)
+ MDptr MDp;
+ { int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<32;j=j+8)
+ printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+ }
+
+ /* MDbegin(MDp)
+ ** Initialize message digest buffer MDp.
+ ** This is a user-callable routine.
+ */
+ void
+ MDbegin(MDp)
+
+
+
+Rivest [Page 10]
+
+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 <stdio.h>
+ #include "md4.h"
+
+ /* MDtimetrial()
+ ** A time trial routine, to measure the speed of MD4.
+ ** Measures speed for 1M blocks = 64M bytes.
+ */
+ MDtimetrial()
+
+
+
+Rivest [Page 14]
+
+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;i<argc;i++)
+ if (argv[i][0]=='-' && argv[i][1]=='s') MDstring(argv[i]+2);
+ else if (strcmp(argv[i],"-t")==0) MDtimetrial();
+ else if (strcmp(argv[i],"-x")==0) MDtestsuite();
+ else MDfile(argv[i]);
+ }
+
+ /*
+ ** end of md4driver.c
+ ****************************(cut)***********************************/
+
+
+ --------------------------------------------------------------------
+ --- Sample session. Compiling and using MD4 on SUN Sparcstation ---
+ --------------------------------------------------------------------
+ >ls
+ total 66
+ -rw-rw-r-- 1 rivest 3 Feb 14 17:40 abcfile
+ -rwxrwxr-x 1 rivest 24576 Feb 17 12:28 md4
+ -rw-rw-r-- 1 rivest 9347 Feb 17 00:37 md4.c
+ -rw-rw-r-- 1 rivest 25150 Feb 17 12:25 md4.doc
+ -rw-rw-r-- 1 rivest 1844 Feb 16 21:21 md4.h
+ -rw-rw-r-- 1 rivest 3497 Feb 17 12:27 md4driver.c
+ >
+ >cc -o md4 -O4 md4.c md4driver.c
+ md4.c:
+ md4driver.c:
+ Linking:
+ >
+ >md4 -x
+ MD4 test suite results:
+ 31d6cfe0d16ae931b73c59d7e0c089c0 ""
+ bde52cb31de33e46245e05fbdbd6fb24 "a"
+ a448017aaf21d8525fc10ae87aa6729d "abc"
+ d9130a8164549fe818874806e1c7014b "message digest"
+ d79e1c308aa5bbcdeea8ed63df412da9 "abcdefghijklmnopqrstuvwxyz"
+ 043f8582f241db351ce627e153e7f0e4
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ a448017aaf21d8525fc10ae87aa6729d abcfile
+ >
+ >md4 -sabc -shi
+ a448017aaf21d8525fc10ae87aa6729d "abc"
+ cfaee2512bd25eb033236f0cd054e308 "hi"
+ >
+ >md4 *
+ a448017aaf21d8525fc10ae87aa6729d abcfile
+
+
+
+Rivest [Page 17]
+
+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 0000000..6be1a29
--- /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 <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <string.h>
+#include "md4.h"
+
+/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
+ Order is from low-order byte to high-order byte of digest.
+ Each byte is printed with high-order hexadecimal digit first.
+ */
+static void MDPrint (mdContext)
+MD4_CTX *mdContext;
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ printf ("%02x", mdContext->digest[i]);
+}
+
+/* size of test block */
+#define TEST_BLOCK_SIZE 1000
+
+/* number of blocks to process */
+#define TEST_BLOCKS 2000
+
+/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
+static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
+
+/* A time trial routine, to measure the speed of MD4.
+ Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
+ characters.
+ */
+static void MDTimeTrial ()
+{
+ MD4_CTX mdContext;
+ time_t endTime, startTime;
+ unsigned char data[TEST_BLOCK_SIZE];
+ unsigned int i;
+
+ /* initialize test data */
+ for (i = 0; i < TEST_BLOCK_SIZE; i++)
+ data[i] = (unsigned char)(i & 0xFF);
+
+ /* start timer */
+ printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES);
+ time (&startTime);
+
+ /* digest data in TEST_BLOCK_SIZE byte blocks */
+ MD4Init (&mdContext);
+ for (i = TEST_BLOCKS; i > 0; i--)
+ MD4Update (&mdContext, data, TEST_BLOCK_SIZE);
+ MD4Final (&mdContext);
+Rivest [Page 14]
+
+
+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 0000000..6f70f18
--- /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 0000000..b1d93d1
--- /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 0000000..22d0e6e
--- /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 0000000..baea62b
--- /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 0000000..08566f0
--- /dev/null
+++ b/src/lib/glue4.c
@@ -0,0 +1,19 @@
+#include <krb5/krb5.h>
+
+krb5_data string_list[3] = {
+{11, "FOO.MIT.EDU"},
+{6, "jtkohl"},
+};
+
+krb5_data *princ[] = {&string_list[0], &string_list[1], 0};
+
+krb5_data string_list2[3] = {
+{11, "FOO.MIT.EDU"},
+{4, "rcmd"},
+{13, "lycus.mit.edu"},
+};
+
+krb5_data *princ2[] = {&string_list2[0], &string_list2[1], &string_list2[2], 0};
+
+krb5_last_req_entry lrentries[] = { {32000, 1}, {0, 3}, {10, 2} };
+krb5_last_req_entry *lrfoo1[] = {&lrentries[0], &lrentries[1], &lrentries[2], 0};
diff --git a/src/lib/gssapi/README b/src/lib/gssapi/README
new file mode 100644
index 0000000..dd1a074
--- /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 0000000..045f87e
--- /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
+# <krb5/copyright.h>.
+#
+
+ DEPLIBS = ../libgssapi.a $(DEPKLIB)
+LOCAL_LIBRARIES = ../libgssapi.a $(KLIB)
+ DEFINES = -DDEBUG
+
+SRCS = flogin.c fcmd.c flogind.c fsh.c fcp.c login.c logutil.c
+OBJS = flogin.o fcmd.o flogind.o fsh.o fcp.o login.o logutil.o
+
+FLOGINSRCS = flogin.c fcmd.c
+FLOGINOBJS = flogin.o fcmd.o
+
+LOGINSRCS = login.c logutil.c
+LOGINOBJS = login.o logutil.o
+
+FLOGINDSRCS = flogind.c logutil.c
+FLOGINDOBJS = flogind.o logutil.o
+
+FSHSRCS = fsh.c fcmd.c
+FSHOBJS = fsh.o fcmd.o
+
+FSHDSRCS = fshd.c
+FSHDOBJS = fshd.o
+
+FCPSRCS = fcp.c fcmd.c
+FCPOBJS = fcp.o fcmd.o
+
+all:: flogin login.gssapi flogind
+
+NormalProgramTarget(flogin,$(FLOGINOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(login.gssapi,$(LOGINOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(flogind,$(FLOGINDOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fsh,$(FSHOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fshd,$(FSHDOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+NormalProgramTarget(fcp,$(FCPOBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+
+SaberProgramTarget(flogin, $(FLOGINSRCS), $(FLOGINOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(login.gssapi, $(LOGINSRCS), $(LOGINOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(flogind, $(FLOGINDSRCS), $(FLOGINDOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fsh, $(FSHSRCS), $(FSHOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fshd, $(FSHDSRCS), $(FSHDOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+SaberProgramTarget(fcp, $(FCPSRCS), $(FCPOBJS),
+ $(DEPLIBS) $(LOCAL_LIBRARIES),)
+
+DependTarget()
diff --git a/src/lib/gssapi/sample/MAIL.KANNAN b/src/lib/gssapi/sample/MAIL.KANNAN
new file mode 100644
index 0000000..0bd0f0a
--- /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 0000000..3dd42fb
--- /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 </tmp/IIf.002934>
+# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
+#
+# Platform-specific parameters may be set in the appropriate .cf
+# configuration files. Site-wide parameters may be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor doesn't define any unique symbols, you'll need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make Makefile", "make Makefiles", or "make World").
+#
+# If you absolutely can't get imake to work, you'll need to set the
+# variables at the top of each Makefile as well as the dependencies at the
+# bottom (makedepend will do this automatically).
+#
+
+###########################################################################
+# platform-specific configuration parameters - edit vaxbsd.cf to change
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+###########################################################################
+# site-specific configuration parameters - edit site.def to change
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+# site: $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../../../.
+ CURRENT_DIR = ./lib/gssapi/sample
+
+ AR = ar cq
+ BOOTSTRAPCFLAGS =
+ CC = gcc -fstrength-reduce -fpcc-struct-return -pedantic -ansi -Wall -Dunix -Dvax
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc -fstrength-reduce -fpcc-struct-return -pedantic -ansi -Wall -Dunix -Dvax -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LDLOCATIONS =
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+ RM = rm -f
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ SABER_DEFINES = -I/mit/gnu/vaxlib/gcc-include -Dconst=
+ EXTRA_LOAD_FLAGS = -Z
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+ ETAGS = etags
+STDC_TOP_INCLUDES = -I$(TOP)/include/stdc-incl
+
+ SIGNAL_DEFINES = -DSIGNALRETURNSINT
+
+ INSTPGMFLAGS = -s
+
+ INSTSCRFLAGS =
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -o root -m 4755
+ INSTLIBFLAGS = -m 0664
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -o root -m 4755
+
+ DESTDIR =
+
+ TOP_INCLUDES = -I$(TOP)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+ COMPATFLAGS =
+
+ ALLINCLUDES = $(INCLUDES) $(STD_INCLUDES) $(TOP_INCLUDES) $(EXTRA_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LDLOCATIONS)
+ LDCOMBINEFLAGS = -X -r
+ MDFLAGS = -D__STDC__ -I/mit/gnu/vaxlib/gcc-include
+
+ MACROFILE = vaxbsd.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGSRC)
+
+ IMAKE_CMD = $(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# Kerberos version 5 Build Parameters
+#
+# $Source$
+# $Author$
+# $Id$
+
+P_TERMIOS=-UHasPosixTermiosTrue
+
+P_FLOCKS=-UHasPosixFileLocksTrue
+
+P_TYPES=-UHasPosixTypesTrue
+
+P_SIGTYPE=-UHasVoidSignalReturnTrue
+
+P_STRINGH=-DHasStringHTrue
+
+P_BITSIZE=-DBitsize32 -UBitsize16 -UBitsize64
+
+P_DBM=-DHasNdbmTrue
+
+P_INET=-DHasInetTrue
+
+P_STDLIBH=-UHasStdlibHTrue -UForceStdlibH
+
+P_TIME_DEFS=-DUseSysTimeH -UUseTimeH
+
+P_PROTOS=-UProvidePrototypes
+
+P_NPROTO=-UUseNarrowPrototypes
+
+P_STDARG=-UUseStdarg
+
+ ARADD = ar cruv
+ TOP_INCLUDES = -I$(TOP)/include $(STDC_TOP_INCLUDES)
+ CONFIGSRC = $(TOP)/config
+ ISODE = /mit/isode/isode-6.8
+ PSYFLAGS = -f -h0 -a -s
+ PEPSY = $(ISODE)/@sys/bin/pepsy
+ TOUCH = touch
+ IMAKE = imake
+ DEPEND = makedepend
+ UNIFDEF = unifdef
+ HESDEFS = -DHESIOD
+ HESLIBS = -lhesiod
+
+ PROCESS_DEFINES = $(P_TERMIOS) $(P_FLOCKS) $(P_TYPES) $(P_SIGTYPE) $(P_STRINGH) $(P_BITSIZE) $(P_DBM) $(P_INET) $(P_STDLIBH) $(P_TIME_DEFS) $(P_PROTOS) $(P_NPROTO) $(P_STDARG) -DUnifdefRan
+ DESDEFINES = -DBIG -DLSBFIRST
+ TOPLIBD = $(TOP)/lib
+ OSLIB = os
+ OSDEPLIB = $(TOPLIBD)/libos.a
+ DESLIB = des5
+ DESDEPLIB = $(TOPLIBD)/libdes5.a
+ RSAMD4LIB = md4
+ RSAMD4DEPLIB = $(TOPLIBD)/libmd4.a
+ KRB5LIB = krb5
+ KRB5DEPLIB = $(TOPLIBD)/libkrb5.a
+ CRCLIB = crc32
+ CRCDEPLIB = $(TOPLIBD)/libcrc32.a
+ ISODELIB = -L/mit/isode/isode-6.8/@sys/lib -lisode
+
+ DBMLIB =
+ DEPKLIB = $(KRB5DEPLIB) $(DESDEPLIB) $(OSDEPLIB)
+ KLIBLOC = -L$(TOPLIBD)
+ KLIB = $(KLIBLOC) -l$(KRB5LIB) -l$(DESLIB) -l$(OSLIB) $(ISODELIB) $(COMERRLIB) $(DBMLIB)
+ KDBDEPLIB = $(TOPLIBD)/libkdb.a
+ KDBLIB = $(KLIBLOC) -lkdb
+ KRB425DEPLIB = $(TOPLIBD)/libkrb425.a
+ KRB425LIB = krb425
+ DES425DEPLIB = $(TOPLIBD)/libdes425.a
+ DES425LIB = des425
+ KRB4LIB = -lkrb $(KLIBLOC) -l$(DES425LIB)
+ KRB4INCLUDES = -I$(TOP)/include/kerberosIV
+ KRB4DEPLIB = $(DES425DEPLIB)
+
+ SSLIB = -lss
+ MK_CMDS = mk_cmds
+ COMERRLIB = -lcom_err
+ COMPILE_ET = compile_et
+
+ ADMIN_BINDIR = /krb5/admin
+ ADMIN_MANSUFFIX = 8
+ ADMIN_MANDIR = /krb5/man/man8
+ SERVER_BINDIR = /krb5/sbin
+ SERVER_MANSUFFIX = 8
+ SERVER_MANDIR = /krb5/man/man8
+ CLIENT_BINDIR = /krb5/bin
+ CLIENT_MANSUFFIX = 1
+ CLIENT_MANDIR = /krb5/man/man1
+
+# $Source$
+# $Author$
+# $Id$
+#
+
+###########################################################################
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
+
+###########################################################################
+# start of Imakefile
+
+# $Source$
+# $Author$
+# $Id$
+#
+# Copyright 1991 by the Massachusetts Institute of Technology.
+# All Rights Reserved.
+#
+# For copying and distribution information, please see the file
+# <krb5/copyright.h>.
+#
+
+ DEPLIBS = $(DEPKLIB) ../libgssapi.a
+LOCAL_LIBRARIES = $(KLIB) ../libgssapi.a
+ DEFINES = -DDEBUG
+
+SRCS = flogin.c fcmd.c flogind.c fsh.c fcp.c login.c logutil.c
+OBJS = flogin.o fcmd.o flogind.o fsh.o fcp.o login.o logutil.o
+
+FLOGINSRCS = flogin.c fcmd.c
+FLOGINOBJS = flogin.o fcmd.o
+
+LOGINSRCS = login.c logutil.c
+LOGINOBJS = login.o logutil.o
+
+FLOGINDSRCS = flogind.c logutil.c
+FLOGINDOBJS = flogind.o logutil.o
+
+FSHSRCS = fsh.c fcmd.c
+FSHOBJS = fsh.o fcmd.o
+
+FSHDSRCS = fshd.c
+FSHDOBJS = fshd.o
+
+FCPSRCS = fcp.c fcmd.c
+FCPOBJS = fcp.o fcmd.o
+
+all:: flogin login.gssapi flogind
+
+flogin: $(FLOGINOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(FLOGINOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) flogin
+
+login.gssapi: $(LOGINOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(LOGINOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) login.gssapi
+
+flogind: $(FLOGINDOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(FLOGINDOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) flogind
+
+fsh: $(FSHOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(FSHOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) fsh
+
+fshd: $(FSHDOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(FSHDOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) fshd
+
+fcp: $(FCPOBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(FCPOBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+clean::
+ $(RM) fcp
+
+saber_flogin:
+ #load $(ALLDEFINES) $(FLOGINSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_flogin:
+ #load $(ALLDEFINES) $(FLOGINOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_login.gssapi:
+ #load $(ALLDEFINES) $(LOGINSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_login.gssapi:
+ #load $(ALLDEFINES) $(LOGINOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_flogind:
+ #load $(ALLDEFINES) $(FLOGINDSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_flogind:
+ #load $(ALLDEFINES) $(FLOGINDOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fsh:
+ #load $(ALLDEFINES) $(FSHSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fsh:
+ #load $(ALLDEFINES) $(FSHOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fshd:
+ #load $(ALLDEFINES) $(FSHDSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fshd:
+ #load $(ALLDEFINES) $(FSHDOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+saber_fcp:
+ #load $(ALLDEFINES) $(FCPSRCS) $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_fcp:
+ #load $(ALLDEFINES) $(FCPOBJS)
+ $(DEPLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+SRCS=$(SERVERSRCS) $(CLIENTSRCS)
+
+depend::
+ $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) $(MDFLAGS) -- $(SRCS)
+
+###########################################################################
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) \#*
+
+Makefile:: Imakefile
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) -s Makefile.new
+ $(MAKE) -f Makefile.new noop
+ -@if [ -f Makefile ]; then \
+ echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ fi
+ $(MV) Makefile.new Makefile
+
+noop::
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(ETAGS) *.[ch]
+
+saber:
+ #load $(ALLDEFINES) $(SABER_DEFINES) $(SRCS)
+ #setopt load_flags $(ALLDEFINES) $(SABER_DEFINES)
+
+osaber:
+ #load $(ALLDEFINES) $(OBJS)
+
+###########################################################################
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+###########################################################################
+# dependencies generated by makedepend
+
+# DO NOT DELETE
diff --git a/src/lib/gssapi/sample/gssapi.mail b/src/lib/gssapi/sample/gssapi.mail
new file mode 100644
index 0000000..fce9209
--- /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 0000000..0ec048c
--- /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 <client-name> using kinit, and arrange for a server Kerberos */
+/* credential for <server-name> to be available in a keytable, and issue */
+/* the command: */
+/* kitest-krb -S kitest-krb <client-name> <server-name> */
+/* */
+/* The original process becomes the context initiator, while the spawned */
+/* subprocess (running the executable specified after the -S flag) is */
+/* expected to act as the context acceptor. */
+
+#if defined(KERBEROS) && defined(DCE)
+#error "Both KERBEROS and DCE specified"
+#endif
+
+#if !defined(KERBEROS) && !defined(DCE)
+#error "Neither KERBEROS nor DCE defined"
+#endif
+
+/* You need to create links from krb-gssapi.h to the Kerberos gssapi.h, and */
+/* from dce-gssapi.h to the DCE gssapi.h. */
+#ifdef KERBEROS
+#include "krb-gssapi.h"
+#endif
+
+#ifdef DCE
+#include "dce-gssapi.h"
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+#ifndef GSS_ERROR
+#define GSS_ERROR(x) (x & 0xffff0000)
+/* The Kerberos gssapi.h doesn't define this macro. */
+#endif
+
+#define DOWN_CHANNEL 3
+/* Don't understand why stdin doesn't work here, but channel 3 seems to */
+/* work fine. */
+
+#define INITIAL_CHILD_MESSAGES 7
+
+extern int errno;
+
+int master = 0;
+int inpipe[2];
+int outpipe[2];
+int errpipe[2];
+
+gss_name_t source_internal_name;
+gss_name_t target_internal_name;
+gss_name_t source_authenticated_name;
+gss_buffer_desc source_name_buffer;
+gss_buffer_desc target_name_buffer;
+
+gss_cred_id_t my_cred_handle;
+gss_cred_id_t delegated_cred_handle;
+gss_ctx_id_t my_ctx_handle;
+gss_OID_set actual_cred_mech_set;
+gss_OID actual_ctx_mech_type;
+OM_uint32 actual_cred_time_rec;
+OM_uint32 actual_ctx_time_rec;
+gss_buffer_desc token_to_send;
+gss_buffer_desc token_received;
+int actual_ret_flags;
+struct gss_channel_bindings_struct my_channel_bindings;
+
+char source_name[512];
+char target_name[512];
+
+char my_host_name[50];
+char my_internet_address[4];
+struct hostent * my_hostent;
+
+unsigned char received_token_buffer[2048];
+unsigned received_length;
+
+OM_uint32 major_status;
+OM_uint32 kept_status;
+OM_uint32 minor_status;
+
+int subprocess_pid = 0;
+
+char line_buffer[128];
+int chars_read;
+
+void indicate_data(void) {
+ fprintf(stderr, "\a\n");
+ fflush(stderr);
+}
+
+void send_data(void * ptr, unsigned length) {
+ unsigned char length_buf[2];
+ unsigned char * char_ptr;
+ int data_sent;
+
+ char_ptr = (unsigned char *)ptr;
+
+ length_buf[0] = length & 0xff;
+ length_buf[1] = (length & 0xff00) >> 8;
+
+ if (master) {
+/* Data is sent via inpipe. */
+ errno = 0;
+ if ((data_sent = write(inpipe[1], length_buf, 2)) != 2) {
+ fprintf(stderr,
+ "Write of length sent %d bytes, expected 2\n",
+ data_sent);
+ fflush(stderr);
+ if (data_sent == -1) {
+ fprintf(stderr,
+ "Errno: %d\n",
+ errno);
+ fflush(stderr);
+ };
+ };
+ errno = 0;
+ if ((data_sent =write(inpipe[1], ptr, length)) != length) {
+ fprintf(stderr,
+ "Write of length sent %d bytes, expected 2\n",
+ data_sent);
+ fflush(stderr);
+ if (data_sent == -1) {
+ fprintf(stderr,
+ "Errno: %d\n",
+ errno);
+ fflush(stderr);
+ };
+ };
+ fprintf(stderr, "Sending data (length = %d):\n", length);
+ fprintf(stderr, " %2.2X %2.2X %2.2X %2.2X %2.2X...\n",
+ char_ptr[0], char_ptr[1], char_ptr[2],
+ char_ptr[3], char_ptr[4]);
+ } else {
+/* Data is sent via stdout, and a data indication on stderr. */
+ fwrite(length_buf, 2, 1, stdout);
+ fwrite(ptr, length, 1, stdout);
+ fflush(stdout);
+ indicate_data();
+ };
+}
+
+void receive_data(void * ptr, unsigned * length) {
+ unsigned char length_buf[2];
+ unsigned char * char_ptr;
+ int data_read;
+
+ char_ptr = (unsigned char *)ptr;
+
+ if (master) {
+/* Data is received via outpipe. A data indication is assumed to have been */
+/* received on errpipe, otherwise this routine will hang. */
+ read(outpipe[0], length_buf, 2);
+ *length = length_buf[0] | (length_buf[1]<<8);
+ read(outpipe[0], ptr, *length);
+ } else {
+/* Data is received on fd3 */
+ errno = 0;
+ if ((data_read = read(DOWN_CHANNEL, length_buf, 2)) != 2) {
+ fprintf(stderr,
+ "Error: received %d bytes for length, expecting 2\n",
+ data_read);
+ fflush(stderr);
+ if (data_read == -1) {
+ fprintf(stderr, "errno: %d\n", errno);
+ fflush(stderr);
+ };
+ };
+
+ *length = length_buf[0] | (length_buf[1]<<8);
+
+ errno = 0;
+ if ((data_read = read(DOWN_CHANNEL, ptr, *length)) != *length) {
+ fprintf(stderr,
+ "Error: received %d bytes for data, expecting %d\n",
+ data_read, *length);
+ fflush(stderr);
+ if (data_read == -1) {
+ fprintf(stderr, "errno: %d\n", errno);
+ fflush(stderr);
+ };
+ };
+
+ fprintf(stderr, "Received data (length = %d):\n", *length);
+ fprintf(stderr, " %2.2X %2.2X %2.2X %2.2X %2.2X...\n",
+ char_ptr[0], char_ptr[1], char_ptr[2],
+ char_ptr[3], char_ptr[4]);
+
+ };
+}
+
+int read_subproc_line(char * ptr, unsigned buf_length) {
+/* Returns length of data read, or zero if binary data waiting. */
+ int bytes_read = 0;
+ int finished = 0;
+ if (!master) {
+ fprintf(stderr, "Error: Child called read_subproc_data\n");
+ fflush(stderr);
+ exit(2);
+ } else {
+ while (!finished) {
+ read(errpipe[0], &ptr[bytes_read], 1);
+ if (ptr[bytes_read] == '\n') finished = 1;
+ if (bytes_read >= buf_length) finished = 1;
+ bytes_read ++;
+ };
+ if (bytes_read == 2 && ptr[0] == '\a') return 0;
+ else return bytes_read;
+ };
+}
+
+void display_error(char * where, OM_uint32 maj_stat, OM_uint32 min_stat) {
+ int context = 0;
+ OM_uint32 major_status, minor_status;
+ gss_buffer_desc message_buffer;
+
+ fprintf(stderr, "Error: %s\n", where);
+ fprintf(stderr, "Major status (%d) (min = %d):\n", maj_stat, min_stat);
+ fflush(stderr);
+ do {
+ message_buffer.length = 0;
+ message_buffer.value = NULL;
+ major_status = gss_display_status(&minor_status,
+ maj_stat,
+ GSS_C_GSS_CODE,
+ GSS_C_NULL_OID,
+ &context,
+ &message_buffer);
+ fprintf(stderr,
+ " message_buffer.length = %u, message_buffer.value = %p\n",
+ message_buffer.length, message_buffer.value);
+ fflush(stderr);
+ if (message_buffer.length = 0) {
+ fprintf(stderr,
+ " %.*s\n",
+ message_buffer.length,
+ message_buffer.value);
+ major_status = gss_release_buffer(&minor_status, &message_buffer);
+ } else {
+ fprintf(stderr, "-- no message --\n");
+ /* If we've been asked to translate an invalid status code */
+ };
+ fflush(stderr);
+
+ } while (context != 0);
+ fprintf(stderr, "Minor status:\n");
+ fflush(stderr);
+ major_status = gss_display_status(&minor_status,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NULL_OID,
+ &context,
+ &message_buffer);
+ fprintf(stderr,
+ " %.*s\n",
+ message_buffer.length,
+ message_buffer.value);
+ fflush(stderr);
+
+ major_status = gss_release_buffer(&minor_status, &message_buffer);
+
+}
+
+void import_names(void) {
+
+ source_name_buffer.value = (void *)&source_name[0];
+ source_name_buffer.length = strlen(source_name);
+
+ major_status = gss_import_name(&minor_status,
+ &source_name_buffer,
+ GSS_C_NULL_OID,
+ &source_internal_name);
+
+ if (major_status != GSS_S_COMPLETE)
+ display_error("Importing source principal", major_status, minor_status);
+
+ target_name_buffer.value = (void *)&target_name[0];
+ target_name_buffer.length = strlen(target_name);
+
+ major_status = gss_import_name(&minor_status,
+ &target_name_buffer,
+ GSS_C_NULL_OID,
+ &target_internal_name);
+
+ if (major_status != GSS_S_COMPLETE)
+ display_error("Importing target principal", major_status, minor_status);
+
+}
+
+
+void alarm_handler(int sig) {
+ fprintf(stderr, "SIGALRM received, terminating subprocess\n");
+ fflush(stderr);
+ kill(subprocess_pid, SIGTERM);
+ exit(0);
+}
+
+
+void flush_subprocess_message_queue_and_exit(void) {
+
+ signal(SIGALRM, alarm_handler);
+ alarm(10);
+
+ do {
+ chars_read = read_subproc_line(line_buffer,
+ sizeof(line_buffer));
+ if (chars_read == 0) {
+ fprintf(stderr,
+ "Unexpected binary data received from child\n");
+ fflush(stderr);
+ receive_data(received_token_buffer,
+ &received_length);
+ } else {
+ fprintf(stderr,"CHILD> %.*s", chars_read, line_buffer);
+ };
+ fflush(stderr);
+ } while (1);
+}
+
+void sigpipe_handler(int sig) {
+ fprintf(stderr, "SIGPIPE received, flushing subprocess message queue\n");
+ fflush(stderr);
+ flush_subprocess_message_queue_and_exit();
+}
+
+int main(int argc, char *argv[]) {
+
+ int c;
+ int errflg = 0;
+ char * image_name;
+ int pid;
+
+ int i;
+
+ extern int optind, opterr;
+ extern char * optarg;
+
+ int blocking;
+
+ while ((c = getopt(argc, argv, "S:")) != EOF) {
+ switch (c) {
+ case 'S' : master = 1;
+ image_name = optarg;
+ break;
+ case '?' : errflg++;
+ break;
+ };
+ };
+
+ if (optind < argc) {
+ strncpy(source_name, argv[optind++], sizeof(source_name)-1);
+ } else {
+ fprintf(stderr, "Error: Source name (prin-1) missing\n");
+ errflg++;
+ };
+
+ if (optind < argc) {
+ strncpy(target_name, argv[optind++], sizeof(source_name)-1);
+ } else {
+ fprintf(stderr, "Error: Target name (prin-2) missing\n");
+ errflg++;
+ };
+
+ if (optind < argc) {
+ fprintf(stderr, "Error: too many parameters\n");
+ errflg++;
+ };
+
+ if (errflg) {
+ fprintf(stderr, "Usage: %s -S <subprocess> <princ-1> <princ-2>\n", argv[0]);
+ exit(2);
+ };
+
+ gethostname(my_host_name, sizeof(my_host_name));
+ my_hostent = gethostbyname(my_host_name);
+ memcpy(&my_internet_address, my_hostent->h_addr_list[0], 4);
+
+ fprintf(stderr,"Host: '%s', %u.%u.%u.%u\n",
+ my_host_name,
+ my_internet_address[0],
+ my_internet_address[1],
+ my_internet_address[2],
+ my_internet_address[3]);
+
+ my_channel_bindings.initiator_addrtype = GSS_C_AF_INET;
+ my_channel_bindings.initiator_address.length = 4;
+ my_channel_bindings.initiator_address.value = my_internet_address;
+
+ my_channel_bindings.acceptor_addrtype = GSS_C_AF_INET;
+ my_channel_bindings.acceptor_address.length = 4;
+ my_channel_bindings.acceptor_address.value = my_internet_address;
+
+ my_channel_bindings.application_data.length = 0;
+ my_channel_bindings.application_data.value = NULL;
+
+ my_ctx_handle = GSS_C_NO_CONTEXT;
+
+ if (!master) {
+
+/* Subprocess. */
+
+ fprintf(stderr, "Importing names\n");
+ fflush(stderr);
+
+ import_names();
+
+ fprintf(stderr, "Calling acquire_cred\n");
+ fflush(stderr);
+
+ major_status = gss_acquire_cred(&minor_status,
+ target_internal_name,
+ 60 * 60 * 24,
+ GSS_C_NULL_OID_SET,
+ GSS_C_ACCEPT,
+ &my_cred_handle,
+ &actual_cred_mech_set,
+ &actual_cred_time_rec);
+
+ if (major_status != GSS_S_COMPLETE) {
+ display_error("Acquiring ACCEPT credential for target principal",
+ major_status, minor_status);
+ while (1) ;
+ };
+
+ fprintf(stderr, "Returned from acquire_cred, waiting for token from parent\n");
+ fflush(stderr);
+
+ do {
+
+ receive_data(received_token_buffer,
+ &received_length);
+ token_received.value = (void *)received_token_buffer;
+ token_received.length = received_length;
+
+ fprintf(stderr, "Got token, calling accept_sec_context\n");
+ fflush(stderr);
+
+ major_status = gss_accept_sec_context(&minor_status,
+ &my_ctx_handle,
+ my_cred_handle,
+ &token_received,
+ &my_channel_bindings,
+ &source_authenticated_name,
+ &actual_ctx_mech_type,
+ &token_to_send,
+ &actual_ret_flags,
+ &actual_ctx_time_rec,
+ &delegated_cred_handle);
+ kept_status = major_status;
+
+ if (GSS_ERROR(major_status)) {
+ display_error("ACCEPT_SEC_CONTEXT",
+ major_status, minor_status);
+ while (1) ;
+ };
+
+ if (token_to_send.length != 0) {
+ send_data(token_to_send.value, token_to_send.length);
+ major_status = gss_release_buffer(&minor_status,
+ &token_to_send);
+ };
+
+ if (kept_status & GSS_S_CONTINUE_NEEDED) {
+ receive_data(received_token_buffer,
+ &received_length);
+ token_received.value = (void *)received_token_buffer;
+ token_received.length = received_length;
+ };
+
+ } while (kept_status & GSS_S_CONTINUE_NEEDED);
+
+ if (!GSS_ERROR(kept_status)) {
+ fprintf(stderr, "Authenticated context established\n");
+ } else {
+ fprintf(stderr, "Context not established\n");
+ };
+ fflush(stderr);
+ while (1) ;
+ } else {
+/* We need to create three pipes - inpipe, outpipe and errpipe, to which */
+/* the subprocess will connect its fd3, stdout and stderr channels. */
+
+ if (pipe(inpipe) < 0) {
+ fprintf(stderr, "Error: Can't make inpipe\n");
+ exit(2);
+ };
+ if (pipe(outpipe) < 0) {
+ fprintf(stderr, "Error: Can't make outpipe\n");
+ exit(2);
+ };
+ if (pipe(errpipe) < 0) {
+ fprintf(stderr, "Error: Can't make errpipe\n");
+ exit(2);
+ };
+
+ if ((subprocess_pid = fork()) == 0) {
+/* This is the slave subprocess in a two-process chain. Connect inpipe, */
+/* outpipe and errpipe to fd3, stderr and stdout, and then exec the slave */
+/* image. */
+ fprintf(stderr, "CHILD: forked, closing pipes\n");
+ fflush(stderr);
+
+ close(inpipe[1]); /* Close write end of inpipe */
+ close(outpipe[0]); /* Close read end of outpipe */
+ close(errpipe[0]); /* Close read end of errpipe */
+
+
+ write (errpipe[1],
+ "Child process forked (write to errpipe[1])\n",
+ strlen("Child process forked (write to errpipe[1])\n")
+ );
+
+ if (dup2(inpipe[0], DOWN_CHANNEL) == -1) {
+ fprintf(stderr, "CHILD: Can't dup2 inpipe[0]\n");
+ fflush(stderr);
+ };
+ /* Attach inpipe to fd3 */
+ if (dup2(outpipe[1], 1) == -1) {
+ fprintf(stderr, "CHILD: Can't dup2 outpipe[1]\n");
+ fflush(stderr);
+ };
+ /* Attach outpipe to stdout */
+ if (dup2(errpipe[1], 2) == -1) {
+ fprintf(stderr, "CHILD: Can't dup2 errpipe[1]\n");
+ fflush(stderr);
+ };
+ /* Attach errpipe to stderr */
+
+ write (2,
+ "Child process forked (write to fd2)\n",
+ strlen("Child process forked (write to fd2)\n")
+ );
+
+ fprintf(stderr, "Execing %s\n", image_name);
+ fflush(stderr);
+
+ execl(image_name, image_name, source_name, target_name, (char *)0);
+
+ fprintf(stderr, "Error: Couldn't exec %s\n", image_name);
+ exit(2);
+
+ } else if (subprocess_pid < 0) {
+ fprintf(stderr, "Error: Fork returned %d\n", subprocess_pid);
+ exit(2);
+ } else {
+/* This is the master process in a two-process chain. The slave process */
+/* has connected inpipe, outpipe and errpipe to its fd3, stdout and */
+/* stderr. We have to use the other ends. */
+
+
+ close(inpipe[0]); /* Close read end of inpipe */
+ close(outpipe[1]); /* Close write end of outpipe */
+ close(errpipe[1]); /* Close write end of errpipe */
+
+/* A simple protocol will be used between master and slave processes. The */
+/* subprocess (slave) will always expect that data received on its inpipe */
+/* will be binary messages, preceeded by a two-byte count. Messages from */
+/* slave to master will be sent on the errpipe channel if they are text */
+/* messages, and on outpipe if they are binary data (preceeded as above by */
+/* a two-byte count field). The presence of a binary message in the */
+/* outpipe will be indicated by writing the sequence "\a\n" to errpipe. */
+/* This protocol is implemented in the master by the routine */
+/* read_subproc_line, which reads a single line of text from the */
+/* subprocess, returning either its length, or zero to indicate that binary */
+/* data is waiting. Binary data is received by either process by invoking */
+/* the receive_data routine, and sent by invoking the send_data routine. */
+/* The receive_data routine will block until the data is available, so */
+/* care should be taken in the master not to call this routine unless a */
+/* data indication has already been received. */
+
+/* Master: */
+ signal(SIGPIPE, sigpipe_handler);
+
+/* The child will send us messages on start-up (at least */
+/* INITIAL_CHILD_MESSAGES of them), so we'll read them here to make sure we */
+/* catch a sleepy child early. */
+
+ fprintf(stderr, "Parent waiting for wake-up call from child...\n");
+ fflush(stderr);
+
+ signal(SIGALRM, alarm_handler);
+ alarm(10);
+
+ for (i=0; i<INITIAL_CHILD_MESSAGES; i++) {
+ chars_read = read_subproc_line(line_buffer,
+ sizeof(line_buffer));
+
+ if (chars_read == 0) {
+ fprintf(stderr,
+ "Unexpected binary data received from child\n");
+ fflush(stderr);
+ receive_data(received_token_buffer,
+ &received_length);
+ } else {
+ fprintf(stderr,"CHILD> %.*s", chars_read, line_buffer);
+ };
+ fflush(stderr);
+
+ };
+
+ alarm(0);
+
+ fprintf(stderr, "Parent continuing, importing names...\n");
+ fflush(stderr);
+
+ import_names();
+
+ fprintf(stderr, "Parent got names...\n");
+ fflush(stderr);
+
+#ifdef KERBEROS
+
+/* This version of the acquire_cred code requests the client credential */
+/* explicitly by name; the DCE version uses no name, meaning "give me a */
+/* to the default credential. */
+
+ fprintf(stderr, "Parent calling acquire_cred...\n");
+ fflush(stderr);
+
+ major_status = gss_acquire_cred(&minor_status,
+ source_internal_name,
+ 60 * 60 * 24,
+ GSS_C_NULL_OID_SET,
+ GSS_C_INITIATE,
+ &my_cred_handle,
+ &actual_cred_mech_set,
+ &actual_cred_time_rec);
+
+ fprintf(stderr, "Parent returned from acquire_cred.\n");
+ fflush(stderr);
+
+#endif
+#ifdef DCE
+ major_status = gss_acquire_cred(&minor_status,
+ GSS_C_NO_NAME,
+ 60 * 60 * 24,
+ GSS_C_NULL_OID_SET,
+ GSS_C_INITIATE,
+ &my_cred_handle,
+ &actual_cred_mech_set,
+ &actual_cred_time_rec);
+#endif
+ if (major_status != GSS_S_COMPLETE)
+ display_error("Acquiring INITIATE credential for source principal",
+ major_status, minor_status);
+
+
+ token_received.length = 0;
+ token_received.value = NULL;
+
+ do {
+
+ fprintf(stderr, "Parent calling init_sec_ctx...\n");
+ fflush(stderr);
+
+ major_status = gss_init_sec_context(&minor_status,
+ my_cred_handle,
+ &my_ctx_handle,
+ target_internal_name,
+ GSS_C_NULL_OID,
+ GSS_C_MUTUAL_FLAG,
+ 60 * 60 * 23,
+ &my_channel_bindings,
+ &token_received,
+ &actual_ctx_mech_type,
+ &token_to_send,
+ &actual_ret_flags,
+ &actual_ctx_time_rec);
+
+ fprintf(stderr, "Parent returned from init_sec_ctx...\n");
+ fflush(stderr);
+
+ kept_status = major_status;
+
+ if (GSS_ERROR(major_status))
+ display_error("INIT_SEC_CONTEXT",
+ major_status, minor_status);
+
+ if (token_to_send.length != 0) {
+
+ fprintf(stderr, "Parent transmitting token...\n");
+ fflush(stderr);
+
+ send_data(token_to_send.value, token_to_send.length);
+ major_status = gss_release_buffer(&minor_status,
+ &token_to_send);
+ };
+
+ if (kept_status & GSS_S_CONTINUE_NEEDED) {
+ signal(SIGALRM, alarm_handler);
+ alarm(30);
+ while ((chars_read = read_subproc_line(line_buffer,
+ sizeof(line_buffer))
+ ) != 0) {
+ fprintf(stderr, "CHILD> %.*s", chars_read, line_buffer);
+ };
+ alarm(0);
+ receive_data(received_token_buffer,
+ &received_length);
+ token_received.value = (void *)received_token_buffer;
+ token_received.length = received_length;
+ };
+
+ } while (kept_status & GSS_S_CONTINUE_NEEDED);
+
+ if (!GSS_ERROR(kept_status)) {
+ fprintf(stderr, "Authenticated context established\n");
+ } else {
+ fprintf(stderr, "Context not established\n");
+ };
+ fflush(stderr);
+
+ flush_subprocess_message_queue_and_exit();
+
+ };
+ };
+}
diff --git a/src/lib/gssapi/sample/logutil.c b/src/lib/gssapi/sample/logutil.c
new file mode 100644
index 0000000..d1a5350
--- /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 <sys/types.h>
+#include <sys/file.h>
+#include <utmp.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#define UTMPFILE "/etc/utmp"
+#define WTMPFILE "/usr/adm/wtmp"
+
+void
+login(ut)
+ struct utmp *ut;
+{
+ register int fd;
+ int tty;
+ off_t lseek();
+
+ tty = ttyslot();
+ if (tty > 0 && (fd = open(UTMPFILE, O_WRONLY, 0)) >= 0) {
+ (void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
+ (void)write(fd, (char *)ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+ if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) >= 0) {
+ (void)write(fd, (char *)ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+}
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)logout.c 5.1 (Berkeley) 8/31/88";
+#endif /* LIBC_SCCS and not lint */
+
+logout(line)
+ register char *line;
+{
+ register FILE *fp;
+ struct utmp ut;
+ int rval;
+ time_t time();
+
+ if (!(fp = fopen(UTMPFILE, "r+")))
+ return(0);
+ rval = 1;
+ while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
+ if (!ut.ut_name[0] ||
+ strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
+ continue;
+ bzero(ut.ut_name, sizeof(ut.ut_name));
+ bzero(ut.ut_host, sizeof(ut.ut_host));
+ (void)time(&ut.ut_time);
+ (void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
+ (void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
+ (void)fseek(fp, (long)0, L_INCR);
+ rval = 0;
+ }
+ (void)fclose(fp);
+ return(rval);
+}
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)logwtmp.c 5.2 (Berkeley) 9/20/88";
+#endif /* LIBC_SCCS and not lint */
+
+logwtmp(line, name, host)
+ char *line, *name, *host;
+{
+ struct utmp ut;
+ struct stat buf;
+ int fd;
+ time_t time();
+ char *strncpy();
+
+ if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
+ return;
+ if (!fstat(fd, &buf)) {
+ (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+ (void)time(&ut.ut_time);
+ if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
+ sizeof(struct utmp))
+ (void)ftruncate(fd, buf.st_size);
+ }
+ (void)close(fd);
+}
diff --git a/src/lib/krb5.saber.source b/src/lib/krb5.saber.source
new file mode 100644
index 0000000..a4c374a
--- /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 0000000..9fa9d2e
--- /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 <krb5/krb5.h>
+ 14: #include <krb5/ext-proto.h>
+( while sourcing "/tmp/saber.source":18 )
+Cannot open 'krb5/krb5.h' for input.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":335, krb5_rc_dfl_recover(), Unused automatic variable (Warning #591)
+ 334: struct dfl_data *t = (struct dfl_data *)id->data;
+ * 335: int i;
+ 336: krb5_donot_replay *rep;
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":402, krb5_rc_dfl_recover(), Unused label (Warning #593)
+( while sourcing "/tmp/saber.source":18 )
+Label 'end_loop' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":443, krb5_rc_dfl_store(), Statement not reached (Warning #529)
+ 442: case CMP_MALLOC:
+ * 443: return KRB5_RC_MALLOC; break;
+ 444: case CMP_REPLAY:
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":445, krb5_rc_dfl_store(), Statement not reached (Warning #529)
+ 444: case CMP_REPLAY:
+ * 445: return KRB5KRB_AP_ERR_REPEAT; break;
+ 446: case 0: break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":438, krb5_rc_dfl_store(), Unused automatic variable (Warning #591)
+ 437: struct dfl_data *t = (struct dfl_data *)id->data;
+ * 438: int i;
+ 439:
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":525, krb5_rc_dfl_expunge(), Benign argumentmismatch (Warning #68)
+ 524: {
+ * 525: if (krb5_rc_io_store (&tmp, &q->rep))
+ 526: return KRB5_RC_IO;
+( while sourcing "/tmp/saber.source":18 )
+Benign type mismatch in call to function 'krb5_rc_io_store':
+Argument #1 has type (struct krb5_rc_iostuff *) but type (struct dfl_data *) was expected.
+Defined/declared in "/mit/krb5/src/lib/rcache/rc_dfl.c":404
+----------------
+"/mit/krb5/src/lib/rcache/rc_dfl.c":473, krb5_rc_dfl_expunge(), Unused automatic variable (Warning #591)
+ 472: struct dfl_data *t = (struct dfl_data *)id->data;
+ * 473: int i;
+ 474: #ifdef NOIOSTUFF
+( while sourcing "/tmp/saber.source":18 )
+Automatic variable 'i' was not used.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":33, Unknown directive (Warning #471)
+ 32: #else
+ 33: #error find some way to use net-byte-order file version numbers.
+ ^
+ 34: #endif
+( while sourcing "/tmp/saber.source":18 )
+Directive 'error' is undefined.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":73, krb5_rc_io_creat(), Constant in conditional (Warning #558)
+ 72:
+ * 73: GETDIR;
+ 74: if (fn && *fn)
+( while sourcing "/tmp/saber.source":18 )
+The conditional expression for 'do/while' is always false.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":156, krb5_rc_io_open(), Constant in conditional (Warning #558)
+ 155:
+ * 156: GETDIR;
+ 157: if (!(d->fn = malloc(strlen(fn) + dirlen + 1)))
+( while sourcing "/tmp/saber.source":18 )
+The conditional expression for 'do/while' is always false.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":165, krb5_rc_io_open(), Function redeclared (Warning #701)
+ 164:
+ * 165: me = getuid();
+ 166: /* must be owned by this user, to prevent some security problems with
+( while sourcing "/tmp/saber.source":18 )
+Function 'getuid' was previously declared as:
+ extern short getuid();
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":238, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 237: {
+ * 238: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ 239: case EFBIG: return KRB5_RC_IO_SPACE; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":239, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 238: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 239: case EFBIG: return KRB5_RC_IO_SPACE; break;
+ 240: #ifdef EDQUOT
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":241, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 240: #ifdef EDQUOT
+ * 241: case EDQUOT: return KRB5_RC_IO_SPACE; break;
+ 242: #endif
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":243, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 242: #endif
+ * 243: case ENOSPC: return KRB5_RC_IO_SPACE; break;
+ 244: case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":244, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 243: case ENOSPC: return KRB5_RC_IO_SPACE; break;
+ * 244: case EIO: return KRB5_RC_IO_IO; break;
+ 245: default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":245, krb5_rc_io_write(), Statement not reached (Warning #529)
+ 244: case EIO: return KRB5_RC_IO_IO; break;
+ * 245: default: return KRB5_RC_IO_UNKNOWN; break;
+ 246: }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":256, krb5_rc_io_sync(), Statement not reached (Warning #529)
+ 255: {
+ * 256: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ 257: case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":257, krb5_rc_io_sync(), Statement not reached (Warning #529)
+ 256: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 257: case EIO: return KRB5_RC_IO_IO; break;
+ 258: default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":258, krb5_rc_io_sync(), Statement not reached (Warning #529)
+ 257: case EIO: return KRB5_RC_IO_IO; break;
+ * 258: default: return KRB5_RC_IO_UNKNOWN; break;
+ 259: }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":273, krb5_rc_io_read(), Statement not reached (Warning #529)
+ 272: {
+ * 273: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ 274: case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":274, krb5_rc_io_read(), Statement not reached (Warning #529)
+ 273: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 274: case EIO: return KRB5_RC_IO_IO; break;
+ 275: default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":275, krb5_rc_io_read(), Statement not reached (Warning #529)
+ 274: case EIO: return KRB5_RC_IO_IO; break;
+ * 275: default: return KRB5_RC_IO_UNKNOWN; break;
+ 276: }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":298, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 297: {
+ * 298: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ 299: case EIO: return KRB5_RC_IO_IO; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":299, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 298: case EBADF: return KRB5_RC_IO_UNKNOWN; break;
+ * 299: case EIO: return KRB5_RC_IO_IO; break;
+ 300: case EPERM: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":300, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 299: case EIO: return KRB5_RC_IO_IO; break;
+ * 300: case EPERM: return KRB5_RC_IO_PERM; break;
+ 301: case EBUSY: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":301, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 300: case EPERM: return KRB5_RC_IO_PERM; break;
+ * 301: case EBUSY: return KRB5_RC_IO_PERM; break;
+ 302: case EROFS: return KRB5_RC_IO_PERM; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":302, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 301: case EBUSY: return KRB5_RC_IO_PERM; break;
+ * 302: case EROFS: return KRB5_RC_IO_PERM; break;
+ 303: default: return KRB5_RC_IO_UNKNOWN; break;
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
+----------------
+"/mit/krb5/src/lib/rcache/rc_io.c":303, krb5_rc_io_destroy(), Statement not reached (Warning #529)
+ 302: case EROFS: return KRB5_RC_IO_PERM; break;
+ * 303: default: return KRB5_RC_IO_UNKNOWN; break;
+ 304: }
+( while sourcing "/tmp/saber.source":18 )
+The statement cannot be reached.
diff --git a/src/lib/krb5/asn.1/.rconf b/src/lib/krb5/asn.1/.rconf
new file mode 100644
index 0000000..abd9419
--- /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 0000000..d14fddb
--- /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 0000000..3267de1
--- /dev/null
+++ b/src/lib/krb5/asn.1/glue2.c
@@ -0,0 +1,31 @@
+#include <krb5/krb5.h>
+
+krb5_data string_list[3] = {
+{14, "ATHENA.MIT.EDU"},
+{6, "jtkohl"},
+{4, "root"},
+};
+
+krb5_data *princ[] = {&string_list[0], &string_list[1], &string_list[2], 0};
+
+krb5_data string_list2[3] = {
+{14, "ATHENA.MIT.EDU"},
+{6, "krbtgt"},
+{14, "ATHENA.MIT.EDU"},
+};
+
+krb5_data *princ2[] = {&string_list2[0], &string_list2[1], &string_list2[2], 0};
+
+krb5_last_req_entry lrentries[] = { {32000, 1}, {0, 3}, {10, 2} };
+krb5_last_req_entry *lrfoo1[] = {&lrentries[0], &lrentries[1], &lrentries[2], 0};
+
+krb5_authdata adarr1[] = { {3, 7, "authdat"}, {2,4,"foob"}, {257,9,"jtkohlxxx"}};
+krb5_authdata *authdats[] = {&adarr1[0],&adarr1[1],&adarr1[2],0};
+
+krb5_pa_data authdarr1[] = { {3, 7, "authdat"}, {2,4,"foob"}, {257,9,"jtkohlxxx"}};
+krb5_pa_data *padats[] = {&authdarr1[0],&authdarr1[1],&authdarr1[2],0};
+
+krb5_address adrarr1[] = { {ADDRTYPE_INET,4,"abcd"},
+ {ADDRTYPE_ISO,10,"6176432831"},
+ {ADDRTYPE_INET,4,"efgh"} };
+krb5_address *addrs[] = {&adrarr1[0],&adrarr1[1],&adrarr1[2],0};
diff --git a/src/lib/krb5/asn.1/process.perl b/src/lib/krb5/asn.1/process.perl
new file mode 100644
index 0000000..ce3e84b
--- /dev/null
+++ b/src/lib/krb5/asn.1/process.perl
@@ -0,0 +1,50 @@
+#
+# usage: perl process <input-c-file> <output-prefix> <c-flist> <o-flist>
+#
+$header = "";
+$count = 0;
+$pepyid = "";
+$extrainclude = '#include <krb5/asn.1/KRB5-types-aux.h>' . "\n";
+
+if ($#ARGV != 3) {die "Usage: process input-file.c output-prefix cflist-file oflist-file";}
+
+print "processing ", $ARGV[0], "\n";
+open(CFILE, "< $ARGV[0]") || die "can't open $ARGV[0]";
+open(CFLIST, "> $ARGV[2]") || die "can't open $ARGV[2]";
+open(OFLIST, "> $ARGV[3]") || die "can't open $ARGV[2]";
+
+mainloop: while (<CFILE>) {
+ next mainloop if /^# line/;
+ if (/pepyid/) {
+ $pepyid = $_;
+ } elsif (/^\/\* ARGS|^free/) {
+ print "processing output from $pepyid" if ($count == 0);
+ close(OUTFILE);
+ $ofile = "$ARGV[1]" . $count . ".c";
+ open(OUTFILE, ">$ofile" ) || die "can't open file $ofile";
+ print OUTFILE $pepyid if ($count == 0);
+ print $ofile, "\n";
+ @clist = (@clist, " " . $ofile);
+ $count++;
+ print OUTFILE $header;
+ print OUTFILE $extrainclude;
+ print OUTFILE $_;
+ } elsif ($count == 0) {
+ $header .= $_;
+ } else {
+ print OUTFILE $_;
+ }
+}
+close(OUTFILE);
+print CFLIST "TYPESSRCS= ", @clist, "\n";
+close(CFLIST);
+while ($cfile = shift(@clist)) {
+ $cfile =~ s/.c$/.o/;
+ @olist = (@olist, $cfile);
+}
+print OFLIST "TYPESOBJS=", @olist, "\n";
+close(OFLIST);
+#
+# $Source$
+# $Author$
+# $Id$
diff --git a/src/lib/krb5/ccache/file/.rconf b/src/lib/krb5/ccache/file/.rconf
new file mode 100644
index 0000000..55ab262
--- /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 0000000..e1aa6de
--- /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 0000000..ed1ddb8
--- /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 0000000..874fb07
--- /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 0000000..a986543
--- /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 ::= <int16>
+
+etc.
diff --git a/src/lib/krb5/ccache/stdio/todo b/src/lib/krb5/ccache/stdio/todo
new file mode 100644
index 0000000..56a423f
--- /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 0000000..9adf82b
--- /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 0000000..54e912b
--- /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 0000000..99187cc
--- /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 <malloc.h>. rc_io.c assumes fsync() and a gaggle of
+error codes. These assumptions are not as portable as the code itself.
+
+
+rcache.c:
+
+The rcache.c compatibility interface's type registration is a no-op; it
+simply passes the type name on to rc_base.h. rcache.h is obsolete; use
+rc_base.h if possible.
+
+There are some slight differences between rcache.c and the prototypes I
+saw in krb/func-proto.h. Don't look at me, it's your interface.
+
+rcache.c's get_name doesn't fill with zeros unless strncpy does.
+
+
+rc_base.c:
+
+If SEMAPHORE is defined and <semaphore.h> exists when rc_base.c is
+compiled, all access to the type list will be protected by appropriate
+semaphore ups and downs. This is untested.
+
+It doesn't take linker magic to preregister types. Just change the
+typehead initialization in rc_base.c, with an appropriate include file
+setting the ops.
+
+
+rc_dfl.c:
+
+If NOIOSTUFF is defined when rc_dfl.c is compiled, all dfl rcaches will
+be per-process. This is untested.
+
+Provided that separate threads use separate rcaches, rc_dfl.c is safe
+for multithreading.
+
+Getting the name of a cache is only valid after it is created and before
+it is closed. Recovering a cache is only valid after it has been created.
+
+krb5_unparse_name had better produce a zero-terminated string.
+
+rc_dfl.c isn't smart enough to try expunge/retry upon a malloc error.
+Then again, such an error indicates that the whole system's about to die;
+without real memory management there's no good solution.
+
+HASHSIZE can be defined at compile time. It defaults to 997 in rc_dfl.c.
+EXCESSREPS can be defined at compile time. It defaults to 30 in rc_dfl.c.
+
+Hopefully adding a deltat to a time to compare to another time cannot
+overflow.
+
+In rc_dfl's struct dfl_data, the name field is never freed, even though
+it may be malloced by io_creat on a generate-name call. This should not
+be a problem: a single process should not be opening and closing many
+rcaches. One fix would be another field to indicate whether the string
+was malloced or not; normally this is an unstated characteristic of a
+char pointer, but here it would have to be explicit.
+
+
+rc_io.c:
+
+rc_io.c assumes that siginterrupt() is not set. If siginterrupt() is set
+and a signal occurs during, say, close(), then the close will fail.
+
+On a machine without fsync() you might as well not use the disk at all.
diff --git a/src/lib/krb5/rcache/RELEASE b/src/lib/krb5/rcache/RELEASE
new file mode 100644
index 0000000..21a4624
--- /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
+
+<signature>, dated 7 July 1990