IPchkExt.cpp
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:17k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // IPchkExt.cpp : Defines the initialization routines for the DLL.
  2. //
  3. #include "stdafx.h"
  4. #include "WarDaemon.h"
  5. #include "IPchkExt.h"
  6. #include <afxdllx.h>
  7. #include "resource.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. static AFX_EXTENSION_MODULE IPchkExtDLL = { NULL, NULL };
  14. int CallOnConnect(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  15. int CallOnVerifyIPAddress(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  16. int CallOnBadPassword(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  17. int CallOnHasLoggedOn(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  18. int CallOnVerifyLogin(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  19. int CallOnSocketIsDestroyed(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam);
  20. ////////////////////////////////////////
  21. // ADDED: This is required for plugin's
  22. static CIPchkExt *pMe;
  23. extern "C" int APIENTRY
  24. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  25. {
  26. if (dwReason == DLL_PROCESS_ATTACH)
  27. {
  28. TRACE0("IPCHKEXT.DLL Initializing!n");
  29. // Extension DLL one-time initialization
  30. AfxInitExtensionModule(IPchkExtDLL, hInstance);
  31. // Insert this DLL into the resource chain
  32. new CDynLinkLibrary(IPchkExtDLL);
  33. pMe = new CIPchkExt;
  34. if (pMe->Register("IPchkExt") != 0)
  35. return 0; // Failure
  36. }
  37. else if (dwReason == DLL_PROCESS_DETACH)
  38. {
  39. TRACE0("IPCHKEXT.DLL Terminating!n");
  40. ////////////////////////////////////////
  41. // ADDED: This is required for plugin's
  42. if (pMe)
  43. delete pMe;
  44. }
  45. return 1;   // ok
  46. }
  47. // Initialize the extended COptions variables
  48. void CIPchkExt::InitializeCOptions()
  49. {
  50. DeclOpt("Connection delay", m_ConnectionDelay, 1, 1, DATATYPE_INT);
  51. DeclOpt("Passwd retries", m_MaxPasswdRetries, 3, 2, DATATYPE_INT);
  52. DeclOpt("Passwd retry delay", m_PasswdRetryDelay, 3, 3, DATATYPE_INT);
  53. DeclOpt("Hack pswd attmpt", m_MaxPasswdHacks, 9, 4, DATATYPE_INT);
  54. DeclOpt("Hack delay", m_HackDely, 6, 5, DATATYPE_INT);
  55. }
  56. CIPchkExt::CIPchkExt()
  57. {
  58. }
  59. CIPchkExt::~CIPchkExt()
  60. {
  61. CIPConnList::KillAll(this);
  62. }
  63. int CIPchkSock::OnConnect(int Event, WPARAM wParam, LPARAM lParam)
  64. {
  65. CIPConnList *pConn = NULL;
  66. CString cBuf("- No message -"), cFmt;
  67. m_SessionBadPwdCnt = 0;
  68. if (Event)
  69. return 0; // We don't want to handle socket errors...
  70. if (!CIPConnList::VerifyConnection(pSock, &pConn))
  71. {
  72. if (pSock->IsKindOf(RUNTIME_CLASS(CTextSock)))
  73. {
  74. CTextSock *pTextSock = (CTextSock *)pSock;
  75. if (pConn->m_IsHacker)
  76. {
  77. cBuf.LoadString(IDS_FUCKHACKERS);
  78. }
  79. else
  80. {
  81. cFmt.LoadString(IDS_TIMEOUTACTIVE);
  82. DWORD TimeLeft = pConn->m_Suspend.TimeLeft(pConn->m_SuspendVal);
  83. TimeLeft /= (1000 * 60);
  84. if (!TimeLeft)
  85. TimeLeft = 1;
  86. cBuf.Format(cFmt, TimeLeft );
  87. }
  88. // We need to send the message directly to bypass the framework's
  89. // processing. (The connection is not yet ready for normal control messages).
  90. cFmt.Format("421 %srn", cBuf);
  91. cBuf = cFmt;
  92. pTextSock->CAsyncSocket::Send(cBuf, cBuf.GetLength());
  93. }
  94. pMe->LogMsg(LOGF_SECURITY, "CIPchkSock::OnConnect() Access denied. Told client: %s", cBuf);
  95. CSocketException::Throw(pSock, "CIPchkSock::OnConnect()", -1, cBuf);
  96. }
  97. return 0;
  98. }
  99. int CIPchkSock::OnBadPassword(int Event, WPARAM wParam, LPARAM lParam)
  100. {
  101. CIPConnList *pConn = NULL;
  102. CString Name;
  103. if (pConn = CIPConnList::Find(pSock, Name))
  104. {
  105. ++m_SessionBadPwdCnt;
  106. ++pConn->m_BadPwdCnt;
  107. if (pConn->m_BadPwdCnt >= pMe->m_MaxPasswdHacks)
  108. {
  109. // Hacker!
  110. pConn->m_IsHacker = TRUE;
  111. pConn->m_SuspendVal = pMe->m_HackDely * 1000 * 60 * 60;
  112. pConn->m_ExpiryVal = max(pConn->m_ExpiryVal, pConn->m_SuspendVal);
  113. pConn->m_BadPwdCnt = 0; // Reset for the next user on this IP, - in a couple of hours...
  114. // Say gently goodbye...
  115. ASSERT(pSock->IsKindOf(RUNTIME_CLASS(CTextSock)));
  116. CTextSock *pTextSock = (CTextSock *)pSock;
  117. pTextSock->LogMsg(LOGF_SECURITY,"CIPchkSock::OnBadPassword() - HACKER detected. Turning on full protection.");
  118. pTextSock->SendMsg(530,"Hacking is a very bad habbit... Goodbye.");
  119. CSocketException::Throw(pSock, "CIPchkSock::OnBadPassword()", -1, "Hacker detected.");
  120. }
  121. if (m_SessionBadPwdCnt >= pMe->m_MaxPasswdRetries)
  122. {
  123. pConn->m_SuspendVal = pMe->m_PasswdRetryDelay * 1000 * 60;
  124. pConn->m_ExpiryVal = max(pConn->m_ExpiryVal, pConn->m_SuspendVal);
  125. // Say gently goodbye...
  126. ASSERT(pSock->IsKindOf(RUNTIME_CLASS(CTextSock)));
  127. CTextSock *pTextSock = (CTextSock *)pSock;
  128. pTextSock->LogMsg(LOGF_SECURITY,"CIPchkSock::OnBadPassword() - Too many bad passwords. Disconnecting user.");
  129. pTextSock->SendMsg(530,"You better check your login name and password. Goodbye.");
  130. CSocketException::Throw(pSock, "CIPchkSock::OnBadPassword()", -1, "Too many login attempts");
  131. }
  132. }
  133. return 0;
  134. }
  135. int CIPchkSock::OnVerifyLogin(int Event, WPARAM wParam, LPARAM lParam)
  136. {
  137. USER *pUser = (USER *)wParam;
  138. LOGINPRMS *pLP = (LOGINPRMS *)lParam;
  139. CIPConnList *pConn = NULL;
  140. CString Name;
  141. if (CUsr::IsAdmin(*pUser))
  142. return 0; // Don't mess with admins...
  143. if (pConn = CIPConnList::Find(pSock, Name))
  144. {
  145. // Check IP/Domain shitlist for the user
  146. if (pConn->IsBanned(*pUser, pSock))
  147. {
  148. pLP->Sock->LogMsg(LOGF_SECURITY,"CIPchkSock::OnVerifyLogin() - User %s from %s is shitlisted on IP/domain level. Access is denied.", pLP->UserID, pLP->Sock->m_DNSName);
  149. pLP->Sock->SendMsg(530,"Your IP address or domain name is shitlisted. Goodbye.");
  150. CSocketException::Throw(pSock, "CIPchkSock::OnVerifyLogin()", -1, "Shitlisted");
  151. }
  152. // Check max logins on the IP for the user account
  153. int MaxConnections = CUsr::GetRecursiveParam(*pUser, "IP MaxConn", 0);
  154. if (MaxConnections > 0)
  155. {
  156. int Count = 0;
  157. for(CLinkedListItem *Item = CSock::m_SocketList.First()
  158. ; Item
  159. ; Item = CSock::m_SocketList.Next(Item))
  160. {
  161. CSock *pSck = (CSock *)CSock::m_SocketList.Ptr(Item);
  162. if (!pSck->IsKindOf(RUNTIME_CLASS(CTextSock)))
  163. continue;
  164. if (pSck->m_PeerName == pConn->m_Name)
  165. ++Count;
  166. }
  167. if (Count > MaxConnections)
  168. {
  169. pLP->Sock->LogMsg(LOGF_SECURITY,"CIPchkSock::OnVerifyLogin() - To many connections from IP %s. Access is denied.", pLP->UserID, pConn->m_Name);
  170. pLP->Sock->SendMsg(530,"Your have exeeded your limit of %d concurrent sessions. Goodbye.", MaxConnections);
  171. CSocketException::Throw(pSock, "CIPchkSock::OnVerifyLogin()", -1, "To many connections from IP");
  172. }
  173. }
  174. }
  175. return 0;
  176. }
  177. int CIPchkSock::OnHasLoggedOn(int Event, WPARAM wParam, LPARAM lParam)
  178. {
  179. CIPConnList *pConn = NULL;
  180. CString Name;
  181. if (pConn = CIPConnList::Find(pSock, Name))
  182. {
  183. // Reset counters and flags.
  184. pConn->m_BadPwdCnt = 0;
  185. pConn->m_SuspendVal = ((DWORD)pMe->m_ConnectionDelay * 1000 * 60);
  186. pConn->m_IsHacker = FALSE;
  187. }
  188. return 0;
  189. }
  190. int CIPchkSock::OnVerifyIPAddress(int Event, WPARAM wParam, LPARAM lParam)
  191. {
  192. return 0;
  193. }
  194. int CallOnConnect(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  195. {
  196. return ((CIPchkSock *)Origin)->OnConnect(Event, wParam, lParam);
  197. }
  198. int CallOnVerifyIPAddress(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  199. {
  200. return ((CIPchkSock *)Origin)->OnVerifyIPAddress(Event, wParam, lParam);
  201. }
  202. int CallOnBadPassword(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  203. {
  204. return ((CIPchkSock *)Origin)->OnBadPassword(Event, wParam, lParam);
  205. }
  206. int CallOnHasLoggedOn(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  207. {
  208. return ((CIPchkSock *)Origin)->OnHasLoggedOn(Event, wParam, lParam);
  209. }
  210. int CallOnVerifyLogin(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  211. {
  212. return ((CIPchkSock *)Origin)->OnVerifyLogin(Event, wParam, lParam);
  213. }
  214. // Reqired function if sockets extentions are used
  215. // Creates a new socket derived 
  216. int CallOnSocketIsDestroyed(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  217. {
  218. delete (CIPchkSock *)Origin; // CSocketAPI destructor will delete references
  219. return 0;
  220. }
  221. // Required function
  222. int CallApiInitInstance(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  223. {
  224. return ((CIPchkExt *)Origin)->ApiInitInstance(Event, wParam, lParam);
  225. }
  226. // Required function
  227. int CallApiExitInstance(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  228. {
  229. return ((CIPchkExt *)Origin)->ApiExitInstance(Event, wParam, lParam);
  230. }
  231. void CIPchkExt::LogMsg(int flag, LPCSTR Format, ...)
  232. {
  233. ASSERT(AfxIsValidAddress(this,sizeof(CIPchkExt)));
  234. ASSERT(m_pLog != NULL);
  235. ASSERT(AfxIsValidAddress(m_pLog, sizeof(CLog)));
  236. if (!ShouldLog(m_pLog, flag))
  237. return;
  238. {
  239. CString cBuf;
  240. ASSERT(AfxIsValidString(Format, FALSE));
  241. cBuf.Format("(CIPchkExt) %s", Format);
  242. va_list argList;
  243. va_start(argList, Format);
  244. m_pLog->LogMsgV(flag, cBuf, argList);
  245. va_end(argList);
  246. }
  247. }
  248. // We check _all_ sockets. This to prevent server to server transfers to
  249. // banned sites.
  250. int CallOnNewSocket(LPVOID Origin, int Event, WPARAM wParam, LPARAM lParam)
  251. {
  252. CSock *pSock = (CSock *)lParam;
  253. // Create a new CNTFTPConn object and link it to the calls we will use.
  254. CDllInfo *pDLL = pMe->GetDLLInfo();
  255. ASSERT(pDLL != NULL);
  256. if (pDLL == NULL)
  257. return 0;
  258. CIPchkSock *pConn = new CIPchkSock;
  259. pConn->pSock = pSock; // Required
  260. pSock->m_Funcs[CSock::iOnSocketIsDestroyed].AddLast(pDLL, CSock::iOnSocketIsDestroyed, pConn, CallOnSocketIsDestroyed);
  261. pSock->m_Funcs[CSock::iOnConnect].AddLast(pDLL, CSock::iOnConnect, pConn, CallOnConnect);
  262. pSock->m_Funcs[CSock::iOnVerifyIPAddress].AddLast(pDLL, CSock::iOnVerifyIPAddress, pConn, CallOnVerifyIPAddress);
  263. pSock->m_Funcs[CSock::iOnBadPassword].AddLast(pDLL, CSock::iOnBadPassword, pConn, CallOnBadPassword);
  264. pSock->m_Funcs[CSock::iOnHasLoggedOn].AddLast(pDLL, CSock::iOnHasLoggedOn, pConn, CallOnHasLoggedOn);
  265. pSock->m_Funcs[CSock::iOnVerifyLogin].AddLast(pDLL, CSock::iOnVerifyLogin, pConn, CallOnVerifyLogin);
  266. return 0;
  267. }
  268. //////////////////////////////////////////////////////////////////////////////////////////
  269. // CIPConnList
  270. CIPConnList::CIPConnList(LPCSTR Name)
  271. {
  272. m_Name = Name;
  273. m_BadPwdCnt = 0;
  274. m_ExpiryVal = 1000 * 60 * 60; // Remember a connection for 1 hours
  275. m_SuspendVal = 0;
  276. m_IsHacker = FALSE;
  277. }
  278. CIPConnList::~CIPConnList()
  279. {
  280. }
  281. void CIPConnList::KillAll(CIPchkExt *pExt)
  282. {
  283. CIPConnList *pConn;
  284. while(pConn = (CIPConnList *)pExt->m_History.GetAndDeleteFirst())
  285. delete pConn;
  286. }
  287. // Verify if a connection can be accepted.
  288. // Called from OnConnect()
  289. BOOL CIPConnList::VerifyConnection(CSock *pSock, CIPConnList **ppConn)
  290. {
  291. CIPConnList *pConn;
  292. CString Name("");
  293. BOOL Rval = TRUE;
  294. if (pConn = Find(pSock, Name))
  295. {
  296. if (pConn->m_IsHacker || pSock->IsKindOf(RUNTIME_CLASS(CTextSock)))
  297. {
  298. if (!pConn->m_Suspend.TimeOut(pConn->m_SuspendVal))
  299. {
  300. Rval = FALSE;
  301. }
  302. else
  303. pConn->m_IsHacker = FALSE; // Only hacker until timeout...
  304. if (pSock->IsKindOf(RUNTIME_CLASS(CTextSock)))
  305. {
  306. // We always reset the timeout periods on CTextSock connection 
  307. // or attempted connections...
  308. pConn->m_Suspend.Reset();
  309. pConn->m_Expiry.Reset();
  310. }
  311. }
  312. }
  313. else
  314. {
  315. // Just add the socket
  316. if (Name.IsEmpty())
  317. return FALSE; // Find() is supposed to initialize 'Name'
  318. pConn = new CIPConnList(Name);
  319. pMe->m_History.AddFirst((LPVOID)pConn);
  320. }
  321. ASSERT(pConn != NULL);
  322. // Set the suspend length.
  323. if (!pConn->m_IsHacker && !pConn->m_BadPwdCnt)
  324. {
  325. pConn->m_SuspendVal = ((DWORD)pMe->m_ConnectionDelay * 1000 * 60);
  326. }
  327. // Make sure that the expery val is larger or equal to than the suspend val
  328. pConn->m_ExpiryVal = max(pConn->m_ExpiryVal, pConn->m_SuspendVal);
  329. if (ppConn)
  330. *ppConn = pConn;
  331. return Rval;
  332. }
  333. CIPConnList *CIPConnList::Find(CSock *pSock, CString& Name)
  334. {
  335. UINT Dummy;
  336. if (!pMe)
  337. return FALSE; // Dll not loaded. Something bad is going on...
  338. if (!pSock->GetPeerName(Name, Dummy))
  339. {
  340. pMe->LogMsg(LOGF_WARNINGS,"CIPConnList::Find() - Can't resolve IP name. Connection refused.");
  341. return FALSE;
  342. }
  343. return Find(Name);
  344. }
  345. CIPConnList *CIPConnList::Find(LPCSTR Name)
  346. {
  347. if (!pMe)
  348. return NULL; // Dll not loaded. Something bad is going on...
  349. for(CLinkedListItem *Item = pMe->m_History.First(); Item;)
  350. {
  351. CLinkedListItem *Curr = Item;
  352. Item = pMe->m_History.Next(Item);
  353. CIPConnList *pConn = (CIPConnList *)pMe->m_History.Ptr(Curr);
  354. if (pConn->m_Expiry.TimeOut(pConn->m_ExpiryVal))
  355. {
  356. pMe->m_History.DeleteItem(Curr);
  357. delete pConn;
  358. continue;
  359. }
  360. if (pConn->m_Name == Name)
  361. return pConn;
  362. }
  363. return NULL;
  364. }
  365. // Check if a connection is banned.
  366. // Verification is done on both IP name and DNS name.
  367. // Exceptions override denials.
  368. // Scan order: Server, class, group, user
  369. BOOL CIPConnList::IsBanned(USER User, CSock *pSock)
  370. {
  371. USER ParseOrder[5];
  372. memset(&ParseOrder, 0, sizeof(ParseOrder));
  373. int Index;
  374. BOOL Denied = FALSE;
  375. if (User == INVALID_USER_VALUE)
  376. {
  377. // Use the system list only
  378. ParseOrder[0] = CUsr::FindUser(UT_SYSTEM, "*");
  379. // Don't do anything if the shitlist is disabled
  380. if (CUsr::GetRecursiveParam(ParseOrder[0], "Disable IP Shitlist", FALSE) == TRUE)
  381. return FALSE;
  382. }
  383. else
  384. {
  385. // Don't do anything if the shitlist is disabled
  386. if (CUsr::GetRecursiveParam(User, "Disable IP Shitlist", FALSE) == TRUE)
  387. return FALSE;
  388. // Full scan
  389. Index = 0;
  390. USER Test;
  391. if ((Test = CUsr::GetUserSystem(User)) != INVALID_USER_VALUE)
  392. ParseOrder[Index++] = Test;
  393. if ((Test = CUsr::GetUserClass(User)) != INVALID_USER_VALUE)
  394. ParseOrder[Index++] = Test;
  395. if ((Test = CUsr::GetUserGroup(User)) != INVALID_USER_VALUE)
  396. ParseOrder[Index++] = Test;
  397. ParseOrder[Index] = User;
  398. }
  399. // Check shitlist
  400. for(Index = 0; ParseOrder[Index]; Index++)
  401. {
  402. CString AccessList;
  403. CUsr::GetParam(ParseOrder[Index], "IP Shitlist", "", AccessList);
  404. if (!AccessList.IsEmpty())
  405. {
  406. TranslateList(AccessList);
  407. Denied = IPGenericIsIpInList(m_Name, AccessList);
  408. if (!Denied && (m_Name != pSock->m_DNSName))
  409. Denied = IPGenericIsIpInList(pSock->m_DNSName, AccessList);
  410. if (Denied)
  411. break;
  412. }
  413. }
  414. if (Denied)
  415. {
  416. // Check viplist
  417. for(Index = 0; ParseOrder[Index]; Index++)
  418. {
  419. CString AccessList;
  420. CUsr::GetParam(ParseOrder[Index], "IP Viplist", "", AccessList);
  421. if (!AccessList.IsEmpty())
  422. {
  423. TranslateList(AccessList);
  424. Denied = (IPGenericIsIpInList(m_Name, AccessList) == FALSE);
  425. if (Denied && (m_Name != pSock->m_DNSName))
  426. Denied = (IPGenericIsIpInList(pSock->m_DNSName, AccessList) == FALSE);
  427. if (!Denied)
  428. break;
  429. }
  430. }
  431. }
  432. return Denied;
  433. }
  434. /////////////////////////////////////////////////////////////////////////////////////
  435. // IP mask based pattern matching
  436. // Parse the rule and return the mask
  437. BOOL IPVerifyRule(LPCSTR Rule,int **IPmask)
  438. {
  439. int Index = 0;
  440. int FromTo = 0;
  441. int MyMask[4][2];
  442. if (!Rule || !*Rule)
  443. return FALSE;
  444. // 1.2.3.4
  445. // *.2.3.4
  446. // 1-4.200-203.*.4
  447. // Initialize
  448. memset(MyMask,0,sizeof(MyMask));
  449. while(*Rule)
  450. {
  451. // Determine token type
  452. if (*Rule == '*')
  453. {
  454. if (MyMask[Index][0])
  455. return FALSE;
  456. MyMask[Index][0] = 0;
  457. MyMask[Index][1] = 255;
  458. FromTo = 1;
  459. ++Rule;
  460. if (*Rule && (*Rule != '.'))
  461. return FALSE;
  462. }
  463. else if (*Rule == ' ')
  464. {
  465. ++Rule; // Ignore space
  466. }
  467. else if (*Rule == '-')
  468. {
  469. if (FromTo)
  470. return FALSE;
  471. ++FromTo;
  472. if (!isdigit(*++Rule))
  473. return FALSE;
  474. }
  475. else if (*Rule == '.')
  476. {
  477. if (!FromTo)
  478. MyMask[Index][1] = MyMask[Index][0];
  479. FromTo = 0;
  480. if (!isdigit(*++Rule) && (*Rule != '*'))
  481. return FALSE;
  482. if ((MyMask[Index][0] > 255) || (MyMask[Index][1] > 255))
  483. return FALSE;
  484. if (++Index == 4)
  485. return FALSE;
  486. }
  487. else
  488. {
  489. MyMask[Index][FromTo] *= 10;
  490. MyMask[Index][FromTo] += *(Rule++) - '0';
  491. if (*Rule == '*')
  492. return FALSE;
  493. }
  494. }
  495. if (Index != 3)
  496. return FALSE;
  497. if (!FromTo)
  498. MyMask[Index][1] = MyMask[Index][0];
  499. if ((MyMask[Index][0] > 255) || (MyMask[Index][1] > 255))
  500. return FALSE;
  501. if (IPmask)
  502. memcpy(IPmask,MyMask,sizeof(MyMask));
  503. return TRUE;
  504. }
  505. BOOL IPGenericIsIpInList(LPCSTR IPaddess,CString &cList)
  506. {
  507. int MyMask[4][2];
  508. int MyIp[4];
  509. int Index;
  510. CString Rules = cList;
  511. char *p = Rules.GetBuffer(1);
  512. int Match;
  513. if (!*p)
  514. return FALSE; // No rule
  515. if (inet_addr(IPaddess) == INADDR_NONE)
  516. goto name_lookup;
  517. memset(MyIp,0,sizeof(MyIp));
  518. // Parse IPaddess and get the ip address numbers
  519. if (sscanf(IPaddess,"%d.%d.%d.%d", &MyIp[0], &MyIp[1], &MyIp[2], &MyIp[3]) != 4)
  520. goto name_lookup;
  521. for(p = strtok(p,";rn"); p && *p; p = strtok(NULL, ";rn"))
  522. {
  523. if (IPVerifyRule(p,(int **)MyMask))
  524. {
  525. Match = 0;
  526. for(Index = 0; Index < 4; Index++)
  527. {
  528. if ((MyIp[Index] >= MyMask[Index][0]) && (MyIp[Index] <= MyMask[Index][1]))
  529. ++Match;
  530. }
  531. if (Match == 4)
  532. return TRUE;
  533. }
  534. else
  535. {
  536. name_lookup:
  537. if (PatternMatchesName(p, IPaddess))
  538. return TRUE;
  539. }
  540. }
  541. return FALSE;
  542. }
  543. void TranslateList(CString &Val)
  544. {
  545. CString cBuf = Val;
  546. LPSTR p = cBuf.GetBuffer(1);
  547. Val = "";
  548. for(p = strtok(p, ";rn"); p; p = strtok(NULL, ";rn"))
  549. {
  550. if (!Val.IsEmpty())
  551. Val += "rn";
  552. Val += p;
  553. }
  554. }