mirror of
https://gitlab.com/gnuwget/wget2.git
synced 2026-02-01 04:10:48 +00:00
741 lines
19 KiB
C
741 lines
19 KiB
C
/*
|
|
* Copyright (c) 2017-2024 Free Software Foundation, Inc.
|
|
*
|
|
* This file is part of Wget
|
|
*
|
|
* Wget is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Wget is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Wget If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
*
|
|
* Dummy plugins for plugin support testing
|
|
*
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <wget.h>
|
|
|
|
#if defined TEST_SELECT_NAME
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
const char *name = wget_plugin_get_name(plugin);
|
|
if (strcmp(name, "pluginname") != 0) {
|
|
wget_error_printf("Plugin took a wrong name '%s'\n", name);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
FILE *stream = fopen("plugin-loaded.txt", "wb");
|
|
if (! stream)
|
|
wget_error_printf_exit("Cannot open plugin-loaded.txt: %s", strerror(errno));
|
|
wget_fprintf(stream, "Plugin loaded\n");
|
|
fclose(stream);
|
|
|
|
return 0;
|
|
}
|
|
#elif defined TEST_SELECT_EXITSTATUS
|
|
static void finalizer(WGET_GCC_UNUSED wget_plugin *plugin, int exit_status)
|
|
{
|
|
FILE *stream = fopen("exit-status.txt", "wb");
|
|
if (! stream)
|
|
wget_error_printf_exit("Cannot open exit-status.txt: %s", strerror(errno));
|
|
wget_fprintf(stream, "exit(%d)\n", exit_status);
|
|
fclose(stream);
|
|
}
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
wget_plugin_register_finalizer(plugin, finalizer);
|
|
return 0;
|
|
}
|
|
#elif defined TEST_SELECT_FAULTY1
|
|
WGET_EXPORT void irrelevant(void);
|
|
void irrelevant(void)
|
|
{
|
|
}
|
|
#elif defined TEST_SELECT_FAULTY2
|
|
static void finalizer(WGET_GCC_UNUSED wget_plugin *plugin, int exit_status)
|
|
{
|
|
FILE *stream = fopen("exit-status.txt", "wb");
|
|
if (! stream)
|
|
wget_error_printf_exit("Cannot open exit-status.txt: %s", strerror(errno));
|
|
wget_fprintf(stream, "exit(%d)\n", exit_status);
|
|
fclose(stream);
|
|
}
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
wget_plugin_register_finalizer(plugin, finalizer);
|
|
wget_error_printf("Plugin failed to initialize, intentionally\n");
|
|
return 1;
|
|
}
|
|
#elif defined TEST_SELECT_OPTIONS
|
|
static struct option_filter {
|
|
const char
|
|
*name;
|
|
bool
|
|
valid_without_val : 1,
|
|
valid_with_val : 1;
|
|
} options[] = {
|
|
{"x", 1, 1},
|
|
{"y", 1, 0},
|
|
{"z", 0, 1},
|
|
{"alpha", 1, 1},
|
|
{"beta", 1, 0},
|
|
{"gamma", 0, 1},
|
|
{NULL, 0, 0}
|
|
};
|
|
static int argp_fn(wget_plugin *plugin, const char *option, const char *value)
|
|
{
|
|
// List of options the plugin accepts
|
|
int i;
|
|
|
|
// Simulate help output
|
|
if (strcmp(option, "help") == 0) {
|
|
for (i = 0; options[i].name; i++) {
|
|
printf("--plugin-opt=%s.%s", wget_plugin_get_name(plugin), options[i].name);
|
|
if (options[i].valid_without_val) {
|
|
if (options[i].valid_with_val)
|
|
printf("[=value]");
|
|
} else {
|
|
printf("=value");
|
|
}
|
|
printf("\tDescription for '%s'\n", options[i].name);
|
|
}
|
|
printf("--plugin-opt=%s.help\tPrint help message for this plugin\n", wget_plugin_get_name(plugin));
|
|
return 0;
|
|
}
|
|
|
|
// Simulate option accept/reject
|
|
for (i = 0; options[i].name; i++) {
|
|
if (strcmp(option, options[i].name) == 0)
|
|
break;
|
|
}
|
|
if (! options[i].name) {
|
|
wget_error_printf("Unknown option %s\n", option);
|
|
return -1;
|
|
}
|
|
if ((!options[i].valid_with_val) && value) {
|
|
wget_error_printf("Option %s does not accept an argument.\n", option);
|
|
return -1;
|
|
}
|
|
if ((!options[i].valid_without_val) && !value) {
|
|
wget_error_printf("Option %s requires an argument\n", option);
|
|
return -1;
|
|
}
|
|
|
|
// Append option to options.txt
|
|
FILE *stream = fopen("options.txt", "ab");
|
|
if (! stream)
|
|
wget_error_printf_exit("Cannot open options.txt: %s", strerror(errno));
|
|
if (value)
|
|
wget_fprintf(stream, "%s=%s\n", option, value);
|
|
else
|
|
wget_fprintf(stream, "%s\n", option);
|
|
fclose(stream);
|
|
|
|
return 0;
|
|
}
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
wget_plugin_register_option_callback(plugin, argp_fn);
|
|
return 0;
|
|
}
|
|
#elif defined TEST_SELECT_API
|
|
|
|
// Separate assert definition because here assertions are part of the tests
|
|
#define test_assert(expr) \
|
|
do { \
|
|
if (! (expr)) \
|
|
wget_error_printf_exit(__FILE__ ":%d: Failed assertion [%s]\n", __LINE__, #expr); \
|
|
} while (0)
|
|
|
|
// A very simple option parser for plugin
|
|
struct option;
|
|
typedef int (*option_parser)(const struct option *opt, const char *value);
|
|
struct option {
|
|
const char *name;
|
|
const char *arg_desc;
|
|
const char *desc;
|
|
option_parser fn;
|
|
void *lptr;
|
|
};
|
|
static int parse_option(const struct option *options, wget_plugin *plugin, const char *option, const char *value)
|
|
{
|
|
size_t i;
|
|
|
|
// Handle help
|
|
if (strcmp(option, "help") == 0) {
|
|
for (i = 0; options[i].name; i++) {
|
|
printf("--plugin-opt=%s.%s%s\t%s\n", wget_plugin_get_name(plugin),
|
|
options[i].name, options[i].arg_desc, options[i].desc);
|
|
}
|
|
printf("--plugin-opt=%s.help\tShow this help\n", wget_plugin_get_name(plugin));
|
|
return 0;
|
|
}
|
|
|
|
// Search for option
|
|
for (i = 0; options[i].name; i++) {
|
|
if (strcmp(option, options[i].name) == 0)
|
|
break;
|
|
}
|
|
if (! options[i].name) {
|
|
wget_error_printf("Unknown option %s\n", option);
|
|
return -1;
|
|
}
|
|
|
|
// Delegate
|
|
return (* options[i].fn)(options + i, value);
|
|
}
|
|
|
|
static int parse_boolean(const struct option *option, const char *value)
|
|
{
|
|
int *intptr = (int *) option->lptr;
|
|
int bool_val = 1;
|
|
|
|
if (value && strcmp(value, "false") == 0)
|
|
bool_val = 0;
|
|
|
|
*intptr = bool_val;
|
|
|
|
return 0;
|
|
}
|
|
static int parse_string(const struct option *option, const char *value)
|
|
{
|
|
char **strptr = (char **) option->lptr;
|
|
|
|
if (! value) {
|
|
wget_error_printf("%s: Value expected\n", option->name);
|
|
return -1;
|
|
}
|
|
|
|
wget_xfree(*strptr);
|
|
*strptr = wget_strdup(value);
|
|
return 0;
|
|
}
|
|
struct pair {
|
|
char *l;
|
|
char *r;
|
|
};
|
|
static void free_pair(struct pair *p)
|
|
{
|
|
wget_xfree(p->l);
|
|
wget_xfree(p->r);
|
|
}
|
|
static int parse_pair(const struct option *option, const char *value)
|
|
{
|
|
struct pair *p = (struct pair *) option->lptr;
|
|
|
|
if (! value) {
|
|
wget_error_printf("%s: Value expected\n", option->name);
|
|
return -1;
|
|
}
|
|
|
|
const char *ptr = strchr(value, ':');
|
|
|
|
if (ptr) {
|
|
free_pair(p);
|
|
p->l = wget_strmemdup(value, ptr - value);
|
|
p->r = wget_strdup(ptr + 1);
|
|
} else {
|
|
wget_error_printf("%s: Expected ':'\n", option->name);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
typedef struct {
|
|
wget_vector *files_processed;
|
|
|
|
char *reject;
|
|
char *accept;
|
|
struct pair replace;
|
|
struct pair saveas;
|
|
int parse_rot13;
|
|
int only_rot13;
|
|
int test_pp;
|
|
} plugin_data_t;
|
|
|
|
static int argp_fn(wget_plugin *plugin, const char *option, const char *value)
|
|
{
|
|
plugin_data_t *d = (plugin_data_t *) plugin->plugin_data;
|
|
struct option options[] = {
|
|
{"reject", "=substring", "Do not fetch URL containing substring",
|
|
parse_string, (void *) &d->reject},
|
|
{"accept", "=substring", "Force fetch URLs containing substring",
|
|
parse_string, (void *) &d->accept},
|
|
{"replace", "=substring:replacement", "Replace substring with replacement in URLs",
|
|
parse_pair, (void *) &d->replace},
|
|
{"saveas", "=substring:filename", "Save URLs containing substring as filename",
|
|
parse_pair, (void *) &d->saveas},
|
|
{"parse-rot13", "[=false]", "Parse rot13 obfuscated links (default: false)",
|
|
parse_boolean, (void *) &d->parse_rot13},
|
|
{"only-rot13", "[=false]", "Parse only rot13 links (default: false)",
|
|
parse_boolean, (void *) &d->only_rot13},
|
|
{"test-pp", "[=false]", "Test post-processing API for consistency",
|
|
parse_boolean, (void *) &d->test_pp},
|
|
{NULL, NULL, NULL, NULL, NULL}
|
|
};
|
|
|
|
return parse_option(options, plugin, option, value);
|
|
}
|
|
|
|
static void finalizer(wget_plugin *plugin, WGET_GCC_UNUSED int exit_status)
|
|
{
|
|
plugin_data_t *d = (plugin_data_t *) plugin->plugin_data;
|
|
|
|
if (d->test_pp) {
|
|
int i;
|
|
FILE *stream;
|
|
|
|
wget_vector_sort(d->files_processed);
|
|
test_assert((stream = fopen("files_processed.txt", "wb")));
|
|
for (i = 0; i < wget_vector_size(d->files_processed); i++)
|
|
wget_fprintf(stream, "%s\n", (const char *) wget_vector_get(d->files_processed, i));
|
|
fclose(stream);
|
|
}
|
|
wget_vector_free(&d->files_processed);
|
|
|
|
wget_xfree(d->reject);
|
|
wget_xfree(d->accept);
|
|
free_pair(&d->replace);
|
|
free_pair(&d->saveas);
|
|
|
|
wget_xfree(plugin->plugin_data);
|
|
}
|
|
|
|
static void url_filter(wget_plugin *plugin, const wget_iri *iri, wget_intercept_action *action)
|
|
{
|
|
plugin_data_t *d = (plugin_data_t *) plugin->plugin_data;
|
|
|
|
if (d->reject && strstr(iri->uri, d->reject))
|
|
wget_intercept_action_reject(action);
|
|
if (d->accept && strstr(iri->uri, d->accept))
|
|
wget_intercept_action_accept(action);
|
|
if (d->saveas.l && strstr(iri->uri, d->saveas.l))
|
|
wget_intercept_action_set_local_filename(action, d->saveas.r);
|
|
if (d->replace.l) {
|
|
const char *ptr, *find;
|
|
size_t find_len;
|
|
wget_buffer buf[1];
|
|
wget_iri *alt_iri;
|
|
|
|
wget_buffer_init(buf, NULL, 0);
|
|
find_len = strlen(d->replace.l);
|
|
|
|
for (ptr = iri->uri; (find = strstr(ptr, d->replace.l)); ptr = find + find_len) {
|
|
wget_buffer_memcat(buf, ptr, find - ptr);
|
|
wget_buffer_strcat(buf, d->replace.r);
|
|
}
|
|
wget_buffer_strcat(buf, ptr);
|
|
|
|
alt_iri = wget_iri_parse(buf->data, "utf-8");
|
|
if (! alt_iri) {
|
|
wget_fprintf(stderr, "Cannot parse URL after replacement (%s)\n", buf->data);
|
|
}
|
|
wget_intercept_action_set_alt_url(action, alt_iri);
|
|
|
|
wget_iri_free(&alt_iri);
|
|
wget_buffer_deinit(buf);
|
|
}
|
|
}
|
|
|
|
static int post_processor(wget_plugin *plugin, wget_downloaded_file *file)
|
|
{
|
|
plugin_data_t *d = (plugin_data_t *) plugin->plugin_data;
|
|
|
|
if (d->parse_rot13 && wget_downloaded_file_get_recurse(file)) {
|
|
const char *data;
|
|
size_t len, i, j;
|
|
static const char *needle = "rot13(";
|
|
|
|
wget_downloaded_file_get_contents(file, (const void **) &data, &len);
|
|
|
|
// Since data is not null-terminated and may have null bytes, strstr() cannot be used here.
|
|
j = 0;
|
|
for (i = 0; i < len; i++) {
|
|
if (needle[j]) {
|
|
// No prefix table needed for "rot13("
|
|
if (needle[j] == data[i])
|
|
j++;
|
|
else
|
|
j = 0;
|
|
} else {
|
|
// Match found
|
|
size_t end;
|
|
for (end = i; end < len && data[end] && data[end] != ')'; end++)
|
|
;
|
|
if (end < len && end > i && data[end] == ')') {
|
|
// Obfuscated URL found, now deobfuscate and add it
|
|
char *url = wget_malloc(end - i + 1);
|
|
size_t k;
|
|
wget_iri *iri;
|
|
|
|
for (k = 0; k < end - i; k++) {
|
|
char c = data[i + k];
|
|
if (c >= 'A' && c <= 'Z')
|
|
c = (((c - 'A') + 13) % 26) + 'A';
|
|
if (c >= 'a' && c <= 'z')
|
|
c = (((c - 'a') + 13) % 26) + 'a';
|
|
url[k] = c;
|
|
}
|
|
url[end - i] = 0;
|
|
|
|
if ((iri = wget_iri_parse(url, "utf-8"))) {
|
|
wget_downloaded_file_add_recurse_url(file, iri);
|
|
wget_iri_free(&iri);
|
|
}
|
|
wget_free(url);
|
|
|
|
i = end;
|
|
}
|
|
|
|
j = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (d->test_pp) {
|
|
const wget_iri *iri = wget_downloaded_file_get_source_url(file);
|
|
const char *data;
|
|
size_t size;
|
|
FILE *stream;
|
|
|
|
// Compare downloaded file contents with wget_downloaded_file_get_contents()
|
|
test_assert(wget_downloaded_file_get_contents(file, (const void **) &data, &size) == 0);
|
|
|
|
// Compare wget_downloaded_file_get_size() against wget_downloaded_file_get_contents()
|
|
test_assert(size == wget_downloaded_file_get_size(file));
|
|
|
|
// Compare with file on disk
|
|
const char *fname = wget_downloaded_file_get_local_filename(file);
|
|
if (fname) {
|
|
char *refdata;
|
|
size_t refsize;
|
|
test_assert((refdata = wget_read_file(fname, &refsize)));
|
|
test_assert(refsize == size && "wget_read_file(fname, &refsize)");
|
|
test_assert(memcmp(data, refdata, size) == 0);
|
|
wget_free(refdata);
|
|
}
|
|
|
|
// Compare downloaded file contents with wget_downloaded_file_open_stream()
|
|
stream = wget_downloaded_file_open_stream(file);
|
|
if (stream) {
|
|
size_t i;
|
|
for (i = 0; i < size; i++)
|
|
test_assert((int) data[i] == getc(stream));
|
|
test_assert("At end of stream, wget_downloaded_file_open_stream(file)" && getc(stream) == EOF);
|
|
fclose(stream);
|
|
}
|
|
|
|
// Update list of files processed
|
|
{
|
|
const char *basename = strrchr(iri->uri, '/');
|
|
if (basename)
|
|
wget_vector_add(d->files_processed, wget_strdup(basename + 1));
|
|
}
|
|
}
|
|
|
|
return d->only_rot13 ? 0 : 1;
|
|
}
|
|
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
plugin_data_t *d = (plugin_data_t *) wget_calloc(1, sizeof(plugin_data_t));
|
|
|
|
d->files_processed = wget_vector_create(4, (wget_vector_compare_fn *) strcmp);
|
|
|
|
plugin->plugin_data = d;
|
|
wget_plugin_register_option_callback(plugin, argp_fn);
|
|
wget_plugin_register_finalizer(plugin, finalizer);
|
|
|
|
wget_plugin_register_url_filter_callback(plugin, url_filter);
|
|
wget_plugin_register_post_processor(plugin, post_processor);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#elif defined TEST_SELECT_DATABASE
|
|
|
|
// HPKP database for testing
|
|
static int hpkp_db_load_counter = 0;
|
|
|
|
// this is a dummy hpkp db implementation for the plugin
|
|
typedef struct {
|
|
int dummy;
|
|
} test_hpkp_db;
|
|
|
|
static wget_hpkp_db *test_hpkp_db_init(wget_hpkp_db *hpkp_db, const char *fname)
|
|
{
|
|
(void) fname;
|
|
|
|
if (!hpkp_db)
|
|
hpkp_db = wget_calloc(1, sizeof(test_hpkp_db));
|
|
else
|
|
memset(hpkp_db, 0, sizeof(test_hpkp_db));
|
|
|
|
return hpkp_db;
|
|
}
|
|
|
|
static void test_hpkp_db_deinit(wget_hpkp_db *hpkp_db)
|
|
{
|
|
if (hpkp_db) {
|
|
memset(hpkp_db, 0, sizeof(test_hpkp_db));
|
|
}
|
|
}
|
|
|
|
static void test_hpkp_db_free(wget_hpkp_db **hpkp_db)
|
|
{
|
|
wget_free(*hpkp_db);
|
|
*hpkp_db = NULL;
|
|
}
|
|
|
|
static int test_hpkp_db_check_pubkey(wget_hpkp_db *hpkp_db, const char *host, const void *pubkey, size_t pubkeysize)
|
|
{
|
|
(void) hpkp_db;
|
|
wget_debug_printf("%s: host %s pubkey %p pksize %zu\n", __func__,
|
|
host, pubkey, pubkeysize);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void test_hpkp_db_add(wget_hpkp_db *hpkp_db, wget_hpkp **hpkp)
|
|
{
|
|
(void) hpkp_db;
|
|
wget_debug_printf("%s: hpkp %p\n", __func__, (void *) hpkp);
|
|
}
|
|
|
|
static int test_hpkp_db_load(wget_hpkp_db *hpkp_db)
|
|
{
|
|
(void) hpkp_db;
|
|
hpkp_db_load_counter++;
|
|
return 0;
|
|
}
|
|
|
|
static int test_hpkp_db_save(wget_hpkp_db *hpkp_db)
|
|
{
|
|
(void) hpkp_db;
|
|
return 0;
|
|
}
|
|
|
|
static wget_hpkp_db_vtable test_hpkp_db_vtable = {
|
|
.init = test_hpkp_db_init,
|
|
.deinit = test_hpkp_db_deinit,
|
|
.free = test_hpkp_db_free,
|
|
.check_pubkey = test_hpkp_db_check_pubkey,
|
|
.add = test_hpkp_db_add,
|
|
.load = test_hpkp_db_load,
|
|
.save = test_hpkp_db_save,
|
|
};
|
|
|
|
|
|
// HSTS database for testing
|
|
static int hsts_db_load_counter = 0;
|
|
|
|
// this is a dummy hsts db implementation for the plugin
|
|
typedef struct {
|
|
int dummy;
|
|
} test_hsts_db_t;
|
|
|
|
static int test_hsts_db_host_match(const wget_hsts_db *hsts_db, const char *host, uint16_t port)
|
|
{
|
|
(void) hsts_db;
|
|
|
|
wget_debug_printf("%s: host %s port %hu\n", __func__,
|
|
host, port);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static wget_hsts_db *test_hsts_db_init(wget_hsts_db *hsts_db, const char *fname)
|
|
{
|
|
(void) fname;
|
|
|
|
if (!hsts_db)
|
|
hsts_db = wget_calloc(1, sizeof(test_hsts_db_t));
|
|
else
|
|
memset(hsts_db, 0, sizeof(test_hsts_db_t));
|
|
|
|
return hsts_db;
|
|
}
|
|
|
|
static void test_hsts_db_deinit(wget_hsts_db *hsts_db)
|
|
{
|
|
if (hsts_db) {
|
|
memset(hsts_db, 0, sizeof(test_hsts_db_t));
|
|
}
|
|
}
|
|
|
|
static void test_hsts_db_free(wget_hsts_db **hsts_db)
|
|
{
|
|
wget_free(*hsts_db);
|
|
*hsts_db = NULL;
|
|
}
|
|
|
|
static void test_hsts_db_add(wget_hsts_db *hsts_db, const char *host, uint16_t port, int64_t maxage, bool include_subdomains)
|
|
{
|
|
(void) hsts_db;
|
|
wget_debug_printf("%s: host %s port %hu maxage %lld include_subdomains %d\n", __func__,
|
|
host, port, (long long) maxage, include_subdomains);
|
|
}
|
|
|
|
static int test_hsts_db_load(wget_hsts_db *hsts_db)
|
|
{
|
|
(void) hsts_db;
|
|
hsts_db_load_counter++;
|
|
return 0;
|
|
}
|
|
|
|
static int test_hsts_db_save(wget_hsts_db *hsts_db)
|
|
{
|
|
(void) hsts_db;
|
|
return 0;
|
|
}
|
|
|
|
static const wget_hsts_db_vtable test_hsts_db_vtable = {
|
|
.host_match = test_hsts_db_host_match,
|
|
.init = test_hsts_db_init,
|
|
.deinit = test_hsts_db_deinit,
|
|
.free = test_hsts_db_free,
|
|
.add = test_hsts_db_add,
|
|
.load = test_hsts_db_load,
|
|
.save = test_hsts_db_save,
|
|
};
|
|
|
|
// OCSP database for testing
|
|
static int ocsp_db_load_counter = 0;
|
|
|
|
// this is a dummy ocsp db implementation for the plugin
|
|
typedef struct {
|
|
int dummy;
|
|
} test_ocsp_db;
|
|
|
|
static wget_ocsp_db *test_ocsp_db_init(wget_ocsp_db *ocsp_db, const char *fname)
|
|
{
|
|
(void) fname;
|
|
|
|
if (!ocsp_db)
|
|
ocsp_db = wget_calloc(1, sizeof(test_ocsp_db));
|
|
else
|
|
memset(ocsp_db, 0, sizeof(test_ocsp_db));
|
|
|
|
return ocsp_db;
|
|
}
|
|
|
|
static void test_ocsp_db_deinit(wget_ocsp_db *ocsp_db)
|
|
{
|
|
if (ocsp_db) {
|
|
memset(ocsp_db, 0, sizeof(test_ocsp_db));
|
|
}
|
|
}
|
|
|
|
static void test_ocsp_db_free(wget_ocsp_db **ocsp_db)
|
|
{
|
|
wget_free(*ocsp_db);
|
|
*ocsp_db = NULL;
|
|
}
|
|
|
|
static bool test_ocsp_db_fingerprint_in_cache(const wget_ocsp_db *ocsp_db, const char *fingerprint, int *valid)
|
|
{
|
|
(void) ocsp_db; (void) valid;
|
|
|
|
wget_debug_printf("%s: fingerprint %s\n", __func__, fingerprint);
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool test_ocsp_db_hostname_is_valid(const wget_ocsp_db *ocsp_db, const char *hostname)
|
|
{
|
|
(void) ocsp_db;
|
|
|
|
wget_debug_printf("%s: hostname %s\n", __func__, hostname);
|
|
|
|
return true;
|
|
}
|
|
|
|
static void test_ocsp_db_add_fingerprint(wget_ocsp_db *ocsp_db, const char *fingerprint, int64_t maxage, bool valid)
|
|
{
|
|
(void) ocsp_db;
|
|
|
|
wget_debug_printf("%s: fingerprint %s maxage %lld valid %d\n", __func__, fingerprint, (long long) maxage, valid);
|
|
}
|
|
|
|
static void test_ocsp_db_add_host(wget_ocsp_db *ocsp_db, const char *host, int64_t maxage)
|
|
{
|
|
(void) ocsp_db;
|
|
|
|
wget_debug_printf("%s: host %s maxage %lld\n", __func__, host, (long long) maxage);
|
|
}
|
|
|
|
static int test_ocsp_db_load(wget_ocsp_db *ocsp_db)
|
|
{
|
|
(void) ocsp_db;
|
|
ocsp_db_load_counter++;
|
|
return 0;
|
|
}
|
|
|
|
static int test_ocsp_db_save(wget_ocsp_db *ocsp_db)
|
|
{
|
|
(void) ocsp_db;
|
|
return 0;
|
|
}
|
|
|
|
static const wget_ocsp_db_vtable test_ocsp_db_vtable = {
|
|
.init = test_ocsp_db_init,
|
|
.deinit = test_ocsp_db_deinit,
|
|
.free = test_ocsp_db_free,
|
|
.fingerprint_in_cache = test_ocsp_db_fingerprint_in_cache,
|
|
.hostname_is_valid = test_ocsp_db_hostname_is_valid,
|
|
.add_fingerprint = test_ocsp_db_add_fingerprint,
|
|
.add_host = test_ocsp_db_add_host,
|
|
.load = test_ocsp_db_load,
|
|
.save = test_ocsp_db_save,
|
|
};
|
|
|
|
static void finalizer(WGET_GCC_UNUSED wget_plugin *plugin, WGET_GCC_UNUSED int exit_status)
|
|
{
|
|
if (hpkp_db_load_counter != 1)
|
|
wget_error_printf_exit("wget using wrong HPKP database (%d)\n", hpkp_db_load_counter);
|
|
if (hsts_db_load_counter != 1)
|
|
wget_error_printf_exit("wget using wrong HSTS database (%d)\n", hsts_db_load_counter);
|
|
if (ocsp_db_load_counter != 1)
|
|
wget_error_printf_exit("wget using wrong OCSP database (%d)\n", ocsp_db_load_counter);
|
|
}
|
|
|
|
WGET_EXPORT int wget_plugin_initializer(wget_plugin *plugin);
|
|
int wget_plugin_initializer(wget_plugin *plugin)
|
|
{
|
|
// set the replacement for the standard HPKP database functions
|
|
wget_hpkp_set_plugin(&test_hpkp_db_vtable);
|
|
|
|
// set the replacement for the standard HSTS database functions
|
|
wget_hsts_set_plugin(&test_hsts_db_vtable);
|
|
|
|
// set the replacement for the standard OCSP database functions
|
|
wget_ocsp_set_plugin(&test_ocsp_db_vtable);
|
|
|
|
wget_plugin_register_finalizer(plugin, finalizer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
#error One of the TEST_SELECT_* must be defined to build this file
|
|
#endif
|