array( 'title' => t('Administer Ubercart SSL settings'), ), ); return $perms; } function uc_ssl_page_is_in_https_mode() { if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) { return TRUE; } return FALSE; } function uc_ssl_disable_overlay_module() { $modules = module_list(); $base_path = base_path(); if (variable_get('uc_ssl_switch_to_non_ssl', '') && in_array('overlay', $modules)) { //Overlay is on, lets disable it. module_disable(array(0 => 'overlay')); } } function uc_ssl_init() { //Drupals Overlay panel is not secure! Fix that here by disable it all together. We cannot allow this. Drupal 7 is insecure by default, such a sad thing :/ uc_ssl_disable_overlay_module(); //menu_rebuild(); //First and foremost, make sure Clean URLs are on. if (uc_ssl_clean_urls_enabled() && !drupal_is_cli()) { //Setup a hook for ssl checking uc_ssl_check(); //Run ssl check on every page load. uc_ssl_run(); } } function uc_ssl_include_ssl_paths() { global $user; $paths = array( 'All Ubercart Cart pages' => '/cart*', //Secure ALL cart pages. //NOTE: If you remove the /user definition here, you CAN NOT use Mixed SSL Mode with D7. It HAS to exist because D7 http sessions are missing //data that https sessions require. But http sessions work with the https session variables. Thus, you MUST login with https or your sessions //will not carry between the http and https versions of your wesite. This is a D7 bug only, I believe its more of a feature than a bug. 'All User pages' => '/user*', //Secure ALL user pages. //Added support for Drupal commerce which is based upon Ubercart. 'All Drupal Commerce Checkout pages' => '/checkout*', //Secure ALL cart pages. NOTE: SEE EXCLUDES to see why the cart listing itself isnt secured! //This supports both UC and Commerce admins 'All Ubercart Cart Admin pages' => '/admin/store*', //Secure ALL UC admin pages. #'example 1' => '/cart', //Only secure the /cart and /cart/ page. #'example 2' => 'cart', //Only secure the /cart and /cart/ page. #'example 3' => 'cart/', //Only secure the /cart and /cart/ page. #'example 4' => '/cart*/something', //matches /cartThis/something and /cart/something but NOT thiscart/something etc. #'example 5' => '/cart/*/something', //Matches /cart/123/something and cart/this/something, but NOT /cart/something #'example 6' => '/cart/something', //Only secure the /cart/something and /cart/something/ page. ); return $paths; } //Implementation of hook_exclude_ssl_paths() function uc_ssl_exclude_ssl_paths() { $paths = array( //These excludes no longer seem to be required for the D7 version and thus they have been removed until issues come up again. //'Exclude the cart page itself' => '/cart', //We dont need to secure the cart contents so we exclude that here //'Exclude Autocomplete' => '*autocomplete*', //'Exclude Ajax' => '*ajax*', #'example 1' => '/cart', //Only exclude the /cart and /cart/ page. #'example 2' => 'cart', //Only exclude the /cart and /cart/ page. #'example 3' => 'cart/', //Only secure the /cart and /cart/ page. #'example 4' => '/cart*/something', //matches /cartThis/something and /cart/something but NOT thiscart/something etc. #'example 5' => '/cart/*/something', //Matches /cart/123/something and cart/this/something, but NOT /cart/something #'example 6' => '/cart/something', //Only exclude the /cart/something and /cart/something/ page. ); return $paths; } //Implementation of hook_exclude_ssl_paths() //This function is so you can completely ignore ANY switching at all no matter what. function uc_ssl_exclude_ssl_switch_paths() { $paths = array( #'example 1' => '/*ajax*', //Dont touch ajax paths whatsoever, this is just an example. ); return $paths; } function uc_ssl_menu() { $items = array(); $items['admin/config/system/uc_ssl'] = array( 'title' => 'Ubercart SSL', // 'title' => 'Ubercart SSL module settings', 'description' => 'Ubercart SSL module settings', 'page callback' => 'drupal_get_form', 'page arguments' => array('uc_ssl_admin'), 'access arguments' => array('administer uc_ssl'), 'type' => MENU_NORMAL_ITEM, 'file' => 'uc_ssl.admin.inc', ); return $items; } function uc_ssl_enabled() { return variable_get('uc_ssl_status', ''); } function uc_ssl_is_configured() { $query = "SELECT count(name) AS count from {variable} WHERE name = 'uc_ssl_status'"; $results = db_query($query); $rows = $results->fetchAll(); $rows = $rows[0]; //If uc_ssl is not configured, warn the user and show a link to config it. if (!$rows->count) { $admin_link = 'http://'.$_SERVER['HTTP_HOST'].url().'admin/config/system/uc_ssl'; drupal_set_message("Please configure Ubercart SSL for SSL enabled cart checkouts to work: $admin_link", 'warning'); } return $rows->count; } function uc_ssl_switch_to_non_ssl() { return variable_get('uc_ssl_switch_to_non_ssl', ''); } function uc_ssl_path_match($path, $pages) { $result = FALSE; //This is here just to get rid of retarded php 'notice' messages. I hate php notices. if (!empty($pages)) { //Trim off trailing / and then re-add it to avoid double /'s. This allows cart and cart/ to match as the same thing or cart/1 and cart/1/ to be the same. $path = trim($path, '/').'/'; $regexp = '/^('; foreach ($pages AS $key => $regexp_path) { if ($regexp_path) { $regexp_path = trim($regexp_path, '/').'/'; $regexp_path1 = str_replace('/', '\/', $regexp_path); //replace / with a \/ $regexp_path2 = str_replace('*', '.*', $regexp_path1);//replace * with a .* $regexp .= $regexp_path2.'|'; //Append a | to signify end of this expression } } $regexp = trim($regexp, '|'); $regexp .= ')$/'; if (variable_get('uc_ssl_case_insensitive', 1)) { $regexp .= 'i'; } $result = preg_match($regexp, $path); } return $result; } function is_clean_url($path) { //Skip ANY ?q= urls since these do NOT come from a web browser when clean URLs is on. Doing this allows us to skip //ajax and autocomplete type URLs that come from within drupal itself. This is a major problem with Secure_Pages module //and we dont want the same problems so we restrict people to using ONLY clean URLs. if (!stristr($path, '?q=')) { return TRUE; } return FALSE; } function uc_ssl_http_request($url) { //Handle JS type urls in the background as they are likely to be ajax type posts. if (arg(0) == 'js') { $js_response = drupal_http_request($url); return; } //Handle post type URLs. This should handle ajax POST urls such as the tax calculation/progress bars. if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST['uc_ssl_post'])) { $_POST['uc_ssl_post'] = 1; $options['headers'] = array('Content-Type' => 'application/x-www-form-urlencoded'); $options['method'] = 'POST'; $options['data'] = http_build_query($_POST, '', '&'); //Drupal 7 decided to completely recode drupal_http_request so I dont know if this will cause issues or not. Report any bugs please. //$response = drupal_http_request($url, $headers, 'POST', http_build_query($_POST, '', '&')); $response = drupal_http_request($url, $options); return; } //All other types of urls are handled normally. // Reset destination variables or we'll get sent there instead of to $url unset($_REQUEST['destination'], $_GET['destination']); drupal_goto($url); return; } function uc_ssl_run() { //Set the current path without url() since it will mess up regex checks. Using url() also supports languages, base_path does not. //$current_path = trim($_SERVER['REQUEST_URI'], url()); $root = url(); $current_path = substr(trim($_SERVER['REQUEST_URI']),strlen($root)); $ssl_domain = variable_get('uc_ssl_ssl_domain', ''); $nonssl_domain = variable_get('uc_ssl_non_ssl_domain', ''); //If uc_ssl is configured, run it. if (uc_ssl_is_configured() && is_clean_url($current_path)) { if (uc_ssl_enabled()) { //Get a list of all the URL links that should be included and excluded from SSL pages from other modules. $items = array(); $exclude_secured_urls = array(); $exclude_secured_urls = module_invoke('uc_ssl', 'exclude_ssl_paths', $exclude_secured_urls); foreach (module_implements('exclude_ssl_paths') as $module) { $new = module_invoke($module, 'exclude_ssl_paths', $exclude_secured_urls); if ($module != 'uc_ssl') //Skip uc_ssl since we already processed it above. Allow external modules to change uc_ssl defaults. { if (is_array($new)) { $exclude_secured_urls = array_merge($exclude_secured_urls, $new); } } } $include_secured_urls = array(); $include_secured_urls = module_invoke('uc_ssl', 'include_ssl_paths', $include_secured_urls); foreach (module_implements('include_ssl_paths') as $module) { $new = module_invoke($module, 'include_ssl_paths', $include_secured_urls); if ($module != 'uc_ssl') //Skip uc_ssl since we already processed it above. Allow external modules to change uc_ssl defaults. { if (is_array($new)) { $include_secured_urls = array_merge($include_secured_urls, $new); } } } // Get a list of all the URL links that should not switch between HTTP/HTTPS at all. $exclude_switch_urls = array(); $exclude_switch_urls = module_invoke('uc_ssl', 'exclude_ssl_switch_paths', $exclude_switch_urls); foreach (module_implements('exclude_ssl_switch_paths') as $module) { $new = module_invoke($module, 'exclude_ssl_switch_paths', $exclude_switch_urls); if ($module != 'uc_ssl') //Skip uc_ssl since we already processed it above. Allow external modules to change uc_ssl defaults. { if (is_array($new)) { $exclude_switch_urls = array_merge($exclude_switch_urls, $new); } } } // make sure we return an array if (! is_array($include_secured_urls)) { $include_secured_urls = array(); } if (! is_array($exclude_secured_urls)) { $exclude_secured_urls = array(); } if (! is_array($exclude_switch_urls)) { $exclude_switch_urls = array(); } //If the path is in the exclude switch hook, dont do ANYTHING at all. if (uc_ssl_path_match($current_path, $exclude_switch_urls)) { return; } //Switch to SSL no matter what the link is if Switch isnt on. if (!uc_ssl_switch_to_non_ssl()) { if (!uc_ssl_page_is_in_https_mode() && !uc_ssl_path_match($current_path, $exclude_secured_urls)) { uc_ssl_http_request($ssl_domain . $_SERVER['REQUEST_URI']); } } else { //If uc_ssl_switch_to_non_ssl() is enabled then we switch back to non-ssl link for non-cart links. if (uc_ssl_page_is_in_https_mode()) { //The only exceptions are the links listed in the exclude list by other modules. if (uc_ssl_path_match($current_path, $exclude_secured_urls)) { uc_ssl_http_request($nonssl_domain . $_SERVER['REQUEST_URI']); } if (!uc_ssl_path_match($current_path, $include_secured_urls) && uc_ssl_switch_to_non_ssl()) { uc_ssl_http_request($nonssl_domain . $_SERVER['REQUEST_URI']); } } } //If on a cart url, use HTTPS and re-post/re-direct to the SSL version of the url. if (!uc_ssl_page_is_in_https_mode() && uc_ssl_path_match($current_path, $include_secured_urls) && !uc_ssl_path_match($current_path, $exclude_secured_urls)) { uc_ssl_http_request($ssl_domain . $_SERVER['REQUEST_URI']); } } } } function uc_ssl_clean_urls_enabled() { $check = variable_get('clean_url', 0); if ($check == 1) { return TRUE; } drupal_set_message('Ubercart SSL (uc_ssl): The uc_ssl module REQUIRES that Clean URLs be enabled in order to work properly. This allows the module to distinguish between an Ajax call and a Web browser call as the two are handled differently so we need a way to distinguish them and this is the quickest easiest way to do so. This will also make your website URLs search engine friendly as well which is a good thing. Please enable clean urls here: Clean URLs', 'warn'); return FALSE; } //This is a quickie hook to see if SSL works or not. It's not fool proof but it works for me. function uc_ssl_check($site = '') { error_reporting(E_ALL); if (!$site) { if (isset($_GET['uc_ssl_check']) && $_GET['uc_ssl_check']) { if (uc_ssl_page_is_in_https_mode()) { echo TRUE; } else { echo FALSE; } exit; } } else { $check = drupal_http_request($site."?uc_ssl_check=1"); if (isset($check->data) && $check->data == '1') { return TRUE; } //IF we are here, then the request failed for some reason, so we try to use a different method. if (ini_get('allow_url_fopen')) { if (file_get_contents($site."?uc_ssl_check=1") == '1') { return TRUE; } } //If we are here, something went wrong. Give the user some ideas on what they need to fix. drupal_set_message("Ubercart SSL (uc_ssl): The uc_ssl_check() function is returning FALSE because it was unable to contact the SSL (https) version of your website that you defined in the settings. This can be caused by 3 things. 1. Your website is not setup properly for SSL, 2. The OpenSSL extension is not enabled on in your PHP installation, 3. allow_url_fopen is not enabled in php.ini. If #2 fails, uc_ssl will try to use file_get_contents() which requires allow_url_fopen to be set to TRUE in php.ini. Hopefully these hints will help you fix this issue so that you can use uc_ssl. You can try to debug this by going to $site?uc_ssl_check=1", "error"); } return FALSE; } if (!function_exists('printr')) { function printr($arr) { echo "
"; print_r($arr); echo ""; } }