⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipacl.cxx

📁 mgcp协议源代码。支持多种编码:g711
💻 CXX
字号:
/* * ipacl.cxx * * PWLib application source file for rcsd * * Main program entry point. * * Copyright 1998 Equivalence Pty. Ltd. * * $Log: ipacl.cxx,v $ * Revision 1.7  1999/02/25 13:01:11  robertj * Fixed subtle bug in GNU compiler not automatically casting IP address. * * Revision 1.6  1999/02/25 11:10:52  robertj * Fixed count of non-hidden entries in config file. * * Revision 1.5  1999/02/25 05:05:15  robertj * Added missing test for hidden entries not to be written to config file * * Revision 1.4  1999/02/08 08:05:39  robertj * Changed semantics of IP access control list for empty list. * * Revision 1.3  1999/01/31 10:14:07  robertj * Changed about dialog to be full company name * * Revision 1.2  1999/01/31 08:10:33  robertj * Fixed PConfig file save, out by one error in array subscript. * * Revision 1.1  1999/01/31 00:59:26  robertj * Added IP Access Control List class to PTLib Components * */#include <ptlib.h>#include <ptclib/ipacl.h>#define new PNEWPIpAccessControlEntry::PIpAccessControlEntry(PIPSocket::Address addr,                                             PIPSocket::Address msk,                                             BOOL allow)  : address(addr), mask(msk){  allowed = allow;  hidden = FALSE;}PIpAccessControlEntry::PIpAccessControlEntry(const PString & description)  : address(0), mask(0xffffffff){  Parse(description);}PIpAccessControlEntry & PIpAccessControlEntry::operator=(const PString & description){  Parse(description);  return *this;}PIpAccessControlEntry & PIpAccessControlEntry::operator=(const char * description){  Parse(description);  return *this;}PObject::Comparison PIpAccessControlEntry::Compare(const PObject & obj) const{  PAssert(obj.IsDescendant(Class()), PInvalidCast);  const PIpAccessControlEntry & other = (const PIpAccessControlEntry &)obj;  // The larger the mask value, th more specific the range, so earlier in list  if (mask > other.mask)    return LessThan;  if (mask < other.mask)    return GreaterThan;  if (!domain && !other.domain)    return domain.Compare(other.domain);  if (address > other.address)    return LessThan;  if (address < other.address)    return GreaterThan;  return EqualTo;}void PIpAccessControlEntry::PrintOn(ostream & strm) const{  if (!allowed)    strm << '-';  if (hidden)    strm << '@';  if (domain.IsEmpty())    strm << address;  else if (domain[0] != '\xff')    strm << domain;  else {    strm << "ALL";    return;  }  if (mask != 0 && mask != 0xffffffff)    strm << '/' << mask;}void PIpAccessControlEntry::ReadFrom(istream & strm){  char buffer[200];  strm >> ws >> buffer;  Parse(buffer);}BOOL PIpAccessControlEntry::Parse(const PString & description){  domain = PString();  address = 0;  if (description.IsEmpty())    return FALSE;  // Check for the allow/deny indication in first character of description  BOOL offset = 1;  if (description[0] == '-')    allowed = FALSE;  else {    allowed = TRUE;    if (description[0] != '+')      offset = 0;  }  // Check for indication entry is from the hosts.allow/hosts.deny file  hidden = FALSE;  if (description[offset] == '@') {    offset++;    hidden = TRUE;  }  if (description.Mid(offset) *= "all") {    domain = "\xff";    mask = 0;    return TRUE;  }  PINDEX slash = description.Find('/', offset);  PString preSlash = description(offset, slash-1);  if (preSlash[0] == '.') {    // If has a leading dot then assume a domain, ignore anything after slash    domain = preSlash;    mask = 0;    return TRUE;  }  if (strspn(preSlash, "0123456789.") != (size_t)preSlash.GetLength()) {    // If is not all numbers and dots can't be an IP number so assume hostname    domain = preSlash;  }  else if (preSlash[preSlash.GetLength()-1] != '.') {    // Must be explicit IP number if doesn't end in dot    address = preSlash;  }  else {    // Must be partial IP number, count the dots!    PINDEX dot = preSlash.Find('.', preSlash.Find('.')+1);    if (dot == P_MAX_INDEX) {      // One dot      preSlash += "0.0.0";      mask = "255.0.0.0";    }    else if ((dot = preSlash.Find('.', dot+1)) == P_MAX_INDEX) {      // has two dots      preSlash += "0.0";      mask = "255.255.0.0";    }    else if (preSlash.Find('.', dot+1) == P_MAX_INDEX) {      // has three dots      preSlash += "0";      mask = "255.255.255.0";    }    else {      // Has more than three dots!      return FALSE;    }    address = preSlash;    return TRUE;  }  if (slash == P_MAX_INDEX) {    // No slash so assume a full mask    mask = 0xffffffff;    return TRUE;  }  PString postSlash = description.Mid(slash+1);  if (strspn(postSlash, "0123456789.") != (size_t)postSlash.GetLength()) {    domain = PString();    address = 0;    return FALSE;  }  if (postSlash.Find('.') != P_MAX_INDEX)    mask = postSlash;  else {    unsigned bits = postSlash.AsUnsigned();    if (bits >= 32)      mask = bits;    else#if PBYTE_ORDER==PLITTLE_ENDIAN      mask = 0xffffffff >> (32 - bits);#else      mask = 0xffffffff << (32 - bits);#endif  }  if (mask == 0)    domain = "\xff";  address = (DWORD)address & (DWORD)mask;  return TRUE;}PString PIpAccessControlEntry::AsString() const{  PStringStream str;  str << *this;  return str;}BOOL PIpAccessControlEntry::IsValid(){  return address != 0 || !domain;}BOOL PIpAccessControlEntry::Match(PIPSocket::Address & addr){  switch (domain[0]) {    case '\0' : // Must have address field set      break;    case '.' :  // Are a domain name      return PIPSocket::GetHostName(addr).Right(domain.GetLength()) *= domain;    case '\xff' :  // Match all      return TRUE;    default : // All else must be a hostname      if (!PIPSocket::GetHostAddress(domain, address))        return FALSE;  }  return (address & mask) == (addr & mask);}///////////////////////////////////////////////////////////////////////////////PIpAccessControlList::PIpAccessControlList(){}static BOOL ReadConfigFileLine(PTextFile & file, PString & line){  line = PString();  do {    if (!file.ReadLine(line))      return FALSE;  } while (line.IsEmpty() || line[0] == '#');  PINDEX lastCharPos;  while (line[lastCharPos = line.GetLength()-1] == '\\') {    PString str;    if (!file.ReadLine(str))      return FALSE;    line[lastCharPos] = ' ';    line += str;  }  return TRUE;}static void ParseConfigFileExcepts(const PString & str,                                   PStringList & entries,                                   PStringList & exceptions){  PStringArray terms = str.Tokenise(' ', FALSE);  BOOL hadExcept = FALSE;  PINDEX d;  for (d = 0; d < terms.GetSize(); d++) {    if (terms[d] == "EXCEPT")      hadExcept = TRUE;    else if (hadExcept)      exceptions.AppendString(terms[d]);    else      entries.AppendString(terms[d]);  }}static BOOL SplitConfigFileLine(const PString & line, PString & daemons, PString & clients){  PINDEX colon = line.Find(':');  if (colon == P_MAX_INDEX)    return FALSE;  daemons = line.Left(colon).Trim();  PINDEX other_colon = line.Find(':', ++colon);  clients = line(colon, other_colon-1).Trim();  return TRUE;}static BOOL IsDaemonInConfigFileLine(const PString & daemon, const PString & daemons){  PStringList daemonsIn, daemonsOut;  ParseConfigFileExcepts(daemons, daemonsIn, daemonsOut);  for (PINDEX in = 0; in < daemonsIn.GetSize(); in++) {    if (daemonsIn[in] == "ALL" || daemonsIn[in] == daemon) {      PINDEX out;      for (out = 0; out < daemonsOut.GetSize(); out++) {        if (daemonsOut[out] == daemon)          break;      }      if (out >= daemonsOut.GetSize())        return TRUE;    }  }  return FALSE;}static BOOL ReadConfigFile(PTextFile & file,                           const PString & daemon,                           PStringList & clientsIn,                           PStringList & clientsOut){  PString line;  while (ReadConfigFileLine(file, line)) {    PString daemons, clients;    if (SplitConfigFileLine(line, daemons, clients) &&        IsDaemonInConfigFileLine(daemon, daemons)) {      ParseConfigFileExcepts(clients, clientsIn, clientsOut);      return TRUE;    }  }  return FALSE;}BOOL PIpAccessControlList::InternalLoadHostsAccess(const PString & daemonName,                                                   const char * filename,                                                   BOOL allowance){  PTextFile file;  if (!file.Open(PProcess::GetOSConfigDir() + filename, PFile::ReadOnly))    return TRUE;  BOOL ok = TRUE;  PStringList clientsIn;  PStringList clientsOut;  while (ReadConfigFile(file, daemonName, clientsIn, clientsOut)) {    PINDEX i;    for (i = 0; i < clientsOut.GetSize(); i++) {      if (!Add((allowance ? "-@" : "+@") + clientsOut[i]))        ok = FALSE;    }    for (i = 0; i < clientsIn.GetSize(); i++) {      if (!Add((allowance ? "+@" : "-@") + clientsIn[i]))        ok = FALSE;    }  }  return ok;}BOOL PIpAccessControlList::LoadHostsAccess(const char * daemonName){  PString daemon;  if (daemonName != NULL)    daemon = daemonName;  else    daemon = PProcess::Current().GetName();  return InternalLoadHostsAccess(daemon, "hosts.allow", TRUE) &  // Really is a single &         InternalLoadHostsAccess(daemon, "hosts.deny", FALSE);}static const char DefaultConfigName[] = "IP Access Control List";BOOL PIpAccessControlList::Load(PConfig & cfg){  return Load(cfg, DefaultConfigName);}BOOL PIpAccessControlList::Load(PConfig & cfg, const PString & baseName){  BOOL ok = TRUE;  PINDEX count = cfg.GetInteger(baseName & "Array Size");  for (PINDEX i = 1; i <= count; i++) {    if (!Add(cfg.GetString(baseName & PString(PString::Unsigned, i))))      ok = FALSE;  }  return ok;}void PIpAccessControlList::Save(PConfig & cfg){  Save(cfg, DefaultConfigName);}void PIpAccessControlList::Save(PConfig & cfg, const PString & baseName){  PINDEX count = 0;  for (PINDEX i = 0; i < GetSize(); i++) {    PIpAccessControlEntry & entry = operator[](i);    if (!entry.IsHidden()) {      count++;      cfg.SetString(baseName & PString(PString::Unsigned, count), entry.AsString());    }  }  cfg.SetInteger(baseName & "Array Size", count);}BOOL PIpAccessControlList::Add(const PString & description){  PIpAccessControlEntry entry(description);  if (!entry.IsValid())    return FALSE;  return InternalAddEntry(entry);}BOOL PIpAccessControlList::Add(PIPSocket::Address addr, PIPSocket::Address mask, BOOL allow){  PIpAccessControlEntry entry(addr, mask, allow);  return InternalAddEntry(entry);}BOOL PIpAccessControlList::InternalAddEntry(PIpAccessControlEntry & entry){  PINDEX idx = GetValuesIndex(entry);  if (idx == P_MAX_INDEX)    idx = Append(new PIpAccessControlEntry(entry));  return operator[](idx).IsAllowed() == entry.IsAllowed();}BOOL PIpAccessControlList::Remove(const PString & description){  PIpAccessControlEntry entry(description);  if (!entry.IsValid())    return FALSE;  return InternalRemoveEntry(entry);}BOOL PIpAccessControlList::Remove(PIPSocket::Address addr, PIPSocket::Address mask){  PIpAccessControlEntry entry(addr, mask, TRUE);  return InternalRemoveEntry(entry);}BOOL PIpAccessControlList::InternalRemoveEntry(PIpAccessControlEntry & entry){  PINDEX idx = GetValuesIndex(entry);  if (idx == P_MAX_INDEX)    return FALSE;  RemoveAt(idx);  return TRUE;}BOOL PIpAccessControlList::IsAllowed(PIPSocket::Address address){  PINDEX size = GetSize();  if (size == 0)    return TRUE;  for (PINDEX i = 0; i < size; i++) {    PIpAccessControlEntry & entry = operator[](i);    if (entry.Match(address))      return entry.IsAllowed();  }  return FALSE;}// End of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -