Though the solution to this one is easy, this took a long time and a lot of testing with debug logging to find.

If I correctly understand the overall intended logic of httpbl_check(), it goes like this:

#1 - If we've already calculated a result for our user, we're done (return). Otherwise...
#2 - We check to see if the user is already white-listed, else
#3 - If we're caching results, we look for the user in our cache table.
#4 - We check the results of #3, and if it's not an integer (0,1 or 2), we proceed with a DNS lookup and checking to see if the user is malicious and should be grey or blacklisted, or if they're safe, etc.

My testing found that #4 was always happening because the test of #3 results was not an integer, even when it appeared to be a 0, 1 or 2.

I tested this by asking a friend (whose IP I know) to visit a web site with httpbl installed. Before they visited I manually added them to the cache table as a greylisted user (2). However, what happened when they arrived at the site was nothing but the usual experience. They were not greylisted. When I checked the httpbl cache table after their visit, their status was 0, Safe or white-listed in cache only (not the {access} table).

Later I kept repeating this test by manually grey-listing my own IP and visiting the site with a second browser. I kept not getting blacklisted, but getting cache whitelisted. Eventually I added debug logging to each step along the way, to see what was happening.

It turned out that even though I was found in the cache table with a status of 2, a DNS lookup was happening anyway, and because my IP address is not really evil, I was being deemed safe and my status changed to a 0.

So the focus became checking out that integer check ... if (!is_int($result)) {. I did some googling and some reading, like...

http://us2.php.net/is_int, http://us2.php.net/manual/en/function.is-numeric.php, http://drupal.org/node/136473 and http://drupal.org/node/27781

So the first thing I tried was changing the line to if (!is_numeric($result)) {. That worked. After that, if I manually greylisted an IP in the cache {httpbl} table, it stayed greylisted until either I changed it back or proceeded with a successful whitelist challenge, or failed and became blacklisted.

I still don't understand what is happening to the $result variable after _httpbl_cache_get() returns the status value in the cache table, but it seems that's where it loses it's integer type.

However, the final solution I used was to change the test back to if (!is_int($result)) {, but make sure $result is forced back to being an integer when it retrieves the cache table status.

(I'll post the patch when I get the number for this issue).

CommentFileSizeAuthor
#1 580060.patch403 bytesbryrock
#2 httpbl-580060-A.patch427 bytesbryrock
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bryrock’s picture

FileSize
403 bytes

Okay, here is the patch I promised above.

Updated: This patch will not really solve the problem. See below.

bryrock’s picture

FileSize
427 bytes

Oops. The above patch won't work, either. It results in the opposite behavior. That is, if the cache table is checked and nothing is found, and if that result is forced to be an integer, then the value will be 0 and the integer test will always be true (0, 1 or 2), and that results in no DNS lookup at Honeypot.

So this patch goes back to the first option I described in the initial issue post, to simply check whether the results of the cache lookup are numeric.

bryrock’s picture

Status: Active » Needs review

I meant to change the status above, also.

praseodym’s picture

Status: Needs review » Fixed

Nice explanation and good catch, thanks! I've applied the patch to HEAD, so a new development release should be ready in a day.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.