2023-04-04 14:27:23 +00:00
|
|
|
#!rsc by RouterOS
|
|
|
|
# RouterOS script: mod/ssh-keys-import
|
2024-01-01 14:25:25 +00:00
|
|
|
# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
|
2023-04-04 14:27:23 +00:00
|
|
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
|
|
|
#
|
2024-04-04 19:45:02 +00:00
|
|
|
# requires RouterOS, version=7.13
|
2023-11-02 08:46:25 +00:00
|
|
|
#
|
2023-04-04 14:27:23 +00:00
|
|
|
# import ssh keys for public key authentication
|
|
|
|
# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ssh-keys-import.md
|
|
|
|
|
|
|
|
:global SSHKeysImport;
|
|
|
|
:global SSHKeysImportFile;
|
|
|
|
|
|
|
|
# import single key passed as string
|
|
|
|
:set SSHKeysImport do={
|
|
|
|
:local Key [ :tostr $1 ];
|
|
|
|
:local User [ :tostr $2 ];
|
|
|
|
|
2023-11-02 08:38:47 +00:00
|
|
|
:global CharacterReplace;
|
2023-04-04 14:27:23 +00:00
|
|
|
:global GetRandom20CharAlNum;
|
2024-03-08 11:45:38 +00:00
|
|
|
:global LogPrint;
|
2023-04-04 14:27:23 +00:00
|
|
|
:global MkDir;
|
|
|
|
:global WaitForFile;
|
|
|
|
|
|
|
|
:if ([ :len $Key ] = 0 || [ :len $User ] = 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("Missing argument(s), please pass key and user!");
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
:if ([ :len [ /user/find where name=$User ] ] = 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("User '" . $User . "' does not exist.");
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
|
2023-11-02 08:38:47 +00:00
|
|
|
:local KeyVal [ :toarray [ $CharacterReplace $Key " " "," ] ];
|
2023-08-18 13:26:18 +00:00
|
|
|
:if (!($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa")) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-08-18 07:15:44 +00:00
|
|
|
}
|
|
|
|
|
2023-11-02 08:46:25 +00:00
|
|
|
:local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ];
|
2023-11-07 12:34:02 +00:00
|
|
|
|
|
|
|
:if ([ :len [ /user/ssh-keys/find where user=$User key-owner~("\\bmd5=" . $FingerPrintMD5 . "\\b") ] ] > 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \
|
|
|
|
") is already available for user '" . $User . "'.");
|
2023-11-07 12:34:02 +00:00
|
|
|
:return false;
|
2024-04-23 12:26:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
:if ([ $MkDir "tmpfs/ssh-keys-import" ] = false) do={
|
|
|
|
$LogPrint warning $0 ("Creating directory 'tmpfs/ssh-keys-import' failed!");
|
|
|
|
:return false;
|
2023-11-07 12:34:02 +00:00
|
|
|
}
|
|
|
|
|
2023-04-04 14:27:23 +00:00
|
|
|
:local FileName ("tmpfs/ssh-keys-import/key-" . [ $GetRandom20CharAlNum 6 ] . ".pub");
|
2023-11-02 08:46:25 +00:00
|
|
|
/file/add name=$FileName contents=($Key . ", md5=" . $FingerPrintMD5);
|
2023-04-04 14:27:23 +00:00
|
|
|
$WaitForFile $FileName;
|
|
|
|
|
|
|
|
:do {
|
|
|
|
/user/ssh-keys/import public-key-file=$FileName user=$User;
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint info $0 ("Imported ssh public key (" . $KeyVal->2 . ", " . $KeyVal->0 . ", " . \
|
|
|
|
"MD5:" . $FingerPrintMD5 . ") for user '" . $User . "'.");
|
2024-04-23 12:30:42 +00:00
|
|
|
/file/remove "tmpfs/ssh-keys-import";
|
2023-04-04 14:27:23 +00:00
|
|
|
} on-error={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("Failed importing key.");
|
2024-04-23 12:30:42 +00:00
|
|
|
/file/remove "tmpfs/ssh-keys-import";
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# import keys from a file
|
|
|
|
:set SSHKeysImportFile do={
|
|
|
|
:local FileName [ :tostr $1 ];
|
|
|
|
:local User [ :tostr $2 ];
|
|
|
|
|
2023-11-02 08:38:47 +00:00
|
|
|
:global CharacterReplace;
|
2023-04-04 14:27:23 +00:00
|
|
|
:global EitherOr;
|
2024-03-08 11:45:38 +00:00
|
|
|
:global LogPrint;
|
2023-04-04 14:27:23 +00:00
|
|
|
:global ParseKeyValueStore;
|
|
|
|
:global SSHKeysImport;
|
|
|
|
|
|
|
|
:if ([ :len $FileName ] = 0 || [ :len $User ] = 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("Missing argument(s), please pass file name and user!");
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
:local File [ /file/find where name=$FileName ];
|
|
|
|
:if ([ :len $File ] = 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("File '" . $FileName . "' does not exist.");
|
2024-03-08 16:47:56 +00:00
|
|
|
:return false;
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
:local Keys ([ /file/get $FileName contents ] . "\n");
|
|
|
|
|
|
|
|
:do {
|
|
|
|
:local Continue false;
|
|
|
|
:local Line [ :pick $Keys 0 [ :find $Keys "\n" ] ];
|
|
|
|
:set Keys [ :pick $Keys ([ :find $Keys "\n" ] + 1) [ :len $Keys ] ];
|
2023-12-21 10:33:09 +00:00
|
|
|
:local KeyVal [ :toarray [ $CharacterReplace $Line " " "," ] ];
|
2023-08-18 13:26:18 +00:00
|
|
|
:if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={
|
2023-11-07 12:48:49 +00:00
|
|
|
:do {
|
|
|
|
$SSHKeysImport $Line $User;
|
|
|
|
} on-error={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("Failed importing key for user '" . $User . "'.");
|
2023-11-07 12:48:49 +00:00
|
|
|
}
|
2023-04-04 14:27:23 +00:00
|
|
|
:set Continue true;
|
|
|
|
}
|
2023-11-02 08:38:47 +00:00
|
|
|
:if ($Continue = false && $KeyVal->0 = "#") do={
|
2023-04-04 14:27:23 +00:00
|
|
|
:set User [ $EitherOr ([ $ParseKeyValueStore [ :pick $Line 2 [ :len $Line ] ] ]->"user") $User ];
|
|
|
|
:set Continue true;
|
|
|
|
}
|
2023-11-02 08:38:47 +00:00
|
|
|
:if ($Continue = false && [ :len ($KeyVal->0) ] > 0) do={
|
2024-03-08 11:45:38 +00:00
|
|
|
$LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
|
2023-04-04 14:27:23 +00:00
|
|
|
}
|
|
|
|
} while=([ :len $Keys ] > 0);
|
|
|
|
}
|