int TcpExchangeChallenge (SOCKET s, int seed, int nVersion, const char *key) { FILETIME ft; struct S_Challenge Out1, In1, Out2, In2; int Rc; int Ark; GetSystemTimeAsFileTime (&ft); srand (ft.dwLowDateTime + seed + (unsigned) s); for (Ark=0 ; Ark< sizeof Out1.challenge ; Ark++) Out1.challenge[Ark] = (unsigned char) (rand () & 0xFF); Out1.pad = 0; Out1.version = nVersion; Rc = TcpPPSend ( s, (char *) & Out1, sizeof Out1, INVALID_FILE_HANDLE ); if (Rc<0) return Rc; Rc = TcpPPRecv ( s, (char *) & In1, sizeof In1, 10, INVALID_FILE_HANDLE ); if (Rc<0) {int Ark = WSAGetLastError (); LogToMonitor ("Error %d receiving on socket %d\n", Ark, s); return Rc; } /* verify version */ if (In1.version != nVersion) return TCP4U_VERSION_ERROR; /* 'crypt' challenge */ Out2 = In1; sym_crypt ( Out2.challenge, sizeof Out2.challenge, key ); /* resend frame */ Rc = TcpPPSend ( s, (char *)& Out2, sizeof Out2, INVALID_FILE_HANDLE ); if (Rc<0) return Rc; /* wait for our Challenge (*/ Rc = TcpPPRecv ( s, (char *)& In2, sizeof In2, 10, INVALID_FILE_HANDLE ); if (Rc<0) return Rc; /* un crypt In2 and compare with Out1 */ sym_crypt ( In2.challenge, sizeof In2.challenge, key ); return memcmp (In2.challenge, Out1.challenge, sizeof Out1.challenge)==0 ? TCP4U_SUCCESS : TCP4U_BAD_AUTHENT ; } // TcpExchangeChallenge
void TftpdConsole (void *param) { SOCKET sDlg; int Rc; int nTriggeredEvent; static struct S_ConsoleMsg msg; enum e_Events { EV_TOGUI, EV_FROMGUI, EV_NUMBER }; HANDLE tEvents [EV_NUMBER]; // open logging facility StartAsyncMessagingFacility ( ); do { LogToMonitor ("opening comm socket\n"); SetGuiStatus (NOT_CONNECTED); sDlg = WaitForGuiConnection (); // fail only if thread ends if (sDlg==INVALID_SOCKET) continue; // Verify Versions LogToMonitor ("Verify Console/GUI parameters\n"); Rc = TcpExchangeChallenge (sDlg, 0x56AE, CURRENT_PROTOCOL_VERSION, NULL, sSettings.szConsolePwd); if ( Rc < 0 ) { Sleep (1000); continue; } LogToMonitor ( "Version check OK\n" ); SetGuiStatus (CONNECTED); // Startup blocking service by creating // one event and one semaphore to code the blocking sendmsgrequest hMsgRequestSemaf = CreateMutex(NULL, 0, NULL); hEvMsgSent = CreateEvent(NULL,FALSE,FALSE,NULL); if (hMsgRequestSemaf==NULL) CMsgBox (NULL, "Can not create resource", APPLICATION, MB_OK | MB_ICONERROR); tThreads[TH_CONSOLE].bInit = TRUE; // inits OK // Create Socket Event tEvents [EV_FROMGUI] = WSACreateEvent(); WSAEventSelect (sDlg, tEvents[EV_FROMGUI], FD_READ | FD_CLOSE); do { // waits either internal sollicitation or msg reception tEvents[EV_TOGUI] = tThreads[TH_CONSOLE].hEv; nTriggeredEvent = WaitForMultipleObjects (EV_NUMBER, tEvents, FALSE, INFINITE); switch (nTriggeredEvent) { case EV_FROMGUI : // WSA events should be manually reset WSAEventSelect (sDlg, 0, 0); ResetEvent (tEvents[EV_FROMGUI]); Rc = TcpPPRecv (sDlg, (void *) &msg, sizeof msg, 10, INVALID_HANDLE_VALUE); if (Rc>0) LOG (9, "received %d bytes from console", Rc); if (Rc>0) ProcessMsg (sDlg, &msg); else LogToMonitor ("rcvd error %d/%d in console\n", Rc, GetLastError ()); WSAEventSelect (sDlg, tEvents[EV_FROMGUI], FD_READ | FD_CLOSE); break; // message to be sent to Gui (except logs) case EV_TOGUI : ProcessAsyncMessages ( sDlg, hEvMsgSent ); break; } // switch signalled events } while (tThreads[TH_CONSOLE].gRunning && (Rc>0 || Rc==TCP4U_TIMEOUT) ); WSACloseEvent (tEvents [EV_FROMGUI]); tEvents [EV_FROMGUI] = INVALID_HANDLE_VALUE; closesocket (sDlg); // blocking service not available CloseHandle (hEvMsgSent); hEvMsgSent = INVALID_HANDLE_VALUE; CloseHandle (hMsgRequestSemaf); hMsgRequestSemaf = INVALID_HANDLE_VALUE; LogToMonitor ("end of GUI session\n"); } while ( tThreads[TH_CONSOLE].gRunning ); // terminate therad : don't listen anymore // closesocket (sListen); // unblock some threads SetEvent (hEvMsgSent); Sleep (10); SetEvent (hEvMsgSent); // stop logging service StopAsyncMessagingFacility (); LogToMonitor ("End of console thread\n"); _endthread (); } // TftpdConsole