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 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 96 Protocol::~Protocol() 97 { 98 if (!oldProtocolMode) { 99 _lme.Disconnect(APF_DISCONNECT_BY_APPLICATION); 100 } 101 DeinitFull(); 102 DestroySockets(); 103 _listenFailReported.clear(); 104 } 105 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