aboutsummaryrefslogtreecommitdiffstats
path: root/mod/ssh-keys-import.rsc
diff options
context:
space:
mode:
Diffstat (limited to 'mod/ssh-keys-import.rsc')
-rw-r--r--mod/ssh-keys-import.rsc91
1 files changed, 58 insertions, 33 deletions
diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc
index 31bb3e6..2fae4b1 100644
--- a/mod/ssh-keys-import.rsc
+++ b/mod/ssh-keys-import.rsc
@@ -1,89 +1,114 @@
#!rsc by RouterOS
# RouterOS script: mod/ssh-keys-import
-# Copyright (c) 2020-2023 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.16
#
# import ssh keys for public key authentication
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ssh-keys-import.md
+# https://rsc.eworm.de/doc/mod/ssh-keys-import.md
:global SSHKeysImport;
:global SSHKeysImportFile;
# import single key passed as string
-:set SSHKeysImport do={
+:set SSHKeysImport do={ :do {
:local Key [ :tostr $1 ];
:local User [ :tostr $2 ];
:global GetRandom20CharAlNum;
- :global LogPrintExit2;
+ :global LogPrint;
:global MkDir;
- :global RequiredRouterOS;
+ :global RmDir;
:global WaitForFile;
:if ([ :len $Key ] = 0 || [ :len $User ] = 0) do={
- $LogPrintExit2 warning $0 ("Missing argument(s), please pass key and user!") true;
+ $LogPrint warning $0 ("Missing argument(s), please pass key and user!");
+ :return false;
}
:if ([ :len [ /user/find where name=$User ] ] = 0) do={
- $LogPrintExit2 warning $0 ("User '" . $User . "' does not exist.") true;
+ $LogPrint warning $0 ("User '" . $User . "' does not exist.");
+ :return false;
+ }
+
+ :local KeyVal ([ :deserialize $Key delimiter=" " from=dsv options=dsv.plain ]->0);
+ :if (!($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa")) do={
+ $LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
+ :return false;
}
- :local Type [ :pick $Key 0 [ :find $Key " " ] ];
- :if (!(([ $RequiredRouterOS $0 "7.12beta1" ] = true && $Type = "ssh-ed25519") || $Type = "ssh-rsa")) do={
- $LogPrintExit2 warning $0 ("SSH key of type '" . $Type . "' is not supported.") true;
+ :local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ];
+
+ :if ([ :len [ /user/ssh-keys/find where user=$User key-owner~("\\bmd5=" . $FingerPrintMD5 . "\\b") ] ] > 0) do={
+ $LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \
+ ") is already available for user '" . $User . "'.");
+ :return false;
}
:if ([ $MkDir "tmpfs/ssh-keys-import" ] = false) do={
- $LogPrintExit2 warning $0 ("Creating directory 'tmpfs/ssh-keys-import' failed!") true;
+ $LogPrint warning $0 ("Creating directory 'tmpfs/ssh-keys-import' failed!");
+ :return false;
}
:local FileName ("tmpfs/ssh-keys-import/key-" . [ $GetRandom20CharAlNum 6 ] . ".pub");
- /file/add name=$FileName contents=$Key;
+ /file/add name=$FileName contents=($Key . ", md5=" . $FingerPrintMD5);
$WaitForFile $FileName;
:do {
/user/ssh-keys/import public-key-file=$FileName user=$User;
+ $LogPrint info $0 ("Imported ssh public key (" . $KeyVal->2 . ", " . $KeyVal->0 . ", " . \
+ "MD5:" . $FingerPrintMD5 . ") for user '" . $User . "'.");
+ $RmDir "tmpfs/ssh-keys-import";
} on-error={
- $LogPrintExit2 warning $0 ("Failed importing key.") true;
+ $LogPrint warning $0 ("Failed importing key.");
+ $RmDir "tmpfs/ssh-keys-import";
+ :return false;
}
-}
+} on-error={
+ :global ExitError; $ExitError false $0;
+} }
# import keys from a file
-:set SSHKeysImportFile do={
+:set SSHKeysImportFile do={ :do {
:local FileName [ :tostr $1 ];
:local User [ :tostr $2 ];
:global EitherOr;
- :global LogPrintExit2;
+ :global LogPrint;
:global ParseKeyValueStore;
- :global RequiredRouterOS;
:global SSHKeysImport;
:if ([ :len $FileName ] = 0 || [ :len $User ] = 0) do={
- $LogPrintExit2 warning $0 ("Missing argument(s), please pass file name and user!") true;
+ $LogPrint warning $0 ("Missing argument(s), please pass file name and user!");
+ :return false;
}
:local File [ /file/find where name=$FileName ];
:if ([ :len $File ] = 0) do={
- $LogPrintExit2 warning $0 ("File '" . $FileName . "' does not exist.") true;
+ $LogPrint warning $0 ("File '" . $FileName . "' does not exist.");
+ :return false;
}
- :local Keys ([ /file/get $FileName contents ] . "\n");
+ :local Keys [ :tolf [ /file/get $FileName contents ] ];
- :do {
+ :foreach KeyVal in=[ :deserialize $Keys delimiter=" " from=dsv options=dsv.plain ] do={
:local Continue false;
- :local Line [ :pick $Keys 0 [ :find $Keys "\n" ] ];
- :set Keys [ :pick $Keys ([ :find $Keys "\n" ] + 1) [ :len $Keys ] ];
- :local Type [ :pick $Line 0 [ :find $Line " " ] ];
- :if (([ $RequiredRouterOS $0 "7.12beta1" ] = true && $Type = "ssh-ed25519") || $Type = "ssh-rsa") do={
- $SSHKeysImport $Line $User;
+ :if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={
+ :do {
+ $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User;
+ } on-error={
+ $LogPrint warning $0 ("Failed importing key for user '" . $User . "'.");
+ }
:set Continue true;
}
- :if ($Continue = false && $Type = "#") do={
- :set User [ $EitherOr ([ $ParseKeyValueStore [ :pick $Line 2 [ :len $Line ] ] ]->"user") $User ];
+ :if ($Continue = false && $KeyVal->0 = "#") do={
+ :set User [ $EitherOr ([ $ParseKeyValueStore ($KeyVal->1) ]->"user") $User ];
:set Continue true;
}
- :if ($Continue = false && [ :len $Type ] > 0) do={
- $LogPrintExit2 warning $0 ("SSH key of type '" . $Type . "' is not supported.") false;
+ :if ($Continue = false && [ :len ($KeyVal->0) ] > 0) do={
+ $LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
}
- } while=([ :len $Keys ] > 0);
-}
+ }
+} on-error={
+ :global ExitError; $ExitError false $0;
+} }