Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for certificate expiration notifications #493

Merged
merged 18 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeModules/UseCompat.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ macro(USE_COMPAT)

check_symbol_exists(get_current_dir_name "unistd.h" HAVE_GET_CURRENT_DIR_NAME)

check_function_exists(timegm HAVE_TIMEGM)

# crypt
check_include_file("crypt.h" HAVE_CRYPT_H)

Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ The *libnetconf2* NETCONF server has two APIs that load YANG modules into the co
- **ietf-netconf**: writable-running, candidate, rollback-on-error, validate, startup, url, xpath, confirmed-commit,
- **ietf-netconf-monitoring**: no features.

The second API is [nc_server_config_load_modules](https://netopeer.liberouter.org/doc/libnetconf2/master/html/group__server__config__functions.html#ga3760b87e3ab4309514e9ad82c4c09cdb). Supported features (marked by ✔) are loaded into the context by this API. The only exception is the feature `local-users-supported`, which is by default loaded, but can be disabled, which will influence the behaviour of the SSH authentication (see the *libnetconf2* [documentation](https://netopeer.liberouter.org/doc/libnetconf2/master/html/howtoserver.html)).
The second API is [nc_server_config_load_modules](https://netopeer.liberouter.org/doc/libnetconf2/master/html/group__server__config__functions.html#ga3760b87e3ab4309514e9ad82c4c09cdb). Supported features (marked by ✔) are loaded into the context by this API.

- **iana-crypt-hash**: crypt-hash-md5 ✔, crypt-hash-sha-256 ✔, crypt-hash-sha-512 ✔,
- **ietf-netconf-server**: ssh-listen ✔, tls-listen ✔, ssh-call-home ✔, tls-call-home ✔, central-netconf-server-supported ✔,
Expand All @@ -265,7 +265,7 @@ The second API is [nc_server_config_load_modules](https://netopeer.liberouter.or
- **iana-ssh-mac-algs**: no features,
- **iana-ssh-public-key-algs**: no features,
- **iana-tls-cipher-suite-algs**: no features,
- **ietf-crypto-types**: cleartext-passwords ✔, cleartext-private-keys ✔, private-key-encryption ✘, csr-generation ✘, p10-csr-format ✘, certificate-expiration-notification , encrypted-passwords ✘, hidden-symmetric-keys ✘, encrypted-symmetric-keys ✘, hidden-private-keys ✘, encrypted-private-keys ✘, one-symmetric-key-format ✘, one-asymmetric-key-format ✘, symmetrically-encrypted-value-format ✘, asymmetrically-encrypted-value-format ✘, cms-enveloped-data-format ✘, cms-encrypted-data-format ✘, cleartext-symmetric-keys ✘,
- **ietf-crypto-types**: cleartext-passwords ✔, cleartext-private-keys ✔, private-key-encryption ✘, csr-generation ✘, p10-csr-format ✘, certificate-expiration-notification **?**, encrypted-passwords ✘, hidden-symmetric-keys ✘, encrypted-symmetric-keys ✘, hidden-private-keys ✘, encrypted-private-keys ✘, one-symmetric-key-format ✘, one-asymmetric-key-format ✘, symmetrically-encrypted-value-format ✘, asymmetrically-encrypted-value-format ✘, cms-enveloped-data-format ✘, cms-encrypted-data-format ✘, cleartext-symmetric-keys ✘,
- **ietf-keystore**: central-keystore-supported ✔, inline-definitions-supported ✔, asymmetric-keys ✔, symmetric-keys ✘,
- **ietf-netconf-server**: ssh-listen ✔, tls-listen ✔, ssh-call-home ✔, tls-call-home ✔, central-netconf-server-supported ✔,
- **ietf-ssh-common**: transport-params ✔, ssh-x509-certs ✘, public-key-generation ✘,
Expand All @@ -279,6 +279,11 @@ The second API is [nc_server_config_load_modules](https://netopeer.liberouter.or
- **ietf-x509-cert-to-name**: no features,
- **libnetconf2-netconf-server**: no features.

The following features can be enabled/disabled to influence the behaviour of the `libnetconf2` NETCONF server:

- `local-users-supported` - enabled by default, disable to change the behaviour of the SSH authentication (see the *libnetconf2* [documentation](https://netopeer.liberouter.org/doc/libnetconf2/master/html/howtoserver.html)).
- `certificate-expiration-notification` - disabled by default, but certificate expiration notifications are supported and you can enable this feature to create such YANG data (see the *libnetconf2* documentation).

### Client

Currently no client specific YANG modules are supported.
34 changes: 34 additions & 0 deletions compat/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,37 @@ crypt_r(const char *phrase, const char *setting, struct crypt_data *data)
}

#endif

#ifndef HAVE_TIMEGM
time_t
timegm(struct tm *tm)
{
pthread_mutex_t tz_lock = PTHREAD_MUTEX_INITIALIZER;
time_t ret;
char *tz;

pthread_mutex_lock(&tz_lock);

tz = getenv("TZ");
if (tz) {
tz = strdup(tz);
}
setenv("TZ", "", 1);
tzset();

ret = mktime(tm);

if (tz) {
setenv("TZ", tz, 1);
free(tz);
} else {
unsetenv("TZ");
}
tzset();

pthread_mutex_unlock(&tz_lock);

return ret;
}

#endif
5 changes: 5 additions & 0 deletions compat/compat.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
#cmakedefine HAVE_STRCHRNUL
#cmakedefine HAVE_GET_CURRENT_DIR_NAME
#cmakedefine HAVE_CRYPT_R
#cmakedefine HAVE_TIMEGM

#ifndef bswap64
#define bswap64(val) \
Expand Down Expand Up @@ -222,4 +223,8 @@ struct crypt_data {
char *crypt_r(const char *phrase, const char *setting, struct crypt_data *data);
#endif

#ifndef HAVE_TIMEGM
time_t timegm(struct tm *tm);
#endif

#endif /* _COMPAT_H_ */
19 changes: 19 additions & 0 deletions doc/libnetconf.doc
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,13 @@
* this request with ::nc_ps_accept_ssh_channel() or ::nc_session_accept_ssh_channel()
* depending on the structure you want to use as the argument.
*
* The server-side notifications are also supported. You can create a new notification
* with ::nc_server_notif_new() and send it via ::nc_server_notif_send() to subscribed clients.
* Keep in mind that the session you wish to send a notification on has to have at least one
* subscriber, see ::nc_session_inc_notif_status().
* Currently, only notifications about certificate expiration are implemented,
* see ::nc_server_notif_cert_expiration_thread_start().
*
* Functions List
* --------------
*
Expand All @@ -665,6 +672,18 @@
* - ::nc_ps_clear()
* - ::nc_ps_accept_ssh_channel()
* - ::nc_session_accept_ssh_channel()
*
* - ::nc_server_notif_new()
* - ::nc_server_notif_send()
* - ::nc_server_notif_free()
* - ::nc_server_notif_get_time()

* - ::nc_session_inc_notif_status()
* - ::nc_session_dec_notif_status()
* - ::nc_session_get_notif_status()

* - ::nc_server_notif_cert_expiration_thread_start()
* - ::nc_server_notif_cert_expiration_thread_stop()
*/

/**
Expand Down
76 changes: 73 additions & 3 deletions [email protected][email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ module libnetconf2-netconf-server {
prefix tlss;
}

revision "2024-01-15" {
description "Initial revision.";
revision "2024-07-09" {
description "Second revision.";
}

/*
// Identities

/*
identity ed25519-private-key-format {
base ct:private-key-format;
description
Expand Down Expand Up @@ -240,6 +242,20 @@ module libnetconf2-netconf-server {
https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD";
}

// Typedefs

typedef time-period {
type string {
pattern '(1[0-2]|[1-9])m|[1-4]w|[1-7]d|(2[0-4]|1[0-9]|[1-9])h';
}

description
"The time-period type allows to specify time in either months, weeks, days, or hours.
Its purpose is to create time intervals for the certificate expiration notifications.";
}

// Groupings

grouping ssh-authentication-params-grouping {
description
"Grouping for SSH authentication parameters.";
Expand Down Expand Up @@ -322,6 +338,8 @@ module libnetconf2-netconf-server {
}
}

// Augments

augment "/ncs:netconf-server/ncs:listen/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh" +
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
uses ssh-authentication-params-grouping;
Expand Down Expand Up @@ -375,4 +393,56 @@ module libnetconf2-netconf-server {
"/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
uses endpoint-reference-grouping;
}

// Protocol-accessible Nodes

container ln2-netconf-server {
container certificate-expiration-notif-intervals {
if-feature "ct:certificate-expiration-notification";

description
"Container for the certificate expiration notification intervals.
Its child nodes describe the ability to set the time intervals for the certificate
expiration notifications. These intervals are given in the form of an anchor and a period.
By default, these notifications are generated 3, 2, and 1 month; 2 weeks; 7, 6, 5, 4, 3, 2 and 1 day before a certificate expires.
Additionally, notifications are generated on the day of expiration and every day thereafter.

Simplified example of YANG data that describe the default intervals:

Anchor Period
3m ... 1m
2w ... 1w
7d ... 1d
";

list interval {
key "anchor period";

leaf anchor {
type time-period;

description
"The time anchor for the notification. The anchor is the time
before the certificate expiration when a notification will be sent.
It is essentially the lower bound of the given interval.";
}
leaf period {
type time-period;

// Require the period to be smaller than the anchor (only units are checked for simplicity)
must "(contains(., 'm') and contains(../anchor, 'm')) or
(contains(., 'w') and (contains(../anchor, 'm') or contains(../anchor, 'w'))) or
(contains(., 'd') and (contains(../anchor, 'm') or contains(../anchor, 'w') or contains(../anchor, 'd'))) or
contains(., 'h')" {
error-message
"Certificate expiration notification period must be smaller than the anchor.";
}

description
"The period of the notification. The period is the time
between two notifications within the given time interval.";
}
}
}
}
}
8 changes: 4 additions & 4 deletions src/messages_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,11 @@ void nc_server_reply_free(struct nc_server_reply *reply);
* @brief Create Event Notification object to be sent to the subscribed client(s).
*
* @param[in] event Notification data tree (valid as LYD_OPT_NOTIF) from libyang. The tree is directly used in created
* object, so the caller is supposed to not free the tree on its own, but only via freeng the created object.
* object, so the caller is supposed to not free the tree on its own, but only via freeing the created object.
* @param[in] eventtime YANG dateTime format value of the time when the event was generated by the event source.
* Caller can use nc_timespec2datetime() to create the value from a timespec value.
* @param[in] paramtype How to further manage data parameters.
* @return Newly created structure of the Event Notification object to be sent to the clients via nc_server_send_notif()
* @return Newly created structure of the Event Notification object to be sent to the clients via nc_server_notif_send()
* and freed using nc_server_notif_free().
*/
struct nc_server_notif *nc_server_notif_new(struct lyd_node *event, char *eventtime, NC_PARAMTYPE paramtype);
Expand All @@ -310,8 +310,8 @@ struct nc_server_notif *nc_server_notif_new(struct lyd_node *event, char *eventt
* @brief Send NETCONF Event Notification via the session.
*
* @param[in] session NETCONF session where the Event Notification will be written.
* @param[in] notif NETCOFN Notification object to send via specified session. Object can be created by
* nc_notif_new() function.
* @param[in] notif NETCONF Notification object to send via specified session. Object can be created by
* nc_server_notif_new() function.
* @param[in] timeout Timeout for writing in milliseconds. Use negative value for infinite
* waiting and 0 for return if data cannot be sent immediately.
* @return #NC_MSG_NOTIF on success,
Expand Down
Loading