mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 17:23:00 +02:00
Compare commits
2
Commits
v25.08.x
...
user-scripts
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
257f1df1d5 | ||
|
|
8664c27096 |
@@ -22,6 +22,8 @@ All notable changes to the project are documented in this file.
|
||||
- Update documentation for use of VETH pairs in containers
|
||||
- Issue #454: create bridges in `factory-config` with IGMP/MLD snooping
|
||||
enabled by default
|
||||
- Add support for optionally running user scripts from
|
||||
`/cfg/user-scripts.d`
|
||||
|
||||
### Fixes
|
||||
- Add missing LICENSE hash for factory reset tool
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
task [2] run-parts /cfg/user-scripts.d -- Running user startup scripts
|
||||
@@ -226,7 +226,7 @@ sysrepoctl -s $SEARCH \
|
||||
-i infix-dhcp-client@2024-04-12.yang -g wheel -p 0660 \
|
||||
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
|
||||
-i infix-system@2024-04-12.yang -g wheel -p 0660 \
|
||||
-i infix-services@2024-04-08.yang -g wheel -p 0660 \
|
||||
-i infix-services@2024-05-21.yang -g wheel -p 0660 \
|
||||
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
|
||||
-i infix-ethernet-interface@2024-02-27.yang -g wheel -p 0660 \
|
||||
-I "${INIT_DATA}"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
SVC(web) \
|
||||
SVC(ttyd) \
|
||||
SVC(netbrowse) \
|
||||
SVC(userscripts) \
|
||||
SVC(all) /* must be last entry */
|
||||
|
||||
typedef enum {
|
||||
@@ -52,7 +53,7 @@ struct mdns_svc {
|
||||
};
|
||||
|
||||
static const struct srx_module_requirement reqs[] = {
|
||||
{ .dir = YANG_PATH_, .name = "infix-services", .rev = "2024-04-08" },
|
||||
{ .dir = YANG_PATH_, .name = "infix-services", .rev = "2024-05-21" },
|
||||
{ .dir = YANG_PATH_, .name = "ieee802-dot1ab-lldp", .rev = "2022-03-15" },
|
||||
{ .dir = YANG_PATH_, .name = "infix-lldp", .rev = "2023-08-23" },
|
||||
{ NULL }
|
||||
@@ -291,6 +292,21 @@ static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return put(cfg, srv);
|
||||
}
|
||||
|
||||
static int userscripts_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "user-scripts", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
svc_enadis(lydx_is_enabled(srv, "enabled"), none, "user-scripts");
|
||||
|
||||
return put(cfg, srv);
|
||||
}
|
||||
|
||||
int infix_services_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
@@ -312,6 +328,8 @@ int infix_services_init(struct confd *confd)
|
||||
0, netbrowse_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ieee802-dot1ab-lldp", "/ieee802-dot1ab-lldp:lldp",
|
||||
0, lldp_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:user-scripts",
|
||||
0, userscripts_change, confd, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
|
||||
+17
@@ -7,6 +7,10 @@ module infix-services {
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "Infix services, generic.";
|
||||
|
||||
revision 2024-05-21 {
|
||||
description "Add support for user-scripts.";
|
||||
reference "internal";
|
||||
}
|
||||
revision 2024-04-08 {
|
||||
description "Initial support for web services.";
|
||||
reference "internal";
|
||||
@@ -33,6 +37,19 @@ module infix-services {
|
||||
}
|
||||
}
|
||||
|
||||
container user-scripts {
|
||||
description "Run scripts in /cfg/user-scripts.d on system startup
|
||||
|
||||
CAUTION! Anyone who can write to this directory will be able to
|
||||
install a permanent backdoor on the system. This could include
|
||||
a remote attacker with brief window of access.";
|
||||
|
||||
leaf enabled {
|
||||
description "Enable or disable user script execution";
|
||||
type boolean;
|
||||
}
|
||||
}
|
||||
|
||||
container web {
|
||||
description "Web services";
|
||||
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
|
||||
import random
|
||||
import string
|
||||
|
||||
import infamy
|
||||
|
||||
def attach(env):
|
||||
return (env.attach("target", "mgmt"), env.attach("target", "mgmt", "ssh"))
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Initialize"):
|
||||
env = infamy.Env(infamy.std_topology("1x1"))
|
||||
target, tgtssh = attach(env)
|
||||
|
||||
cookie = "".join((random.choices(string.ascii_lowercase, k=16)))
|
||||
script = f"/cfg/user-scripts.d/infamy-user-script-test.sh"
|
||||
output = f"/tmp/{cookie}.cookie"
|
||||
|
||||
with test.step(f"Install {script}"):
|
||||
tgtssh.runsh(f"""
|
||||
set -e
|
||||
|
||||
mkdir -p $(dirname {script})
|
||||
printf '#!/bin/sh\necho -n {cookie} >{output}\n' >{script}
|
||||
chmod +x {script}
|
||||
""")
|
||||
|
||||
with test.step("Enable user scripts and reboot"):
|
||||
target.put_config_dict("infix-services", {
|
||||
"user-scripts": {
|
||||
"enabled": True
|
||||
}
|
||||
})
|
||||
target.copy("running", "startup")
|
||||
target.reboot()
|
||||
infamy.util.wait_boot(target) or test.fail()
|
||||
target, tgtssh = attach(env)
|
||||
|
||||
with test.step(f"Verify that {script} has run"):
|
||||
cat = tgtssh.runsh(f"cat {output}").stdout
|
||||
assert cat == cookie, f"Read back {repr(cat)}, expected {repr(cookie)}"
|
||||
|
||||
with test.step("Disable user scripts and reboot"):
|
||||
target.put_config_dict("infix-services", {
|
||||
"user-scripts": {
|
||||
"enabled": False
|
||||
}
|
||||
})
|
||||
target.copy("running", "startup")
|
||||
target.reboot()
|
||||
infamy.util.wait_boot(target) or test.fail()
|
||||
target, tgtssh = attach(env)
|
||||
|
||||
with test.step(f"Verify that {script} has not run"):
|
||||
exists = tgtssh.run(["test", "-f", f"{output}"]).returncode == 0
|
||||
assert not exists, f"Unexpectedly found {output}"
|
||||
|
||||
with test.step(f"Remove {script}"):
|
||||
tgtssh.runsh(f"rm {script}")
|
||||
|
||||
test.succeed()
|
||||
Reference in New Issue
Block a user