2  *    This program is free software; you can redistribute it and/or modify
 
   3  *    it under the terms of the GNU General Public License as published by
 
   4  *    the Free Software Foundation; either version 2 of the License, or
 
   5  *    (at your option) any later version.
 
   7  *    This program is distributed in the hope that it will be useful,
 
   8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  10  *    GNU General Public License for more details.
 
  12  *    You should have received a copy of the GNU General Public License
 
  13  *    along with this program; if not, write to the Free Software
 
  14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
  18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
 
  19  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
 
  24 #include "ur_functor.h"
 
  26 #include "stg/common.h"
 
  27 #include "stg/locker.h"
 
  28 #include "stg/users.h"
 
  29 #include "stg/user_property.h"
 
  30 #include "stg/logger.h"
 
  41 #include <netinet/ip.h>
 
  44 #define MAX_SHORT_PCKT  (3)
 
  46 extern volatile time_t stgTime;
 
  48 using RS::REMOTE_SCRIPT;
 
  55     explicit USER_IS(RS::UserPtr u) : user(u) {}
 
  56     bool operator()(const T & notifier) { return notifier.GetUser() == user; }
 
  61 } // namespace anonymous
 
  63 extern "C" STG::Plugin* GetPlugin()
 
  65     static REMOTE_SCRIPT plugin;
 
  68 //-----------------------------------------------------------------------------
 
  69 //-----------------------------------------------------------------------------
 
  70 //-----------------------------------------------------------------------------
 
  71 RS::SETTINGS::SETTINGS()
 
  76 //-----------------------------------------------------------------------------
 
  77 int RS::SETTINGS::ParseSettings(const STG::ModuleSettings & s)
 
  82 ///////////////////////////
 
  84 auto pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
  85 if (pvi == s.moduleParams.end() || pvi->value.empty())
 
  87     errorStr = "Parameter \'Port\' not found.";
 
  88     printfd(__FILE__, "Parameter 'Port' not found\n");
 
  91 if (ParseIntInRange(pvi->value[0], 2, 65535, &p) != 0)
 
  93     errorStr = "Cannot parse parameter \'Port\': " + errorStr;
 
  94     printfd(__FILE__, "Cannot parse parameter 'Port'\n");
 
  97 port = static_cast<uint16_t>(p);
 
  98 ///////////////////////////
 
  99 pv.param = "SendPeriod";
 
 100 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 101 if (pvi == s.moduleParams.end() || pvi->value.empty())
 
 103     errorStr = "Parameter \'SendPeriod\' not found.";
 
 104     printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
 
 108 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod) != 0)
 
 110     errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
 
 111     printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
 
 114 ///////////////////////////
 
 115 pv.param = "UserParams";
 
 116 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 117 if (pvi == s.moduleParams.end() || pvi->value.empty())
 
 119     errorStr = "Parameter \'UserParams\' not found.";
 
 120     printfd(__FILE__, "Parameter 'UserParams' not found\n");
 
 123 userParams = pvi->value;
 
 124 ///////////////////////////
 
 125 pv.param = "Password";
 
 126 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 127 if (pvi == s.moduleParams.end() || pvi->value.empty())
 
 129     errorStr = "Parameter \'Password\' not found.";
 
 130     printfd(__FILE__, "Parameter 'Password' not found\n");
 
 133 password = pvi->value[0];
 
 134 ///////////////////////////
 
 135 pv.param = "SubnetFile";
 
 136 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 137 if (pvi == s.moduleParams.end() || pvi->value.empty())
 
 139     errorStr = "Parameter \'SubnetFile\' not found.";
 
 140     printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
 
 143 subnetFile = pvi->value[0];
 
 145 NRMapParser nrMapParser;
 
 147 if (!nrMapParser.ReadFile(subnetFile))
 
 148     netRouters = nrMapParser.GetMap();
 
 150     STG::PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
 
 154 //-----------------------------------------------------------------------------
 
 155 //-----------------------------------------------------------------------------
 
 156 //-----------------------------------------------------------------------------
 
 157 REMOTE_SCRIPT::REMOTE_SCRIPT()
 
 163       logger(STG::PluginLogger::get("rscript"))
 
 166 //-----------------------------------------------------------------------------
 
 167 void REMOTE_SCRIPT::Run(std::stop_token token)
 
 170 sigfillset(&signalSet);
 
 171 pthread_sigmask(SIG_BLOCK, &signalSet, nullptr);
 
 175 while (!token.stop_requested())
 
 183 //-----------------------------------------------------------------------------
 
 184 int REMOTE_SCRIPT::ParseSettings()
 
 186 auto ret = rsSettings.ParseSettings(settings);
 
 188     errorStr = rsSettings.GetStrError();
 
 190 sendPeriod = rsSettings.GetSendPeriod();
 
 191 halfPeriod = sendPeriod / 2;
 
 195 //-----------------------------------------------------------------------------
 
 196 int REMOTE_SCRIPT::Start()
 
 198 netRouters = rsSettings.GetSubnetsMap();
 
 200 InitEncrypt(rsSettings.GetPassword());
 
 202 m_onAddUserConn = users->onAdd([this](auto user){ AddUser(user); });
 
 203 m_onDelUserConn = users->onDel([this](auto user){ DelUser(user); });
 
 212     m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
 
 217 //-----------------------------------------------------------------------------
 
 218 int REMOTE_SCRIPT::Stop()
 
 223 m_thread.request_stop();
 
 226         authorizedUsers.begin(),
 
 227         authorizedUsers.end(),
 
 228         DisconnectUser(*this)
 
 235     //5 seconds to thread stops itself
 
 236     for (int i = 0; i < 25 && isRunning; i++)
 
 238         struct timespec ts = {0, 200000000};
 
 239         nanosleep(&ts, nullptr);
 
 245     logger("Cannot stop thread.");
 
 253 //-----------------------------------------------------------------------------
 
 254 int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
 
 256 NRMapParser nrMapParser;
 
 258 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
 
 260     errorStr = nrMapParser.GetErrorStr();
 
 261     logger("Map file reading error: %s", errorStr.c_str());
 
 266     std::lock_guard lock(m_mutex);
 
 268     printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
 
 270     netRouters = nrMapParser.GetMap();
 
 273 std::for_each(authorizedUsers.begin(),
 
 274               authorizedUsers.end(),
 
 275               UpdateRouter(*this));
 
 277 logger("%s reloaded successfully.", rsSettings.GetMapFileName().c_str());
 
 278 printfd(__FILE__, "REMOTE_SCRIPT::Reload() %s reloaded successfully.\n");
 
 282 //-----------------------------------------------------------------------------
 
 283 bool REMOTE_SCRIPT::PrepareNet()
 
 285 sock = socket(AF_INET, SOCK_DGRAM, 0);
 
 289     errorStr = "Cannot create socket.";
 
 290     logger("Canot create a socket: %s", strerror(errno));
 
 291     printfd(__FILE__, "Cannot create socket\n");
 
 297 //-----------------------------------------------------------------------------
 
 298 bool REMOTE_SCRIPT::FinalizeNet()
 
 303 //-----------------------------------------------------------------------------
 
 304 void REMOTE_SCRIPT::PeriodicSend()
 
 306 std::lock_guard lock(m_mutex);
 
 308 auto it = authorizedUsers.begin();
 
 309 while (it != authorizedUsers.end())
 
 311     if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
 
 318 //-----------------------------------------------------------------------------
 
 320 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, RS::USER & rsu, bool forceDisconnect) const
 
 322 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, RS::USER & rsu, bool forceDisconnect) const
 
 325 RS::PACKET_HEADER packetHead;
 
 327 memset(packetHead.padding, 0, sizeof(packetHead.padding));
 
 328 memcpy(packetHead.magic, RS_ID, sizeof(RS_ID));
 
 329 packetHead.protoVer[0] = '0';
 
 330 packetHead.protoVer[1] = '2';
 
 333     packetHead.packetType = RS_DISCONNECT_PACKET;
 
 334     printfd(__FILE__, "RSCRIPT: force disconnect for '%s'\n", rsu.user->GetLogin().c_str());
 
 338     if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
 
 341         packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
 
 342         if (rsu.user->IsInetable())
 
 343             printfd(__FILE__, "RSCRIPT: connect for '%s'\n", rsu.user->GetLogin().c_str());
 
 345             printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
 
 350         packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
 
 351         if (rsu.user->IsInetable())
 
 352             printfd(__FILE__, "RSCRIPT: alive for '%s'\n", rsu.user->GetLogin().c_str());
 
 354             printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
 
 357 rsu.shortPacketsCount++;
 
 358 rsu.lastSentTime = stgTime;
 
 360 packetHead.ip = htonl(rsu.ip);
 
 361 packetHead.id = htonl(rsu.user->GetID());
 
 362 strncpy(reinterpret_cast<char*>(packetHead.login), rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
 
 363 packetHead.login[RS_LOGIN_LEN - 1] = 0;
 
 365 memcpy(buf, &packetHead, sizeof(packetHead));
 
 367 if (packetHead.packetType == RS_ALIVE_PACKET)
 
 372 RS::PACKET_TAIL packetTail;
 
 374 memset(packetTail.padding, 0, sizeof(packetTail.padding));
 
 375 memcpy(packetTail.magic, RS_ID, sizeof(RS_ID));
 
 377 for (const auto& param : rsSettings.GetUserParams())
 
 379     auto value = rsu.user->GetParamValue(param);
 
 380     if (params.length() + value.length() > RS_PARAMS_LEN - 1)
 
 382         logger("Script params string length %d exceeds the limit of %d symbols.", params.length() + value.length(), RS_PARAMS_LEN);
 
 385     params += value + " ";
 
 387 strncpy(reinterpret_cast<char*>(packetTail.params), params.c_str(), RS_PARAMS_LEN);
 
 388 packetTail.params[RS_PARAMS_LEN - 1] = 0;
 
 390 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
 
 392 Encrypt(buf + sizeof(packetHead), reinterpret_cast<char *>(&packetTail), sizeof(packetTail) / 8);
 
 396 //-----------------------------------------------------------------------------
 
 397 bool REMOTE_SCRIPT::Send(RS::USER & rsu, bool forceDisconnect) const
 
 399 char buffer[RS_MAX_PACKET_LEN];
 
 401 memset(buffer, 0, sizeof(buffer));
 
 403 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
 
 405     printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
 
 409 for (const auto& ip : rsu.routers)
 
 411     struct sockaddr_in sendAddr;
 
 413     sendAddr.sin_family = AF_INET;
 
 414     sendAddr.sin_port = htons(rsSettings.GetPort());
 
 415     sendAddr.sin_addr.s_addr = ip;
 
 417     return sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr*>(&sendAddr), sizeof(sendAddr)) > 0;
 
 422 //-----------------------------------------------------------------------------
 
 423 bool REMOTE_SCRIPT::SendDirect(RS::USER & rsu, uint32_t routerIP, bool forceDisconnect) const
 
 425 char buffer[RS_MAX_PACKET_LEN];
 
 427 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
 
 429     printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
 
 433 struct sockaddr_in sendAddr;
 
 435 sendAddr.sin_family = AF_INET;
 
 436 sendAddr.sin_port = htons(rsSettings.GetPort());
 
 437 sendAddr.sin_addr.s_addr = routerIP;
 
 439 ssize_t res = sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&sendAddr), sizeof(sendAddr));
 
 442     logger("sendto error: %s", strerror(errno));
 
 444 return (res != sizeof(buffer));
 
 446 //-----------------------------------------------------------------------------
 
 447 bool REMOTE_SCRIPT::GetUsers()
 
 451 int h = users->OpenSearch();
 
 452 assert(h && "USERS::OpenSearch is always correct");
 
 454 while (users->SearchNext(h, &u) != 0)
 
 457 users->CloseSearch(h);
 
 460 //-----------------------------------------------------------------------------
 
 461 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
 
 463 std::lock_guard lock(m_mutex);
 
 464 for (auto& nr : netRouters)
 
 465     if ((ip & nr.subnetMask) == (nr.subnetIP & nr.subnetMask))
 
 469 //-----------------------------------------------------------------------------
 
 470 void REMOTE_SCRIPT::SetUserNotifiers(UserPtr u)
 
 472 ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
 
 473 connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
 
 475 //-----------------------------------------------------------------------------
 
 476 void REMOTE_SCRIPT::UnSetUserNotifiers(UserPtr u)
 
 478 ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
 
 479                                     ipNotifierList.end(),
 
 480                                     USER_IS<IP_NOTIFIER>(u)),
 
 481                      ipNotifierList.end());
 
 482 connNotifierList.erase(std::remove_if(connNotifierList.begin(),
 
 483                                       connNotifierList.end(),
 
 484                                       USER_IS<CONNECTED_NOTIFIER>(u)),
 
 485                        connNotifierList.end());
 
 488 //-----------------------------------------------------------------------------
 
 489 void REMOTE_SCRIPT::AddRSU(UserPtr user)
 
 491 RS::USER rsu(IP2Routers(user->GetCurrIP()), user);
 
 494 std::lock_guard lock(m_mutex);
 
 495 authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
 
 497 //-----------------------------------------------------------------------------
 
 498 void REMOTE_SCRIPT::DelRSU(UserPtr user)
 
 500 std::lock_guard lock(m_mutex);
 
 501 auto it = authorizedUsers.begin();
 
 502 while (it != authorizedUsers.end())
 
 504     if (it->second.user == user)
 
 506         Send(it->second, true);
 
 507         authorizedUsers.erase(it);
 
 512 /*const auto it = authorizedUsers.find(user->GetCurrIP());
 
 513 if (it != authorizedUsers.end())
 
 515     Send(it->second, true);
 
 516     authorizedUsers.erase(it);
 
 519 //-----------------------------------------------------------------------------
 
 520 void RS::IP_NOTIFIER::notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
 
 527 //-----------------------------------------------------------------------------
 
 528 void RS::CONNECTED_NOTIFIER::notify(const bool & /*oldValue*/, const bool & newValue)
 
 535 //-----------------------------------------------------------------------------
 
 536 void REMOTE_SCRIPT::InitEncrypt(const std::string & password) const
 
 538 unsigned char keyL[PASSWD_LEN];  // Пароль для шифровки
 
 539 memset(keyL, 0, PASSWD_LEN);
 
 540 strncpy(reinterpret_cast<char*>(keyL), password.c_str(), PASSWD_LEN);
 
 541 Blowfish_Init(&ctx, keyL, PASSWD_LEN);
 
 543 //-----------------------------------------------------------------------------
 
 544 void REMOTE_SCRIPT::Encrypt(void * dst, const void * src, size_t len8) const
 
 547     memcpy(dst, src, len8 * 8);
 
 548 for (size_t i = 0; i < len8; ++i)
 
 549     Blowfish_Encrypt(&ctx, static_cast<uint32_t *>(dst) + i * 2, static_cast<uint32_t *>(dst) + i * 2 + 1);
 
 551 //-----------------------------------------------------------------------------