void __stdcall ReceivedMsgFromUser(DWORD dwConnectionIndex,char* pMsg,DWORD dwLength) { MSGROOT* pTempMsg = reinterpret_cast<MSGROOT*>(pMsg); // ServerTraffic * Msg = reinterpret_cast<ServerTraffic*>(pMsg); ASSERT(g_pUserMsgParser[pTempMsg->Category]); //---KES Distribute Encrypt 071003 USERINFO* pInfo = g_pUserTable->FindUser(dwConnectionIndex); if( pInfo ) { if( pInfo->cbCheckSum == 0 ) { pInfo->cbCheckSum = pTempMsg->CheckSum; } else if( pInfo->cbCheckSum != pTempMsg->CheckSum ) { OnDisconnectUser( dwConnectionIndex ); DisconnectUser( dwConnectionIndex ); return; } ++pInfo->cbCheckSum; int headerSize = sizeof( MSGROOT ); if( !pInfo->crypto.Decrypt( ( char * )pTempMsg + headerSize, dwLength - headerSize ) ) { ASSERTMSG(0,"Decrypt Error"); OnDisconnectUser( dwConnectionIndex ); DisconnectUser( dwConnectionIndex ); return; } char aaa = pInfo->crypto.GetDeCRCConvertChar(); if( pTempMsg->Code != aaa ) { ASSERTMSG(0,"Decrypt CRC Error"); OnDisconnectUser( dwConnectionIndex ); DisconnectUser( dwConnectionIndex ); return; } } //-------------------------------- if( g_pUserMsgParser[pTempMsg->Category] == NULL || pTempMsg->Category >= MP_MAX || pTempMsg->Category == 0) return; g_pUserMsgParser[pTempMsg->Category](dwConnectionIndex, pMsg, dwLength); }
// Translates message and does the appropriate task for message handled by // the NDK. void CNDKServer::TranslateMessage(long lUserId, CNDKMessage& message) { switch (message.GetId()) { case NDKPingServer: SendMessageToUser(lUserId, message); break; case NDKPingClient: { long lNbMilliseconds = 0; message.GetAt(0, lNbMilliseconds); OnPing(lUserId, ::GetTickCount() - lNbMilliseconds); } break; case NDKClientDisconnect: DisconnectUser(lUserId, NDKServer_ClientCloseConnection); break; default: OnMessage(lUserId, message); break; } }
void __stdcall OnAcceptUser(DWORD dwConnectionIndex) { if(g_bReady == FALSE) { // 초기화가 완전히 안됐는데 들어온경우. MSGBASE send; send.Category = MP_USERCONN; send.Protocol = MP_USERCONN_SERVER_NOTREADY; send.dwObjectID = 0; g_Network.Send2User(dwConnectionIndex, (char *)&send, sizeof(send)); DisconnectUser(dwConnectionIndex); return; } USERINFO* pPreInfo = g_pUserTable->FindUser( dwConnectionIndex ); if( pPreInfo ) { g_pUserTable->RemoveUser( dwConnectionIndex ); memset(pPreInfo, 0, sizeof(USERINFO)); g_UserInfoPool.Free( pPreInfo ); } DWORD authkey = g_pServerSystem->MakeAuthKey(); USERINFO * info = g_UserInfoPool.Alloc(); memset(info, 0, sizeof(USERINFO)); info->dwConnectionIndex = dwConnectionIndex; info->dwUniqueConnectIdx = authkey; info->dwLastConnectionCheckTime = gCurTime; //SW051107 추가 g_pUserTable->AddUser(info,dwConnectionIndex); //---KES Distribute Encrypt 071003 /* MSGBASE send; send.Category = MP_USERCONN; send.Protocol = MP_USERCONN_DIST_CONNECTSUCCESS; send.dwObjectID = authkey; g_Network.Send2User(dwConnectionIndex, (char *)&send, sizeof(send)); */ MSG_DIST_CONNECTSUCCESS send; send.Category = MP_USERCONN; send.Protocol = MP_USERCONN_DIST_CONNECTSUCCESS; send.dwObjectID = authkey; info->crypto.Create(); // key 생성 send.eninit = *info->crypto.GetEnKey(); send.deinit = *info->crypto.GetDeKey(); g_Network.Send2User(dwConnectionIndex, (char *)&send, sizeof(send)); info->crypto.SetInit( TRUE ); // init on //-------------------------------- // g_Console.Log(eLogDisplay,4, "OnAcceptUser : Client Connected - Idx:%d, AuthKey:%d, Total(%d)",dwConnectionIndex,authkey, g_pUserTable->GetUserCount()); // g_Console.Log(eLogFile,4, "OnAcceptUser : Client Connected - Idx:%d, AuthKey:%d, Total(%d)",dwConnectionIndex,authkey, g_pUserTable->GetUserCount()); }
void CTrafficLog::AddUserPacket(DWORD dwUserID, BYTE Category) { USERTRAFFIC* pData = NULL; // 유저 정보를 가져온다 pData = m_UserTrafficTable.GetData(dwUserID); // 정보가 유효하고 로그인 중일때 if( pData && pData->bLogin ) { // 카테고리가 잘못되었다면 if(Category >= MP_MAX || Category <= 0) // 잘못된 패킷 pData->dwUnValuedCount++; else // 정상 패킷 pData->dwValuedCount++; // 전체 패킷 pData->dwTotalPacketCount++; // 잘못된 패킷이 기준치 이상 들어오면 잘라냄 if(pData->dwUnValuedCount >= m_dwUnValuedCount) { DWORD dwConIdx = pData->dwConnectionIndex; OnDisconnectUser( dwConIdx ); DisconnectUser( dwConIdx ); } // 정상 패킷이 기준치 이상 들어오면 잘라냄 if(pData->dwValuedCount >= m_dwValuedCount) { DWORD dwConIdx = pData->dwConnectionIndex; OnDisconnectUser( dwConIdx ); DisconnectUser( dwConIdx ); } return; } // 로그인 중이 아니라면 잘못되었다. // ASSERT(0); // 한꺼번에 많은 데이터가 들어올시 접속 종료후에 메세지를 처리해서 들어올수 있다. }
void CServerSystem::ConnectionCheck() { // YH 현재 30초마다 한번씩 들어옴 DWORD _60sec = 60*1000; USERINFO* pInfo; DWORD elapsedtime; if(g_bReady == FALSE) return; cPtrList removelist; g_pUserTable->SetPositionHead(); while((pInfo = g_pUserTable->GetData()) != NULL) { if(pInfo->dwConnectionIndex != 0) { // 아직 접속이 제대로 이뤄지지 않은 경우 elapsedtime = gCurTime - pInfo->dwLastConnectionCheckTime; if( elapsedtime > _60sec * 2 ) { if(pInfo->bConnectionCheckFailed) { //!!테스트 후 30초 마다 들어오게 바꾸고 지울것~! //pInfo->dwLastConnectionCheckTime += 1000 * 10; //OnDisconnectUser( 리턴 받기 전에 반복 방지. removelist.AddTail(pInfo); continue; } else { pInfo->bConnectionCheckFailed = TRUE; SendConnectionCheckMsg(pInfo); pInfo->dwLastConnectionCheckTime = gCurTime; } } } } PTRLISTPOS pos = removelist.GetHeadPosition(); while( pos ) { USERINFO* p = (USERINFO*)removelist.GetNext(pos); ASSERT(p->dwConnectionIndex); // LoginCheckDelete(p->dwUserID); // 로그인체크 테이블에서 삭제 // g_pServerSystem->ReleaseAuthKey(p->dwUniqueConnectIdx); // g_pUserTable->RemoveUser(p->dwConnectionIndex); // memset(p,0,sizeof(USERINFO)); // g_UserInfoPool.Free(p); DisconnectUser( p->dwConnectionIndex ); } removelist.RemoveAll(); }
// подключение клиента void MyServer::incomingConnection(int handle) { //передаем дескрпитор сокета, указатель на сервер (для вызова его методов), // и стандартный параметр - parent MyClient *client = new MyClient(handle, this, this); //подключаем сигналы напрямую к виджету, если его передали в конструктор сервера if (widget != 0) { connect(client, SIGNAL(ConnectUser(QString)), widget, SLOT(AddUser(QString))); connect(client, SIGNAL(DisconnectUser(QString)), widget, SLOT(DelitUser(QString))); connect(client, SIGNAL(messageUser(QString,QString,QStringList)), widget, SLOT(MessagesUser(QString,QString,QStringList))); } connect(client, SIGNAL(DisconUser(MyClient*)), this, SLOT(RemoveUser(MyClient*))); clients.append(client); }
// Processes pending read. void CNDKServer::ProcessPendingRead(CNDKServerSocket* pSocket, long lErrorCode) { long lUserId = 0; CMessageList messages; BOOL bResult = m_userMgr.ProcessPendingRead(pSocket, lErrorCode, lUserId, messages); if (bResult) { POSITION pos = messages.GetHeadPosition(); while (pos != NULL) TranslateMessage(lUserId, messages.GetNext(pos)); messages.RemoveAll(); } else { DisconnectUser(lUserId, NDKServer_ErrorReceivingMessage); } }
int main(int argc, char const *argv[]){ int i; initSocket(); // allocating memory for clients' array clients = (Client*)calloc(MaxClientsNumber,sizeof(Client)); // initializing clients for(i = 0; i < MaxClientsNumber; i++){ strncpy(clients[i].status, "OFFLINE", 7); clients[i].id = i; clients[i].username = (char*)calloc(USERNAMESIZE,sizeof(char)); } CHAT_ONLINE = TRUE; system("clear"); fprintf(stderr,"CHAT OPENED!\n"); fprintf(stderr,"-- 'close' to end the chat\n\n"); pthread_create(&adminThread, &pthread_custom_attr, serverCommand, (void*)0); pthread_create(&acceptLoopThread, &pthread_custom_attr, acceptConnection_LOOP, (void*)0); while(CHAT_ONLINE){ //loop } for(i = 0; i < Clients_Count; i++){ if(strcmp(clients[i].status,"ONLINE") == 0){ DisconnectUser(i); } } close(sockfd); return 0; }
void VNCSetNewPasswordsList(HVNC hVNC,bool bDisconnectLoggedUsers,PASSWORDS_LIST *lpPasswordsList) { HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC); if ((!lpHandle) || (!lpHandle->lpServer)) return; PHVNC lpServer=lpHandle->lpServer; rfbScreenInfoPtr rfbScreen=lpServer->rfbScreen; bool bReplaceList=false; if (rfbScreen->authPasswdData) { if ((lpPasswordsList) && (lpPasswordsList->dwPasswordsCount)) { PASSWORD_ITEM **lppPasswords=(PASSWORD_ITEM **)rfbScreen->authPasswdData; for (int i=0; i < lpPasswordsList->dwPasswordsCount; i++) { for (int j=0; lppPasswords[j]; j++) { if (!lstrcmpA(lpPasswordsList->piPasswords[i].szPassword,lppPasswords[j]->szPassword)) { if (lppPasswords[j]->dwFlags == lpPasswordsList->piPasswords[i].dwFlags) lppPasswords[j]->dwFlags=-1; } } } bReplaceList=true; } else rfbScreen->newClientHook=OnNewClient; PASSWORD_ITEM **lppPasswords=(PASSWORD_ITEM **)rfbScreen->authPasswdData; for (int i=0; lppPasswords[i]; i++) { if (lppPasswords[i]->dwFlags != -1) { if (bDisconnectLoggedUsers) DisconnectUser(lpServer,lppPasswords[i]); } MemFree(lppPasswords[i]); } MemFree(lppPasswords); rfbScreen->authPasswdData=NULL; } else if ((lpPasswordsList) && (lpPasswordsList->dwPasswordsCount)) { if (bDisconnectLoggedUsers) DisconnectUser(lpServer,NULL); bReplaceList=true; rfbScreen->passwordCheck=OnNewClientAuth; } if (bReplaceList) { DWORD dwPasswordsCount=lpPasswordsList->dwPasswordsCount; PASSWORD_ITEM **lppPasswords=(PASSWORD_ITEM **)MemAlloc((dwPasswordsCount+1)*sizeof(PASSWORD_ITEM *)); for (DWORD i=0; i < dwPasswordsCount; i++) { lppPasswords[i]=(PASSWORD_ITEM*)MemAlloc(sizeof(PASSWORD_ITEM)); lppPasswords[i]->dwFlags=lpPasswordsList->piPasswords[i].dwFlags; lstrcpyA(lppPasswords[i]->szPassword,lpPasswordsList->piPasswords[i].szPassword); } rfbScreen->authPasswdData=lppPasswords; } return; }
// Disconnects a specified user. OnDisconnection callback will be call with the value // NDKNormalDisconnection. BOOL CNDKServer::DisconnectUser(long lUserId) { return DisconnectUser(lUserId, NDKServer_NormalDisconnection); }
void CNProtectManager::NetworkMsgParse(DWORD dwConnectionIndex, char* pMsg, DWORD dwLength) { MSGROOT* pTempMsg = (MSGROOT*)pMsg; switch(pTempMsg->Protocol) { case MP_NPROTECT_ANSWER: { MSG_DWORD4* pmsg = (MSG_DWORD4*)pMsg; USERINFO* pUserInfo = g_pUserTable->FindUser(dwConnectionIndex); if( pUserInfo == NULL ) { return; } else if( pUserInfo->m_pCSA == NULL ) { return; } pUserInfo->m_pCSA->m_AuthAnswer.dwIndex = pmsg->dwData1; pUserInfo->m_pCSA->m_AuthAnswer.dwValue1 = pmsg->dwData2; pUserInfo->m_pCSA->m_AuthAnswer.dwValue2 = pmsg->dwData3; pUserInfo->m_pCSA->m_AuthAnswer.dwValue3 = pmsg->dwData4; DWORD dwRet = pUserInfo->m_pCSA->CheckAuthAnswer(); if(dwRet != ERROR_SUCCESS) { char buf[256] = {0,}; SYSTEMTIME ti; GetLocalTime( &ti ); sprintf(buf, "[ERRCODE:%d] Query : %08X %08X %08X %08X, Answer: %08X %08X %08X %08X, UserIdx: %d, CharIdx: %d, Time: %02d:%02d:%02d\n", dwRet, pUserInfo->m_pCSA->m_AuthQuery.dwIndex, pUserInfo->m_pCSA->m_AuthQuery.dwValue1, pUserInfo->m_pCSA->m_AuthQuery.dwValue2, pUserInfo->m_pCSA->m_AuthQuery.dwValue3, pUserInfo->m_pCSA->m_AuthAnswer.dwIndex, pUserInfo->m_pCSA->m_AuthAnswer.dwValue1, pUserInfo->m_pCSA->m_AuthAnswer.dwValue2, pUserInfo->m_pCSA->m_AuthAnswer.dwValue3, pUserInfo->dwUserID, pUserInfo->dwCharacterID, ti.wHour, ti.wMinute, ti.wSecond ); char fname[256]; sprintf(fname,"./Log/NProtect_%02d_%02d%02d%02d.txt", g_pServerSystem->GetServerNum(), ti.wYear, ti.wMonth, ti.wDay); FILE* pFile = fopen(fname, "a+"); fprintf(pFile, buf); fclose(pFile); MSGBASE msg; msg.Category = MP_NPROTECT; msg.Protocol = MP_NPROTECT_DISCONNECT; g_Network.Send2User(pUserInfo->dwConnectionIndex,(char*)&msg,sizeof(msg)); OnDisconnectUser( dwConnectionIndex ); DisconnectUser( dwConnectionIndex ); // NPROTECTMGR->Block(pUserInfo, dwRet); //---KES NProtect 계정 Block을 하려면 여기 주석을 풀어주자. return; } pUserInfo->m_bCSA = FALSE; // 1차 인증 if(pUserInfo->m_nCSAInit == 1) { // 2차 인증 pUserInfo->m_nCSAInit = 2; NPROTECTMGR->SendAuthQuery(pUserInfo); } else if(pUserInfo->m_nCSAInit == 2) { pUserInfo->m_nCSAInit = 3; // 이후에는 주기적으로 인증해준다 pUserInfo->dwLastNProtectCheck += 1000*60*2; //처음은 1분만에. } } break; case MP_NPROTECT_USER_DISCONNECT: { // 클라이언트의 nProtect가 클라이언트를 강제 종료시킬때 보내는 메세지 MSG_DWORD* pmsg = (MSG_DWORD*)pMsg; // NPROTECTMGR->Block(pUserInfo, pmsg->dwData); --> 클라이언트 해킹은 블럭하지 않는다. } break; default: break; } }
void CNProtectManager::SendAuthQuery(USERINFO* pInfo) { pInfo->dwLastNProtectCheck = gCurTime; if(pInfo->m_bCSA) { MSGBASE msg; msg.Category = MP_NPROTECT; msg.Protocol = MP_NPROTECT_DISCONNECT; g_Network.Send2User(pInfo->dwConnectionIndex,(char*)&msg,sizeof(msg)); if( pInfo->UserLevel >= eUSERLEVEL_GM ) //---KES NProtect GM이상은 접속을 끊지 않는다 { DWORD dwConIdx = pInfo->dwConnectionIndex; OnDisconnectUser( dwConIdx ); DisconnectUser( dwConIdx ); } // Block(pInfo, 0); return; } pInfo->m_bCSA = TRUE; MSG_DWORD4 msg; DWORD dwRet = pInfo->m_pCSA->GetAuthQuery(); if(dwRet != ERROR_SUCCESS) { char buf[256] = {0,}; SYSTEMTIME ti; GetLocalTime( &ti ); sprintf(buf, "Query : %08X %08X %08X %08X, UserIdx: %d, CharIdx: %d, Time: %02d:%02d:%02d\n", pInfo->m_pCSA->m_AuthQuery.dwIndex, pInfo->m_pCSA->m_AuthQuery.dwValue1, pInfo->m_pCSA->m_AuthQuery.dwValue2, pInfo->m_pCSA->m_AuthQuery.dwValue3, pInfo->dwUserID, pInfo->dwCharacterID, ti.wHour, ti.wMinute, ti.wSecond); char fname[256]; sprintf(fname,"./Log/NProtect_%02d_%02d%02d%02d.txt", g_pServerSystem->GetServerNum(), ti.wYear, ti.wMonth, ti.wDay); FILE* pFile = fopen(fname, "a+"); fprintf(pFile, buf); fclose(pFile); return; } msg.Category = MP_NPROTECT; msg.Protocol = MP_NPROTECT_QUERY; msg.dwData1 = pInfo->m_pCSA->m_AuthQuery.dwIndex; msg.dwData2 = pInfo->m_pCSA->m_AuthQuery.dwValue1; msg.dwData3 = pInfo->m_pCSA->m_AuthQuery.dwValue2; msg.dwData4 = pInfo->m_pCSA->m_AuthQuery.dwValue3; g_Network.Send2User(pInfo->dwConnectionIndex,(char*)&msg,sizeof(msg)); }