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 */
|