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.

514 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1998
  6. //
  7. // File: ceppswrd.cpp
  8. //
  9. // Contents: Cisco enrollment protocol implementation. This module
  10. // implement the request hash table.
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "global.hxx"
  14. #include <dbgdef.h>
  15. DWORD g_dwRequestDuration=0;
  16. CEP_REQUEST_TABLE_INFO g_CEPRequestTable;
  17. //***************************************************************************
  18. //
  19. // The following are APIs called internally.
  20. //
  21. //
  22. //***************************************************************************
  23. //--------------------------------------------------------------------------
  24. //
  25. // CEPRequestFreeRequestEntry
  26. //
  27. //--------------------------------------------------------------------------
  28. void CEPRequestFreeRequestEntry(CEP_REQUEST_ENTRY *pRequestEntry)
  29. {
  30. if(pRequestEntry)
  31. {
  32. free(pRequestEntry);
  33. }
  34. }
  35. //--------------------------------------------------------------------------
  36. //
  37. // CEPRequestFreeValidityEntry
  38. //
  39. //--------------------------------------------------------------------------
  40. void CEPRequestFreeValidityEntry(CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry,
  41. BOOL fFreeRequestEntry)
  42. {
  43. if(pValidityEntry)
  44. {
  45. if(fFreeRequestEntry)
  46. CEPRequestFreeRequestEntry(pValidityEntry->pRequestEntry);
  47. free(pValidityEntry);
  48. }
  49. }
  50. //--------------------------------------------------------------------------
  51. //
  52. // CEPHashRequest
  53. //
  54. // For any cases that we can not convert the psz, we use index 0.
  55. //--------------------------------------------------------------------------
  56. BOOL CEPHashRequest(BYTE *pbHash, DWORD *pdw)
  57. {
  58. BYTE byte=0;
  59. *pdw=0;
  60. if(!pbHash)
  61. return FALSE;
  62. byte=pbHash[0];
  63. *pdw=(DWORD)byte;
  64. if(*pdw >= CEP_HASH_TABLE_SIZE)
  65. *pdw=0;
  66. return TRUE;
  67. }
  68. //--------------------------------------------------------------------------
  69. //
  70. // CEPSearchRequest
  71. //
  72. //--------------------------------------------------------------------------
  73. CEP_REQUEST_ENTRY *CEPSearchRequest(BYTE *pbHash, DWORD *pdwIndex)
  74. {
  75. CEP_REQUEST_ENTRY *pRequestEntry=NULL;
  76. DWORD dwHashIndex=0;
  77. if(pdwIndex)
  78. *pdwIndex=0;
  79. if(NULL==pbHash)
  80. return NULL;
  81. //hash based on the 1st byte
  82. if(!CEPHashRequest(pbHash, &dwHashIndex))
  83. return NULL;
  84. for(pRequestEntry=g_CEPRequestTable.rgRequestEntry[dwHashIndex]; NULL != pRequestEntry; pRequestEntry=pRequestEntry->pNext)
  85. {
  86. if(0==memcmp(pRequestEntry->pbHash, pbHash, CEP_MD5_HASH_SIZE))
  87. {
  88. break;
  89. }
  90. }
  91. if(pRequestEntry)
  92. {
  93. if(pdwIndex)
  94. *pdwIndex=dwHashIndex;
  95. }
  96. return pRequestEntry;
  97. }
  98. //--------------------------------------------------------------------------
  99. //
  100. // CEPInsertValidityEntry
  101. //
  102. //--------------------------------------------------------------------------
  103. BOOL CEPInsertValidityEntry(CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry)
  104. {
  105. if(!pValidityEntry)
  106. return FALSE;
  107. if(g_CEPRequestTable.pTimeNew)
  108. {
  109. g_CEPRequestTable.pTimeNew->pNext=pValidityEntry;
  110. pValidityEntry->pPrevious=g_CEPRequestTable.pTimeNew;
  111. g_CEPRequestTable.pTimeNew=pValidityEntry;
  112. }
  113. else
  114. {
  115. //no item in the list yet
  116. g_CEPRequestTable.pTimeOld=pValidityEntry;
  117. g_CEPRequestTable.pTimeNew=pValidityEntry;
  118. }
  119. return TRUE;
  120. }
  121. //--------------------------------------------------------------------------
  122. //
  123. // CEPInsertRequestEntry
  124. //
  125. //--------------------------------------------------------------------------
  126. BOOL CEPInsertRequestEntry(CEP_REQUEST_ENTRY *pRequestEntry, DWORD dwHashIndex)
  127. {
  128. if(!pRequestEntry)
  129. return FALSE;
  130. if(g_CEPRequestTable.rgRequestEntry[dwHashIndex])
  131. {
  132. g_CEPRequestTable.rgRequestEntry[dwHashIndex]->pPrevious=pRequestEntry;
  133. pRequestEntry->pNext=g_CEPRequestTable.rgRequestEntry[dwHashIndex];
  134. g_CEPRequestTable.rgRequestEntry[dwHashIndex]=pRequestEntry;
  135. }
  136. else
  137. {
  138. //1st item
  139. g_CEPRequestTable.rgRequestEntry[dwHashIndex]=pRequestEntry;
  140. }
  141. return TRUE;
  142. }
  143. //--------------------------------------------------------------------------
  144. //
  145. // CEPRequestRemoveValidityEntry
  146. //
  147. //--------------------------------------------------------------------------
  148. BOOL CEPRequestRemoveValidityEntry(CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry)
  149. {
  150. BOOL fResult=FALSE;
  151. if(!pValidityEntry)
  152. goto InvalidArgErr;
  153. if(pValidityEntry->pPrevious)
  154. pValidityEntry->pPrevious->pNext=pValidityEntry->pNext;
  155. else
  156. {
  157. //1st item
  158. g_CEPRequestTable.pTimeOld=pValidityEntry->pNext;
  159. }
  160. if(pValidityEntry->pNext)
  161. pValidityEntry->pNext->pPrevious=pValidityEntry->pPrevious;
  162. else
  163. {
  164. //last itme
  165. g_CEPRequestTable.pTimeNew=pValidityEntry->pPrevious;
  166. }
  167. fResult=TRUE;
  168. CommonReturn:
  169. return fResult;
  170. ErrorReturn:
  171. fResult=FALSE;
  172. goto CommonReturn;
  173. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  174. }
  175. //--------------------------------------------------------------------------
  176. //
  177. // CEPRequestRemoveRequestEntry
  178. //
  179. //--------------------------------------------------------------------------
  180. BOOL CEPRequestRemoveRequestEntry(CEP_REQUEST_ENTRY *pRequestEntry, DWORD dwIndex)
  181. {
  182. BOOL fResult=FALSE;
  183. if(!pRequestEntry)
  184. goto InvalidArgErr;
  185. if(pRequestEntry->pPrevious)
  186. pRequestEntry->pPrevious->pNext=pRequestEntry->pNext;
  187. else
  188. g_CEPRequestTable.rgRequestEntry[dwIndex]=pRequestEntry->pNext;
  189. if(pRequestEntry->pNext)
  190. pRequestEntry->pNext->pPrevious=pRequestEntry->pPrevious;
  191. fResult=TRUE;
  192. CommonReturn:
  193. return fResult;
  194. ErrorReturn:
  195. fResult=FALSE;
  196. goto CommonReturn;
  197. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  198. }
  199. //--------------------------------------------------------------------------
  200. //
  201. // CEPRequestRefresh
  202. //
  203. //--------------------------------------------------------------------------
  204. BOOL CEPRequestRefresh()
  205. {
  206. BOOL fResult=FALSE;
  207. DWORD dwHashIndex=0;
  208. CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry=NULL;
  209. while(g_CEPRequestTable.pTimeOld)
  210. {
  211. if(!CEPHashIsCurrentTimeEntry(&(g_CEPRequestTable.pTimeOld->TimeStamp), 0, g_dwRequestDuration))
  212. {
  213. if(!CEPHashRequest(g_CEPRequestTable.pTimeOld->pRequestEntry->pbHash, &dwHashIndex))
  214. {
  215. g_CEPRequestTable.pTimeOld->pPrevious=NULL;
  216. goto InvalidArgErr;
  217. }
  218. CEPRequestRemoveRequestEntry(g_CEPRequestTable.pTimeOld->pRequestEntry, dwHashIndex);
  219. CEPRequestFreeRequestEntry(g_CEPRequestTable.pTimeOld->pRequestEntry);
  220. pValidityEntry=g_CEPRequestTable.pTimeOld;
  221. g_CEPRequestTable.pTimeOld=g_CEPRequestTable.pTimeOld->pNext;
  222. CEPRequestFreeValidityEntry(pValidityEntry, FALSE);
  223. }
  224. else
  225. {
  226. //we find a new enough entry
  227. g_CEPRequestTable.pTimeOld->pPrevious=NULL;
  228. break;
  229. }
  230. }
  231. //we have get rid of all items
  232. if(NULL == g_CEPRequestTable.pTimeOld)
  233. {
  234. g_CEPRequestTable.pTimeNew=NULL;
  235. }
  236. fResult=TRUE;
  237. CommonReturn:
  238. return fResult;
  239. ErrorReturn:
  240. fResult=FALSE;
  241. goto CommonReturn;
  242. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  243. }
  244. //***************************************************************************
  245. //
  246. // The following are APIs called by the upper (external) layer
  247. //
  248. //
  249. //***************************************************************************
  250. //--------------------------------------------------------------------------
  251. //
  252. // InitRequestTable
  253. //
  254. //--------------------------------------------------------------------------
  255. BOOL WINAPI InitRequestTable()
  256. {
  257. DWORD cbData=0;
  258. DWORD dwData=0;
  259. DWORD dwType=0;
  260. HKEY hKey=NULL;
  261. memset(&g_CEPRequestTable, 0, sizeof(CEP_REQUEST_TABLE_INFO));
  262. g_dwRequestDuration=CEP_REQUEST_DURATION;
  263. if(ERROR_SUCCESS == RegOpenKeyExU(
  264. HKEY_LOCAL_MACHINE,
  265. MSCEP_CACHE_REQUEST_LOCATION,
  266. 0,
  267. KEY_READ,
  268. &hKey))
  269. {
  270. cbData=sizeof(dwData);
  271. if(ERROR_SUCCESS == RegQueryValueExU(
  272. hKey,
  273. MSCEP_KEY_CACHE_REQUEST,
  274. NULL,
  275. &dwType,
  276. (BYTE *)&dwData,
  277. &cbData))
  278. {
  279. if ((dwType == REG_DWORD) ||
  280. (dwType == REG_BINARY))
  281. {
  282. g_dwRequestDuration=dwData;
  283. }
  284. }
  285. }
  286. if(hKey)
  287. RegCloseKey(hKey);
  288. return TRUE;
  289. }
  290. //--------------------------------------------------------------------------
  291. //
  292. // ReleaseRequestTable
  293. //
  294. //--------------------------------------------------------------------------
  295. BOOL WINAPI ReleaseRequestTable()
  296. {
  297. CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry=NULL;
  298. if(g_CEPRequestTable.pTimeOld)
  299. {
  300. do{
  301. pValidityEntry=g_CEPRequestTable.pTimeOld;
  302. g_CEPRequestTable.pTimeOld = g_CEPRequestTable.pTimeOld->pNext;
  303. CEPRequestFreeValidityEntry(pValidityEntry, TRUE);
  304. }
  305. while(g_CEPRequestTable.pTimeOld);
  306. }
  307. memset(&g_CEPRequestTable, 0, sizeof(CEP_REQUEST_TABLE_INFO));
  308. return TRUE;
  309. }
  310. //--------------------------------------------------------------------------
  311. //
  312. // CEPRequestRetrieveRequestIDFromHash
  313. //
  314. //--------------------------------------------------------------------------
  315. BOOL WINAPI CEPRequestRetrieveRequestIDFromHash(BYTE *pbHash,
  316. DWORD *pdwRequestID)
  317. {
  318. BOOL fResult=FALSE;
  319. CEP_REQUEST_ENTRY *pRequestEntry=NULL;
  320. DWORD dwIndex=0;
  321. *pdwRequestID=0;
  322. //delete all stale requests
  323. CEPRequestRefresh();
  324. if(NULL == (pRequestEntry=CEPSearchRequest(pbHash, &dwIndex)))
  325. goto InvalidArgErr;
  326. *pdwRequestID=pRequestEntry->dwRequestID;
  327. fResult=TRUE;
  328. CommonReturn:
  329. return fResult;
  330. ErrorReturn:
  331. fResult=FALSE;
  332. goto CommonReturn;
  333. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  334. }
  335. //--------------------------------------------------------------------------
  336. //
  337. // CEPRequestAddHashAndRequestID
  338. //
  339. //--------------------------------------------------------------------------
  340. BOOL WINAPI CEPRequestAddHashAndRequestID(BYTE *pbHash,
  341. DWORD dwRequestID)
  342. {
  343. BOOL fResult=FALSE;
  344. SYSTEMTIME SystemTime;
  345. DWORD dwHashIndex=0;
  346. CEP_REQUEST_ENTRY *pRequestEntry=NULL;
  347. CEP_REQUEST_VALIDITY_ENTRY *pValidityEntry=NULL;
  348. //delete all stale requests
  349. CEPRequestRefresh();
  350. if(!CEPHashRequest(pbHash, &dwHashIndex))
  351. goto InvalidArgErr;
  352. pRequestEntry=(CEP_REQUEST_ENTRY *)malloc(sizeof(CEP_REQUEST_ENTRY));
  353. if(!pRequestEntry)
  354. goto MemoryErr;
  355. memset(pRequestEntry, 0, sizeof(CEP_REQUEST_ENTRY));
  356. pValidityEntry=(CEP_REQUEST_VALIDITY_ENTRY *)malloc(sizeof(CEP_REQUEST_VALIDITY_ENTRY));
  357. if(!pValidityEntry)
  358. goto MemoryErr;
  359. memset(pValidityEntry, 0, sizeof(CEP_REQUEST_VALIDITY_ENTRY));
  360. memcpy(pRequestEntry->pbHash, pbHash, CEP_MD5_HASH_SIZE);
  361. pRequestEntry->dwRequestID=dwRequestID;
  362. pRequestEntry->pValidityEntry=pValidityEntry;
  363. pRequestEntry->pNext=NULL;
  364. pRequestEntry->pPrevious=NULL;
  365. GetSystemTime(&SystemTime);
  366. if(!SystemTimeToFileTime(&SystemTime, &(pValidityEntry->TimeStamp)))
  367. goto TraceErr;
  368. pValidityEntry->pRequestEntry=pRequestEntry;
  369. pValidityEntry->pNext=NULL;
  370. pValidityEntry->pPrevious=NULL;
  371. CEPInsertValidityEntry(pValidityEntry);
  372. CEPInsertRequestEntry(pRequestEntry, dwHashIndex);
  373. fResult=TRUE;
  374. CommonReturn:
  375. return fResult;
  376. ErrorReturn:
  377. if(pRequestEntry)
  378. CEPRequestFreeRequestEntry(pRequestEntry);
  379. if(pValidityEntry)
  380. CEPRequestFreeValidityEntry(pValidityEntry, FALSE);
  381. fResult=FALSE;
  382. goto CommonReturn;
  383. TRACE_ERROR(TraceErr);
  384. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  385. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  386. }