1 /*******************************************************************************
2 * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * - Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * - Neither the name of Intel Corp. nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 #if defined(__sun) || defined(_LINUX)
35 #include <cerrno>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
38 #include <netinet/in.h>
39 #include <net/if.h>
40 #include <sys/ioctl.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <netdb.h>
44 #include <syslog.h>
45
46 #define _stprintf_s snprintf
47 #define strnicmp strncasecmp
48 #else
49
50 #include <winsock2.h>
51 #include <iphlpapi.h>
52 #include <Ws2tcpip.h>
53 #include <tchar.h>
54
55 #endif // __sun || _LINUX
56
57 #include <fstream>
58 #include <algorithm>
59 #include "Protocol.h"
60 #include "LMS_if.h"
61 #include "LMS_if_compat.h"
62 #include "Lock.h"
63 #include "ATNetworkTool.h"
64
65 const LMEProtocolVersionMessage Protocol::MIN_PROT_VERSION(1, 0);
66 const LMEProtocolVersionMessage Protocol::MAX_PROT_VERSION(1, 0);
67
Protocol()68 Protocol::Protocol() :
69 #if DEBUGLOG
70 _lme(true),
71 #else
72 _lme(false),
73 #endif
74 _rxSocketBuffer(NULL),
75 _rxSocketBufferSize(0)
76 #ifdef _REMOTE_SUPPORT
77 , _cfg(true)
78 #endif
79 {
80 _serverSignalSocket = INVALID_SOCKET;
81 _clientSignalSocket = INVALID_SOCKET;
82 _sockets_active = false;
83 _handshakingStatus = NOT_INITIATED;
84 _pfwdService = NOT_STARTED;
85 _AmtProtVersion.MajorVersion = 0;
86 _AmtProtVersion.MinorVersion = 0;
87 #ifdef _REMOTE_SUPPORT
88 _remoteAccessEnabled = false;
89 #endif
90 memset(_AMTFQDN, 0, sizeof(_AMTFQDN));
91 oldProtocolMode = false;
92 _deinitReq = false;
93 _listenFailReported.clear();
94 }
95
~Protocol()96 Protocol::~Protocol()
97 {
98 if (!oldProtocolMode) {
99 _lme.Disconnect(APF_DISCONNECT_BY_APPLICATION);
100 }
101 DeinitFull();
102 DestroySockets();
103 _listenFailReported.clear();
104 }
105
Init(EventLogCallback cb,void * param)106 bool Protocol::Init(EventLogCallback cb, void *param)
107 {
108 _eventLog = cb;
109 _eventLogParam = param;
110
111 DeinitFull();
112
113 {
114 Lock dl(_deinitLock);
115 _deinitReq = false;
116 }
117
118 if (!_lme.Init(_LmeCallback, this)) {
119 return false;
120 }
121
122 oldProtocolMode = (LMS_PROCOL_VERSION != _lme.protocolVer);
123
124 {
125 Lock l(_versionLock);
126
127 if (_handshakingStatus == NOT_INITIATED) {
128 if (oldProtocolMode) {
129 _lme.CompatProtocolVersion();
130 } else {
131 _lme.ProtocolVersion(MAX_PROT_VERSION);
132 }
133 _handshakingStatus = INITIATED;
134 }
135 }
136
137 if (!oldProtocolMode) {
138 #ifdef _REMOTE_SUPPORT
139 if (!_cfg.Init(true)) {
140 #else
141 if (!_cfg.IsAMTEnabled(false)) {
142 #endif
143 _lme.Deinit();
144 return false;
145 }
146 }
147
148 long bufSize = _lme.GetHeciBufferSize() - sizeof(APF_CHANNEL_DATA_MESSAGE);
149 if (bufSize > 0) {
150 _rxSocketBuffer = new char[bufSize];
151 _rxSocketBufferSize = bufSize;
152 } else {
153 DeinitFull();
154 return false;
155 }
156
157 #ifdef _REMOTE_SUPPORT
158 if (!oldProtocolMode) {
159 _checkRemoteSupport(true);
160 }
161 #endif
162 return true;
163 }
164
165 Channel *Protocol::_getSockOpenChannel(SOCKET s)
166 {
167 if (oldProtocolMode) {
168 ChannelMap::iterator it = _openChannels.begin();
169 for (; it != _openChannels.end(); it++) {
170 if (it->second->GetSocket() == s) {
171 return it->second;
172 }
173 }
174 } else {
175 ChannelMap::iterator it = _openChannels.find(s);
176 if (it != _openChannels.end()) {
177 return it->second;
178 }
179 }
180 return NULL;
181 }
182
183 bool Protocol::IsDeInitialized()
184 {
185 Lock dl(_deinitLock);
186 return _deinitReq;
187 }
188
189
190 bool Protocol::IsInitialized()
191 {
192 if (IsDeInitialized()) {
193 return false;
194 }
195
196 return _lme.IsInitialized();
197 }
198
199 void Protocol::Deinit()
200 {
201 Lock dl(_deinitLock);
202 _deinitReq = true;
203
204 ATNetworkTool::CloseSocket(_serverSignalSocket);
205 ATNetworkTool::CloseSocket(_clientSignalSocket);
206
207 {
208 Lock l(_channelsLock);
209
210 ChannelMap::iterator it = _openChannels.begin();
211
212 for (; it != _openChannels.end(); it++) {
213 ATNetworkTool::CloseSocket(it->second->GetSocket());
214 delete it->second;
215 }
216
217 _openChannels.clear();
218 }
219
220 {
221 Lock l(_portsLock);
222 PortMap::iterator it = _openPorts.begin();
223
224 for (; it != _openPorts.end(); it++) {
225 if (it->second.size() > 0) {
226 ATNetworkTool::CloseSocket(it->second[0]->GetListeningSocket());
227
228 PortForwardRequestList::iterator it2 = it->second.begin();
229 for (; it2 != it->second.end(); it2++) {
230 delete *it2;
231 }
232 }
233 }
234 _openPorts.clear();
235 }
236
237 _lme.Deinit();
238
239 #ifdef _REMOTE_SUPPORT
240 if (!oldProtocolMode) {
241 _cfg.Deinit();
242 }
243 #endif
244
245 {
246 Lock vl(_versionLock);
247 _handshakingStatus = NOT_INITIATED;
248 _pfwdService = NOT_STARTED;
249 _AmtProtVersion.MajorVersion = 0;
250 _AmtProtVersion.MinorVersion = 0;
251 }
252
253 }
254
255 void Protocol::DeinitFull()
256 {
257 Deinit();
258
259 if (_rxSocketBuffer != NULL) {
260 delete []_rxSocketBuffer;
261 _rxSocketBuffer = NULL;
262 _rxSocketBufferSize = 0;
263 }
264
265 _serverSignalSocket = INVALID_SOCKET;
266 _clientSignalSocket = INVALID_SOCKET;
267 _sockets_active = false;
268
269 #ifdef _REMOTE_SUPPORT
270 _remoteAccessEnabled = false;
271 #endif
272 memset(_AMTFQDN, 0, sizeof(_AMTFQDN));
273 }
274
275 bool Protocol::_checkListen(std::string address, in_port_t port, int &socket)
276 {
277 bool exists = false;
278
279 PortMap::iterator it = _openPorts.find(port);
280 if (it != _openPorts.end()) {
281 if (it->second.size() > 0) {
282 socket = it->second[0]->GetListeningSocket();
283 PortForwardRequestList::iterator it2 = it->second.begin();
284
285 for (; it2 != it->second.end(); it2++) {
286 if (((*it2)->GetStatus() != PortForwardRequest::NOT_ACTIVE) &&
287 ((*it2)->GetBindedAddress().compare(address) == 0)) {
288 exists = true;
289 break;
290 }
291 }
292
293 }
294 } else {
295 PortForwardRequestList portForwardRequestList;
296 _openPorts[port] = portForwardRequestList;
297 }
298
299 return exists;
300 }
301
302 int Protocol::_listenPort(in_port_t port, int &error)
303 {
304 return ATNetworkTool::CreateServerSocket(
305 port,
306 error,
307 false, true, PF_INET);
308 }
309
310 bool Protocol::_localListen(in_port_t port)
311 {
312 int error;
313 int socket = INVALID_SOCKET;
314 bool exists = _checkListen("127.0.0.1", port, socket);
315
316 int serverSocket = _listenPort(port, error);
317 if (serverSocket == INVALID_SOCKET) {
318 PRINT("[Compat]LMS Service cannot listen at port %d.\n", (int)port);
319 if (exists) {
320 //already listening
321 }
322 return false;
323 }
324 PRINT("[Compat]Listening at port %d at local interface.\n", (int)port);
325
326 PortForwardRequest *portForwardRequest =
327 new PortForwardRequest("127.0.0.1", port,
328 serverSocket, _isLocalCallback, true);
329
330 _openPorts[port].push_back(portForwardRequest);
331 portForwardRequest->SetStatus(PortForwardRequest::LISTENING);
332
333 return true;
334 }
335
336 bool Protocol::CreateSockets()
337 {
338 int error;
339 _sockets_active = false;
340
341 ATNetworkTool::CloseSocket(_serverSignalSocket);
342 _serverSignalSocket = ATNetworkTool::CreateServerSocket((in_port_t)0, error, true);
343 if (_serverSignalSocket == INVALID_SOCKET) {
344 return false;
345 }
346
347 ATNetworkTool::CloseSocket(_clientSignalSocket);
348 _clientSignalSocket = ATNetworkTool::ConnectToSocket(_serverSignalSocket, error);
349 if (_clientSignalSocket == INVALID_SOCKET) {
350 ATNetworkTool::CloseSocket(_serverSignalSocket);
351 _serverSignalSocket = INVALID_SOCKET;
352 return false;
353 }
354
355 struct sockaddr_storage addr;
356 socklen_t addrLen = sizeof(addr);
357 SOCKET s_new = accept(_serverSignalSocket, (struct sockaddr *)&addr, &addrLen);
358 if (s_new == INVALID_SOCKET) {
359 ATNetworkTool::CloseSocket(_serverSignalSocket);
360 ATNetworkTool::CloseSocket(_clientSignalSocket);
361 _serverSignalSocket = INVALID_SOCKET;
362 _clientSignalSocket = INVALID_SOCKET;
363 return false;
364 }
365
366 ATNetworkTool::CloseSocket(_serverSignalSocket);
367 _serverSignalSocket = s_new;
368
369 if (oldProtocolMode) {
370 if (!_localListen(16992)) {
371 return false;
372 }
373 if (!_localListen(16993)) {
374 return false;
375 }
376 }
377
378 _sockets_active = true;
379 return true;
380 }
381
382 void Protocol::DestroySockets()
383 {
384 _sockets_active = false;
385
386 if (_serverSignalSocket != INVALID_SOCKET) {
387 ATNetworkTool::CloseSocket(_serverSignalSocket);
388 _serverSignalSocket = INVALID_SOCKET;
389 }
390 }
391
392 bool Protocol::_acceptConnection(SOCKET s, unsigned int port)
393 {
394 ATAddress addr;
395 int error = 0;
396 char buf[NI_MAXHOST];
397
398 if (!IsInitialized()) {
399 return false;
400 }
401
402 SOCKET s_new = ATNetworkTool::Accept(s, addr, error);
403 if (s_new == INVALID_SOCKET) {
404 #if DEBUGLOG
405 char *msg = _getErrMsg(error);
406 PRINT("Error accepting new connection (%d): %s\n", error, msg);
407 #endif
408 return false;
409 }
410
411 const char *addrStr = addr.inNtoP(buf, NI_MAXHOST);
412 if (addrStr == NULL) {
413 PRINT("Error: ntop failed for new connection\n");
414 ATNetworkTool::CloseSocket(s_new);
415 return false;
416 }
417
418 PortForwardRequest *portForwardRequest = NULL;
419
420 //_portsLock is already aquired by the calling function: Select().
421 PortMap::iterator it = _openPorts.find(port);
422 if (it != _openPorts.end()) {
423 PortForwardRequestList::iterator it2 = it->second.begin();
424
425 for (; it2 != it->second.end(); it2++) {
426 if (((*it2)->GetStatus() == PortForwardRequest::LISTENING) &&
427 (1 == (*it2)->IsConnectionPermitted(this, s_new))) {
428 portForwardRequest = *it2;
429 break;
430 }
431 }
432
433 }
434
435 if (portForwardRequest == NULL) {
436 PRINT("Error: new connection is denied (addr %s)\n", addrStr);
437 ATNetworkTool::CloseSocket(s_new);
438 return false;
439 }
440
441 if (oldProtocolMode) {
442 unsigned int connId;
443 bool oret = _lme.CompatOpenConnection(port, addr, connId);
444 if (!oret) {
445 PRINT("[Compat]Error: failed to open new LME MEI connection\n");
446 ATNetworkTool::CloseSocket(s_new);
447 return false;
448 }
449 PRINT("[Compat]Send open connection to LME. Sender %d.\n", (int)s_new);
450
451 Channel *c = new Channel(portForwardRequest, s_new);
452 c->SetStatus(Channel::OPEN);
453 c->SetRecipientChannel(connId);
454 c->AddBytesTxWindow(1024);
455
456 Lock l(_channelsLock);
457 _openChannels[connId] = c;
458 c->GetPortForwardRequest()->IncreaseChannelCount();
459 } else {
460 Channel *c = new Channel(portForwardRequest, s_new);
461 c->SetStatus(Channel::NOT_OPENED);
462
463 Lock l(_channelsLock);
464 _openChannels[s_new] = c;
465 c->GetPortForwardRequest()->IncreaseChannelCount();
466
467 _lme.ChannelOpenForwardedRequest((UINT32)s_new,
468 port,
469 ((portForwardRequest->IsLocal()) ? "127.0.0.1" : addrStr),
470 addr.inPort());
471 PRINT("Send channel open request to LME. Sender %d.\n", (int)s_new);
472 }
473
474 return true;
475 }
476
477 int Protocol::Select()
478 {
479 fd_set rset;
480 struct timeval tv;
481 int res;
482 int fdCount = 0;
483 int fdMin = -1;
484
485 tv.tv_sec = 1;
486 tv.tv_usec = 0;
487
488 FD_ZERO(&rset);
489
490 FD_SET(_serverSignalSocket, &rset);
491 if ((int)_serverSignalSocket > fdCount) {
492 fdCount = (int)_serverSignalSocket;
493 }
494
495 {
496 Lock l(_portsLock);
497 PortMap::iterator it = _openPorts.begin();
498
499 for (; it != _openPorts.end(); it++) {
500 if (it->second.size() > 0) {
501 SOCKET serverSocket = it->second[0]->GetListeningSocket();
502 FD_SET(serverSocket, &rset);
503 if ((int)serverSocket > fdCount) {
504 fdCount = (int)serverSocket;
505 }
506 }
507 }
508 }
509
510 {
511 Lock l(_channelsLock);
512
513 ChannelMap::iterator it = _openChannels.begin();
514
515 for (; it != _openChannels.end(); it++) {
516 if ((it->second->GetStatus() == Channel::OPEN) &&
517 (it->second->GetTxWindow() > 0)) {
518 SOCKET socket = it->second->GetSocket();
519 FD_SET(socket, &rset);
520 if ((int)socket > fdCount) {
521 fdCount = (int)socket;
522 }
523 if ((fdMin == -1) || ((int)socket < fdMin)) {
524 fdMin = (int)socket;
525 }
526 }
527 }
528 }
529
530 fdCount++;
531 res = select(fdCount, &rset, NULL, NULL, &tv);
532 if (res == -1) {
533 #if DEBUGLOG
534 #if defined(__sun) || defined(_LINUX)
535 int err = errno;
536 #else
537 int err = GetLastError();
538 #endif // __sun || _LINUX
539
540 char *msg = _getErrMsg(err);
541 PRINT("Select error (%d): %s\n", err, msg);
542 #endif
543 return -1;
544 }
545
546 if (res == 0) {
547 return 0;
548 }
549
550 if (!IsInitialized()) {
551 return 0;
552 }
553
554 if (FD_ISSET(_serverSignalSocket, &rset)) { // Received a 'signal'
555 char c = 0;
556 res = recv(_serverSignalSocket, &c, 1, 0);
557 FD_CLR(_serverSignalSocket, &rset);
558 res--;
559 }
560
561 {
562 Lock l(_portsLock);
563 PortMap::iterator it = _openPorts.begin();
564
565 for (; it != _openPorts.end(); it++) {
566 if (it->second.size() > 0) {
567 SOCKET serverSocket = it->second[0]->GetListeningSocket();
568 if (FD_ISSET(serverSocket, &rset)) {
569 // connection request
570 PRINT("Connection requested on port %d\n", it->first);
571 _acceptConnection(serverSocket, it->first);
572 FD_CLR(serverSocket, &rset);
573 res--;
574 }
575 }
576 }
577 }
578
579 int i;
580 for (i = fdMin/*0*/; (res > 0) && (i < fdCount); i++) {
581 if (FD_ISSET(i, &rset)) {
582 _rxFromSocket(i);
583 res--;
584 }
585 }
586
587 return 1;
588 }
589
590 int Protocol::_rxFromSocket(SOCKET s)
591 {
592 Channel *c = NULL;
593
594 if (!IsInitialized()) {
595 return 0;
596 }
597
598 {
599 Lock l(_channelsLock);
600
601 Channel *cx = _getSockOpenChannel(s);
602
603 if (cx == NULL) {
604 // Data received from a socket that is not in the map.
605 // Since we only select on our sockets, this means it was
606 // in the map, but was removed, probably because we received
607 // an End Connection message from the HECI.
608 return 0;
609 }
610
611 c = new Channel(*cx);
612 }
613
614 int res = 0;
615
616 int len = std::min(c->GetTxWindow(), _rxSocketBufferSize);
617 res = recv(s, _rxSocketBuffer, len, 0);
618 if (res > 0) {
619 // send data to LME
620 PRINT("Received %d bytes from socket %d. Sending to LME\n", res, (int)s);
621 if (oldProtocolMode) {
622 _lme.CompatSendMessage((UINT8)c->GetRecipientChannel(), res, (unsigned char *)_rxSocketBuffer);
623 } else {
624 _lme.ChannelData(c->GetRecipientChannel(), res, (unsigned char *)_rxSocketBuffer);
625 }
626 goto out;
627 } else if (res == 0) {
628 // connection closed
629 PRINT("Received 0 bytes from socket %d.\n", (int)s);
630 goto out;
631 } else {
632 #if DEBUGLOG
633 #if defined(__sun) || defined(_LINUX)
634 int err = errno;
635 #else
636 int err = GetLastError();
637 #endif // __sun || _LINUX
638
639 char *msg = _getErrMsg(err);
640 PRINT("Receive error on socket %d (%d): %s\n", (int)s, err, msg);
641 #endif
642 #ifdef __sun
643 ATNetworkTool::CloseSocket(s);
644 #endif
645 goto out;
646 }
647
648 out:
649 {
650 Lock l(_channelsLock);
651
652 Channel *cx = _getSockOpenChannel(s);
653
654 if (cx == NULL) {
655 // Data received from a socket that is not in the map.
656 // Since we only select on our sockets, this means it was
657 // in the map, but was removed, probably because we received
658 // an End Connection message from the HECI.
659 delete c;
660 return 0;
661 }
662 if (res > 0) {
663 if (!oldProtocolMode) {
664 cx->AddBytesTxWindow(-res);
665 }
666 }
667 else {
668 cx->SetStatus(Channel::WAITING_CLOSE);
669 if (oldProtocolMode) {
670 if (res == 0) {
671 _closeMChannel(cx);
672
673 ChannelMap::iterator it = _openChannels.begin();
674 for (; it != _openChannels.end(); it++) {
675 if (it->second == cx) {
676 break;
677 }
678 }
679 if (it != _openChannels.end()) {
680 _openChannels.erase(it);
681 }
682 }
683 _lme.CompatCloseConnection(c->GetRecipientChannel(),
684 ((res == 0) ? LMS_CLOSE_STATUS_CLIENT :
685 LMS_CLOSE_STATUS_SOCKET));
686 } else {
687 _lme.ChannelClose(c->GetRecipientChannel());
688 }
689 }
690 }
691 delete c;
692
693 return 0;
694 }
695
696 void Protocol::_signalSelect()
697 {
698 int senderr = 0;
699
700 _send(_clientSignalSocket, "s", 1, senderr); //Enforce a new execution of Select()
701 }
702
703 void Protocol::_closePortForwardRequest(PortForwardRequest *p)
704 {
705 PortMap::iterator it = _openPorts.find(p->GetPort());
706 if (it == _openPorts.end()) {
707 return;
708 }
709
710 bool found = false;
711 PortForwardRequestList::iterator it2 = it->second.begin();
712 for (; it2 != it->second.end(); it2++) {
713 if ((*it2) == p) {
714 found = true;
715 break;
716 }
717 }
718
719 if ((*it2)->GetStatus() == PortForwardRequest::NOT_ACTIVE) {
720
721 SOCKET serverSocket = (*it2)->GetListeningSocket();
722 delete (*it2);
723 it->second.erase(it2);
724
725 if (it->second.size() == 0) {
726 int res = ATNetworkTool::CloseSocket(serverSocket);
727 if (res != 0) {
728 int err;
729
730 #if defined(__sun) || defined(_LINUX)
731 err = errno;
732 #else
733 err = WSAGetLastError()
734 #endif
735 PRINT("Error %d in closing server socket at port %d.\n", err, p->GetPort());
736 }
737 _openPorts.erase(it);
738 }
739 }
740 }
741
742 bool Protocol::_checkProtocolFlow(LMEMessage *message)
743 {
744 switch (message->MessageType) {
745 case APF_SERVICE_REQUEST:
746 case APF_USERAUTH_REQUEST:
747 {
748 Lock l(_versionLock);
749 if (_handshakingStatus != AGREED) {
750 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
751 Deinit();
752 return false;
753 }
754 return true;
755 }
756 break;
757
758 case APF_GLOBAL_REQUEST:
759 case APF_CHANNEL_OPEN:
760 case APF_CHANNEL_OPEN_CONFIRMATION:
761 case APF_CHANNEL_OPEN_FAILURE:
762 case APF_CHANNEL_CLOSE:
763 case APF_CHANNEL_DATA:
764 case APF_CHANNEL_WINDOW_ADJUST:
765 {
766 Lock l(_versionLock);
767 if ((_handshakingStatus != AGREED) || (_pfwdService != STARTED)) {
768 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
769 Deinit();
770 return false;
771 }
772 return true;
773 }
774 break;
775
776 case APF_DISCONNECT:
777 case APF_PROTOCOLVERSION:
778 return true;
779 break;
780
781 default:
782 {
783 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
784 Deinit();
785 return false;
786 }
787 break;
788 }
789
790 return false;
791 }
792
793 unsigned int Protocol::_getMinMessageLen(LMEMessage *message)
794 {
795 switch (message->MessageType) {
796 case APF_SERVICE_REQUEST:
797 return sizeof(LMEServiceRequestMessage);
798 break;
799 case APF_USERAUTH_REQUEST:
800 return sizeof(LMEUserAuthRequestMessage);
801 break;
802 case APF_GLOBAL_REQUEST:
803 return sizeof(LMEGlobalRequestMessage);
804 break;
805 case APF_CHANNEL_OPEN:
806 return sizeof(LMEChannelOpenRequestMessage);
807 break;
808 case APF_CHANNEL_OPEN_CONFIRMATION:
809 return sizeof(LMEChannelOpenReplaySuccessMessage);
810 break;
811 case APF_CHANNEL_OPEN_FAILURE:
812 return sizeof(LMEChannelOpenReplayFailureMessage);
813 break;
814 case APF_CHANNEL_CLOSE:
815 return sizeof(LMEChannelCloseMessage);
816 break;
817 case APF_CHANNEL_DATA:
818 return sizeof(LMEChannelDataMessage);
819 break;
820 case APF_CHANNEL_WINDOW_ADJUST:
821 return sizeof(LMEChannelWindowAdjustMessage);
822 break;
823 case APF_DISCONNECT:
824 return sizeof(LMEDisconnectMessage);
825 break;
826 case APF_PROTOCOLVERSION:
827 return sizeof(LMEProtocolVersionMessage);
828 break;
829 default:
830 return 0;
831 }
832
833 return 0;
834 }
835
836 bool Protocol::_checkMessageAndProtocol(LMEMessage *message, unsigned int len)
837 {
838 if (len < sizeof(LMEMessage)) {
839 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
840 Deinit();
841 return false;
842 }
843
844 if (!_checkProtocolFlow(message)) {
845 return false;
846 }
847 if (len < _getMinMessageLen(message)) {
848 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
849 Deinit();
850 return false;
851 }
852 return true;
853 }
854
855 void Protocol::_LmeCallback(void *param, void *buffer, unsigned int len, int *status)
856 {
857 Protocol *prot = (Protocol *)param;
858
859 if (prot->oldProtocolMode) {
860 prot->_LmeReceiveCompat((char *)buffer, len, status);
861 } else {
862 prot->_LmeReceive(buffer, len, status);
863 }
864 }
865
866 void Protocol::_LmeReceive(void *buffer, unsigned int len, int *status)
867 {
868 LMEMessage *message = (LMEMessage *)buffer;
869 *status = 0;
870
871 if (!_checkMessageAndProtocol(message, len)) {
872 return;
873 }
874
875 switch (message->MessageType) {
876 case APF_DISCONNECT:
877 {
878 PRINT("LME requested to disconnect with reason code 0x%08x\n",
879 ((LMEDisconnectMessage *)message)->ReasonCode);
880 Deinit();
881 return;
882 }
883 break;
884
885 case APF_SERVICE_REQUEST:
886 {
887 LMEServiceRequestMessage *sRMsg =
888 (LMEServiceRequestMessage *)message;
889
890 if ((sRMsg->ServiceName.compare(APF_SERVICE_AUTH) == 0) ||
891 (sRMsg->ServiceName.compare(APF_SERVICE_PFWD) == 0)) {
892
893 _lme.ServiceAccept(sRMsg->ServiceName);
894 PRINT("Accepting service: %s\n",
895 sRMsg->ServiceName.c_str());
896 if (sRMsg->ServiceName.compare(APF_SERVICE_PFWD) == 0) {
897 Lock l(_versionLock);
898 _pfwdService = STARTED;
899 }
900 } else {
901 PRINT("Requesting to disconnect from LME with reason code 0x%08x\n",
902 APF_DISCONNECT_SERVICE_NOT_AVAILABLE);
903 _lme.Disconnect(APF_DISCONNECT_SERVICE_NOT_AVAILABLE);
904 Deinit();
905 return;
906 }
907 }
908 break;
909
910 case APF_USERAUTH_REQUEST:
911 {
912 PRINT("Sending Userauth success message\n");
913 _lme.UserAuthSuccess();
914 }
915 break;
916
917 case APF_PROTOCOLVERSION:
918 _apfProtocolVersion((LMEProtocolVersionMessage *)message);
919 break;
920
921 case APF_GLOBAL_REQUEST:
922 _apfGlobalRequest((LMEGlobalRequestMessage *)message, len, status);
923 break;
924
925 case APF_CHANNEL_OPEN:
926 _apfChannelOpen((LMEChannelOpenRequestMessage *)message, status);
927 break;
928
929 case APF_CHANNEL_OPEN_CONFIRMATION:
930 {
931 LMEChannelOpenReplaySuccessMessage *chOpenSuccMsg =
932 (LMEChannelOpenReplaySuccessMessage *)message;
933
934 Lock l(_channelsLock);
935
936 ChannelMap::iterator it = _openChannels.find(chOpenSuccMsg->RecipientChannel);
937 if (it != _openChannels.end()) {
938 it->second->SetStatus(Channel::OPEN);
939 it->second->SetRecipientChannel(chOpenSuccMsg->SenderChannel);
940 it->second->AddBytesTxWindow(chOpenSuccMsg->InitialWindow);
941 }
942
943 _signalSelect();
944 }
945 break;
946
947 case APF_CHANNEL_OPEN_FAILURE:
948 {
949 PortForwardRequest *clPFwdReq =
950 _apfChannelOFail((LMEChannelOpenReplayFailureMessage *)message);
951 if (clPFwdReq != NULL) {
952 Lock l(_portsLock);
953 _closePortForwardRequest(clPFwdReq);
954 }
955 }
956 break;
957
958 case APF_CHANNEL_CLOSE:
959 {
960 PortForwardRequest *clPFwdReq =
961 _apfChannelClose((LMEChannelCloseMessage *)message);
962 if (clPFwdReq != NULL) {
963 Lock l(_portsLock);
964 _closePortForwardRequest(clPFwdReq);
965 }
966 }
967 break;
968
969 case APF_CHANNEL_DATA:
970 {
971 PortForwardRequest *clPFwdReq =
972 _apfChannelData((LMEChannelDataMessage *)message, status);
973 if (clPFwdReq != NULL) {
974 Lock l(_portsLock);
975 _closePortForwardRequest(clPFwdReq);
976 }
977 }
978 break;
979
980 case APF_CHANNEL_WINDOW_ADJUST:
981 {
982 LMEChannelWindowAdjustMessage *channelWindowMessage = (LMEChannelWindowAdjustMessage *)message;
983
984 Lock l(_channelsLock);
985
986 ChannelMap::iterator it = _openChannels.find(channelWindowMessage->RecipientChannel);
987 if (it != _openChannels.end()) {
988 it->second->AddBytesTxWindow(channelWindowMessage->BytesToAdd);
989 _signalSelect();
990 }
991 }
992 break;
993
994 default:
995 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
996 Deinit();
997 break;
998 }
999 }
1000
1001 unsigned int Protocol::_getMinGlobalMsgLen(LMEGlobalRequestMessage *globalMessage)
1002 {
1003 switch (globalMessage->RequestType) {
1004 case LMEGlobalRequestMessage::TCP_FORWARD_REQUEST:
1005 return sizeof(LMETcpForwardRequestMessage);
1006 break;
1007 case LMEGlobalRequestMessage::TCP_FORWARD_CANCEL_REQUEST:
1008 return sizeof(LMETcpForwardCancelRequestMessage);
1009 break;
1010 case LMEGlobalRequestMessage::UDP_SEND_TO:
1011 return sizeof(LMEUdpSendToMessage);
1012 break;
1013 default:
1014 return 0;
1015 }
1016 return 0;
1017 }
1018
1019 void Protocol::_apfGlobalRequest(LMEGlobalRequestMessage *globalMessage,
1020 unsigned int len, int *status)
1021 {
1022 PRINT("Global Request type 0x%02x\n", globalMessage->RequestType);
1023
1024 if (len < _getMinGlobalMsgLen(globalMessage)) {
1025 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
1026 Deinit();
1027 return;
1028 }
1029
1030 switch (globalMessage->RequestType) {
1031 case LMEGlobalRequestMessage::TCP_FORWARD_REQUEST:
1032 _apfTcpForwardRequest((LMETcpForwardRequestMessage *)globalMessage, status);
1033 break;
1034
1035 case LMEGlobalRequestMessage::TCP_FORWARD_CANCEL_REQUEST:
1036 _apfTcpForwardCancel((LMETcpForwardCancelRequestMessage *)globalMessage);
1037 break;
1038
1039 case LMEGlobalRequestMessage::UDP_SEND_TO:
1040 _aptSendUdp((LMEUdpSendToMessage *)globalMessage, status);
1041 break;
1042
1043 default:
1044 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
1045 Deinit();
1046 break;
1047 }
1048 }
1049
1050 void Protocol::_apfTcpForwardRequest(LMETcpForwardRequestMessage *tcpFwdReqMsg, int *status)
1051 {
1052 IsConnectionPermittedCallback cb = NULL;
1053 bool failure = false;
1054
1055 #ifdef _REMOTE_SUPPORT
1056 if (tcpFwdReqMsg->Address.compare("0.0.0.0") == 0) {
1057 cb = _isRemoteCallback;
1058 }
1059 else
1060 #endif
1061 {
1062 cb = _isLocalCallback;
1063 }
1064
1065 {
1066 Lock l(_portsLock);
1067 SOCKET serverSocket = INVALID_SOCKET;
1068 listenPortSet::iterator lpi;
1069
1070 if (_checkListen(tcpFwdReqMsg->Address, tcpFwdReqMsg->Port, serverSocket)) {
1071 *status = 1;
1072 // Log in Event Log
1073 TCHAR message[1024];
1074 _stprintf_s(message, 1024,
1075 TEXT("LMS Service already accepted a request at %s:%d\n"),
1076 tcpFwdReqMsg->Address.c_str(),
1077 tcpFwdReqMsg->Port);
1078 _eventLog(_eventLogParam, message, EVENTLOG_ERROR_TYPE);
1079 PRINT(message);
1080 // Send Failure replay to LME
1081 _lme.TcpForwardReplyFailure();
1082 return;
1083 }
1084
1085 lpi = _listenFailReported.find(tcpFwdReqMsg->Port);
1086
1087 if (serverSocket == INVALID_SOCKET) {
1088 int error;
1089 serverSocket = _listenPort(tcpFwdReqMsg->Port, error);
1090 if (serverSocket == INVALID_SOCKET) {
1091 *status = 1;
1092 // Log in Event Log
1093 TCHAR message[1024];
1094 _stprintf_s(message, 1024,
1095 TEXT("LMS Service cannot listen at port %d.\n"),
1096 tcpFwdReqMsg->Port);
1097 if (lpi == _listenFailReported.end()) {
1098 _eventLog(_eventLogParam, message, EVENTLOG_ERROR_TYPE);
1099 _listenFailReported.insert(tcpFwdReqMsg->Port);
1100 }
1101 PRINT(message);
1102 // Send Failure replay to LME
1103 _lme.TcpForwardReplyFailure();
1104 failure = true;
1105 }
1106 }
1107
1108 if (failure != true) {
1109 PRINT("Listening at port %d at %s interface.\n",
1110 tcpFwdReqMsg->Port,
1111 ((cb == _isLocalCallback) ? "local" : "remote"));
1112
1113 PortForwardRequest *portForwardRequest =
1114 new PortForwardRequest(tcpFwdReqMsg->Address,
1115 tcpFwdReqMsg->Port,
1116 serverSocket, cb, (cb == _isLocalCallback));
1117
1118 _openPorts[tcpFwdReqMsg->Port].push_back(portForwardRequest);
1119
1120 // Send Success replay to LME
1121 _lme.TcpForwardReplySuccess(tcpFwdReqMsg->Port);
1122
1123 portForwardRequest->SetStatus(
1124 (cb == _isLocalCallback) ?
1125 PortForwardRequest::LISTENING :
1126 PortForwardRequest::PENDING_REQUEST);
1127 if (lpi != _listenFailReported.end()) {
1128 _listenFailReported.erase(lpi);
1129 }
1130
1131 _signalSelect();
1132 }
1133 }
1134
1135 if (failure == true) {
1136 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR);
1137 Deinit();
1138 return;
1139 }
1140
1141 if (cb == _isLocalCallback) {
1142 if (_listenFailReported.empty()) {
1143 _updateIPFQDN(tcpFwdReqMsg->Address.c_str());
1144 }
1145 }
1146 #ifdef _REMOTE_SUPPORT
1147 else {
1148 _checkRemoteSupport(true);
1149 }
1150 #endif
1151 }
1152
1153 void Protocol::_apfTcpForwardCancel(LMETcpForwardCancelRequestMessage *tcpFwdCnclMsg)
1154 {
1155 bool found = false;
1156 Lock l(_portsLock);
1157
1158 PortMap::iterator it = _openPorts.find(tcpFwdCnclMsg->Port);
1159 if (it == _openPorts.end()) {
1160 PRINT("Previous request on address %s and port %d doesn't exist.\n",
1161 tcpFwdCnclMsg->Address.c_str(), tcpFwdCnclMsg->Port);
1162 _lme.TcpForwardCancelReplyFailure();
1163 return;
1164 }
1165
1166 PortForwardRequestList::iterator it2 = it->second.begin();
1167 for (; it2 != it->second.end(); it2++) {
1168 if (((*it2)->GetBindedAddress().compare(tcpFwdCnclMsg->Address) == 0) &&
1169 //((*it2)->GetPort() == tcpFwdCnclMsg->Port)) {
1170 ((*it2)->GetStatus() != PortForwardRequest::NOT_ACTIVE)) {
1171 found = true;
1172 break;
1173 }
1174 }
1175
1176 if (found) {
1177 (*it2)->SetStatus(PortForwardRequest::NOT_ACTIVE);
1178 if ((*it2)->GetChannelCount() == 0) {
1179 _closePortForwardRequest(*it2);
1180 }
1181 _lme.TcpForwardCancelReplySuccess();
1182 } else {
1183 PRINT("Previous request on address %s and port %d doesn't exist.\n",
1184 tcpFwdCnclMsg->Address.c_str(), tcpFwdCnclMsg->Port);
1185 _lme.TcpForwardCancelReplyFailure();
1186 }
1187 }
1188
1189 void Protocol::_aptSendUdp(LMEUdpSendToMessage *udpSendToMessage, int *status)
1190 {
1191 int error = 0;
1192
1193 SOCKET s = ATNetworkTool::Connect(udpSendToMessage->Address.c_str(),
1194 udpSendToMessage->Port, error,
1195 PF_INET, SOCK_DGRAM);
1196 if (s == INVALID_SOCKET) {
1197 *status = 1;
1198 PRINT("Unable to send UDP data.\n");
1199 return;
1200 }
1201
1202 int count = _send(s, (char *)udpSendToMessage->Data, udpSendToMessage->DataLength, error);
1203 PRINT("Sent UDP data: %d bytes of %d.\n", count, udpSendToMessage->DataLength);
1204
1205 ATNetworkTool::CloseSocket(s);
1206 }
1207
1208 void Protocol::_apfProtocolVersion(LMEProtocolVersionMessage *verMsg)
1209 {
1210 Lock l(_versionLock);
1211
1212 switch (_handshakingStatus) {
1213 case AGREED:
1214 case NOT_INITIATED:
1215 _lme.ProtocolVersion(MAX_PROT_VERSION);
1216 case INITIATED:
1217 if (*verMsg < MIN_PROT_VERSION) {
1218 PRINT("Version %d.%d is not supported.\n",
1219 verMsg->MajorVersion, verMsg->MinorVersion);
1220 _lme.Disconnect(APF_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED);
1221 Deinit();
1222 return;
1223 }
1224 if (*verMsg > MAX_PROT_VERSION) {
1225 _AmtProtVersion = MAX_PROT_VERSION;
1226 } else {
1227 _AmtProtVersion = (*verMsg);
1228 }
1229 _handshakingStatus = AGREED;
1230 break;
1231
1232 default:
1233 _lme.Disconnect(APF_DISCONNECT_BY_APPLICATION);
1234 Deinit();
1235 break;
1236 }
1237 }
1238
1239 void Protocol::_apfChannelOpen(LMEChannelOpenRequestMessage *chOpenMsg, int *status)
1240 {
1241 int error = 0;
1242
1243 PRINT("Got channel request from AMT. "
1244 " Recipient channel %d for address %s, port %d.\n",
1245 chOpenMsg->SenderChannel,
1246 chOpenMsg->Address.c_str(), chOpenMsg->Port);
1247
1248 SOCKET s = ATNetworkTool::Connect(chOpenMsg->Address.c_str(),
1249 chOpenMsg->Port, error, PF_INET);
1250 if (s == INVALID_SOCKET) {
1251 *status = 1;
1252 PRINT("Unable to open direct channel to address %s.\n",
1253 chOpenMsg->Address.c_str());
1254 return;
1255 }
1256
1257 ATNetworkTool::SetNonBlocking(s);
1258
1259 Channel *c = new Channel(NULL, s);
1260 c->AddBytesTxWindow(chOpenMsg->InitialWindow);
1261 c->SetRecipientChannel(chOpenMsg->SenderChannel);
1262 c->SetStatus(Channel::OPEN);
1263
1264 {
1265 Lock l(_channelsLock);
1266 _openChannels[c->GetSenderChannel()] = c;
1267 _lme.ChannelOpenReplaySuccess(c->GetRecipientChannel(), c->GetSenderChannel());
1268 }
1269
1270 _signalSelect();
1271 }
1272
1273 PortForwardRequest *Protocol::_closeMChannel(Channel *c)
1274 {
1275 PortForwardRequest *clPFwdReq = NULL;
1276
1277 ATNetworkTool::CloseSocket(c->GetSocket());
1278 PortForwardRequest *p = c->GetPortForwardRequest();
1279 if ((p != NULL) && (p->DecreaseChannelCount() == 0)) {
1280 clPFwdReq = p;
1281 }
1282 delete c;
1283
1284 return clPFwdReq;
1285 }
1286
1287 PortForwardRequest *Protocol::_apfChannelOFail(LMEChannelOpenReplayFailureMessage *chFailMsg)
1288 {
1289 PortForwardRequest *clPFwdReq = NULL;
1290
1291 Lock l(_channelsLock);
1292
1293 ChannelMap::iterator it = _openChannels.find(chFailMsg->RecipientChannel);
1294 if (it != _openChannels.end()) {
1295 clPFwdReq = _closeMChannel(it->second);
1296 _openChannels.erase(it);
1297 PRINT("Channel open request was refused. Reason code: 0x%02x reason.\n",
1298 chFailMsg->ReasonCode);
1299 }
1300
1301 return clPFwdReq;
1302 }
1303
1304 PortForwardRequest *Protocol::_apfChannelClose(LMEChannelCloseMessage *chClMsg)
1305 {
1306 PortForwardRequest *clPFwdReq = NULL;
1307
1308 Lock l(_channelsLock);
1309
1310 ChannelMap::iterator it = _openChannels.find(chClMsg->RecipientChannel);
1311 if (it != _openChannels.end()) {
1312 Channel *c = it->second;
1313 switch(c->GetStatus()) {
1314 case Channel::OPEN:
1315 c->SetStatus(Channel::CLOSED);
1316 _lme.ChannelClose(c->GetRecipientChannel());
1317 PRINT("Channel %d was closed by AMT.\n", c->GetSenderChannel());
1318 break;
1319
1320 case Channel::WAITING_CLOSE:
1321 PRINT("Received reply by AMT on closing channel %d.\n", c->GetSenderChannel());
1322 break;
1323
1324 case Channel::CLOSED:
1325 case Channel::NOT_OPENED:
1326 break;
1327 }
1328
1329 clPFwdReq = _closeMChannel(c);
1330 _openChannels.erase(it);
1331 }
1332
1333 return clPFwdReq;
1334 }
1335
1336 PortForwardRequest *Protocol::_apfChannelData(LMEChannelDataMessage *chDMsg, int *status)
1337 {
1338 PortForwardRequest *clPFwdReq = NULL;
1339
1340 do {
1341 Lock l(_channelsLock);
1342
1343 ChannelMap::iterator it = _openChannels.find(chDMsg->RecipientChannel);
1344 if (it == _openChannels.end()) {
1345 break;
1346 }
1347
1348 if ((it->second->GetStatus() != Channel::OPEN) &&
1349 (it->second->GetStatus() != Channel::WAITING_CLOSE)) {
1350 break;
1351 }
1352
1353 if (it->second->GetRxWindow() < chDMsg->DataLength) {
1354 break;
1355 }
1356
1357 int senderr = 0;
1358 int count = _send(it->second->GetSocket(), (char *)chDMsg->Data,
1359 chDMsg->DataLength, senderr);
1360 PRINT("Sent %d bytes of %d from AMT to channel %d with socket %d.\n",
1361 count, chDMsg->DataLength, chDMsg->RecipientChannel,
1362 it->second->GetSocket());
1363
1364 if ((count == -1) && (senderr == EPIPE)) {
1365 *status = 1;
1366 clPFwdReq = _closeMChannel(it->second);
1367 _openChannels.erase(it);
1368 PRINT("Channel send data request was refused. Broken pipe.\n");
1369 break;
1370 }
1371 //it->second->AddBytesRxWindow(-count);
1372 //if (it->second->GetRxWindow() < Channel::LMS_WINDOW_SIZE / 2) {
1373 _lme.ChannelWindowAdjust(it->second->GetRecipientChannel(), chDMsg->DataLength);
1374 //Channel::LMS_WINDOW_SIZE - it->second->GetRxWindow());
1375 //}
1376 } while (0);
1377
1378 return clPFwdReq;
1379 }
1380
1381 #ifdef _REMOTE_SUPPORT
1382
1383 bool Protocol::_compareDNSSuffix(std::string AMTDNSSuffix, std::string suffix)
1384 {
1385 if (AMTDNSSuffix.size() > suffix.size()) {
1386 return false;
1387 }
1388
1389 if ((AMTDNSSuffix.size() < suffix.size()) &&
1390 (suffix[suffix.size()-AMTDNSSuffix.size()-1] != '.')) {
1391 return false;
1392 }
1393
1394 if (strnicmp(suffix.c_str() + suffix.size()-AMTDNSSuffix.size(),
1395 AMTDNSSuffix.c_str(),
1396 AMTDNSSuffix.size()) == 0) {
1397 return true;
1398 }
1399
1400 return false;
1401 }
1402
1403 bool Protocol::_checkRemoteSupport(bool requestDnsFromAmt)
1404 {
1405 if (requestDnsFromAmt) {
1406 std::list<std::string> amtDnsSuffixes;
1407
1408 AMT_STATUS status = _cfg.RequestEntDNSSuffixList(amtDnsSuffixes);
1409
1410 if (status != AMT_STATUS_SUCCESS) {
1411 PRINT("Remote access is disabled - AMT is not configured [%x]\n", status);
1412 return false;
1413 }
1414
1415 _AMTDNSLock.acquire();
1416 _AMTDNSSuffixes.clear();
1417 _AMTDNSSuffixes.assign(amtDnsSuffixes.begin(), amtDnsSuffixes.end());
1418 _AMTDNSLock.release();
1419
1420 amtDnsSuffixes.clear();
1421 }
1422
1423 ATDomainMap domains;
1424 int error = 0;
1425 ATNetworkTool::GetLocalNetDomains(domains, error, PF_INET);
1426 _updateEnterpriseAccessStatus(domains);
1427
1428 return true;
1429 }
1430
1431 void Protocol::_updateEnterpriseAccessStatus(const ATDomainMap &localDNSSuffixes)
1432 {
1433 _AMTDNSLock.acquire();
1434
1435 std::list<std::string>::iterator remIt;
1436 std::list<std::string>::iterator startIt = _AMTDNSSuffixes.begin();
1437 std::list<std::string>::iterator endIt = _AMTDNSSuffixes.end();
1438 ATDomainMap::const_iterator locIt;
1439
1440 bool access = false;
1441 ATAddress localIp;
1442
1443 for (locIt = localDNSSuffixes.begin(); locIt != localDNSSuffixes.end(); locIt++) {
1444 remIt = find_if(startIt, endIt, bind2nd(ptr_fun(_compareDNSSuffix), locIt->second));
1445 if (remIt != _AMTDNSSuffixes.end()) {
1446 access = true;
1447 localIp = locIt->first;
1448 break;
1449 }
1450 }
1451
1452 _AMTDNSLock.release();
1453
1454 bool sendEntAccessMessage = true;
1455 if (access) {
1456 Lock l(_portsLock);
1457 for (PortMap::iterator it = _openPorts.begin(); it != _openPorts.end(); it++) {
1458 for (PortForwardRequestList::iterator it2 = it->second.begin();
1459 it2 != it->second.end(); it2++) {
1460
1461 if ((*it2)->GetStatus() == PortForwardRequest::PENDING_REQUEST) {
1462 (*it2)->SetStatus(PortForwardRequest::LISTENING);
1463 sendEntAccessMessage = false;
1464 break; // Assuming that there is a such request one per port
1465 }
1466 }
1467 }
1468
1469 _signalSelect();
1470 }
1471
1472 if (sendEntAccessMessage == false) {
1473 return;
1474 }
1475
1476 AMT_STATUS status = _cfg.SendEnterpriseAccess(access, localIp);
1477
1478 Lock l(_remoteAccessLock);
1479 _remoteAccessEnabled = (status == AMT_STATUS_SUCCESS);
1480 switch (status) {
1481 case AMT_STATUS_SUCCESS:
1482 PRINT("Remote access is allowed.\n");
1483 break;
1484 case AMT_STATUS_REMOTE_ACCESS_NOT_GRANTED:
1485 PRINT("Remote access is denied because AMT is directly connected "
1486 "to enterprise network.\n");
1487 break;
1488 case AMT_STATUS_REMOTE_ACCESS_HOST_VPN_IS_DISABLED:
1489 PRINT("Remote access is disabled.\n");
1490 break;
1491 default:
1492 PRINT("Remote access is disabled.\n");
1493 break;
1494 }
1495
1496 //if (_remoteAccessEnabled) {
1497 // Lock l(_portsLock);
1498 // for (PortMap::iterator it = _openPorts.begin(); it != _openPorts.end(); it++) {
1499 // for (PortForwardRequestList::iterator it2 = it->second.begin();
1500 // it2 != it->second.end(); it2++) {
1501
1502 // if ((*it2)->GetStatus() == PortForwardRequest::PENDING_REQUEST) {
1503 // (*it2)->SetStatus(PortForwardRequest::LISTENING);
1504 // break; // Assuming that there is a such request one per port
1505 // }
1506 // }
1507 // }
1508
1509 // _signalSelect();
1510 //}
1511
1512 }
1513
1514 #endif
1515
1516 int Protocol::_isLocalCallback(void *const param, SOCKET s)
1517 {
1518 int error = 0;
1519
1520 return ((1 == ATNetworkTool::IsSockPeerLocal(s, error, PF_INET)) ? 1 : -1);
1521 }
1522
1523 #ifdef _REMOTE_SUPPORT
1524
1525 int Protocol::_isRemoteCallback(void *const param, SOCKET s)
1526 {
1527 Protocol *prot = (Protocol *)param;
1528
1529 return prot->_isRemote(s);
1530 }
1531
1532 int Protocol::_isRemote(SOCKET s) const
1533 {
1534 int result = 0;
1535 int error = 0;
1536 int ret;
1537 std::string dnsSuffix;
1538
1539 ret = ATNetworkTool::GetSockDomain(s, dnsSuffix, error);
1540 if (ret != 1) {
1541 return ret;
1542 }
1543
1544 Lock l(_remoteAccessLock);
1545
1546 if (_remoteAccessEnabled) {
1547
1548 _AMTDNSLock.acquire();
1549
1550 std::list<std::string>::const_iterator it = _AMTDNSSuffixes.begin();
1551 for (; it != _AMTDNSSuffixes.end(); it++) {
1552 if (_compareDNSSuffix(*it, dnsSuffix)) {
1553 result = 1;
1554 break;
1555 }
1556 }
1557
1558 _AMTDNSLock.release();
1559 }
1560
1561 return result;
1562 }
1563 #endif
1564
1565 int Protocol::_updateIPFQDN(const char *fqdn)
1566 {
1567 if (strcmp(fqdn, _AMTFQDN) != 0) {
1568 char localName[FQDN_MAX_SIZE] = "\0";
1569 int res = gethostname(localName, sizeof(localName));
1570
1571 // If AMT FQDN is equal to local FQDN than we don't do anything
1572 if ((res == -1) || (strcmp(fqdn, localName) != 0)) {
1573 if (_handleFQDNChange(fqdn) < 0) {
1574 ERROR("Error: failed to update FQDN info\n");
1575 return -1;
1576 }
1577 } else {
1578 if (_handleFQDNChange("") < 0) {
1579 ERROR("Error: failed to update FQDN info\n");
1580 return -1;
1581 }
1582 }
1583 }
1584
1585 memcpy(_AMTFQDN, fqdn, sizeof(_AMTFQDN));
1586
1587 PRINT("Got FQDN: %s\n", _AMTFQDN);
1588
1589 return 0;
1590 }
1591
1592
1593 char *Protocol::_getErrMsg(DWORD err)
1594 {
1595 static char buffer[1024];
1596
1597 #if defined(__sun) || defined(_LINUX)
1598 strerror_r(err, buffer, sizeof(buffer) - 1);
1599 #else
1600 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
1601 NULL,
1602 err,
1603 0,
1604 buffer,
1605 sizeof(buffer) - 1,
1606 0);
1607 #endif // __sun || _LINUX
1608
1609 return buffer;
1610 }
1611
1612
1613 int Protocol::_handleFQDNChange(const char *fqdn)
1614 {
1615 const char *hostFile = "hosts";
1616 const char *tmpFile = "hosts-lms.tmp";
1617 bool hasFqdn = false;
1618 #define LMS_MAX_FILENAME_LEN 1024
1619 char inFileName[LMS_MAX_FILENAME_LEN] = "";
1620 char oldFqdn[FQDN_MAX_SIZE + 1];
1621 char outFileName[LMS_MAX_FILENAME_LEN] = "";
1622 char host[FQDN_MAX_SIZE + 1];
1623 #define LMS_MAX_LINE_LEN 1023
1624 char line[LMS_MAX_LINE_LEN + 1];
1625 #define LMS_LINE_SIG_FIRST_WORDS "# LMS GENERATED "
1626 #define LMS_LINE_SIG_LAST_WORD "LINE"
1627 #define LMS_LINE_SIG_LAST_WORD_LEN 4
1628 #define LMS_LINE_SIG LMS_LINE_SIG_FIRST_WORDS LMS_LINE_SIG_LAST_WORD
1629 #define lmsstr(s) lmsname(s)
1630 #define lmsname(s) #s
1631 #define LMS_LINE_FORMAT "127.0.0.1 %s %s " LMS_LINE_SIG
1632 #define LMS_LINE_SCAN_FORMAT "127.0.0.1 %" lmsstr(FQDN_MAX_SIZE) "s %" lmsstr(FQDN_MAX_SIZE) "s " LMS_LINE_SIG_FIRST_WORDS "%" lmsstr(LMS_LINE_SIG_LAST_WORD_LEN) "c"
1633 char tmpsige[LMS_LINE_SIG_LAST_WORD_LEN];
1634
1635 #if defined(__sun) || defined(_LINUX)
1636
1637 const char *dir = "/etc/";
1638
1639 #else
1640
1641 char *sysDrive;
1642 const char *dir = "\\system32\\drivers\\etc\\";
1643
1644 sysDrive = getenv("SystemRoot");
1645 if (NULL == sysDrive) {
1646 return -1;
1647 }
1648
1649 // sanity check before string copying
1650 if (LMS_MAX_FILENAME_LEN < (strnlen(sysDrive, LMS_MAX_FILENAME_LEN)
1651 + strnlen(dir, LMS_MAX_FILENAME_LEN)
1652 + strnlen(hostFile, LMS_MAX_FILENAME_LEN) + 1)) {
1653 return -1;
1654 }
1655 // sanity check before string copying
1656 if (LMS_MAX_FILENAME_LEN < (strnlen(sysDrive, LMS_MAX_FILENAME_LEN)
1657 + strnlen(dir, LMS_MAX_FILENAME_LEN)
1658 + strnlen(tmpFile, LMS_MAX_FILENAME_LEN) + 1)) {
1659 return -1;
1660 }
1661
1662 strncpy(inFileName, sysDrive, LMS_MAX_FILENAME_LEN - 1);
1663 strncpy(outFileName, sysDrive, LMS_MAX_FILENAME_LEN - 1);
1664
1665 #endif // __sun || _LINUX
1666
1667 strncat(inFileName, dir, LMS_MAX_FILENAME_LEN - 1);
1668 strncat(outFileName, dir, LMS_MAX_FILENAME_LEN - 1);
1669 strncat(inFileName, hostFile, LMS_MAX_FILENAME_LEN - 1);
1670 strncat(outFileName, tmpFile, LMS_MAX_FILENAME_LEN - 1);
1671
1672 FILE *ifp = fopen(inFileName, "r");
1673 if (NULL == ifp) {
1674 _eventLog(_eventLogParam, TEXT("Error: Can't open hosts file"), EVENTLOG_ERROR_TYPE);
1675 return -1;
1676 }
1677
1678 FILE *ofp = fopen(outFileName, "w");
1679 if (NULL == ofp) {
1680 _eventLog(_eventLogParam, TEXT("Error: Can't create temporary hosts file"), EVENTLOG_ERROR_TYPE);
1681 fclose(ifp);
1682 return -1;
1683 }
1684
1685 // First create a copy of the hosts file, without lines that were
1686 // previously added by the LMS.
1687 // Go over each line and copy it to the tmp file.
1688 while (fgets(line, sizeof(line), ifp)) {
1689 // don't copy the line if it was generated by the LMS
1690 memset(oldFqdn, 0, sizeof(oldFqdn));
1691 memset(tmpsige, 0, sizeof(tmpsige));
1692 if (0 == (
1693 (3 == sscanf(line, LMS_LINE_SCAN_FORMAT, oldFqdn, host, tmpsige))
1694 ? strncmp(tmpsige, LMS_LINE_SIG_LAST_WORD, LMS_LINE_SIG_LAST_WORD_LEN)
1695 : (-2))
1696 ) {
1697 if (0 == strncmp((char *)fqdn, oldFqdn, FQDN_MAX_SIZE)) {
1698 // copy the old LMS line too, since it's up to date
1699 fprintf(ofp, "%s", line);
1700 hasFqdn = true;
1701 }
1702 continue;
1703 }
1704
1705 fprintf(ofp, "%s", line);
1706
1707 while ((LMS_MAX_LINE_LEN == strnlen(line, LMS_MAX_LINE_LEN))
1708 && ('\n' != line[LMS_MAX_LINE_LEN - 1])
1709 && (fgets(line, sizeof(line), ifp))) {
1710 fprintf(ofp, "%s", line);
1711 }
1712 }
1713
1714 if (hasFqdn) {
1715 fclose(ofp);
1716 fclose(ifp);
1717 unlink(outFileName);
1718 return 0;
1719 }
1720
1721 // If the original hosts file does not end with a new line character,
1722 // add a new line at the end of the new file before adding our line.
1723 fseek(ifp, -1, SEEK_END);
1724 char lastChar = fgetc(ifp);
1725 if ('\n' != lastChar) {
1726 fprintf(ofp, "\n");
1727 }
1728
1729 memset(host, 0, FQDN_MAX_SIZE + 1);
1730 strncpy(host, fqdn, FQDN_MAX_SIZE);
1731 char *lmsdot = strchr(host, '.');
1732 if (NULL != lmsdot) {
1733 lmsdot[0] = '\0';
1734 }
1735
1736 if ((fqdn != NULL) && (fqdn[0] != 0)) {
1737 // Add the specified FQDN to the end of the tmp file
1738 fprintf(ofp, LMS_LINE_FORMAT "\n", fqdn, host);
1739 }
1740
1741 fclose(ofp);
1742 fclose(ifp);
1743
1744 if (0 != std::rename(outFileName, inFileName)) {
1745 std::string tmp2FileName = std::string(inFileName) + ".~tmp";
1746 std::ifstream mfile(inFileName, std::ios_base::in);
1747 if (!mfile.is_open()) {
1748 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [1]"), EVENTLOG_ERROR_TYPE);
1749 return -1;
1750 }
1751 std::ofstream wfile(tmp2FileName.c_str(), std::ios_base::out | std::ios_base::trunc);
1752 if (!wfile.is_open()) {
1753 mfile.close();
1754 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [2]"), EVENTLOG_ERROR_TYPE);
1755 return -1;
1756 }
1757 wfile << mfile.rdbuf();
1758 if (wfile.bad()) {
1759 mfile.close();
1760 wfile.close();
1761 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [3]"), EVENTLOG_ERROR_TYPE);
1762 return -1;
1763 }
1764 mfile.close();
1765 wfile.close();
1766 std::ifstream sfile(outFileName, std::ios_base::in);
1767 if (!sfile.is_open()) {
1768 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [4]"), EVENTLOG_ERROR_TYPE);
1769 return -1;
1770 }
1771 std::ofstream dfile(inFileName, std::ios_base::out | std::ios_base::trunc);
1772 if (!dfile.is_open()) {
1773 sfile.close();
1774 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [5]"), EVENTLOG_ERROR_TYPE);
1775 return -1;
1776 }
1777 dfile << sfile.rdbuf();
1778 if (dfile.bad()) {
1779 sfile.close();
1780 dfile.close();
1781 unlink(inFileName);
1782 if (0 != std::rename(outFileName, inFileName)) {
1783 std::rename(tmp2FileName.c_str(), inFileName);
1784 _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [6]"), EVENTLOG_ERROR_TYPE);
1785 return -1;
1786 }
1787 }
1788 sfile.close();
1789 dfile.close();
1790 }
1791
1792 _eventLog(_eventLogParam, TEXT("hosts file updated"), EVENTLOG_INFORMATION_TYPE);
1793
1794 return 0;
1795 }
1796
1797 ssize_t Protocol::_send(int s, const void *buf, size_t len, int &senderr)
1798 {
1799 ssize_t result;
1800
1801 #if defined(_LINUX)
1802 if (-1 == (result = send(s, buf, len, MSG_NOSIGNAL))) {
1803 senderr = errno;
1804 }
1805 #elif defined(__sun)
1806 if (-1 == (result = send(s, buf, len, 0))) {
1807 senderr = errno;
1808 }
1809 #else
1810 result = send(s, buf, len);
1811 #endif // _LINUX
1812
1813 return result;
1814 }
1815
1816