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.

588 lines
14 KiB

  1. /* Copyright (c) 1992, Microsoft Corporation, all rights reserved
  2. **
  3. ** util.c
  4. ** Remote Access External APIs
  5. ** Utility routines
  6. **
  7. ** 10/12/92 Steve Cobb
  8. */
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <debug.h> // Trace and assert
  17. #include <rasman.h>
  18. #include <rasapip.h>
  19. #include <pbk.h>
  20. #define EAP_CUSTOM_KEY 0x43424431
  21. typedef struct _EAP_CUSTOM_DATA
  22. {
  23. DWORD dwSignature;
  24. DWORD dwCustomAuthKey;
  25. DWORD dwSize;
  26. BYTE abdata[1];
  27. } EAP_CUSTOM_DATA;
  28. BOOL IsRouterPhonebook(LPCTSTR pszPhonebook)
  29. {
  30. const TCHAR *psz;
  31. BOOL fRouter = FALSE;
  32. if(NULL == pszPhonebook)
  33. {
  34. goto done;
  35. }
  36. psz = pszPhonebook + lstrlen(pszPhonebook);
  37. //
  38. // Seek back to the beginning of the filename
  39. //
  40. while(psz != pszPhonebook)
  41. {
  42. if(TEXT('\\') == *psz)
  43. {
  44. break;
  45. }
  46. psz--;
  47. }
  48. if(TEXT('\\') == *psz)
  49. {
  50. psz += 1;
  51. }
  52. TRACE1("IsRouterPhonebook: pbk=%ws", psz);
  53. //For whistler 524726
  54. fRouter = ( CSTR_EQUAL == CompareString(
  55. LOCALE_INVARIANT,
  56. NORM_IGNORECASE,
  57. TEXT("router.pbk"),
  58. -1,
  59. psz,
  60. -1
  61. )
  62. );
  63. done:
  64. return fRouter;
  65. }
  66. BOOL
  67. DwIsDefaultConnection(
  68. IN PWCHAR pszEntryName)
  69. {
  70. DWORD dwErr = NO_ERROR, dwCb = 0, dwCount = 1;
  71. RASAUTODIALENTRYW adEntry;
  72. INT iCmp;
  73. // Validate parameters
  74. //
  75. if (!pszEntryName)
  76. {
  77. return FALSE;
  78. }
  79. // Initialze
  80. //
  81. ZeroMemory(&adEntry, sizeof(adEntry));
  82. dwCb = adEntry.dwSize = sizeof(adEntry);
  83. dwErr = RasGetAutodialAddressW(
  84. NULL,
  85. NULL,
  86. &adEntry,
  87. &dwCb,
  88. &dwCount);
  89. if (dwErr != NO_ERROR)
  90. {
  91. return FALSE;
  92. }
  93. iCmp = _wcsnicmp(
  94. adEntry.szEntry,
  95. pszEntryName,
  96. sizeof(adEntry.szEntry) / sizeof(WCHAR));
  97. return (0 == iCmp);
  98. }
  99. DWORD
  100. DwPbentryToDetails(
  101. IN PBENTRY* pEntry,
  102. IN LPCWSTR pszPhonebookPath,
  103. IN BOOL fIsAllUsersPbk,
  104. OUT RASENUMENTRYDETAILS* pDetails)
  105. {
  106. DWORD dwErr = NO_ERROR;
  107. DTLNODE *pdtlnode;
  108. PBLINK *pLink;
  109. pDetails->dwSize = sizeof(RASENUMENTRYDETAILS);
  110. pDetails->dwType = pEntry->dwType;
  111. pDetails->fShowMonitorIconInTaskBar =
  112. pEntry->fShowMonitorIconInTaskBar;
  113. if(pEntry->pGuid)
  114. {
  115. pDetails->guidId = *pEntry->pGuid;
  116. }
  117. //For .Net 587396
  118. lstrcpynW(pDetails->szEntryName,
  119. pEntry->pszEntryName,
  120. RASAPIP_MAX_ENTRY_NAME+1);
  121. pDetails->dwFlags = (fIsAllUsersPbk) ? REN_AllUsers : REN_User;
  122. if(pszPhonebookPath)
  123. {
  124. lstrcpynW(pDetails->szPhonebookPath,
  125. pszPhonebookPath,
  126. MAX_PATH + 1);
  127. }
  128. else
  129. {
  130. pDetails->szPhonebookPath[0] = L'\0';
  131. }
  132. //
  133. // Get the devicename associated with the first
  134. // link in the list of entries associated with
  135. // this entry
  136. //
  137. pDetails->szDeviceName[0] = TEXT('\0');
  138. pDetails->szPhoneNumber[0] = TEXT('\0');
  139. pdtlnode = (DTLNODE *)
  140. DtlGetFirstNode(pEntry->pdtllistLinks);
  141. if(pdtlnode)
  142. {
  143. pLink = (PBLINK *) DtlGetData(pdtlnode);
  144. if( (NULL != pLink)
  145. && (pLink->pbport.pszDevice))
  146. {
  147. pDetails->rdt = RdtFromPbdt(
  148. pLink->pbport.pbdevicetype,
  149. pLink->pbport.dwFlags);
  150. if(RAS_DEVICE_CLASS(pDetails->rdt) == RDT_Tunnel)
  151. {
  152. (void) DwGetVpnDeviceName(
  153. pEntry->dwVpnStrategy,
  154. pLink->pbport.pszDevice,
  155. pDetails->szDeviceName);
  156. }
  157. else
  158. {
  159. lstrcpy(pDetails->szDeviceName,
  160. pLink->pbport.pszDevice);
  161. }
  162. }
  163. // XP 351412
  164. //
  165. // Populate the phone number as well
  166. //
  167. if( (NULL != pLink)
  168. && (pLink->pdtllistPhones))
  169. {
  170. DTLNODE* pnodeNum = DtlGetFirstNode(pLink->pdtllistPhones);
  171. PBPHONE* pPhone = NULL;
  172. if (NULL != pnodeNum)
  173. {
  174. pPhone = DtlGetData(pnodeNum);
  175. if ((NULL != pPhone) && (NULL != pPhone->pszPhoneNumber))
  176. {
  177. lstrcpyn(
  178. pDetails->szPhoneNumber,
  179. pPhone->pszPhoneNumber,
  180. RAS_MaxPhoneNumber);
  181. }
  182. }
  183. }
  184. }
  185. // Mark whether this is the default connection
  186. // XP 286752
  187. //
  188. if (DwIsDefaultConnection(pEntry->pszEntryName))
  189. {
  190. pDetails->dwFlagsPriv |= REED_F_Default;
  191. }
  192. return dwErr;
  193. }
  194. DWORD
  195. DwSendRasNotification(
  196. IN RASEVENTTYPE Type,
  197. IN PBENTRY* pEntry,
  198. IN LPCTSTR pszPhonebookPath,
  199. IN HANDLE hData) // Extra Type-specific info
  200. {
  201. RASEVENT RasEvent;
  202. DWORD dwErr = ERROR_SUCCESS;
  203. ZeroMemory((PBYTE) &RasEvent, sizeof(RASEVENT));
  204. RasEvent.Type = Type;
  205. //
  206. // Ignore the notification if this is a router interface
  207. //
  208. if(IsRouterPhonebook(pszPhonebookPath))
  209. {
  210. goto done;
  211. }
  212. switch(Type)
  213. {
  214. case ENTRY_ADDED:
  215. case ENTRY_MODIFIED:
  216. case ENTRY_AUTODIAL:
  217. {
  218. BOOL fAllUsers = TRUE;
  219. if (NULL != pszPhonebookPath)
  220. {
  221. fAllUsers = IsPublicPhonebook(pszPhonebookPath);
  222. }
  223. DwPbentryToDetails(
  224. pEntry,
  225. pszPhonebookPath,
  226. fAllUsers,
  227. &(RasEvent.Details)
  228. );
  229. break;
  230. }
  231. case ENTRY_DELETED:
  232. case ENTRY_RENAMED:
  233. {
  234. if(NULL != pEntry->pGuid)
  235. {
  236. RasEvent.guidId = *pEntry->pGuid;
  237. }
  238. if(ENTRY_RENAMED == Type)
  239. {
  240. lstrcpy(RasEvent.pszwNewName,
  241. pEntry->pszEntryName);
  242. }
  243. break;
  244. }
  245. default:
  246. {
  247. #if DBG
  248. ASSERT(FALSE);
  249. #endif
  250. goto done;
  251. }
  252. }
  253. dwErr = RasSendNotification(&RasEvent);
  254. done:
  255. return dwErr;
  256. }
  257. DWORD
  258. DwGetCustomAuthData(PBENTRY *pEntry,
  259. DWORD *pcbCustomAuthData,
  260. PBYTE *ppCustomAuthData)
  261. {
  262. DWORD retcode = SUCCESS;
  263. DWORD cbOffset = 0;
  264. EAP_CUSTOM_DATA *pCustomData = NULL;
  265. ASSERT(NULL != pcbCustomAuthData);
  266. ASSERT(NULL != ppCustomAuthData);
  267. ASSERT(NULL != pEntry);
  268. *pcbCustomAuthData = 0;
  269. *ppCustomAuthData = NULL;
  270. //
  271. // first check to see if we understand the format of the
  272. // eap blob stored in the phonebook
  273. //
  274. if(NULL == pEntry->pCustomAuthData)
  275. {
  276. goto done;
  277. }
  278. if( (sizeof(DWORD) > pEntry->cbCustomAuthData)
  279. || ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
  280. {
  281. Free(pEntry->pCustomAuthData);
  282. pEntry->pCustomAuthData = NULL;
  283. pEntry->cbCustomAuthData = 0;
  284. goto done;
  285. }
  286. //
  287. // Loop through the blob and return the blob corresponding
  288. // to the eap type of the entry
  289. //
  290. while(cbOffset < pEntry->cbCustomAuthData)
  291. {
  292. pCustomData = (EAP_CUSTOM_DATA *)
  293. ((PBYTE) pEntry->pCustomAuthData + cbOffset);
  294. if( (sizeof(DWORD) > (pEntry->cbCustomAuthData - cbOffset))
  295. || ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
  296. {
  297. //
  298. // The data is corrupt. Blow away the data.
  299. // should we return an error?
  300. //
  301. Free(pEntry->pCustomAuthData);
  302. pEntry->pCustomAuthData = NULL;
  303. pEntry->cbCustomAuthData = 0;
  304. TRACE("GetCustomAuthdata: data is corrupt");
  305. goto done;
  306. }
  307. if(pCustomData->dwCustomAuthKey == pEntry->dwCustomAuthKey)
  308. {
  309. break;
  310. }
  311. cbOffset += sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize;
  312. }
  313. if(cbOffset < pEntry->cbCustomAuthData)
  314. {
  315. *pcbCustomAuthData = pCustomData->dwSize;
  316. *ppCustomAuthData = pCustomData->abdata;
  317. }
  318. done:
  319. return retcode;
  320. }
  321. DWORD
  322. DwSetCustomAuthData(PBENTRY *pEntry,
  323. DWORD cbCustomAuthData,
  324. PBYTE pCustomAuthData)
  325. {
  326. DWORD retcode = SUCCESS;
  327. DWORD cbOffset = 0;
  328. EAP_CUSTOM_DATA *pCustomData = NULL;
  329. DWORD dwSize;
  330. PBYTE pNewCustomAuthData;
  331. ASSERT(NULL != pEntry);
  332. if(NULL != pEntry->pCustomAuthData)
  333. {
  334. if( (sizeof(DWORD) > pEntry->cbCustomAuthData)
  335. || ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
  336. {
  337. Free(pEntry->pCustomAuthData);
  338. pEntry->pCustomAuthData = NULL;
  339. pEntry->cbCustomAuthData = 0;
  340. }
  341. }
  342. //
  343. // Find the old Eap Data
  344. //
  345. while(cbOffset < pEntry->cbCustomAuthData)
  346. {
  347. pCustomData = (EAP_CUSTOM_DATA *)
  348. ((PBYTE)pEntry->pCustomAuthData + cbOffset);
  349. if( (sizeof(DWORD) > (pEntry->cbCustomAuthData - cbOffset))
  350. || ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
  351. {
  352. //
  353. // The data is corrupt. Blow away the data.
  354. // should we return an error?
  355. //
  356. Free(pEntry->pCustomAuthData);
  357. pEntry->pCustomAuthData = NULL;
  358. pEntry->cbCustomAuthData = 0;
  359. TRACE("SetCustomAuthData: data is corrupt!");
  360. break;
  361. }
  362. if(pCustomData->dwCustomAuthKey == pEntry->dwCustomAuthKey)
  363. {
  364. break;
  365. }
  366. cbOffset += (sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize);
  367. }
  368. //
  369. // Prefast warning
  370. //
  371. if( (NULL != pCustomData)
  372. && (cbOffset < pEntry->cbCustomAuthData))
  373. {
  374. dwSize = sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize;
  375. ASSERT(pEntry->cbCustomAuthData >= (cbOffset + dwSize));
  376. MoveMemory(pEntry->pCustomAuthData + cbOffset,
  377. pEntry->pCustomAuthData
  378. + cbOffset + dwSize,
  379. pEntry->cbCustomAuthData - cbOffset - dwSize);
  380. pEntry->cbCustomAuthData -= dwSize;
  381. }
  382. if(0 == pEntry->cbCustomAuthData)
  383. {
  384. Free0(pEntry->pCustomAuthData);
  385. pEntry->pCustomAuthData = NULL;
  386. }
  387. if( (0 == cbCustomAuthData)
  388. || (NULL == pCustomAuthData))
  389. {
  390. goto done;
  391. }
  392. dwSize = cbCustomAuthData
  393. + pEntry->cbCustomAuthData
  394. + sizeof(EAP_CUSTOM_DATA);
  395. pNewCustomAuthData = Malloc(dwSize);
  396. if(NULL == pNewCustomAuthData)
  397. {
  398. retcode = E_OUTOFMEMORY;
  399. goto done;
  400. }
  401. ZeroMemory(pNewCustomAuthData, dwSize);
  402. CopyMemory(pNewCustomAuthData,
  403. pEntry->pCustomAuthData,
  404. pEntry->cbCustomAuthData);
  405. pCustomData = (EAP_CUSTOM_DATA *) (pNewCustomAuthData
  406. + pEntry->cbCustomAuthData);
  407. pCustomData->dwSignature = EAP_CUSTOM_KEY;
  408. pCustomData->dwCustomAuthKey = pEntry->dwCustomAuthKey;
  409. pCustomData->dwSize = cbCustomAuthData;
  410. CopyMemory(pCustomData->abdata,
  411. pCustomAuthData,
  412. cbCustomAuthData);
  413. pEntry->cbCustomAuthData = dwSize;
  414. if(NULL != pEntry->pCustomAuthData)
  415. {
  416. Free(pEntry->pCustomAuthData);
  417. }
  418. pEntry->pCustomAuthData = pNewCustomAuthData;
  419. done:
  420. return retcode;
  421. }
  422. DWORD
  423. DwGetVpnDeviceName(
  424. DWORD dwVpnStrategy,
  425. WCHAR *pszDeviceDefault,
  426. WCHAR *pszDeviceName)
  427. {
  428. DWORD dwErr = ERROR_SUCCESS, dwType;
  429. CHAR szDeviceName[MAX_DEVICE_NAME];
  430. // Figure out the device name we're interested in
  431. // discovering.
  432. //
  433. dwType = RDT_Tunnel_L2tp;
  434. switch (dwVpnStrategy)
  435. {
  436. case VS_Default:
  437. case VS_L2tpFirst:
  438. case VS_L2tpOnly:
  439. dwType = RDT_Tunnel_L2tp;
  440. break;
  441. case VS_PptpFirst:
  442. case VS_PptpOnly:
  443. dwType = RDT_Tunnel_Pptp;
  444. break;
  445. }
  446. TRACE1("RasGetDeviceName(rdt=%d)...", dwType);
  447. dwErr = RasGetDeviceNameW(
  448. dwType,
  449. pszDeviceName);
  450. TRACE1("RasGetDeviceName. 0x%x", dwErr);
  451. if(ERROR_SUCCESS != dwErr)
  452. {
  453. dwErr = ERROR_SUCCESS;
  454. // We can't determine from rasman -- use the phonebook
  455. // value if possible
  456. //
  457. if (NULL != pszDeviceDefault)
  458. {
  459. lstrcpyn(
  460. pszDeviceName,
  461. pszDeviceDefault,
  462. RASAPIP_MAX_DEVICE_NAME);
  463. }
  464. }
  465. return dwErr;
  466. }
  467. BOOL
  468. IsServerOS ( )
  469. {
  470. BOOL fServerOS = TRUE; //Default
  471. //Check to see if the OS is server - Data Center, Server, Advanced Server
  472. OSVERSIONINFOEX stOsvEx;
  473. ZeroMemory( &stOsvEx, sizeof(stOsvEx) );
  474. stOsvEx.dwOSVersionInfoSize = sizeof(stOsvEx);
  475. GetVersionEx((LPOSVERSIONINFO)&stOsvEx);
  476. if ( stOsvEx.wProductType == VER_NT_WORKSTATION )
  477. fServerOS = FALSE;
  478. return fServerOS;
  479. }