Cover V08, I01
Article
Listing 1
Listing 2
Listing 3
Sidebar 1

jan99.tar


Listing 3: get_char.c

 * This function calls the function ret_char until the carriage 
 * return is pressed or until len is reached.
 * Use this in a shell script as such: 
 * xvar=`get_char`
 */
#include <stdio.h>
#include <termio.h>
#include <fcntl.h>
     
main()
{
char password[22];
int i=0, c, len=20;
     
while (1)
   {
   c = ret_char();
   if(c == '\r' || c == '\n' || c == -1 || c == 3)
      break;
   password[i++] = c;
   if(i > len)
      break;
   }
password[i] = '\0';
printf("%s\n", password);
}
     
/*
 * coffin.c: author Ed Schaefer:
 * 
 * Encrypt:
 * Usage:
 *   coffin -e {password} {key}
 *      
 * Decrypt:
 * Usage:
 *   coffin -d {password}
 */
#include <stdio.h>
     
/* encode 1 character */ 
#define ENC(c) (((c) & 077) + ' ')
/* decode 1 character */ 
#define DEC(c)  (((c) - ' ') & 077)
#define CRC_16 0x1021
#define UNIX_SW 1
#define MODVAL 100000
#define MODLEN 5
#define REC_LEN 80
#define PASSLEN 15
unsigned long compute_crc();
void parse_password();
FILE *open_file();
     
main(argc, argv)
int  argc;
char *argv[];
{
   char *key, *password;  
   char *file_name="./encrypt.fil";
   char *key_file="./key.fil";
   char newincode[80]; 
   char outcode[80];
   char crc_code[8];
   char key_string[25];
   int stopit, len;
   FILE *fh;
     
   switch (argv[1][0])
     {
     case '-':  
       switch (argv[1][1])
         {
         case 'e':  /* ENCRYPT  */
            if(geteuid() != 0 && UNIX_SW)
               {
               printf("Only root can encrypt with Coffin\n"); 
               exit(1);
               }
            if(argc != 4) 
               exit(1); /* terminate without proper arguments */
            password=argv[2];  
            key=argv[3];  
            if((len = strlen(password)) > PASSLEN)
               {
               perror("password too long");
               exit(1);
               }
            /* save the key to a file */
            if((fh=open_file(key_file, "w", 1)) == NULL)
               exit(1);
            fprintf(fh,"%s", key);
            fclose(fh);
            /* encode the password */
            encode(password, strlen(password), outcode, key); 
            if((fh=open_file(file_name, "w", 1)) == NULL)
               exit(1);
            fprintf(fh,"%s\n", outcode);
            fclose(fh);
            break;
     
         case 'd':  /* DECRYPT  */
            if(argc != 3) 
               exit(1); /* terminate without proper arguments */
            password=argv[2];  
            /* read the key from key.fil*/
            if((fh=open_file(key_file, "r", 1)) == NULL)
               exit(1);
            fgets(key_string, REC_LEN, fh);
            fclose(fh);
            /* read the cipher text from encypt.fil */ 
            if((fh=open_file(file_name, "r", 1)) == NULL)
               exit(1);
            fgets(outcode, REC_LEN, fh);
            fclose(fh);
            decode(newincode, outcode, key_string); 
            parse_password(newincode, crc_code); 
            if(compute_crc(newincode, strlen(newincode)) != 
atol(crc_code)) 
               { /* if bad CRC, error out */
               if(UNIX_SW)
                  crc_error("root");
               exit(1);
               }
            if(strcmp(password, newincode) == 0)
               exit(0);   /* Good password */
            else
               exit(1);   /* Bad password */
            break;
     
            default: /* illegal flag */
               exit(1);
         }
         default: /* no flag */
            exit(1);
       }
       exit(1);  /* no flag */
     }
     
/*
 * This function:
 * 1) obtains the CRC of the plaintext password, 'in'
 * 2) appends the last MODVAL characters to the end of the 
 *    password
 * 3) encode the password with the xor function
 * 4) change the encoded string 'newstr' to ascii with 
 *    a call to uuencode function
 * 5) return the encoded string 'out' 
 */
encode(in, inlen, out, key)
char *in;
int inlen;  /* length of string to encode */ 
char *out;  /* encoded string */
char *key;  
{
   char newstr[80], crcstr[9];
   int i, offset;
     
   /* save the last MODLEN characters of the crc */ 
   sprintf(crcstr,"%05u", compute_crc(in, inlen) ); 
   strcpy(newstr, in); 
   strcat(newstr, crcstr); 
   xor(newstr, key); 
   /* and bump the string by MODLEN */
   inlen += MODLEN;
   offset=0; 
   for (i=0; i<(inlen+4); i += 3)
      uuencode(&newstr[i], out, &offset);
   out[offset] = '\0';
}
     
