aboutsummaryrefslogtreecommitdiffstats
#!rsc
# RouterOS script: global-functions
# Copyright (c) 2013-2019 Christian Hesse <mail@eworm.de>
#
# global functions

# expected configuration version
:global ExpectedConfigVersion 2;

# global variables not to be changed by user
:global SentRouterosUpdateNotification "-";
:global SentLteFirmwareUpgradeNotification "-";
:global Identity [ / system identity get name ];

# read input from user
:global Read do={
  :return;
}

# url encoding
:global UrlEncode do={
  :local Input [ :tostr $1 ];
  :local Return "";

  :if ([ :len $Input ] > 0) do={
    :local Chars " %&";
    :local Subs { "%20"; "%25"; "%26" };

    :for I from=0 to=([ :len $Input ] - 1) do={
      :local Char [ :pick $Input $I ];
      :local Replace [ :find $Chars $Char ];

      :if ([ :len $Replace ] > 0) do={
        :set Char ($Subs->$Replace);
      }
      :set Return ($Return . $Char);
    }
  }

  :return $Return;
}

# character replace
:global CharacterReplace do={
  :local String [ :tostr $1 ];
  :local ReplaceFrom [ :tostr $2 ];
  :local ReplaceWith [ :tostr $3 ];
  :local Len [ :len $ReplaceFrom ];

  :if ($ReplaceFrom = "") do={
    :return $String;
  }

  :while ($String ~ $ReplaceFrom) do={
    :local Pos [ :find $String $ReplaceFrom ];
    :set String ([ :pick $String 0 $Pos ] . $ReplaceWith . [ :pick $String ($Pos + $Len) 999 ]);
  }

  :return $String;
}

# check and import required certificates
:global CertificateAvailable do={
  :local CommonName [ :tostr $1 ];
  :local FileName ([ :tostr $2 ] . ".pem");

  :global ScriptUpdatesBaseUrl;
  :global ScriptUpdatesUrlSuffix;

  :if ([ / certificate print count-only where common-name=$CommonName ] = 0) do={
    :log info ("Certificate with CommonName " . $CommonName . \
      " not available, downloading and importing.");
    :do {
      / tool fetch check-certificate=yes-without-crl \
        ($ScriptUpdatesBaseUrl . "certs/" . \
        $FileName . $ScriptUpdatesUrlSuffix) \
        dst-path=$FileName;
      / certificate import file-name=$FileName passphrase="";
    } on-error={
      :log warning "Failed imprting certificate!";
    }
  }
}

# send notification via e-mail and telegram
# Note that attachment is ignored for telegram!
:global SendNotification do={
  :local Subject [ :tostr $1 ];
  :local Message [ :tostr $2 ];
  :local Attach [ :tostr $3 ];

  :global Identity;
  :global EmailGeneralTo;
  :global EmailGeneralCc;
  :global TelegramTokenId;
  :global TelegramChatId;

  :global UrlEncode;
  :global CertificateAvailable;

  :if ([ :len $EmailGeneralTo ] > 0) do={
    :do {
      / tool e-mail send to=$EmailGeneralTo cc=$EmailGeneralCc \
        subject=("[" . $Identity . "] " . $Subject) body=$Message file=$Attach;
    } on-error={
      :log warning "Failed sending notification mail!";
    }
  }

  :if ([ :len $TelegramTokenId ] > 0 && [ :len $TelegramChatId ] > 0) do={
    $CertificateAvailable "Go Daddy Secure Certificate Authority - G2" "godaddy";
    :do {
      / tool fetch check-certificate=yes-without-crl keep-result=no http-method=post \
        ("https://api.telegram.org/bot" . $TelegramTokenId . "/sendMessage") \
        http-data=("chat_id=" . $TelegramChatId . "&text=" . \
        [ $UrlEncode ("[" . $Identity . "] " . $Subject . "\n\n" . $Message) ]);
    } on-error={
      :log warning "Failed sending telegram notification!";
    }
  }
}

# get MAC vendor
:global GetMacVendor do={
  :local Mac [ :tostr $1 ];

  :global CertificateAvailable;

  :do {
    :local Vendor;
    $CertificateAvailable "Let's Encrypt Authority X3" "letsencrypt";
    :set Vendor ([ / tool fetch mode=https check-certificate=yes-without-crl \
        ("https://api.macvendors.com/" . [ :pick $Mac 0 8 ]) output=user as-value ]->"data");
    :return $Vendor;
  } on-error={
    :return "unknown vendor";
  }
}

# download package from upgrade server
:global DownloadPackage do={
  :local PkgName [ :tostr $1 ];
  :local PkgVer  [ :tostr $2 ];
  :local PkgArch [ :tostr $3 ];
  :local PkgDest [ :tostr $4 ];

  :global CertificateAvailable;

  :if ([ :len $PkgName ] = 0) do={ return false; }
  :if ([ :len $PkgVer  ] = 0) do={ :set PkgVer  [ / system package update get installed-version ]; }
  :if ([ :len $PkgArch ] = 0) do={ :set PkgArch [ / system resource get architecture-name ]; }

  $CertificateAvailable "Let's Encrypt Authority X3" "letsencrypt";
  :do {
    :local PkgFile ($PkgName . "-" . $PkgVer . "-" . $PkgArch . ".npk");
    / tool fetch mode=https check-certificate=yes-without-crl \
      ("https://upgrade.mikrotik.com/routeros/" . $PkgVer . "/" . $PkgFile) \
      dst-path=($PkgDest . "/" . $PkgFile);
    :return true;
  } on-error={
    :return false;
  }
}