Support for multiple ips or ranges.
sgriffin - December 29, 2008 - 15:14
| Project: | IP Login |
| Version: | 5.x-1.0 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Description
It would be nice to support multiple ips/ranges.

#1
i would just like to second this. we could use this module if we could assign multiple ips and complex ranges to each user. :)
#2
Yes, it's an interesting idea, I'll look into it.
DT
#3
what we really need is for our member institutions to be recognized from their IP ranges, and then have a separate user login give them the ability to edit and change their ranges. I think the IPAuthenticator module is closer to this, but I'm not sure (?)
#4
Giving someone ability to edit their own ranges, is a little nuts. They could easily open your whole site to unauthorized access. I don't think this is a feature any group of people will want, so you'd need to program the forms yourself.
#5
If the profile field containing the IP address has a certain visibility set, it will be editable by that user i.e they can update their own IP address. That _might_ be suitable in certain situations.
Of course, IP Login does support IP address ranges of the form 123.123.123.*
More complex ranges ( regular expressions ? ) may be available in the next version.
DT
#6
Strangely, IP range does not work for me. The following is what I did:
1) Install IP Login
2) Create a profile
3) Enable IP Login
4) Choose the IP Login profile
5) Assign an IP range to a user
Am I missing anything?
I'm desperately in need of support for multiple IP addresses/ranges. Until this module supports this, is there any other way?
#7
@tscyberia
IP ranges are currently supported in the form of adding an asterisk to the end of the address
e.g: 123.123.123.*
more complex ranges may be implemented in the future.
DT
#8
Thank you, DT.
Actually, before posting my inquiry I did exactly as you explained, but no IP range was recognized. That's why I asked you whether I was missing anything. What reasons can there be for this problem I've encountered?
Another question: a wild card can be used not only in the fourth block but also in others, e.g., 123.123.*.*, or partially, e.g., 123.123.123.12*?
#9
I've solved the issue of multiple IP addresses temporarily by simply making a separate user for each of them. But unfortunately, I haven't solved the problem of an IP range. I use only basic ones like 123.123.123.*, but even they don't always seem to be recognized. I use IP Login for IP authentication for institutional subscribers to an online journal. Some institutions have told me that they are authorized automatically to access the site, but others have not been recognized by their IPs. I haven't been able to find any difference between the two groups. Is there anyone who had this problem with IP Login (and solved it)? DT, any suggestion?
#10
It may be the case the those users who are not authenticated have an invalid / different IP address from that stored in their profile field.
They will need to supply their public IP address which can be found be visiting sites such as
http://whatismyip.com
Regarding IP address ranges, if anyone wants to submit a patch on that, it would be welcomed.
Also, regarding multiple IPs per user, it would be reasonably simple to create multiple profile fields for the IPs, or perhaps store a comma separated string in one, and check for that. The admin settings could have a multi-select for the profile fields or the code could extract a comma separated list and loop through those instead. I will consider that for a next version though patches are always welcome.
DT
#11
Thank you, DT.
Actually, what I wrote in my previous comment wasn't exact. Something like 123.123.123.* does always work, but the problem is with something like 123.123.*.*. It's not recognized. I've tried 123.123.* instead of 123.123.*.*, but in vain. Any workaround?
#12
no workaround as such as only 123.123.123.* type address ranges are supported, as stated earlier.
to add further complexity there, you'd need to modify the module, particularly the
ip_login_get_range($ip){}function, to return the range, or perhaps an array of ranges to check for.
DT
#13
Thank you, DT.
Unfortunately, the solution you kindly suggested is beyon my limited knowledge of Drupal.
In the meanwhile I've realized a serious security problem. Anyone who is inside an institution that subscribes to our journal and is authorized to access it can actually change the registered email and password. Finding a way to prevent this is also beyond me. After all, I'm just a university lecturer in the humanities, and am volunteering for one of the academic societies I belong to for its new online journal.
If you think you can solve these two problems, our society is ready to pay for you. It seems difficult to find someone else who is more qualified than you. If you think you can, please let me know where I can find your online contact form so that neither of us may have to put our email addresses here.
#14
@tscyberia
My contact form is available through my user profile
http://drupal.org/user/151344/contact
What you have specified is a particular use case that isn't currently accounted for by IP Login, however, it wouldn't be too difficult to implement.
Perhaps we can work something out, on the condition any further development of the module can be committed back to the GPL project here.
regards,
DT
#15
DT, thank you for your readiness. Yesterday I sent you a message through the contact form you mentioned, but I haven't heard from you. So I'm not sure if it has reached you. Please acknowledge receipt by private mail (my email address must be in that message). If you haven't received it, I'll retry.
#16
Ok, so I did an ugly patch to get this to work for the 123.456.*.* range.
This first set of code IS NOT what I did, but we really should be checking by every quadrant like this:
$addr = explode(".", $_SERVER['REMOTE_ADDR']);// See if it's an allowed IP address for this user.
if ($addr[0] == $ip_addr1_q1) {
if ($addr[1] == $user->ip_addr1_q2) {
if ($addr[2] == $user->ip_addr1_q3) {
if ($addr[3] == $user->ip_addr1_q4) {
// Exact match - OKAY
}
if (($addr[3] >= $user->ip_addr1_q4) && ($addr[3] <= $user->ip_addr2_q4)) {
// Match in 4th quadrant range - OKAY
}
}
if (($addr[2] >= $user->ip_addr1_q3) && ($addr[2] <= $user->ip_addr2_q3)) {
if (($addr[3] >= $user->ip_addr1_q4) && ($addr[3] <= $user->ip_addr2_q4)) {
// Match in 3rd and 4th quadrant range - OKAY
}
}
}
}
else {
// No Match
}
So I added a new function at the bottom of ip_login.module:
function ip_login_get_extended_range($ip){if($ip){
$ip = explode('.', $ip); //explode ip to array
array_pop($ip); //remove last element
array_pop($ip); //remove next-to-last element
$ip = implode('.', $ip).'.*.*'; //convert to string and add .*
}
return $ip;
}
and modified the ip_login_login function so that the first 13 lines of that function look like this (i really only added one line, and changed the dbquery) :
//get wildcard IP for fuzzy range matches e.g 203.123.456.*
$ip_range = ip_login_get_range($ip);
$ip_extended_range = ip_login_get_extended_range($ip);
//get profile field for ip address
$profile_field = variable_get('ip_login_profile_ip_field', 'profile_ip');
//DB lookup uid with passed ip address or range
$result = db_fetch_object(
db_query("SELECT pv.uid, pv.value FROM {profile_values} pv
INNER JOIN {profile_fields} pf ON pv.fid = pf.fid
WHERE pf.name = '%s' AND (pv.value = '%s' OR pv.value = '%s' OR pv.value = '%s')", $profile_field, $ip, $ip_range, $ip_extended_range)
);
#17
Ok, so it isn't the prettiest work I've ever done, but from what I can tell it is functional with ranges of the type:
123.456.789.*
123.456.*.*
123.456.1.* - 123.456.7.*
If you want to specify a range like the latter, you have to create a second profile field which doesn't have to be used for all users.
I had to rework most of the module, what I did is attached.
#18
Just realized that I left the main function call outside of an if statement, corrected in new attachment
#19
Hi there,
I'm trying to port this solution to D6, but it doesn't seem to be working.
I'm getting the following error:
user warning: Can't find FULLTEXT index matching the column list query: SELECT pv.uid, pv.value FROM profile_values pv INNER JOIN profile_fields pf ON pv.fid = pf.fid WHERE pf.name = 'profile_ip' AND MATCH (pv.value) AGAINST ('203') in /hsphere/local/home/instoadm/insto.com.au/sites/all/modules/ip_login/ip_login.module on line 78.Attached is my code - basically all I've changed from the .module file above is the hook_menu call, and I've replaced the db_num_rows in function ip_login_admin_settings with
$result_rows = db_query("SELECT count(*), name FROM {profile_fields} GROUP BY name");Does anyone have any ideas what I've missed here? I'm not experienced with this stuff at all, just finding my way around in the dark, so to speak.
Thanks.
Also not sure if I should change the "version" stuff above.
#20
Hello again,
I have solved the error above by running the following SQL on the database:
ALTER TABLE profile_values ADD FULLTEXT(value)Problem is, I'm still not being logged in as I should be.
Anyone have any ideas?
thanks,
#21
OK, I figured it out. I'm not sure if it's my version of mysql or a drupal 5/6 issue, but my system did not like the SQL that used MATCH AGAINST.
I changed that db query to use LIKE:
$first_IP = db_query("SELECT pv.uid, pv.value FROM {profile_values} pvINNER JOIN {profile_fields} pf ON pv.fid = pf.fid
WHERE pf.name = '%s' AND (pv.value) LIKE ('%s%')", $profile_field_1, $addr[0]);
and everything seems to work fine now.
I also changed the hook_init call to hook_boot.