PHP Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesPHP Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old January 4th, 2012, 07:35 PM
zxcvbnm's Avatar
zxcvbnm zxcvbnm is offline
A Change of Season
Click here for more information.
 
Join Date: Mar 2004
Posts: 1,589 zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 19 h 37 m 26 sec
Reputation Power: 70
Securing a folder that updates the database

Hello forum;

I need to confirm I am doing the right thing here.

I have a folder called "ipn". The folder is only used when Pay pal calls it (That's just poor English). In other words, its not allowed to access any of the pages in this directly from the address bar (ie. www.domain.com/ipn/update_customer.php is not allowed).

Files in this folder update the database based on the $_GET values received from Pay pal:

For example:

PHP Code:
//Check and validating the $_GET values....
//.....
//If all good, then:
$qupdate="UPDATE customers_credits SET status = 'active', history = '".$history."' WHERE id = '".$clean_data_get['id']."'"


And this is what I send to Pay pal:

Code:
<input type="hidden" name="notify_url" value="http://www.domain.com/ipn/voucher_ipn_res.php?id=<?php echo $_GET['id'];?>"  />


Here is my solution (which seems to be working just fine):

I create a .htaccess file in that folder with this content:

Code:
  Order Deny,Allow
  Deny from All
  Allow from paypal.com


I appreciate if you point the security holes in that.

Thanks
__________________
Devshed people, please fix the spell check:

System is temporarily busy. Please try again in a few seconds.

Last edited by zxcvbnm : January 5th, 2012 at 05:43 PM.

Reply With Quote
  #2  
Old January 4th, 2012, 08:40 PM
requinix's Avatar
requinix requinix is offline
Still alive
Click here for more information.
 
Join Date: Mar 2007
Location: Washington, USA
Posts: 12,681 requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)requinix User rank is General 120th Grade (Above 100000 Reputation Level)  Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1Folding Points: 417516 Folding Title: Super Ultimate Folder - Level 1
Time spent in forums: 5 Months 1 Week 4 Days 2 h 20 m 36 sec
Reputation Power: 8969
Send a message via AIM to requinix Send a message via MSN to requinix Send a message via Yahoo to requinix Send a message via Google Talk to requinix
That's about it, really. But are there multiple files in that folder? The IPN script itself should be safe by virtue of how it works: it verifies the request against PayPal's servers and doesn't continue if it gets a bad response.

Otherwise I could be pedantic about the Order directive, but I don't feel like it. (It's fine.)

Reply With Quote
  #3  
Old January 4th, 2012, 08:58 PM
zxcvbnm's Avatar
zxcvbnm zxcvbnm is offline
A Change of Season
Click here for more information.
 
Join Date: Mar 2004
Posts: 1,589 zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 19 h 37 m 26 sec
Reputation Power: 70
Quote:
Originally Posted by requinix
That's about it, really. But are there multiple files in that folder? The IPN script itself should be safe by virtue of how it works: it verifies the request against PayPal's servers and doesn't continue if it gets a bad response.
Otherwise I could be pedantic about the Order directive, but I don't feel like it. (It's fine.)


Thanks yes there is only this file in the folder.

Reply With Quote
  #4  
Old January 5th, 2012, 07:17 AM
deav deav is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2011
Location: United Kingdom
Posts: 40 deav User rank is Corporal (100 - 500 Reputation Level)deav User rank is Corporal (100 - 500 Reputation Level)deav User rank is Corporal (100 - 500 Reputation Level)deav User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 7 h 52 m 5 sec
Reputation Power: 4
It would be possible to perform an attack at the DNS level to modify your hosts resolution of paypal.com to that of the attacker.

Reply With Quote
  #5  
Old January 5th, 2012, 07:39 AM
Northie's Avatar
Northie Northie is offline
Square Peg in a Round Hole
Click here for more information.
 
Join Date: Oct 2007
Location: North Yorkshire, UK
Posts: 3,415 Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 9 h 21 m 40 sec
Reputation Power: 3833
I've you've coded up your ipn script properly then the world and his wife you view it and you'd still be safe.

Did you start your ipn script by copying the php sample code from paypal?
__________________
PHP OOPS! <?php DB::Execute(SQL::makeFrom($_GET))->fetchArray()->FormatWith(Template::getInstance('default'))->printHtml(); ?>

PDO vs mysql_* functions: Find a Migration Guide Here

[ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]

Reply With Quote
  #6  
Old January 5th, 2012, 06:13 PM
zxcvbnm's Avatar
zxcvbnm zxcvbnm is offline
A Change of Season
Click here for more information.
 
Join Date: Mar 2004
Posts: 1,589 zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 19 h 37 m 26 sec
Reputation Power: 70
Quote:
Originally Posted by Northie
I've you've coded up your ipn script properly then the world and his wife you view it and you'd still be safe.


Hey this is strange English, pretty sure you have a good point but I don't understand.

Quote:
Originally Posted by Northie
Did you start your ipn script by copying the php sample code from paypal?


