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.

413 lines
10 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. template.c
  5. Abstract:
  6. Contains common template matching code
  7. Author:
  8. BrianSw 10-19-200
  9. Environment:
  10. User Level: Win32/kernel
  11. NOTE: Since this is used by user and kernel mode, code accordingly
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. BOOL
  16. WINAPI IsAllZero(BYTE *c, DWORD dwSize)
  17. {
  18. DWORD i;
  19. for (i=0;i<dwSize;i++) {
  20. if (c[i] != 0) {
  21. return FALSE;
  22. }
  23. }
  24. return TRUE;
  25. }
  26. BOOL
  27. WINAPI CmpBlob(IPSEC_BYTE_BLOB* c1, IPSEC_BYTE_BLOB *c2)
  28. {
  29. if (c1->dwSize == 0) {
  30. return TRUE;
  31. }
  32. if (c1->dwSize != c2->dwSize) {
  33. return FALSE;
  34. }
  35. if (memcmp(c1->pBlob,c2->pBlob,c1->dwSize) == 0) {
  36. return TRUE;
  37. }
  38. return FALSE;
  39. }
  40. BOOL
  41. WINAPI CmpData(BYTE* c1, BYTE *c2, DWORD size)
  42. {
  43. if ((!IsAllZero(c1,size)) &&
  44. (memcmp(c1,c2,size) != 0)) {
  45. return FALSE;
  46. }
  47. return TRUE;
  48. }
  49. /*
  50. For comparing structs like:
  51. typedef struct _PROTOCOL {
  52. PROTOCOL_TYPE ProtocolType;
  53. DWORD dwProtocol;
  54. } PROTOCOL, * PPROTOCOL;
  55. dwTypeSize is sizeof PROTOCOL_TYPE, dwStructSize is sizeof(PROTOCOL)
  56. Assumes type info is first in struct
  57. Template symantics:
  58. Template is:
  59. All 0, everything matches
  60. Type 0, rest non-0, exact match of rest of data
  61. Type non-0, rest 0, all entries of given type
  62. Type non-0, rest non-0, exact match
  63. */
  64. BOOL
  65. WINAPI CmpTypeStruct(BYTE *Template, BYTE *comp,
  66. DWORD dwTypeSize, DWORD dwStructSize)
  67. {
  68. if (IsAllZero(Template,dwStructSize)) {
  69. return TRUE;
  70. }
  71. if (IsAllZero(Template,dwTypeSize)) {
  72. if (memcmp(Template+dwTypeSize,comp+dwTypeSize,
  73. dwStructSize-dwTypeSize) == 0) {
  74. return TRUE;
  75. }
  76. return FALSE;
  77. }
  78. // Know here that Template.TypeInfo is non-0
  79. if (memcmp(Template,comp,dwTypeSize) != 0) {
  80. return FALSE;
  81. }
  82. if (IsAllZero(Template+dwTypeSize,dwStructSize-dwTypeSize)) {
  83. return TRUE;
  84. }
  85. if (memcmp(Template+dwTypeSize,comp+dwTypeSize,dwStructSize-dwTypeSize) == 0) {
  86. return TRUE;
  87. }
  88. return FALSE;
  89. }
  90. BOOL
  91. WINAPI CmpAddr(ADDR *Template, ADDR *a2)
  92. {
  93. if (Template->AddrType == IP_ADDR_UNIQUE && Template->uIpAddr) {
  94. if (Template->uIpAddr != (a2->uIpAddr)) {
  95. return FALSE;
  96. }
  97. if (a2->AddrType != IP_ADDR_UNIQUE) {
  98. return FALSE;
  99. }
  100. }
  101. if (IsSpecialServ(Template->AddrType) &&
  102. !(Template->AddrType == a2->AddrType)) {
  103. return FALSE;
  104. }
  105. if (Template->AddrType == IP_ADDR_SUBNET && Template->uIpAddr) {
  106. if ((Template->uIpAddr & Template->uSubNetMask)
  107. != (a2->uIpAddr & Template->uSubNetMask)) {
  108. return FALSE;
  109. }
  110. // Make sure template subnet contains a2's subnet (if a2 is unique, any subnet is superset of unique filter
  111. if (a2->AddrType == IP_ADDR_SUBNET &&
  112. ((Template->uSubNetMask & a2->uSubNetMask) != Template->uSubNetMask)) {
  113. return FALSE;
  114. }
  115. }
  116. return TRUE;
  117. }
  118. BOOL
  119. WINAPI CmpFilter(IPSEC_QM_FILTER *Template, IPSEC_QM_FILTER* f2)
  120. {
  121. if (!CmpTypeStruct((BYTE*)&Template->Protocol,
  122. (BYTE*)&f2->Protocol,
  123. sizeof(PROTOCOL_TYPE),
  124. sizeof(PROTOCOL))) {
  125. return FALSE;
  126. }
  127. if (!CmpTypeStruct((BYTE*)&Template->SrcPort,
  128. (BYTE*)&f2->SrcPort,
  129. sizeof(PORT_TYPE),
  130. sizeof(PORT))) {
  131. return FALSE;
  132. }
  133. if (!CmpTypeStruct((BYTE*)&Template->DesPort,
  134. (BYTE*)&f2->DesPort,
  135. sizeof(PORT_TYPE),
  136. sizeof(PORT))) {
  137. return FALSE;
  138. }
  139. if (Template->QMFilterType) {
  140. if (Template->QMFilterType != f2->QMFilterType) {
  141. return FALSE;
  142. }
  143. }
  144. if (!CmpData((BYTE*)&Template->MyTunnelEndpt,
  145. (BYTE*)&f2->MyTunnelEndpt,
  146. sizeof(ADDR))) {
  147. return FALSE;
  148. }
  149. if (!CmpData((BYTE*)&Template->PeerTunnelEndpt,
  150. (BYTE*)&f2->PeerTunnelEndpt,
  151. sizeof(ADDR))) {
  152. return FALSE;
  153. }
  154. if (!CmpAddr(&Template->SrcAddr,&f2->SrcAddr)) {
  155. return FALSE;
  156. }
  157. if (!CmpAddr(&Template->DesAddr,&f2->DesAddr)) {
  158. return FALSE;
  159. }
  160. return TRUE;
  161. }
  162. BOOL
  163. WINAPI CmpQMAlgo(PIPSEC_QM_ALGO Template, PIPSEC_QM_ALGO a2)
  164. {
  165. if (!CmpData((BYTE*)&Template->Operation,
  166. (BYTE*)&a2->Operation,
  167. sizeof(IPSEC_OPERATION))) {
  168. return FALSE;
  169. }
  170. if (!CmpData((BYTE*)&Template->uAlgoIdentifier,
  171. (BYTE*)&a2->uAlgoIdentifier,
  172. sizeof(ULONG))) {
  173. return FALSE;
  174. }
  175. if (!CmpData((BYTE*)&Template->uSecAlgoIdentifier,
  176. (BYTE*)&a2->uSecAlgoIdentifier,
  177. sizeof(HMAC_AUTH_ALGO_ENUM))) {
  178. return FALSE;
  179. }
  180. if (!CmpData((BYTE*)&Template->MySpi,
  181. (BYTE*)&a2->MySpi,
  182. sizeof(IPSEC_QM_SPI))) {
  183. return FALSE;
  184. }
  185. if (!CmpData((BYTE*)&Template->PeerSpi,
  186. (BYTE*)&a2->PeerSpi,
  187. sizeof(IPSEC_QM_SPI))) {
  188. return FALSE;
  189. }
  190. return TRUE;
  191. }
  192. BOOL
  193. WINAPI CmpQMOffer(PIPSEC_QM_OFFER Template, PIPSEC_QM_OFFER o2)
  194. {
  195. DWORD i;
  196. if (!CmpData((BYTE*)&Template->Lifetime,
  197. (BYTE*)&o2->Lifetime,
  198. sizeof(KEY_LIFETIME))) {
  199. return FALSE;
  200. }
  201. if (Template->bPFSRequired) {
  202. if (Template->bPFSRequired != o2->bPFSRequired) {
  203. return FALSE;
  204. }
  205. }
  206. if (Template->dwPFSGroup) {
  207. if (Template->dwPFSGroup != o2->dwPFSGroup) {
  208. return FALSE;
  209. }
  210. }
  211. if (Template->dwNumAlgos) {
  212. if (Template->dwNumAlgos != o2->dwNumAlgos) {
  213. return FALSE;
  214. }
  215. for (i=0; i < Template->dwNumAlgos; i++) {
  216. if (!CmpQMAlgo(&Template->Algos[i],
  217. &o2->Algos[i])) {
  218. return FALSE;
  219. }
  220. }
  221. }
  222. return TRUE;
  223. }
  224. /*
  225. True if this NotifyListEntry Template matches the CurInfo
  226. */
  227. BOOL
  228. WINAPI MatchQMSATemplate(IPSEC_QM_SA *Template,IPSEC_QM_SA *CurInfo)
  229. {
  230. if (Template == NULL) {
  231. return TRUE;
  232. }
  233. if (!CmpFilter(&Template->IpsecQMFilter,
  234. &CurInfo->IpsecQMFilter)) {
  235. return FALSE;
  236. }
  237. if (!CmpData((BYTE*)&Template->MMSpi.Initiator,
  238. (BYTE*)&CurInfo->MMSpi.Initiator,sizeof(IKE_COOKIE))) {
  239. return FALSE;
  240. }
  241. if (!CmpData((BYTE*)&Template->MMSpi.Responder,
  242. (BYTE*)&CurInfo->MMSpi.Responder,sizeof(IKE_COOKIE))) {
  243. return FALSE;
  244. }
  245. if (!CmpData((BYTE*)&Template->gQMPolicyID,
  246. (BYTE*)&CurInfo->gQMPolicyID,sizeof(GUID))) {
  247. return FALSE;
  248. }
  249. if (!CmpQMOffer(&Template->SelectedQMOffer,
  250. &CurInfo->SelectedQMOffer)) {
  251. return FALSE;
  252. }
  253. if (!CmpData((BYTE*)&Template->EncapInfo.SAEncapType,
  254. (BYTE*)&CurInfo->EncapInfo.SAEncapType,
  255. sizeof(IPSEC_SA_UDP_ENCAP_TYPE))) {
  256. return FALSE;
  257. }
  258. if (!CmpData((BYTE*)&Template->EncapInfo.UdpEncapContext,
  259. (BYTE*)&CurInfo->EncapInfo.UdpEncapContext,
  260. sizeof(IPSEC_UDP_ENCAP_CONTEXT))) {
  261. return FALSE;
  262. }
  263. if (!CmpAddr(&Template->EncapInfo.PeerPrivateAddr,&CurInfo->EncapInfo.PeerPrivateAddr)) {
  264. return FALSE;
  265. }
  266. return TRUE;
  267. }
  268. BOOL
  269. WINAPI MatchMMSATemplate(IPSEC_MM_SA *MMTemplate, IPSEC_MM_SA *SaData)
  270. {
  271. if (MMTemplate == NULL) {
  272. return TRUE;
  273. }
  274. if (!CmpData((BYTE*)&MMTemplate->gMMPolicyID,
  275. (BYTE*)&SaData->gMMPolicyID,sizeof(GUID))) {
  276. return FALSE;
  277. }
  278. if (!CmpData((BYTE*)&MMTemplate->MMSpi.Initiator,
  279. (BYTE*)&SaData->MMSpi.Initiator,sizeof(COOKIE))) {
  280. return FALSE;
  281. }
  282. if (!CmpData((BYTE*)&MMTemplate->MMSpi.Responder,
  283. (BYTE*)&SaData->MMSpi.Responder,sizeof(COOKIE))) {
  284. return FALSE;
  285. }
  286. if (!CmpAddr(&MMTemplate->Me,&SaData->Me)) {
  287. return FALSE;
  288. }
  289. if (!CmpAddr(&MMTemplate->Peer,&SaData->Peer)) {
  290. return FALSE;
  291. }
  292. if (!CmpData((BYTE*)&MMTemplate->SelectedMMOffer.EncryptionAlgorithm,(BYTE*)&SaData->SelectedMMOffer.EncryptionAlgorithm,sizeof(IPSEC_MM_ALGO))) {
  293. return FALSE;
  294. }
  295. if (!CmpData((BYTE*)&MMTemplate->SelectedMMOffer.HashingAlgorithm,(BYTE*)&SaData->SelectedMMOffer.HashingAlgorithm,sizeof(IPSEC_MM_ALGO))) {
  296. return FALSE;
  297. }
  298. if (!CmpData((BYTE*)&MMTemplate->SelectedMMOffer.dwDHGroup,(BYTE*)&SaData->SelectedMMOffer.dwDHGroup,sizeof(DWORD))) {
  299. return FALSE;
  300. }
  301. if (!CmpData((BYTE*)&MMTemplate->SelectedMMOffer.Lifetime,(BYTE*)&SaData->SelectedMMOffer.Lifetime,sizeof(KEY_LIFETIME))) {
  302. return FALSE;
  303. }
  304. if (!CmpData((BYTE*)&MMTemplate->SelectedMMOffer.dwQuickModeLimit,(BYTE*)&SaData->SelectedMMOffer.dwQuickModeLimit,sizeof(DWORD))) {
  305. return FALSE;
  306. }
  307. if (!CmpBlob(&MMTemplate->MyId,&SaData->MyId)) {
  308. return FALSE;
  309. }
  310. if (!CmpBlob(&MMTemplate->PeerId,&SaData->PeerId)) {
  311. return FALSE;
  312. }
  313. if (!CmpBlob(&MMTemplate->MyCertificateChain,&SaData->MyCertificateChain)) {
  314. return FALSE;
  315. }
  316. if (!CmpBlob(&MMTemplate->PeerCertificateChain,&SaData->PeerCertificateChain)) {
  317. return FALSE;
  318. }
  319. //
  320. // TBD - Add UDP encapsulation context comparison later on.
  321. //
  322. return TRUE;
  323. }