]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/rscript/rscript.cpp
Correct description for tariffUsers
[stg.git] / projects / stargazer / plugins / other / rscript / rscript.cpp
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
20  */
21
22 /*
23  $Revision: 1.33 $
24  $Date: 2010/04/16 12:30:37 $
25  $Author: faust $
26 */
27
28 #include <sys/time.h>
29
30 #include <csignal>
31 #include <cassert>
32 #include <cstdlib>
33 #include <algorithm>
34
35 #include "stg/common.h"
36 #include "stg/locker.h"
37 #include "stg/user_property.h"
38 #include "rscript.h"
39 #include "ur_functor.h"
40 #include "send_functor.h"
41
42 extern volatile const time_t stgTime;
43
44 #define RS_MAX_ROUTERS  (100)
45
46 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
49 class RS_CREATOR
50 {
51 private:
52     REMOTE_SCRIPT * rs;
53
54 public:
55     RS_CREATOR()
56         : rs(new REMOTE_SCRIPT())
57         {
58         };
59     ~RS_CREATOR()
60         {
61         delete rs;
62         };
63
64     REMOTE_SCRIPT * GetPlugin()
65         {
66         return rs;
67         };
68 };
69 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 RS_CREATOR rsc;
73 //-----------------------------------------------------------------------------
74 //-----------------------------------------------------------------------------
75 //-----------------------------------------------------------------------------
76 PLUGIN * GetPlugin()
77 {
78 return rsc.GetPlugin();
79 }
80 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
82 //-----------------------------------------------------------------------------
83 RS_USER::RS_USER()
84     : lastSentTime(0),
85       user(NULL),
86       shortPacketsCount(0)
87 {
88 }
89 //-----------------------------------------------------------------------------
90 RS_USER::RS_USER(const std::vector<uint32_t> & r, USER_PTR it)
91     : lastSentTime(0),
92       user(it),
93       routers(r),
94       shortPacketsCount(0)
95 {
96 }
97 //-----------------------------------------------------------------------------
98 RS_SETTINGS::RS_SETTINGS()
99     : sendPeriod(0),
100       port(0)
101 {
102 }
103 //-----------------------------------------------------------------------------
104 int RS_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
105 {
106 if (str2x(str.c_str(), *val))
107     {
108     errorStr = "Incorrect value \'" + str + "\'.";
109     return -1;
110     }
111 if (*val < min || *val > max)
112     {
113     errorStr = "Value \'" + str + "\' out of range.";
114     return -1;
115     }
116 return 0;
117 }
118 //-----------------------------------------------------------------------------
119 int RS_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
120 {
121 int p;
122 PARAM_VALUE pv;
123 vector<PARAM_VALUE>::const_iterator pvi;
124 netRouters.clear();
125 ///////////////////////////
126 pv.param = "Port";
127 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
128 if (pvi == s.moduleParams.end())
129     {
130     errorStr = "Parameter \'Port\' not found.";
131     printfd(__FILE__, "Parameter 'Port' not found\n");
132     return -1;
133     }
134 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
135     {
136     errorStr = "Cannot parse parameter \'Port\': " + errorStr;
137     printfd(__FILE__, "Cannot parse parameter 'Port'\n");
138     return -1;
139     }
140 port = p;
141 ///////////////////////////
142 pv.param = "SendPeriod";
143 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
144 if (pvi == s.moduleParams.end())
145     {
146     errorStr = "Parameter \'SendPeriod\' not found.";
147     printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
148     return -1;
149     }
150
151 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
152     {
153     errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
154     printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
155     return -1;
156     }
157 ///////////////////////////
158 pv.param = "UserParams";
159 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
160 if (pvi == s.moduleParams.end())
161     {
162     errorStr = "Parameter \'UserParams\' not found.";
163     printfd(__FILE__, "Parameter 'UserParams' not found\n");
164     return -1;
165     }
166 userParams = pvi->value;
167 ///////////////////////////
168 pv.param = "Password";
169 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
170 if (pvi == s.moduleParams.end())
171     {
172     errorStr = "Parameter \'Password\' not found.";
173     printfd(__FILE__, "Parameter 'Password' not found\n");
174     return -1;
175     }
176 password = pvi->value[0];
177 ///////////////////////////
178 pv.param = "SubnetFile";
179 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
180 if (pvi == s.moduleParams.end())
181     {
182     errorStr = "Parameter \'SubnetFile\' not found.";
183     printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
184     return -1;
185     }
186 subnetFile = pvi->value[0];
187
188 NRMapParser nrMapParser;
189
190 if (nrMapParser.ReadFile(subnetFile))
191     {
192     errorStr = nrMapParser.GetErrorStr();
193     return -1;
194     }
195
196 netRouters = nrMapParser.GetMap();
197
198 if (netRouters.empty())
199     {
200     errorStr = "Parameter(s) \'Subnet*\' not found.";
201     printfd(__FILE__, "Parameter(s) 'Subnet*' not found\n");
202     return -1;
203     }
204
205 return 0;
206 }
207 //-----------------------------------------------------------------------------
208 //-----------------------------------------------------------------------------
209 //-----------------------------------------------------------------------------
210 REMOTE_SCRIPT::REMOTE_SCRIPT()
211     : sendPeriod(15),
212       halfPeriod(8),
213       nonstop(false),
214       isRunning(false),
215       users(NULL),
216       sock(0),
217       onAddUserNotifier(*this),
218       onDelUserNotifier(*this)
219 {
220 pthread_mutex_init(&mutex, NULL);
221 }
222 //-----------------------------------------------------------------------------
223 REMOTE_SCRIPT::~REMOTE_SCRIPT()
224 {
225 pthread_mutex_destroy(&mutex);
226 }
227 //-----------------------------------------------------------------------------
228 void * REMOTE_SCRIPT::Run(void * d)
229 {
230 REMOTE_SCRIPT * rs = static_cast<REMOTE_SCRIPT *>(d);
231
232 rs->isRunning = true;
233
234 while (rs->nonstop)
235     {
236     rs->PeriodicSend();
237     sleep(2);
238     }
239
240 rs->isRunning = false;
241 return NULL;
242 }
243 //-----------------------------------------------------------------------------
244 int REMOTE_SCRIPT::ParseSettings()
245 {
246 int ret = rsSettings.ParseSettings(settings);
247 if (ret)
248     errorStr = rsSettings.GetStrError();
249
250 sendPeriod = rsSettings.GetSendPeriod();
251 halfPeriod = sendPeriod / 2;
252
253 return ret;
254 }
255 //-----------------------------------------------------------------------------
256 int REMOTE_SCRIPT::Start()
257 {
258 netRouters = rsSettings.GetSubnetsMap();
259
260 InitEncrypt(&ctx, rsSettings.GetPassword());
261
262 //onAddUserNotifier.SetRemoteScript(this);
263 //onDelUserNotifier.SetRemoteScript(this);
264
265 users->AddNotifierUserAdd(&onAddUserNotifier);
266 users->AddNotifierUserDel(&onDelUserNotifier);
267
268 nonstop = true;
269
270 if (GetUsers())
271     {
272     return -1;
273     }
274
275 if (PrepareNet())
276     {
277     return -1;
278     }
279
280 if (!isRunning)
281     {
282     if (pthread_create(&thread, NULL, Run, this))
283         {
284         errorStr = "Cannot create thread.";
285         printfd(__FILE__, "Cannot create thread\n");
286         return -1;
287         }
288     }
289
290 errorStr = "";
291 return 0;
292 }
293 //-----------------------------------------------------------------------------
294 int REMOTE_SCRIPT::Stop()
295 {
296 if (!IsRunning())
297     return 0;
298
299 nonstop = false;
300
301 std::for_each(
302         authorizedUsers.begin(),
303         authorizedUsers.end(),
304         DisconnectUser(*this)
305         );
306
307 FinalizeNet();
308
309 if (isRunning)
310     {
311     //5 seconds to thread stops itself
312     for (int i = 0; i < 25 && isRunning; i++)
313         {
314         usleep(200000);
315         }
316
317     //after 5 seconds waiting thread still running. now killing it
318     if (isRunning)
319         {
320         if (pthread_kill(thread, SIGINT))
321             {
322             errorStr = "Cannot kill thread.";
323             printfd(__FILE__, "Cannot kill thread\n");
324             return -1;
325             }
326         printfd(__FILE__, "REMOTE_SCRIPT killed Run\n");
327         }
328     }
329
330 users->DelNotifierUserDel(&onDelUserNotifier);
331 users->DelNotifierUserAdd(&onAddUserNotifier);
332
333 return 0;
334 }
335 //-----------------------------------------------------------------------------
336 int REMOTE_SCRIPT::Reload()
337 {
338 NRMapParser nrMapParser;
339
340 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
341     {
342     errorStr = nrMapParser.GetErrorStr();
343     return -1;
344     }
345
346     {
347     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
348
349     printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
350
351     netRouters = nrMapParser.GetMap();
352     }
353
354 std::for_each(authorizedUsers.begin(),
355               authorizedUsers.end(),
356               UpdateRouter(*this));
357
358 return 0;
359 }
360 //-----------------------------------------------------------------------------
361 bool REMOTE_SCRIPT::PrepareNet()
362 {
363 sock = socket(AF_INET, SOCK_DGRAM, 0);
364
365 if (sock < 0)
366     {
367     errorStr = "Cannot create socket.";
368     printfd(__FILE__, "Cannot create socket\n");
369     return true;
370     }
371
372 return false;
373 }
374 //-----------------------------------------------------------------------------
375 bool REMOTE_SCRIPT::FinalizeNet()
376 {
377 close(sock);
378 return false;
379 }
380 //-----------------------------------------------------------------------------
381 void REMOTE_SCRIPT::PeriodicSend()
382 {
383 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
384
385 map<uint32_t, RS_USER>::iterator it(authorizedUsers.begin());
386 while (it != authorizedUsers.end())
387     {
388     if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
389     //if (stgTime - it->second.lastSentTime > sendPeriod)
390         {
391         Send(it->first, it->second);
392         }
393     ++it;
394     }
395 }
396 //-----------------------------------------------------------------------------
397 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
398 {
399 RS_PACKET_HEADER packetHead;
400
401 memset(packetHead.padding, 0, sizeof(packetHead.padding));
402 strcpy((char*)packetHead.magic, RS_ID);
403 packetHead.protoVer[0] = '0';
404 packetHead.protoVer[1] = '2';
405 if (forceDisconnect)
406     {
407     packetHead.packetType = RS_DISCONNECT_PACKET;
408     }
409 else
410     {
411     if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
412         {
413         //SendLong
414         packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
415         }
416     else
417         {
418         //SendShort
419         packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
420         }
421     }
422 rsu.shortPacketsCount++;
423 rsu.lastSentTime = stgTime;
424
425 packetHead.ip = htonl(ip);
426 packetHead.id = htonl(rsu.user->GetID());
427 strncpy((char*)packetHead.login, rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
428 packetHead.login[RS_LOGIN_LEN - 1] = 0;
429
430 memcpy(buf, &packetHead, sizeof(packetHead));
431
432 if (packetHead.packetType == RS_ALIVE_PACKET)
433     {
434     return false;
435     }
436
437 RS_PACKET_TAIL packetTail;
438
439 memset(packetTail.padding, 0, sizeof(packetTail.padding));
440 strcpy((char*)packetTail.magic, RS_ID);
441 vector<string>::const_iterator it;
442 std::string params;
443 for(it = rsSettings.GetUserParams().begin();
444     it != rsSettings.GetUserParams().end();
445     ++it)
446     {
447     std::string parameter(GetUserParam(rsu.user, *it));
448     if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
449         break;
450     params += parameter + " ";
451     }
452 strncpy((char *)packetTail.params, params.c_str(), RS_PARAMS_LEN);
453 packetTail.params[RS_PARAMS_LEN - 1] = 0;
454
455 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
456
457 Encrypt(&ctx, buf + sizeof(packetHead), (char *)&packetTail, sizeof(packetTail) / 8);
458
459 return false;
460 }
461 //-----------------------------------------------------------------------------
462 bool REMOTE_SCRIPT::Send(uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
463 {
464 char buffer[RS_MAX_PACKET_LEN];
465
466 memset(buffer, 0, sizeof(buffer));
467
468 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
469     {
470     printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
471     return true;
472     }
473
474 std::for_each(
475         rsu.routers.begin(),
476         rsu.routers.end(),
477         PacketSender(sock, buffer, sizeof(buffer), htons(rsSettings.GetPort()))
478         );
479
480 return false;
481 }
482 //-----------------------------------------------------------------------------
483 bool REMOTE_SCRIPT::SendDirect(uint32_t ip, RS_USER & rsu, uint32_t routerIP, bool forceDisconnect) const
484 {
485 char buffer[RS_MAX_PACKET_LEN];
486
487 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
488     {
489     printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
490     return true;
491     }
492
493 struct sockaddr_in sendAddr;
494
495 sendAddr.sin_family = AF_INET;
496 sendAddr.sin_port = htons(rsSettings.GetPort());
497 sendAddr.sin_addr.s_addr = routerIP;
498
499 int res = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));
500
501 return (res != sizeof(buffer));
502 }
503 //-----------------------------------------------------------------------------
504 bool REMOTE_SCRIPT::GetUsers()
505 {
506 USER_PTR u;
507
508 int h = users->OpenSearch();
509 if (!h)
510     {
511     errorStr = "users->OpenSearch() error.";
512     printfd(__FILE__, "OpenSearch() error\n");
513     return true;
514     }
515
516 while (!users->SearchNext(h, &u))
517     {
518     SetUserNotifier(u);
519     }
520
521 users->CloseSearch(h);
522 return false;
523 }
524 //-----------------------------------------------------------------------------
525 void REMOTE_SCRIPT::ChangedIP(USER_PTR u, uint32_t oldIP, uint32_t newIP)
526 {
527 /*
528  * When ip changes process looks like:
529  * old => 0, 0 => new
530  *
531  */
532 if (newIP)
533     {
534     RS_USER rsu(IP2Routers(newIP), u);
535     Send(newIP, rsu);
536
537     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
538     authorizedUsers[newIP] = rsu;
539     }
540 else
541     {
542     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
543     const map<uint32_t, RS_USER>::iterator it(
544             authorizedUsers.find(oldIP)
545             );
546     if (it != authorizedUsers.end())
547         {
548         Send(oldIP, it->second, true);
549         authorizedUsers.erase(it);
550         }
551     }
552 }
553 //-----------------------------------------------------------------------------
554 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
555 {
556 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
557 for (size_t i = 0; i < netRouters.size(); ++i)
558     {
559     if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
560         {
561         return netRouters[i].routers;
562         }
563     }
564 return std::vector<uint32_t>();
565 }
566 //-----------------------------------------------------------------------------
567 string REMOTE_SCRIPT::GetUserParam(USER_PTR u, const string & paramName) const
568 {
569 string value = "";
570 if (strcasecmp(paramName.c_str(), "cash") == 0)
571     strprintf(&value, "%f", u->GetProperty().cash.Get());
572 else
573 if (strcasecmp(paramName.c_str(), "freeMb") == 0)
574     strprintf(&value, "%f", u->GetProperty().freeMb.Get());
575 else
576 if (strcasecmp(paramName.c_str(), "passive") == 0)
577     strprintf(&value, "%d", u->GetProperty().passive.Get());
578 else
579 if (strcasecmp(paramName.c_str(), "disabled") == 0)
580     strprintf(&value, "%d", u->GetProperty().disabled.Get());
581 else
582 if (strcasecmp(paramName.c_str(), "alwaysOnline") == 0)
583     strprintf(&value, "%d", u->GetProperty().alwaysOnline.Get());
584 else
585 if (strcasecmp(paramName.c_str(), "tariffName") == 0 ||
586     strcasecmp(paramName.c_str(), "tariff") == 0)
587     value = "\"" + u->GetProperty().tariffName.Get() + "\"";
588 else
589 if (strcasecmp(paramName.c_str(), "nextTariff") == 0)
590     value = "\"" + u->GetProperty().nextTariff.Get() + "\"";
591 else
592 if (strcasecmp(paramName.c_str(), "address") == 0)
593     value = "\"" + u->GetProperty().address.Get() + "\"";
594 else
595 if (strcasecmp(paramName.c_str(), "note") == 0)
596     value = "\"" + u->GetProperty().note.Get() + "\"";
597 else
598 if (strcasecmp(paramName.c_str(), "group") == 0)
599     value = "\"" + u->GetProperty().group.Get() + "\"";
600 else
601 if (strcasecmp(paramName.c_str(), "email") == 0)
602     value = "\"" + u->GetProperty().email.Get() + "\"";
603 else
604 if (strcasecmp(paramName.c_str(), "realName") == 0)
605     value = "\"" + u->GetProperty().realName.Get() + "\"";
606 else
607 if (strcasecmp(paramName.c_str(), "credit") == 0)
608     strprintf(&value, "%f", u->GetProperty().credit.Get());
609 else
610 if (strcasecmp(paramName.c_str(), "userdata0") == 0)
611     value = "\"" + u->GetProperty().userdata0.Get() + "\"";
612 else
613 if (strcasecmp(paramName.c_str(), "userdata1") == 0)
614     value = "\"" + u->GetProperty().userdata1.Get() + "\"";
615 else
616 if (strcasecmp(paramName.c_str(), "userdata2") == 0)
617     value = "\"" + u->GetProperty().userdata2.Get() + "\"";
618 else
619 if (strcasecmp(paramName.c_str(), "userdata3") == 0)
620     value = "\"" + u->GetProperty().userdata3.Get() + "\"";
621 else
622 if (strcasecmp(paramName.c_str(), "userdata4") == 0)
623     value = "\"" + u->GetProperty().userdata4.Get() + "\"";
624 else
625 if (strcasecmp(paramName.c_str(), "userdata5") == 0)
626     value = "\"" + u->GetProperty().userdata5.Get() + "\"";
627 else
628 if (strcasecmp(paramName.c_str(), "userdata6") == 0)
629     value = "\"" + u->GetProperty().userdata6.Get() + "\"";
630 else
631 if (strcasecmp(paramName.c_str(), "userdata7") == 0)
632     value = "\"" + u->GetProperty().userdata7.Get() + "\"";
633 else
634 if (strcasecmp(paramName.c_str(), "userdata8") == 0)
635     value = "\"" + u->GetProperty().userdata8.Get() + "\"";
636 else
637 if (strcasecmp(paramName.c_str(), "userdata9") == 0)
638     value = "\"" + u->GetProperty().userdata9.Get() + "\"";
639 else
640 if (strcasecmp(paramName.c_str(), "enabledDirs") == 0)
641     value = u->GetEnabledDirs();
642 else
643     printfd(__FILE__, "Unknown value name: %s\n", paramName.c_str());
644 return value;
645 }
646 //-----------------------------------------------------------------------------
647 void REMOTE_SCRIPT::SetUserNotifier(USER_PTR u)
648 {
649 RS_CHG_AFTER_NOTIFIER<uint32_t> afterChgIPNotifier(*this, u);
650
651 afterChgIPNotifierList.push_front(afterChgIPNotifier);
652
653 u->AddCurrIPAfterNotifier(&(*afterChgIPNotifierList.begin()));
654 }
655 //-----------------------------------------------------------------------------
656 void REMOTE_SCRIPT::UnSetUserNotifier(USER_PTR u)
657 {
658 list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator  ipAIter;
659 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator> toErase;
660
661 for (ipAIter = afterChgIPNotifierList.begin(); ipAIter != afterChgIPNotifierList.end(); ++ipAIter)
662     {
663     if (ipAIter->GetUser() == u)
664         {
665         u->DelCurrIPAfterNotifier(&(*ipAIter));
666         toErase.push_back(ipAIter);
667         }
668     }
669
670 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator>::iterator eIter;
671
672 for (eIter = toErase.begin(); eIter != toErase.end(); ++eIter)
673     {
674     afterChgIPNotifierList.erase(*eIter);
675     }
676 }
677 //-----------------------------------------------------------------------------
678 template <typename varParamType>
679 void RS_CHG_AFTER_NOTIFIER<varParamType>::Notify(const varParamType & oldValue, const varParamType & newValue)
680 {
681 rs.ChangedIP(user, oldValue, newValue);
682 }
683 //-----------------------------------------------------------------------------
684 void REMOTE_SCRIPT::InitEncrypt(BLOWFISH_CTX * ctx, const string & password) const
685 {
686 unsigned char keyL[PASSWD_LEN];  // Пароль для шифровки
687 memset(keyL, 0, PASSWD_LEN);
688 strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
689 Blowfish_Init(ctx, keyL, PASSWD_LEN);
690 }
691 //-----------------------------------------------------------------------------
692 void REMOTE_SCRIPT::Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, size_t len8) const
693 {
694 if (dst != src)
695     memcpy(dst, src, len8 * 8);
696 for (size_t i = 0; i < len8; ++i)
697     Blowfish_Encrypt(ctx, (uint32_t *)(dst + i * 8), (uint32_t *)(dst + i * 8 + 4));
698 }
699 //-----------------------------------------------------------------------------