The ipn/update_customer.php script is just a simple database update script like this:
PHP Code:
 $sql "SELECT id FROM orders WHERE id=:id AND status=:status";
$args = array('id'=>$_GET['id'], 'status'=>'pending' );

//Chris probably won't like this but:
$number_of_rows DB::Load()->Execute($sql,$args)->returnNumAffectedRows();


if(
$number_of_rows==1)
 {
     
//$sql = "UPDATE...";
       
$args =...;
       
$execute...
 }
else
 {
    
//invalid 
  


Reply With Quote
  #7  
Old January 6th, 2012, 02:29 AM
Northie's Avatar
Northie Northie is offline
Square Peg in a Round Hole
Click here for more information.
 
Join Date: Oct 2007
Location: North Yorkshire, UK
Posts: 3,415 Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 9 h 21 m 40 sec
Reputation Power: 3833
Quote:
Originally Posted by zxcvbnm
Hey this is strange English, pretty sure you have a good point but I don't understand.


sorry, that should have been

Quote:
Originally Posted by Northie
If you've coded up your ipn script properly then the world and his wife could view it and you'd still be safe.


Quote:
Originally Posted by zxcvbnm
The ipn/update_customer.php script is just a simple database update script like this: ...


There's your problem, you're doing no validation checks with paypal. The code you've written should live deep inside an "if" statement.... read on for more, and some sample code

In an ipn call, paypal calls a script on your server. You are supposed to send these post values back to paypal in server-generated post request and read the response from it. Paypal's response to this post tells you if the transaction is legitimate, or not. Paypal knows if they, themselves, made the request to your ipn script and responds accordingly when asked to do so.

paypal sample code php code here:

https://cms.paypal.com/cms_content/.../IPN_PHP_41.txt

As for protecting your folder so that just paypal can access it - try this: The paypal sandbox will allow me to test any IPN script i know about, the request will come from a paypal.com domain

Last edited by Northie : January 6th, 2012 at 02:36 AM.

Reply With Quote
  #8  
Old January 6th, 2012, 09:14 AM
phpwebmaster phpwebmaster is offline
Contributing Badly User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2007
Posts: 143 phpwebmaster User rank is Corporal (100 - 500 Reputation Level)phpwebmaster User rank is Corporal (100 - 500 Reputation Level)phpwebmaster User rank is Corporal (100 - 500 Reputation Level)phpwebmaster User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 Day 18 h 32 m 38 sec
Reputation Power: 9
I am sure there is a system check that is available to you, as a part of your integrity checks.

Not 100% sure but i would think paypal has a call you can make to find out which system made the call to your server, live or sandbox.

as pointed out you can make a call to any ipn script with the sandbox, so there must be a system type call you can make.
__________________
If i went into too much detail or assumed this was what you meant, well thats just how i thought you wanted it

Reply With Quote
  #9  
Old January 18th, 2012, 06:48 PM
zxcvbnm's Avatar
zxcvbnm zxcvbnm is offline
A Change of Season
Click here for more information.
 
Join Date: Mar 2004
Posts: 1,589 zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 19 h 37 m 26 sec
Reputation Power: 70
Quote:
Originally Posted by Northie
There's your problem, you're doing no validation checks with paypal. The code you've written should live deep inside an "if" statement.... read on for more, and some sample code

In an ipn call, paypal calls a script on your server. You are supposed to send these post values back to paypal in server-generated post request and read the response from it. Paypal's response to this post tells you if the transaction is legitimate, or not. Paypal knows if they, themselves, made the request to your ipn script and responds accordingly when asked to do so.

paypal sample code php code here:

https://cms.paypal.com/cms_content/.../IPN_PHP_41.txt

As for protecting your folder so that just paypal can access it - try this: The paypal sandbox will allow me to test any IPN script i know about, the request will come from a paypal.com domain


Hello;

I am a bit closer to your solution. I used the following code and the Sandbox says IPN successfully sent but I get the Invalid email. In other words in the ipn.php the check with Paypal is NOT verified. Please see below:

PHP Code:
<?php  
    
// read the post from PayPal system and add 'cmd'  
    
$req 'cmd=_notify-validate';  
    foreach (
$_POST as $key => $value)
        {  
            
$value urlencode(stripslashes($value));  
            
$req .= "&$key=$value";  
        }  
    
// post back to PayPal system to validate  
    
$header "POST /cgi-bin/webscr HTTP/1.0\r\n";  
    
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";  
    
$header .= "Content-Length: ".strlen($req)."\r\n\r\n";  
    
$fp fsockopen ('ssl://www.paypal.com'443$errno$errstr30);  
    if (!
$fp)
        {  
            
// HTTP ERROR  
        
}
    else
        {  
            
fputs ($fp$header.$req);  
            while(!
feof($fp))
                {  
                    
$res fgets ($fp1024);  
                    if (
strcmp ($res"VERIFIED") == 0)
                        {  
                            
// PAYMENT VALIDATED & VERIFIED!
                            
$email $_POST['payer_email'];
                            
mail($email$subject$message$headers);
                            
// PAYMENT VALIDATED & VERIFIED!
                        
}  
                    elseif(
strcmp ($res"INVALID") == 0)
                            {  
                                
$email $_POST['payer_email'];
                                foreach(
$_POST as $var)
                                    {
                                        
$message .= "\r\n".$var;
                                    }
                                
mail($email'Invalid'$message$headers);
                            }  
                }  
            
fclose ($fp);  
        }  
?>


And I keep getting an email with the title Invalid with the follwoing content:

Code:
1
instant
16:27:50 Jan 18, 2012 PST
Completed
confirmed
verified
John
Smith
pmdg3@yahoo.com
TESTBUYERID01
John Smith
United States
US
95131
CA
San Jose
123, any street
seller@paypalsandbox.com
seller@paypalsandbox.com
TESTSELLERID1
US
something
AK-1234
1
3.04
2.02
USD
0.44
12.34
9.34
web_accept
50119027
2.1
xyz123
windows-1252
Ay6yLHy3emJ0Ljt4I6eJB1vMeiv7AN8R9NE95JCSLrf.qgUlNmZn9Hu8


So basically this part of the code does not meet the criteria:

if (strcmp ($res, "VERIFIED") == 0)

What do you think is wrong?

Merci

Reply With Quote
  #10  
Old January 19th, 2012, 06:30 AM
Northie's Avatar
Northie Northie is offline
Square Peg in a Round Hole
Click here for more information.
 
Join Date: Oct 2007
Location: North Yorkshire, UK
Posts: 3,415 Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level)Northie User rank is General 43rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 9 h 21 m 40 sec
Reputation Power: 3833
Paypal is always a pain.

