Minor cleanups, KNF, error handling consistency.

This commit is contained in:
christos 2005-04-21 12:45:12 +00:00
parent ff33efda18
commit 7391aafa62
5 changed files with 194 additions and 260 deletions

View File

@ -1,5 +1,6 @@
# $NetBSD: Makefile,v 1.6 2005/04/21 11:21:58 he Exp $
# $NetBSD: Makefile,v 1.7 2005/04/21 12:45:12 christos Exp $
WARNS=3
PROG= veriexecctl
MAN= veriexec.4 veriexecctl.8
SRCS= veriexecctl_parse.y veriexecctl_conf.l veriexecctl.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: veriexecctl.c,v 1.7 2005/04/21 11:21:58 he Exp $ */
/* $NetBSD: veriexecctl.c,v 1.8 2005/04/21 12:45:12 christos Exp $ */
/*-
* Copyright 2005 Elad Efrat <elad@bsd.org.il>
@ -47,31 +47,29 @@
#define VERIEXEC_DEVICE "/dev/veriexec"
#define usage(code) errx(code, "Usage: %s [-v] [load <signature_file>] " \
"[fingerprints]", \
getprogname())
extern struct veriexec_params params; /* in veriexecctl_parse.y */
extern char *filename; /* in veriexecctl_conf.l */
int gfd, verbose = 0, no_mem = 0, phase;
unsigned line;
size_t line;
/*
* Prototypes
*/
int fingerprint_load(char*);
static FILE *openlock(const char *);
static void phase1_preload(void);
static int fingerprint_load(char*);
static void usage(void) __attribute__((__noreturn__));
FILE *
static FILE *
openlock(const char *path)
{
int lfd;
lfd = open(path, O_RDONLY|O_EXLOCK, 0);
if (lfd < 0)
return (NULL);
if ((lfd = open(path, O_RDONLY|O_EXLOCK, 0)) == -1)
return NULL;
return (fdopen(lfd, "r"));
return fdopen(lfd, "r");
}
struct vexec_up *
@ -79,12 +77,11 @@ dev_lookup(dev_t d)
{
struct vexec_up *p;
CIRCLEQ_FOREACH(p, &params_list, vu_list) {
CIRCLEQ_FOREACH(p, &params_list, vu_list)
if (p->vu_param.dev == d)
return (p);
}
return (NULL);
return NULL;
}
struct vexec_up *
@ -92,8 +89,7 @@ dev_add(dev_t d)
{
struct vexec_up *up;
up = calloc(1, sizeof(*up));
if (up == NULL)
if ((up = calloc((size_t)1, sizeof(*up))) == NULL)
err(1, "No memory");
up->vu_param.dev = d;
@ -101,11 +97,11 @@ dev_add(dev_t d)
CIRCLEQ_INSERT_TAIL(&params_list, up, vu_list);
return (up);
return up;
}
/* Load all devices, get rid of the list. */
int
static void
phase1_preload(void)
{
if (verbose)
@ -116,13 +112,10 @@ phase1_preload(void)
vup = CIRCLEQ_FIRST(&params_list);
if (ioctl(gfd, VERIEXEC_TABLESIZE, &(vup->vu_param)) < 0) {
(void) fprintf(stderr, "Error in phase 1: Can't "
"set hash table size for device %d: %s.\n",
vup->vu_param.dev, strerror(errno));
return (-1);
}
if (ioctl(gfd, VERIEXEC_TABLESIZE, &(vup->vu_param)) == -1)
err(1, "Error in phase 1: Can't "
"set hash table size for device %d",
vup->vu_param.dev);
if (verbose) {
printf(" => Hash table sizing successful for device "
@ -133,8 +126,6 @@ phase1_preload(void)
CIRCLEQ_REMOVE(&params_list, vup, vu_list);
free(vup);
}
return (0);
}
/*
@ -144,24 +135,21 @@ phase1_preload(void)
void
phase2_load(void)
{
if (ioctl(gfd, VERIEXEC_LOAD, &params) < 0) {
(void) fprintf(stderr, "%s: %s\n", params.file,
strerror(errno));
}
if (ioctl(gfd, VERIEXEC_LOAD, &params) == -1)
err(1, "Cannot load params from `%s'", params.file);
free(params.fingerprint);
}
/*
* Fingerprint load handling.
*/
int
static int
fingerprint_load(char *ifile)
{
CIRCLEQ_INIT(&params_list);
if ((yyin = openlock(ifile)) == NULL) {
err(1, "Failed to open %s", ifile);
}
if ((yyin = openlock(ifile)) == NULL)
err(1, "Cannot open `%s'", ifile);
/*
* Phase 1: Scan all config files, creating the list of devices
@ -171,14 +159,13 @@ fingerprint_load(char *ifile)
phase = 1;
if (verbose) {
(void) fprintf(stderr, "Phase 1: Building hash table information:\n");
(void) fprintf(stderr, "=> Parsing \"%s\"\n", ifile);
(void)printf("Phase 1: Building hash table information:\n");
(void)printf("=> Parsing \"%s\"\n", ifile);
}
yyparse();
if (phase1_preload() < 0)
exit(1);
phase1_preload();
/*
* Phase 2: After we have a circular queue containing all the
@ -189,16 +176,23 @@ fingerprint_load(char *ifile)
rewind(yyin);
phase = 2;
if (verbose) {
(void) fprintf(stderr, "Phase 2: Loading per-file "
"fingerprints.\n");
(void) fprintf(stderr, "=> Parsing \"%s\"\n", ifile);
(void)printf("Phase 2: Loading per-file fingerprints.\n");
(void)printf("=> Parsing \"%s\"\n", ifile);
}
yyparse();
(void) fclose(yyin);
(void)fclose(yyin);
return(0);
return 0;
}
static void
usage(void)
{
(void)fprintf(stderr, "Usage: %s [-v] [load <signature_file>] "
"[fingerprints]", getprogname());
exit(1);
}
int
@ -206,82 +200,61 @@ main(int argc, char **argv)
{
char *newp;
int c;
unsigned size;
size_t size;
struct veriexec_fp_report report;
if ((argc < 2) || (argc > 4)) {
usage(1);
}
setprogname(argv[0]);
while ((c = getopt(argc, argv, "v")) != -1) {
while ((c = getopt(argc, argv, "v")) != -1)
switch (c) {
case 'v':
verbose = 1;
break;
default:
usage(1);
usage();
}
}
argc -= optind;
argv += optind;
gfd = open(VERIEXEC_DEVICE, O_RDWR, 0);
if (gfd == -1) {
err(1, "Failed to open pseudo-device");
}
if ((gfd = open(VERIEXEC_DEVICE, O_RDWR, 0)) == -1)
err(1, "Cannot open `%s'", VERIEXEC_DEVICE);
/*
* Handle the different commands we can do.
*/
if (strcasecmp(argv[0], "load") == 0) {
if (argc == 2 && strcasecmp(argv[0], "load") == 0) {
line = 0;
filename = argv[1];
fingerprint_load(argv[1]);
} else if (strcasecmp(argv[0], "fingerprints") == 0) {
} else if (argc == 1 && strcasecmp(argv[0], "fingerprints") == 0) {
size = report.size = 100;
if ((report.fingerprints = malloc(report.size)) == NULL) {
fprintf(stderr, "fingerprints: malloc failed.\n");
exit(1);
}
if ((report.fingerprints = malloc(report.size)) == NULL)
err(1, "malloc fingeprints");
if (ioctl(gfd, VERIEXEC_FINGERPRINTS, &report) == 0) {
if (size != report.size) {
if (verbose)
fprintf(stderr, "fingerprints: "
"buffer insufficient, "
"reallocating to %d bytes.\n",
report.size);
/* fingerprint store was not large enough
make more room and try again. */
if ((newp = realloc(report.fingerprints,
report.size)) == NULL) {
fprintf(stderr, "fingerprints: "
"realloc failed\n");
exit(1);
}
if (ioctl(gfd, VERIEXEC_FINGERPRINTS,
&report) < 0) {
fprintf(stderr,
"fingerprints ioctl: %s\n",
strerror(errno));
exit(1);
}
}
} else {
(void) fprintf(stderr,
"fingerprints ioctl: %s\n",
strerror(errno));
exit(1);
if (ioctl(gfd, VERIEXEC_FINGERPRINTS, &report) == -1)
err(1, "fingerprints ioctl");
if (size != report.size) {
if (verbose)
(void)printf("fingerprints: buffer too small, "
"reallocating to %d bytes.\n",
report.size);
/* fingerprint store was not large enough
make more room and try again. */
if ((newp = realloc(report.fingerprints, report.size))
== NULL)
err(1, "realloc fingeprints");
if (ioctl(gfd, VERIEXEC_FINGERPRINTS,
&report) == -1)
err(1, "fingerprints ioctl");
}
printf("Supported fingerprints: %s\n", report.fingerprints);
} else {
usage(1);
}
} else
usage();
(void) close(gfd);
return (0);
(void)close(gfd);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: veriexecctl.h,v 1.2 2005/04/21 11:21:58 he Exp $ */
/* $NetBSD: veriexecctl.h,v 1.3 2005/04/21 12:45:12 christos Exp $ */
/*-
* Copyright 2005 Elad Efrat <elad@bsd.org.il>
@ -30,8 +30,8 @@
*
*/
#ifndef _VEXECCTL_H_
#define _VEXECCTL_H_
#ifndef _VERIEXECCTL_H_
#define _VERIEXECCTL_H_
CIRCLEQ_HEAD(vexec_ups, vexec_up) params_list;
struct vexec_up {
@ -40,7 +40,7 @@ struct vexec_up {
};
extern int gfd, no_mem, phase, verbose;
extern unsigned line;
extern size_t line;
extern char *infile;
extern FILE *yyin;
@ -48,11 +48,8 @@ int yywrap(void);
int yylex(void);
int yyparse(void);
void yyerror(const char *);
FILE *openlock(const char *);
struct vexec_up *dev_lookup(dev_t);
struct vexec_up *dev_add(dev_t);
int phase1_preload(void);
void phase2_load(void);
int convert(u_char *, u_char *);
#endif /* _VEXECCTL_H_ */
#endif /* _VERIEXECCTL_H_ */

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: veriexecctl_conf.l,v 1.3 2005/04/20 13:44:45 blymn Exp $ */
/* $NetBSD: veriexecctl_conf.l,v 1.4 2005/04/21 12:45:12 christos Exp $ */
/*-
* Copyright 2005 Elad Efrat <elad@bsd.org.il>
@ -55,35 +55,16 @@ STRING [0-9a-zA-Z]+
/* path */
\/[^ \t]+ {
yylval.string = strdup(yytext);
return (PATH);
if ((yylval.string = strdup(yytext)) == NULL)
err(1, "Cannot allocate string");
return PATH;
}
/* string (fingerprint, type, options) */
{STRING} {
yylval.string = strdup(yytext);
if (!(yylval.string)) {
(void) fprintf(stderr, "WARNING: Out"
" of memory during run-time! "
"Attempting recover...\n");
/*
* Sleep a little bit and let the
* machine calm down. ;)
*/
usleep(60000);
yylval.string = strdup(yytext);
if (!(yylval.string)) {
(void) fprintf(stderr, "ERROR:"
" No memory. Aborting.\n");
exit(1);
}
(void) fprintf(stderr, "Recovered.\n");
}
return (STRING);
if ((yylval.string = strdup(yytext)) == NULL)
err(1, "Cannot allocate string");
return STRING;
}
@ -96,17 +77,22 @@ STRING [0-9a-zA-Z]+
/* eol on a line with data. need a call to ioctl, return eol */
\n {
line++;
return (EOL);
return EOL;
}
. { yyerror("Invalid character"); }
%%
int yywrap(void) {
return (1);
int
yywrap(void)
{
return 1;
}
void yyerror(const char *string) {
fprintf(stderr, "%s at \"%s\", line %d\n", string, yytext, line);
void
yyerror(const char *string)
{
(void)fprintf(stderr, "%s: %s at \"%s\", line %d\n", getprogname(),
string, yytext, line);
}

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: veriexecctl_parse.y,v 1.6 2005/04/21 11:21:58 he Exp $ */
/* $NetBSD: veriexecctl_parse.y,v 1.7 2005/04/21 12:45:12 christos Exp $ */
/*-
* Copyright 2005 Elad Efrat <elad@bsd.org.il>
@ -46,6 +46,7 @@
#include "veriexecctl.h"
struct veriexec_params params;
static int convert(u_char *, u_char *);
%}
@ -62,128 +63,110 @@ struct veriexec_params params;
statement : /* empty */
| statement path type fingerprint flags eol {
struct stat sb;
struct stat sb;
struct vexec_up *p;
if (phase == 2) {
phase2_load();
goto phase_2_end;
}
if (phase == 2) {
phase2_load();
goto phase_2_end;
}
if (stat(params.file, &sb) == 0) {
struct vexec_up *p;
if (stat(params.file, &sb) == -1) {
warnx("Line %lu: Can't stat `%s'",
(unsigned long)line, params.file);
goto phase_2_end;
}
/* Only regular files */
if (!S_ISREG(sb.st_mode)) {
(void) fprintf(stderr,
"Line %u: "
"%s is not a regular file.\n",
line,
params.file);
}
/* Only regular files */
if (!S_ISREG(sb.st_mode)) {
warnx("Line %lu: %s is not a regular file",
(unsigned long)line, params.file);
goto phase_2_end;
}
if ((p = dev_lookup(sb.st_dev)) != NULL) {
(p->vu_param.hash_size)++;
} else {
if (verbose) {
struct statvfs sf;
if ((p = dev_lookup(sb.st_dev)) == NULL) {
(p->vu_param.hash_size)++;
goto phase_2_end;
}
statvfs(params.file,
&sf);
(void) printf(
" => Adding device"
" ID %d. (%s)\n",
sb.st_dev,
sf.f_mntonname);
}
dev_add(sb.st_dev);
}
} else {
(void) fprintf(stderr,
"Line %u: Can't stat"
" %s.\n",
line, params.file);
}
if (verbose) {
struct statvfs sf;
if (statvfs(params.file, &sf) == -1)
err(1, "Cannot statvfs `%s'", params.file);
(void)printf( " => Adding device ID %d. (%s)\n",
sb.st_dev, sf.f_mntonname);
}
dev_add(sb.st_dev);
phase_2_end:
bzero(&params, sizeof(params));
}
(void)memset(&params, 0, sizeof(params));
}
| statement eol
| statement error eol {
yyerrok;
}
yyerrok;
}
;
path : PATH {
strlcpy(params.file, $1, MAXPATHLEN);
}
(void)strlcpy(params.file, $1, MAXPATHLEN);
}
;
type : STRING {
if (phase != 1) {
if (strlen($1) >=
sizeof(params.fp_type)) {
yyerror("Fingerprint type too " "long");
YYERROR;
}
strlcpy(params.fp_type, $1,
sizeof(params.fp_type));
}
}
if (phase != 1) {
if (strlen($1) >= sizeof(params.fp_type)) {
yyerror("Fingerprint type too long");
YYERROR;
}
(void)strlcpy(params.fp_type, $1, sizeof(params.fp_type));
}
}
;
fingerprint : STRING {
if (phase != 1) {
params.fingerprint = (char *)
malloc(strlen($1) / 2);
if (params.fingerprint == NULL) {
fprintf(stderr, "Fingerprint"
"mem alloc failed, "
"cannot continue.\n");
exit(1);
}
if (phase != 1) {
params.fingerprint = malloc(strlen($1) / 2);
if (params.fingerprint == NULL)
err(1, "Fingerprint mem alloc failed");
if ((params.size =
convert($1, params.fingerprint))
== -1) {
free(params.fingerprint);
yyerror("Bad fingerprint");
YYERROR;
}
}
if ((params.size = convert($1, params.fingerprint)) == -1) {
free(params.fingerprint);
yyerror("Bad fingerprint");
YYERROR;
}
}
}
;
}
;
flags : /* empty */ {
if (phase == 2)
params.type = VERIEXEC_DIRECT;
}
if (phase == 2)
params.type = VERIEXEC_DIRECT;
}
| flags flag_spec
;
flag_spec : STRING {
if (phase != 1) {
if (strcasecmp($1, "direct") == 0) {
params.type = VERIEXEC_DIRECT;
} else if (strcasecmp($1, "indirect")
== 0) {
params.type = VERIEXEC_INDIRECT;
/* } else if (strcasecmp($1, "shell") == 0) {
params.vxp_type = VEXEC_SHELL;*/
} else if (strcasecmp($1, "file")
== 0) {
params.type = VERIEXEC_FILE;
} else {
yyerror("Bad option");
YYERROR;
}
}
if (phase != 1) {
if (strcasecmp($1, "direct") == 0)
params.type = VERIEXEC_DIRECT;
else if (strcasecmp($1, "indirect") == 0)
params.type = VERIEXEC_INDIRECT;
#ifdef notdef
else if (strcasecmp($1, "shell") == 0)
params.vxp_type = VEXEC_SHELL;
#endif
else if (strcasecmp($1, "file") == 0)
params.type = VERIEXEC_FILE;
else {
yyerror("Bad option");
YYERROR;
}
}
}
}
;
eol : EOL
@ -197,44 +180,38 @@ eol : EOL
* by "out". Returns the number of bytes converted or -1 if the conversion
* fails.
*/
int convert(u_char *fp, u_char *out) {
int i, value, error, count;
static int
convert(u_char *fp, u_char *out)
{
size_t i, count;
u_char value;
count = strlen(fp);
/*
* if there are not an even number of hex digits then there is
* not an integral number of bytes in the fingerprint.
*/
/*
* if there are not an even number of hex digits then there is
* not an integral number of bytes in the fingerprint.
*/
if ((count % 2) != 0)
return -1;
count /= 2;
error = count;
#define cvt(cv) \
if (isdigit(cv)) \
value += (cv) - '0'; \
else if (isxdigit(cv)) \
value += 10 + tolower(cv) - 'a'; \
else \
return -1
for (i = 0; i < count; i++) {
if ((fp[2*i] >= '0') && (fp[2*i] <= '9')) {
value = 16 * (fp[2*i] - '0');
} else if ((tolower(fp[2*i]) >= 'a')
&& (tolower(fp[2*i]) <= 'f')) {
value = 16 * (10 + tolower(fp[2*i]) - 'a');
} else {
error = -1;
break;
}
if ((fp[2*i + 1] >= '0') && (fp[2*i + 1] <= '9')) {
value += fp[2*i + 1] - '0';
} else if ((tolower(fp[2*i + 1]) >= 'a')
&& (tolower(fp[2*i + 1]) <= 'f')) {
value += tolower(fp[2*i + 1]) - 'a' + 10;
} else {
error = -1;
break;
}
value = 0;
cvt(fp[2 * i]);
value <<= 4;
cvt(fp[2 * i + 1]);
out[i] = value;
}
return (error);
return count;
}