|
reSIProcate/repro
9694
|
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 };
1.7.5.1