When testing your ipn script from paypals developer/sandbox then the domain to which you open a socket to needs to be the sandbox domain/url not the normal one!

Reply With Quote
  #11  
Old November 20th, 2012, 06:57 PM
zxcvbnm's Avatar
zxcvbnm zxcvbnm is offline
A Change of Season
Click here for more information.
 
Join Date: Mar 2004
Posts: 1,589 zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level)zxcvbnm User rank is Second Lieutenant (5000 - 10000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 19 h 37 m 26 sec
Reputation Power: 70
In case anyone runs into this thread, note that Paypal has a new php listener. So do not use the code above, instead use the new version:
PHP Code:
// STEP 1: Read POST data
 
// reading posted data from directly from $_POST causes serialization 
// issues with array data in POST
// reading raw POST data from input stream instead. 
$raw_post_data file_get_contents('php://input');
$raw_post_array explode('&'$raw_post_data);
$myPost = array();
foreach (
$raw_post_array as $keyval) {
  
$keyval explode ('='$keyval);
  if (
count($keyval) == 2)
     
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
// read the post from PayPal system and add 'cmd'
$req 'cmd=_notify-validate';
if(
function_exists('get_magic_quotes_gpc')) {
   
$get_magic_quotes_exists true;

foreach (
$myPost as $key => $value) {        
   if(
$get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 
        
$value urlencode(stripslashes($value)); 
   } else {
        
$value urlencode($value);
   }
   
$req .= "&$key=$value";
}
 
 
// STEP 2: Post IPN data back to paypal to validate
 
$ch curl_init('https://www.paypal.com/cgi-bin/webscr');
curl_setopt($chCURLOPT_HTTP_VERSIONCURL_HTTP_VERSION_1_1);
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFER,1);
curl_setopt($chCURLOPT_POSTFIELDS$req);
curl_setopt($chCURLOPT_SSL_VERIFYPEER1);
curl_setopt($chCURLOPT_SSL_VERIFYHOST2);
curl_setopt($chCURLOPT_FORBID_REUSE1);
curl_setopt($chCURLOPT_HTTPHEADER, array('Connection: Close'));
 
// In wamp like environments that do not come bundled with root authority certificates,
// please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path 
// of the certificate as shown below.
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
if( !($res curl_exec($ch)) ) {
    
// error_log("Got " . curl_error($ch) . " when processing IPN data");
    
curl_close($ch);
    exit;
}
curl_close($ch);
 
 
// STEP 3: Inspect IPN validation result and act accordingly
 
if (strcmp ($res"VERIFIED") == 0) { 
    
// check whether the payment_status is Completed
    // check that txn_id has not been previously processed
    // check that receiver_email is your Primary PayPal email
    // check that payment_amount/payment_currency are correct
    // process payment
 
    // assign posted variables to local variables
    
$item_name $_POST['item_name'];
    
$item_number $_POST['item_number'];
    
$payment_status $_POST['payment_status'];
    
$payment_amount $_POST['mc_gross'];
    
$payment_currency $_POST['mc_currency'];
    
$txn_id $_POST['txn_id'];
    
$receiver_email $_POST['receiver_email'];
    
$payer_email $_POST['payer_email'];
} else if (
strcmp ($res"INVALID") == 0) {
    
// log for manual investigation


Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPHP Development > Securing a folder that updates the database

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap