mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
confd: Add YANG pattern constraints for string leaves
Add input validation patterns to string-type leaves in container, firewall, DHCP, and interface YANG models. Also use mkdtemp() for temporary key files in keystore. Signed-off-by: Mattias Walström <lazzer@gmail.com>
This commit is contained in:
+1
-1
@@ -2,6 +2,7 @@
|
|||||||
.claude
|
.claude
|
||||||
.gdb_history
|
.gdb_history
|
||||||
.claude
|
.claude
|
||||||
|
AGENTS.md
|
||||||
/.backup
|
/.backup
|
||||||
/.ccache
|
/.ccache
|
||||||
/dl
|
/dl
|
||||||
@@ -11,4 +12,3 @@
|
|||||||
/test/.log
|
/test/.log
|
||||||
/local.mk
|
/local.mk
|
||||||
/test/spec/Readme.adoc
|
/test/spec/Readme.adoc
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,6 @@
|
|||||||
|
|
||||||
#define XPATH_KEYSTORE_ASYM "/ietf-keystore:keystore/asymmetric-keys"
|
#define XPATH_KEYSTORE_ASYM "/ietf-keystore:keystore/asymmetric-keys"
|
||||||
#define XPATH_KEYSTORE_SYM "/ietf-keystore:keystore/symmetric-keys"
|
#define XPATH_KEYSTORE_SYM "/ietf-keystore:keystore/symmetric-keys"
|
||||||
#define SSH_PRIVATE_KEY "/tmp/ssh.key"
|
|
||||||
#define SSH_PUBLIC_KEY "/tmp/ssh.pub"
|
|
||||||
|
|
||||||
/* return file size */
|
/* return file size */
|
||||||
static size_t filesz(const char *fn)
|
static size_t filesz(const char *fn)
|
||||||
@@ -91,6 +89,9 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
char tmpdir[] = "/tmp/keystore.XXXXXX";
|
||||||
|
char priv_path[sizeof(tmpdir) + 16];
|
||||||
|
char pub_path[sizeof(tmpdir) + 16];
|
||||||
char *name = srx_get_str(session, "%s/name", list[i].xpath);
|
char *name = srx_get_str(session, "%s/name", list[i].xpath);
|
||||||
char *public_key_format, *private_key_format;
|
char *public_key_format, *private_key_format;
|
||||||
char *pub_key = NULL, *priv_key = NULL;
|
char *pub_key = NULL, *priv_key = NULL;
|
||||||
@@ -115,16 +116,24 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
NOTE("SSH key (%s) does not exist, generating...", name);
|
NOTE("SSH key (%s) does not exist, generating...", name);
|
||||||
if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) {
|
|
||||||
|
if (!mkdtemp(tmpdir)) {
|
||||||
|
ERRNO("Failed creating temp dir for SSH key generation");
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
snprintf(priv_path, sizeof(priv_path), "%s/ssh.key", tmpdir);
|
||||||
|
snprintf(pub_path, sizeof(pub_path), "%s/ssh.pub", tmpdir);
|
||||||
|
|
||||||
|
if (systemf("/usr/libexec/infix/mkkeys %s %s", priv_path, pub_path)) {
|
||||||
ERROR("Failed generating SSH keys for %s", name);
|
ERROR("Failed generating SSH keys for %s", name);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY));
|
priv_key = filerd(priv_path, filesz(priv_path));
|
||||||
if (!priv_key)
|
if (!priv_key)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY));
|
pub_key = filerd(pub_path, filesz(pub_path));
|
||||||
if (!pub_key)
|
if (!pub_key)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
@@ -140,10 +149,8 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
next:
|
next:
|
||||||
if (erase(SSH_PRIVATE_KEY))
|
if (rmrf(tmpdir))
|
||||||
ERRNO("Failed removing SSH server private key");
|
ERRNO("Failed removing temp dir %s", tmpdir);
|
||||||
if (erase(SSH_PUBLIC_KEY))
|
|
||||||
ERRNO("Failed removing SSH server public key");
|
|
||||||
|
|
||||||
if (priv_key)
|
if (priv_key)
|
||||||
free(priv_key);
|
free(priv_key);
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ module infix-containers {
|
|||||||
prefix infix-sys;
|
prefix infix-sys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
revision 2026-02-23 {
|
||||||
|
description "Input validation improvements";
|
||||||
|
reference "internal";
|
||||||
|
}
|
||||||
|
|
||||||
revision 2025-12-09 {
|
revision 2025-12-09 {
|
||||||
description "Add resource management:
|
description "Add resource management:
|
||||||
- Add resource-limit container with memory and cpu configuration.
|
- Add resource-limit container with memory and cpu configuration.
|
||||||
@@ -84,6 +89,17 @@ module infix-containers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef image-reference {
|
||||||
|
description "OCI image reference or transport URI.
|
||||||
|
Allows registry references (e.g., quay.io/user/image:tag),
|
||||||
|
transport prefixes (docker://, oci-archive:, dir:), and
|
||||||
|
download URLs (ftp://, http://, https://).";
|
||||||
|
type string {
|
||||||
|
pattern '[a-zA-Z0-9][a-zA-Z0-9_./:@=+%~-]*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef mount-type {
|
typedef mount-type {
|
||||||
type enumeration {
|
type enumeration {
|
||||||
enum bind {
|
enum bind {
|
||||||
@@ -181,7 +197,7 @@ module infix-containers {
|
|||||||
container will be put on a queue that retries pull every time
|
container will be put on a queue that retries pull every time
|
||||||
there is a route change in the host's system.";
|
there is a route change in the host's system.";
|
||||||
mandatory true;
|
mandatory true;
|
||||||
type string;
|
type image-reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
container checksum {
|
container checksum {
|
||||||
@@ -240,7 +256,9 @@ module infix-containers {
|
|||||||
|
|
||||||
leaf command {
|
leaf command {
|
||||||
description "Override ENTRYPOINT from image and run command + args.";
|
description "Override ENTRYPOINT from image and run command + args.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[a-zA-Z0-9_./ :=@%^,+-]+';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf hostname {
|
leaf hostname {
|
||||||
@@ -298,7 +316,9 @@ module infix-containers {
|
|||||||
NOTE: Some (*) options only work with masquerading container bridges,
|
NOTE: Some (*) options only work with masquerading container bridges,
|
||||||
which automatically create VETH pairs with one end in the host
|
which automatically create VETH pairs with one end in the host
|
||||||
bridge and the other in the container.";
|
bridge and the other in the container.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[a-zA-Z_][a-zA-Z0-9_]*=[a-zA-Z0-9.:_/-]+';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +330,9 @@ module infix-containers {
|
|||||||
Sample: 8080:80 -- forward tcp port 8080 to container port 80
|
Sample: 8080:80 -- forward tcp port 8080 to container port 80
|
||||||
69:69/udp -- forward udp port 69 to container port 69
|
69:69/udp -- forward udp port 69 to container port 69
|
||||||
127.0.0.1:8080:80 -- forward only from loopback interface";
|
127.0.0.1:8080:80 -- forward only from loopback interface";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[0-9.:\[\]]+(/[a-zA-Z]+)?';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf-list dns {
|
leaf-list dns {
|
||||||
@@ -464,7 +486,7 @@ module infix-containers {
|
|||||||
When mounting files, directories (and globs) from the host,
|
When mounting files, directories (and globs) from the host,
|
||||||
the source must be an absolute path.";
|
the source must be an absolute path.";
|
||||||
type string {
|
type string {
|
||||||
pattern '/.*';
|
pattern '/[a-zA-Z0-9_./*?-]+([ ]?[a-zA-Z0-9_./*?-]+)*';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,7 +515,7 @@ module infix-containers {
|
|||||||
or import the text file using the 'content' node.";
|
or import the text file using the 'content' node.";
|
||||||
mandatory true;
|
mandatory true;
|
||||||
type string {
|
type string {
|
||||||
pattern '/.*';
|
pattern '/[a-zA-Z0-9_./-]+(/[a-zA-Z0-9_./-]+)*';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +567,7 @@ module infix-containers {
|
|||||||
description "Absolute path to target destination directory inside the container.";
|
description "Absolute path to target destination directory inside the container.";
|
||||||
mandatory true;
|
mandatory true;
|
||||||
type string {
|
type string {
|
||||||
pattern '/.*';
|
pattern '/[a-zA-Z0-9_./-]+(/[a-zA-Z0-9_./-]+)*';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -593,12 +615,12 @@ module infix-containers {
|
|||||||
input {
|
input {
|
||||||
leaf uri {
|
leaf uri {
|
||||||
description "The URL or local file path, e.g., /lib/oci/archive.tar.gz";
|
description "The URL or local file path, e.g., /lib/oci/archive.tar.gz";
|
||||||
type string;
|
type image-reference;
|
||||||
mandatory true;
|
mandatory true;
|
||||||
}
|
}
|
||||||
leaf name {
|
leaf name {
|
||||||
description "Image name[:tag], default: basename of archive dir + :latest";
|
description "Image name[:tag], default: basename of archive dir + :latest";
|
||||||
type string;
|
type image-reference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,9 @@ module infix-dhcp-server {
|
|||||||
case default-opt {
|
case default-opt {
|
||||||
leaf string {
|
leaf string {
|
||||||
description "Generic string value.";
|
description "Generic string value.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +152,9 @@ module infix-dhcp-server {
|
|||||||
|
|
||||||
leaf description {
|
leaf description {
|
||||||
description "Additional information about this subnet (e.g., purpose, location, or notes).";
|
description "Additional information about this subnet (e.g., purpose, location, or notes).";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf enabled {
|
leaf enabled {
|
||||||
@@ -206,7 +210,9 @@ module infix-dhcp-server {
|
|||||||
|
|
||||||
leaf description {
|
leaf description {
|
||||||
description "Additional information about this entry, e.g., owner's name, equipment details, or location.";
|
description "Additional information about this entry, e.g., owner's name, equipment details, or location.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container match {
|
container match {
|
||||||
|
|||||||
@@ -201,7 +201,9 @@ module infix-firewall {
|
|||||||
|
|
||||||
leaf description {
|
leaf description {
|
||||||
description "Free-form description of the zone.";
|
description "Free-form description of the zone.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}<>&]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf-list interface {
|
leaf-list interface {
|
||||||
@@ -304,7 +306,9 @@ module infix-firewall {
|
|||||||
|
|
||||||
leaf description {
|
leaf description {
|
||||||
description "Free-form description of this policy's purpose and scope.";
|
description "Free-form description of this policy's purpose and scope.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}<>&]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf-list ingress {
|
leaf-list ingress {
|
||||||
@@ -421,7 +425,9 @@ module infix-firewall {
|
|||||||
|
|
||||||
leaf description {
|
leaf description {
|
||||||
description "Free-form description of the service.";
|
description "Free-form description of the service.";
|
||||||
type string;
|
type string {
|
||||||
|
pattern '[^\p{Cc}<>&]*';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list port {
|
list port {
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ module infix-interfaces {
|
|||||||
deviate replace {
|
deviate replace {
|
||||||
type string {
|
type string {
|
||||||
length "0..64";
|
length "0..64";
|
||||||
|
pattern '[^\p{Cc}]*';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- sh -*-
|
# -*- sh -*-
|
||||||
MODULES=(
|
MODULES=(
|
||||||
"infix-interfaces -e containers"
|
"infix-interfaces -e containers"
|
||||||
"infix-containers@2025-12-09.yang"
|
"infix-containers@2026-02-23.yang"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user