void TCSoapThread(const std::string& host, uint16 port) { struct soap soap; soap_init(&soap); soap_set_imode(&soap, SOAP_C_UTFSTRING); soap_set_omode(&soap, SOAP_C_UTFSTRING); // check every 3 seconds if world ended soap.accept_timeout = 3; soap.recv_timeout = 5; soap.send_timeout = 5; if (!soap_valid_socket(soap_bind(&soap, host.c_str(), port, 100))) { TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", host.c_str(), port); exit(-1); } TC_LOG_INFO("network.soap", "Bound to http://%s:%d", host.c_str(), port); while (!World::IsStopped()) { if (!soap_valid_socket(soap_accept(&soap))) continue; // ran into an accept timeout TC_LOG_DEBUG("network.soap", "Accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF); struct soap* thread_soap = soap_copy(&soap);// make a safe copy process_message(thread_soap); } soap_done(&soap); }
void TCSoapRunnable::run() { struct soap soap; soap_init(&soap); soap_set_imode(&soap, SOAP_C_UTFSTRING); soap_set_omode(&soap, SOAP_C_UTFSTRING); // check every 3 seconds if world ended soap.accept_timeout = 3; soap.recv_timeout = 5; soap.send_timeout = 5; if (!soap_valid_socket(soap_bind(&soap, _host.c_str(), _port, 100))) { TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", _host.c_str(), _port); exit(-1); } TC_LOG_INFO("network.soap", "Bound to http://%s:%d", _host.c_str(), _port); while (!World::IsStopped()) { if (!soap_valid_socket(soap_accept(&soap))) continue; // ran into an accept timeout TC_LOG_DEBUG("network.soap", "Accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF); struct soap* thread_soap = soap_copy(&soap);// make a safe copy ACE_Message_Block* mb = new ACE_Message_Block(sizeof(struct soap*)); ACE_OS::memcpy(mb->wr_ptr(), &thread_soap, sizeof(struct soap*)); process_message(mb); } soap_done(&soap); }
void MaNGOSsoapRunnable::run() { // Create pool SOAPWorkingThread pool; pool.activate(THR_NEW_LWP | THR_JOINABLE, POOL_SIZE); struct soap soap; int m, s; soap_init(&soap); soap_set_imode(&soap, SOAP_C_UTFSTRING); soap_set_omode(&soap, SOAP_C_UTFSTRING); m = soap_bind(&soap, m_host.c_str(), m_port, 100); // Check every 3 seconds if world ended soap.accept_timeout = 3; soap.recv_timeout = 5; soap.send_timeout = 5; if (m < 0) { sLog.outError("MaNGOSsoap: couldn't bind to %s:%d", m_host.c_str(), m_port); exit(-1); } sLog.outString("MaNGOSsoap: bound to http://%s:%d", m_host.c_str(), m_port); while (!World::IsStopped()) { s = soap_accept(&soap); if (s < 0) { // Ran into an accept timeout continue; } DEBUG_LOG("MaNGOSsoap: accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip >> 24) & 0xFF, (int)(soap.ip >> 16) & 0xFF, (int)(soap.ip >> 8) & 0xFF, (int)soap.ip & 0xFF); // Make a safe copy struct soap* thread_soap = soap_copy(&soap); ACE_Message_Block* mb = new ACE_Message_Block(sizeof(struct soap*)); ACE_OS::memcpy(mb->wr_ptr(), &thread_soap, sizeof(struct soap*)); pool.putq(mb); } pool.msg_queue()->deactivate(); pool.wait(); soap_done(&soap); }
void SOAPThread::Work() { soap soap; soap_init(&soap); soap_set_imode(&soap, SOAP_C_UTFSTRING); soap_set_omode(&soap, SOAP_C_UTFSTRING); soap.accept_timeout = AcceptTimeout; soap.recv_timeout = DataTimeout; soap.send_timeout = DataTimeout; if (soap_bind(&soap, m_host.c_str(), m_port, BackLogSize) < 0) { sLog.outError("MaNGOSsoap: couldn't bind to %s:%d", m_host.c_str(), m_port); exit(-1); } sLog.outString("MaNGOSsoap: bound to http://%s:%d", m_host.c_str(), m_port); while (!World::IsStopped()) { auto s = soap_accept(&soap); // timeout? if (s == SOAP_INVALID_SOCKET) continue; DEBUG_LOG("MaNGOSsoap: accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip >> 24) & 0xFF, (int)(soap.ip >> 16) & 0xFF, (int)(soap.ip >> 8) & 0xFF, (int)soap.ip & 0xFF); auto copy = soap_copy(&soap); soap_serve(copy); soap_destroy(copy); } soap_end(&soap); soap_done(&soap); }
int ns__getClientUpdate(struct soap *soap, struct clientUpdateInfoRequest sClientUpdateInfo, struct clientUpdateResponse* lpsResponse) { unsigned int er = erSuccess; ClientVersion sCurrentVersion = {0}; ClientVersion sLatestVersion; unsigned int ulLicenseResponse = 0; unsigned char *lpLicenseResponse = NULL; ECLicenseClient *lpLicenseClient = NULL; std::string strClientMSIName; std::string strPath; FILE *fd = NULL; int res; unsigned int ulUserID = 0; ECSession *lpecSession = NULL; ECDatabase *lpDatabase = NULL; std::string strCurVersion; std::string strLatestVersion; std::string strQuery; time_t tNow = 0; char *lpszClientUpdatePath = g_lpConfig->GetSetting("client_update_path"); unsigned int ulLogLevel = atoui(g_lpConfig->GetSetting("client_update_log_level")); if (!parseBool(g_lpConfig->GetSetting("client_update_enabled"))) { // do not set on high loglevel, since by default the client updater is installed, and this will be quite often in your log g_lpLogger->Log(EC_LOGLEVEL_NOTICE, "Client update: trackid: 0x%08X, Config option 'client_update_enabled' has disabled this feature.", sClientUpdateInfo.ulTrackId); er = ZARAFA_E_NO_SUPPORT; goto exit; } // setup soap soap_set_imode(soap, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING | SOAP_ENC_ZLIB | SOAP_ENC_MTOM); soap_set_omode(soap, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING | SOAP_ENC_ZLIB | SOAP_ENC_MTOM | SOAP_IO_CHUNK); if (!lpszClientUpdatePath || lpszClientUpdatePath[0] == 0) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, The configuration field 'client_update_path' is empty.", sClientUpdateInfo.ulTrackId); er = ZARAFA_E_NO_ACCESS; goto exit; } er = g_lpSessionManager->CreateSessionInternal(&lpecSession); if(er != erSuccess) goto exit; // Lock the session lpecSession->Lock(); er = lpecSession->GetDatabase(&lpDatabase); if (er != erSuccess) goto exit; //@TODO change loglevel? g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, computername: %s, username: %s, clientversion: %s, windowsversion: %s, iplist: %s, soapip: %s", sClientUpdateInfo.ulTrackId, (sClientUpdateInfo.szComputerName) ? sClientUpdateInfo.szComputerName : "-", (sClientUpdateInfo.szUsername) ? sClientUpdateInfo.szUsername : "******", (sClientUpdateInfo.szClientVersion) ? sClientUpdateInfo.szClientVersion : "-", (sClientUpdateInfo.szWindowsVersion) ? sClientUpdateInfo.szWindowsVersion : "-", (sClientUpdateInfo.szClientIPList) ? sClientUpdateInfo.szClientIPList : "-", PrettyIP(soap->ip).c_str() ); if (!sClientUpdateInfo.szComputerName) sClientUpdateInfo.szComputerName = ""; //Client has no name? if(!sClientUpdateInfo.szUsername) { er = ZARAFA_E_NO_ACCESS; g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Client did not send a username", sClientUpdateInfo.ulTrackId); } // validate user name er = lpecSession->GetUserManagement()->SearchObjectAndSync(sClientUpdateInfo.szUsername, 0x01/*EMS_AB_ADDRESS_LOOKUP*/, &ulUserID); if (er != erSuccess) { er = ZARAFA_E_NO_ACCESS; g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, unknown username '%s'", sClientUpdateInfo.ulTrackId, sClientUpdateInfo.szUsername); } if(lpecSession->GetUserManagement()->IsInternalObject(ulUserID)) { er = ZARAFA_E_NO_ACCESS; g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Wrong user data. User name '%s' is a reserved user", sClientUpdateInfo.ulTrackId, sClientUpdateInfo.szUsername); goto exit; } // Check if the user connect to the right server, else redirect if (lpecSession->GetSessionManager()->IsDistributedSupported() ) { objectdetails_t sUserDetails; er = lpecSession->GetUserManagement()->GetObjectDetails(ulUserID, &sUserDetails); if (er != erSuccess) goto exit; /* Check if this is the correct server */ string strServerName = sUserDetails.GetPropString(OB_PROP_S_SERVERNAME); if (strServerName.empty()) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, User '%s' has no default server", sClientUpdateInfo.ulTrackId, sClientUpdateInfo.szUsername); er = ZARAFA_E_NO_ACCESS; goto exit; } if (stricmp(strServerName.c_str(), g_lpSessionManager->GetConfig()->GetSetting("server_name")) != 0) { string strServerPath; er = GetBestServerPath(soap, lpecSession, strServerName, &strServerPath); if (er != erSuccess) goto exit; lpsResponse->lpszServerPath = s_strcpy(soap, strServerPath.c_str());// Server Path must always utf8 (also in 6.40.x) g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_INFO, "Client update: trackid: 0x%08X, User '%s' is redirected to '%s'", sClientUpdateInfo.ulTrackId, sClientUpdateInfo.szUsername, lpsResponse->lpszServerPath); g_lpStatsCollector->Increment(SCN_REDIRECT_COUNT, 1); er = ZARAFA_E_UNABLE_TO_COMPLETE; goto exit; } } lpLicenseClient = new ECLicenseClient(g_lpConfig->GetSetting("license_socket"), atoui(g_lpConfig->GetSetting("license_timeout"))); er = lpLicenseClient->Auth(sClientUpdateInfo.sLicenseReq.__ptr, sClientUpdateInfo.sLicenseReq.__size, &lpLicenseResponse, &ulLicenseResponse); if (er != erSuccess) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Invalid license request, error: 0x%08X.", sClientUpdateInfo.ulTrackId, er); goto exit; } if (sClientUpdateInfo.szClientVersion == NULL || sClientUpdateInfo.szClientVersion[0] == '\0') { g_lpLogger->Log(EC_LOGLEVEL_INFO, "Client update: trackid: 0x%08X, The client did not sent the current version number.", sClientUpdateInfo.ulTrackId); } else if (!GetVersionFromString(sClientUpdateInfo.szClientVersion, &sCurrentVersion)) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Failed in getting version from input data.", sClientUpdateInfo.ulTrackId); goto exit; //@fixme can we give the latest? } if (!GetLatestVersionAtServer(lpszClientUpdatePath, sClientUpdateInfo.ulTrackId, &sLatestVersion)) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, No updates found on server.", sClientUpdateInfo.ulTrackId); er = ZARAFA_E_NO_ACCESS; goto exit; } res = CompareVersions(sCurrentVersion, sLatestVersion); if (res == 0) { g_lpLogger->Log(EC_LOGLEVEL_INFO, "Client update: trackid: 0x%08X, Client already has the latest version.", sClientUpdateInfo.ulTrackId); goto ok; } else if (res > 0) { g_lpLogger->Log(EC_LOGLEVEL_INFO, "Client update: trackid: 0x%08X, Client has newer version than server.", sClientUpdateInfo.ulTrackId); goto ok; } if (!GetClientMSINameFromVersion(sLatestVersion, &strClientMSIName)) { g_lpLogger->Log(EC_LOGLEVEL_INFO, "Client update: trackid: 0x%08X, No suitable version available.", sClientUpdateInfo.ulTrackId); er = ZARAFA_E_NO_ACCESS; goto exit; } if (ConvertAndValidatePath(lpszClientUpdatePath, strClientMSIName, &strPath) != true) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Error in path conversion and validation.", sClientUpdateInfo.ulTrackId); er = ZARAFA_E_NO_ACCESS; goto exit; } fd = fopen(strPath.c_str(), "rb"); if (!fd) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Path not found %s.", sClientUpdateInfo.ulTrackId, strPath.c_str()); er = ZARAFA_E_NO_ACCESS; goto exit; } // Update auto update client status VersionToString(sCurrentVersion, &strCurVersion); VersionToString(sLatestVersion, &strLatestVersion); tNow = time(NULL); // Get current time strQuery = "REPLACE INTO clientupdatestatus(userid, trackid, updatetime, currentversion, latestversion, computername, status) VALUES ("+ stringify(ulUserID)+", "+stringify(sClientUpdateInfo.ulTrackId)+", FROM_UNIXTIME("+ stringify(tNow) + "), \"" + strCurVersion + "\", \"" + strLatestVersion + "\", \"" + lpDatabase->Escape(sClientUpdateInfo.szComputerName).c_str()+"\", "+ stringify(UPDATE_STATUS_PENDING) + ")"; // ignore error in database tracking, SQL error logged in server, still send new client lpDatabase->DoUpdate(strQuery); soap->fmimereadopen = &mime_file_read_open; soap->fmimeread = &mime_file_read; soap->fmimereadclose = &mime_file_read_close; // Setup the MTOM Attachments lpsResponse->sStreamData.xop__Include.__ptr = (unsigned char*)fd; lpsResponse->sStreamData.xop__Include.__size = 0; lpsResponse->sStreamData.xop__Include.type = s_strcpy(soap, "application/binary"); lpsResponse->sStreamData.xop__Include.id = s_strcpy(soap, "zarafaclient"); g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Client update: trackid: 0x%08X, Sending new installer %s", sClientUpdateInfo.ulTrackId, strClientMSIName.c_str()); ok: // Client is already up to date lpsResponse->sLicenseResponse.__size = ulLicenseResponse; lpsResponse->sLicenseResponse.__ptr = (unsigned char *)s_memcpy(soap, (const char *)lpLicenseResponse, ulLicenseResponse); lpsResponse->ulLogLevel = ulLogLevel; // 0 = none, 1 = on errors, 2 = always exit: if(lpecSession) { lpecSession->Unlock(); g_lpSessionManager->RemoveSessionInternal(lpecSession); } lpsResponse->er = er; if (lpLicenseResponse) delete [] lpLicenseResponse; if (lpLicenseClient) delete lpLicenseClient; if (er && fd) fclose(fd); return SOAP_OK; }