Add 'audit-packages -F <file>' to process a list of packages/patterns
from a file. Update and sort options in the man page
This commit is contained in:
parent
8b93918fe5
commit
44c6e6e2dd
2 changed files with 282 additions and 206 deletions
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: audit-packages.1.in,v 1.5 2007/08/10 22:50:46 adrianp Exp $
|
||||
.\" $NetBSD: audit-packages.1.in,v 1.6 2008/01/07 22:27:59 adrianp Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jeremy C. Reed. All rights reserved.
|
||||
.\"
|
||||
|
@ -30,7 +30,7 @@
|
|||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd August 10, 2007
|
||||
.Dd January 7, 2008
|
||||
.Os
|
||||
.Dt AUDIT-PACKAGES 1
|
||||
.Sh NAME
|
||||
|
@ -41,6 +41,7 @@
|
|||
.Nm
|
||||
.Op Fl deqsVv
|
||||
.Op Fl c Ar config_file
|
||||
.Op Fl F Ar file
|
||||
.Op Fl g Ar file
|
||||
.Op Fl h Ar file
|
||||
.Op Fl K Ar pkg_dbdir
|
||||
|
@ -63,16 +64,49 @@ vulnerable package.
|
|||
.Pp
|
||||
The following flags are supported:
|
||||
.Bl -tag -width XcXconfigXfileXX
|
||||
.It Fl c Ar config_file
|
||||
Specify a custom
|
||||
.Ar config_file
|
||||
configuration file to use.
|
||||
.It Fl d
|
||||
Attempt to download the vulnerabilities file using the
|
||||
.Nm download-vulnerability-list
|
||||
script before scanning the installed packages for vulnerabilities.
|
||||
.It Fl e
|
||||
Check for end-of-life (eol) packages.
|
||||
.It Fl q
|
||||
Be ``quiet'' in emitting report headers and such, just dump the
|
||||
raw info (basically, assume a non-human reading).
|
||||
.It Fl s
|
||||
Verify the signature of the current
|
||||
.Pa pkg-vulnerabilities
|
||||
file.
|
||||
The key used to sign the file is available from:
|
||||
.Pa ftp://ftp.netbsd.org/pub/NetBSD/security/PGP/pkgsrc-security@NetBSD.org.asc
|
||||
.Pp
|
||||
In order for this to function correctly the above key must be
|
||||
added to the gpg keyring of the user who runs
|
||||
.Ic audit-packages -s
|
||||
and/or
|
||||
.Ic download-vulnerability-list -s .
|
||||
In addition to this the gpg binary must be installed on your system.
|
||||
The path to the gpg binary can be set in
|
||||
.Xr audit-packages.conf 5 .
|
||||
.Pp
|
||||
The requirement for GnuPG may go away in the future when a suitable
|
||||
replacement is implemented.
|
||||
.It Fl V
|
||||
Display the version number and exit.
|
||||
.It Fl v
|
||||
Be more verbose.
|
||||
Specify multiple
|
||||
.Fl v
|
||||
flags to increase verbosity.
|
||||
Currently a maximum level of three is supported.
|
||||
.It Fl c Ar config_file
|
||||
Specify a custom
|
||||
.Ar config_file
|
||||
configuration file to use.
|
||||
.It Fl F Ar file
|
||||
Load a
|
||||
.Ar file
|
||||
containing a list of package names and or package patterns to check.
|
||||
.It Fl g Ar file
|
||||
Compute the SHA512 hash on
|
||||
.Ar file .
|
||||
|
@ -102,39 +136,10 @@ are
|
|||
.Dv PKGVULNDIR ,
|
||||
and
|
||||
.Dv IGNORE_URLS .
|
||||
.It Fl q
|
||||
Be ``quiet'' in emitting report headers and such, just dump the
|
||||
raw info (basically, assume a non-human reading).
|
||||
.It Fl s
|
||||
Verify the signature of the current
|
||||
.Pa pkg-vulnerabilities
|
||||
file.
|
||||
The key used to sign the file is available from:
|
||||
.Pa ftp://ftp.netbsd.org/pub/NetBSD/security/PGP/pkgsrc-security@NetBSD.org.asc
|
||||
.Pp
|
||||
In order for this to function correctly the above key must be
|
||||
added to the gpg keyring of the user who runs
|
||||
.Ic audit-packages -s
|
||||
and/or
|
||||
.Ic download-vulnerability-list -s .
|
||||
In addition to this the gpg binary must be installed on your system.
|
||||
The path to the gpg binary can be set in
|
||||
.Xr audit-packages.conf 5 .
|
||||
.Pp
|
||||
The requirement for GnuPG may go away in the future when a suitable
|
||||
replacement is implemented.
|
||||
.It Fl t Ar type
|
||||
Only check for the specified
|
||||
.Ar type
|
||||
of vulnerability.
|
||||
.It Fl V
|
||||
Display the version number and exit.
|
||||
.It Fl v
|
||||
Be more verbose.
|
||||
Specify multiple
|
||||
.Fl v
|
||||
flags to increase verbosity.
|
||||
Currently a maximum level of three is supported.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: audit-packages.c,v 1.11 2007/08/22 23:23:22 adrianp Exp $ */
|
||||
/* $NetBSD: audit-packages.c,v 1.12 2008/01/07 22:27:59 adrianp Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Adrian Portelli <adrianp@NetBSD.org>.
|
||||
|
@ -104,7 +104,6 @@ char *ignore = NULL; /* ignore urls */
|
|||
/* globals */
|
||||
char *conf_file = SYSCONFDIR"/audit-packages.conf"; /* config file location */
|
||||
char *program_name; /* the program name */
|
||||
char *pkgname; /* package name in msg */
|
||||
|
||||
/* program defaults */
|
||||
int verbose = 0; /* be quiet */
|
||||
|
@ -112,58 +111,54 @@ Boolean eol = FALSE; /* don't check eol */
|
|||
Boolean quiet = FALSE; /* display full data */
|
||||
|
||||
int main(int, char **);
|
||||
void *safe_calloc(size_t, size_t);
|
||||
char *ap_fixpkgname(char *);
|
||||
static int checkforpkg(const char *);
|
||||
void usage(void);
|
||||
int dvl(void);
|
||||
void old_pvfile(void);
|
||||
void pv_format(FILE *);
|
||||
char *gen_hash(char *);
|
||||
char *get_hash(char *);
|
||||
int check_hash(char *);
|
||||
int check_sig(char *);
|
||||
int pv_message(char *[]);
|
||||
int ap_ignore(char *[]);
|
||||
void show_info(char *);
|
||||
void set_pvfile(const char *);
|
||||
char *clean_conf(char *);
|
||||
int get_confvalues(void);
|
||||
char *safe_strdup(const char *);
|
||||
static void *safe_calloc(size_t, size_t);
|
||||
static char *checkforpkg(const char *);
|
||||
static void usage(void);
|
||||
static int dvl(void);
|
||||
static void old_pvfile(void);
|
||||
static void pv_format(FILE *);
|
||||
static char *gen_hash(char *);
|
||||
static char *get_hash(char *);
|
||||
static int check_hash(char *);
|
||||
static int check_sig(char *);
|
||||
static int pv_message(char *[], char *);
|
||||
static int ap_ignore(char *[]);
|
||||
static void show_info(char *);
|
||||
static void set_pvfile(const char *);
|
||||
static char *clean_conf(char *);
|
||||
static int get_confvalues(void);
|
||||
static char *safe_strdup(const char *);
|
||||
static int checkforvuln(FILE *, char *, Boolean, char *, Boolean);
|
||||
static char *trim_r(char *);
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* built in gz/bzip2 support
|
||||
* merge download-vulnerability-list(1)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* get the options for what were doing and do the actual processing of
|
||||
* get the options for what we are doing, and do the actual processing of
|
||||
* the pkg-vulnerabilities file
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *line_ptr;
|
||||
char *one_pkg = NULL;
|
||||
char *one_package = NULL;
|
||||
char *bpkg = NULL;
|
||||
char *bpkg_ptr = NULL;
|
||||
char *pkg_type = NULL;
|
||||
char *pv_token = NULL;
|
||||
char *line_tmp = NULL;
|
||||
char *pv_entry[] = {NULL, NULL, NULL};
|
||||
char *line = NULL;
|
||||
char *check_hash_file = NULL;
|
||||
char *gen_hash_file = NULL;
|
||||
char *hash_generated = NULL;
|
||||
char *query_var = NULL;
|
||||
char *pkgname = NULL;
|
||||
char *bulk_file = NULL;
|
||||
|
||||
int ch, i;
|
||||
int line_count = 0;
|
||||
int ch = 0;
|
||||
int retval = -1;
|
||||
int vuln_count = 0;
|
||||
|
||||
Boolean ignore_found = FALSE;
|
||||
Boolean download = FALSE;
|
||||
Boolean pkg_installed = FALSE;
|
||||
Boolean verify_sig = FALSE;
|
||||
|
@ -171,10 +166,11 @@ main(int argc, char **argv)
|
|||
Boolean type = FALSE;
|
||||
Boolean cli_check_hash = FALSE;
|
||||
Boolean cli_gen_hash = FALSE;
|
||||
Boolean vuln_found = FALSE;
|
||||
Boolean info = FALSE;
|
||||
Boolean bulk = FALSE;
|
||||
Boolean vuln_found = FALSE;
|
||||
|
||||
FILE *pv;
|
||||
FILE *pv, *bf;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
|
@ -184,7 +180,7 @@ main(int argc, char **argv)
|
|||
|
||||
opterr = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, ":dveqK:n:h:g:c:p:st:Q:V")) != -1) {
|
||||
while ((ch = getopt(argc, argv, ":dveqK:n:h:g:c:p:st:F:Q:V")) != -1) {
|
||||
|
||||
switch (ch) {
|
||||
|
||||
|
@ -211,7 +207,7 @@ main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'n':
|
||||
one_package = optarg;
|
||||
pkgname = optarg;
|
||||
check_one = TRUE;
|
||||
pkg_installed = FALSE;
|
||||
break;
|
||||
|
@ -221,15 +217,20 @@ main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'p':
|
||||
one_package = optarg;
|
||||
pkgname = optarg;
|
||||
check_one = TRUE;
|
||||
pkg_installed = TRUE;
|
||||
break;
|
||||
|
||||
|
||||
case 'q':
|
||||
quiet = TRUE;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
bulk_file = optarg;
|
||||
bulk = TRUE;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
verify_sig = TRUE;
|
||||
break;
|
||||
|
@ -279,7 +280,7 @@ main(int argc, char **argv)
|
|||
* check the hash and/or sig for a specified file
|
||||
*
|
||||
* if -h <file> is given then just the hash is checked
|
||||
* but if -s -f <file> are given then both the hash and the
|
||||
* but if -s -h <file> are given then both the hash and the
|
||||
* sig are checked. this is purely for
|
||||
* download-vulnerability-list, users should not be directly
|
||||
* calling audit-packages with -h <file> or -s -h <file>.
|
||||
|
@ -309,9 +310,6 @@ main(int argc, char **argv)
|
|||
retval = get_confvalues();
|
||||
|
||||
/* if we found some IGNORE_URLS lines */
|
||||
if (ignore != NULL)
|
||||
ignore_found = TRUE;
|
||||
|
||||
if (verbose >= 2) {
|
||||
fprintf(stderr, "debug2: Using PKGDB_DIR: %s\n", _pkgdb_getPKGDB_DIR());
|
||||
fprintf(stderr, "debug2: Using pkg-vulnerabilities file: %s\n", pvfile);
|
||||
|
@ -373,41 +371,104 @@ main(int argc, char **argv)
|
|||
|
||||
/*
|
||||
* this is for -p:
|
||||
* (Check a specific installed package for vulnerabilities.)
|
||||
* we run pkg_info to get the package name into one_pkg
|
||||
* and to check if it's actually installed.
|
||||
*
|
||||
* if we find that it's not installed then just exit silently.
|
||||
* check a specific installed package for vulnerabilities
|
||||
* if we find that it's not installed, just exit silently
|
||||
*/
|
||||
if ((pkg_installed == TRUE) && (check_one == TRUE)) {
|
||||
if ((checkforpkg(one_package)) == 0) {
|
||||
if ((checkforpkg(pkgname)) != NULL) {
|
||||
if (verbose >= 3)
|
||||
fprintf(stderr, "debug3: Package found to be installed (-p): %s\n", one_package);
|
||||
fprintf(stderr, "debug3: Package found to be installed (-p): %s\n", pkgname);
|
||||
} else {
|
||||
if (verbose >= 3)
|
||||
fprintf(stderr, "debug3: Package not found to be installed (-p): %s\n", one_package);
|
||||
fprintf(stderr, "debug3: Package not found to be installed (-p): %s\n", pkgname);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this is for -n
|
||||
* Check a specific installed package for vulnerabilities.
|
||||
*
|
||||
* here we don't care if it's installed or not.
|
||||
* this is for -n:
|
||||
* check a specific package for vulnerabilities
|
||||
* here we don't care if it's installed or not
|
||||
*/
|
||||
if ((pkg_installed == FALSE) && (check_one == TRUE)) {
|
||||
one_pkg = one_package;
|
||||
pkgname = one_package;
|
||||
|
||||
if (verbose >= 3)
|
||||
fprintf(stderr, "debug3: Looking for package (-n): %s\n", one_pkg);
|
||||
fprintf(stderr, "debug3: Looking for package (-n): %s\n", pkgname);
|
||||
}
|
||||
|
||||
line = safe_calloc(MAXLINELEN, sizeof(char));
|
||||
rewind(pv);
|
||||
|
||||
while ((line_ptr = fgets(line, MAXLINELEN, pv)) != NULL) {
|
||||
/* check a package for vulnerabilities */
|
||||
if (bulk == FALSE) {
|
||||
retval = checkforvuln(pv, pkgname, type, pkg_type, check_one);
|
||||
|
||||
if (retval != 0)
|
||||
vuln_found = TRUE;
|
||||
} else {
|
||||
check_one = TRUE;
|
||||
|
||||
if ((bf = fopen(bulk_file, "r")) == NULL) {
|
||||
errx(EXIT_FAILURE, "Unable to open: %s", bulk_file);
|
||||
}
|
||||
|
||||
bpkg = safe_calloc(MAXLINELEN, sizeof(char));
|
||||
|
||||
while ((bpkg_ptr = fgets(bpkg, MAXLINELEN, bf)) != NULL) {
|
||||
|
||||
/* what we're not interested in */
|
||||
if ((bpkg[0] == '#') || (bpkg[0] == '\n'))
|
||||
continue;
|
||||
|
||||
bpkg = trim_r(bpkg);
|
||||
|
||||
retval = checkforvuln(pv, bpkg, type, pkg_type, check_one);
|
||||
if (retval != 0)
|
||||
vuln_found = TRUE;
|
||||
}
|
||||
|
||||
free(bpkg);
|
||||
|
||||
/* bail if ferror is set */
|
||||
if (ferror(bf) != 0)
|
||||
errx(EXIT_FAILURE, "Unable to read: %s", bulk_file);
|
||||
|
||||
fclose(bf);
|
||||
}
|
||||
|
||||
fclose(pv);
|
||||
|
||||
if ((verbose >= 1) && (vuln_found == FALSE))
|
||||
fprintf(stderr, "No vulnerable packages found.\n");
|
||||
|
||||
if (vuln_found == FALSE) {
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* end main() */
|
||||
|
||||
/*
|
||||
* check a given pattern/package for a hit in the pkg-vulnerabilities file
|
||||
*/
|
||||
static int
|
||||
checkforvuln(FILE *vuln_file, char *package, Boolean type, char *pkg_type, Boolean check_one)
|
||||
{
|
||||
Boolean vuln_found = FALSE;
|
||||
|
||||
char *line = NULL;
|
||||
char *line_tmp = NULL;
|
||||
char *pv_token = NULL;
|
||||
char *pv_entry[] = {NULL, NULL, NULL};
|
||||
|
||||
int line_count = 0;
|
||||
int i = 0;
|
||||
int retval = -1;
|
||||
int vuln_count = 0;
|
||||
|
||||
line = safe_calloc(MAXLINELEN, sizeof(char));
|
||||
|
||||
while (fgets(line, MAXLINELEN, vuln_file) != NULL) {
|
||||
|
||||
++line_count;
|
||||
|
||||
|
@ -424,10 +485,7 @@ main(int argc, char **argv)
|
|||
|
||||
i = 0;
|
||||
|
||||
line_tmp = safe_strdup(line);
|
||||
|
||||
if (line_tmp[strlen(line_tmp) - 1] == '\n')
|
||||
line_tmp[strlen(line_tmp) - 1] = ' ';
|
||||
line_tmp = trim_r(line);
|
||||
|
||||
do {
|
||||
pv_token = strsep(&line_tmp, " \t");
|
||||
|
@ -460,7 +518,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* deal with URLs that we're ignorning */
|
||||
if (ignore_found == TRUE) {
|
||||
if (ignore != NULL) {
|
||||
retval = ap_ignore(pv_entry);
|
||||
|
||||
/* if we got an ignore hit then stop here */
|
||||
|
@ -478,12 +536,8 @@ main(int argc, char **argv)
|
|||
* matching.
|
||||
*/
|
||||
|
||||
if ((pkg_match(pv_entry[0], one_package)) == 1) {
|
||||
|
||||
/* flag to indicate we have found something */
|
||||
if ((pkg_match(pv_entry[0], package)) == 1)
|
||||
vuln_found = TRUE;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
|
@ -492,18 +546,16 @@ main(int argc, char **argv)
|
|||
* pattern in pv_entry[0] is installed.
|
||||
*/
|
||||
|
||||
if ((checkforpkg(pv_entry[0])) == 0) {
|
||||
|
||||
/* flag to indicate we have found something */
|
||||
package = checkforpkg(pv_entry[0]);
|
||||
if (package != NULL)
|
||||
vuln_found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* display the messages for all the vulnerable packages seen */
|
||||
if (vuln_found == TRUE) {
|
||||
|
||||
/* EOL or vulnerable message and increment the count */
|
||||
retval = pv_message(pv_entry);
|
||||
retval = pv_message(pv_entry, package);
|
||||
vuln_count = vuln_count + retval;
|
||||
|
||||
/* reset the found flag */
|
||||
|
@ -512,26 +564,19 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* bail if ferror is set */
|
||||
if (ferror(pv) != 0) {
|
||||
if (ferror(vuln_file) != 0)
|
||||
errx(EXIT_FAILURE, "Unable to read specified pkg-vulnerabilities file: %s", pvfile);
|
||||
}
|
||||
|
||||
fclose(pv);
|
||||
|
||||
rewind(vuln_file);
|
||||
free(line);
|
||||
|
||||
if ((verbose >= 1) && (vuln_count == 0))
|
||||
fprintf(stderr, "No vulnerable packages found.\n");
|
||||
|
||||
if (vuln_count == 0) {
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return vuln_count;
|
||||
}
|
||||
|
||||
/* wrap calloc in some common error checking */
|
||||
void *
|
||||
/*
|
||||
* wrap calloc in some common error checking
|
||||
*/
|
||||
static void *
|
||||
safe_calloc(size_t number, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
@ -545,35 +590,31 @@ safe_calloc(size_t number, size_t size)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/* fix a pkgname by removing a directory prefix (if any) */
|
||||
char *
|
||||
ap_fixpkgname(char *fixpkgname)
|
||||
{
|
||||
char *tmppkgname = NULL;
|
||||
char *retval = NULL;
|
||||
|
||||
retval = safe_calloc(MAXPKGNAMELEN, sizeof(char));
|
||||
|
||||
/* get the last separator */
|
||||
tmppkgname = strrchr(fixpkgname, '/');
|
||||
|
||||
/* if there's no separator present then we assume the name is ok */
|
||||
if (tmppkgname == NULL) {
|
||||
retval = fixpkgname;
|
||||
} else {
|
||||
/* strrchr will leave the first separator still in the string */
|
||||
if (tmppkgname[0] == '/')
|
||||
strlcpy(retval, &tmppkgname[1], MAXPKGNAMELEN);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* clean a valid line from the configuration file */
|
||||
char *
|
||||
clean_conf(char *conf_line)
|
||||
/*
|
||||
* strip any trailing characters we don't want from a string
|
||||
*/
|
||||
static char *
|
||||
trim_r(char *trimmer)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = (strlen(trimmer) - 1); i > 0; --i) {
|
||||
if (STRIP(trimmer[i])) {
|
||||
trimmer[i] = '\0';
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return trimmer;
|
||||
}
|
||||
|
||||
/*
|
||||
* clean a valid line from the configuration file
|
||||
*/
|
||||
static char *
|
||||
clean_conf(char *conf_line)
|
||||
{
|
||||
size_t len = 0;
|
||||
char *token = NULL;
|
||||
char *cp;
|
||||
|
@ -593,13 +634,7 @@ clean_conf(char *conf_line)
|
|||
}
|
||||
|
||||
/* remove any trailing characters we don't want */
|
||||
for (i = (strlen(token) - 1); i > 0; --i) {
|
||||
if (STRIP(token[i])) {
|
||||
token[i] = '\0';
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
token = trim_r(token);
|
||||
|
||||
len = strlen(token);
|
||||
|
||||
|
@ -611,8 +646,10 @@ clean_conf(char *conf_line)
|
|||
return token;
|
||||
}
|
||||
|
||||
/* read in our values from a configuration file */
|
||||
int
|
||||
/*
|
||||
* read in our values from a configuration file
|
||||
*/
|
||||
static int
|
||||
get_confvalues(void)
|
||||
{
|
||||
FILE *conf;
|
||||
|
@ -640,7 +677,7 @@ get_confvalues(void)
|
|||
if ((line[0] == '#') || (line[0] == '\n'))
|
||||
continue;
|
||||
|
||||
if ((strncmp(line, "IGNORE_URLS", 11) == 0) &&
|
||||
if ((strncmp(line, "IGNORE_URLS", 11) == 0) &&
|
||||
(f_ignore == FALSE)) {
|
||||
retval = clean_conf(line);
|
||||
if (retval != NULL) {
|
||||
|
@ -656,7 +693,7 @@ get_confvalues(void)
|
|||
f_verify_bin = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((strncmp(line, "PKGVULNDIR", 9) == 0) &&
|
||||
else if ((strncmp(line, "PKGVULNDIR", 9) == 0) &&
|
||||
(f_set_pvfile == FALSE)) {
|
||||
retval = clean_conf(line);
|
||||
if (retval != NULL) {
|
||||
|
@ -669,9 +706,8 @@ get_confvalues(void)
|
|||
}
|
||||
|
||||
/* bail if eof has not been set or ferror is set */
|
||||
if ((feof(conf) == 0) || (ferror(conf) != 0)) {
|
||||
if ((feof(conf) == 0) || (ferror(conf) != 0))
|
||||
errx(EXIT_FAILURE, "Unable to read specified configuration file: %s", conf_file);
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(conf);
|
||||
|
@ -679,28 +715,36 @@ get_confvalues(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* check to see if a package exists */
|
||||
static int
|
||||
checkforpkg(const char *one_package)
|
||||
/*
|
||||
* check to see if a package exists
|
||||
*/
|
||||
static char *
|
||||
checkforpkg(const char *package)
|
||||
{
|
||||
pkgname = find_best_matching_installed_pkg(one_package);
|
||||
if (pkgname == NULL && !ispkgpattern(one_package)) {
|
||||
char *retval = NULL;
|
||||
|
||||
retval = find_best_matching_installed_pkg(package);
|
||||
|
||||
if (retval == NULL && !ispkgpattern(package)) {
|
||||
char *pattern;
|
||||
|
||||
if (asprintf(&pattern, "%s-[0-9]*", one_package) == -1)
|
||||
if (asprintf(&pattern, "%s-[0-9]*", package) == -1)
|
||||
errx(EXIT_FAILURE, "asprintf failed");
|
||||
|
||||
pkgname = find_best_matching_installed_pkg(pattern);
|
||||
retval = find_best_matching_installed_pkg(pattern);
|
||||
free(pattern);
|
||||
}
|
||||
return pkgname == NULL ? 1 : 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* usage message for this program */
|
||||
void
|
||||
/*
|
||||
* usage message for this program
|
||||
*/
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-deqsVv] [-c config_file] [-g file] [-h file] [-K pkg_dbdir] [-n package] [-p package] [-Q varname ] [-t type]\n", program_name);
|
||||
fprintf(stderr, "Usage: %s [-deqsVv] [-c config_file] [-F file] [-g file] [-h file] [-K pkg_dbdir] [-n package] [-p package] [-Q varname ] [-t type]\n", program_name);
|
||||
fprintf(stderr, "\t-d : Run the download-vulnerability-list script before anything else.\n");
|
||||
fprintf(stderr, "\t-e : Check for end-of-life (eol) packages.\n");
|
||||
fprintf(stderr, "\t-q : Be quiet and just dump the detected vulnerable package names.\n");
|
||||
|
@ -708,6 +752,7 @@ usage(void)
|
|||
fprintf(stderr, "\t-V : Display version and exit.\n");
|
||||
fprintf(stderr, "\t-v : Be more verbose. Specify multiple -v flags to increase verbosity.\n");
|
||||
fprintf(stderr, "\t-c : Specify a custom configuration file to use.\n");
|
||||
fprintf(stderr, "\t-F : Check all packages listed in a file for vulnerabilities.\n");
|
||||
fprintf(stderr, "\t-g : Compute the hash of a file.\n");
|
||||
fprintf(stderr, "\t-h : Check the hash of a file against the internally stored value.\n");
|
||||
fprintf(stderr, "\t-K : Use pkg_dbdir as PKG_DBDIR.\n");
|
||||
|
@ -718,8 +763,10 @@ usage(void)
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* we need to download the file first */
|
||||
int
|
||||
/*
|
||||
* we need to download the file first
|
||||
*/
|
||||
static int
|
||||
dvl(void)
|
||||
{
|
||||
int retval = -1;
|
||||
|
@ -734,8 +781,10 @@ dvl(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* check for an old vulnerabilities file if we're being verbose */
|
||||
void
|
||||
/*
|
||||
* check for an old vulnerabilities file if we're being verbose
|
||||
*/
|
||||
static void
|
||||
old_pvfile(void)
|
||||
{
|
||||
float t_diff;
|
||||
|
@ -763,8 +812,10 @@ old_pvfile(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* get the #FORMAT from the pkg-vulnerabilities file */
|
||||
void
|
||||
/*
|
||||
* get the #FORMAT from the pkg-vulnerabilities file
|
||||
*/
|
||||
static void
|
||||
pv_format(FILE * pv)
|
||||
{
|
||||
char *line = NULL;
|
||||
|
@ -814,8 +865,10 @@ pv_format(FILE * pv)
|
|||
free(line);
|
||||
}
|
||||
|
||||
/* extract the stored hash in the pkg-vulnerabilities file */
|
||||
char *
|
||||
/*
|
||||
* extract the stored hash in the pkg-vulnerabilities file
|
||||
*/
|
||||
static char *
|
||||
get_hash(char *hash_input)
|
||||
{
|
||||
char *line = NULL;
|
||||
|
@ -853,8 +906,10 @@ get_hash(char *hash_input)
|
|||
return hash;
|
||||
}
|
||||
|
||||
/* check the internally stored hash against the computed hash (-h <file>) */
|
||||
int
|
||||
/*
|
||||
* check the internally stored hash against the computed hash (-h <file>)
|
||||
*/
|
||||
static int
|
||||
check_hash(char *hash_input)
|
||||
{
|
||||
int retval = -1;
|
||||
|
@ -889,8 +944,10 @@ check_hash(char *hash_input)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* do the hash calculation on specified input */
|
||||
char *
|
||||
/*
|
||||
* do the hash calculation on specified input
|
||||
*/
|
||||
static char *
|
||||
gen_hash(char *hash_input)
|
||||
{
|
||||
char *hash_result = NULL;
|
||||
|
@ -947,8 +1004,10 @@ gen_hash(char *hash_input)
|
|||
return hash_calc;
|
||||
}
|
||||
|
||||
/* do signature checking - if required */
|
||||
int
|
||||
/*
|
||||
* do signature checking - if required
|
||||
*/
|
||||
static int
|
||||
check_sig(char *sig_input)
|
||||
{
|
||||
int retval = -1;
|
||||
|
@ -962,9 +1021,11 @@ check_sig(char *sig_input)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* print the messages for eol and vulnerable packages */
|
||||
int
|
||||
pv_message(char *pv_entry[])
|
||||
/*
|
||||
* print the messages for eol and vulnerable packages
|
||||
*/
|
||||
static int
|
||||
pv_message(char *pv_entry[], char *package)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
|
@ -982,21 +1043,23 @@ pv_message(char *pv_entry[])
|
|||
retval = 1;
|
||||
|
||||
/* Just make sure we display _something_ useful here */
|
||||
if (pkgname == NULL)
|
||||
pkgname = pv_entry[0];
|
||||
if (package == NULL)
|
||||
package = pv_entry[0];
|
||||
|
||||
if (quiet == FALSE) {
|
||||
fprintf(stdout, "Package %s has a %s vulnerability, see %s\n", pkgname, pv_entry[1], pv_entry[2]);
|
||||
if (quiet == FALSE) {
|
||||
fprintf(stdout, "Package %s has a %s vulnerability, see: %s\n", package, pv_entry[1], pv_entry[2]);
|
||||
} else {
|
||||
fprintf(stdout, "%s\n", pkgname);
|
||||
fprintf(stdout, "%s\n", package);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* deal with URLs that we're ignorning */
|
||||
int
|
||||
/*
|
||||
* deal with URLs that we're ignorning
|
||||
*/
|
||||
static int
|
||||
ap_ignore(char *pv_entry[])
|
||||
{
|
||||
char *ignore_tmp = NULL;
|
||||
|
@ -1032,14 +1095,18 @@ ap_ignore(char *pv_entry[])
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* at the moment we really don't need to clean anything up */
|
||||
/*
|
||||
* at the moment we really don't need to clean anything up
|
||||
*/
|
||||
void
|
||||
cleanup(int signo)
|
||||
{
|
||||
}
|
||||
|
||||
/* print what the current settings are */
|
||||
void
|
||||
/*
|
||||
* print what the current settings are
|
||||
*/
|
||||
static void
|
||||
show_info(char *varname)
|
||||
{
|
||||
if (strncmp(varname, "GPG", 3) == 0) {
|
||||
|
@ -1053,8 +1120,10 @@ show_info(char *varname)
|
|||
}
|
||||
}
|
||||
|
||||
/* set the location for the pkg-vulnerabilities file */
|
||||
void
|
||||
/*
|
||||
* set the location for the pkg-vulnerabilities file
|
||||
*/
|
||||
static void
|
||||
set_pvfile(const char *vuln_dir)
|
||||
{
|
||||
char *pvloc = NULL;
|
||||
|
@ -1071,8 +1140,10 @@ set_pvfile(const char *vuln_dir)
|
|||
free(pvloc);
|
||||
}
|
||||
|
||||
/* duplicate a string and check the return value */
|
||||
char *
|
||||
/*
|
||||
* duplicate a string and check the return value
|
||||
*/
|
||||
static char *
|
||||
safe_strdup(const char *dupe)
|
||||
{
|
||||
char *retval;
|
||||
|
|
Loading…
Reference in a new issue