898 lines
25 KiB
C
898 lines
25 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* February 22 2024, Christian Hopps <chopps@labn.net>
|
|
*
|
|
* Copyright (C) 2024 LabN Consulting, L.L.C.
|
|
*
|
|
* This program 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 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program 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 this program; see the file COPYING; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#include <zebra.h>
|
|
#include "lib_errors.h"
|
|
#include "northbound.h"
|
|
#include "keychain.h"
|
|
|
|
static void keychain_touch(struct keychain *keychain)
|
|
{
|
|
keychain->last_touch = time(NULL);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain
|
|
*/
|
|
static int key_chains_key_chain_create(struct nb_cb_create_args *args)
|
|
{
|
|
const char *name;
|
|
struct keychain *keychain;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "name");
|
|
keychain = keychain_get(name);
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static int key_chains_key_chain_destroy(struct nb_cb_destroy_args *args)
|
|
{
|
|
const char *name;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "name");
|
|
keychain_delete(keychain_lookup(name));
|
|
return NB_OK;
|
|
}
|
|
|
|
static const void *key_chains_key_chain_get_next(struct nb_cb_get_next_args *args)
|
|
{
|
|
const struct listnode *prev = args->list_entry;
|
|
|
|
return prev ? prev->next : keychain_list->head;
|
|
}
|
|
|
|
static int key_chains_key_chain_get_keys(struct nb_cb_get_keys_args *args)
|
|
{
|
|
const struct listnode *node = args->list_entry;
|
|
const struct keychain *keychain = node->data;
|
|
|
|
args->keys->num = 1;
|
|
strlcpy(args->keys->key[0], keychain->name, sizeof(args->keys->key[0]));
|
|
return NB_OK;
|
|
}
|
|
|
|
static const void *key_chains_key_chain_lookup_entry(struct nb_cb_lookup_entry_args *args)
|
|
{
|
|
const char *name = args->keys->key[0];
|
|
struct keychain *keychain;
|
|
struct listnode *node;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(keychain_list, node, keychain)) {
|
|
if (strcmp(keychain->name, name) == 0)
|
|
return node;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static int __destroy_nop(struct nb_cb_destroy_args *args)
|
|
{
|
|
/* modified by sibling or cleaned up by container destroy */
|
|
return NB_OK;
|
|
}
|
|
|
|
static struct key *__dnode_get_key2(const struct lyd_node *dnode, bool touch)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
name = yang_dnode_get_string(dnode, "../../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(dnode, "../../key-id");
|
|
key = key_lookup(keychain, index);
|
|
if (touch)
|
|
keychain_touch(keychain);
|
|
return key;
|
|
}
|
|
|
|
static struct key *__dnode_get_key3(const struct lyd_node *dnode, bool touch)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
name = yang_dnode_get_string(dnode, "../../../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(dnode, "../../../key-id");
|
|
key = key_lookup(keychain, index);
|
|
if (touch)
|
|
keychain_touch(keychain);
|
|
return key;
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/description
|
|
*/
|
|
static int key_chains_key_chain_description_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../name");
|
|
keychain = keychain_lookup(name);
|
|
XFREE(MTYPE_KEYCHAIN_DESC, keychain->desc);
|
|
keychain->desc = XSTRDUP(MTYPE_KEYCHAIN_DESC,
|
|
yang_dnode_get_string(args->dnode, NULL));
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static int key_chains_key_chain_description_destroy(struct nb_cb_destroy_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../name");
|
|
keychain = keychain_lookup(name);
|
|
XFREE(MTYPE_KEYCHAIN_DESC, keychain->desc);
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/last-modified-timestamp
|
|
*/
|
|
static struct yang_data *key_chains_key_chain_last_modified_timestamp_get_elem(struct nb_cb_get_elem_args *args)
|
|
{
|
|
const struct listnode *kcnode = args->list_entry;
|
|
const struct keychain *keychain = kcnode->data;
|
|
|
|
return yang_data_new_date_and_time(args->xpath, keychain->last_touch,
|
|
false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key
|
|
*/
|
|
static int key_chains_key_chain_key_create(struct nb_cb_create_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
struct key *key;
|
|
const char *name;
|
|
uint64_t keyid;
|
|
|
|
if (args->event != NB_EV_VALIDATE && args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
keyid = yang_dnode_get_uint64(args->dnode, "key-id");
|
|
if (args->event == NB_EV_VALIDATE) {
|
|
if (keyid > UINT32_MAX) {
|
|
/* Warn most protocols can't use this value */
|
|
flog_err(EC_LIB_NB_CB_CONFIG_VALIDATE,
|
|
"Protocols do not accept > 32-bit key-id values");
|
|
return NB_EV_VALIDATE;
|
|
}
|
|
return NB_OK;
|
|
}
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../name");
|
|
keychain = keychain_lookup(name);
|
|
assert(keyid <= UINT32_MAX);
|
|
key = key_get(keychain, (uint32_t)keyid);
|
|
assert(key);
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static int key_chains_key_chain_key_destroy(struct nb_cb_destroy_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
struct key *key;
|
|
const char *name;
|
|
uint64_t keyid;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
keyid = yang_dnode_get_uint64(args->dnode, "key-id");
|
|
if (keyid > UINT32_MAX)
|
|
return NB_ERR_NOT_FOUND;
|
|
name = yang_dnode_get_string(args->dnode, "../name");
|
|
keychain = keychain_lookup(name);
|
|
key = key_lookup(keychain, (uint32_t)keyid);
|
|
key_delete(keychain, key);
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static const void *key_chains_key_chain_key_get_next(struct nb_cb_get_next_args *args)
|
|
{
|
|
const struct listnode *kcnode = args->parent_list_entry;
|
|
const struct keychain *keychain = kcnode->data;
|
|
const struct listnode *prev = args->list_entry;
|
|
|
|
return prev ? prev->next : keychain->key->head;
|
|
}
|
|
|
|
static int key_chains_key_chain_key_get_keys(struct nb_cb_get_keys_args *args)
|
|
{
|
|
const struct listnode *node = args->list_entry;
|
|
const struct key *key = node->data;
|
|
|
|
args->keys->num = 1;
|
|
snprintf(args->keys->key[0], sizeof(args->keys->key[0]), "%" PRIu32,
|
|
key->index);
|
|
|
|
return NB_OK;
|
|
}
|
|
|
|
static const void *key_chains_key_chain_key_lookup_entry(struct nb_cb_lookup_entry_args *args)
|
|
{
|
|
const struct listnode *kcnode = args->parent_list_entry;
|
|
const struct keychain *keychain = kcnode->data;
|
|
struct listnode *node;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
index = strtoul(args->keys->key[0], NULL, 0);
|
|
for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key))
|
|
if (key->index == index)
|
|
return node;
|
|
return NULL;
|
|
}
|
|
|
|
static int __lifetime_create(struct nb_cb_create_args *args, bool send,
|
|
bool accept, bool always)
|
|
{
|
|
struct key *key;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
if (always)
|
|
key = __dnode_get_key3(args->dnode, true);
|
|
else
|
|
key = __dnode_get_key2(args->dnode, true);
|
|
if (send) {
|
|
key->send.start = 0;
|
|
key->send.end = -1;
|
|
key->send.duration = 0;
|
|
}
|
|
if (accept) {
|
|
key->accept.start = 0;
|
|
key->accept.end = -1;
|
|
key->accept.duration = 0;
|
|
}
|
|
return NB_OK;
|
|
}
|
|
|
|
static int __lifetime_start_date_time_modify(struct nb_cb_modify_args *args,
|
|
bool send, bool accept)
|
|
{
|
|
struct key *key;
|
|
time_t time;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
key = __dnode_get_key3(args->dnode, true);
|
|
time = yang_dnode_get_date_and_time(args->dnode, NULL);
|
|
|
|
if (send)
|
|
key->send.start = time;
|
|
if (accept)
|
|
key->accept.start = time;
|
|
|
|
return NB_OK;
|
|
}
|
|
|
|
static int __lifetime_no_end_time_create(struct nb_cb_create_args *args,
|
|
bool send, bool accept)
|
|
{
|
|
struct key *key;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
key = __dnode_get_key3(args->dnode, true);
|
|
if (send)
|
|
key->send.end = -1;
|
|
if (accept)
|
|
key->accept.end = -1;
|
|
return NB_OK;
|
|
}
|
|
|
|
static int __lifetime_duration_modify(struct nb_cb_modify_args *args, bool send,
|
|
bool accept)
|
|
{
|
|
struct key *key;
|
|
uint32_t duration;
|
|
time_t time;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
key = __dnode_get_key3(args->dnode, true);
|
|
time = yang_dnode_get_date_and_time(args->dnode, "../start-date-time");
|
|
duration = yang_dnode_get_uint32(args->dnode, NULL);
|
|
|
|
if (send)
|
|
key->send.end = time + duration;
|
|
if (accept)
|
|
key->accept.end = time + duration;
|
|
return NB_OK;
|
|
}
|
|
|
|
static int __lifetime_end_date_time_modify(struct nb_cb_modify_args *args,
|
|
bool send, bool accept)
|
|
{
|
|
struct key *key;
|
|
time_t time;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
key = __dnode_get_key3(args->dnode, true);
|
|
time = yang_dnode_get_date_and_time(args->dnode, NULL);
|
|
|
|
if (send)
|
|
key->send.end = time;
|
|
if (accept)
|
|
key->accept.end = time;
|
|
return NB_OK;
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_accept_lifetime_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
|
|
return __lifetime_create(args, true, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_accept_lifetime_always_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_create(args, true, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time
|
|
*/
|
|
static int
|
|
key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_modify(
|
|
struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_start_date_time_modify(args, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time
|
|
*/
|
|
static int
|
|
key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_no_end_time_create(args, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_modify(
|
|
struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_duration_modify(args, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time
|
|
*/
|
|
static int
|
|
key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_modify(
|
|
struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_end_date_time_modify(args, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
|
|
return __lifetime_create(args, true, false, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_always_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_create(args, true, false, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/start-date-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_start_date_time_modify(args, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/no-end-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_create(struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_no_end_time_create(args, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/duration
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_duration_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_duration_modify(args, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/end-date-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_end_date_time_modify(args, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_create(
|
|
struct nb_cb_create_args *args)
|
|
{
|
|
|
|
return __lifetime_create(args, false, true, false);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/always
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_always_create(struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_create(args, false, true, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/start-date-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_start_date_time_modify(args, false, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/no-end-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_create(struct nb_cb_create_args *args)
|
|
{
|
|
return __lifetime_no_end_time_create(args, false, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/duration
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_duration_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_duration_modify(args, false, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/end-date-time
|
|
*/
|
|
static int key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
return __lifetime_end_date_time_modify(args, false, true);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/crypto-algorithm
|
|
*/
|
|
static int key_chains_key_chain_key_crypto_algorithm_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
static const char prefix[] = "ietf-key-chain:";
|
|
static const int prefix_len = sizeof(prefix) - 1;
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
uint8_t hash_algo;
|
|
|
|
if (args->event != NB_EV_VALIDATE && args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, NULL);
|
|
if (!strncmp(name, prefix, prefix_len))
|
|
name += prefix_len;
|
|
hash_algo = keychain_get_algo_id_by_name(name);
|
|
|
|
if (args->event == NB_EV_VALIDATE) {
|
|
if (!hash_algo) {
|
|
zlog_err("\"%s\" hash algo not supported", name);
|
|
return NB_ERR_VALIDATION;
|
|
}
|
|
#ifndef CRYPTO_OPENSSL
|
|
if (hash_algo == KEYCHAIN_ALGO_NULL) {
|
|
zlog_err("\"%s\" algo not supported, compile with --with-crypto=openssl",
|
|
name);
|
|
return NB_ERR_VALIDATION;
|
|
}
|
|
#endif /* CRYPTO_OPENSSL */
|
|
return NB_OK;
|
|
}
|
|
|
|
assert(args->event == NB_EV_APPLY);
|
|
name = yang_dnode_get_string(args->dnode, "../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../key-id");
|
|
key = key_lookup(keychain, index);
|
|
key->hash_algo = hash_algo;
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static int key_chains_key_chain_key_crypto_algorithm_destroy(
|
|
struct nb_cb_destroy_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id");
|
|
key = key_lookup(keychain, index);
|
|
key->hash_algo = KEYCHAIN_ALGO_NULL;
|
|
keychain_touch(keychain);
|
|
|
|
return NB_OK;
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/key-string/keystring
|
|
*/
|
|
static int key_chains_key_chain_key_key_string_keystring_modify(struct nb_cb_modify_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id");
|
|
key = key_lookup(keychain, index);
|
|
assert(key);
|
|
|
|
|
|
if (key->string)
|
|
XFREE(MTYPE_KEY, key->string);
|
|
key->string = XSTRDUP(MTYPE_KEY,
|
|
yang_dnode_get_string(args->dnode, NULL));
|
|
|
|
keychain_touch(keychain);
|
|
return NB_OK;
|
|
}
|
|
|
|
static int key_chains_key_chain_key_key_string_keystring_destroy(struct nb_cb_destroy_args *args)
|
|
{
|
|
struct keychain *keychain;
|
|
const char *name;
|
|
struct key *key;
|
|
uint32_t index;
|
|
|
|
if (args->event != NB_EV_APPLY)
|
|
return NB_OK;
|
|
|
|
name = yang_dnode_get_string(args->dnode, "../../../name");
|
|
keychain = keychain_lookup(name);
|
|
index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id");
|
|
key = key_lookup(keychain, index);
|
|
assert(key);
|
|
|
|
XFREE(MTYPE_KEY, key->string);
|
|
keychain_touch(keychain);
|
|
|
|
return NB_OK;
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/send-lifetime-active
|
|
*/
|
|
static struct yang_data *key_chains_key_chain_key_send_lifetime_active_get_elem(struct nb_cb_get_elem_args *args)
|
|
{
|
|
const struct listnode *node = args->list_entry;
|
|
const struct key *key = node->data;
|
|
time_t now = time(NULL);
|
|
bool active = false;
|
|
|
|
if (key->send.start == 0)
|
|
active = true;
|
|
else if (key->send.start <= now)
|
|
if (key->send.end >= now || key->send.end == -1)
|
|
active = true;
|
|
|
|
return yang_data_new_bool(args->xpath, active);
|
|
}
|
|
|
|
/*
|
|
* XPath: /ietf-key-chain:key-chains/key-chain/key/accept-lifetime-active
|
|
*/
|
|
static struct yang_data *key_chains_key_chain_key_accept_lifetime_active_get_elem(struct nb_cb_get_elem_args *args)
|
|
{
|
|
const struct listnode *node = args->list_entry;
|
|
const struct key *key = node->data;
|
|
time_t now = time(NULL);
|
|
bool active = false;
|
|
|
|
if (key->accept.start == 0)
|
|
active = true;
|
|
else if (key->accept.start <= now)
|
|
if (key->accept.end >= now || key->accept.end == -1)
|
|
active = true;
|
|
|
|
return yang_data_new_bool(args->xpath, active);
|
|
}
|
|
|
|
static const char * const keychain_features[] = {
|
|
"independent-send-accept-lifetime",
|
|
NULL,
|
|
};
|
|
|
|
/* clang-format off */
|
|
const struct frr_yang_module_info ietf_key_chain_info = {
|
|
.name = "ietf-key-chain",
|
|
.features = (const char **)keychain_features,
|
|
.nodes = {
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_create,
|
|
.destroy = key_chains_key_chain_destroy,
|
|
.get_next = key_chains_key_chain_get_next,
|
|
.get_keys = key_chains_key_chain_get_keys,
|
|
.lookup_entry = key_chains_key_chain_lookup_entry,
|
|
.cli_show = key_chains_key_chain_cli_write,
|
|
.cli_show_end = key_chains_key_chain_cli_write_end,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/description",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_description_modify,
|
|
.destroy = key_chains_key_chain_description_destroy,
|
|
.cli_show = key_chains_key_chain_description_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/last-modified-timestamp",
|
|
.cbs = {
|
|
.get_elem = key_chains_key_chain_last_modified_timestamp_get_elem,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_create,
|
|
.destroy = key_chains_key_chain_key_destroy,
|
|
.get_next = key_chains_key_chain_key_get_next,
|
|
.get_keys = key_chains_key_chain_key_get_keys,
|
|
.lookup_entry = key_chains_key_chain_key_lookup_entry,
|
|
.cli_show = key_chains_key_chain_key_cli_write,
|
|
.cli_show_end = key_chains_key_chain_key_cli_write_end,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_accept_lifetime_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_accept_lifetime_always_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
.cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_lifetime_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_lifetime_always_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/start-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
.cli_show = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/no-end-time",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/duration",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_lifetime_duration_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/end-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_accept_lifetime_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/always",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_accept_lifetime_always_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/start-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
.cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/no-end-time",
|
|
.cbs = {
|
|
.create = key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_create,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/duration",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_accept_lifetime_duration_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/end-date-time",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_modify,
|
|
.destroy = __destroy_nop,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/crypto-algorithm",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_crypto_algorithm_modify,
|
|
.destroy = key_chains_key_chain_key_crypto_algorithm_destroy,
|
|
.cli_show = key_chains_key_chain_key_crypto_algorithm_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/key-string/keystring",
|
|
.cbs = {
|
|
.modify = key_chains_key_chain_key_key_string_keystring_modify,
|
|
.destroy = key_chains_key_chain_key_key_string_keystring_destroy,
|
|
.cli_show = key_chains_key_chain_key_key_string_keystring_cli_write,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/send-lifetime-active",
|
|
.cbs = {
|
|
.get_elem = key_chains_key_chain_key_send_lifetime_active_get_elem,
|
|
}
|
|
},
|
|
{
|
|
.xpath = "/ietf-key-chain:key-chains/key-chain/key/accept-lifetime-active",
|
|
.cbs = {
|
|
.get_elem = key_chains_key_chain_key_accept_lifetime_active_get_elem,
|
|
}
|
|
},
|
|
{
|
|
.xpath = NULL,
|
|
},
|
|
},
|
|
};
|