Source code of Windows XP (NT5)
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.

395 lines
11 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // logresult.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the function IASRadiusLogResult.
  12. //
  13. ///////////////////////////////////////////////////////////////////////////////
  14. #include <radcommon.h>
  15. #include <iastlutl.h>
  16. #include <iasutil.h>
  17. #include <logresult.h>
  18. // Dummy attribute ID for the stringized reason code.
  19. const DWORD IAS_ATTRIBUTE_REASON_STRING = 0xBADF00D;
  20. // An empty string.
  21. WCHAR emptyString[1];
  22. // Create a newly-allocated copy of a string.
  23. PWSTR copyString(PCWSTR sz) throw ()
  24. {
  25. if (sz)
  26. {
  27. // Calculate the number of bytes.
  28. size_t nbyte = (wcslen(sz) + 1) * sizeof(WCHAR);
  29. // Allocate the memory.
  30. PVOID p = LocalAlloc(LMEM_FIXED, nbyte);
  31. if (p)
  32. {
  33. // Copy the string and return.
  34. return (PWSTR)memcpy(p, sz, nbyte);
  35. }
  36. }
  37. // If anything went wrong, return an empty string.
  38. return emptyString;
  39. }
  40. // Frees a string returned by copyString.
  41. void freeString(PWSTR sz) throw ()
  42. {
  43. if (sz != emptyString) { LocalFree(sz); }
  44. }
  45. // Format an integer value.
  46. PWSTR formatInteger(DWORD value) throw ()
  47. {
  48. WCHAR buffer[11], *p = buffer + 10;
  49. *p = L'\0';
  50. do { *--p = L'0' + (WCHAR)(value % 10); } while (value /= 10);
  51. return copyString(p);
  52. }
  53. // Format a parameter value.
  54. PWSTR formatParameter(DWORD value) throw ()
  55. {
  56. WCHAR buffer[13], *p = buffer + 12;
  57. *p = L'\0';
  58. do { *--p = L'0' + (WCHAR)(value % 10); } while (value /= 10);
  59. *--p = L'%';
  60. *--p = L'%';
  61. return copyString(p);
  62. }
  63. // Format the IAS_ATTRIBUTE_PROVIDER_TYPE value.
  64. PWSTR formatProviderType(DWORD type) throw ()
  65. {
  66. switch (type)
  67. {
  68. case IAS_PROVIDER_WINDOWS:
  69. return formatParameter(IASP_PROVIDER_WINDOWS);
  70. case IAS_PROVIDER_RADIUS_PROXY:
  71. return formatParameter(IASP_PROVIDER_RADIUS_PROXY);
  72. default:
  73. return formatParameter(IASP_NONE);
  74. }
  75. }
  76. // Format the IAS_ATTRIBUTE_AUTHENTICATION_TYPE value.
  77. PWSTR formatAuthType(DWORD type) throw ()
  78. {
  79. switch (type)
  80. {
  81. case IAS_AUTH_PAP:
  82. return copyString(L"PAP");
  83. case IAS_AUTH_MD5CHAP:
  84. return copyString(L"MD5-CHAP");
  85. case IAS_AUTH_MSCHAP:
  86. return copyString(L"MS-CHAPv1");
  87. case IAS_AUTH_MSCHAP2:
  88. return copyString(L"MS-CHAPv2");
  89. case IAS_AUTH_EAP:
  90. return copyString(L"EAP");
  91. case IAS_AUTH_ARAP:
  92. return copyString(L"ARAP");
  93. case IAS_AUTH_NONE:
  94. return copyString(L"Unauthenticated");
  95. case IAS_AUTH_CUSTOM:
  96. return copyString(L"Extension");
  97. case IAS_AUTH_MSCHAP_CPW:
  98. return copyString(L"MS-CHAPv1 CPW");
  99. case IAS_AUTH_MSCHAP2_CPW:
  100. return copyString(L"MS-CHAPv2 CPW");
  101. default:
  102. return formatInteger(type);
  103. }
  104. }
  105. // Format the NAS-Port-Type value.
  106. PWSTR formatPortType(DWORD type) throw ()
  107. {
  108. switch (type)
  109. {
  110. case 0:
  111. return copyString(L"Async");
  112. case 1:
  113. return copyString(L"Sync");
  114. case 2:
  115. return copyString(L"ISDN Sync");
  116. case 3:
  117. return copyString(L"ISDN Async V.120");
  118. case 4:
  119. return copyString(L"ISDN Async V.110");
  120. case 5:
  121. return copyString(L"Virtual");
  122. case 6:
  123. return copyString(L"PIAFS");
  124. case 7:
  125. return copyString(L"HDLC Clear Channel");
  126. case 8:
  127. return copyString(L"X.25");
  128. case 9:
  129. return copyString(L"X.75");
  130. case 10:
  131. return copyString(L"G.3 Fax");
  132. case 11:
  133. return copyString(L"SDSL");
  134. case 12:
  135. return copyString(L"ADSL-CAP");
  136. case 13:
  137. return copyString(L"ADSL-DMT");
  138. case 14:
  139. return copyString(L"IDSL");
  140. case 15:
  141. return copyString(L"Ethernet");
  142. case 16:
  143. return copyString(L"xDSL");
  144. case 17:
  145. return copyString(L"Cable");
  146. case 18:
  147. return copyString(L"Wireless - Other");
  148. case 19:
  149. return copyString(L"Wireless - IEEE 802.11");
  150. default:
  151. return formatInteger(type);
  152. }
  153. }
  154. PWSTR formatAttribute(
  155. IRequest* request,
  156. IAttributesRaw* raw,
  157. DWORD dwId,
  158. DWORD defaultValue
  159. ) throw ()
  160. {
  161. // Is this one of the 'special' attributes ?
  162. switch (dwId)
  163. {
  164. case IAS_ATTRIBUTE_REASON_CODE:
  165. {
  166. LONG reason = 0;
  167. request->get_Reason(&reason);
  168. return formatInteger(reason);
  169. }
  170. case IAS_ATTRIBUTE_REASON_STRING:
  171. {
  172. LONG reason = 0;
  173. request->get_Reason(&reason);
  174. return formatParameter(reason + 0x1000);
  175. }
  176. }
  177. // Get a single attribute with the give ID.
  178. DWORD posCount = 1;
  179. ATTRIBUTEPOSITION pos;
  180. raw->GetAttributes(&posCount, &pos, 1, &dwId);
  181. // If it's not present, use the defaultValue parameter.
  182. if (!posCount) { return formatParameter(defaultValue); }
  183. // Otherwise, save and release.
  184. const IASVALUE& val = pos.pAttribute->Value;
  185. IASAttributeRelease(pos.pAttribute);
  186. // Format the value.
  187. switch (val.itType)
  188. {
  189. case IASTYPE_ENUM:
  190. case IASTYPE_INTEGER:
  191. {
  192. switch (dwId)
  193. {
  194. case RADIUS_ATTRIBUTE_NAS_PORT_TYPE:
  195. return formatPortType(val.Enumerator);
  196. case IAS_ATTRIBUTE_PROVIDER_TYPE:
  197. return formatProviderType(val.Enumerator);
  198. case IAS_ATTRIBUTE_AUTHENTICATION_TYPE:
  199. return formatAuthType(val.Enumerator);
  200. // Fall through.
  201. }
  202. return formatInteger(val.Integer);
  203. }
  204. case IASTYPE_INET_ADDR:
  205. {
  206. WCHAR buffer[16];
  207. return copyString(ias_inet_htow(val.InetAddr, buffer));
  208. }
  209. case IASTYPE_STRING:
  210. {
  211. if (val.String.pszWide)
  212. {
  213. return copyString(val.String.pszWide);
  214. }
  215. else
  216. {
  217. USES_CONVERSION;
  218. return copyString(A2W(val.String.pszAnsi));
  219. }
  220. }
  221. case IASTYPE_OCTET_STRING:
  222. {
  223. return copyString(IAS_OCT2WIDE(val.OctetString));
  224. }
  225. }
  226. return emptyString;
  227. }
  228. ///////
  229. // An InsertionString definition consists of the attribute ID and a
  230. // defaultValue to be used if the attribute isn't present.
  231. ///////
  232. struct InsertionString
  233. {
  234. DWORD attrID;
  235. DWORD defaultValue;
  236. };
  237. // Insertion strings for an Access-Accept.
  238. InsertionString ACCEPT_ATTRS[] =
  239. {
  240. { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT },
  241. { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED },
  242. { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT },
  243. { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT },
  244. { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT },
  245. { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT },
  246. { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT },
  247. { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT },
  248. { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT },
  249. { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE },
  250. { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED },
  251. { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED },
  252. { IAS_ATTRIBUTE_NP_NAME, IASP_UNDETERMINED },
  253. { IAS_ATTRIBUTE_AUTHENTICATION_TYPE, IASP_UNDETERMINED },
  254. { IAS_ATTRIBUTE_EAP_FRIENDLY_NAME, IASP_UNDETERMINED },
  255. { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED }
  256. };
  257. // Insertion strings for an Access-Reject.
  258. InsertionString REJECT_ATTRS[] =
  259. {
  260. { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT },
  261. { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED },
  262. { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT },
  263. { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT },
  264. { RADIUS_ATTRIBUTE_CALLED_STATION_ID, IASP_NOT_PRESENT },
  265. { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT },
  266. { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT },
  267. { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT },
  268. { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT },
  269. { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT },
  270. { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE },
  271. { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED },
  272. { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED },
  273. { IAS_ATTRIBUTE_NP_NAME, IASP_UNDETERMINED },
  274. { IAS_ATTRIBUTE_AUTHENTICATION_TYPE, IASP_UNDETERMINED },
  275. { IAS_ATTRIBUTE_EAP_FRIENDLY_NAME, IASP_UNDETERMINED },
  276. { IAS_ATTRIBUTE_REASON_CODE, IASP_UNDETERMINED },
  277. { IAS_ATTRIBUTE_REASON_STRING, IASP_UNDETERMINED },
  278. { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED }
  279. };
  280. // Insertion strings for a discarded request.
  281. InsertionString DISCARD_ATTRS[] =
  282. {
  283. { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT },
  284. { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED },
  285. { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT },
  286. { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT },
  287. { RADIUS_ATTRIBUTE_CALLED_STATION_ID, IASP_NOT_PRESENT },
  288. { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT },
  289. { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT },
  290. { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT },
  291. { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT },
  292. { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT },
  293. { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE },
  294. { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED },
  295. { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED },
  296. { IAS_ATTRIBUTE_REASON_CODE, IASP_UNDETERMINED },
  297. { IAS_ATTRIBUTE_REASON_STRING, IASP_UNDETERMINED },
  298. { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED }
  299. };
  300. VOID
  301. WINAPI
  302. IASRadiusLogResult(
  303. IRequest* request,
  304. IAttributesRaw* raw
  305. )
  306. {
  307. // We only care about Access-Requests.
  308. LONG type = 0;
  309. request->get_Request(&type);
  310. if (type != IAS_REQUEST_ACCESS_REQUEST) { return; }
  311. // Determine which response type this is.
  312. request->get_Response(&type);
  313. DWORD eventID;
  314. InsertionString* attrs;
  315. switch (type)
  316. {
  317. case IAS_RESPONSE_ACCESS_ACCEPT:
  318. eventID = IAS_RESPONSE_ACCEPT;
  319. attrs = ACCEPT_ATTRS;
  320. break;
  321. case IAS_RESPONSE_ACCESS_REJECT:
  322. eventID = IAS_RESPONSE_REJECT;
  323. attrs = REJECT_ATTRS;
  324. break;
  325. case IAS_RESPONSE_DISCARD_PACKET:
  326. eventID = IAS_RESPONSE_DISCARD;
  327. attrs = DISCARD_ATTRS;
  328. break;
  329. default:
  330. return;
  331. }
  332. // Format the insertion strings.
  333. PWSTR strings[24];
  334. DWORD numStrings = 0;
  335. for ( ; attrs->attrID != ATTRIBUTE_UNDEFINED; ++attrs, ++numStrings)
  336. {
  337. strings[numStrings] = formatAttribute(
  338. request,
  339. raw,
  340. attrs->attrID,
  341. attrs->defaultValue
  342. );
  343. }
  344. // Report the event.
  345. IASReportEvent(
  346. eventID,
  347. numStrings,
  348. 0,
  349. (PCWSTR*)strings,
  350. NULL
  351. );
  352. // Free the insertion strings.
  353. while (numStrings--)
  354. {
  355. freeString(strings[numStrings]);
  356. }
  357. }