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.

910 lines
25 KiB

  1. //---------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1997 - 1999
  3. //
  4. // httpreg.c
  5. //
  6. // HTTP/RPC Proxy Registry Functions.
  7. //
  8. // Author:
  9. // 06-16-97 Edward Reus Initial version.
  10. //
  11. //---------------------------------------------------------------------------
  12. #include <sysinc.h>
  13. #include <rpc.h>
  14. #include <rpcdce.h>
  15. #include <winsock2.h>
  16. #include <httpfilt.h>
  17. #include <httpext.h>
  18. #include <mbstring.h>
  19. #include <ecblist.h>
  20. #include <filter.h>
  21. #include <regexp.h>
  22. #include <registry.h>
  23. #include <resource.h>
  24. #include <PEventLog.h>
  25. //-------------------------------------------------------------------------
  26. // AtoUS()
  27. //
  28. // Convert a numeric string to an unsigned short. If the conversion
  29. // fails return FALSE.
  30. //-------------------------------------------------------------------------
  31. static BOOL AtoUS( char *pszValue, unsigned short *pusValue )
  32. {
  33. int iValue;
  34. size_t iLen = strlen(pszValue);
  35. *pusValue = 0;
  36. if ((iLen == 0) || (iLen > 5) || (iLen != strspn(pszValue,"0123456789")))
  37. {
  38. return FALSE;
  39. }
  40. iValue = atoi(pszValue);
  41. if ((iValue < 0) || (iValue > 65535))
  42. {
  43. return FALSE;
  44. }
  45. *pusValue = (unsigned short) iValue;
  46. return TRUE;
  47. }
  48. char *
  49. SkipLeadingSpaces (
  50. IN const char *CurrentPosition
  51. )
  52. /*++
  53. Routine Description:
  54. Skips all spaces (0x20) starting from the current position.
  55. Arguments:
  56. CurrentPosition - the beginning of the string
  57. Return Value:
  58. The first non-space character in the string
  59. --*/
  60. {
  61. while (*CurrentPosition == ' ')
  62. CurrentPosition ++;
  63. return (char *)CurrentPosition;
  64. }
  65. void
  66. RemoveTrailingSpaces (
  67. IN char *CurrentPosition,
  68. IN char *BeginningOfString
  69. )
  70. /*++
  71. Routine Description:
  72. Removes all trailing spaces at the end of the string
  73. by converting them to 0.
  74. Arguments:
  75. CurrentPosition - the current position in the string -
  76. usually one before the null terminator.
  77. BeginningOfString - the beginning of the string - we should
  78. not move beyond this.
  79. Return Value:
  80. --*/
  81. {
  82. ASSERT(CurrentPosition >= BeginningOfString);
  83. // whack all trailing spaces
  84. while (*CurrentPosition == ' ' && CurrentPosition > BeginningOfString)
  85. {
  86. *CurrentPosition = '\0';
  87. -- CurrentPosition;
  88. }
  89. }
  90. void
  91. LogEventValidPortsFailure (
  92. IN char *ValidPorts
  93. )
  94. /*++
  95. Routine Description:
  96. Logs a message to the event log reporting that the
  97. ValidPorts regkey cannot be parsed.
  98. Arguments:
  99. ValidPorts - parses the valid ports string as read from the registry.
  100. Return Value:
  101. --*/
  102. {
  103. HANDLE hEventSource;
  104. char *Strings[] = { ValidPorts };
  105. hEventSource = RegisterEventSourceW (NULL, // uses local computer
  106. EVENT_LOG_SOURCE_NAME); // source name
  107. if (hEventSource == NULL)
  108. {
  109. #if DBG
  110. DbgPrint("Rpc Proxy - RegisterEventSourceW failed: %X. Can't log event ValidPorts failure event. \n",
  111. GetLastError());
  112. #endif // DBG
  113. return;
  114. }
  115. if (!ReportEventA(hEventSource,
  116. EVENTLOG_ERROR_TYPE, // event type
  117. RPCPROXY_EVENTLOG_STARTUP_CATEGORY, // category
  118. RPCPROXY_EVENTLOG_VALID_PORTS_ERR, // event identifier
  119. NULL, // user security identifier
  120. 1, // # of substitution strings
  121. 0, // no data
  122. Strings, // pointer to string array
  123. NULL)) // pointer to data
  124. {
  125. #if DBG
  126. DbgPrint("Rpc Proxy - ReportEventW failed: %X. Can't log event ValidPorts failure. \n", GetLastError());
  127. #endif // DBG
  128. // fall through on error
  129. }
  130. DeregisterEventSource(hEventSource);
  131. }
  132. void
  133. LogEventStartupSuccess (
  134. IN char *IISMode
  135. )
  136. /*++
  137. Routine Description:
  138. Logs a message to the event log reporting that the
  139. RPC proxy started successfully.
  140. Arguments:
  141. IISMode - the mode that we start in. Must be the string "5"
  142. for 5.0 mode and the string "6" for 6.0 mode.
  143. Return Value:
  144. --*/
  145. {
  146. HANDLE hEventSource;
  147. char *Strings[] = { IISMode };
  148. hEventSource = RegisterEventSourceW (NULL, // uses local computer
  149. EVENT_LOG_SOURCE_NAME); // source name
  150. if (hEventSource == NULL)
  151. {
  152. #if DBG
  153. DbgPrint("Rpc Proxy - RegisterEventSourceW failed: %X. Can't log event StartupSuccess event. \n",
  154. GetLastError());
  155. #endif // DBG
  156. return;
  157. }
  158. if (!ReportEventA(hEventSource,
  159. EVENTLOG_INFORMATION_TYPE, // event type
  160. RPCPROXY_EVENTLOG_STARTUP_CATEGORY, // category
  161. RPCPROXY_EVENTLOG_SUCCESS_LOAD, // event identifier
  162. NULL, // user security identifier
  163. 1, // # of substitution strings
  164. 0, // no data
  165. Strings, // pointer to string array
  166. NULL)) // pointer to data
  167. {
  168. #if DBG
  169. DbgPrint("Rpc Proxy - ReportEventW failed: %X. Can't log event Startup Success. \n", GetLastError());
  170. #endif // DBG
  171. // fall through on error
  172. }
  173. DeregisterEventSource(hEventSource);
  174. }
  175. //-------------------------------------------------------------------------
  176. // HttpParseServerPort()
  177. //
  178. // Parse strings of the form: <svr>:<port>[-<port>]
  179. //
  180. // Return TRUE iff we have a valid specification of a server/port range.
  181. //
  182. // N.B.: pszServerPortRange gets modified on output
  183. //-------------------------------------------------------------------------
  184. static BOOL HttpParseServerPort( IN char *pszServerPortRange,
  185. OUT VALID_PORT *pValidPort )
  186. {
  187. char *psz;
  188. char *pszColon;
  189. char *pszDash;
  190. char *pszCurrent;
  191. pszServerPortRange = SkipLeadingSpaces (pszServerPortRange);
  192. if (pszColon=_mbschr(pszServerPortRange,':'))
  193. {
  194. if (pszColon == pszServerPortRange)
  195. {
  196. return FALSE;
  197. }
  198. *pszColon = 0;
  199. psz = pszColon;
  200. psz++;
  201. pValidPort->pszMachine = (char*)MemAllocate(1+lstrlen(pszServerPortRange));
  202. if (!pValidPort->pszMachine)
  203. {
  204. return FALSE;
  205. }
  206. lstrcpy(pValidPort->pszMachine,pszServerPortRange);
  207. // truncate trailing spaces in the name
  208. // position on the last character before the terminating NULL
  209. pszCurrent = pValidPort->pszMachine + _mbstrlen(pValidPort->pszMachine) - 1;
  210. // we checked above that the machine name is not empty
  211. ASSERT(pszCurrent > pValidPort->pszMachine);
  212. RemoveTrailingSpaces (pszCurrent, pValidPort->pszMachine);
  213. if (*psz)
  214. {
  215. // skip leading spaces
  216. psz = SkipLeadingSpaces (psz);
  217. if (pszDash=_mbschr(psz,'-'))
  218. {
  219. *pszDash = 0;
  220. RemoveTrailingSpaces (pszDash - 1, psz);
  221. if (!AtoUS(psz,&pValidPort->usPort1))
  222. {
  223. pValidPort->pszMachine = MemFree(pValidPort->pszMachine);
  224. return FALSE;
  225. }
  226. psz = SkipLeadingSpaces (pszDash + 1);
  227. if (!AtoUS(psz,&pValidPort->usPort2))
  228. {
  229. pValidPort->pszMachine = MemFree(pValidPort->pszMachine);
  230. return FALSE;
  231. }
  232. }
  233. else
  234. {
  235. psz = SkipLeadingSpaces (psz);
  236. if (!AtoUS(psz,&pValidPort->usPort1))
  237. {
  238. pValidPort->pszMachine = MemFree(pValidPort->pszMachine);
  239. return FALSE;
  240. }
  241. pValidPort->usPort2 = pValidPort->usPort1;
  242. }
  243. }
  244. else
  245. {
  246. pValidPort->pszMachine = MemFree(pValidPort->pszMachine);
  247. return FALSE;
  248. }
  249. }
  250. else
  251. {
  252. return FALSE;
  253. }
  254. return TRUE;
  255. }
  256. //-------------------------------------------------------------------------
  257. // HttpFreeValidPortList()
  258. //
  259. //-------------------------------------------------------------------------
  260. void HttpFreeValidPortList( IN VALID_PORT *pValidPorts )
  261. {
  262. VALID_PORT *pCurrent = pValidPorts;
  263. if (pValidPorts)
  264. {
  265. while (pCurrent->pszMachine)
  266. {
  267. MemFree(pCurrent->pszMachine);
  268. if (pCurrent->ppszDotMachineList)
  269. {
  270. FreeIpAddressList(pCurrent->ppszDotMachineList);
  271. }
  272. pCurrent++;
  273. }
  274. MemFree(pValidPorts);
  275. }
  276. }
  277. //-------------------------------------------------------------------------
  278. // HttpParseValidPortsList()
  279. //
  280. // Given a semicolon separated list of valid machine name/port ranges
  281. // string, part it and return an array of ValidPort structures. The last
  282. // entry has a NULL pszMachine field.
  283. //-------------------------------------------------------------------------
  284. VALID_PORT *HttpParseValidPortsList( IN char *pszValidPorts )
  285. {
  286. int i;
  287. int iLen;
  288. int count = 1;
  289. DWORD dwSize = 1+lstrlen(pszValidPorts);
  290. char *pszList;
  291. char *pszFirst;
  292. char *psz;
  293. VALID_PORT *pValidPorts = NULL;
  294. if (!dwSize)
  295. {
  296. return NULL;
  297. }
  298. // Make a local copy of the machine/ports list to work with:
  299. pszList = MemAllocate(dwSize);
  300. if (!pszList)
  301. {
  302. // Out of memory.
  303. return NULL;
  304. }
  305. lstrcpy(pszList,pszValidPorts);
  306. // See how many separate machine/port range patterns ther are in
  307. // the list:
  308. //
  309. // NOTE: That count may be too high, if either the list contains
  310. // double semicolons or the list ends with a semicolon. If
  311. // either/both of these happen that's Ok, our array will be
  312. // just a little too long.
  313. psz = pszList;
  314. while (psz=_mbsstr(psz,";"))
  315. {
  316. count++;
  317. psz++;
  318. }
  319. pValidPorts = (VALID_PORT*)MemAllocate( (1+count)*sizeof(VALID_PORT) );
  320. if (!pValidPorts)
  321. {
  322. // Out of memory.
  323. MemFree(pszList);
  324. return NULL;
  325. }
  326. memset(pValidPorts,0,(1+count)*sizeof(VALID_PORT));
  327. i = 0;
  328. psz = pszList;
  329. while (i<count)
  330. {
  331. if (!*psz)
  332. {
  333. // End of list. This happens when the list contained empty
  334. // patterns.
  335. break;
  336. }
  337. pszFirst = psz;
  338. psz = _mbsstr(pszFirst,";");
  339. if (psz)
  340. {
  341. *psz = 0; // Nul where the semicolon was...
  342. if ( (iLen=lstrlen(pszFirst)) == 0)
  343. {
  344. // Zero length pattern.
  345. ++psz;
  346. continue;
  347. }
  348. if (!HttpParseServerPort(pszFirst,&(pValidPorts[i++])))
  349. {
  350. MemFree(pszList);
  351. HttpFreeValidPortList(pValidPorts);
  352. return NULL;
  353. }
  354. }
  355. else
  356. {
  357. // Last one.
  358. if (!HttpParseServerPort(pszFirst,&(pValidPorts[i++])))
  359. {
  360. MemFree(pszList);
  361. HttpFreeValidPortList(pValidPorts);
  362. return NULL;
  363. }
  364. }
  365. ++psz;
  366. }
  367. MemFree(pszList);
  368. return pValidPorts;
  369. }
  370. BOOL InvalidPortsRangeEventLogged = FALSE;
  371. //-------------------------------------------------------------------------
  372. // HttpProxyRefreshValidPorts()
  373. //
  374. // Check the registry to see if HTTP/RPC is enabled and if so, return a
  375. // list (array) of machines that the RPC Proxy is allowed to reach (may
  376. // be NULL. The returned list specifies specifically what machines may
  377. // be reached by the proxy.
  378. //
  379. // The following registry entries are found in:
  380. //
  381. // \HKEY_LOCAL_MACHINE
  382. // \Software
  383. // \Microsoft
  384. // \Rpc
  385. // \RpcProxy
  386. //
  387. // Enabled : REG_DWORD
  388. //
  389. // TRUE iff the RPC proxy is enabled.
  390. //
  391. // ValidPorts : REG_SZ
  392. //
  393. // Semicolon separated list of machine/port ranges used to specify
  394. // what machine are reachable from the RPC proxy. For example:
  395. //
  396. // foxtrot:1-4000;Data*:200-4000
  397. //
  398. // Will allow access to the machine foxtrot (port ranges 1 to 4000) and
  399. // to all machines whose name begins with Data (port ranges 200-4000).
  400. //
  401. //-------------------------------------------------------------------------
  402. VALID_PORT *HttpProxyRefreshValidPorts(IN HKEY hKey OPTIONAL)
  403. {
  404. long lStatus;
  405. BOOL KeyOpenedLocally;
  406. DWORD dwType;
  407. DWORD dwSize;
  408. VALID_PORT *ValidPorts = NULL;
  409. char *pszValidPorts = NULL;
  410. KeyOpenedLocally = FALSE;
  411. if (hKey == NULL)
  412. {
  413. lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PROXY_PATH_STR, 0, KEY_READ, &hKey);
  414. if (lStatus != ERROR_SUCCESS)
  415. {
  416. goto CleanupAndExit;
  417. }
  418. KeyOpenedLocally = TRUE;
  419. }
  420. dwSize = 0;
  421. lStatus = RegQueryValueEx(hKey, REG_PROXY_VALID_PORTS_STR, 0, &dwType, (LPBYTE)NULL, &dwSize);
  422. if ( (lStatus != ERROR_SUCCESS) || (dwSize == 0) )
  423. {
  424. goto CleanupAndExit;
  425. }
  426. // dwSize is now how big the valid ports string is (including the trailing nul).
  427. pszValidPorts = (char *) MemAllocate(dwSize);
  428. if (pszValidPorts == NULL)
  429. goto CleanupAndExit;
  430. lStatus = RegQueryValueEx(hKey, REG_PROXY_VALID_PORTS_STR, 0, &dwType, (LPBYTE)pszValidPorts, &dwSize);
  431. if (lStatus != ERROR_SUCCESS)
  432. {
  433. goto CleanupAndExit;
  434. }
  435. ValidPorts = HttpParseValidPortsList(pszValidPorts);
  436. // fall through to the cleanup and exit code
  437. CleanupAndExit:
  438. if (KeyOpenedLocally)
  439. RegCloseKey(hKey);
  440. // if we failed to load/parse the valid ports list, log an event
  441. if (ValidPorts == NULL)
  442. {
  443. // log the event only the first time
  444. if (InvalidPortsRangeEventLogged == FALSE)
  445. {
  446. LogEventValidPortsFailure (pszValidPorts);
  447. // remember we have logged the event.
  448. InvalidPortsRangeEventLogged = TRUE;
  449. }
  450. }
  451. else
  452. {
  453. // we parsed the ports successfully.
  454. InvalidPortsRangeEventLogged = FALSE;
  455. }
  456. if (pszValidPorts)
  457. MemFree(pszValidPorts);
  458. return ValidPorts;
  459. }
  460. BOOL HttpProxyCheckRegistry(void)
  461. {
  462. int i;
  463. long lStatus;
  464. DWORD dwType;
  465. DWORD dwSize;
  466. HKEY hKey;
  467. char *pszValidPorts;
  468. struct hostent UNALIGNED *pHostEnt;
  469. struct in_addr ServerInAddr;
  470. HMODULE RedirectorDll;
  471. RPC_CHAR *RedirectorDllName;
  472. RPC_CHAR RedirectorDllNameBuffer[40];
  473. lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_PROXY_PATH_STR,0,KEY_READ,&hKey);
  474. if (lStatus != ERROR_SUCCESS)
  475. {
  476. return TRUE;
  477. }
  478. dwSize = sizeof(g_pServerInfo->dwEnabled);
  479. lStatus = RegQueryValueEx(hKey,REG_PROXY_ENABLE_STR,0,&dwType,(LPBYTE)&g_pServerInfo->dwEnabled,&dwSize);
  480. if (lStatus != ERROR_SUCCESS)
  481. {
  482. RegCloseKey(hKey);
  483. return TRUE;
  484. }
  485. if (!g_pServerInfo->dwEnabled)
  486. {
  487. // RPC Proxy is disabled, no need to go on.
  488. RegCloseKey(hKey);
  489. return TRUE;
  490. }
  491. dwSize = sizeof(g_pServerInfo->dwEnabled);
  492. lStatus = RegQueryValueEx(hKey,REG_PROXY_ALLOW_ANONYMOUS,0,&dwType,(LPBYTE)&g_pServerInfo->AllowAnonymous,&dwSize);
  493. if ((lStatus == ERROR_SUCCESS) && (dwType != REG_DWORD))
  494. {
  495. // if the type is wrong, bail out
  496. RegCloseKey(hKey);
  497. return FALSE;
  498. }
  499. dwSize = sizeof(RedirectorDllNameBuffer);
  500. lStatus = RegQueryValueExW(hKey, REG_PROXY_REDIRECTOR_DLL, 0, &dwType, (LPBYTE)RedirectorDllNameBuffer, &dwSize);
  501. if (
  502. (
  503. (lStatus == ERROR_SUCCESS)
  504. ||
  505. (lStatus == ERROR_MORE_DATA)
  506. )
  507. && (dwType != REG_SZ)
  508. )
  509. {
  510. // if the type is wrong, bail out
  511. RegCloseKey(hKey);
  512. return FALSE;
  513. }
  514. if (lStatus == ERROR_MORE_DATA)
  515. {
  516. RedirectorDllName = MemAllocate(dwSize);
  517. if (RedirectorDllName == NULL)
  518. {
  519. RegCloseKey(hKey);
  520. return FALSE;
  521. }
  522. lStatus = RegQueryValueExW(hKey, REG_PROXY_REDIRECTOR_DLL, 0, &dwType, (LPBYTE)RedirectorDllName, &dwSize);
  523. }
  524. else
  525. RedirectorDllName = RedirectorDllNameBuffer;
  526. if (lStatus == ERROR_SUCCESS)
  527. {
  528. // a redirector DLL was configured
  529. // Load it.
  530. RedirectorDll = LoadLibraryW(RedirectorDllName);
  531. if (RedirectorDll == NULL)
  532. {
  533. RegCloseKey(hKey);
  534. return FALSE;
  535. }
  536. g_pServerInfo->RpcNewHttpProxyChannel
  537. = (RPC_NEW_HTTP_PROXY_CHANNEL)GetProcAddress(RedirectorDll, "RpcNewHttpProxyChannel");
  538. g_pServerInfo->RpcHttpProxyFreeString
  539. = (RPC_HTTP_PROXY_FREE_STRING)GetProcAddress(RedirectorDll, "RpcHttpProxyFreeString");
  540. if ((g_pServerInfo->RpcNewHttpProxyChannel == NULL)
  541. || (g_pServerInfo->RpcHttpProxyFreeString == NULL))
  542. {
  543. g_pServerInfo->RpcNewHttpProxyChannel = NULL;
  544. g_pServerInfo->RpcHttpProxyFreeString = NULL;
  545. FreeLibrary(RedirectorDll);
  546. RegCloseKey(hKey);
  547. return FALSE;
  548. }
  549. }
  550. // this is called as part of the ISAPI initialization - no need
  551. // to claim the right to refresh ports - we're single threaded
  552. // by definition.
  553. g_pServerInfo->RefreshingValidPorts = FALSE;
  554. g_pServerInfo->pValidPorts = HttpProxyRefreshValidPorts(hKey);
  555. RegCloseKey(hKey);
  556. if (g_pServerInfo->pValidPorts)
  557. return TRUE;
  558. else
  559. return FALSE;
  560. }
  561. //-------------------------------------------------------------------------
  562. // HttpConvertToDotAddress()
  563. //
  564. // Convert the specified machine name to IP dot notation if possible.
  565. //-------------------------------------------------------------------------
  566. char *HttpConvertToDotAddress( char *pszMachineName )
  567. {
  568. struct hostent UNALIGNED *pHostEnt;
  569. struct in_addr MachineInAddr;
  570. char *pszDot = NULL;
  571. char *pszDotMachine = NULL;
  572. pHostEnt = gethostbyname(pszMachineName);
  573. if (pHostEnt)
  574. {
  575. memcpy(&MachineInAddr,pHostEnt->h_addr,pHostEnt->h_length);
  576. pszDot = inet_ntoa(MachineInAddr);
  577. }
  578. if (pszDot)
  579. {
  580. pszDotMachine = (char*)MemAllocate(1+lstrlen(pszDot));
  581. if (pszDotMachine)
  582. {
  583. lstrcpy(pszDotMachine,pszDot);
  584. }
  585. }
  586. return pszDotMachine;
  587. }
  588. //-------------------------------------------------------------------------
  589. // HttpNameToDotAddressList()
  590. //
  591. // Convert the specified machine name to IP dot notation if possible.
  592. // Return a list (null terminated) of the IP dot addresses in ascii.
  593. //
  594. // If the function fails, then retrun NULL. It can fail if gethostbyname()
  595. // fails, or memory allocation fails.
  596. //-------------------------------------------------------------------------
  597. char **HttpNameToDotAddressList( IN char *pszMachineName )
  598. {
  599. int i;
  600. int iCount = 0;
  601. struct hostent UNALIGNED *pHostEnt;
  602. struct in_addr MachineInAddr;
  603. char **ppszDotList = NULL;
  604. char *pszDot = NULL;
  605. char *pszDotMachine = NULL;
  606. pHostEnt = gethostbyname(pszMachineName);
  607. if (pHostEnt)
  608. {
  609. // Count how many addresses we have:
  610. while (pHostEnt->h_addr_list[iCount])
  611. {
  612. iCount++;
  613. }
  614. // Make sure we have at lease one address:
  615. if (iCount > 0)
  616. {
  617. ppszDotList = (char**)MemAllocate( sizeof(char*)*(1+iCount) );
  618. }
  619. // Build an array of strings, holding the addresses (ascii DOT
  620. // notation:
  621. if (ppszDotList)
  622. {
  623. for (i=0; i<iCount; i++)
  624. {
  625. memcpy(&MachineInAddr,
  626. pHostEnt->h_addr_list[i],
  627. pHostEnt->h_length);
  628. pszDot = inet_ntoa(MachineInAddr);
  629. if (pszDot)
  630. {
  631. ppszDotList[i] = (char*)MemAllocate(1+lstrlen(pszDot));
  632. if (ppszDotList[i])
  633. {
  634. strcpy(ppszDotList[i],pszDot);
  635. }
  636. else
  637. {
  638. // memory allocate failed:
  639. break;
  640. }
  641. }
  642. }
  643. ppszDotList[i] = NULL; // Null terminated list.
  644. }
  645. }
  646. return ppszDotList;
  647. }
  648. //-------------------------------------------------------------------------
  649. // CheckCacheTimestamp()
  650. //
  651. // Return true if the current time stamp is aged out.
  652. //-------------------------------------------------------------------------
  653. BOOL CheckCacheTimestamp( DWORD dwCurrentTickCount,
  654. DWORD dwCacheTimestamp )
  655. {
  656. if ( (dwCurrentTickCount < dwCacheTimestamp)
  657. || ((dwCurrentTickCount - dwCacheTimestamp) > VALID_PORTS_CACHE_LIFE) )
  658. {
  659. return TRUE;
  660. }
  661. return FALSE;
  662. }
  663. //-------------------------------------------------------------------------
  664. // CheckPort()
  665. //
  666. //-------------------------------------------------------------------------
  667. static BOOL CheckPort( DWORD dwPortNumber,
  668. VALID_PORT *pValidPort )
  669. {
  670. return ( (dwPortNumber >= pValidPort->usPort1)
  671. && (dwPortNumber <= pValidPort->usPort2) );
  672. }
  673. //-------------------------------------------------------------------------
  674. // HttpProxyIsValidMachine()
  675. //
  676. //-------------------------------------------------------------------------
  677. BOOL HttpProxyIsValidMachine( SERVER_INFO *pServerInfo,
  678. char *pszMachine,
  679. char *pszDotMachine,
  680. DWORD dwPortNumber )
  681. {
  682. int i;
  683. char **ppszDot;
  684. DWORD dwTicks;
  685. DWORD dwSize;
  686. DWORD dwStatus;
  687. VALID_PORT *pValidPorts;
  688. // Check the machine name against those that were allowed
  689. // in the registry:
  690. dwStatus = RtlEnterCriticalSection(&pServerInfo->cs);
  691. dwTicks = GetTickCount();
  692. if (CheckCacheTimestamp(dwTicks, pServerInfo->dwCacheTimestamp)
  693. && pServerInfo->RefreshingValidPorts == FALSE)
  694. {
  695. // claim the right to refresh the ports
  696. pServerInfo->RefreshingValidPorts = TRUE;
  697. RtlLeaveCriticalSection(&pServerInfo->cs);
  698. // refresh them outside the critical section
  699. pValidPorts = HttpProxyRefreshValidPorts (
  700. NULL // hKey
  701. );
  702. // get back into the critical section
  703. RtlEnterCriticalSection(&pServerInfo->cs);
  704. pServerInfo->RefreshingValidPorts = FALSE;
  705. if (pValidPorts)
  706. {
  707. // if success, refresh the tick count
  708. pServerInfo->dwCacheTimestamp = dwTicks;
  709. }
  710. if (pServerInfo->pValidPorts)
  711. MemFree (pServerInfo->pValidPorts);
  712. pServerInfo->pValidPorts = pValidPorts;
  713. }
  714. pValidPorts = pServerInfo->pValidPorts;
  715. if (pValidPorts)
  716. {
  717. while (pValidPorts->pszMachine)
  718. {
  719. // See if we have a name match:
  720. if ( (MatchREi(pszMachine,pValidPorts->pszMachine))
  721. && (CheckPort(dwPortNumber,pValidPorts)) )
  722. {
  723. dwStatus = RtlLeaveCriticalSection(&pServerInfo->cs);
  724. return TRUE;
  725. }
  726. // The "valid entry" in the registry might be an address
  727. // wildcard, check it:
  728. if ( (pszDotMachine)
  729. && (MatchREi(pszDotMachine,pValidPorts->pszMachine))
  730. && (CheckPort(dwPortNumber,pValidPorts)) )
  731. {
  732. dwStatus = RtlLeaveCriticalSection(&pServerInfo->cs);
  733. return TRUE;
  734. }
  735. // Try a match using internet dot address:
  736. if ( (pValidPorts->ppszDotMachineList)
  737. && (pszDotMachine)
  738. && (CheckPort(dwPortNumber,pValidPorts)) )
  739. {
  740. // Note that the machine may have more than one address
  741. // associated with it:
  742. //
  743. ppszDot = pValidPorts->ppszDotMachineList;
  744. while (*ppszDot)
  745. {
  746. if (!_mbsicmp(pszDotMachine,*ppszDot))
  747. {
  748. dwStatus = RtlLeaveCriticalSection(&pServerInfo->cs);
  749. return TRUE;
  750. }
  751. else
  752. {
  753. ppszDot++;
  754. }
  755. }
  756. }
  757. pValidPorts++;
  758. }
  759. }
  760. dwStatus = RtlLeaveCriticalSection(&pServerInfo->cs);
  761. return FALSE;
  762. }