]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp
Complete replacement notifiers with subscriptions.
[stg.git] / projects / stargazer / plugins / authorization / inetaccess / inetaccess.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  */
20
21 #ifndef _GNU_SOURCE
22 #define _GNU_SOURCE
23 #endif
24
25 #include "inetaccess.h"
26
27 #include "stg/common.h"
28 #include "stg/locker.h"
29 #include "stg/tariff.h"
30 #include "stg/settings.h"
31
32 #include <algorithm>
33 #include <csignal>
34 #include <cstdlib>
35 #include <cstdio> // snprintf
36 #include <cerrno>
37 #include <cmath>
38
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <unistd.h> // close
42
43 #define IA_PROTO_VER    (6)
44
45 extern volatile time_t stgTime;
46
47 extern "C" STG::Plugin* GetPlugin()
48 {
49     static AUTH_IA plugin;
50     return &plugin;
51 }
52 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 //-----------------------------------------------------------------------------
55 AUTH_IA_SETTINGS::AUTH_IA_SETTINGS()
56     : userDelay(0),
57       userTimeout(0),
58       port(0),
59       freeMbShowType(freeMbCash),
60       logProtocolErrors(false)
61 {
62 }
63 //-----------------------------------------------------------------------------
64 int AUTH_IA_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
65 {
66 int p;
67 STG::ParamValue pv;
68 std::vector<STG::ParamValue>::const_iterator pvi;
69 ///////////////////////////
70 pv.param = "Port";
71 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
72 if (pvi == s.moduleParams.end() || pvi->value.empty())
73     {
74     errorStr = "Parameter \'Port\' not found.";
75     printfd(__FILE__, "Parameter 'Port' not found\n");
76     return -1;
77     }
78 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
79     {
80     errorStr = "Cannot parse parameter \'Port\': " + errorStr;
81     printfd(__FILE__, "Cannot parse parameter 'Port'\n");
82     return -1;
83     }
84 port = static_cast<uint16_t>(p);
85 ///////////////////////////
86 pv.param = "UserDelay";
87 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
88 if (pvi == s.moduleParams.end() || pvi->value.empty())
89     {
90     errorStr = "Parameter \'UserDelay\' not found.";
91     printfd(__FILE__, "Parameter 'UserDelay' not found\n");
92     return -1;
93     }
94
95 if (ParseIntInRange(pvi->value[0], 5, 600, &userDelay))
96     {
97     errorStr = "Cannot parse parameter \'UserDelay\': " + errorStr;
98     printfd(__FILE__, "Cannot parse parameter 'UserDelay'\n");
99     return -1;
100     }
101 ///////////////////////////
102 pv.param = "UserTimeout";
103 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
104 if (pvi == s.moduleParams.end() || pvi->value.empty())
105     {
106     errorStr = "Parameter \'UserTimeout\' not found.";
107     printfd(__FILE__, "Parameter 'UserTimeout' not found\n");
108     return -1;
109     }
110
111 if (ParseIntInRange(pvi->value[0], 15, 1200, &userTimeout))
112     {
113     errorStr = "Cannot parse parameter \'UserTimeout\': " + errorStr;
114     printfd(__FILE__, "Cannot parse parameter 'UserTimeout'\n");
115     return -1;
116     }
117 ///////////////////////////
118 pv.param = "LogProtocolErrors";
119 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
120 if (pvi == s.moduleParams.end() || pvi->value.empty())
121     logProtocolErrors = false;
122 else if (ParseYesNo(pvi->value[0], &logProtocolErrors))
123     {
124     errorStr = "Cannot parse parameter \'LogProtocolErrors\': " + errorStr;
125     printfd(__FILE__, "Cannot parse parameter 'LogProtocolErrors'\n");
126     return -1;
127     }
128 /////////////////////////////////////////////////////////////
129 std::string freeMbType;
130 int n = 0;
131 pv.param = "FreeMb";
132 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
133 if (pvi == s.moduleParams.end() || pvi->value.empty())
134     {
135     errorStr = "Parameter \'FreeMb\' not found.";
136     printfd(__FILE__, "Parameter 'FreeMb' not found\n");
137     return -1;
138     }
139 freeMbType = pvi->value[0];
140
141 if (strcasecmp(freeMbType.c_str(), "cash") == 0)
142     {
143     freeMbShowType = freeMbCash;
144     }
145 else if (strcasecmp(freeMbType.c_str(), "none") == 0)
146     {
147     freeMbShowType = freeMbNone;
148     }
149 else if (!str2x(freeMbType.c_str(), n))
150     {
151     if (n < 0 || n >= DIR_NUM)
152         {
153         errorStr = "Incorrect parameter \'" + freeMbType + "\'.";
154         printfd(__FILE__, "%s\n", errorStr.c_str());
155         return -1;
156         }
157     freeMbShowType = static_cast<FREEMB>(n);
158     }
159 else
160     {
161     errorStr = "Incorrect parameter \'" + freeMbType + "\'.";
162     printfd(__FILE__, "%s\n", errorStr.c_str());
163     return -1;
164     }
165 /////////////////////////////////////////////////////////////
166 return 0;
167 }
168 //-----------------------------------------------------------------------------
169 //-----------------------------------------------------------------------------
170 //-----------------------------------------------------------------------------
171 #ifdef IA_PHASE_DEBUG
172 IA_PHASE::IA_PHASE()
173     : phase(1),
174       flog(NULL)
175 {
176 gettimeofday(&phaseTime, NULL);
177 }
178 #else
179 IA_PHASE::IA_PHASE()
180     : phase(1)
181 {
182 gettimeofday(&phaseTime, NULL);
183 }
184 #endif
185 //-----------------------------------------------------------------------------
186 IA_PHASE::~IA_PHASE()
187 {
188 #ifdef IA_PHASE_DEBUG
189 flog = fopen(log.c_str(), "at");
190 if (flog)
191     {
192     fprintf(flog, "IA %s D\n", login.c_str());
193     fclose(flog);
194     }
195 #endif
196 }
197 //-----------------------------------------------------------------------------
198 #ifdef IA_PHASE_DEBUG
199 void IA_PHASE::SetLogFileName(const string & logFileName)
200 {
201 log = logFileName + ".ia.log";
202 }
203 //-----------------------------------------------------------------------------
204 void IA_PHASE::SetUserLogin(const string & login)
205 {
206 IA_PHASE::login = login;
207 }
208 //-----------------------------------------------------------------------------
209 void IA_PHASE::WritePhaseChange(int newPhase)
210 {
211 UTIME newPhaseTime;
212 gettimeofday(&newPhaseTime, NULL);
213 flog = fopen(log.c_str(), "at");
214 if (flog)
215     {
216     string action = newPhase == phase ? "U" : "C";
217     double delta = newPhaseTime.GetSec() - phaseTime.GetSec();
218     delta += (newPhaseTime.GetUSec() - phaseTime.GetUSec()) * 1.0e-6;
219     fprintf(flog, "IA %s %s oldPhase = %d, newPhase = %d. dt = %.6f\n",
220             login.c_str(),
221             action.c_str(),
222             phase,
223             newPhase,
224             delta);
225     fclose(flog);
226     }
227 }
228 #endif
229 //-----------------------------------------------------------------------------
230 void IA_PHASE::SetPhase1()
231 {
232 #ifdef IA_PHASE_DEBUG
233 WritePhaseChange(1);
234 #endif
235 phase = 1;
236 gettimeofday(&phaseTime, NULL);
237 }
238 //-----------------------------------------------------------------------------
239 void IA_PHASE::SetPhase2()
240 {
241 #ifdef IA_PHASE_DEBUG
242 WritePhaseChange(2);
243 #endif
244 phase = 2;
245 gettimeofday(&phaseTime, NULL);
246 }
247 //-----------------------------------------------------------------------------
248 void IA_PHASE::SetPhase3()
249 {
250 #ifdef IA_PHASE_DEBUG
251 WritePhaseChange(3);
252 #endif
253 phase = 3;
254 gettimeofday(&phaseTime, NULL);
255 }
256 //-----------------------------------------------------------------------------
257 void IA_PHASE::SetPhase4()
258 {
259 #ifdef IA_PHASE_DEBUG
260 WritePhaseChange(4);
261 #endif
262 phase = 4;
263 gettimeofday(&phaseTime, NULL);
264 }
265 //-----------------------------------------------------------------------------
266 int IA_PHASE::GetPhase() const
267 {
268 return phase;
269 }
270 //-----------------------------------------------------------------------------
271 void IA_PHASE::UpdateTime()
272 {
273 #ifdef IA_PHASE_DEBUG
274 WritePhaseChange(phase);
275 #endif
276 gettimeofday(&phaseTime, NULL);
277 }
278 //-----------------------------------------------------------------------------
279 const UTIME & IA_PHASE::GetTime() const
280 {
281 return phaseTime;
282 }
283 //-----------------------------------------------------------------------------
284 //-----------------------------------------------------------------------------
285 //-----------------------------------------------------------------------------
286 AUTH_IA::AUTH_IA()
287     : isRunningRun(false),
288       isRunningRunTimeouter(false),
289       users(NULL),
290       stgSettings(NULL),
291       listenSocket(-1),
292       enabledDirs(0xFFffFFff),
293       logger(STG::PluginLogger::get("auth_ia"))
294 {
295 InitContext("pr7Hhen", 7, &ctxS);
296
297 memset(&connSynAck6, 0, sizeof(CONN_SYN_ACK_6));
298 memset(&connSynAck8, 0, sizeof(CONN_SYN_ACK_8));
299 memset(&disconnSynAck6, 0, sizeof(DISCONN_SYN_ACK_6));
300 memset(&disconnSynAck8, 0, sizeof(DISCONN_SYN_ACK_8));
301 memset(&aliveSyn6, 0, sizeof(ALIVE_SYN_6));
302 memset(&aliveSyn8, 0, sizeof(ALIVE_SYN_8));
303 memset(&fin6, 0, sizeof(FIN_6));
304 memset(&fin8, 0, sizeof(FIN_8));
305
306 printfd(__FILE__, "sizeof(CONN_SYN_6) = %d %d\n",           sizeof(CONN_SYN_6),     Min8(sizeof(CONN_SYN_6)));
307 printfd(__FILE__, "sizeof(CONN_SYN_8) = %d %d\n",           sizeof(CONN_SYN_8),     Min8(sizeof(CONN_SYN_8)));
308 printfd(__FILE__, "sizeof(CONN_SYN_ACK_6) = %d %d\n",       sizeof(CONN_SYN_ACK_6), Min8(sizeof(CONN_SYN_ACK_6)));
309 printfd(__FILE__, "sizeof(CONN_SYN_ACK_8) = %d %d\n",       sizeof(CONN_SYN_ACK_8), Min8(sizeof(CONN_SYN_ACK_8)));
310 printfd(__FILE__, "sizeof(CONN_ACK_6) = %d %d\n",           sizeof(CONN_ACK_6),     Min8(sizeof(CONN_ACK_6)));
311 printfd(__FILE__, "sizeof(ALIVE_SYN_6) = %d %d\n",          sizeof(ALIVE_SYN_6),    Min8(sizeof(ALIVE_SYN_6)));
312 printfd(__FILE__, "sizeof(ALIVE_SYN_8) = %d %d\n",          sizeof(ALIVE_SYN_8),    Min8(sizeof(ALIVE_SYN_8)));
313 printfd(__FILE__, "sizeof(ALIVE_ACK_6) = %d %d\n",          sizeof(ALIVE_ACK_6),    Min8(sizeof(ALIVE_ACK_6)));
314 printfd(__FILE__, "sizeof(DISCONN_SYN_6) = %d %d\n",        sizeof(DISCONN_SYN_6),  Min8(sizeof(DISCONN_SYN_6)));
315 printfd(__FILE__, "sizeof(DISCONN_SYN_ACK_6) = %d %d\n",    sizeof(DISCONN_SYN_ACK_6), Min8(sizeof(DISCONN_SYN_ACK_6)));
316 printfd(__FILE__, "sizeof(DISCONN_SYN_ACK_8) = %d %d\n",    sizeof(DISCONN_SYN_ACK_8), Min8(sizeof(DISCONN_SYN_ACK_8)));
317 printfd(__FILE__, "sizeof(DISCONN_ACK_6) = %d %d\n",        sizeof(DISCONN_ACK_6),  Min8(sizeof(DISCONN_ACK_6)));
318 printfd(__FILE__, "sizeof(FIN_6) = %d %d\n",                sizeof(FIN_6),          Min8(sizeof(FIN_6)));
319 printfd(__FILE__, "sizeof(FIN_8) = %d %d\n",                sizeof(FIN_8),          Min8(sizeof(FIN_8)));
320 printfd(__FILE__, "sizeof(ERR) = %d %d\n",                  sizeof(ERR),            Min8(sizeof(ERR)));
321 printfd(__FILE__, "sizeof(INFO_6) = %d %d\n",               sizeof(INFO_6),         Min8(sizeof(INFO_6)));
322 printfd(__FILE__, "sizeof(INFO_7) = %d %d\n",               sizeof(INFO_7),         Min8(sizeof(INFO_7)));
323 printfd(__FILE__, "sizeof(INFO_8) = %d %d\n",               sizeof(INFO_8),         Min8(sizeof(INFO_8)));
324
325 packetTypes["CONN_SYN"] = CONN_SYN_N;
326 packetTypes["CONN_SYN_ACK"] = CONN_SYN_ACK_N;
327 packetTypes["CONN_ACK"] = CONN_ACK_N;
328 packetTypes["ALIVE_SYN"] = ALIVE_SYN_N;
329 packetTypes["ALIVE_ACK"] = ALIVE_ACK_N;
330 packetTypes["DISCONN_SYN"] = DISCONN_SYN_N;
331 packetTypes["DISCONN_SYN_ACK"] = DISCONN_SYN_ACK_N;
332 packetTypes["DISCONN_ACK"] = DISCONN_ACK_N;
333 packetTypes["FIN"] = FIN_N;
334 packetTypes["ERR"] = ERROR_N;
335 }
336 //-----------------------------------------------------------------------------
337 AUTH_IA::~AUTH_IA()
338 {
339 }
340 //-----------------------------------------------------------------------------
341 int AUTH_IA::Start()
342 {
343 m_onDelUserConn = users->onDel([this](auto user){ DelUser(user); });
344
345 if (PrepareNet())
346     return -1;
347
348 if (!m_thread.joinable())
349     m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
350
351 if (!m_timeouterThread.joinable())
352     m_timeouterThread = std::jthread([this](auto token){ RunTimeouter(std::move(token)); });
353
354 errorStr = "";
355 return 0;
356 }
357 //-----------------------------------------------------------------------------
358 int AUTH_IA::Stop()
359 {
360 if (!IsRunning())
361     return 0;
362
363 m_thread.request_stop();
364 m_timeouterThread.request_stop();
365
366 std::for_each(
367         ip2user.begin(),
368         ip2user.end(),
369         UnauthorizeUser(this)
370         );
371
372 if (isRunningRun)
373     {
374     //5 seconds to thread stops itself
375     for (int i = 0; i < 25 && isRunningRun; i++)
376         {
377         struct timespec ts = {0, 200000000};
378         nanosleep(&ts, NULL);
379         }
380     }
381
382 FinalizeNet();
383
384 if (isRunningRunTimeouter)
385     {
386     //5 seconds to thread stops itself
387     for (int i = 0; i < 25 && isRunningRunTimeouter; i++)
388         {
389         struct timespec ts = {0, 200000000};
390         nanosleep(&ts, NULL);
391         }
392     }
393
394 m_onDelUserConn.disconnect();
395
396 if (isRunningRun)
397     m_thread.detach();
398 else
399     m_thread.join();
400
401 if (isRunningRunTimeouter)
402     m_timeouterThread.detach();
403 else
404     m_timeouterThread.join();
405
406 if (isRunningRun || isRunningRunTimeouter)
407     return -1;
408
409 printfd(__FILE__, "AUTH_IA::Stoped successfully.\n");
410 return 0;
411 }
412 //-----------------------------------------------------------------------------
413 void AUTH_IA::Run(std::stop_token token)
414 {
415 sigset_t signalSet;
416 sigfillset(&signalSet);
417 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
418
419 isRunningRun = true;
420
421 char buffer[512];
422
423 time_t touchTime = stgTime - MONITOR_TIME_DELAY_SEC;
424
425 while (!token.stop_requested())
426     {
427     RecvData(buffer, sizeof(buffer));
428     if ((touchTime + MONITOR_TIME_DELAY_SEC <= stgTime) && stgSettings->GetMonitoring())
429         {
430         touchTime = stgTime;
431         std::string monFile = stgSettings->GetMonitorDir() + "/inetaccess_r";
432         TouchFile(monFile);
433         }
434     }
435
436 isRunningRun = false;
437 }
438 //-----------------------------------------------------------------------------
439 void AUTH_IA::RunTimeouter(std::stop_token token)
440 {
441 sigset_t signalSet;
442 sigfillset(&signalSet);
443 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
444
445 isRunningRunTimeouter = true;
446
447 int a = -1;
448 std::string monFile = stgSettings->GetMonitorDir() + "/inetaccess_t";
449 while (!token.stop_requested())
450     {
451     struct timespec ts = {0, 20000000};
452     nanosleep(&ts, NULL);
453     Timeouter();
454     // TODO change counter to timer and MONITOR_TIME_DELAY_SEC
455     if (++a % (50 * 60) == 0 && stgSettings->GetMonitoring())
456         {
457         TouchFile(monFile);
458         }
459     }
460
461 isRunningRunTimeouter = false;
462 }
463 //-----------------------------------------------------------------------------
464 int AUTH_IA::ParseSettings()
465 {
466 int ret = iaSettings.ParseSettings(settings);
467 if (ret)
468     errorStr = iaSettings.GetStrError();
469 return ret;
470 }
471 //-----------------------------------------------------------------------------
472 int AUTH_IA::Reload(const STG::ModuleSettings & ms)
473 {
474 AUTH_IA_SETTINGS newIaSettings;
475 if (newIaSettings.ParseSettings(ms))
476     {
477     printfd(__FILE__, "AUTH_IA::Reload() - Failed to reload InetAccess.\n");
478     logger("AUTH_IA: Cannot reload InetAccess. Errors found.");
479     return -1;
480     }
481
482 printfd(__FILE__, "AUTH_IA::Reload() -  Reloaded InetAccess successfully.\n");
483 logger("AUTH_IA: Reloaded InetAccess successfully.");
484 iaSettings = newIaSettings;
485 return 0;
486 }
487 //-----------------------------------------------------------------------------
488 int AUTH_IA::PrepareNet()
489 {
490 struct sockaddr_in listenAddr;
491
492 listenSocket = socket(AF_INET, SOCK_DGRAM, 0);
493
494 if (listenSocket < 0)
495     {
496     errorStr = "Cannot create socket.";
497     logger("Cannot create a socket: %s", strerror(errno));
498     return -1;
499     }
500
501 listenAddr.sin_family = AF_INET;
502 listenAddr.sin_port = htons(iaSettings.GetUserPort());
503 listenAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
504
505 if (bind(listenSocket, reinterpret_cast<sockaddr*>(&listenAddr), sizeof(listenAddr)) < 0)
506     {
507     errorStr = "AUTH_IA: Bind failed.";
508     logger("Cannot bind the socket: %s", strerror(errno));
509     return -1;
510     }
511
512 return 0;
513 }
514 //-----------------------------------------------------------------------------
515 int AUTH_IA::FinalizeNet()
516 {
517 close(listenSocket);
518 return 0;
519 }
520 //-----------------------------------------------------------------------------
521 int AUTH_IA::RecvData(char * buffer, int bufferSize)
522 {
523 if (!WaitPackets(listenSocket)) // Timeout
524     {
525     return 0;
526     }
527
528 struct sockaddr_in outerAddr;
529 socklen_t outerAddrLen(sizeof(outerAddr));
530 ssize_t dataLen = recvfrom(listenSocket, buffer, bufferSize, 0, reinterpret_cast<sockaddr *>(&outerAddr), &outerAddrLen);
531
532 if (!dataLen) // EOF
533     {
534     return 0;
535     }
536
537 if (dataLen <= 0) // Error
538     {
539     if (errno != EINTR)
540         {
541         printfd(__FILE__, "recvfrom res=%d, error: '%s'\n", dataLen, strerror(errno));
542         logger("recvfrom error: %s", strerror(errno));
543         return -1;
544         }
545     return 0;
546     }
547
548 if (dataLen > 256)
549     return -1;
550
551 uint32_t sip = outerAddr.sin_addr.s_addr;
552 uint16_t sport = htons(outerAddr.sin_port);
553
554 int protoVer;
555 if (CheckHeader(buffer, sip, &protoVer))
556     return -1;
557
558 char login[PASSWD_LEN];  //TODO why PASSWD_LEN ?
559 memset(login, 0, PASSWD_LEN);
560
561 DecryptString(login, buffer + 8, PASSWD_LEN, &ctxS);
562
563 UserPtr user;
564 if (users->FindByName(login, &user))
565     {
566     logger("User's connect failed: user '%s' not found. IP %s",
567            login,
568            inet_ntostring(sip).c_str());
569     printfd(__FILE__, "User '%s' NOT found!\n", login);
570     SendError(sip, sport, protoVer, IconvString("Неправильный логин.", "utf8", "koi8-ru"));
571     return -1;
572     }
573
574 printfd(__FILE__, "User '%s' FOUND!\n", user->GetLogin().c_str());
575
576 if (user->GetProperties().disabled.Get())
577     {
578     logger("Cannont authorize '%s', user is disabled.", login);
579     SendError(sip, sport, protoVer, IconvString("Учетная запись заблокирована.", "utf8", "koi8-ru"));
580     return 0;
581     }
582
583 if (user->GetProperties().passive.Get())
584     {
585     logger("Cannont authorize '%s', user is passive.", login);
586     SendError(sip, sport, protoVer, IconvString("Учетная запись заморожена.", "utf8", "koi8-ru"));
587     return 0;
588     }
589
590 if (!user->GetProperties().ips.Get().find(sip))
591     {
592     printfd(__FILE__, "User %s. IP address is incorrect. IP %s\n",
593             user->GetLogin().c_str(), inet_ntostring(sip).c_str());
594     logger("User %s. IP address is incorrect. IP %s",
595            user->GetLogin().c_str(), inet_ntostring(sip).c_str());
596     SendError(sip, sport, protoVer, IconvString("Пользователь не опознан. Проверьте IP-адрес.", "utf8", "koi8-ru"));
597     return 0;
598     }
599
600 return PacketProcessor(buffer, dataLen, sip, sport, protoVer, user);
601 }
602 //-----------------------------------------------------------------------------
603 int AUTH_IA::CheckHeader(const char * buffer, uint32_t sip, int * protoVer)
604 {
605 if (strncmp(IA_ID, buffer, strlen(IA_ID)) != 0)
606     {
607     printfd(__FILE__, "update needed - IA_ID\n");
608     if (iaSettings.LogProtocolErrors())
609         logger("IP: %s. Header: invalid packed signature.", inet_ntostring(sip).c_str());
610     return -1;
611     }
612
613 if (buffer[6] != 0) //proto[0] shoud be 0
614     {
615     printfd(__FILE__, "update needed - PROTO major: %d\n", buffer[6]);
616     if (iaSettings.LogProtocolErrors())
617         logger("IP: %s. Header: invalid protocol major version: %d.", inet_ntostring(sip).c_str(), buffer[6]);
618     return -1;
619     }
620
621 if (buffer[7] < 6)
622     {
623     // need update
624     printfd(__FILE__, "update needed - PROTO minor: %d\n", buffer[7]);
625     if (iaSettings.LogProtocolErrors())
626         logger("IP: %s. Header: invalid protocol minor version: %d.", inet_ntostring(sip).c_str(), buffer[7]);
627     return -1;
628     }
629 else
630     {
631     *protoVer = buffer[7];
632     }
633 return 0;
634 }
635 //-----------------------------------------------------------------------------
636 int AUTH_IA::Timeouter()
637 {
638 std::lock_guard lock(m_mutex);
639
640 std::map<uint32_t, IA_USER>::iterator it;
641 it = ip2user.begin();
642
643 while (it != ip2user.end())
644     {
645     uint32_t sip = it->first;
646
647     static UTIME currTime;
648     gettimeofday(&currTime, NULL);
649
650     if ((it->second.phase.GetPhase() == 2)
651         && (currTime - it->second.phase.GetTime()) > iaSettings.GetUserDelay())
652         {
653         if (iaSettings.LogProtocolErrors())
654             logger("User '%s'. Protocol version: %d. Phase 2: connect request timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserDelay().GetSec());
655         it->second.phase.SetPhase1();
656         printfd(__FILE__, "Phase changed from 2 to 1. Reason: timeout\n");
657         ip2user.erase(it++);
658         continue;
659         }
660
661     if (it->second.phase.GetPhase() == 3)
662         {
663         if (!it->second.messagesToSend.empty())
664             {
665             if (it->second.protoVer == 6)
666                 RealSendMessage6(*it->second.messagesToSend.begin(), sip, it->second);
667
668             if (it->second.protoVer == 7)
669                 RealSendMessage7(*it->second.messagesToSend.begin(), sip, it->second);
670
671             if (it->second.protoVer == 8)
672                 RealSendMessage8(*it->second.messagesToSend.begin(), sip, it->second);
673
674             it->second.messagesToSend.erase(it->second.messagesToSend.begin());
675             }
676
677         if((currTime - it->second.lastSendAlive) > iaSettings.GetUserDelay())
678             {
679             switch (it->second.protoVer)
680                 {
681                 case 6:
682                     Send_ALIVE_SYN_6(&(it->second), sip);
683                     break;
684                 case 7:
685                     Send_ALIVE_SYN_7(&(it->second), sip);
686                     break;
687                 case 8:
688                     Send_ALIVE_SYN_8(&(it->second), sip);
689                     break;
690                 }
691
692             gettimeofday(&it->second.lastSendAlive, NULL);
693             }
694
695         if ((currTime - it->second.phase.GetTime()) > iaSettings.GetUserTimeout())
696             {
697             if (iaSettings.LogProtocolErrors())
698                 logger("User '%s'. Protocol version: %d. Phase 3: alive timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserTimeout().GetSec());
699             users->Unauthorize(it->second.user->GetLogin(), this);
700             ip2user.erase(it++);
701             continue;
702             }
703         }
704
705     if ((it->second.phase.GetPhase() == 4)
706         && ((currTime - it->second.phase.GetTime()) > iaSettings.GetUserDelay()))
707         {
708         if (iaSettings.LogProtocolErrors())
709             logger("User '%s'. Protocol version: %d. Phase 4: disconnect request timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserDelay().GetSec());
710         it->second.phase.SetPhase3();
711         printfd(__FILE__, "Phase changed from 4 to 3. Reason: timeout\n");
712         }
713
714     ++it;
715     }
716
717 return 0;
718 }
719 //-----------------------------------------------------------------------------
720 int AUTH_IA::PacketProcessor(void * buff, size_t dataLen, uint32_t sip, uint16_t sport, int protoVer, UserPtr user)
721 {
722 std::string login(user->GetLogin());
723 const size_t offset = LOGIN_LEN + 2 + 6; // LOGIN_LEN + sizeOfMagic + sizeOfVer;
724
725 std::lock_guard lock(m_mutex);
726 std::map<uint32_t, IA_USER>::iterator it(ip2user.find(sip));
727
728 if (it == ip2user.end())
729     {
730     UserPtr userPtr;
731     if (!users->FindByIPIdx(sip, &userPtr))
732         {
733         if (userPtr->GetID() != user->GetID())
734             {
735             printfd(__FILE__, "IP address already in use by user '%s'. IP %s, login: '%s'\n",
736                     userPtr->GetLogin().c_str(),
737                     inet_ntostring(sip).c_str(),
738                    login.c_str());
739             logger("IP address is already in use by user '%s'. IP %s, login: '%s'",
740                    userPtr->GetLogin().c_str(),
741                    inet_ntostring(sip).c_str(),
742                    login.c_str());
743             SendError(sip, sport, protoVer, IconvString("IP-адрес уже сипользуется.", "utf8", "koi8-ru"));
744             return 0;
745             }
746         }
747
748     printfd(__FILE__, "Add new user '%s' from ip %s\n",
749             login.c_str(), inet_ntostring(sip).c_str());
750     std::pair<std::map<uint32_t, IA_USER>::iterator, bool> res;
751     res = ip2user.insert(std::make_pair(sip, IA_USER(login, user, sport, protoVer)));
752     it = res.first;
753     #ifdef IA_PHASE_DEBUG
754     it->second.phase.SetLogFileName(stgSettings->GetLogFileName());
755     it->second.phase.SetUserLogin(login);
756     #endif
757     }
758 else if (user->GetID() != it->second.user->GetID())
759     {
760     printfd(__FILE__, "IP address already in use by user '%s'. IP %s, login: '%s'\n",
761             it->second.user->GetLogin().c_str(),
762             inet_ntostring(sip).c_str(),
763             user->GetLogin().c_str());
764     logger("IP address is already in use by user '%s'. IP %s, login: '%s'",
765            it->second.user->GetLogin().c_str(),
766            inet_ntostring(sip).c_str(),
767            user->GetLogin().c_str());
768     SendError(sip, sport, protoVer, IconvString("IP-адрес уже используется.", "utf8", "koi8-ru"));
769     return 0;
770     }
771
772 IA_USER * iaUser = &(it->second);
773
774 if (iaUser->password != user->GetProperties().password.Get())
775     {
776     const std::string & password = user->GetProperties().password.Get();
777     InitContext(password.c_str(), password.length(), &iaUser->ctx);
778     iaUser->password = user->GetProperties().password.Get();
779     }
780
781 DecryptString(static_cast<char *>(buff) + offset, static_cast<char *>(buff) + offset, (dataLen - offset), &iaUser->ctx);
782
783 char packetName[IA_MAX_TYPE_LEN];
784 strncpy(packetName,  static_cast<char *>(buff) + offset + 4, IA_MAX_TYPE_LEN);
785 packetName[IA_MAX_TYPE_LEN - 1] = 0;
786
787 std::map<std::string, int>::iterator pi(packetTypes.find(packetName));
788 if (pi == packetTypes.end())
789     {
790     SendError(sip, sport, protoVer, IconvString("Неправильный логин или пароль.", "utf8", "koi8-ru"));
791     printfd(__FILE__, "Login or password is wrong!\n");
792     logger("User's connect failed. User: '%s', ip %s. Wrong login or password",
793            login.c_str(),
794            inet_ntostring(sip).c_str());
795     ip2user.erase(it);
796     return 0;
797     }
798
799 if (user->IsAuthorizedBy(this) && user->GetCurrIP() != sip)
800     {
801     printfd(__FILE__, "Login %s already in use from ip %s. IP %s\n",
802             login.c_str(), inet_ntostring(user->GetCurrIP()).c_str(),
803             inet_ntostring(sip).c_str());
804     logger("Login '%s' is already in use from ip %s. IP %s",
805            login.c_str(),
806            inet_ntostring(user->GetCurrIP()).c_str(),
807            inet_ntostring(sip).c_str());
808     SendError(sip, sport, protoVer, IconvString("Логин уже используется.", "utf8", "koi8-ru"));
809     ip2user.erase(it);
810     return 0;
811     }
812
813 switch (pi->second)
814     {
815     case CONN_SYN_N:
816         switch (protoVer)
817             {
818             case 6:
819                 if (Process_CONN_SYN_6(static_cast<CONN_SYN_6 *>(buff), &(it->second), sip))
820                     return -1;
821                 return Send_CONN_SYN_ACK_6(iaUser, sip);
822             case 7:
823                 if (Process_CONN_SYN_7(static_cast<CONN_SYN_7 *>(buff), &(it->second), sip))
824                     return -1;
825                 return Send_CONN_SYN_ACK_7(iaUser, sip);
826             case 8:
827                 if (Process_CONN_SYN_8(static_cast<CONN_SYN_8 *>(buff), &(it->second), sip))
828                     return -1;
829                 return Send_CONN_SYN_ACK_8(iaUser, sip);
830             }
831         break;
832
833     case CONN_ACK_N:
834         switch (protoVer)
835             {
836             case 6:
837                 if (Process_CONN_ACK_6(static_cast<CONN_ACK_6 *>(buff), iaUser, sip))
838                     return -1;
839                 return Send_ALIVE_SYN_6(iaUser, sip);
840             case 7:
841                 if (Process_CONN_ACK_7(static_cast<CONN_ACK_6 *>(buff), iaUser, sip))
842                     return -1;
843                 return Send_ALIVE_SYN_7(iaUser, sip);
844             case 8:
845                 if (Process_CONN_ACK_8(static_cast<CONN_ACK_8 *>(buff), iaUser, sip))
846                     return -1;
847                 return Send_ALIVE_SYN_8(iaUser, sip);
848             }
849         break;
850
851     case ALIVE_ACK_N:
852         switch (protoVer)
853             {
854             case 6:
855                 return Process_ALIVE_ACK_6(static_cast<ALIVE_ACK_6 *>(buff), iaUser, sip);
856             case 7:
857                 return Process_ALIVE_ACK_7(static_cast<ALIVE_ACK_6 *>(buff), iaUser, sip);
858             case 8:
859                 return Process_ALIVE_ACK_8(static_cast<ALIVE_ACK_8 *>(buff), iaUser, sip);
860             }
861         break;
862
863     case DISCONN_SYN_N:
864         switch (protoVer)
865             {
866             case 6:
867                 if (Process_DISCONN_SYN_6(static_cast<DISCONN_SYN_6 *>(buff), iaUser, sip))
868                     return -1;
869                 return Send_DISCONN_SYN_ACK_6(iaUser, sip);
870             case 7:
871                 if (Process_DISCONN_SYN_7(static_cast<DISCONN_SYN_6 *>(buff), iaUser, sip))
872                     return -1;
873                 return Send_DISCONN_SYN_ACK_7(iaUser, sip);
874             case 8:
875                 if (Process_DISCONN_SYN_8(static_cast<DISCONN_SYN_8 *>(buff), iaUser, sip))
876                     return -1;
877                 return Send_DISCONN_SYN_ACK_8(iaUser, sip);
878             }
879         break;
880
881     case DISCONN_ACK_N:
882         switch (protoVer)
883             {
884             case 6:
885                 if (Process_DISCONN_ACK_6(static_cast<DISCONN_ACK_6 *>(buff), iaUser, sip, it))
886                     return -1;
887                 return Send_FIN_6(iaUser, sip, it);
888             case 7:
889                 if (Process_DISCONN_ACK_7(static_cast<DISCONN_ACK_6 *>(buff), iaUser, sip, it))
890                     return -1;
891                 return Send_FIN_7(iaUser, sip, it);
892             case 8:
893                 if (Process_DISCONN_ACK_8(static_cast<DISCONN_ACK_8 *>(buff), iaUser, sip, it))
894                     return -1;
895                 return Send_FIN_8(iaUser, sip, it);
896             }
897         break;
898     }
899
900 return -1;
901 }
902 //-----------------------------------------------------------------------------
903 void AUTH_IA::DelUser(UserPtr u)
904 {
905
906 uint32_t ip = u->GetCurrIP();
907
908 if (!ip)
909     return;
910
911 std::map<uint32_t, IA_USER>::iterator it;
912
913 std::lock_guard lock(m_mutex);
914 it = ip2user.find(ip);
915 if (it == ip2user.end())
916     {
917     //Nothing to delete
918     printfd(__FILE__, "Nothing to delete\n");
919     return;
920     }
921
922 if (it->second.user == u)
923     {
924     printfd(__FILE__, "User removed!\n");
925     users->Unauthorize(u->GetLogin(), this);
926     ip2user.erase(it);
927     }
928 }
929 //-----------------------------------------------------------------------------
930 int AUTH_IA::SendError(uint32_t ip, uint16_t port, int protoVer, const std::string & text)
931 {
932 struct sockaddr_in sendAddr;
933 ssize_t res;
934 switch (protoVer)
935     {
936     case 6:
937     case 7:
938         ERR err;
939         memset(&err, 0, sizeof(ERR));
940
941         sendAddr.sin_family = AF_INET;
942         sendAddr.sin_port = htons(port);
943         sendAddr.sin_addr.s_addr = ip;
944
945         err.len = 1;
946         memcpy(err.type, "ERR", 3);
947         memcpy(err.text, text.c_str(), std::min<size_t>(text.length(), MAX_MSG_LEN));
948
949         #ifdef ARCH_BE
950         SwapBytes(err.len);
951         #endif
952
953         res = sendto(listenSocket, &err, sizeof(err), 0, reinterpret_cast<sockaddr*>(&sendAddr), sizeof(sendAddr));
954         printfd(__FILE__, "SendError %d bytes sent\n", res);
955         break;
956
957     case 8:
958         ERR_8 err8;
959         memset(&err8, 0, sizeof(ERR_8));
960
961         sendAddr.sin_family = AF_INET;
962         sendAddr.sin_port = htons(port);
963         sendAddr.sin_addr.s_addr = ip;
964
965         err8.len = 256;
966         memcpy(err8.type, "ERR", 3);
967         memcpy(err8.text, text.c_str(), std::min<size_t>(text.length(), MAX_MSG_LEN));
968
969         #ifdef ARCH_BE
970         SwapBytes(err8.len);
971         #endif
972
973         res = sendto(listenSocket, &err8, sizeof(err8), 0, reinterpret_cast<sockaddr*>(&sendAddr), sizeof(sendAddr));
974         printfd(__FILE__, "SendError_8 %d bytes sent\n", res);
975         break;
976     }
977
978 return 0;
979 }
980 //-----------------------------------------------------------------------------
981 int AUTH_IA::Send(uint32_t ip, uint16_t port, const void* buffer, size_t len)
982 {
983 struct sockaddr_in sendAddr;
984
985 sendAddr.sin_family = AF_INET;
986 sendAddr.sin_port = htons(port);
987 sendAddr.sin_addr.s_addr = ip;
988
989 if (sendto(listenSocket, buffer, len, 0, reinterpret_cast<sockaddr*>(&sendAddr), sizeof(sendAddr)) == static_cast<ssize_t>(len))
990     return 0;
991
992 return -1;
993 }
994 //-----------------------------------------------------------------------------
995 int AUTH_IA::SendMessage(const STG::Message & msg, uint32_t ip) const
996 {
997 printfd(__FILE__, "SendMessage userIP=%s\n", inet_ntostring(ip).c_str());
998
999 std::map<uint32_t, IA_USER>::iterator it;
1000
1001 std::lock_guard lock(m_mutex);
1002 it = ip2user.find(ip);
1003 if (it == ip2user.end())
1004     {
1005     errorStr = "Unknown user.";
1006     return -1;
1007     }
1008 it->second.messagesToSend.push_back(msg);
1009 return 0;
1010 }
1011 //-----------------------------------------------------------------------------
1012 int AUTH_IA::RealSendMessage6(const STG::Message & msg, uint32_t ip, IA_USER & user)
1013 {
1014 printfd(__FILE__, "RealSendMessage 6 user=%s\n", user.login.c_str());
1015
1016 INFO_6 info;
1017 memset(&info, 0, sizeof(INFO_6));
1018
1019 info.len = 256;
1020 memcpy(info.type, "INFO", 4);
1021 info.infoType = 'I';
1022 memcpy(info.text, msg.text.c_str(), std::min<size_t>(msg.text.length(), 235));
1023 info.text[234] = 0;
1024
1025 size_t len = info.len;
1026 #ifdef ARCH_BE
1027 SwapBytes(info.len);
1028 #endif
1029
1030 char buffer[256];
1031 memcpy(buffer, &info, sizeof(INFO_6));
1032 EncryptString(buffer, buffer, len, &user.ctx);
1033 return Send(ip, iaSettings.GetUserPort(), buffer, len);
1034 }
1035 //-----------------------------------------------------------------------------
1036 int AUTH_IA::RealSendMessage7(const STG::Message & msg, uint32_t ip, IA_USER & user)
1037 {
1038 printfd(__FILE__, "RealSendMessage 7 user=%s\n", user.login.c_str());
1039
1040 INFO_7 info;
1041 memset(&info, 0, sizeof(INFO_7));
1042
1043 info.len = 264;
1044 memcpy(info.type, "INFO_7", 6);
1045 info.infoType = static_cast<int8_t>(msg.header.type);
1046 info.showTime = static_cast<int8_t>(msg.header.showTime);
1047 info.sendTime = msg.header.creationTime;
1048
1049 size_t len = info.len;
1050 #ifdef ARCH_BE
1051 SwapBytes(info.len);
1052 SwapBytes(info.sendTime);
1053 #endif
1054
1055 memcpy(info.text, msg.text.c_str(), std::min<size_t>(msg.text.length(), MAX_MSG_LEN - 1));
1056 info.text[MAX_MSG_LEN - 1] = 0;
1057
1058 char buffer[300];
1059 memcpy(buffer, &info, sizeof(INFO_7));
1060
1061 EncryptString(buffer, buffer, len, &user.ctx);
1062 return Send(ip, iaSettings.GetUserPort(), buffer, len);
1063 }
1064 //-----------------------------------------------------------------------------
1065 int AUTH_IA::RealSendMessage8(const STG::Message & msg, uint32_t ip, IA_USER & user)
1066 {
1067 printfd(__FILE__, "RealSendMessage 8 user=%s\n", user.login.c_str());
1068
1069 INFO_8 info;
1070 memset(&info, 0, sizeof(INFO_8));
1071
1072 info.len = 1056;
1073 memcpy(info.type, "INFO_8", 6);
1074 info.infoType = static_cast<int8_t>(msg.header.type);
1075 info.showTime = static_cast<int8_t>(msg.header.showTime);
1076 info.sendTime = msg.header.creationTime;
1077
1078 memcpy(info.text, msg.text.c_str(), std::min<size_t>(msg.text.length(), IA_MAX_MSG_LEN_8 - 1));
1079 info.text[IA_MAX_MSG_LEN_8 - 1] = 0;
1080
1081 size_t len = info.len;
1082 #ifdef ARCH_BE
1083 SwapBytes(info.len);
1084 SwapBytes(info.sendTime);
1085 #endif
1086
1087 char buffer[1500];
1088 memcpy(buffer, &info, sizeof(INFO_8));
1089
1090 EncryptString(buffer, buffer, len, &user.ctx);
1091 return Send(ip, user.port, buffer, len);
1092 }
1093 //-----------------------------------------------------------------------------
1094 int AUTH_IA::Process_CONN_SYN_6(CONN_SYN_6 *, IA_USER * iaUser, uint32_t)
1095 {
1096 if (!(iaUser->phase.GetPhase() == 1 || iaUser->phase.GetPhase() == 3))
1097     return -1;
1098
1099 enabledDirs = 0xFFffFFff;
1100
1101 iaUser->phase.SetPhase2();
1102 printfd(__FILE__, "Phase changed from %d to 2. Reason: CONN_SYN_6\n", iaUser->phase.GetPhase());
1103 return 0;
1104 }
1105 //-----------------------------------------------------------------------------
1106 int AUTH_IA::Process_CONN_SYN_7(CONN_SYN_7 * connSyn, IA_USER * iaUser, uint32_t sip)
1107 {
1108 return Process_CONN_SYN_6(connSyn, iaUser, sip);
1109 }
1110 //-----------------------------------------------------------------------------
1111 int AUTH_IA::Process_CONN_SYN_8(CONN_SYN_8 * connSyn, IA_USER * iaUser, uint32_t sip)
1112 {
1113 #ifdef ARCH_BE
1114 SwapBytes(connSyn->dirs);
1115 #endif
1116 int ret = Process_CONN_SYN_6(reinterpret_cast<CONN_SYN_6 *>(connSyn), iaUser, sip);
1117 enabledDirs = connSyn->dirs;
1118 return ret;
1119 }
1120 //-----------------------------------------------------------------------------
1121 int AUTH_IA::Process_CONN_ACK_6(CONN_ACK_6 * connAck, IA_USER * iaUser, uint32_t sip)
1122 {
1123 #ifdef ARCH_BE
1124 SwapBytes(connAck->len);
1125 SwapBytes(connAck->rnd);
1126 #endif
1127 printfd( __FILE__, "CONN_ACK_6 %s\n", connAck->type);
1128
1129 if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
1130     {
1131     iaUser->phase.UpdateTime();
1132
1133     iaUser->lastSendAlive = iaUser->phase.GetTime();
1134     if (users->Authorize(iaUser->login, sip, enabledDirs, this))
1135         {
1136         iaUser->phase.SetPhase3();
1137         printfd(__FILE__, "Phase changed from 2 to 3. Reason: CONN_ACK_6\n");
1138         return 0;
1139         }
1140     else
1141         {
1142         errorStr = iaUser->user->GetStrError();
1143         if (iaSettings.LogProtocolErrors())
1144             logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: phase 2, authorization error ('%s').", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, errorStr.c_str());
1145         iaUser->phase.SetPhase1();
1146         ip2user.erase(sip);
1147         printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
1148         return -1;
1149         }
1150     }
1151 printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d, expected: %d\n", iaUser->phase.GetPhase(), connAck->rnd, iaUser->rnd + 1);
1152 if (iaSettings.LogProtocolErrors())
1153     {
1154     if (iaUser->phase.GetPhase() != 2)
1155         logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid phase, expected 2, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1156     if (connAck->rnd != iaUser->rnd + 1)
1157         logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), connAck->rnd);
1158     }
1159 return -1;
1160 }
1161 //-----------------------------------------------------------------------------
1162 int AUTH_IA::Process_CONN_ACK_7(CONN_ACK_7 * connAck, IA_USER * iaUser, uint32_t sip)
1163 {
1164 return Process_CONN_ACK_6(connAck, iaUser, sip);
1165 }
1166 //-----------------------------------------------------------------------------
1167 int AUTH_IA::Process_CONN_ACK_8(CONN_ACK_8 * connAck, IA_USER * iaUser, uint32_t sip)
1168 {
1169 #ifdef ARCH_BE
1170 SwapBytes(connAck->len);
1171 SwapBytes(connAck->rnd);
1172 #endif
1173 printfd( __FILE__, "CONN_ACK_8 %s\n", connAck->type);
1174
1175 if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
1176     {
1177     iaUser->phase.UpdateTime();
1178     iaUser->lastSendAlive = iaUser->phase.GetTime();
1179     if (users->Authorize(iaUser->login, sip, enabledDirs, this))
1180         {
1181         iaUser->phase.SetPhase3();
1182         printfd(__FILE__, "Phase changed from 2 to 3. Reason: CONN_ACK_8\n");
1183         return 0;
1184         }
1185     else
1186         {
1187         errorStr = iaUser->user->GetStrError();
1188         if (iaSettings.LogProtocolErrors())
1189             logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: phase 2, authorization error ('%s').", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, errorStr.c_str());
1190         iaUser->phase.SetPhase1();
1191         ip2user.erase(sip);
1192         printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
1193         return -1;
1194         }
1195     }
1196 printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d, expected: %d\n", iaUser->phase.GetPhase(), connAck->rnd, iaUser->rnd + 1);
1197 if (iaSettings.LogProtocolErrors())
1198     {
1199     if (iaUser->phase.GetPhase() != 2)
1200         logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid phase, expected 2, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1201     if (connAck->rnd != iaUser->rnd + 1)
1202         logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), connAck->rnd);
1203     }
1204 return -1;
1205 }
1206 //-----------------------------------------------------------------------------
1207 int AUTH_IA::Process_ALIVE_ACK_6(ALIVE_ACK_6 * aliveAck, IA_USER * iaUser, uint32_t)
1208 {
1209 #ifdef ARCH_BE
1210 SwapBytes(aliveAck->len);
1211 SwapBytes(aliveAck->rnd);
1212 #endif
1213 printfd(__FILE__, "ALIVE_ACK_6\n");
1214 if ((iaUser->phase.GetPhase() == 3) && (aliveAck->rnd == iaUser->rnd + 1))
1215     {
1216     iaUser->phase.UpdateTime();
1217     #ifdef IA_DEBUG
1218     iaUser->aliveSent = false;
1219     #endif
1220     }
1221 return 0;
1222 }
1223 //-----------------------------------------------------------------------------
1224 int AUTH_IA::Process_ALIVE_ACK_7(ALIVE_ACK_7 * aliveAck, IA_USER * iaUser, uint32_t sip)
1225 {
1226 return Process_ALIVE_ACK_6(aliveAck, iaUser, sip);
1227 }
1228 //-----------------------------------------------------------------------------
1229 int AUTH_IA::Process_ALIVE_ACK_8(ALIVE_ACK_8 * aliveAck, IA_USER * iaUser, uint32_t)
1230 {
1231 #ifdef ARCH_BE
1232 SwapBytes(aliveAck->len);
1233 SwapBytes(aliveAck->rnd);
1234 #endif
1235 printfd(__FILE__, "ALIVE_ACK_8\n");
1236 if ((iaUser->phase.GetPhase() == 3) && (aliveAck->rnd == iaUser->rnd + 1))
1237     {
1238     iaUser->phase.UpdateTime();
1239     #ifdef IA_DEBUG
1240     iaUser->aliveSent = false;
1241     #endif
1242     }
1243 return 0;
1244 }
1245 //-----------------------------------------------------------------------------
1246 int AUTH_IA::Process_DISCONN_SYN_6(DISCONN_SYN_6 *, IA_USER * iaUser, uint32_t sip)
1247 {
1248 printfd(__FILE__, "DISCONN_SYN_6\n");
1249 if (iaUser->phase.GetPhase() != 3)
1250     {
1251     if (iaSettings.LogProtocolErrors())
1252         logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_SYN: invalid phase, expected 3, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1253     printfd(__FILE__, "Invalid phase. Expected 3, actual %d\n", iaUser->phase.GetPhase());
1254     errorStr = "Incorrect request DISCONN_SYN";
1255     return -1;
1256     }
1257
1258 iaUser->phase.SetPhase4();
1259 printfd(__FILE__, "Phase changed from 3 to 4. Reason: DISCONN_SYN_6\n");
1260
1261 return 0;
1262 }
1263 //-----------------------------------------------------------------------------
1264 int AUTH_IA::Process_DISCONN_SYN_7(DISCONN_SYN_7 * disconnSyn, IA_USER * iaUser, uint32_t sip)
1265 {
1266 return Process_DISCONN_SYN_6(disconnSyn, iaUser, sip);
1267 }
1268 //-----------------------------------------------------------------------------
1269 int AUTH_IA::Process_DISCONN_SYN_8(DISCONN_SYN_8 *, IA_USER * iaUser, uint32_t sip)
1270 {
1271 if (iaUser->phase.GetPhase() != 3)
1272     {
1273     if (iaSettings.LogProtocolErrors())
1274         logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_SYN: invalid phase, expected 3, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1275     errorStr = "Incorrect request DISCONN_SYN";
1276     printfd(__FILE__, "Invalid phase. Expected 3, actual %d\n", iaUser->phase.GetPhase());
1277     return -1;
1278     }
1279
1280 iaUser->phase.SetPhase4();
1281 printfd(__FILE__, "Phase changed from 3 to 4. Reason: DISCONN_SYN_6\n");
1282
1283 return 0;
1284 }
1285 //-----------------------------------------------------------------------------
1286 int AUTH_IA::Process_DISCONN_ACK_6(DISCONN_ACK_6 * disconnAck,
1287                                    IA_USER * iaUser,
1288                                    uint32_t sip,
1289                                    std::map<uint32_t, IA_USER>::iterator)
1290 {
1291 #ifdef ARCH_BE
1292 SwapBytes(disconnAck->len);
1293 SwapBytes(disconnAck->rnd);
1294 #endif
1295 printfd(__FILE__, "DISCONN_ACK_6\n");
1296 if (!((iaUser->phase.GetPhase() == 4) && (disconnAck->rnd == iaUser->rnd + 1)))
1297     {
1298     if (iaSettings.LogProtocolErrors())
1299         {
1300         if (iaUser->phase.GetPhase() != 4)
1301             logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid phase, expected 4, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1302         if (disconnAck->rnd != iaUser->rnd + 1)
1303             logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), disconnAck->rnd);
1304         }
1305     printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), disconnAck->rnd);
1306     return -1;
1307     }
1308
1309 return 0;
1310 }
1311 //-----------------------------------------------------------------------------
1312 int AUTH_IA::Process_DISCONN_ACK_7(DISCONN_ACK_7 * disconnAck, IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator it)
1313 {
1314 return Process_DISCONN_ACK_6(disconnAck, iaUser, sip, it);
1315 }
1316 //-----------------------------------------------------------------------------
1317 int AUTH_IA::Process_DISCONN_ACK_8(DISCONN_ACK_8 * disconnAck, IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator)
1318 {
1319 #ifdef ARCH_BE
1320 SwapBytes(disconnAck->len);
1321 SwapBytes(disconnAck->rnd);
1322 #endif
1323 printfd(__FILE__, "DISCONN_ACK_8\n");
1324 if (!((iaUser->phase.GetPhase() == 4) && (disconnAck->rnd == iaUser->rnd + 1)))
1325     {
1326     if (iaSettings.LogProtocolErrors())
1327         {
1328         if (iaUser->phase.GetPhase() != 4)
1329             logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid phase, expected 4, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
1330         if (disconnAck->rnd != iaUser->rnd + 1)
1331             logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), disconnAck->rnd);
1332         }
1333     printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), disconnAck->rnd);
1334     return -1;
1335     }
1336
1337 return 0;
1338 }
1339 //-----------------------------------------------------------------------------
1340 int AUTH_IA::Send_CONN_SYN_ACK_6(IA_USER * iaUser, uint32_t sip)
1341 {
1342 //+++ Fill static data in connSynAck +++
1343 // TODO Move this code. It must be executed only once
1344 connSynAck6.len = Min8(sizeof(CONN_SYN_ACK_6));
1345 memcpy(connSynAck6.type, "CONN_SYN_ACK", 12);
1346 for (int j = 0; j < DIR_NUM; j++)
1347     {
1348     memcpy(connSynAck6.dirName[j],
1349            stgSettings->GetDirName(j).c_str(),
1350            std::min(stgSettings->GetDirName(j).length(), sizeof(string16)));
1351
1352     connSynAck6.dirName[j][sizeof(string16) - 1] = 0;
1353     }
1354 //--- Fill static data in connSynAck ---
1355
1356 iaUser->rnd = static_cast<uint32_t>(random());
1357 connSynAck6.rnd = iaUser->rnd;
1358
1359 printfd(__FILE__, "Sending CONN_SYN_ACK with control number %d.\n", iaUser->rnd);
1360
1361 connSynAck6.userTimeOut = iaSettings.GetUserTimeout().GetSec();
1362 connSynAck6.aliveDelay = iaSettings.GetUserDelay().GetSec();
1363
1364 #ifdef ARCH_BE
1365 SwapBytes(connSynAck6.len);
1366 SwapBytes(connSynAck6.rnd);
1367 SwapBytes(connSynAck6.userTimeOut);
1368 SwapBytes(connSynAck6.aliveDelay);
1369 #endif
1370
1371 EncryptString(&connSynAck6, &connSynAck6, Min8(sizeof(CONN_SYN_ACK_6)), &iaUser->ctx);
1372 return Send(sip, iaSettings.GetUserPort(), &connSynAck6, Min8(sizeof(CONN_SYN_ACK_6)));;
1373 }
1374 //-----------------------------------------------------------------------------
1375 int AUTH_IA::Send_CONN_SYN_ACK_7(IA_USER * iaUser, uint32_t sip)
1376 {
1377 return Send_CONN_SYN_ACK_6(iaUser, sip);
1378 }
1379 //-----------------------------------------------------------------------------
1380 int AUTH_IA::Send_CONN_SYN_ACK_8(IA_USER * iaUser, uint32_t sip)
1381 {
1382 memcpy(connSynAck8.hdr.magic, IA_ID, strlen(IA_ID));
1383 connSynAck8.hdr.protoVer[0] = 0;
1384 connSynAck8.hdr.protoVer[1] = 8;
1385
1386 //+++ Fill static data in connSynAck +++
1387 // TODO Move this code. It must be executed only once
1388 connSynAck8.len = Min8(sizeof(CONN_SYN_ACK_8));
1389 memcpy(connSynAck8.type, "CONN_SYN_ACK", 12);
1390 for (int j = 0; j < DIR_NUM; j++)
1391     {
1392     memcpy(connSynAck8.dirName[j],
1393            stgSettings->GetDirName(j).c_str(),
1394            std::min(stgSettings->GetDirName(j).length(), sizeof(string16)));
1395
1396     connSynAck8.dirName[j][sizeof(string16) - 1] = 0;
1397     }
1398 //--- Fill static data in connSynAck ---
1399
1400 iaUser->rnd = static_cast<uint32_t>(random());
1401 connSynAck8.rnd = iaUser->rnd;
1402
1403 printfd(__FILE__, "Sending CONN_SYN_ACK with control number %d.\n", iaUser->rnd);
1404
1405 connSynAck8.userTimeOut = iaSettings.GetUserTimeout().GetSec();
1406 connSynAck8.aliveDelay = iaSettings.GetUserDelay().GetSec();
1407
1408 #ifdef ARCH_BE
1409 SwapBytes(connSynAck8.len);
1410 SwapBytes(connSynAck8.rnd);
1411 SwapBytes(connSynAck8.userTimeOut);
1412 SwapBytes(connSynAck8.aliveDelay);
1413 #endif
1414
1415 EncryptString(&connSynAck8, &connSynAck8, Min8(sizeof(CONN_SYN_ACK_8)), &iaUser->ctx);
1416 return Send(sip, iaUser->port, &connSynAck8, Min8(sizeof(CONN_SYN_ACK_8)));
1417 }
1418 //-----------------------------------------------------------------------------
1419 int AUTH_IA::Send_ALIVE_SYN_6(IA_USER * iaUser, uint32_t sip)
1420 {
1421 aliveSyn6.len = Min8(sizeof(ALIVE_SYN_6));
1422 aliveSyn6.rnd = iaUser->rnd = static_cast<uint32_t>(random());
1423
1424 memcpy(aliveSyn6.type, "ALIVE_SYN", 9);
1425
1426 for (int i = 0; i < DIR_NUM; i++)
1427     {
1428     aliveSyn6.md[i] = iaUser->user->GetProperties().down.Get()[i];
1429     aliveSyn6.mu[i] = iaUser->user->GetProperties().up.Get()[i];
1430
1431     aliveSyn6.sd[i] = iaUser->user->GetSessionDownload()[i];
1432     aliveSyn6.su[i] = iaUser->user->GetSessionUpload()[i];
1433     }
1434
1435 //TODO
1436 int dn = iaSettings.GetFreeMbShowType();
1437 const auto tf = iaUser->user->GetTariff();
1438
1439 if (dn < DIR_NUM)
1440     {
1441     double p = tf->GetPriceWithTraffType(aliveSyn6.mu[dn],
1442                                          aliveSyn6.md[dn],
1443                                          dn,
1444                                          stgTime);
1445     p *= 1024 * 1024;
1446     if (std::fabs(p) < 1.0e-3)
1447         {
1448         memcpy(aliveSyn6.freeMb, "---", 3);
1449         }
1450     else
1451         {
1452         double fmb = iaUser->user->GetProperties().freeMb;
1453         fmb = fmb < 0 ? 0 : fmb;
1454         snprintf(reinterpret_cast<char*>(aliveSyn6.freeMb), IA_FREEMB_LEN, "%.3f", fmb / p);
1455         }
1456     }
1457 else
1458     {
1459     if (freeMbNone == iaSettings.GetFreeMbShowType())
1460         {
1461         aliveSyn6.freeMb[0] = 0;
1462         }
1463     else
1464         {
1465         double fmb = iaUser->user->GetProperties().freeMb;
1466         fmb = fmb < 0 ? 0 : fmb;
1467         snprintf(reinterpret_cast<char*>(aliveSyn6.freeMb), IA_FREEMB_LEN, "C%.3f", fmb);
1468         }
1469     }
1470
1471 #ifdef IA_DEBUG
1472 if (iaUser->aliveSent)
1473     {
1474     printfd(__FILE__, "========= ALIVE_ACK_6(7) TIMEOUT !!! %s =========\n", iaUser->login.c_str());
1475     }
1476 iaUser->aliveSent = true;
1477 #endif
1478
1479 aliveSyn6.cash = static_cast<int64_t>(iaUser->user->GetProperties().cash.Get() * 1000.0);
1480 if (!stgSettings->GetShowFeeInCash())
1481     aliveSyn6.cash -= static_cast<int64_t>((tf->GetFee() * 1000.0));
1482
1483 #ifdef ARCH_BE
1484 SwapBytes(aliveSyn6.len);
1485 SwapBytes(aliveSyn6.rnd);
1486 SwapBytes(aliveSyn6.cash);
1487 for (int i = 0; i < DIR_NUM; ++i)
1488     {
1489     SwapBytes(aliveSyn6.mu[i]);
1490     SwapBytes(aliveSyn6.md[i]);
1491     SwapBytes(aliveSyn6.su[i]);
1492     SwapBytes(aliveSyn6.sd[i]);
1493     }
1494 #endif
1495
1496 EncryptString(&aliveSyn6, &aliveSyn6, Min8(sizeof(aliveSyn6)), &iaUser->ctx);
1497 return Send(sip, iaSettings.GetUserPort(), &aliveSyn6, Min8(sizeof(aliveSyn6)));
1498 }
1499 //-----------------------------------------------------------------------------
1500 int AUTH_IA::Send_ALIVE_SYN_7(IA_USER * iaUser, uint32_t sip)
1501 {
1502 return Send_ALIVE_SYN_6(iaUser, sip);
1503 }
1504 //-----------------------------------------------------------------------------
1505 int AUTH_IA::Send_ALIVE_SYN_8(IA_USER * iaUser, uint32_t sip)
1506 {
1507 memcpy(aliveSyn8.hdr.magic, IA_ID, strlen(IA_ID));
1508 aliveSyn8.hdr.protoVer[0] = 0;
1509 aliveSyn8.hdr.protoVer[1] = 8;
1510
1511 aliveSyn8.len = Min8(sizeof(ALIVE_SYN_8));
1512 aliveSyn8.rnd = iaUser->rnd = static_cast<uint32_t>(random());
1513
1514 memcpy(aliveSyn8.type, "ALIVE_SYN", 9);
1515
1516 for (int i = 0; i < DIR_NUM; i++)
1517     {
1518     aliveSyn8.md[i] = iaUser->user->GetProperties().down.Get()[i];
1519     aliveSyn8.mu[i] = iaUser->user->GetProperties().up.Get()[i];
1520
1521     aliveSyn8.sd[i] = iaUser->user->GetSessionDownload()[i];
1522     aliveSyn8.su[i] = iaUser->user->GetSessionUpload()[i];
1523     }
1524
1525 //TODO
1526 int dn = iaSettings.GetFreeMbShowType();
1527
1528 if (dn < DIR_NUM)
1529     {
1530     const auto tf = iaUser->user->GetTariff();
1531     double p = tf->GetPriceWithTraffType(aliveSyn8.mu[dn],
1532                                          aliveSyn8.md[dn],
1533                                          dn,
1534                                          stgTime);
1535     p *= 1024 * 1024;
1536     if (std::fabs(p) < 1.0e-3)
1537         {
1538         memcpy(aliveSyn8.freeMb, "---", 3);
1539         }
1540     else
1541         {
1542         double fmb = iaUser->user->GetProperties().freeMb;
1543         fmb = fmb < 0 ? 0 : fmb;
1544         snprintf(reinterpret_cast<char*>(aliveSyn8.freeMb), IA_FREEMB_LEN, "%.3f", fmb / p);
1545         }
1546     }
1547 else
1548     {
1549     if (freeMbNone == iaSettings.GetFreeMbShowType())
1550         {
1551         aliveSyn8.freeMb[0] = 0;
1552         }
1553     else
1554         {
1555         double fmb = iaUser->user->GetProperties().freeMb;
1556         fmb = fmb < 0 ? 0 : fmb;
1557         snprintf(reinterpret_cast<char*>(aliveSyn8.freeMb), IA_FREEMB_LEN, "C%.3f", fmb);
1558         }
1559     }
1560
1561 #ifdef IA_DEBUG
1562 if (iaUser->aliveSent)
1563     {
1564     printfd(__FILE__, "========= ALIVE_ACK_8 TIMEOUT !!! =========\n");
1565     }
1566 iaUser->aliveSent = true;
1567 #endif
1568
1569 const auto tf = iaUser->user->GetTariff();
1570
1571 aliveSyn8.cash = static_cast<int64_t>(iaUser->user->GetProperties().cash.Get() * 1000.0);
1572 if (!stgSettings->GetShowFeeInCash())
1573     aliveSyn8.cash -= static_cast<int64_t>(tf->GetFee() * 1000.0);
1574
1575 #ifdef ARCH_BE
1576 SwapBytes(aliveSyn8.len);
1577 SwapBytes(aliveSyn8.rnd);
1578 SwapBytes(aliveSyn8.cash);
1579 SwapBytes(aliveSyn8.status);
1580 for (int i = 0; i < DIR_NUM; ++i)
1581     {
1582     SwapBytes(aliveSyn8.mu[i]);
1583     SwapBytes(aliveSyn8.md[i]);
1584     SwapBytes(aliveSyn8.su[i]);
1585     SwapBytes(aliveSyn8.sd[i]);
1586     }
1587 #endif
1588
1589 EncryptString(&aliveSyn8, &aliveSyn8, Min8(sizeof(aliveSyn8)), &iaUser->ctx);
1590 return Send(sip, iaUser->port, &aliveSyn8, Min8(sizeof(aliveSyn8)));
1591 }
1592 //-----------------------------------------------------------------------------
1593 int AUTH_IA::Send_DISCONN_SYN_ACK_6(IA_USER * iaUser, uint32_t sip)
1594 {
1595 disconnSynAck6.len = Min8(sizeof(DISCONN_SYN_ACK_6));
1596 memcpy(disconnSynAck6.type, "DISCONN_SYN_ACK", 15);
1597 disconnSynAck6.rnd = iaUser->rnd = static_cast<uint32_t>(random());
1598
1599 #ifdef ARCH_BE
1600 SwapBytes(disconnSynAck6.len);
1601 SwapBytes(disconnSynAck6.rnd);
1602 #endif
1603
1604 EncryptString(&disconnSynAck6, &disconnSynAck6, Min8(sizeof(disconnSynAck6)), &iaUser->ctx);
1605 return Send(sip, iaSettings.GetUserPort(), &disconnSynAck6, Min8(sizeof(disconnSynAck6)));
1606 }
1607 //-----------------------------------------------------------------------------
1608 int AUTH_IA::Send_DISCONN_SYN_ACK_7(IA_USER * iaUser, uint32_t sip)
1609 {
1610 return Send_DISCONN_SYN_ACK_6(iaUser, sip);
1611 }
1612 //-----------------------------------------------------------------------------
1613 int AUTH_IA::Send_DISCONN_SYN_ACK_8(IA_USER * iaUser, uint32_t sip)
1614 {
1615 memcpy(disconnSynAck8.hdr.magic, IA_ID, strlen(IA_ID));
1616 disconnSynAck8.hdr.protoVer[0] = 0;
1617 disconnSynAck8.hdr.protoVer[1] = 8;
1618
1619 disconnSynAck8.len = Min8(sizeof(DISCONN_SYN_ACK_8));
1620 memcpy(disconnSynAck8.type, "DISCONN_SYN_ACK", 15);
1621 disconnSynAck8.rnd = iaUser->rnd = static_cast<uint32_t>(random());
1622
1623 #ifdef ARCH_BE
1624 SwapBytes(disconnSynAck8.len);
1625 SwapBytes(disconnSynAck8.rnd);
1626 #endif
1627
1628 EncryptString(&disconnSynAck8, &disconnSynAck8, Min8(sizeof(disconnSynAck8)), &iaUser->ctx);
1629 return Send(sip, iaUser->port, &disconnSynAck8, Min8(sizeof(disconnSynAck8)));
1630 }
1631 //-----------------------------------------------------------------------------
1632 int AUTH_IA::Send_FIN_6(IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator it)
1633 {
1634 fin6.len = Min8(sizeof(FIN_6));
1635 memcpy(fin6.type, "FIN", 3);
1636 memcpy(fin6.ok, "OK", 2);
1637
1638 #ifdef ARCH_BE
1639 SwapBytes(fin6.len);
1640 #endif
1641
1642 EncryptString(&fin6, &fin6, Min8(sizeof(fin6)), &iaUser->ctx);
1643
1644 users->Unauthorize(iaUser->login, this);
1645
1646 int res = Send(sip, iaSettings.GetUserPort(), &fin6, Min8(sizeof(fin6)));
1647
1648 ip2user.erase(it);
1649
1650 return res;
1651 }
1652 //-----------------------------------------------------------------------------
1653 int AUTH_IA::Send_FIN_7(IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator it)
1654 {
1655 return Send_FIN_6(iaUser, sip, it);
1656 }
1657 //-----------------------------------------------------------------------------
1658 int AUTH_IA::Send_FIN_8(IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator it)
1659 {
1660 memcpy(fin8.hdr.magic, IA_ID, strlen(IA_ID));
1661 fin8.hdr.protoVer[0] = 0;
1662 fin8.hdr.protoVer[1] = 8;
1663
1664 fin8.len = Min8(sizeof(FIN_8));
1665 memcpy(fin8.type, "FIN", 3);
1666 memcpy(fin8.ok, "OK", 2);
1667
1668 #ifdef ARCH_BE
1669 SwapBytes(fin8.len);
1670 #endif
1671
1672 EncryptString(&fin8, &fin8, Min8(sizeof(fin8)), &iaUser->ctx);
1673
1674 users->Unauthorize(iaUser->login, this);
1675
1676 int res = Send(sip, iaUser->port, &fin8, Min8(sizeof(fin8)));
1677
1678 ip2user.erase(it);
1679
1680 return res;
1681 }