2023-05-21 23:05:39 +00:00
|
|
|
#include <stdio.h> // printf
|
|
|
|
#include <string.h> // memcpy
|
|
|
|
#include <unistd.h> // getopt
|
2023-06-19 08:56:49 +00:00
|
|
|
#include <libgen.h> // dirname/basename
|
|
|
|
#include <limits.h> // realpath
|
|
|
|
#include <stdlib.h> // realpath
|
2023-05-21 23:05:39 +00:00
|
|
|
|
|
|
|
#ifdef USE_SYSLOG
|
|
|
|
#include <syslog.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "hasher.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "main.h"
|
2023-06-19 08:56:49 +00:00
|
|
|
#include "manipulations.h"
|
2023-05-21 23:05:39 +00:00
|
|
|
|
|
|
|
#define PATHBUF 4097
|
|
|
|
#define BUFLEN 2048
|
|
|
|
|
|
|
|
int run_verbose = 0;
|
|
|
|
int run_terse = 0;
|
|
|
|
int force_print_parameters = 0;
|
|
|
|
|
|
|
|
|
2023-06-19 08:56:49 +00:00
|
|
|
FILE * get_outfile(FILE *infile, const char * filepath){
|
|
|
|
FILE* outfile;
|
|
|
|
if(infile == stdin){
|
|
|
|
outfile = stdout;
|
|
|
|
} else {
|
|
|
|
//Taken from man dirname(3)
|
|
|
|
|
|
|
|
const char * extension = ".aux";
|
|
|
|
size_t extlen = sizeof(extension);
|
|
|
|
char * filepath2 = realpath(filepath, NULL);
|
|
|
|
if(run_verbose){
|
|
|
|
printf("Realpath for infile is %s\n", filepath2);
|
|
|
|
}
|
|
|
|
size_t outpathlen = strlen(filepath2) + 3 + extlen;
|
|
|
|
char * outpath = (char*)malloc(outpathlen);
|
|
|
|
char *dirc = strdup(filepath2);
|
|
|
|
char *basec = strdup(filepath2);
|
|
|
|
char *dir = dirname(dirc);
|
|
|
|
char *base = basename(basec);
|
|
|
|
int pathlen;
|
|
|
|
snprintf(outpath, outpathlen, "%s/.%s%s", dir, base, extension);
|
|
|
|
free(dirc);
|
|
|
|
free(basec);
|
|
|
|
free(filepath2);
|
|
|
|
if(run_verbose){
|
|
|
|
printf("Committing hash to auxiliary file %s\n", outpath);
|
|
|
|
}
|
|
|
|
(void)pathlen;
|
|
|
|
outfile = fopen(outpath, "w");
|
|
|
|
}
|
|
|
|
return outfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Give blocks of data to the message digest algorithm.
|
|
|
|
*/
|
|
|
|
size_t digest_file(FILE * infile){
|
|
|
|
|
|
|
|
/*
|
|
|
|
Set up input buffers
|
|
|
|
*/
|
|
|
|
// unsigned char * in stores the unsigned version of signin
|
|
|
|
unsigned char * in = (unsigned char*)malloc(BUFLEN * sizeof *in);
|
|
|
|
/* End set up buffers*/
|
|
|
|
|
|
|
|
size_t bytesdigested = 0;
|
|
|
|
unsigned int round = 0;
|
|
|
|
while(!feof(infile) && !ferror(infile)){
|
|
|
|
round++;
|
|
|
|
size_t bytesread = fread((unsigned char*)in, sizeof(char), sizeof(char) * BUFLEN, infile);
|
|
|
|
if(bytesread==0){
|
|
|
|
verb("0 bytes read, breaking");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
digest_part(in, bytesread);
|
|
|
|
bytesdigested += bytesread;
|
|
|
|
verb("Passed %lu bytes to digest algorithm in round %u, %lu bytes passed so far", bytesread, round, bytesdigested);
|
|
|
|
}
|
|
|
|
if(run_verbose){
|
|
|
|
printf("Input:\n\t");
|
|
|
|
for(int i = 0; i < bytesdigested; i++){
|
|
|
|
printf("%02x ", in[i]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
free(in);
|
|
|
|
return bytesdigested;
|
2023-05-21 23:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *const argv[]){
|
|
|
|
|
|
|
|
#ifdef USE_SYSLOG
|
|
|
|
openlog(PROGNAME, 0, LOG_USER);
|
|
|
|
#endif
|
|
|
|
|
2023-06-19 08:56:49 +00:00
|
|
|
char *filepath = (char*)malloc(PATHBUF * sizeof *filepath);
|
|
|
|
|
|
|
|
int opt;
|
2023-05-21 23:05:39 +00:00
|
|
|
while((opt = getopt(argc, argv, "vhtpf:")) != -1) {
|
|
|
|
switch(opt){
|
|
|
|
case 'v':
|
|
|
|
run_verbose = 1;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
print_help();
|
|
|
|
return 0;
|
|
|
|
case 't':
|
|
|
|
run_terse = 1;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
force_print_parameters = 1;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
memcpy(filepath, optarg, strlen(optarg));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Literally how could you pass an unspecified argument to this program");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Print run parameters at startup
|
|
|
|
*/
|
|
|
|
if(force_print_parameters) {
|
|
|
|
if(run_terse && run_verbose){
|
|
|
|
printf(PROGNAME " called with arguments to run both tersely and verbosely, the author legitimately cannot tell what you want her to do\n");
|
|
|
|
} else if(run_terse) {
|
|
|
|
printf(PROGNAME " will run tersely\n");
|
|
|
|
} else if(run_verbose) {
|
|
|
|
printf(PROGNAME " will run verbosely\n");
|
|
|
|
}
|
|
|
|
if(!run_terse){
|
|
|
|
if(filepath != NULL){
|
|
|
|
printf(PROGNAME " will read input from file %s\n", filepath);
|
|
|
|
} else {
|
|
|
|
printf(PROGNAME " will read input from standard input\n");
|
|
|
|
}
|
|
|
|
}
|
2023-06-19 08:56:49 +00:00
|
|
|
}
|
2023-05-21 23:05:39 +00:00
|
|
|
|
2023-06-19 08:56:49 +00:00
|
|
|
if(!init_hasher()){
|
2023-05-21 23:05:39 +00:00
|
|
|
log(LOG_INFO, "Error encountered while initializing hasher");
|
|
|
|
}
|
|
|
|
|
|
|
|
begin_digest();
|
|
|
|
|
|
|
|
/*
|
|
|
|
Set up the input stream
|
|
|
|
Try to open file pointed to by filepath, or else use stdin
|
2023-06-19 08:56:49 +00:00
|
|
|
*/
|
2023-05-21 23:05:39 +00:00
|
|
|
FILE * infile;
|
|
|
|
if(strlen(filepath) >= 0){
|
|
|
|
log(LOG_DEBUG, "Trying to open file %s for input", filepath);
|
|
|
|
infile = fopen(filepath, "r");
|
|
|
|
}
|
|
|
|
if(infile == NULL){
|
|
|
|
infile = stdin;
|
|
|
|
}
|
|
|
|
/* End set up the input stream */
|
|
|
|
|
2023-06-19 08:56:49 +00:00
|
|
|
size_t bytesdigested = digest_file(infile);
|
|
|
|
(void)bytesdigested;
|
|
|
|
|
|
|
|
if(infile != stdin){
|
|
|
|
fclose(infile);
|
2023-05-21 23:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int len;
|
|
|
|
unsigned char * a = get_digest(&len);
|
2023-06-19 08:56:49 +00:00
|
|
|
unsigned int aalen;
|
|
|
|
char *aa = atohex(a, len, &aalen);
|
|
|
|
|
|
|
|
FILE * outfile = get_outfile(infile, filepath);
|
|
|
|
/*
|
|
|
|
Commit hash to auxiliary file
|
|
|
|
*/
|
|
|
|
if(run_verbose){
|
|
|
|
printf("Output:\n\t");
|
|
|
|
}
|
|
|
|
if(run_verbose && outfile != stdout){
|
|
|
|
fwrite(aa, sizeof(*aa), aalen, stdout);
|
|
|
|
}
|
|
|
|
size_t bytes_written = 0;
|
|
|
|
size_t bytes_round;
|
|
|
|
while(bytes_written < aalen && !ferror(outfile)){
|
|
|
|
bytes_round = fwrite(aa + bytes_written, sizeof(*aa), aalen - bytes_written, outfile);
|
|
|
|
bytes_written += bytes_round;
|
|
|
|
verb("Round wrote %lu bytes\n", bytes_round);
|
2023-05-21 23:05:39 +00:00
|
|
|
}
|
2023-06-19 08:56:49 +00:00
|
|
|
/* End commit hash to auxiliary file*/
|
2023-05-21 23:05:39 +00:00
|
|
|
|
|
|
|
OPENSSL_free(a);
|
|
|
|
free(aa);
|
|
|
|
if(deinit_hasher()){
|
|
|
|
log(LOG_INFO, "Error encountered while deinitializing hasher");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_SYSLOG
|
|
|
|
closelog();
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|