home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-19 | 41.8 KB | 1,792 lines |
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v10i031: DES encryption routines and a login front-end
- Message-ID: <523@uunet.UU.NET>
- Date: 2 Jul 87 03:04:55 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 1781
- Approved: rs@uunet.uu.net
-
- Mod.Sources: Volume 10, Number 31
- Submitted by: Bdale Garbee <winfree!bdale>
- Archive-name: des
-
- [ Those of you who have a copy of the Volume 6 posting should consider
- this a replacement for it. Those of you concerned about the legality
- of posting this, don't be --r$ ]
-
- Rich - Here is an updated copy of the DES routines shar file. Phil found
- and fixed a bug in the main.c module that caused the DES program to
- occasionally mutilate keys resulting in un-decodable files. He also has
- now included uuencode and uudecode routines, which are helpful for creating
- filters into and out of mail systems... since many mailers don't deal with
- 8-bit data.
-
- Regards,
-
- Bdale Garbee, N3EUA phone: 303/593-9828 h, 303/590-2868 w
- uucp: {bellcore,crash,hp-lsd,hpcsma,ncc,pitt,usafa,vixie}!winfree!bdale
- fido: sysop of 128/19 packet: n3eua @ k0hoa, Colorado Springs
-
- - - - - - - - - - -
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./Makefile`
- then
- echo "writing ./Makefile"
- cat > ./Makefile << '\SHAR\EOF\'
- CFLAGS=-O -DLITTLE_ENDIAN
- all: descalc descycle descert certify radlogin benchmark des uuencode uudecode
-
- des: main.o des.o getpass.o misc.o
- cc -o des main.o des.o getpass.o misc.o
-
- benchmark: benchmark.o des.o
- cc -o benchmark benchmark.o des.o
-
- radlogin: radlogin.o des.o
- cc -o radlogin radlogin.o des.o
-
- descert: descert.o des.o
- cc -o descert descert.o des.o
-
- descalc: descalc.o des.o
- cc -o descalc descalc.o des.o
-
- descycle: descycle.o des.o
- cc -o descycle descycle.o des.o
-
- certify: descert testdata
- descert < testdata
- touch certify
-
- radlogin.o: radlogin.c
- cc -c -O -DUTMP_FILE=\"/etc/utmp\" radlogin.c
-
- uuencode: uuencode.o
- cc -o uuencode uuencode.o
-
- uudecode: uudecode.o
- cc -o uudecode uudecode.o
-
- clean:
- rm -f descalc descycle descert certify radlogin benchmark des *.o
- rm -f uuencode uudecode
- \SHAR\EOF\
- else
- echo "will not over write ./Makefile"
- fi
- if `test ! -s ./README`
- then
- echo "writing ./README"
- cat > ./README << '\SHAR\EOF\'
- Late breaking news:
- Versions of uuencode and uudecode now included, which are helpful
- for using this package to send/receive encrypted mail.
-
- Phil asked me to clean this up slightly and package it for distribution.
- I've got it running on my Symmetric 4.2bsd system, Phil reports it runs fine
- on a variety of systems at Bellcore. Note that getopt is required but not
- provided, as there is already a getopt package in the mod.sources archives.
-
- Bdale Garbee, N3EUA 870401
- winfree!bdale aka bdale%winfree.uucp@flash.bellcore.com
-
- - - - - -
-
- This package contains a DES subroutine library based on the original public
- domain code by James Gillogly, but made faster and more flexible. Commands
- using this library have been added for testing and for encrypting and
- decrypting files (compatible with the DES command under Sun UNIX), among
- other things.
-
- Run make. That will compile everything and run test data (from the NBS
- certification suite) through it. It runs as-is under UNIX. It will run
- under MS-DOS with a few minor changes: make sure you define LITTLE_ENDIAN
- when compiling des.c, and change the name of the console in getpass.c. If
- you have the byte order flag set wrong, you will get ENCRYPT FAIL messages
- when the descert test is run.
-
- radlogin.c is an experimental program for secure UNIX login via insecure
- channels (like amateur packet radio). Make it and set it up as the login
- shell for a special, password-free login (e.g., "radio"). When it starts the
- user will be asked his REAL login name, which is then looked up in
- /etc/rkeys. (This file must be read protected since it contains DES keys).
- The time of day is then printed in hex as a challenge. The user must encrypt
- it using DES and his key and type the answer back. The user may use the
- program "descalc" to perform his local calculation. All this is very clumsy;
- it works, but after all it's only experimental.
-
- Phil Karn, KA9Q
- bellcore!karn aka karn@flash.bellcore.com
-
- - - - - -
- Subject: Re: rkeys file
-
- rkeys:
- karn 0123456789abcdef
- uid des_key_in_hex
-
- - - - - -
- \SHAR\EOF\
- else
- echo "will not over write ./README"
- fi
- if `test ! -s ./benchmark.c`
- then
- echo "writing ./benchmark.c"
- cat > ./benchmark.c << '\SHAR\EOF\'
- /* Just run DES in a loop consuming CPU time; good for benchmarking
- * Phil Karn
- */
- #include <stdio.h>
- main()
- {
- char key[8],work[8];
- long iter,count;
-
- desinit(0);
- printf("Enter key: ");
- get8(key);
- printf("Setting key: "); put8(key); printf("\n");
- setkey(key);
- printf("Enter starting value: ");
- get8(work);
- printf("Starting value: "); put8(work); printf("\n");
- printf("Number of iterations: ");
- scanf("%ld",&count);
-
- for(iter = 0;iter < count; iter++)
- endes(work);
- }
- get8(cp)
- char *cp;
- {
- int i,t;
-
- for(i=0;i<8;i++){
- scanf("%2x",&t);
- *cp++ = t;
- }
- }
- put8(cp)
- char *cp;
- {
- int i;
-
- for(i=0;i<8;i++){
- printf("%2x ",*cp++ & 0xff);
- }
- }
- \SHAR\EOF\
- else
- echo "will not over write ./benchmark.c"
- fi
- if `test ! -s ./des.1`
- then
- echo "writing ./des.1"
- cat > ./des.1 << '\SHAR\EOF\'
- .TH DES 1 "24 March 1987"
- .SH NAME
- des - DES file encryption
- .SH SYNOPSIS
- .PP
- .B des -e|-d [-h] [-k key] [-b]
- .SH DESCRIPTION
- .B des
- is a filter that encrypts or decrypts standard input to standard output
- with the Data Encryption Standard (DES).
- Either -e (encrypt) or -d (decrypt) must be specified. If the key is not
- given on the command line with the -k option the command will prompt for it
- twice, suppressing echo and comparing the two responses to guard against
- mistyping.
- .P
- The -h flag controls how the key string is to be interpreted.
- Without the -h flag, the key is an ASCII string.
- Since DES ignores the low
- order bit of each key byte, the
- high order bit is set for odd parity, thus retaining the information contained
- in the low order bit.
- If the -h flag is set, the key string is interpreted as
- 16 hex/ASCII characters; the low order bit of each byte is again ignored as per
- the DES algorithm.
- This allows the use of any arbitrary 56-bit key, including bytes representing
- control characters that could not be typed if the -h option were not used.
- .PP
- By default, DES Cipher Block Chaining (CBC) mode is used, with an initial
- vector (IV) of all zeros; if the -b option is specified, Electronic Code
- Book (ECB) mode is used instead.
- .PP
- Except for the -h option, this command is compatible with the
- .B des
- command on the Sun Microsystems workstation.
- .SH "SEE ALSO"
- Sun Microsystems DES(1) manual page, which describes in detail how
- the length of the file is encoded in the last block of ciphertext.
- .SH AUTHOR
- Phil Karn, KA9Q
- \SHAR\EOF\
- else
- echo "will not over write ./des.1"
- fi
- if `test ! -s ./des.3`
- then
- echo "writing ./des.3"
- cat > ./des.3 << '\SHAR\EOF\'
- .TH DES 3 "24 March 1987"
- .SH NAME
- desinit, setkey, endes, dedes, desdone - DES encryption
- .SH SYNOPSIS
- .PP
- .B desinit(mode)
- .B int mode;
- .PP
- .B setkey(key)
- .B char *key;
- .PP
- .B endes(block)
- .B char *block;
- .PP
- .B dedes(block)
- .B char *block;
- .PP
- .B desdone()
- .SH DESCRIPTION
- These routines implement both standard and modified forms of the NBS Data
- Encryption Standard (DES). The user must first call
- .B desinit
- with one of three operating modes:
- .PP
- 0 - Standard, vanilla DES.
- .PP
- 1 - DES with the initial and final permutations removed.
- As these permutations do not strengthen the algorithm,
- they are widely regarded as having no purpose other than to slow
- down software implementations.
- Removing them speeds it up but of course the algorithm is no longer standard
- and it will not be compatible with hardware DES chips.
- .PP
- 2 - DES with the initial and final permutations removed, and with independent
- 48-bit subkeys for each of the 16 rounds. Needless to say this is even
- less standard than mode 1, but if properly used (randomize ALL key bytes --
- no padding!) it should strengthen the algorithm.
- .PP
- After calling
- .B desinit
- the user next calls
- .B setkey.
- In modes 0 and 1, 8 key bytes are expected, with the low order bit of
- each key byte ignored (parity is not checked). This gives a 56-bit key.
- In mode 2, 128 key bytes are expected; the high order 2 bits of each byte are
- ignored, giving a 768 bit key.
- In this mode, the first 8 bytes will be used in the first round, the
- second 8 bytes in the second round, and so on.
- .PP
- Once the key is set, the user may perform in-place encryption and decryption
- of 8-byte blocks of data with calls to
- .B endes
- and
- .B dedes.
- .PP
- To free up memory dynamically allocated by
- .B desinit
- the user may call
- .B desdone.
- If further encryption or decryption is to be done,
- .B desinit
- and
- .B setkey
- must be called again.
- .SH AUTHOR
- Phil Karn, KA9Q, building heavily on the earlier public domain code
- by Jim Gillogly.
-
-
- \SHAR\EOF\
- else
- echo "will not over write ./des.3"
- fi
- if `test ! -s ./des.c`
- then
- echo "writing ./des.c"
- cat > ./des.c << '\SHAR\EOF\'
- /* Sofware DES functions
- * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
- * the 1977 public-domain program by Jim Gillogly
- */
- #define NULL 0
-
- #ifdef LITTLE_ENDIAN
- unsigned long byteswap();
- #endif
-
- /* Tables defined in the Data Encryption Standard documents */
-
- /* initial permutation IP */
- static char ip[] = {
- 58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7
- };
-
- /* final permutation IP^-1 */
- static char fp[] = {
- 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25
- };
-
- /* expansion operation matrix
- * This is for reference only; it is unused in the code
- * as the f() function performs it implicitly for speed
- */
- #ifdef notdef
- static char ei[] = {
- 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1
- };
- #endif
-
- /* permuted choice table (key) */
- static char pc1[] = {
- 57, 49, 41, 33, 25, 17, 9,
- 1, 58, 50, 42, 34, 26, 18,
- 10, 2, 59, 51, 43, 35, 27,
- 19, 11, 3, 60, 52, 44, 36,
-
- 63, 55, 47, 39, 31, 23, 15,
- 7, 62, 54, 46, 38, 30, 22,
- 14, 6, 61, 53, 45, 37, 29,
- 21, 13, 5, 28, 20, 12, 4
- };
-
- /* number left rotations of pc1 */
- static char totrot[] = {
- 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
- };
-
- /* permuted choice key (table) */
- static char pc2[] = {
- 14, 17, 11, 24, 1, 5,
- 3, 28, 15, 6, 21, 10,
- 23, 19, 12, 4, 26, 8,
- 16, 7, 27, 20, 13, 2,
- 41, 52, 31, 37, 47, 55,
- 30, 40, 51, 45, 33, 48,
- 44, 49, 39, 56, 34, 53,
- 46, 42, 50, 36, 29, 32
- };
-
- /* The (in)famous S-boxes */
- static char si[8][64] = {
- /* S1 */
- 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
- 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
- 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
- 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
-
- /* S2 */
- 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
- 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
- 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
- 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
-
- /* S3 */
- 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
- 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
- 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
- 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
-
- /* S4 */
- 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
- 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
- 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
- 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
-
- /* S5 */
- 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
- 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
- 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
- 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
-
- /* S6 */
- 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
- 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
- 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
- 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
-
- /* S7 */
- 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
- 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
- 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
- 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
-
- /* S8 */
- 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
- 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
- 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
- 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
- };
-
- /* 32-bit permutation function P used on the output of the S-boxes */
- static char p32i[] = {
- 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25
- };
- /* End of DES-defined tables */
-
- /* Lookup tables initialized once only at startup by desinit() */
- static long (*sp)[64]; /* Combined S and P boxes */
-
- static char (*iperm)[16][8]; /* Initial and final permutations */
- static char (*fperm)[16][8];
-
- /* 8 6-bit subkeys for each of 16 rounds, initialized by setkey() */
- static unsigned char (*kn)[8];
-
- /* bit 0 is left-most in byte */
- static int bytebit[] = {
- 0200,0100,040,020,010,04,02,01
- };
-
- static int nibblebit[] = {
- 010,04,02,01
- };
- static int desmode;
-
- /* Allocate space and initialize DES lookup arrays
- * mode == 0: standard Data Encryption Algorithm
- * mode == 1: DEA without initial and final permutations for speed
- * mode == 2: DEA without permutations and with 128-byte key (completely
- * independent subkeys for each round)
- */
- desinit(mode)
- int mode;
- {
- char *malloc();
-
- if(sp != NULL){
- /* Already initialized */
- return 0;
- }
- desmode = mode;
-
- if((sp = (long (*)[64])malloc(sizeof(long) * 8 * 64)) == NULL){
- return -1;
- }
- spinit();
- kn = (unsigned char (*)[8])malloc(sizeof(char) * 8 * 16);
- if(kn == NULL){
- free((char *)sp);
- return -1;
- }
- if(mode == 1 || mode == 2) /* No permutations */
- return 0;
-
- iperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
- if(iperm == NULL){
- free((char *)sp);
- free((char *)kn);
- return -1;
- }
- perminit(iperm,ip);
-
- fperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
- if(fperm == NULL){
- free((char *)sp);
- free((char *)kn);
- free((char *)iperm);
- return -1;
- }
- perminit(fperm,fp);
-
- return 0;
- }
- /* Free up storage used by DES */
- desdone()
- {
- if(sp == NULL)
- return; /* Already done */
-
- free((char *)sp);
- free((char *)kn);
- if(iperm != NULL)
- free((char *)iperm);
- if(fperm != NULL)
- free((char *)fperm);
-
- sp = NULL;
- iperm = NULL;
- fperm = NULL;
- kn = NULL;
- }
- /* Set key (initialize key schedule array) */
- setkey(key)
- char *key; /* 64 bits (will use only 56) */
- {
- char pc1m[56]; /* place to modify pc1 into */
- char pcr[56]; /* place to rotate pc1 into */
- register int i,j,l;
- int m;
-
- /* In mode 2, the 128 bytes of subkey are set directly from the
- * user's key, allowing him to use completely independent
- * subkeys for each round. Note that the user MUST specify a
- * full 128 bytes.
- *
- * I would like to think that this technique gives the NSA a real
- * headache, but I'm not THAT naive.
- */
- if(desmode == 2){
- for(i=0;i<16;i++)
- for(j=0;j<8;j++)
- kn[i][j] = *key++;
- return;
- }
- /* Clear key schedule */
- for (i=0; i<16; i++)
- for (j=0; j<8; j++)
- kn[i][j]=0;
-
- for (j=0; j<56; j++) { /* convert pc1 to bits of key */
- l=pc1[j]-1; /* integer bit location */
- m = l & 07; /* find bit */
- pc1m[j]=(key[l>>3] & /* find which key byte l is in */
- bytebit[m]) /* and which bit of that byte */
- ? 1 : 0; /* and store 1-bit result */
- }
- for (i=0; i<16; i++) { /* key chunk for each iteration */
- for (j=0; j<56; j++) /* rotate pc1 the right amount */
- pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
- /* rotate left and right halves independently */
- for (j=0; j<48; j++){ /* select bits individually */
- /* check bit that goes to kn[j] */
- if (pcr[pc2[j]-1]){
- /* mask it in if it's there */
- l= j % 6;
- kn[i][j/6] |= bytebit[l] >> 2;
- }
- }
- }
- }
- /* In-place encryption of 64-bit block */
- endes(block)
- char *block;
- {
- register int i;
- unsigned long work[2]; /* Working data storage */
- long tmp;
-
- permute(block,iperm,(char *)work); /* Initial Permutation */
- #ifdef LITTLE_ENDIAN
- work[0] = byteswap(work[0]);
- work[1] = byteswap(work[1]);
- #endif
-
- /* Do the 16 rounds */
- for (i=0; i<16; i++)
- round(i,work);
-
- /* Left/right half swap */
- tmp = work[0];
- work[0] = work[1];
- work[1] = tmp;
-
- #ifdef LITTLE_ENDIAN
- work[0] = byteswap(work[0]);
- work[1] = byteswap(work[1]);
- #endif
- permute((char *)work,fperm,block); /* Inverse initial permutation */
- }
- /* In-place decryption of 64-bit block */
- dedes(block)
- char *block;
- {
- register int i;
- unsigned long work[2]; /* Working data storage */
- long tmp;
-
- permute(block,iperm,(char *)work); /* Initial permutation */
-
- #ifdef LITTLE_ENDIAN
- work[0] = byteswap(work[0]);
- work[1] = byteswap(work[1]);
- #endif
-
- /* Left/right half swap */
- tmp = work[0];
- work[0] = work[1];
- work[1] = tmp;
-
- /* Do the 16 rounds in reverse order */
- for (i=15; i >= 0; i--)
- round(i,work);
-
- #ifdef LITTLE_ENDIAN
- work[0] = byteswap(work[0]);
- work[1] = byteswap(work[1]);
- #endif
-
- permute((char *)work,fperm,block); /* Inverse initial permutation */
- }
-
- /* Permute inblock with perm */
- static
- permute(inblock,perm,outblock)
- char *inblock, *outblock; /* result into outblock,64 bits */
- char perm[16][16][8]; /* 2K bytes defining perm. */
- {
- register int i,j;
- register char *ib, *ob; /* ptr to input or output block */
- register char *p, *q;
-
- if(perm == NULL){
- /* No permutation, just copy */
- for(i=8; i!=0; i--)
- *outblock++ = *inblock++;
- return;
- }
- /* Clear output block */
- for (i=8, ob = outblock; i != 0; i--)
- *ob++ = 0;
-
- ib = inblock;
- for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
- ob = outblock;
- p = perm[j][(*ib >> 4) & 017];
- q = perm[j + 1][*ib & 017];
- for (i = 8; i != 0; i--){ /* and each output byte */
- *ob++ |= *p++ | *q++; /* OR the masks together*/
- }
- }
- }
-
- /* Do one DES cipher round */
- static
- round(num,block)
- int num; /* i.e. the num-th one */
- unsigned long *block;
- {
- long f();
-
- /* The rounds are numbered from 0 to 15. On even rounds
- * the right half is fed to f() and the result exclusive-ORs
- * the left half; on odd rounds the reverse is done.
- */
- if(num & 1){
- block[1] ^= f(block[0],kn[num]);
- } else {
- block[0] ^= f(block[1],kn[num]);
- }
- }
- /* The nonlinear function f(r,k), the heart of DES */
- static
- long
- f(r,subkey)
- unsigned long r; /* 32 bits */
- unsigned char subkey[8]; /* 48-bit key for this round */
- {
- register unsigned long rval,rt;
- #ifdef TRACE
- unsigned char *cp;
- int i;
-
- printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
- r,
- subkey[0], subkey[1], subkey[2],
- subkey[3], subkey[4], subkey[5],
- subkey[6], subkey[7]);
- #endif
- /* Run E(R) ^ K through the combined S & P boxes
- * This code takes advantage of a convenient regularity in
- * E, namely that each group of 6 bits in E(R) feeding
- * a single S-box is a contiguous segment of R.
- */
- rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
- rval = 0;
- rval |= sp[0][((rt >> 26) ^ *subkey++) & 0x3f];
- rval |= sp[1][((rt >> 22) ^ *subkey++) & 0x3f];
- rval |= sp[2][((rt >> 18) ^ *subkey++) & 0x3f];
- rval |= sp[3][((rt >> 14) ^ *subkey++) & 0x3f];
- rval |= sp[4][((rt >> 10) ^ *subkey++) & 0x3f];
- rval |= sp[5][((rt >> 6) ^ *subkey++) & 0x3f];
- rval |= sp[6][((rt >> 2) ^ *subkey++) & 0x3f];
- rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
- rval |= sp[7][(rt ^ *subkey) & 0x3f];
- #ifdef TRACE
- printf(" %08lx\n",rval);
- #endif
- return rval;
- }
- /* initialize a perm array */
- static
- perminit(perm,p)
- char perm[16][16][8]; /* 64-bit, either init or final */
- char p[64];
- {
- register int l, j, k;
- int i,m;
-
- /* Clear the permutation array */
- for (i=0; i<16; i++)
- for (j=0; j<16; j++)
- for (k=0; k<8; k++)
- perm[i][j][k]=0;
-
- for (i=0; i<16; i++) /* each input nibble position */
- for (j = 0; j < 16; j++)/* each possible input nibble */
- for (k = 0; k < 64; k++)/* each output bit position */
- { l = p[k] - 1; /* where does this bit come from*/
- if ((l >> 2) != i) /* does it come from input posn?*/
- continue; /* if not, bit k is 0 */
- if (!(j & nibblebit[l & 3]))
- continue; /* any such bit in input? */
- m = k & 07; /* which bit is this in the byte*/
- perm[i][j][k>>3] |= bytebit[m];
- }
- }
-
- /* Initialize the lookup table for the combined S and P boxes */
- static int
- spinit()
- {
- char pbox[32];
- int p,i,s,j,rowcol;
- long val;
-
- /* Compute pbox, the inverse of p32i.
- * This is easier to work with
- */
- for(p=0;p<32;p++){
- for(i=0;i<32;i++){
- if(p32i[i]-1 == p){
- pbox[p] = i;
- break;
- }
- }
- }
- for(s = 0; s < 8; s++){ /* For each S-box */
- for(i=0; i<64; i++){ /* For each possible input */
- val = 0;
- /* The row number is formed from the first and last
- * bits; the column number is from the middle 4
- */
- rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
- for(j=0;j<4;j++){ /* For each output bit */
- if(si[s][rowcol] & (8 >> j)){
- val |= 1L << (31 - pbox[4*s + j]);
- }
- }
- sp[s][i] = val;
-
- #ifdef DEBUG
- printf("sp[%d][%2d] = %08lx\n",s,i,sp[s][i]);
- #endif
- }
- }
- }
- #ifdef LITTLE_ENDIAN
- /* Byte swap a long */
- static
- unsigned long
- byteswap(x)
- unsigned long x;
- {
- register char *cp,tmp;
-
- cp = (char *)&x;
- tmp = cp[3];
- cp[3] = cp[0];
- cp[0] = tmp;
-
- tmp = cp[2];
- cp[2] = cp[1];
- cp[1] = tmp;
-
- return x;
- }
- #endif
- \SHAR\EOF\
- else
- echo "will not over write ./des.c"
- fi
- if `test ! -s ./descalc.c`
- then
- echo "writing ./descalc.c"
- cat > ./descalc.c << '\SHAR\EOF\'
- /* DES "desk calculator"
- * Phil Karn
- * January 1987
- */
- #include <stdio.h>
- #include <ctype.h>
- main()
- {
- char key[8],work[8];
- char line[80];
- int keyset = 0;
-
- if(desinit(0) == -1){
- printf("DES initialization failed\n");
- exit(1);
- }
- printf("Enter in hexadecimal:\nk <key>\np <plaintext>\nc <ciphertext>\n");
- printf("s - standard DES mode\n");
- printf("f - fast mode (no IP)\n");
- for(;;){
- gets(line);
- if(feof(stdin))
- break;
- if(isupper(line[0]))
- line[0] = tolower(line[0]);
- switch(line[0]){
- case 's':
- desdone();
- desinit(0);
- if(keyset)
- setkey(key);
- break;
- case 'f':
- desdone();
- desinit(1);
- if(keyset)
- setkey(key);
- break;
- case 'k': /* Set key */
- get8(&line[1],key);
- setkey(key);
- keyset = 1;
- break;
- case 'c': /* Decrypt ciphertext */
- if(!keyset){
- printf("Enter key\n");
- break;
- }
- get8(&line[1],work);
- dedes(work);
- printf("Plaintext: ");
- put8(work);
- printf("\n");
- break;
- case 'p': /* Encrypt plaintext */
- if(!keyset){
- printf("Enter key\n");
- break;
- }
- get8(&line[1],work);
- endes(work);
- printf("Ciphertext: ");
- put8(work);
- printf("\n");
- break;
- default:
- printf("eh?\n");
- break;
- }
- }
- }
- get8(buf,cp)
- char *buf;
- register char *cp;
- {
- int ikey[8],i;
-
- sscanf(buf,"%2x%2x%2x%2x%2x%2x%2x%2x",&ikey[0],&ikey[1],&ikey[2],
- &ikey[3],&ikey[4],&ikey[5],&ikey[6],&ikey[7]);
- for(i=0;i<8;i++)
- *cp++ = ikey[i];
- }
- put8(cp)
- register char *cp;
- {
- int i;
-
- for(i=0;i<8;i++){
- printf("%02x ",*cp++ & 0xff);
- }
- }
- \SHAR\EOF\
- else
- echo "will not over write ./descalc.c"
- fi
- if `test ! -s ./descert.c`
- then
- echo "writing ./descert.c"
- cat > ./descert.c << '\SHAR\EOF\'
- #include <stdio.h>
- main()
- {
- char key[8],plain[8],cipher[8],answer[8];
- int i;
- int test;
- int fail;
-
- desinit(0);
-
- for(test=0;!feof(stdin);test++){
-
- get8(key);
- printf(" K: "); put8(key);
- setkey(key);
-
- get8(plain);
- printf(" P: "); put8(plain);
-
- get8(answer);
- printf(" C: "); put8(answer);
-
- for(i=0;i<8;i++)
- cipher[i] = plain[i];
- endes(cipher);
-
- for(i=0;i<8;i++)
- if(cipher[i] != answer[i])
- break;
- fail = 0;
- if(i != 8){
- printf(" Encrypt FAIL");
- fail++;
- }
- dedes(cipher);
- for(i=0;i<8;i++)
- if(cipher[i] != plain[i])
- break;
- if(i != 8){
- printf(" Decrypt FAIL");
- fail++;
- }
- if(fail == 0)
- printf(" OK");
- printf("\n");
- }
- }
- get8(cp)
- char *cp;
- {
- int i,t;
-
- for(i=0;i<8;i++){
- scanf("%2x",&t);
- if(feof(stdin))
- exit(0);
- *cp++ = t;
- }
- }
- put8(cp)
- char *cp;
- {
- int i;
-
- for(i=0;i<8;i++){
- printf("%02x",*cp++ & 0xff);
- }
- }
- \SHAR\EOF\
- else
- echo "will not over write ./descert.c"
- fi
- if `test ! -s ./descycle.c`
- then
- echo "writing ./descycle.c"
- cat > ./descycle.c << '\SHAR\EOF\'
- /* Investigate cycles in DES output feedback mode (experimental)
- * Phil Karn
- */
- #include <stdio.h>
- main()
- {
- char key[8],start[8],work[8];
- long update;
- register int i;
- long iter;
-
- desinit(0);
- printf("Enter key: ");
- get8(key);
- printf("Setting key: "); put8(key); printf("\n");
- setkey(key);
- printf("Enter starting value: ");
- get8(start);
- printf("Starting value: "); put8(start); printf("\n");
- printf("Update interval: ");
- scanf("%ld",&update);
-
- for(i=0;i<8;i++)
- work[i] = start[i];
-
- for(iter = 0;; iter++){
-
- endes(work);
- if((iter % update) == 0){
- printf("%ld ",iter);
- put8(work); printf("\n");
- }
- for(i=0;i<8;i++){
- if(work[i] != start[i])
- break;
- }
- if(i == 8){
- printf("CYCLE FOUND after %ld iterations\n",iter);
- exit(0);
- }
- }
- }
- get8(cp)
- char *cp;
- {
- int i,t;
-
- for(i=0;i<8;i++){
- scanf("%2x",&t);
- *cp++ = t;
- }
- }
- put8(cp)
- char *cp;
- {
- int i;
-
- for(i=0;i<8;i++){
- printf("%2x ",*cp++ & 0xff);
- }
- }
- \SHAR\EOF\
- else
- echo "will not over write ./descycle.c"
- fi
- if `test ! -s ./getopt.c`
- then
- echo "writing ./getopt.c"
- cat > ./getopt.c << '\SHAR\EOF\'
- /* got this off net.sources */
- #include <stdio.h>
-
- /*
- * get option letter from argument vector
- */
- int opterr = 1, /* useless, never set or used */
- optind = 1, /* index into parent argv vector */
- optopt; /* character checked for validity */
- char *optarg; /* argument associated with option */
-
- #define BADCH (int)'?'
- #define EMSG ""
- #define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
- fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
-
- getopt(nargc,nargv,ostr)
- int nargc;
- char **nargv,
- *ostr;
- {
- static char *place = EMSG; /* option letter processing */
- register char *oli; /* option letter list index */
- char *index();
-
- if(!*place) { /* update scanning pointer */
- if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
- if (*place == '-') { /* found "--" */
- ++optind;
- return(EOF);
- }
- } /* option letter okay? */
- if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
- if(!*place) ++optind;
- tell(": illegal option -- ");
- }
- if (*++oli != ':') { /* don't need argument */
- optarg = NULL;
- if (!*place) ++optind;
- }
- else { /* need an argument */
- if (*place) optarg = place; /* no white space */
- else if (nargc <= ++optind) { /* no arg */
- place = EMSG;
- tell(": option requires an argument -- ");
- }
- else optarg = nargv[optind]; /* white space */
- place = EMSG;
- ++optind;
- }
- return(optopt); /* dump back option letter */
- }
- \SHAR\EOF\
- else
- echo "will not over write ./getopt.c"
- fi
- if `test ! -s ./getpass.c`
- then
- echo "writing ./getpass.c"
- cat > ./getpass.c << '\SHAR\EOF\'
- #include <stdio.h>
- #include <signal.h>
- #include <sgtty.h>
-
- #define TTY "/dev/tty" /* Change to "con" for MS-DOS */
-
- /* Issue prompt and read reply with echo turned off */
- char *
- getpass(prompt)
- char *prompt;
- {
- struct sgttyb ttyb,ttysav;
- register char *cp;
- int c;
- FILE *tty;
- static char pbuf[128];
- int (*signal())(),(*sig)();
-
- if ((tty = fdopen(open(TTY, 2), "r")) == NULL)
- tty = stdin;
- else
- setbuf(tty, (char *)NULL);
- sig = signal(SIGINT, SIG_IGN);
- ioctl(fileno(tty), TIOCGETP, &ttyb);
- ioctl(fileno(tty), TIOCGETP, &ttysav);
- ttyb.sg_flags |= RAW;
- ttyb.sg_flags &= ~ECHO;
- ioctl(fileno(tty), TIOCSETP, &ttyb);
- fprintf(stderr, "%s", prompt);
- fflush(stderr);
- cp = pbuf;
- for (;;) {
- c = getc(tty);
- if(c == '\r' || c == '\n' || c == EOF)
- break;
- if (cp < &pbuf[127])
- *cp++ = c;
- }
- *cp = '\0';
- fprintf(stderr,"\r\n");
- fflush(stderr);
- ioctl(fileno(tty), TIOCSETP, &ttysav);
- signal(SIGINT, sig);
- if (tty != stdin)
- fclose(tty);
- return(pbuf);
- }
- \SHAR\EOF\
- else
- echo "will not over write ./getpass.c"
- fi
- if `test ! -s ./main.c`
- then
- echo "writing ./main.c"
- cat > ./main.c << '\SHAR\EOF\'
- /* Encrypt/decrypt command compatible with Sun's "des" command */
- #include <stdio.h>
-
- char iv[8]; /* Initial vector for CBC mode */
- int block;
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int c,cnt,encrypt,decrypt,hexflag;
- register int i;
- char key[8],tkey1[20],tkey2[20],*akey,*getpass();
- extern char *optarg;
-
- hexflag = block = encrypt = decrypt = 0;
- akey = NULL;
- while((c = getopt(argc,argv,"hedk:b")) != EOF){
- switch(c){
- case 'h':
- hexflag++;
- break;
- case 'e':
- encrypt++;
- break;
- case 'd':
- decrypt++;
- break;
- case 'k':
- akey = optarg;
- break;
- case 'b':
- block++;
- break;
- }
- }
- if(encrypt == 0 && decrypt == 0){
- fprintf(stderr,"Usage: des -e|-d [-h] [-k key]\n");
- exit(2);
- }
- if(akey == NULL){
- /* No key on command line, prompt for it */
- memset(tkey1,0,sizeof(tkey1));
- memset(tkey2,0,sizeof(tkey2));
- for(;;){
- akey = getpass("Enter key: ");
- strncpy(tkey1,akey,sizeof(tkey1));
- akey = getpass("Enter key again: ");
- strncpy(tkey2,akey,sizeof(tkey2));
- if(strncmp(tkey1,tkey2,sizeof(tkey1)) != 0){
- fprintf(stderr,"Key mistyped, try again\n");
- } else
- break;
- }
- akey = tkey1;
- }
- if(hexflag){
- for(i=0;i<16;i++){
- if(htoa(akey[i]) == -1){
- fprintf(stderr,"Non-hex character in key\n");
- exit(1);
- }
- }
- gethex(key,akey,8);
- } else {
- strncpy(key,akey,8);
- /* Set up key, determine parity bit */
- for(cnt = 0; cnt < 8; cnt++){
- c = 0;
- for(i=0;i<7;i++)
- if(key[cnt] & (1 << i))
- c++;
- if((c & 1) == 0)
- key[cnt] |= 0x80;
- else
- key[cnt] &= ~0x80;
- }
- }
- /* Blot out original key */
- i = strlen(akey);
- i = (i < 8) ? i : 8;
- memset(akey,0,i);
-
- desinit(0);
- setkey(key);
-
- /* Initialize IV to all zeros */
- memset(iv,0,8);
-
- if(encrypt){
- doencrypt();
- } else {
- dodecrypt();
- }
- }
- /* Encrypt standard input to standard output */
- doencrypt()
- {
- char work[8],*cp,*cp1;
- int cnt,i;
-
- for(;;){
- if((cnt = fread(work,1,8,stdin)) != 8){
- /* Put residual byte count in the last block.
- * Note that garbage is left in the other bytes,
- * if any; this is a feature, not a bug, since it'll
- * be stripped out at decrypt time.
- */
- work[7] = cnt;
- }
- if(!block){
- /* CBC mode; chain in last cipher word */
- cp = work;
- cp1 = iv;
- for(i=8; i!=0; i--)
- *cp++ ^= *cp1++;
- }
- endes(work); /* Encrypt block */
- if(!block){ /* Save outgoing ciphertext for chain */
- memcpy(iv,work,8);
- }
- fwrite(work,1,8,stdout);
- if(cnt != 8)
- break;
- }
- }
- dodecrypt()
- {
- char work[8],nwork[8],ivtmp[8],*cp,*cp1;
- int cnt,i;
-
-
- cnt = fread(work,1,8,stdin); /* Prime the pump */
- for(;;){
- if(!block){ /* Save incoming ciphertext for chain */
- memcpy(ivtmp,work,8);
- }
- dedes(work);
- if(!block){ /* Unchain block, save ciphertext for next */
- cp = work;
- cp1 = iv;
- for(i=8; i!=0; i--){
- *cp++ ^= *cp1++;
- }
- memcpy(iv,ivtmp,8);
- }
- /* Save buffer pending next read */
- memcpy(nwork,work,8);
- /* Try to read next block */
- cnt = fread(work,1,8,stdin);
- if(cnt != 8){ /* Can "only" be 0 if not 8 */
- /* Prev block was last one, write appropriate number
- * of bytes
- */
- cnt = nwork[7];
- if(cnt < 0 || cnt > 7){
- fprintf(stderr,"Corrupted file or wrong key\n");
- } else if(cnt != 0)
- fwrite(nwork,1,cnt,stdout);
- exit(0);
- } else {
- /* Now okay to write previous buffer */
- fwrite(nwork,1,8,stdout);
- }
-
- }
- }
- /* Convert hex/ascii nybble to binary */
- int
- htoa(c)
- char c;
- {
- if(c >= '0' && c <= '9')
- return c - '0';
- if(c >= 'a' && c <= 'f')
- return 10 + c - 'a';
- if(c >= 'A' && c <= 'F')
- return 10 + c - 'A';
- return -1;
- }
- /* Convert bytes from hex/ascii to binary */
- gethex(result,cp,cnt)
- register char *result;
- register char *cp;
- register int cnt;
- {
- while(cnt-- != 0){
- *result = htoa(*cp++) << 4;
- *result++ |= htoa(*cp++);
- }
- }
- #ifdef DEBUG
- put8(cp)
- register char *cp;
- {
- int i;
-
- for(i=0;i<8;i++){
- fprintf(stderr,"%02x ",*cp++ & 0xff);
- }
- }
- #endif
-
- \SHAR\EOF\
- else
- echo "will not over write ./main.c"
- fi
- if `test ! -s ./misc.c`
- then
- echo "writing ./misc.c"
- cat > ./misc.c << '\SHAR\EOF\'
- /* Set block of memory to constant */
- memset(blk,val,size)
- register char *blk;
- register char val;
- register unsigned size;
- {
- while(size-- != 0)
- *blk++ = val;
- }
-
- /* Copy block of memory */
- memcpy(dest,src,size)
- register char *dest,*src;
- register unsigned size;
- {
- while(size-- != 0)
- *dest++ = *src++;
- }
-
- /* Compare two blocks of memory */
- memcmp(a,b,size)
- register char *a,*b;
- register unsigned size;
- {
- while(size-- != 0)
- if(*a++ != *b++)
- return 1;
- return 0;
- }
-
- \SHAR\EOF\
- else
- echo "will not over write ./misc.c"
- fi
- if `test ! -s ./radlogin.c`
- then
- echo "writing ./radlogin.c"
- cat > ./radlogin.c << '\SHAR\EOF\'
- /*
- * Secure packet radio login command. The system first prompts for the
- * user's name. It then generates and sends a unique "challenge" (a 64-bit
- * hexadecimal integer) based on the time of day. The user encrypts
- * this value using the Data Encryption Standard and his private key and
- * type it back to the system. The system also encrypts the challenge
- * with the user's key and compares the two. If they match, he's in.
- *
- * 18 December 1986 Phil Karn, KA9Q
- *
- * mods:
- * 870318 Bdale, N3EUA Add code to run user's .login commands.
- * 870317 Bdale, N3EUA Hacked to remove putenv() by calling execle()
- * instead of execl().
- */
- #include <stdio.h>
- #include <strings.h>
- #include <pwd.h>
- #include <utmp.h>
- #define KEYFILE "/etc/rkeys" /* This file must be read-protected */
- main(argc,argv)
- int argc;
- char *argv[];
- {
- struct passwd *pp,*getpwnam();
- unsigned long t;
- FILE *fp;
- char name[64];
- char key[8];
- char work[8];
- char answer[8];
- char fbuf[64];
- char ibuf[64];
- char home[64];
- char login[64];
- char shell[64];
- char user[64];
- char *keyp;
- char *cp,*tty,*ttyname();
- int i,ikey[8];
- struct utmp utmp;
- char *ep[5]; /* we'll build an environment here */
-
- if((fp = fopen(KEYFILE,"r")) == NULL){
- printf("Can't open key file\n");
- exit(1);
- }
- /* Get user's name and look it up in the database */
- printf("Enter login name: ");
- fgets(ibuf,sizeof(ibuf),stdin);
- if((cp = index(ibuf,'\n')) != NULL)
- *cp = '\0';
- strncpy(name,ibuf,sizeof(name));
- for(;;){
- fgets(fbuf,sizeof(fbuf),fp);
- if(feof(fp)){
- printf("No key for login name\n");
- exit(2);
- }
- if((cp = index(fbuf,'\n')) != NULL)
- *cp = '\0';
- if(strncmp(name,fbuf,strlen(name)) == 0)
- break;
- }
- fclose(fp);
- /* Find the user's DES key */
- if((keyp = index(fbuf,' ')) == NULL){
- printf("Missing key field\n");
- exit(3);
- }
- keyp++;
- /* Initialize DES with the user's key */
- sscanf(keyp,"%2x%2x%2x%2x%2x%2x%2x%2x",
- &ikey[0], &ikey[1], &ikey[2], &ikey[3], &ikey[4], &ikey[5],
- &ikey[6], &ikey[7]);
-
- for(i=0;i<8;i++)
- key[i] = ikey[i];
-
- desinit(0);
- setkey(key);
-
- /* Generate and send the challenge */
- time(&t);
- printf("Challenge: %016x\n",t);
-
- /* Encrypt it locally... */
- for(i=0;i<4;i++)
- work[i] = 0;
- work[4] = t >> 24;
- work[5] = t >> 16;
- work[6] = t >> 8;
- work[7] = t;
- endes(work);
-
- /* ...and see if the user can do the same */
- printf("Response: ");
- for(i=0;i<8;i++){
- scanf("%2x",&t);
- answer[i] = t;
- }
- printf("\n"); /* I like it better with a blank line here - bdale */
- /* Compare the ciphertexts. If they match, he's in */
- for(i=0; i < 8; i++){
- if(work[i] != answer[i]){
- printf("Wrong response\n");
- exit(4);
- }
- }
- if((pp = getpwnam(name)) == NULL){
- printf("login name \"%s\" not in /etc/passwd\n",name);
- exit(4);
- }
- if((fp = fopen(UTMP_FILE,"r+")) == NULL){
- printf("can't open utmp\n");
- exit(4);
- }
- tty = ttyname(0);
- if((cp = rindex(tty,'/')) != NULL)
- tty = cp + 1;
- while(fread((char *)&utmp,sizeof(struct utmp),1,fp),!feof(fp)){
- if(strncmp(utmp.ut_line,tty,8) == 0){
- strncpy(utmp.ut_name,name,8);
- fseek(fp,(long)-sizeof(struct utmp),1);
- fwrite((char *)&utmp,sizeof(struct utmp),1,fp);
- break;
- }
- }
- fclose(fp);
- chdir(pp->pw_dir);
- setregid(pp->pw_gid,pp->pw_gid);
- setreuid(pp->pw_uid,pp->pw_uid);
- if(pp->pw_shell == NULL || *pp->pw_shell == '\0')
- pp->pw_shell = "/bin/ksh";
- sprintf(home,"HOME=%s",pp->pw_dir);
- sprintf(shell,"SHELL=%s",pp->pw_shell);
- sprintf(user,"USER=%s",name);
- sprintf(login,"%s/.login",pp->pw_dir);
- ep[0] = home;
- ep[1] = shell;
- ep[2] = user;
- ep[3] = (char *) NULL;
- execle(pp->pw_shell,"-",0,ep);
- printf("Exec failed\n");
- }
- \SHAR\EOF\
- else
- echo "will not over write ./radlogin.c"
- fi
- if `test ! -s ./rkeys.format`
- then
- echo "writing ./rkeys.format"
- cat > ./rkeys.format << '\SHAR\EOF\'
- >From bellcore!karn@flash.bellcore.com Sat Mar 14 23:48:50 1987
- Received: by flash.bellcore.com (4.12/4.7)
- id AA13633; Sat, 14 Mar 87 00:05:44 est
- Date: Sat, 14 Mar 87 00:05:44 est
- From: karn@flash.bellcore.com (Phil R. Karn)
- Message-Id: <8703140505.AA13633@flash.bellcore.com>
- To: bdale@winfree.UUCP
- Subject: Re: rkeys file
- Status: R
-
- rkeys:
- karn 0123456789abcdef
- uid des_key_in_hex
-
- Phil
-
- \SHAR\EOF\
- else
- echo "will not over write ./rkeys.format"
- fi
- if `test ! -s ./testdata`
- then
- echo "writing ./testdata"
- cat > ./testdata << '\SHAR\EOF\'
- 0000000000000000 0000000000000000 8CA64DE9C1B123A7
- FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58
- 3000000000000000 1000000000000001 958E6E627A05557B
- 1111111111111111 1111111111111111 F40379AB9E0EC533
- 0123456789ABCDEF 1111111111111111 17668DFC7292532D
- 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD
- 0000000000000000 0000000000000000 8CA64DE9C1B123A7
- FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4
- 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
- 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100
- 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606
- E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7
- 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451
- FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE
- 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D
- FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2
- \SHAR\EOF\
- else
- echo "will not over write ./testdata"
- fi
- if `test ! -s ./uudecode.c`
- then
- echo "writing ./uudecode.c"
- cat > ./uudecode.c << '\SHAR\EOF\'
- /* uudecode.c - convert ascii-encoded files back to their original form
- * Usage: uudecode [infile]
- *
- * This command differs from the regular UNIX one in that the embedded
- * file name "/dev/stdout" is recognized, allowing it to be used in a pipeline
- *
- * Written and placed in the public domain by Phil Karn, KA9Q 31 March 1987
- */
- #include <stdio.h>
- #define LINELEN 80
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char linebuf[LINELEN],*index(),*fgets();
- register char *cp;
- int linelen,i;
- FILE *in,*out;
-
- if(argc > 1){
- if((in = fopen(argv[1],"r")) == NULL){
- fprintf(stderr,"Can't read %s\n",argv[1]);
- exit(1);
- }
- } else
- in = stdin;
-
- /* Find begin line */
- while(fgets(linebuf,LINELEN,in) != NULL){
- if((cp = index(linebuf,'\n')) != NULL)
- *cp = '\0';
- if(strncmp(linebuf,"begin",5) == 0)
- break;
- }
- if(feof(in)){
- fprintf(stderr,"No begin found\n");
- exit(1);
- }
- /* Find beginning of file name */
- cp = &linebuf[6];
- if((cp = index(cp,' ')) != NULL)
- cp++;
- /* Set up output stream */
- if(cp == NULL || strcmp(cp,"/dev/stdout") == 0){
- out = stdout;
- } else if((out = fopen(cp,"w")) == NULL){
- fprintf(stderr,"Can't open %s\n",cp);
- exit(1);
- }
- /* Now crunch the input file */
- while(fgets(linebuf,LINELEN,in) != NULL){
- linelen = linebuf[0] - ' ';
- if(linelen == 0 || strncmp(linebuf,"end",3) == 0)
- break;
- for(cp = &linebuf[1];linelen > 0;cp += 4){
- for(i=0;i<4;i++)
- cp[i] -= ' ';
- putc((cp[0] << 2) | ((cp[1] >> 4) & 0x3),out);
- if(--linelen > 0)
- putc((cp[1] << 4) | ((cp[2] >> 2) & 0xf),out);
- if(--linelen > 0)
- putc((cp[2] << 6) | cp[3],out);
- linelen--;
- }
- }
- fclose(out);
- }
-
- \SHAR\EOF\
- else
- echo "will not over write ./uudecode.c"
- fi
- if `test ! -s ./uuencode.c`
- then
- echo "writing ./uuencode.c"
- cat > ./uuencode.c << '\SHAR\EOF\'
- /* uuencode.c - convert files to ascii-encoded form
- * Usage: uuencode [filename] < infile
- *
- * If [filename] isn't specified, "/dev/stdout" is the default. This allows
- * use of my uudecode as a pipeline filter.
- *
- * Written and placed in the public domain by Phil Karn, KA9Q
- * 31 March 1987
- */
- #include <stdio.h>
- #define LINELEN 45
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char linebuf[LINELEN];
- register char *cp;
- int linelen;
-
- if(argc > 1)
- printf("begin 0666 %s\n",argv[1]);
- else
- printf("begin 0666 /dev/stdout\n");
- for(;;){
- linelen = fread(linebuf,1,LINELEN,stdin);
- if(linelen <= 0)
- break;
- putchar(' ' + linelen); /* Record length */
- for(cp = linebuf; cp < &linebuf[linelen]; cp += 3){
- putchar(' ' + ((cp[0] >> 2) & 0x3f));
- putchar(' ' + (((cp[0] << 4) & 0x30) | ((cp[1] >> 4) & 0xf)));
- putchar(' ' + (((cp[1] << 2) & 0x3c) | ((cp[2] >> 6) & 0x3)));
- putchar(' ' + (cp[2] & 0x3f));
- }
- putchar('\n');
- }
- printf(" \n"); /* 0-length null record */
- printf("end\n");
- }
-
- \SHAR\EOF\
- else
- echo "will not over write ./uuencode.c"
- fi
- echo "Finished archive 1 of 1"
- exit
-
-
-
-