From 314ba5796d05591ec4781b72222b95c9c8590928 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 8 Apr 2025 09:41:25 +0200 Subject: [PATCH 1/8] global-functions: $ScriptLock: increase interval with wait time Inspired by: https://github.com/eworm-de/routeros-scripts/issues/95#issuecomment-2773513467 --- global-functions.rsc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index d6661223..d488c0f5 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1387,8 +1387,8 @@ # lock script against multiple invocation :set ScriptLock do={ - :local Script [ :tostr $1 ]; - :local WaitMax ([ :tonum $2 ] * 10); + :local Script [ :tostr $1 ]; + :local WaitMax [ :totime $2 ]; :global GetRandom20CharAlNum; :global IfThenElse; @@ -1477,6 +1477,10 @@ :set ($ScriptLockOrder->$Script) ({}); } + :if ([ :typeof $WaitMax ] = "nil" ) do={ + :set WaitMax 0s; + } + :if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={ $LogPrint error $0 ("A script named '" . $Script . "' does not exist!"); :error false; @@ -1496,12 +1500,13 @@ :local MyTicket [ $GetRandom20CharAlNum 6 ]; $AddTicket $Script $MyTicket; - :local WaitCount 0; - :while ($WaitMax > $WaitCount && \ + :local WaitInterval ($WaitMax / 20); + :local WaitTime $WaitMax; + :while ($WaitTime > 0 && \ ([ $IsFirstTicket $Script $MyTicket ] = false || \ [ $TicketCount $Script ] < [ $JobCount $Script ])) do={ - :set WaitCount ($WaitCount + 1); - :delay 100ms; + :set WaitTime ($WaitTime - $WaitInterval); + :delay $WaitInterval; } :if ([ $IsFirstTicket $Script $MyTicket ] = true && \ @@ -1513,7 +1518,7 @@ $RemoveTicket $Script $MyTicket; $LogPrint debug $0 ("Script '" . $Script . "' started more than once" . \ - [ $IfThenElse ($WaitCount > 0) " and timed out waiting for lock" "" ] . "..."); + [ $IfThenElse ($WaitTime < $WaitMax) " and timed out waiting for lock" "" ] . "..."); :return false; } From 019e10e1903e261ed1629a1db6ff2d64257916aa Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 7 Apr 2025 13:44:53 +0200 Subject: [PATCH 2/8] global-functions: $CertificateDownload: no infinite loop We can not call $CertificateAvailable here, as that will most likely cause an infinite loop. After all that's the certificate mkcert.org is using. And it *is* available in this repository. --- global-functions.rsc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index d488c0f5..30374aa3 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -167,8 +167,8 @@ $LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . \ "' from repository! Trying fallback to mkcert.org..."); :do { - :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ - $LogPrint error $0 ("Downloading required certificate failed."); + :if ([ :len [ /certificate/find where common-name="ISRG Root X1" ] ] = 0) do={ + $LogPrint error $0 ("Required certificate is not available."); :return false; } /tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $0 ] }) \ From e36613608c18bc4bcbc11e2d8da47f6c8c53c454 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 7 Apr 2025 14:14:00 +0200 Subject: [PATCH 3/8] global-functions: $CertificateNameByCN: support matching by fingerprint and name --- global-functions.rsc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 30374aa3..f73ea14f 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -203,11 +203,12 @@ # name a certificate by its common-name :set CertificateNameByCN do={ - :local CommonName [ :tostr $1 ]; + :local Match [ :tostr $1 ]; :global CleanName; - :local Cert [ /certificate/find where common-name=$CommonName ]; + :local Cert [ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]; + :local CommonName [ /certificate/get $Cert common-name ]; /certificate/set $Cert name=[ $CleanName $CommonName ]; } From 44fa91f5c47ec739a7f74aa2861ab58cc42bed39 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 7 Apr 2025 15:05:27 +0200 Subject: [PATCH 4/8] global-functions: $CertificateNameByCN: pick the first match only --- global-functions.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global-functions.rsc b/global-functions.rsc index f73ea14f..7b1c2143 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -207,7 +207,7 @@ :global CleanName; - :local Cert [ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]; + :local Cert ([ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]->0); :local CommonName [ /certificate/get $Cert common-name ]; /certificate/set $Cert name=[ $CleanName $CommonName ]; } From c823ff87ed32beeea6e0a49d194178db9944693d Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 8 Apr 2025 14:42:51 +0200 Subject: [PATCH 5/8] global-functions: $CertificateNameByCN: return false without match... ... and return true on success. --- global-functions.rsc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/global-functions.rsc b/global-functions.rsc index 7b1c2143..d0145676 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -208,8 +208,12 @@ :global CleanName; :local Cert ([ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]->0); + :if ([ :len $Cert ] = 0) do={ + :return false; + } :local CommonName [ /certificate/get $Cert common-name ]; /certificate/set $Cert name=[ $CleanName $CommonName ]; + :return true; } # multiply given character(s) From d4b5e1f5e7acb59bc365c6598749d1ec15c8cd36 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 10 Apr 2025 11:07:59 +0200 Subject: [PATCH 6/8] global-functions: $CertificateNameByCN: warn with no match --- global-functions.rsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/global-functions.rsc b/global-functions.rsc index d0145676..70269c80 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -206,9 +206,11 @@ :local Match [ :tostr $1 ]; :global CleanName; + :global LogPrint; :local Cert ([ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]->0); :if ([ :len $Cert ] = 0) do={ + $LogPrint warning $0 ("No matching certificate found."); :return false; } :local CommonName [ /certificate/get $Cert common-name ]; From a63a6571397f4b2e9d97dba5e26c6a9e07deccc8 Mon Sep 17 00:00:00 2001 From: Miquel Bonastre Date: Mon, 7 Apr 2025 13:51:56 +0200 Subject: [PATCH 7/8] INITIAL-COMMANDS: support installation from custom server Closes: https://github.com/eworm-de/routeros-scripts/pull/96 --- INITIAL-COMMANDS.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md index 8b64d281..002e51af 100644 --- a/INITIAL-COMMANDS.md +++ b/INITIAL-COMMANDS.md @@ -17,23 +17,27 @@ Initial commands Run the complete base installation: { - /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem" as-value; + :local BaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/"; + :local CertFileName "ISRG-Root-X2.pem"; + :local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; + + /tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value; :delay 1s; - /certificate/import file-name="isrg-root-x2.pem" passphrase=""; - :if ([ :len [ /certificate/find where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470" ] ] != 1) do={ + /certificate/import file-name=$CertFileName passphrase=""; + :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] != 1) do={ :error "Something is wrong with your certificates!"; }; :delay 1s; /system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ]; :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/remove [ find where name=$Script ]; - /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . ".rsc") output=user as-value]->"data"); + /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value]->"data"); }; /system/script { run global-config; run global-functions; }; /system/scheduler/remove [ find where name="global-scripts" ]; /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; :global CertificateNameByCN; - $CertificateNameByCN "ISRG Root X2"; + $CertificateNameByCN $CertFingerprint; }; Then continue setup with From 2e0da2c0c790bef0277475387cdee573a1b8bd27 Mon Sep 17 00:00:00 2001 From: Miquel Bonastre Date: Mon, 7 Apr 2025 16:16:19 +0200 Subject: [PATCH 8/8] INITIAL-COMMANDS: add status output --- INITIAL-COMMANDS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md index 002e51af..65b313b5 100644 --- a/INITIAL-COMMANDS.md +++ b/INITIAL-COMMANDS.md @@ -21,6 +21,7 @@ Run the complete base installation: :local CertFileName "ISRG-Root-X2.pem"; :local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; + :put "Importing certificate..."; /tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value; :delay 1s; /certificate/import file-name=$CertFileName passphrase=""; @@ -28,14 +29,19 @@ Run the complete base installation: :error "Something is wrong with your certificates!"; }; :delay 1s; + :put "Renaming global-config-overlay, if exists..."; /system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ]; :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ + :put "Installing $Script..."; /system/script/remove [ find where name=$Script ]; /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value]->"data"); }; + :put "Loading configuration and functions..."; /system/script { run global-config; run global-functions; }; + :put "Scheduling to load configuration and functions..."; /system/scheduler/remove [ find where name="global-scripts" ]; /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; + :put "Renaming certificate by its common-name..."; :global CertificateNameByCN; $CertificateNameByCN $CertFingerprint; };