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.

337 lines
9.5 KiB

  1. /********************************************************************/
  2. /* Copyright(c) 1995 Microsoft Corporation */
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: evdsptch.c
  7. //
  8. // Description: This module contains the event dispatcher for the
  9. // DDM's procedure-driven state machine
  10. //
  11. // Author: Stefan Solomon (stefans) June 9, 1992.
  12. //
  13. //***
  14. #include "ddm.h"
  15. #include "handlers.h"
  16. #include "objects.h"
  17. #include "timer.h"
  18. #include "util.h"
  19. #include <raserror.h>
  20. #include <ddmif.h>
  21. #include <sechost.h>
  22. #include <stdlib.h>
  23. #include "rasmanif.h"
  24. //***
  25. //
  26. // Function: EventDispatcher
  27. //
  28. // Descr: Waits for events to be signaled and invokes the proper
  29. // event handler. Returns when DDM has terminated.
  30. //
  31. //***
  32. DWORD
  33. EventDispatcher(
  34. IN LPVOID arg
  35. )
  36. {
  37. EVENT_HANDLER * pEventHandler;
  38. DWORD dwSignaledEvent;
  39. //
  40. // Indicate that this thread is running
  41. //
  42. InterlockedIncrement( gblDDMConfigInfo.lpdwNumThreadsRunning );
  43. RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyParameters,
  44. TRUE,
  45. REG_NOTIFY_CHANGE_LAST_SET,
  46. gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION],
  47. TRUE );
  48. RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAccounting,
  49. TRUE,
  50. REG_NOTIFY_CHANGE_LAST_SET,
  51. gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION1],
  52. TRUE );
  53. RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAuthentication,
  54. TRUE,
  55. REG_NOTIFY_CHANGE_LAST_SET,
  56. gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION2],
  57. TRUE );
  58. while( TRUE )
  59. {
  60. dwSignaledEvent = WaitForMultipleObjectsEx(
  61. NUM_DDM_EVENTS
  62. + ( gblDeviceTable.NumDeviceBuckets * 3 ),
  63. gblSupervisorEvents,
  64. FALSE,
  65. INFINITE,
  66. TRUE);
  67. if ( ( dwSignaledEvent == 0xFFFFFFFF ) ||
  68. ( dwSignaledEvent == WAIT_TIMEOUT ) )
  69. {
  70. DDMTRACE2("WaitForMultipleObjectsEx returned %d, GetLastError=%d",
  71. dwSignaledEvent, GetLastError() );
  72. continue;
  73. }
  74. //
  75. // DDM has terminated so return
  76. //
  77. if ( dwSignaledEvent == DDM_EVENT_SVC_TERMINATED )
  78. {
  79. LPDWORD lpdwNumThreadsRunning =
  80. gblDDMConfigInfo.lpdwNumThreadsRunning;
  81. //
  82. // If we were running and we are now shutting down, clean up
  83. // gracefully
  84. //
  85. if ( gblDDMConfigInfo.pServiceStatus->dwCurrentState
  86. == SERVICE_STOP_PENDING )
  87. {
  88. DDMCleanUp();
  89. }
  90. //
  91. // Decrease the count for this thread
  92. //
  93. InterlockedDecrement( lpdwNumThreadsRunning );
  94. return( NO_ERROR );
  95. }
  96. //
  97. // invoke the handler associated with the signaled event
  98. //
  99. if ( dwSignaledEvent < NUM_DDM_EVENTS )
  100. {
  101. //
  102. // Some DDM event
  103. //
  104. gblEventHandlerTable[dwSignaledEvent].EventHandler();
  105. }
  106. else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
  107. + gblDeviceTable.NumDeviceBuckets ) )
  108. {
  109. //
  110. // The event was a RASMAN event
  111. //
  112. RmEventHandler( dwSignaledEvent );
  113. }
  114. else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
  115. + gblDeviceTable.NumDeviceBuckets * 2 ) )
  116. {
  117. //
  118. // A frame was received on a port
  119. //
  120. RmRecvFrameEventHandler( dwSignaledEvent );
  121. }
  122. else if ( dwSignaledEvent != WAIT_IO_COMPLETION )
  123. {
  124. //
  125. // We got a disconnect on a dialed out port
  126. //
  127. RasApiDisconnectHandler( dwSignaledEvent );
  128. }
  129. }
  130. return( NO_ERROR );
  131. }
  132. //***
  133. //
  134. // Function: SecurityDllEventHandler
  135. //
  136. // Descr: This will handle all events from the 3rd party security Dll.
  137. // Either the security dialog with the client completed
  138. // successfully, in which case we continue on with the connection,
  139. // or we log the error and bring down the line.
  140. //
  141. //***
  142. VOID
  143. SecurityDllEventHandler(
  144. VOID
  145. )
  146. {
  147. LPWSTR auditstrp[3];
  148. SECURITY_MESSAGE message;
  149. PDEVICE_OBJECT pDevObj;
  150. DWORD dwBucketIndex;
  151. WCHAR wchUserName[UNLEN+1];
  152. //
  153. // loop to get all messages
  154. //
  155. while( ServerReceiveMessage( MESSAGEQ_ID_SECURITY, (BYTE *) &message ) )
  156. {
  157. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  158. //
  159. // identify the message recipient
  160. //
  161. if ( ( pDevObj = DeviceObjGetPointer( message.hPort ) ) == NULL )
  162. {
  163. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  164. return;
  165. }
  166. //
  167. // action on the message type
  168. //
  169. switch( message.dwMsgId )
  170. {
  171. case SECURITYMSG_SUCCESS:
  172. //
  173. // Stop timer for 3rd party security
  174. //
  175. TimerQRemove( (HANDLE)pDevObj->hPort, SvSecurityTimeout );
  176. if ( pDevObj->pRasmanSendBuffer != NULL )
  177. {
  178. RasFreeBuffer( pDevObj->pRasmanSendBuffer );
  179. pDevObj->pRasmanSendBuffer = NULL;
  180. }
  181. //
  182. // copy the user name
  183. //
  184. MultiByteToWideChar( CP_ACP,
  185. 0,
  186. message.UserName,
  187. -1,
  188. pDevObj->wchUserName,
  189. UNLEN+1 );
  190. //
  191. // copy the domain name
  192. //
  193. MultiByteToWideChar( CP_ACP,
  194. 0,
  195. message.Domain,
  196. -1,
  197. pDevObj->wchDomainName,
  198. DNLEN+1 );
  199. pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
  200. //
  201. // Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
  202. // RmEventHandler
  203. //
  204. RasPortConnectComplete(pDevObj->hPort);
  205. dwBucketIndex = DeviceObjHashPortToBucket( pDevObj->hPort );
  206. SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
  207. DDM_PRINT(
  208. gblDDMConfigInfo.dwTraceId,
  209. TRACE_FSM,
  210. "SecurityDllEventHandler: Security DLL success \n" );
  211. break;
  212. case SECURITYMSG_FAILURE:
  213. //
  214. // Log the fact that the use failed to pass 3rd party security.
  215. //
  216. MultiByteToWideChar( CP_ACP,
  217. 0,
  218. message.UserName,
  219. -1,
  220. wchUserName,
  221. UNLEN+1 );
  222. auditstrp[0] = wchUserName;
  223. auditstrp[1] = pDevObj->wchPortName;
  224. DDMLogError( ROUTERLOG_SEC_AUTH_FAILURE, 2, auditstrp, NO_ERROR );
  225. //
  226. // Hang up the line
  227. //
  228. DDM_PRINT(
  229. gblDDMConfigInfo.dwTraceId,
  230. TRACE_FSM,
  231. "SecurityDllEventHandler:Security DLL failure %s\n",
  232. message.UserName );
  233. if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
  234. {
  235. DevStartClosing(pDevObj);
  236. }
  237. else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
  238. {
  239. pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
  240. DevCloseComplete(pDevObj);
  241. }
  242. break;
  243. case SECURITYMSG_ERROR:
  244. auditstrp[0] = pDevObj->wchPortName;
  245. DDMLogErrorString( ROUTERLOG_SEC_AUTH_INTERNAL_ERROR, 1, auditstrp,
  246. message.dwError, 1);
  247. DDM_PRINT(
  248. gblDDMConfigInfo.dwTraceId,
  249. TRACE_FSM,
  250. "SecurityDllEventHandler:Security DLL failure %x\n",
  251. message.dwError );
  252. if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
  253. {
  254. DevStartClosing(pDevObj);
  255. }
  256. else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
  257. {
  258. pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
  259. DevCloseComplete(pDevObj);
  260. }
  261. break;
  262. default:
  263. RTASSERT(FALSE);
  264. break;
  265. }
  266. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  267. }
  268. }