1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/// @file load_unload.cc Defines the load and unload hooks library functions.

#include <config.h>

#include <hooks/hooks.h>
#include <user_chk_log.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <user_registry.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <user_file.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <iostream><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <fstream><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <errno.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

using namespace isc::hooks;
using namespace user_chk;

/// @brief Pointer to the registry instance.
UserRegistryPtr user_registry;

/// @brief Output filestream for recording user check outcomes.
std::fstream user_chk_output;

/// @brief User registry input file name.
/// @todo Hard-coded for now, this should be configurable.
const char* registry_fname = "/tmp/user_chk_registry.txt";

/// @brief User check outcome file name.
/// @todo Hard-coded for now, this should be configurable.
const char* user_chk_output_fname = "/tmp/user_chk_outcome.txt";

/// @brief Text label of user id in the inbound query in callout context
const char* query_user_id_label = "query_user_id";

/// @brief Text label of registered user pointer in callout context
const char* registered_user_label = "registered_user";

/// @brief Text id used to identify the default IPv4 user in the registry
/// The format is a string containing an even number of hex digits.  This
/// value is to look up the default IPv4 user in the user registry for the
/// the purpose of retrieving default values for user options.
const char* default_user4_id_str = "00000000";

/// @brief Text id used to identify the default IPv6 user in the registry
/// The format is a string containing an even number of hex digits.  This
/// value is to look up the default IPv6 user in the user registry for the
/// the purpose of retrieving default values for user options.
const char *default_user6_id_str = "00000000";

// Functions accessed by the hooks framework use C linkage to avoid the name
// mangling that accompanies use of the C++ compiler as well as to avoid
// issues related to namespaces.
extern "C" {

/// @brief Called by the Hooks library manager when the library is loaded.
///
/// Instantiates the UserRegistry and opens the outcome file. Failure in
/// either results in a failed return code.
///
/// @return Returns 0 upon success, non-zero upon failure.
int load(LibraryHandle&) {
    // non-zero indicates an error.
    int ret_val = 0;

    try {
        // If the hook library is dedicated to a specific server(s)
        // please check here process name (Daemon::getProcName() from
        // the process library).

        // Instantiate the registry.
        user_registry.reset(new UserRegistry());

        // Create the data source.
        UserDataSourcePtr user_file(new UserFile(registry_fname));

        // Set the registry's data source
        user_registry->setSource(user_file);

        // Do an initial load of the registry.
        user_registry->refresh();

        // zero out the errno to be safe
        errno = 0;

        // Open up the output file for user_chk results.
        user_chk_output.open(user_chk_output_fname,
                     std::fstream::out | std::fstream::app);

        if (!user_chk_output) {
            // Grab the system error message.
            const char* errmsg = strerror(errno);
            isc_throw(isc::Unexpected, "Cannot open output file: "
                                       << user_chk_output_fname
                                       << " reason: " << errmsg);
        }
    }
    catch (const std::exception& ex) {
        // Log the error and return failure.
        LOG_ERROR(user_chk_logger, USER_CHK_HOOK_LOAD_ERROR)
            .arg(ex.what());
        ret_val = 1;
    }

    return (ret_val);
}

/// @brief Called by the Hooks library manager when the library is unloaded.
///
/// Destroys the UserRegistry and closes the outcome file.
///
/// @return Always returns 0.
int unload() {
    try {
        user_registry.reset();
        if (user_chk_output.is_open()) {
            user_chk_output.close();
        }
    } catch (const std::exception& ex) {
        // On the off chance something goes awry, catch it and log it.
        // @todo Not sure if we should return a non-zero result or not.
        LOG_ERROR(user_chk_logger, USER_CHK_HOOK_UNLOAD_ERROR)
            .arg(ex.what());
    }

    return (0);
}

}