reSIProcate/repro  9694
AclAdmin.cxx
Go to the documentation of this file.
00001 class Acl
00002 {
00003 
00004 
00005    private:
00006       class V6AddrMask
00007       {
00008          public:
00009             V6AddrMask(in_addr6 ip6Addr = v6Loopback, int mask = 128)
00010          friend:
00011             in_addr6 mIp6Addr;  // ?? check these types
00012             int mMask;
00013       };
00014       
00015       class V4AddrMask
00016       {
00017          public:
00018             V4AddrMask(in_addr ip4Addr = v4Loopback, int mask = 32)
00019          friend:
00020             in_addr mIp4Addr;  // ?? check these types
00021             int mMask;
00022       };
00023       
00024       typedef list<V6AddrMask> v6addrMaskList;
00025       typedef list<V4AddrMask> v4addrMaskList;
00026 
00027       v6addrMaskList mV6AclList;
00028       v4addrMaskList mV4AclList;
00029 };
00030 
00031 
00032 
00033 bool Acl::parseAcl(Data& rawInput)
00034 {
00035    // Input can be in any of these formats
00036    // localhost         localhost  (becomes 127.0.0.1/8, ::1/128 and fe80::1/64)
00037    // bare hostname     server1
00038    // FQDN              server1.example.com
00039    // IPv4 address      192.168.1.100
00040    // IPv4 + mask       192.168.1.0/24
00041    // IPv6 address      :341:0:23:4bb:0011:2435:abcd
00042    // IPv6 + mask       :341:0:23:4bb:0011:2435:abcd/80
00043    // IPv6 reference    [:341:0:23:4bb:0011:2435:abcd]
00044    // IPv6 ref + mask   [:341:0:23:4bb:0011:2435:abcd]/64
00045    
00046    ParseBuffer pb(rawInput);
00047    const char* anchor = pb.start();
00048    
00049    bool ipv4 = false;
00050    bool ipv6 = false;
00051    bool fqdn = false;
00052    Data hostOrIp;
00053    u_char in6[20];
00054    u_char in4[4];
00055    int mask;
00056    
00057    if (*pb.position() == '[')   // encountered beginning of IPv6 reference
00058    {
00059       anchor = pb.skipChar();
00060       skipToEndQuote(']');
00061       // TODO check for end of stream here
00062       
00063       pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address
00064       anchor = pb.skipChar();
00065       
00066       // try to convert into IPv6 network form
00067       if (!inet_pton6(hostOrIp.c_str(), in6))  // is this correct?
00068       {
00069          return INVALID;
00070       }
00071       ipv6 = true;
00072    }
00073    else
00074    {
00075       pb.skipToOneOf(".:");
00076       if (pb.position() == pb.end())   // We probably have a bare hostname
00077       {
00078          pb.data(hostOrIp, anchor);
00079          if (hostOrIp.lowercase() == "localhost")
00080          {
00081             // add special localhost addresses for v4 and v6 to list and return
00082             return SUCCESS;
00083          }
00084          // hostOrIp += default domain name
00085       }
00086       else if (*pb.position() == ':')     // Must be an IPv6 address
00087       {
00088          pb.skipToChar('/');
00089 
00090          pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address
00091          anchor = pb.skipChar();
00092 
00093          // try to convert into IPv6 network form
00094          if (!inet_pton6(hostOrIp.c_str(), in6))  // is this correct?
00095          {
00096             return INVALID;
00097          }
00098          ipv6 = true;
00099       }
00100       else // *pb.position() == '.'
00101       {
00102          assert( *pb.position() == '.');
00103          
00104          // Could be either an IPv4 address or an FQDN
00105          pb.skipToChar('/');
00106          pb.data(hostOrIp, anchor);  // copy the presentation form of the address
00107 
00108          // try to interpret as an IPv4 address, if that fails look it up in DNS
00109          if (inet_pton4(hostOrIp.c_str(), in4)) // is this correct?
00110          {
00111             // it was an IPv4 address
00112             ipv4 = true;
00113          }
00114          else
00115          {
00116             // hopefully it is a legal FQDN, try it.
00117             fqdn = true;
00118          }
00119       }   
00120    }
00121 
00122    if (fqdn)
00123    {
00124       // do DNS A and AAAA lookups and store the results with the default (host) mask
00125       return;
00126    }
00127       
00128    if (*pb.position() == '/')    // grab the mask as well
00129    {
00130       anchor = pb.skipChar();
00131       mask = pb.integer();
00132       
00133       if (ipv4)
00134       {
00135          if (mask < 8 || mask > 32)
00136          {
00137             return INVALID;
00138          }
00139       }
00140       else if (ipv6)
00141       {
00142          if (mask < 64 || mask > 128)
00143          {
00144             return INVALID;
00145          }
00146       }
00147    }
00148    else
00149    {
00150       if (ipv4)
00151       {
00152          mask = 32;
00153       }
00154       else // ipv6
00155       {
00156          mask = 128;
00157       }
00158    }
00159    
00160    if pb.position() == pb.end())
00161    {
00162       if (ipv6)
00163       {
00164          mV6AclList.pushback(V6AddrMask(in6,mask));
00165       }
00166       
00167       if (ipv4)
00168       {
00169          mV4AclList.pushback(V4AddrMask(in4,mask));
00170       }
00171       return SUCCESS;
00172    }      
00173    return INVALID;
00174 };