Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. rogue.c
  5. Abstract:
  6. This module contains the rogue detection interface to DHCP for BINL server.
  7. Author:
  8. Andy Herron (andyhe) 19-Aug-1998
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include "binl.h"
  14. #pragma hdrstop
  15. VOID
  16. BinlRogueLoop(
  17. LPVOID Parameter
  18. );
  19. NTSTATUS
  20. MaybeStartRogueThread (
  21. VOID
  22. )
  23. //
  24. // Initiate rogue thread. The gcsDHCPBINL should not be held by caller.
  25. //
  26. {
  27. DWORD Error = ERROR_SUCCESS;
  28. DWORD threadId;
  29. EnterCriticalSection(&gcsDHCPBINL);
  30. //
  31. // if we're stopping anyway or if we're already running the rogue stuff
  32. // or if the DHCP server is up, then we don't bother starting rogue
  33. // detection.
  34. //
  35. if ((BinlCurrentState == BINL_STOPPED) ||
  36. (BinlGlobalHaveCalledRogueInit) ||
  37. (DHCPState != DHCP_STOPPED)) {
  38. LeaveCriticalSection(&gcsDHCPBINL);
  39. return ERROR_SUCCESS;
  40. }
  41. //
  42. // Let's do rogue detection.. first create the events we need
  43. //
  44. if (BinlRogueTerminateEventHandle == NULL) {
  45. BinlRogueTerminateEventHandle = CreateEvent( NULL, FALSE, FALSE, NULL );
  46. }
  47. if (RogueUnauthorizedHandle == NULL) {
  48. RogueUnauthorizedHandle = CreateEvent( NULL, TRUE, FALSE, NULL );
  49. }
  50. if ( BinlRogueTerminateEventHandle == NULL || RogueUnauthorizedHandle == NULL) {
  51. Error = GetLastError();
  52. BinlPrintDbg( (DEBUG_ROGUE,
  53. "Initialize(...) CreateEvent returned error %x for rogue\n",
  54. Error )
  55. );
  56. LeaveCriticalSection(&gcsDHCPBINL);
  57. return Error;
  58. }
  59. Error = DhcpRogueInit( &DhcpRogueInfo,
  60. BinlRogueTerminateEventHandle,
  61. RogueUnauthorizedHandle );
  62. if (Error != ERROR_SUCCESS) {
  63. LeaveCriticalSection(&gcsDHCPBINL);
  64. return Error;
  65. }
  66. //
  67. // create the thread that handles the rogue detection logic in DHCP code.
  68. //
  69. BinlRogueThread = CreateThread( NULL,
  70. 0,
  71. (LPTHREAD_START_ROUTINE)BinlRogueLoop,
  72. NULL,
  73. 0,
  74. &threadId );
  75. if ( BinlRogueThread == NULL ) {
  76. Error = GetLastError();
  77. BinlPrint((DEBUG_ROGUE, "Can't create rogue Thread, %ld.\n", Error));
  78. LeaveCriticalSection(&gcsDHCPBINL);
  79. return Error;
  80. }
  81. BinlGlobalHaveCalledRogueInit = TRUE;
  82. LeaveCriticalSection(&gcsDHCPBINL);
  83. return ERROR_SUCCESS;
  84. }
  85. VOID
  86. StopRogueThread (
  87. VOID
  88. )
  89. //
  90. // Cleanup all rogue thread resources.
  91. // The gcsDHCPBINL should not be held by caller.
  92. //
  93. {
  94. HANDLE tempThreadHandle;
  95. tempThreadHandle = InterlockedExchangePointer( &BinlRogueThread, NULL );
  96. if ( tempThreadHandle != NULL ) {
  97. BinlAssert( BinlRogueTerminateEventHandle != NULL );
  98. SetEvent( BinlRogueTerminateEventHandle );
  99. WaitForSingleObject(
  100. tempThreadHandle,
  101. THREAD_TERMINATION_TIMEOUT );
  102. CloseHandle( tempThreadHandle );
  103. }
  104. EnterCriticalSection(&gcsDHCPBINL);
  105. if (BinlGlobalHaveCalledRogueInit) {
  106. DhcpRogueCleanup( &DhcpRogueInfo );
  107. BinlGlobalHaveCalledRogueInit = FALSE;
  108. }
  109. if ( BinlRogueTerminateEventHandle ) {
  110. CloseHandle( BinlRogueTerminateEventHandle );
  111. BinlRogueTerminateEventHandle = NULL;
  112. }
  113. if ( RogueUnauthorizedHandle ) {
  114. CloseHandle( RogueUnauthorizedHandle );
  115. RogueUnauthorizedHandle = NULL;
  116. }
  117. LeaveCriticalSection(&gcsDHCPBINL);
  118. return;
  119. }
  120. VOID
  121. HandleRogueAuthorized (
  122. VOID
  123. )
  124. {
  125. BOOL oldState = BinlGlobalAuthorized;
  126. BinlGlobalAuthorized = TRUE;
  127. if ((BinlGlobalAuthorized != oldState) &&
  128. (BinlCurrentState != BINL_STOPPED)) {
  129. LogCurrentRogueState( FALSE );
  130. }
  131. return;
  132. }
  133. VOID
  134. HandleRogueUnauthorized (
  135. VOID
  136. )
  137. {
  138. BOOL oldState = BinlGlobalAuthorized;
  139. BinlGlobalAuthorized = FALSE;
  140. if ((BinlGlobalAuthorized != oldState) &&
  141. (BinlCurrentState != BINL_STOPPED)) {
  142. LogCurrentRogueState( FALSE );
  143. }
  144. return;
  145. }
  146. VOID
  147. LogCurrentRogueState (
  148. BOOL ResponseToMessage
  149. )
  150. {
  151. //
  152. // If we're responding to a message and we haven't yet logged that
  153. // we're unauthorized
  154. if ((ResponseToMessage == FALSE) ||
  155. ((BinlGlobalAuthorized == FALSE) &&
  156. (BinlRogueLoggedState == FALSE)) ) {
  157. BinlRogueLoggedState = TRUE;
  158. BinlReportEventW( BinlGlobalAuthorized ?
  159. EVENT_ERROR_DHCP_AUTHORIZED :
  160. EVENT_ERROR_DHCP_NOT_AUTHORIZED,
  161. EVENTLOG_INFORMATION_TYPE,
  162. 0,
  163. 0,
  164. NULL,
  165. NULL
  166. );
  167. }
  168. return;
  169. }
  170. VOID
  171. BinlRogueLoop(
  172. LPVOID Parameter
  173. )
  174. {
  175. HANDLE Handles[3];
  176. ULONG SecondsToSleep, SleepTime, Error;
  177. ULONG Flag;
  178. BinlPrintDbg((DEBUG_ROGUE, "BinlRogue thread has been started.\n" ));
  179. Handles[0] = BinlRogueTerminateEventHandle;
  180. Handles[1] = RogueUnauthorizedHandle;
  181. Handles[2] = BinlGlobalProcessTerminationEvent;
  182. do {
  183. SecondsToSleep = RogueDetectStateMachine(&DhcpRogueInfo);
  184. if( INFINITE == SecondsToSleep ) {
  185. SleepTime = INFINITE;
  186. } else {
  187. SleepTime = SecondsToSleep * 1000;
  188. }
  189. BinlPrintDbg( (DEBUG_ROGUE, "BinlRogue waiting %u milliseconds.\n", SleepTime ));
  190. Error = WaitForMultipleObjects(3, Handles, FALSE, SleepTime );
  191. //
  192. // if we got anything but WAIT_TIMEOUT or RogueUnauthorized, we
  193. // break out. This is per RameshV's sample code.
  194. //
  195. if (Error == WAIT_OBJECT_0+2) {
  196. //
  197. // binl is terminating.
  198. //
  199. BinlPrintDbg((DEBUG_ROGUE, "BinlRogue thread is exiting because BINL shutting down.\n" ));
  200. return;
  201. }
  202. if (BinlRogueThread == NULL) {
  203. //
  204. // we've been terminated because DHCP has started and is doing
  205. // it's own rogue detection.
  206. //
  207. BinlPrintDbg((DEBUG_ROGUE, "BinlRogue thread is exiting because rogue thread is null.\n" ));
  208. return;
  209. }
  210. // if we ever have to do anything besides just continue when the
  211. // state machine tells us to exit, do so here.
  212. #if 0
  213. if ((Error == WAIT_OBJECT_0+1) || (Error == WAIT_TIMEOUT)) {
  214. continue;
  215. }
  216. #endif
  217. //
  218. // supposedly the state machine resets so we should just continue.
  219. //
  220. BinlPrintDbg((DEBUG_ROGUE, "BinlRogue has error of 0x%x. sleeping a bit\n", Error ));
  221. Sleep( 1000 ); // we'll sleep to give the dhcp rogue state
  222. // machine time to reset
  223. } while ( TRUE );
  224. }
  225. // rogue.c eof