J
James Leddy
For some reason, I get a segmentation fault when I exit this program I made.
Most of the time when I have seen this it has occured in the middle of the
program and the program terminates. However, in this instance, the program
gets a segmentation fault on exit.
I already posted this question, but people were asking for some code, so
here it is:
#define DWORD unsigned long
/* called from main() */
int extract(struct tm *date) {
FILE *journ;
DWORD full_date;
DWORD tmp_date;
DWORD index_size;
DWORD index_offset;
DWORD sear_size;
DWORD *index;
DWORD *bsear;
DWORD *esear;
DWORD *psear;
DWORD header[2];
size_t pwd_len;
int extra;
char *raw_buf;
char *clear_buf;
char **pwd;
char *zerout;
char chk[16];
full_date = ((date->tm_year) << 16) | ((date->tm_mon) << 8)
| (date->tm_mday);
journ = fopen(FNAME, "r");
if (fread(chk, 1, 16, journ) == 0)
return FILE_ERROR;
if (memcmp(chk, "EncryptedJournal", 16))
return FILE_ERROR;
fread(&index_offset, sizeof(index_offset), 1, journ);
fseek(journ, index_offset, SEEK_SET);
fread(&index_size, sizeof(index_size), 1, journ);
if ((index = malloc((index_size) * sizeof(*index))) == NULL)
return ERROR;
fread(index, sizeof(*index), index_size, journ);
bsear = index;
esear = index + (index_size - 1);
if (index_size == 1) {
psear = index;
fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
for (sear_size = index_size; sear_size > 2;
sear_size = (esear - bsear) + 1) {
if (tmp_date < full_date)
psear = bsear + (sear_size / 2);
else
psear = esear - (sear_size/2);
fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date == full_date) {
break;
} else if (tmp_date < full_date) {
bsear = psear;
} else if (tmp_date > full_date) {
esear = psear;
}
}
if (sear_size == 2) {
fseek(journ, *bsear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date != full_date) {
fseek(journ, *esear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
}
if (tmp_date != full_date)
return DATE_ERROR;
fread(header, sizeof(*header), 2, journ);
if ((raw_buf = malloc(header[0])) == NULL)
return ERROR;
fread(raw_buf, sizeof(*raw_buf), header[0], journ);
if ((pwd = malloc(1)) == NULL)
return ERROR;
*pwd = NULL;
if ((pwd_len = get_pwd(pwd)) == ERROR) {
printf("Passwords don't match\nSorry =(\n");
free(*pwd);
free(pwd);
return ERROR;
}
if (initialize_blowfish(*pwd, pwd_len) == ERROR) {
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);
return ERROR;
}
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);
extra = decipher(raw_buf, header[0]);
header[0] -= extra;
if ((raw_buf = realloc(raw_buf, header[0])) == NULL)
return ERROR;
if ((clear_buf = malloc(header[1])) == NULL)
return ERROR;
uncompress(clear_buf, (header + 1), raw_buf, header[0]);
fwrite(clear_buf, 1, header[1], stdout);
free(raw_buf);
free(clear_buf);
free(index);
return SUCCESS;
}
/* called from main() */
int conv_str_date(struct tm *result, char *date)
{
char *number;
long int tmp;
//month
if ((number = strtok(date, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 0) || (tmp > 12))
return ERROR;
result->tm_mon = tmp - 1;
//day
if ((number = strtok(NULL, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 1) || (tmp > 31))
return ERROR;
result->tm_mday = tmp;
//year
if ((number = strtok(NULL, "\0")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
tmp-=1900;
if (tmp < 0)
return ERROR;
result->tm_year = tmp;
return 1;
}
/* called from extract() */
int get_pwd(char **pwd)
{
struct termios old, new;
char **check;
char *s;
char *zerout;
int i;
size_t scheck = 0;
size_t spwd = 0;
if ((check = malloc(1)) == NULL)
return ERROR;
*check = NULL;
if (tcgetattr(fileno(stdin), &old) != 0)
return ERROR;
new = old;
new.c_lflag &= ~ECHO;
if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
return ERROR;
for (i = 0; i < 3; i++) {
printf("Password: ");
getline(pwd, &spwd, stdin);
printf("\nAgain: ");
getline(check, &scheck, stdin);
if (!strcmp(*pwd, *check))
break;
printf("\nPasswords don't match\n");
}
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
if ((zerout = calloc(scheck, 1)) == NULL)
return ERROR;
printf("\n");
memcpy(*check, zerout, scheck);
scheck = 0;
free(*check);
free(check);
free(zerout);
if (i == 3) {
if ((zerout = calloc(spwd, 1)) == NULL)
return ERROR;
memcpy(*pwd, zerout, spwd);
return ERROR;
free(zerout);
}
assert((s = strchr(*pwd, (int)'\n')) != NULL);
*s = 0; //we don't want the newlinet in our password!!
return strlen(*pwd);
}
void decipher_dword(void *al, void *ar)
{
DWORD *temp, *xl, *xr;
int i;
xl = al;
xr = ar;
for (i = N + 1; i > 1; i--) {
*xl = *xl ^ P;
*xr = f(xl) ^ *xr;
SWAP(*xl, *xr, *temp);
}
SWAP(*xl, *xr, *temp);
*xr = *xr ^ P[1];
*xl = *xl ^ P[0];
}
int decipher(char *buf, size_t size)
{
div_t fix;
int i;
char *pbuf;
DWORD value;
fix = div(size, 8);
assert (fix.rem == 0);
for (i = 0; i < fix.quot; i++) {
pbuf = buf + (i * 8);
decipher_dword(pbuf, pbuf + 4);
}
if ((value = buf[size -1]) < 8)
return value;
return 0;
}
I know it's a lot, that is why I did not want to post it in the first place.
Thanks again,
James Leddy
Most of the time when I have seen this it has occured in the middle of the
program and the program terminates. However, in this instance, the program
gets a segmentation fault on exit.
I already posted this question, but people were asking for some code, so
here it is:
#define DWORD unsigned long
/* called from main() */
int extract(struct tm *date) {
FILE *journ;
DWORD full_date;
DWORD tmp_date;
DWORD index_size;
DWORD index_offset;
DWORD sear_size;
DWORD *index;
DWORD *bsear;
DWORD *esear;
DWORD *psear;
DWORD header[2];
size_t pwd_len;
int extra;
char *raw_buf;
char *clear_buf;
char **pwd;
char *zerout;
char chk[16];
full_date = ((date->tm_year) << 16) | ((date->tm_mon) << 8)
| (date->tm_mday);
journ = fopen(FNAME, "r");
if (fread(chk, 1, 16, journ) == 0)
return FILE_ERROR;
if (memcmp(chk, "EncryptedJournal", 16))
return FILE_ERROR;
fread(&index_offset, sizeof(index_offset), 1, journ);
fseek(journ, index_offset, SEEK_SET);
fread(&index_size, sizeof(index_size), 1, journ);
if ((index = malloc((index_size) * sizeof(*index))) == NULL)
return ERROR;
fread(index, sizeof(*index), index_size, journ);
bsear = index;
esear = index + (index_size - 1);
if (index_size == 1) {
psear = index;
fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
for (sear_size = index_size; sear_size > 2;
sear_size = (esear - bsear) + 1) {
if (tmp_date < full_date)
psear = bsear + (sear_size / 2);
else
psear = esear - (sear_size/2);
fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date == full_date) {
break;
} else if (tmp_date < full_date) {
bsear = psear;
} else if (tmp_date > full_date) {
esear = psear;
}
}
if (sear_size == 2) {
fseek(journ, *bsear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date != full_date) {
fseek(journ, *esear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
}
if (tmp_date != full_date)
return DATE_ERROR;
fread(header, sizeof(*header), 2, journ);
if ((raw_buf = malloc(header[0])) == NULL)
return ERROR;
fread(raw_buf, sizeof(*raw_buf), header[0], journ);
if ((pwd = malloc(1)) == NULL)
return ERROR;
*pwd = NULL;
if ((pwd_len = get_pwd(pwd)) == ERROR) {
printf("Passwords don't match\nSorry =(\n");
free(*pwd);
free(pwd);
return ERROR;
}
if (initialize_blowfish(*pwd, pwd_len) == ERROR) {
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);
return ERROR;
}
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);
extra = decipher(raw_buf, header[0]);
header[0] -= extra;
if ((raw_buf = realloc(raw_buf, header[0])) == NULL)
return ERROR;
if ((clear_buf = malloc(header[1])) == NULL)
return ERROR;
uncompress(clear_buf, (header + 1), raw_buf, header[0]);
fwrite(clear_buf, 1, header[1], stdout);
free(raw_buf);
free(clear_buf);
free(index);
return SUCCESS;
}
/* called from main() */
int conv_str_date(struct tm *result, char *date)
{
char *number;
long int tmp;
//month
if ((number = strtok(date, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 0) || (tmp > 12))
return ERROR;
result->tm_mon = tmp - 1;
//day
if ((number = strtok(NULL, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 1) || (tmp > 31))
return ERROR;
result->tm_mday = tmp;
//year
if ((number = strtok(NULL, "\0")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
tmp-=1900;
if (tmp < 0)
return ERROR;
result->tm_year = tmp;
return 1;
}
/* called from extract() */
int get_pwd(char **pwd)
{
struct termios old, new;
char **check;
char *s;
char *zerout;
int i;
size_t scheck = 0;
size_t spwd = 0;
if ((check = malloc(1)) == NULL)
return ERROR;
*check = NULL;
if (tcgetattr(fileno(stdin), &old) != 0)
return ERROR;
new = old;
new.c_lflag &= ~ECHO;
if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
return ERROR;
for (i = 0; i < 3; i++) {
printf("Password: ");
getline(pwd, &spwd, stdin);
printf("\nAgain: ");
getline(check, &scheck, stdin);
if (!strcmp(*pwd, *check))
break;
printf("\nPasswords don't match\n");
}
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
if ((zerout = calloc(scheck, 1)) == NULL)
return ERROR;
printf("\n");
memcpy(*check, zerout, scheck);
scheck = 0;
free(*check);
free(check);
free(zerout);
if (i == 3) {
if ((zerout = calloc(spwd, 1)) == NULL)
return ERROR;
memcpy(*pwd, zerout, spwd);
return ERROR;
free(zerout);
}
assert((s = strchr(*pwd, (int)'\n')) != NULL);
*s = 0; //we don't want the newlinet in our password!!
return strlen(*pwd);
}
void decipher_dword(void *al, void *ar)
{
DWORD *temp, *xl, *xr;
int i;
xl = al;
xr = ar;
for (i = N + 1; i > 1; i--) {
*xl = *xl ^ P;
*xr = f(xl) ^ *xr;
SWAP(*xl, *xr, *temp);
}
SWAP(*xl, *xr, *temp);
*xr = *xr ^ P[1];
*xl = *xl ^ P[0];
}
int decipher(char *buf, size_t size)
{
div_t fix;
int i;
char *pbuf;
DWORD value;
fix = div(size, 8);
assert (fix.rem == 0);
for (i = 0; i < fix.quot; i++) {
pbuf = buf + (i * 8);
decipher_dword(pbuf, pbuf + 4);
}
if ((value = buf[size -1]) < 8)
return value;
return 0;
}
I know it's a lot, that is why I did not want to post it in the first place.
Thanks again,
James Leddy