@@ -190,32 +190,67 @@ function is_admin_ip_whitelisted($ip, $conf)
190190 // exclude empty lines and comments
191191 if ($ line === '' || $ line [0 ] === '# ' ) return false ;
192192
193- return ip_matches_cidr ($ ip , $ line );
193+ return ipv6_matches_cidr ( $ ip , $ line ) || ipv4_matches_cidr ($ ip , $ line );
194194 });
195195
196196 return count ($ matches ) > 0 ;
197197}
198198
199199// based on https://www.php.net/manual/en/ref.network.php (comments)
200200/**
201- * Checks if the given IP address matches the given CIDR.
202- * @param $ip
203- * @param $cidr
204-
201+ * Checks if the given IPv4 address matches the given CIDR.
202+ * @param string $ip The IPv4 address.
203+ * @param string $cidr The CIDR in the IPv4 format.
205204 * @return bool
206205 */
207- function ip_matches_cidr ($ ip , $ cidr ) {
206+ function ipv4_matches_cidr ($ ip , $ cidr )
207+ {
208+ if (strpos ($ ip , '. ' ) === false ) return false ;
209+
208210 list ($ net , $ mask ) = explode ('/ ' , $ cidr );
209211 if (!$ mask ) $ mask = 32 ;
210212
211213 $ ip_net = ip2long ($ net );
212- $ ip_mask = ~((1 << (32 - $ mask )) - 1 );
213-
214214 $ ip_ip = ip2long ($ ip );
215+ $ ip_mask = ~((1 << (32 - $ mask )) - 1 );
215216
216217 return (($ ip_ip & $ ip_mask ) == ($ ip_net & $ ip_mask ));
217218}
218219
220+ // based on https://stackoverflow.com/a/7951507/2428861
221+ /**
222+ * Checks if the given IPv6 address matches the given CIDR.
223+ * @param string $ip The IPv6 address.
224+ * @param string $cidr The CIDR in the IPv6 format.
225+ * @return bool
226+ */
227+ function ipv6_matches_cidr ($ ip , $ cidr )
228+ {
229+ if (strpos ($ ip , ': ' ) === false ) return false ;
230+
231+ list ($ net , $ mask ) = explode ('/ ' , $ cidr );
232+ if (!$ mask ) $ mask = 128 ;
233+
234+ $ ip_net = in_addr_to_bitstring (inet_pton ($ net ));
235+ $ ip_ip = in_addr_to_bitstring (inet_pton ($ ip ));
236+
237+ return substr ($ ip_ip , 0 , $ mask ) === substr ($ ip_net , 0 , $ mask );
238+ }
239+
240+ /**
241+ * Converts the output of {@see inet_pton()} to string of bits.
242+ * @param string $in_addr The in_addr representation of the IP address.
243+ * @return string String of bits representing given in_addr representation of the IP address.
244+ */
245+ function in_addr_to_bitstring ($ in_addr )
246+ {
247+ $ result = '' ;
248+ foreach (str_split ($ in_addr ) as $ c ) {
249+ $ result .= str_pad (decbin (ord ($ c )), 8 , '0 ' , STR_PAD_LEFT );
250+ }
251+ return $ result ;
252+ }
253+
219254/**
220255 * Validates user credentials and fetches the user if validation succeeded
221256 * @param app $app
0 commit comments