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

📄 ipacl.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * ipacl.cxx
 *
 * IP Access Control Lists
 *
 * Portable Windows Library
 *
 * Copyright (c) 2002 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: ipacl.cxx,v $
 * Revision 1.1  2006/06/29 04:18:02  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.16  2005/01/26 05:37:58  csoutheren
 * Added ability to remove config file support
 *
 * Revision 1.15  2004/04/03 08:22:20  csoutheren
 * Remove pseudo-RTTI and replaced with real RTTI
 *
 * Revision 1.14  2002/11/06 22:47:25  robertj
 * Fixed header comment (copyright etc)
 *
 * Revision 1.13  2002/07/16 10:05:01  robertj
 * Fixed GNU warning
 *
 * Revision 1.12  2002/07/16 10:02:49  robertj
 * Fixed MSVC warning
 *
 * Revision 1.11  2002/07/16 09:58:51  robertj
 * Fixed compatibility with unix htonl(), use platform independent function!
 * Allow number of bits of 32 to be a full mask, ie a single host ip.
 *
 * Revision 1.10  2002/07/16 08:00:49  robertj
 * Fixed correct endian-ness of mask when specifed in bits.
 *
 * Revision 1.9  2002/06/19 04:03:21  robertj
 * Added default allowance boolean if ACL empty.
 * Added ability to override the creation of ACL entry objects with descendents
 *   so an application can add information/functionality to each entry.
 *
 * Revision 1.8  2002/02/13 02:08:12  robertj
 * Added const to IsAllowed() function.
 * Added missing function that takes a socket.
 *
 * 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 PNEW


PIpAccessControlEntry::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(PIsDescendant(&obj, PIpAccessControlEntry), 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 {
    DWORD bits = postSlash.AsUnsigned();
    if (bits > 32)
      mask = PSocket::Host2Net(bits);
    else
      mask = PSocket::Host2Net((DWORD)(0xffffffff << (32 - bits)));
  }

  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;
  }

⌨️ 快捷键说明

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