/*
 * this function encodes a group of 3 bytes to 4 bytes
 * return the 'in' string, the 'out' string, and the offset 
 */
uuencode(in, out, offset)
char *in;
char *out;
int *offset; 
{
   int c1, c2, c3, c4, i;
     
   i=*offset;
   c1 = in[0] >> 2;
   c2 = (in[0] << 4) & 060 | (in[1] >> 4) & 017; 
   c3 = (in[1] << 2) & 074 | (in[2] >> 6) & 03; 
   c4 = in[2] & 077;
   out[i++]=ENC(c1);
   out[i++]=ENC(c2);
   out[i++]=ENC(c3);
   out[i++]=ENC(c4);
   *offset = i;
}
     
/*
 * this function decodes a group of 4 bytes to 3 bytes
 * return the 'in' string, the 'out' string, and the offset 
 */
uudecode(out, in, offset)
char *out;
char *in;
int *offset;
{
   int c1, c2, c3, i;
     
   i=*offset;
   c1 = DEC(out[0]) << 2 | DEC(out[1]) >> 4; 
   c2 = DEC(out[1]) << 4 | DEC(out[2]) >> 2; 
   c3 = DEC(out[2]) << 6 | DEC(out[3]); 
   in[i++]=c1;
   in[i++]=c2;
   in[i++]=c3;
   *offset = i;
}
     
/*
 * this function:
 * 1) changes the encoded string 'incode' to ascii with 
 *    a call to uudecode function
 * 2) decodes the password with the xor function
 * 3) returns string 'outcode' is the decoded password with CRC 
 */
decode(incode, outcode, key)
char *incode;  /* encoded string */
char *outcode; /* decoded string */
char *key;
{
    int i, offset, lens;
     
    offset=0;
    lens=strlen(outcode);
    for (i=0; i<lens; i += 4)
       uudecode(&outcode[i], incode, &offset);
    incode[lens+1]='\0';
    xor(incode, key); 
}
     
/*
 * encode/decode 'str' with 'key' using the XOR 
 * algorithm
 */
xor(str, key)
char *str;
char *key;
{
   char *keys;
   int str_len, while_len;
     
   while_len = PASSLEN + (PASSLEN/3) + 1; 
   str_len=while_len;
   keys=key; 
   while(while_len)
       {
       if(!*keys)
          keys=key; 
       *(str++) ^= *(keys++);
       while_len--;
       }
    str[str_len+1]='\0'; 
}
     
/*
 * return the 16-bit crc of string 'string', 
 * but return just MODVAL characters.
 */
unsigned long compute_crc(string)
char *string;
{
   int i, j;
   unsigned int accum, accumtot=0;
   unsigned long item;
     
   for(j=0; j < strlen(string); j++)
      {
      accum=0;
      item = string[j];
      item <<= 1;
      for(i=8; i>0; i--)
         {
         item >>= 1;
         if((item ^ accum) & 0x0001)
            accum = (accum >> 1) ^ CRC_16;
         else
            accum >>= 1;
         }
      accumtot += accum;
      }
   return(accumtot % MODVAL);
}
     
/*
 * This function returns the password and
 * the crc.  The crc is the last MODLEN characters 
 * of the string 'pass_str'
 */
void parse_password(pass_str, crc_code) 
char *pass_str, *crc_code;
{
   int i, x, len;
     
   x=0;
   len = strlen(pass_str) - MODLEN;
   for(i=len; *(pass_str + i) != '\0'; i++)
      *(crc_code + x++) = *(pass_str + i);
   *(crc_code + x) = '\0';
   *(pass_str + len) = '\0';
}
     
/*
 * This function opens 'filename' with 'ttype' being 
 *  'r' for read or 'w' for write.  If there is an open error and 
 * 'exit flag' is true terminate else return the FILE pointer.
 */
FILE *open_file(filename, ttype, exit_flag) 
char *filename;  /* file name to open */
char *ttype;     /* type: r for read, w for write */ 
int exit_flag;   /* if true and error, terminate */ 
{
   FILE *f;
     
   if((f = fopen(filename, ttype)) == NULL)
     {
     fprintf(stderr,"can NOT open %s file\n", filename); 
     if(exit_flag)
        exit(1);
     }
   return f;
}
     
/*
 * Unix bad CRC function: e-mail to user_id 
 */
int crc_error(user_id)
char *user_id;
{
   char mail_com[30];
   FILE *ptr;
     
   strcpy(mail_com, "mailx ");
   strcat(mail_com, user_id);
   if((ptr = popen(mail_com, "w")) == NULL)
      perror("couldn't open mail pipe");
   fprintf(ptr,"%s\n", "Security Breach.  Bad CRC for COFFIN"); 
   fclose(ptr);
}
     
     

/* End of File */