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.

512 lines
14 KiB

  1. //---------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1997 - 1999
  3. //
  4. // httpreg.c
  5. //
  6. // HTTP/RPC protocol specific functions.
  7. //
  8. // Author:
  9. // 06-02-97 Edward Reus Initial version.
  10. //
  11. //---------------------------------------------------------------------------
  12. #define FD_SETSIZE 1
  13. #include <precomp.hxx>
  14. //-------------------------------------------------------------------------
  15. // HttpParseServerPort()
  16. //
  17. // Parse strings of the form: <svr>[:<port>]
  18. //-------------------------------------------------------------------------
  19. static BOOL HttpParseServerPort( IN char *pszServerPort,
  20. IN char *pszDefaultPort,
  21. OUT char *pszServer,
  22. OUT char *pszPort )
  23. {
  24. char *psz;
  25. char *pszColon;
  26. char *CurrentPosition;
  27. char ch;
  28. if (pszColon=strchr(pszServerPort,':'))
  29. {
  30. *pszColon = 0;
  31. psz = pszColon;
  32. psz++;
  33. strcpy(pszServer,pszServerPort);
  34. *pszColon = ':';
  35. if (*psz)
  36. {
  37. // take the string until the end or until a space which
  38. // indicates another entry (probably for another protocol).
  39. CurrentPosition = psz;
  40. while (*CurrentPosition && (*CurrentPosition != ' '))
  41. CurrentPosition ++;
  42. ch = *CurrentPosition;
  43. *CurrentPosition = 0;
  44. strcpy(pszPort,psz);
  45. *CurrentPosition = ch;
  46. }
  47. else
  48. {
  49. strcpy(pszPort,pszDefaultPort);
  50. }
  51. }
  52. else
  53. {
  54. strcpy(pszServer,pszServerPort);
  55. strcpy(pszPort,pszDefaultPort);
  56. }
  57. return TRUE;
  58. }
  59. //-------------------------------------------------------------------------
  60. // HttpParseProxyName()
  61. //
  62. //-------------------------------------------------------------------------
  63. const char *HttpProxyPrefix = "http://";
  64. const int HttpProxyPrefixSize = sizeof("http://") - 1;
  65. BOOL HttpParseProxyName( IN char *pszProxyList,
  66. IN BOOL UseSSLProxyPortAsDefault,
  67. OUT char *pszHttpProxy,
  68. OUT char *pszHttpProxyPort )
  69. {
  70. BOOL fStatus;
  71. char *psz;
  72. char *pszSemiColon;
  73. int StringLength;
  74. char *ProtocolType;
  75. char *DefaultPort;
  76. strcpy(pszHttpProxy,"");
  77. strcpy(pszHttpProxyPort,"");
  78. // Check for no configured proxy:
  79. if ((!pszProxyList)||(!*pszProxyList))
  80. {
  81. return TRUE;
  82. }
  83. // if the string is large enough to contain the prefix, check
  84. // whether it has a prefix
  85. StringLength = strlen(pszProxyList);
  86. if (StringLength >= HttpProxyPrefixSize)
  87. {
  88. if (RpcpStringNCompareA(pszProxyList, HttpProxyPrefix, HttpProxyPrefixSize) == 0)
  89. pszProxyList += HttpProxyPrefixSize;
  90. }
  91. if (!strstr(pszProxyList,EQUALS_STR))
  92. {
  93. return HttpParseServerPort(pszProxyList,DEF_HTTP_PORT,pszHttpProxy,pszHttpProxyPort);
  94. }
  95. if (UseSSLProxyPortAsDefault)
  96. {
  97. ProtocolType = HTTPS_EQUALS_STR;
  98. DefaultPort = DEF_HTTP_SSL_PORT;
  99. }
  100. else
  101. {
  102. ProtocolType = HTTP_EQUALS_STR;
  103. DefaultPort = DEF_HTTP_PORT;
  104. }
  105. if (psz=strstr(pszProxyList,ProtocolType))
  106. {
  107. psz += strlen(ProtocolType);
  108. if (pszSemiColon=strstr(psz,SEMICOLON_STR))
  109. {
  110. *pszSemiColon = 0;
  111. fStatus = HttpParseServerPort(psz,DefaultPort,pszHttpProxy,pszHttpProxyPort);
  112. *pszSemiColon = CHAR_SEMICOLON;
  113. return fStatus;
  114. }
  115. else
  116. {
  117. return HttpParseServerPort(psz,DefaultPort,pszHttpProxy,pszHttpProxyPort);
  118. }
  119. }
  120. else
  121. {
  122. return TRUE;
  123. }
  124. }
  125. //-------------------------------------------------------------------------
  126. // HttpFreeProxyOverrideList()
  127. //
  128. //-------------------------------------------------------------------------
  129. static void HttpFreeProxyOverrideList( IN char **ppszOverrideList )
  130. {
  131. char **ppszTmp = ppszOverrideList;
  132. if (ppszOverrideList)
  133. {
  134. while (*ppszTmp)
  135. {
  136. I_RpcFree(*ppszTmp);
  137. ppszTmp++;
  138. }
  139. I_RpcFree(ppszOverrideList);
  140. }
  141. }
  142. //-------------------------------------------------------------------------
  143. // HttpParseProxyOverrideList()
  144. //
  145. //-------------------------------------------------------------------------
  146. static char **HttpParseProxyOverrideList( IN char *pszProxyOverrideList )
  147. {
  148. int i;
  149. int iLen;
  150. int count = 1;
  151. DWORD dwSize = 1+strlen(pszProxyOverrideList);
  152. char *pszList;
  153. char *psz;
  154. char **ppszPatternList;
  155. if (!dwSize)
  156. {
  157. return NULL;
  158. }
  159. // Make a local copy of the pattern list, to work with:
  160. pszList = (char *) alloca(dwSize);
  161. strcpy(pszList,pszProxyOverrideList);
  162. // See how many separate patterns ther are in the override list:
  163. //
  164. // NOTE: That count may be too high, if either the list contains
  165. // double semicolons or the list ends with a semicolon. If
  166. // either/both of these happen that's Ok.
  167. psz = pszList;
  168. while (psz=strstr(psz,";"))
  169. {
  170. count++;
  171. psz++;
  172. }
  173. ppszPatternList = (char**)RpcpFarAllocate( (1+count)*sizeof(char*) );
  174. if (!ppszPatternList)
  175. {
  176. // Out of memory.
  177. return NULL;
  178. }
  179. memset(ppszPatternList,0,(1+count)*sizeof(char*));
  180. i = 0;
  181. while (i<count)
  182. {
  183. if (!*pszList)
  184. {
  185. // End of list. This happens when the list contained empty
  186. // patterns.
  187. break;
  188. }
  189. psz = strstr(pszList,";");
  190. if (psz)
  191. {
  192. *psz = 0;
  193. if ( (iLen=strlen(pszList)) == 0)
  194. {
  195. // Zero length pattern.
  196. pszList = ++psz;
  197. continue;
  198. }
  199. ppszPatternList[i] = (char*)RpcpFarAllocate(1+iLen);
  200. if (!ppszPatternList[i])
  201. {
  202. HttpFreeProxyOverrideList(ppszPatternList);
  203. return NULL;
  204. }
  205. strcpy(ppszPatternList[i++],pszList);
  206. pszList = ++psz;
  207. }
  208. else
  209. {
  210. ppszPatternList[i] = (char*)RpcpFarAllocate(1+strlen(pszList));
  211. if (!ppszPatternList[i])
  212. {
  213. HttpFreeProxyOverrideList(ppszPatternList);
  214. return NULL;
  215. }
  216. strcpy(ppszPatternList[i++],pszList);
  217. }
  218. }
  219. return ppszPatternList;
  220. }
  221. //-------------------------------------------------------------------------
  222. // HttpCheckRegistry()
  223. //
  224. // With IE and WinInet you can setup a list of proxies to use to go through
  225. // with an HTTP (or other) internet request. We need to support this as
  226. // well. There are three registry entries of interest, which are located
  227. // at:
  228. //
  229. // \HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
  230. //
  231. // They are:
  232. //
  233. // ProxyEnable: REG_BINARY
  234. // A flag (TRUE/FALSE) to enable/disable proxies.
  235. //
  236. // ProxyServer: REG_SZ
  237. // On of: an empty string (no proxy specified), a single proxy server
  238. // name (for any format), or a list of proxy servers to use by format.
  239. // The list is of the form:
  240. //
  241. // ftp=<svr:port>,gopher=<svr:port>,http=<svr:port>,...
  242. //
  243. // Note that not all protocols need to be in the list. And the port#
  244. // does not need to be specifed. If not present then default the port#
  245. // to the default for that internet protocol (scheme).
  246. //
  247. // ProxyOverride: REG_SZ
  248. // A semicolon separated list of server names, internet addresses or
  249. // patterns which, if specified are used to denote machines that you
  250. // want to directly access, without using the proxy server. Examples
  251. // would be:
  252. //
  253. // 12.34.56.78;MySvr*;111.222.*;*green*
  254. //
  255. //-------------------------------------------------------------------------
  256. BOOL HttpCheckRegistry( IN char *pszServer,
  257. IN BOOL UseSSLProxyPortAsDefault,
  258. OUT char **ppszHttpProxy,
  259. OUT char **ppszHttpProxyPort,
  260. OUT RPCProxyAccessType *AccessType
  261. )
  262. {
  263. int i;
  264. long lStatus;
  265. DWORD dwType;
  266. DWORD dwEnabled;
  267. DWORD dwSize;
  268. HKEY hKey;
  269. HKEY hUserKey;
  270. char szProxyList[256];
  271. char szProxyOverrideList[256];
  272. char szHttpProxy[MAX_HTTP_COMPUTERNAME_SIZE];
  273. char szHttpProxyPort[MAX_HTTP_PORTSTRING_SIZE];
  274. char *pszDotServer;
  275. char **ppszOverrideList;
  276. struct hostent UNALIGNED *pHostEnt;
  277. struct in_addr ServerInAddr;
  278. BOOL LocalDirect;
  279. *ppszHttpProxy = NULL;
  280. *ppszHttpProxyPort = NULL;
  281. *AccessType = rpcpatDirect;
  282. lStatus = RegOpenCurrentUser( KEY_READ, &hUserKey );
  283. if (lStatus != ERROR_SUCCESS)
  284. {
  285. return TRUE;
  286. }
  287. lStatus = RegOpenKeyEx( hUserKey,
  288. REG_PROXY_PATH_STR,
  289. 0,
  290. KEY_READ,
  291. &hKey );
  292. RegCloseKey(hUserKey);
  293. if (lStatus != ERROR_SUCCESS)
  294. {
  295. return TRUE;
  296. }
  297. dwSize = sizeof(dwEnabled);
  298. lStatus = RegQueryValueEx(
  299. hKey,
  300. REG_PROXY_ENABLE_STR,
  301. 0,
  302. &dwType,
  303. (LPBYTE)&dwEnabled,
  304. &dwSize
  305. );
  306. if (lStatus != ERROR_SUCCESS)
  307. {
  308. RegCloseKey(hKey);
  309. return TRUE;
  310. }
  311. #ifdef DBG_REGISTRY
  312. if (dwType == REG_BINARY)
  313. {
  314. TransDbgPrint((DPFLTR_RPCPROXY_ID,
  315. DPFLTR_WARNING_LEVEL,
  316. "HttpCheckRegistry(): Proxy Enabled: %s\n",
  317. (dwEnabled)? "TRUE" : "FALSE"));
  318. }
  319. #endif // DBG_REGISTRY
  320. if (!dwEnabled)
  321. {
  322. // IE proxies are disabled, no need to go on.
  323. RegCloseKey(hKey);
  324. return TRUE;
  325. }
  326. dwSize = sizeof(szProxyList);
  327. lStatus = RegQueryValueExA( // Needs to be ANSI
  328. hKey,
  329. REG_PROXY_SERVER_STR,
  330. 0,
  331. &dwType,
  332. (LPBYTE)szProxyList,
  333. &dwSize
  334. );
  335. if (lStatus != ERROR_SUCCESS)
  336. {
  337. RegCloseKey(hKey);
  338. return TRUE;
  339. }
  340. #ifdef DBG_REGISTRY
  341. if (dwType == REG_SZ)
  342. {
  343. TransDbgPrint((DPFLTR_RPCPROXY_ID,
  344. DPFLTR_WARNING_LEVEL,
  345. "HttpCheckRegistry(): Proxy List: %s\n",
  346. szProxyList));
  347. }
  348. #endif // DBG_REGISTRY
  349. if (!HttpParseProxyName(szProxyList, UseSSLProxyPortAsDefault, szHttpProxy,szHttpProxyPort))
  350. {
  351. RegCloseKey(hKey);
  352. return TRUE;
  353. }
  354. dwSize = sizeof(szProxyOverrideList);
  355. lStatus = RegQueryValueExA( // Needs to be ANSI
  356. hKey,
  357. REG_PROXY_OVERRIDE_STR,
  358. 0,
  359. &dwType,
  360. (LPBYTE)szProxyOverrideList,
  361. &dwSize
  362. );
  363. if (lStatus != ERROR_SUCCESS)
  364. {
  365. // Don't quit if the ProxyOverride entry is missing, that's Ok...
  366. szProxyOverrideList[0] = 0;
  367. }
  368. #ifdef DBG_REGISTRY
  369. if (dwType == REG_SZ)
  370. {
  371. TransDbgPrint((DPFLTR_RPCPROXY_ID,
  372. DPFLTR_WARNING_LEVEL,
  373. "HttpCheckRegistry(): Proxy Override List: %s\n",
  374. szProxyOverrideList));
  375. }
  376. #endif // DBG_REGISTRY
  377. RegCloseKey(hKey);
  378. ppszOverrideList = HttpParseProxyOverrideList(szProxyOverrideList);
  379. if (ppszOverrideList)
  380. {
  381. LocalDirect = MatchExactList(
  382. (unsigned char *) LOCAL_ADDRESSES_STR,
  383. (unsigned char **) ppszOverrideList
  384. );
  385. if (!LocalDirect)
  386. *AccessType = rpcpatHTTPProxy;
  387. else
  388. {
  389. // we don't know. <local> is in the list of overrides,
  390. // but we don't know whether the server is local
  391. *AccessType = rpcpatUnknown;
  392. }
  393. // Check the server name to see if it's in the override list:
  394. if (MatchREList(
  395. (unsigned char *) pszServer,
  396. (unsigned char **) ppszOverrideList
  397. ))
  398. {
  399. // The server name is in the override list.
  400. HttpFreeProxyOverrideList(ppszOverrideList);
  401. *AccessType = rpcpatDirect;
  402. return TRUE;
  403. }
  404. // Convert the server name to dot notation and see if its in
  405. // the override list:
  406. pHostEnt = gethostbyname(pszServer);
  407. if (pHostEnt)
  408. {
  409. // Note that the server may actually have several addresses in
  410. // a (NULL terminated) array. Need to check each one...
  411. i = 0;
  412. while (pHostEnt->h_addr_list[i])
  413. {
  414. memcpy(&ServerInAddr,pHostEnt->h_addr_list[i++],pHostEnt->h_length);
  415. pszDotServer = inet_ntoa(ServerInAddr);
  416. #ifdef DBG_REGISTRY
  417. TransDbgPrint((DPFLTR_RPCPROXY_ID,
  418. DPFLTR_WARNING_LEVEL,
  419. "HttpCheckRegistry(): Server: %s Address: %s\n",
  420. pszServer,
  421. pszDotServer));
  422. #endif // DBG_REGISTRY
  423. if ( (pszDotServer)
  424. && MatchREList(
  425. (unsigned char *) pszDotServer,
  426. (unsigned char **) ppszOverrideList
  427. ) )
  428. {
  429. // The server name (in dot notation) is in the override list.
  430. HttpFreeProxyOverrideList(ppszOverrideList);
  431. *AccessType = rpcpatDirect;
  432. return TRUE;
  433. }
  434. }
  435. }
  436. HttpFreeProxyOverrideList(ppszOverrideList);
  437. }
  438. *ppszHttpProxy = (char *)RpcpFarAllocate(1+strlen(szHttpProxy));
  439. if (!*ppszHttpProxy)
  440. {
  441. return FALSE;
  442. }
  443. strcpy(*ppszHttpProxy,szHttpProxy);
  444. *ppszHttpProxyPort = (char*)RpcpFarAllocate(1+strlen(szHttpProxyPort));
  445. if (!*ppszHttpProxyPort)
  446. {
  447. I_RpcFree(*ppszHttpProxy);
  448. *ppszHttpProxy = NULL;
  449. return FALSE;
  450. }
  451. strcpy(*ppszHttpProxyPort,szHttpProxyPort);
  452. return TRUE;
  453. }