diff options
Diffstat (limited to 'mod/ssh-keys-import.rsc')
-rw-r--r-- | mod/ssh-keys-import.rsc | 91 |
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; +} } |