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.

406 lines
10 KiB

  1. // Copyright (c) 1997, Microsoft Corporation, all rights reserved
  2. //
  3. // eapcfg.c
  4. // EAP package utility library
  5. //
  6. // These utility routines wrap the third-party EAP authentication
  7. // configuration information written to the registry by third-party EAP
  8. // security package providers.
  9. //
  10. // 11/25/97 Steve Cobb
  11. //
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include <debug.h>
  15. #include <nouiutil.h>
  16. #include <raseapif.h>
  17. #include <ole2.h>
  18. // EAP configuration registry definitions.
  19. //
  20. #define REGKEY_Eap TEXT("System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP")
  21. #define REGVAL_szFriendlyName TEXT("FriendlyName")
  22. #define REGVAL_szConfigDll TEXT("ConfigUIPath")
  23. #define REGVAL_szIdentityDll TEXT("IdentityPath")
  24. #define REGVAL_fRequirePwd TEXT("InvokePasswordDialog")
  25. #define REGVAL_fRequireUser TEXT("InvokeUsernameDialog")
  26. #define REGVAL_pData TEXT("ConfigData")
  27. #define REGVAL_fForceConfig TEXT("RequireConfigUI")
  28. #define REGVAL_fMppeSupported TEXT("MPPEEncryptionSupported")
  29. //
  30. // HACKY Key not to display PEAP and Eapmschapv2 type in here
  31. //
  32. #define REGVAL_fHidePEAPMSChapv2 TEXT("HidePEAPMSChapv2")
  33. #define EAPTYPE_PEAP "25"
  34. #define EAPTYPE_EAPMSCHAPv2 "26"
  35. //-----------------------------------------------------------------------------
  36. // EAP configuration utilitiy routines (alphabetically)
  37. //-----------------------------------------------------------------------------
  38. DTLNODE*
  39. CreateEapcfgNode(
  40. void )
  41. // Returns a created, empty EAPCFG descriptor node, or NULL on error.
  42. //
  43. {
  44. DTLNODE* pNode;
  45. EAPCFG* pEapcfg;
  46. pNode = DtlCreateSizedNode( sizeof(EAPCFG), 0L );
  47. if (pNode)
  48. {
  49. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  50. ASSERT( pEapcfg );
  51. pEapcfg->dwKey = (DWORD )-1;
  52. pEapcfg->pszConfigDll = NULL;
  53. pEapcfg->pszIdentityDll = NULL;
  54. pEapcfg->dwStdCredentialFlags = 0;
  55. pEapcfg->fProvidesMppeKeys = FALSE;
  56. pEapcfg->fForceConfig = FALSE;
  57. pEapcfg->pData = NULL;
  58. pEapcfg->cbData = 0;
  59. pEapcfg->fConfigDllCalled = FALSE;
  60. }
  61. return pNode;
  62. }
  63. VOID
  64. DestroyEapcfgNode(
  65. IN OUT DTLNODE* pNode )
  66. // Release resources associated with EAPCFG node 'pNode'. See
  67. // DtlDestroyList.
  68. //
  69. {
  70. EAPCFG* pEapcfg;
  71. ASSERT( pNode );
  72. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  73. ASSERT( pEapcfg );
  74. Free0( pEapcfg->pszConfigDll );
  75. Free0( pEapcfg->pszIdentityDll );
  76. Free0( pEapcfg->pData );
  77. DtlDestroyNode( pNode );
  78. }
  79. DTLNODE*
  80. EapcfgNodeFromKey(
  81. IN DTLLIST* pList,
  82. IN DWORD dwKey )
  83. // Returns the EAPCFG node in list 'pList' with EAP key value of 'dwKey'
  84. // or NULL if not found.
  85. //
  86. {
  87. DTLNODE* pNode;
  88. for (pNode = DtlGetFirstNode( pList );
  89. pNode;
  90. pNode = DtlGetNextNode( pNode ))
  91. {
  92. EAPCFG* pEapcfg = (EAPCFG* )DtlGetData( pNode );
  93. ASSERT( pEapcfg );
  94. if (pEapcfg->dwKey == dwKey)
  95. {
  96. return pNode;
  97. }
  98. }
  99. return NULL;
  100. }
  101. //
  102. // Will tell us if there is a need to cripple PEAP
  103. // - if true is retured, we dont show PEAP and eapmschapv2
  104. // in the list.
  105. BOOL
  106. IsRasDlgPeapCrippled(HKEY hkeyEap)
  107. {
  108. BOOL fRetCode = FALSE;
  109. DWORD dwRetCode = NO_ERROR;
  110. DWORD dwValue = 0;
  111. DWORD dwType = 0;
  112. DWORD cbValueDataSize = sizeof(DWORD);
  113. dwRetCode = RegQueryValueEx(
  114. hkeyEap,
  115. REGVAL_fHidePEAPMSChapv2,
  116. NULL,
  117. &dwType,
  118. (PBYTE)&dwValue,
  119. &cbValueDataSize );
  120. if ( dwRetCode != NO_ERROR )
  121. {
  122. goto LDone;
  123. }
  124. if ( dwValue != 0 )
  125. {
  126. fRetCode = TRUE;
  127. }
  128. LDone:
  129. return fRetCode;
  130. }
  131. DTLLIST*
  132. ReadEapcfgList(
  133. IN TCHAR* pszMachine )
  134. // Returns the address of a created list of installed custom
  135. // authentication packages or NULL if none could be read. On success, it
  136. // is caller's responsibility to eventually call DtlDestroyList on the
  137. // returned list.
  138. //
  139. {
  140. DWORD dwErr;
  141. BOOL fOk = FALSE;
  142. DTLLIST* pList;
  143. DTLNODE* pNode;
  144. EAPCFG* pEapcfg;
  145. HKEY hkeyLM = NULL;
  146. HKEY hkeyEap = NULL;
  147. HKEY hkeyPackage = NULL;
  148. CHAR szEapType[ 11 + 1 ];
  149. TCHAR* psz;
  150. DWORD dw;
  151. DWORD cb;
  152. INT i;
  153. TCHAR* szCLSID;
  154. HRESULT hr;
  155. BOOL fRasDlgPeapCrippled = FALSE;
  156. pList = DtlCreateList( 0L );
  157. if (!pList)
  158. {
  159. return NULL;
  160. }
  161. // Open the EAP key which contains a sub-key for each installed package.
  162. //
  163. dwErr = RegConnectRegistry( pszMachine, HKEY_LOCAL_MACHINE, &hkeyLM );
  164. if (dwErr != 0 || !hkeyLM)
  165. {
  166. return pList;
  167. }
  168. dwErr = RegOpenKeyEx(
  169. hkeyLM, (LPCTSTR )REGKEY_Eap, 0, KEY_READ, &hkeyEap );
  170. RegCloseKey( hkeyLM );
  171. if (dwErr != 0)
  172. {
  173. return pList;
  174. }
  175. fRasDlgPeapCrippled = IsRasDlgPeapCrippled ( hkeyEap );
  176. // Open each sub-key and extract the package definition from it's values.
  177. // Problems with opening individual sub-keys result in that node only
  178. // being discarded.
  179. //
  180. for (i = 0; TRUE; ++i)
  181. {
  182. cb = sizeof(szEapType);
  183. dwErr = RegEnumKeyExA(
  184. hkeyEap, i, szEapType, &cb, NULL, NULL, NULL, NULL );
  185. if (dwErr != 0)
  186. {
  187. // Includes "out of items", the normal loop termination.
  188. //
  189. break;
  190. }
  191. dwErr = RegOpenKeyExA(
  192. hkeyEap, szEapType, 0, KEY_READ, &hkeyPackage );
  193. if (dwErr != 0)
  194. {
  195. continue;
  196. }
  197. // For whistler bug 442519 and 442458 gangz
  198. // For LEAP, a RolesSupported DWORD will be added, if it is set to 2,
  199. // then we wont show it on the client side
  200. {
  201. DWORD dwRolesSupported = 0;
  202. GetRegDword( hkeyPackage,
  203. RAS_EAP_VALUENAME_ROLES_SUPPORTED,
  204. &dwRolesSupported);
  205. // This values is not configured, or equals 0 or 1, then go ahead
  206. // and show it, or else wont show it
  207. // 0 means can be either Authenticator or Authenticatee
  208. // 1 means can ONLY be Authenticator, for LEAP, it is 1
  209. // 2 means can ONLY be Authenticatee
  210. if ( 0 != dwRolesSupported )
  211. {
  212. if ( !(RAS_EAP_ROLE_AUTHENTICATEE & dwRolesSupported ) )
  213. {
  214. continue;
  215. }
  216. if ( RAS_EAP_ROLE_EXCLUDE_IN_EAP & dwRolesSupported )
  217. {
  218. continue;
  219. }
  220. if ( RAS_EAP_ROLE_EXCLUDE_IN_VPN & dwRolesSupported )
  221. {
  222. continue;
  223. }
  224. }
  225. }
  226. do
  227. {
  228. pNode = CreateEapcfgNode();
  229. if (!pNode)
  230. {
  231. break;
  232. }
  233. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  234. ASSERT( pEapcfg );
  235. // EAP type ID.
  236. //
  237. pEapcfg->dwKey = (LONG )atol( szEapType );
  238. // Friendly display name.
  239. //
  240. psz = NULL;
  241. dwErr = GetRegSz( hkeyPackage, REGVAL_szFriendlyName, &psz );
  242. if (dwErr != 0)
  243. {
  244. break;
  245. }
  246. if (!*psz)
  247. {
  248. Free( psz );
  249. psz = StrDupTFromA( szEapType );
  250. if (!psz)
  251. {
  252. break;
  253. }
  254. }
  255. pEapcfg->pszFriendlyName = psz;
  256. // Configuration DLL path.
  257. //
  258. psz = NULL;
  259. dwErr = GetRegExpandSz( hkeyPackage, REGVAL_szConfigDll, &psz );
  260. if (dwErr != 0)
  261. {
  262. break;
  263. }
  264. if (*psz)
  265. {
  266. pEapcfg->pszConfigDll = psz;
  267. }
  268. else
  269. {
  270. Free( psz );
  271. }
  272. // Identity DLL path.
  273. //
  274. psz = NULL;
  275. dwErr = GetRegExpandSz( hkeyPackage, REGVAL_szIdentityDll, &psz );
  276. if (dwErr != 0)
  277. {
  278. break;
  279. }
  280. if (*psz)
  281. {
  282. pEapcfg->pszIdentityDll = psz;
  283. }
  284. else
  285. {
  286. Free( psz );
  287. }
  288. // Prompt user name
  289. //
  290. dw = 1;
  291. GetRegDword( hkeyPackage, REGVAL_fRequireUser, &dw );
  292. if (dw)
  293. pEapcfg->dwStdCredentialFlags |= EAPCFG_FLAG_RequireUsername;
  294. // Prompt password
  295. //
  296. dw = 0;
  297. GetRegDword( hkeyPackage, REGVAL_fRequirePwd, &dw );
  298. if (dw)
  299. pEapcfg->dwStdCredentialFlags |= EAPCFG_FLAG_RequirePassword;
  300. // MPPE encryption keys flag.
  301. //
  302. dw = 0;
  303. GetRegDword( hkeyPackage, REGVAL_fMppeSupported, &dw );
  304. pEapcfg->fProvidesMppeKeys = !!dw;
  305. // Force configuration API to run at least once.
  306. //
  307. dw = FALSE;
  308. GetRegDword( hkeyPackage, REGVAL_fForceConfig, &dw );
  309. pEapcfg->fForceConfig = !!dw;
  310. // Configuration blob.
  311. //
  312. GetRegBinary(
  313. hkeyPackage, REGVAL_pData,
  314. &pEapcfg->pData, &pEapcfg->cbData );
  315. // ConfigCLSID
  316. //
  317. dwErr = GetRegSz( hkeyPackage, RAS_EAP_VALUENAME_CONFIG_CLSID,
  318. &szCLSID );
  319. if (dwErr != 0)
  320. {
  321. break;
  322. }
  323. // Ignore errors. Eg. EAP MD5-Challenge does not have a ConfigCLSID.
  324. //
  325. hr = CLSIDFromString( szCLSID, &( pEapcfg->guidConfigCLSID ) );
  326. Free( szCLSID );
  327. // Add the completed node to the list.
  328. //
  329. DtlAddNodeLast( pList, pNode );
  330. fOk = TRUE;
  331. }
  332. while (FALSE);
  333. if (!fOk && pNode)
  334. {
  335. DestroyEapcfgNode( pNode );
  336. }
  337. RegCloseKey( hkeyPackage );
  338. }
  339. RegCloseKey( hkeyEap );
  340. return pList;
  341. }