"Fossies" - the Fresh Open Source Software Archive

Member "openlitespeed-1.6.5/src/util/accesscontrol.cpp" (3 Jan 2020, 21690 Bytes) of package /linux/www/openlitespeed-1.6.5.src.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "accesscontrol.cpp" see the Fossies "Dox" file reference documentation.

    1 /*****************************************************************************
    2 *    Open LiteSpeed is an open source HTTP server.                           *
    3 *    Copyright (C) 2013 - 2018  LiteSpeed Technologies, Inc.                 *
    4 *                                                                            *
    5 *    This program is free software: you can redistribute it and/or modify    *
    6 *    it under the terms of the GNU General Public License as published by    *
    7 *    the Free Software Foundation, either version 3 of the License, or       *
    8 *    (at your option) any later version.                                     *
    9 *                                                                            *
   10 *    This program is distributed in the hope that it will be useful,         *
   11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of          *
   12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
   13 *    GNU General Public License for more details.                            *
   14 *                                                                            *
   15 *    You should have received a copy of the GNU General Public License       *
   16 *    along with this program. If not, see http://www.gnu.org/licenses/.      *
   17 *****************************************************************************/
   18 #include <util/accesscontrol.h>
   19 
   20 #include <util/accessdef.h>
   21 #include <util/gpointerlist.h>
   22 #include <util/pool.h>
   23 #include <util/poolalloc.h>
   24 #include <util/stringtool.h>
   25 #include <util/xmlnode.h>
   26 #include <util/sysinfo/systeminfo.h>
   27 
   28 #include <assert.h>
   29 #include <ctype.h>
   30 #include <stdlib.h>
   31 #include <string.h>
   32 #include <sys/types.h>
   33 
   34 typedef union
   35 {
   36     in6_addr    m_addr6;
   37     in_addr_t   m_addrs[4];
   38 } Addr6;
   39 
   40 
   41 AccessControl *AccessControl::s_pAccessCtrl = NULL;
   42 
   43 
   44 static int isIPv6(const char *ip_mask)
   45 {
   46     return (('[' == *ip_mask) || (strchr(ip_mask, ':')));
   47 }
   48 
   49 
   50 static int strToIPv6(char *ip, in6_addr *pAddr)
   51 {
   52     if ('[' == *ip)
   53     {
   54         ++ip;
   55         char *pEnd = ip + strlen(ip) - 1;
   56         if (*pEnd != ']')
   57             return 0;
   58         *pEnd = 0;
   59     }
   60     return inet_pton(AF_INET6, ip, pAddr);
   61 }
   62 
   63 
   64 class IP6Acc
   65 {
   66     in6_addr    m_addr;
   67     int         m_allowed;
   68 public:
   69     IP6Acc(const in6_addr &addr, int allow)
   70         : m_addr(addr)
   71         , m_allowed(allow)
   72     {}
   73     void setAccess(int allow)
   74     {   m_allowed = allow;   }
   75     int getAccess() const
   76     {   return m_allowed;   }
   77     const in6_addr &getAddr() const
   78     {   return m_addr;      }
   79 
   80     static hash_key_t hf(const void *pKey)
   81     {
   82         hash_key_t key;
   83         if (sizeof(hash_key_t) == 4)
   84         {
   85             key = *((const hash_key_t *)pKey) +
   86                   *(((const hash_key_t *)pKey) + 1) +
   87                   *(((const hash_key_t *)pKey) + 2) +
   88                   *(((const hash_key_t *)pKey) + 3);
   89         }
   90         else
   91         {
   92             key = *((const hash_key_t *)pKey) +
   93                   *(((const hash_key_t *)pKey) + 1);
   94         }
   95         return key;
   96     }
   97 
   98     static int  cmp(const void *pVal1, const void *pVal2)
   99     {
  100         return memcmp(pVal1, pVal2, 16);
  101     }
  102 
  103 
  104 
  105     LS_NO_COPY_ASSIGN(IP6Acc);
  106 };
  107 
  108 
  109 class IP6AccessControl : public THash< IP6Acc * >
  110 {
  111     typedef THash< IP6Acc * > IP6Hash;
  112 public:
  113     explicit IP6AccessControl(int initSize)
  114         : IP6Hash(initSize, IP6Acc::hf, IP6Acc::cmp)
  115     {}
  116 
  117     ~IP6AccessControl() { release_objects();  };
  118 
  119     int addUpdate(const in6_addr &ip, long allow);
  120 
  121     void remove(const in6_addr &ip)
  122     {
  123         IP6Hash::iterator iter = IP6Hash::find(&ip);
  124         if (iter != end())
  125         {
  126             delete iter.second();
  127             IP6Hash::erase(iter);
  128         }
  129     }
  130     void clear()    {   release_objects(); IP6Hash::clear();  }
  131     size_t size() const {   return IP6Hash::size();   }
  132 
  133 
  134     LS_NO_COPY_ASSIGN(IP6AccessControl);
  135 };
  136 
  137 
  138 int IP6AccessControl::addUpdate(const in6_addr &ip, long allow)
  139 {
  140     iterator iter = find(&ip);
  141     if (iter == end())
  142     {
  143         IP6Acc *pAcc = new IP6Acc(ip, allow);
  144         if (pAcc)
  145             insert(&pAcc->getAddr(), pAcc);
  146 
  147     }
  148     else
  149         iter.second()->setAccess(allow);
  150     return 0;
  151 }
  152 
  153 
  154 class SubNetNode
  155 {
  156     typedef TPointerList<SubNetNode> NodeList;
  157     NodeList  m_children;
  158     in_addr_t m_id;
  159     in_addr_t m_mask;
  160     int       m_iAllowed;
  161 public:
  162     SubNetNode(in_addr_t id, in_addr_t mask, int allowed)
  163         : m_id(id), m_mask(mask), m_iAllowed(allowed)
  164     {}
  165     ~SubNetNode();
  166 
  167     int hasAccess() const           {   return m_iAllowed;   }
  168     unsigned int getId() const      {   return m_id;        }
  169     const in_addr_t &getMask() const {   return m_mask;      }
  170     void setMask(in_addr_t mask)  {   m_mask = mask;      }
  171     void setAccess(int allow)       {   m_iAllowed = allow; }
  172 
  173     SubNetNode *insertChild(in_addr_t ip, in_addr_t mask, int allowed);
  174     SubNetNode *insertChild(SubNetNode *pNode);
  175     SubNetNode *matchNode(in_addr_t ip);
  176     void clear();
  177 
  178     void *operator new(size_t sz)
  179     {   return Pool::allocate(sizeof(SubNetNode));   }
  180     void operator delete(void *p)
  181     {   return Pool::deallocate(p, sizeof(SubNetNode));    }
  182 
  183 
  184     LS_NO_COPY_ASSIGN(SubNetNode);
  185 };
  186 
  187 
  188 SubNetNode::~SubNetNode()
  189 {
  190     clear();
  191 }
  192 
  193 
  194 void SubNetNode::clear()
  195 {
  196     NodeList::iterator iter;
  197     for (iter = m_children.begin(); iter != m_children.end(); ++iter)
  198         delete *iter;
  199     m_children.clear();
  200 }
  201 
  202 
  203 SubNetNode *SubNetNode::insertChild(in_addr_t ip, in_addr_t mask,
  204                                     int allowed)
  205 {
  206     in_addr_t id = ip & mask;
  207     SubNetNode *pNewChild = new SubNetNode(id, mask, allowed);
  208     return insertChild(pNewChild);
  209 
  210 }
  211 
  212 
  213 SubNetNode *SubNetNode::insertChild(SubNetNode *pNode)
  214 {
  215     //new( pNewChild )
  216 
  217     // the newly inserted one may be parent of other siblings
  218 
  219     NodeList::iterator iter;
  220     for (iter = m_children.begin(); iter != m_children.end();)
  221     {
  222         if (((*iter)->m_id & pNode->m_mask) == pNode->m_id)
  223         {
  224             if ((*iter)->m_mask == pNode->m_mask)
  225             {
  226                 (*iter)->m_iAllowed = pNode->m_iAllowed;
  227                 delete pNode;
  228                 return *iter;
  229             }
  230             else if (((*iter)->m_mask & pNode->m_mask) == pNode->m_mask)
  231             {
  232                 pNode->m_children.push_back(*iter);
  233                 m_children.erase(iter);
  234             }
  235             else
  236                 return (*iter)->insertChild(pNode);
  237         }
  238         else if ((pNode->m_id & (*iter)->m_mask) == (*iter)->m_id)
  239             return (*iter)->insertChild(pNode);
  240         else
  241             ++iter;
  242     }
  243 
  244     m_children.push_back(pNode);
  245 
  246     return pNode;
  247 }
  248 
  249 
  250 SubNetNode *SubNetNode::matchNode(in_addr_t ip)
  251 {
  252     NodeList::const_iterator pos;
  253 
  254     NodeList::const_iterator pEnd = m_children.end();
  255     for (pos = m_children.begin(); pos != pEnd; ++pos)
  256     {
  257         if ((ip & (*pos)->m_mask) == (*pos)->m_id)
  258             return *pos;
  259     }
  260     return NULL;
  261 }
  262 
  263 
  264 class SubNet6Node
  265 {
  266     typedef TPointerList<SubNet6Node> NodeList;
  267     NodeList  m_children;
  268     Addr6     m_id;
  269     Addr6     m_mask;
  270     int       m_allowed;
  271 public:
  272     SubNet6Node(const in6_addr &id, const in6_addr &mask, int allowed)
  273         : m_allowed(allowed)
  274     {
  275         m_id.m_addr6 = id;
  276         m_mask.m_addr6 = mask;
  277     }
  278     ~SubNet6Node();
  279 
  280     void andMask(Addr6 &dest, const Addr6 &ip, const Addr6 &mask)
  281     {
  282         dest.m_addrs[0] = ip.m_addrs[0] & mask.m_addrs[0];
  283         dest.m_addrs[1] = ip.m_addrs[1] & mask.m_addrs[1];
  284         dest.m_addrs[2] = ip.m_addrs[2] & mask.m_addrs[2];
  285         dest.m_addrs[3] = ip.m_addrs[3] & mask.m_addrs[3];
  286     }
  287     int hasAccess() const           {   return m_allowed;   }
  288     const Addr6 &getId() const      {   return m_id;        }
  289     const Addr6 &getMask() const    {   return m_mask;      }
  290     void setMask(in6_addr &mask)  {   m_mask.m_addr6 = mask;      }
  291     void setAccess(int allow)       {   m_allowed = allow; }
  292 
  293     SubNet6Node *insertChild(const in6_addr &ip, const in6_addr &mask,
  294                              int allowed);
  295     SubNet6Node *insertChild(SubNet6Node *pNode);
  296     SubNet6Node *matchNode(const in6_addr &ip);
  297     void clear();
  298 
  299     void *operator new(size_t sz)
  300     {   return Pool::allocate(sizeof(SubNet6Node));   }
  301     void operator delete(void *p)
  302     {   return Pool::deallocate(p, sizeof(SubNet6Node));    }
  303 
  304 
  305     LS_NO_COPY_ASSIGN(SubNet6Node);
  306 };
  307 
  308 
  309 SubNet6Node::~SubNet6Node()
  310 {
  311     clear();
  312 }
  313 
  314 
  315 void SubNet6Node::clear()
  316 {
  317     NodeList::iterator iter;
  318     for (iter = m_children.begin(); iter != m_children.end(); ++iter)
  319         delete *iter;
  320     m_children.clear();
  321 }
  322 
  323 
  324 SubNet6Node *SubNet6Node::insertChild(const in6_addr &ip,
  325                                       const in6_addr &mask, int allowed)
  326 {
  327     Addr6 id;
  328     andMask(id, (const Addr6 &)ip, (const Addr6 &)mask);
  329     SubNet6Node *pNewChild = new SubNet6Node(id.m_addr6, mask, allowed);
  330     return insertChild(pNewChild);
  331 
  332 }
  333 
  334 
  335 SubNet6Node *SubNet6Node::insertChild(SubNet6Node *pNode)
  336 {
  337 
  338     // the newly inserted one may be parent of other siblings
  339     NodeList::iterator iter;
  340     for (iter = m_children.begin(); iter != m_children.end();)
  341     {
  342         Addr6 id1;
  343         andMask(id1, (*iter)->m_id, (const Addr6 &)pNode->m_mask);
  344         if (GHash::cmpIpv6(&id1, &pNode->m_id) == 0)
  345         {
  346             if (GHash::cmpIpv6(&(*iter)->m_mask, &pNode->m_mask) == 0)
  347             {
  348                 (*iter)->m_allowed = pNode->m_allowed;
  349                 delete pNode;
  350                 return *iter;
  351             }
  352             else
  353             {
  354                 pNode->m_children.push_back(*iter);
  355                 m_children.erase(iter);
  356             }
  357         }
  358         else
  359         {
  360             Addr6 id2;
  361             andMask(id2, pNode->m_id, (const Addr6 &)((*iter)->m_mask));
  362             if (GHash::cmpIpv6(&id2, &(*iter)->m_id) == 0)
  363                 return (*iter)->insertChild(pNode);
  364             else
  365                 ++iter;
  366         }
  367     }
  368 
  369     m_children.push_back(pNode);
  370 
  371     return pNode;
  372 }
  373 
  374 
  375 SubNet6Node *SubNet6Node::matchNode(const in6_addr &ip)
  376 {
  377     NodeList::const_iterator pos;
  378 
  379     NodeList::const_iterator pEnd = m_children.end();
  380     for (pos = m_children.begin(); pos != pEnd; ++pos)
  381     {
  382         Addr6 id;
  383         andMask(id, (const Addr6 &)ip, (*pos)->m_mask);
  384         if (GHash::cmpIpv6(&id, &(*pos)->m_id) == 0)
  385             return *pos;
  386     }
  387     return NULL;
  388 }
  389 
  390 
  391 AccessControl::AccessControl()
  392     : m_ipCtrl(13)
  393     , m_pIp6Ctrl(NULL)
  394 {
  395     m_pRoot = new SubNetNode(0, 0, true);
  396     in6_addr addr;
  397     memset(&addr, 0, sizeof(addr));
  398     m_pRoot6 = new SubNet6Node(addr, addr, true);
  399 }
  400 
  401 
  402 AccessControl::~AccessControl()
  403 {
  404     delete m_pRoot;
  405     delete m_pRoot6;
  406     if (m_pIp6Ctrl)
  407         delete m_pIp6Ctrl;
  408 }
  409 
  410 
  411 int AccessControl::hasAccess(const struct sockaddr *pAddr) const
  412 {
  413     switch (pAddr->sa_family)
  414     {
  415     case AF_UNSPEC:
  416         assert(false);
  417     case AF_INET:
  418         {
  419             return hasAccess((((const sockaddr_in *)pAddr)->sin_addr).s_addr);
  420         }
  421     case AF_INET6:
  422         return hasAccess(((const sockaddr_in6 *)pAddr)->sin6_addr);
  423         assert(false);
  424     case AF_UNIX:
  425         assert(false);
  426     }
  427     return false;
  428 }
  429 
  430 
  431 int AccessControl::hasAccess(in_addr_t ip) const
  432 {
  433     if (m_ipCtrl.size())
  434     {
  435         IPAcc pos = m_ipCtrl.find(ip);
  436         if (!pos.isNull())
  437             return pos.getAccess();
  438     }
  439 
  440     SubNetNode *pCurNode = m_pRoot;
  441     SubNetNode *pNextNode;
  442 
  443     while ((pNextNode = pCurNode->matchNode(ip)) != NULL)
  444         pCurNode = pNextNode;
  445 
  446     return pCurNode->hasAccess();
  447 }
  448 
  449 
  450 int AccessControl::hasAccess(const char *pchIP) const
  451 {
  452     if (!isIPv6(pchIP))
  453     {
  454         in_addr ip;
  455         if (0 >= inet_pton(AF_INET, pchIP, &ip))
  456             return false; //err in conversion
  457         return hasAccess(ip.s_addr);
  458     }
  459     else
  460     {
  461         char achTemp[128];
  462         memccpy(achTemp, pchIP, 0, 127);
  463         achTemp[127] = 0;
  464         in6_addr ip;
  465         if (0 >= strToIPv6(achTemp, &ip))
  466             return false;
  467         return hasAccess(ip);
  468     }
  469 }
  470 
  471 
  472 static int checkTrust(char *ip_mask, int allowed)
  473 {
  474     int len = strlen(ip_mask);
  475     char ch = *(ip_mask + len - 1);
  476     if ((ch == 't') || (ch == 'T'))
  477     {
  478         if (allowed)
  479             allowed = AC_TRUST;
  480         *(ip_mask + len - 1) = 0;
  481     }
  482     return allowed;
  483 }
  484 
  485 
  486 int AccessControl::addIPControl(const char *pchIP, int allowed)
  487 {
  488     char achTemp[128];
  489     memccpy(achTemp, pchIP, 0, 127);
  490     achTemp[127] = 0;
  491     allowed = checkTrust(achTemp, allowed);
  492     if (!isIPv6(achTemp))
  493     {
  494         in_addr ip;
  495         if (0 >= inet_pton(AF_INET, achTemp, &ip))
  496             return LS_FAIL; //err in conversion
  497         return addIPControl(ip.s_addr, allowed);
  498     }
  499     else
  500     {
  501         in6_addr ip;
  502         if (0 >= strToIPv6(achTemp, &ip))
  503             return false;
  504         return addIPControl(ip, allowed);
  505     }
  506 }
  507 
  508 
  509 void AccessControl::removeIPControl(const char *pchIP)
  510 {
  511     if (!isIPv6(pchIP))
  512     {
  513         in_addr ip;
  514         if (0 >= inet_pton(AF_INET, pchIP, &ip))
  515             return; //err in conversion
  516         return removeIPControl(ip.s_addr);
  517     }
  518     else
  519     {
  520         char achTemp[128];
  521         memccpy(achTemp, pchIP, 0, 127);
  522         achTemp[127] = 0;
  523         in6_addr ip;
  524         if (0 >= strToIPv6(achTemp, &ip))
  525             return;
  526         if (IN6_IS_ADDR_V4MAPPED(&ip))
  527             return removeIPControl(((Addr6 *)&ip)->m_addrs[3]);
  528         if (m_pIp6Ctrl)
  529             return m_pIp6Ctrl->remove(ip);
  530     }
  531 }
  532 
  533 
  534 int AccessControl::addSubNetControl(in_addr_t subNet,
  535                                     in_addr_t mask,
  536                                     int allowed)
  537 {
  538     if (mask == 0xffffffff)
  539         return addIPControl(subNet, allowed);
  540     if (mask == 0)
  541     {
  542         m_pRoot->setAccess(allowed);
  543         return 0;
  544     }
  545 
  546     return insSubNetControl(subNet, mask, allowed);
  547 }
  548 
  549 
  550 int AccessControl::insSubNetControl(in_addr_t subNet,
  551                                     in_addr_t mask,
  552                                     int allowed)
  553 {
  554     SubNetNode *pCur = m_pRoot;
  555     /*
  556         while ( ( pNext = pCur->matchNode( subNet ) ) != NULL )
  557         {
  558             if ( pNext->getMask() == mask )
  559             {
  560                 pNext->setAccess( allowed );
  561                 return 1; // confict with previous
  562             }
  563             pCur = pNext;
  564         }
  565     */
  566 
  567     pCur->insertChild(subNet, mask, allowed);
  568     return 0;
  569 }
  570 
  571 
  572 static unsigned char s_maskbits[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
  573 int AccessControl::parseNetmask(const char *netMask, int maxbits,
  574                                 void *pMask)
  575 {
  576     char *pEnd;
  577     if (!isdigit(*netMask))
  578         return LS_FAIL;
  579     int bits = strtol(netMask, &pEnd, 10);
  580     if ((*pEnd == 0) && (bits >= 0) && (bits < maxbits))
  581     {
  582         memset(pMask, 0xff, bits / 8);
  583         memset(((char *)pMask) + (bits + 7) / 8, 0, (maxbits - bits) / 8);
  584         if (bits % 8)
  585             *(((char *)pMask) + bits / 8) = s_maskbits[ bits % 8 ];
  586         return 0;
  587     }
  588     else
  589         return ((maxbits != 32) || (0 >= inet_pton(AF_INET, netMask, pMask)));
  590 }
  591 
  592 
  593 int AccessControl::addSubNetControl(const char *ip, const char *netMask,
  594                                     int allowed)
  595 {
  596     //FIXME:no validation of string
  597     if (!isIPv6(ip))
  598     {
  599         in_addr subNet, mask;
  600         if (0 >= inet_pton(AF_INET, ip, &subNet))
  601             return LS_FAIL;
  602         if (0 != parseNetmask(netMask, 32, &mask))
  603             return LS_FAIL;
  604         return addSubNetControl(subNet.s_addr, mask.s_addr, allowed);
  605     }
  606     in6_addr addr, mask;
  607     char achTemp[128];
  608     memccpy(achTemp, ip, 0, 127);
  609     achTemp[127] = 0;
  610     if (0 >= strToIPv6(achTemp, &addr))
  611         return LS_FAIL;
  612     if (0 != parseNetmask(netMask, 128, &mask))
  613         return LS_FAIL;
  614     return addSubNetControl(addr, mask, allowed);
  615 }
  616 
  617 
  618 int AccessControl::addIPv4(const char *ip_mask, int allowed)
  619 {
  620     char ip[256], mask[256];
  621     const char *p0;
  622 
  623     mask[0] = 0;
  624     p0 = strchr(ip_mask, '*');
  625     if (p0 == NULL)
  626         p0 = (char *)ip_mask + strlen(ip_mask) + 1;
  627     if (p0 <= ip_mask)
  628         return 0;
  629     memccpy(ip, ip_mask, 0, p0 - ip_mask);
  630     ip[p0 - ip_mask - 1] = 0;
  631 
  632     int c = 0;
  633     p0 = (char *)ip_mask;
  634     while (*p0)
  635     {
  636         if (*p0 == '.')
  637             ++c;
  638         else if (*p0 == '*')
  639             break;
  640         ++p0;
  641     }
  642     if (*p0 != '*')
  643         ++c;
  644     if (c == 4)
  645         return addIPControl(ip, allowed);
  646     int i = 0;
  647     for (; i < c; ++ i)
  648     {
  649         if (i == 0)
  650             strcat(mask, "255");
  651         else
  652             strcat(mask, ".255");
  653     }
  654     for (i = 0; i < 4 - c; ++ i)
  655     {
  656         strcat(ip, ".0");
  657         strcat(mask, ".0");
  658     }
  659     in_addr subNet, netmask;
  660     if (0 >= inet_pton(AF_INET, ip, &subNet))
  661         return LS_FAIL;
  662     if (0 >= inet_pton(AF_INET, mask, &netmask))
  663         return LS_FAIL;
  664 
  665     return addSubNetControl(subNet.s_addr, netmask.s_addr, allowed);
  666 }
  667 
  668 
  669 int AccessControl::addSubNetControl(const char *ip_mask, int allowed)
  670 {
  671     //IPv4 formats: "192.168.1.*", "192.168.128.5/255.255.128.0", "192.168.128", "192.168.128.0/24"
  672     //IPv6: "::", "::1", "[::1]", "fdab:78a3:3487::1/120"
  673     const char *p0;
  674     char ip[256], mask[256];
  675     char achTemp[128];
  676     memccpy(achTemp, ip_mask, 0, 127);
  677     achTemp[127] = 0;
  678     allowed = checkTrust(achTemp, allowed);
  679     ip_mask = achTemp;
  680     p0 = strchr(ip_mask, '/');
  681     if (p0 != NULL)
  682     {
  683         memccpy(ip, ip_mask, 0, p0 - ip_mask);
  684         ip[p0 - ip_mask] = 0;
  685         strcpy(mask, p0 + 1);
  686         return addSubNetControl(ip, mask, allowed);
  687     }
  688     if ((strcmp(ip_mask, "*") == 0) || (strcasecmp(ip_mask, "ALL") == 0))
  689     {
  690         m_pRoot->setAccess(allowed);
  691         m_pRoot6->setAccess(allowed);
  692         return 0;
  693     }
  694     else
  695     {
  696         if (!isIPv6(achTemp))
  697             return addIPv4(achTemp, allowed);
  698         else
  699             return addIPControl(achTemp, allowed);
  700     }
  701 
  702 }
  703 
  704 
  705 void AccessControl::clear()
  706 {
  707     m_pRoot->clear();
  708     m_pRoot6->clear();
  709     m_ipCtrl.clear();
  710 }
  711 
  712 
  713 int AccessControl::addList(const char *pList, int allow)
  714 {
  715     char achBuf[128];
  716     int added = 0;
  717     while (pList)
  718     {
  719         const char *p = strpbrk(pList, ", \r\n");
  720         const char *pEnd;
  721         if (p)
  722             pEnd = p++;
  723         else
  724             pEnd = pList + strlen(pList);
  725         int len = StringTool::strTrim(pList, pEnd);
  726         if ((len > 0) && (len < (int)sizeof(achBuf)))
  727         {
  728             memccpy(achBuf, pList, 0, len);
  729             achBuf[len] = 0;
  730             //if ( strchr( achBuf, '*' )||( strchr( achBuf, '/' ))
  731             //    || (achBuf[len-1] == '.' )
  732             //    || (strcasecmp( achBuf, "ALL") == 0 ))
  733             if (achBuf[len - 1] == '.')
  734                 achBuf[len - 1] = 0;
  735             added += (addSubNetControl(achBuf, allow) == 0);
  736             //else
  737             //    added += ( addIPControl( achBuf, allow ) == 0 );
  738 
  739         }
  740         pList = p;
  741     }
  742     return added;
  743 }
  744 
  745 
  746 int AccessControl::hasAccess(const in6_addr &ip) const
  747 {
  748     if (m_pIp6Ctrl)
  749     {
  750         IP6AccessControl::iterator iter = m_pIp6Ctrl->find(&ip);
  751         if (iter != m_pIp6Ctrl->end())
  752             return iter.second()->getAccess();
  753     }
  754     SubNet6Node *pCurNode = m_pRoot6;
  755     SubNet6Node *pNextNode;
  756 
  757     while ((pNextNode = pCurNode->matchNode(ip)) != NULL)
  758         pCurNode = pNextNode;
  759 
  760     return pCurNode->hasAccess();
  761 }
  762 
  763 
  764 int AccessControl::addIPControl(const in6_addr &ip, int allowed)
  765 {
  766     if (IN6_IS_ADDR_V4MAPPED(&ip))
  767         return addIPControl(((Addr6 *)&ip)->m_addrs[3], allowed);
  768     Addr6 *p = (Addr6 *)&ip;
  769     if ((!p->m_addrs[0]) && (!p->m_addrs[1]) && (!p->m_addrs[2])
  770         && (!p->m_addrs[3]))
  771     {
  772         m_pRoot6->setAccess(allowed);
  773         return 0;
  774     }
  775     if (!m_pIp6Ctrl)
  776         m_pIp6Ctrl = new IP6AccessControl(13);
  777     if (m_pIp6Ctrl)
  778         return m_pIp6Ctrl->addUpdate(ip, allowed);
  779     return LS_FAIL;
  780 }
  781 
  782 
  783 int AccessControl::addSubNetControl(const in6_addr &subNet,
  784                                     const in6_addr &mask,
  785                                     int allowed)
  786 {
  787     Addr6 *p = (Addr6 *)&mask;
  788     if (IN6_IS_ADDR_V4MAPPED(&subNet))
  789     {
  790         if (p->m_addrs[3])
  791             return addSubNetControl(((Addr6 *)&subNet)->m_addrs[3], p->m_addrs[3],
  792                                     allowed);
  793         return LS_FAIL;
  794     }
  795     if ((0xffffffff == p->m_addrs[3]) &&
  796         (0xffffffff == p->m_addrs[2]) &&
  797         (0xffffffff == p->m_addrs[1]) &&
  798         (0xffffffff == p->m_addrs[0]))
  799         return addIPControl(subNet, allowed);
  800     if ((!p->m_addrs[0]) && (!p->m_addrs[1]) && (!p->m_addrs[2])
  801         && (!p->m_addrs[3]))
  802     {
  803         m_pRoot6->setAccess(allowed);
  804         return 0;
  805     }
  806 
  807     return insSubNetControl(subNet, mask, allowed);
  808 }
  809 
  810 
  811 int AccessControl::insSubNetControl(const in6_addr &subNet,
  812                                     const in6_addr &mask,
  813                                     int allowed)
  814 {
  815     SubNet6Node *pCur = m_pRoot6;
  816     SubNet6Node *pNext;
  817     while ((pNext = pCur->matchNode(subNet)) != NULL)
  818     {
  819         if (GHash::cmpIpv6(&pNext->getMask(), &mask) == 0)
  820         {
  821             pNext->setAccess(allowed);
  822             return 1; // confict with previous
  823         }
  824         pCur = pNext;
  825     }
  826 
  827     pCur->insertChild(subNet, mask, allowed);
  828     return 0;
  829 }
  830 
  831 
  832 int AccessControl::isAvailable(const XmlNode *pNode)
  833 {
  834     const XmlNode *pNode1 = pNode->getChild("accessControl");
  835 
  836     if (pNode1)
  837     {
  838         const char *pAllow = pNode1->getChildValue("allow");
  839 
  840         if (pAllow || pNode1->getChildValue("deny"))
  841             return 1;
  842     }
  843 
  844     return 0;
  845 }
  846 
  847 
  848 
  849 
  850