1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-22 23:49:03 +00:00

Check a metadata.conf file for channel expiration.

This commit is contained in:
david
2011-12-19 22:00:19 +00:00
parent 86bb24947a
commit 097e52a7a4

View File

@@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include "nbase.h"
@@ -496,6 +497,17 @@ static struct {
char *password;
} options;
struct metadata {
int is_expired;
time_t expiry_date;
};
static void metadata_init(struct metadata *metadata)
{
metadata->is_expired = 0;
metadata->expiry_date = 0;
}
static void init_options(void)
{
options.verbose = 1;
@@ -578,6 +590,70 @@ static int read_config_file(const char *conf_filename)
return 0;
}
static int parse_date(const char *s, time_t *t)
{
struct tm tm = {0};
if (strptime(s, "%Y-%d-%m", &tm) == NULL)
return -1;
*t = mktime(&tm);
return 0;
}
static int date_is_after(time_t t, time_t now)
{
return difftime(t, now) > 0;
}
static int read_metadata_file(const char *metadata_filename, struct metadata *metadata)
{
struct config_parser cp;
struct config_entry entry;
int ret;
if (options.verbose)
printf("Trying to open metadata file %s.\n", metadata_filename);
errno = 0;
if (config_parser_open(metadata_filename, &cp) == -1) {
/* A missing file is not an error for metadata. */
return 0;
}
while ((ret = config_parser_next(&cp, &entry)) > 0) {
if (streq(entry.key, "expired")) {
if (parse_date(entry.value, &metadata->expiry_date) == -1) {
fprintf(stderr, "Warning: %s:%lu: can't parse date \"%s\".\n",
metadata_filename, cp.lineno, entry.value);
} else {
if (date_is_after(metadata->expiry_date, time(NULL)))
metadata->is_expired = 1;
}
} else {
fprintf(stderr, "Warning: %s:%lu: unknown key \"%s\".\n",
metadata_filename, cp.lineno, entry.key);
}
config_entry_free(&entry);
}
if (ret == -1) {
fprintf(stderr, "Parse error on line %lu of %s.\n",
cp.lineno, metadata_filename);
config_parser_close(&cp);
return -1;
}
errno = 0;
if (config_parser_close(&cp) == -1) {
if (options.verbose)
printf("Failed to close %s: %s.\n", metadata_filename, strerror(errno));
return -1;
}
return 0;
}
static void usage(FILE *fp)
{
@@ -599,10 +675,11 @@ static void usage_error(void)
}
static int try_channels(const char *channels[], unsigned int num_channels);
static const char *try_channels(const char *channels[], unsigned int num_channels);
static int stage_and_install(const char *channel);
static int stage_channel(const char *channel, const char *staging_dir);
static int install(const char *staging_dir, const char *install_dir);
static int channel_is_expired(const char *channel, time_t *expiry_date);
static void summarize_options(void)
{
@@ -624,6 +701,8 @@ const struct option LONG_OPTIONS[] = {
int main(int argc, char *argv[])
{
int opt, longoptidx;
const char *successful_channel;
time_t expiry_date;
internal_assert(argc > 0);
program_name = argv[0];
@@ -660,10 +739,19 @@ int main(int argc, char *argv[])
exit(1);
}
if (try_channels(options.channels, options.num_channels) == 0)
return 0;
successful_channel = try_channels(options.channels, options.num_channels);
if (options.username == NULL) {
if (successful_channel != NULL && channel_is_expired(successful_channel, &expiry_date)) {
fprintf(stderr, "\
\n\
Channel is expired: %s\n\
\n\
The channel %s is expired and will not receive any more updates.\n\
Go to http://nmap.org/download.html to get a newer Nmap release.\n\
", successful_channel, successful_channel);
}
if (successful_channel == NULL && options.username == NULL) {
fprintf(stderr, "\
\n\
Could not stage any channels and don't have authentication credentials.\n\
@@ -674,20 +762,23 @@ Edit the file %s and enter your username and password. For example:\n\
", options.conf_filename);
}
return 1;
if (successful_channel != NULL)
return 0;
else
return 1;
}
static int try_channels(const char *channels[], unsigned int num_channels)
static const char *try_channels(const char *channels[], unsigned int num_channels)
{
unsigned int i;
for (i = 0; i < num_channels; i++) {
if (stage_and_install(channels[i]) == 0)
return 0;
return channels[i];
}
return -1;
return NULL;
}
@@ -798,6 +889,28 @@ static int stage_channel(const char *channel, const char *staging_dir)
return rc;
}
static int channel_is_expired(const char *channel, time_t *expiry_date)
{
char *metadata_filename;
struct metadata metadata;
int rc;
metadata_init(&metadata);
metadata_filename = path_join(options.staging_dir, channel, "metadata.conf", NULL);
rc = read_metadata_file(metadata_filename, &metadata);
if (rc == -1) {
fprintf(stderr, "Can't read config file %s.\n", metadata_filename);
free(metadata_filename);
exit(1);
}
free(metadata_filename);
*expiry_date = metadata.expiry_date;
return metadata.is_expired;
}
static int copy_tree(const char *from_dirname, const char *to_dirname);
static int rename_file(const char *from_filename, const char *to_filename);