1<?php 2if(!defined('DOKU_INC')) die(); 3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 4require_once(DOKU_PLUGIN.'action.php'); 5 6class action_plugin_redirectssl extends DokuWiki_Action_Plugin { 7 function getInfo(){ return conf_loadfile(dirname(__FILE__).'/info.txt'); } 8 function register($contr){ 9 $contr->register_hook('ACTION_ACT_PREPROCESS','BEFORE',$this,'handle_action',array()); 10 11 #when user does not have permission for an action (e.g., action='show'), DW transitions to a "denied" action, which does not transition to a "login" action, but manually prints a login form. 12 # The manual handling of the login does not trigger another ACTION_ACT_PREPROCESS, so we are unable to handle it here. But Action/Denied.php:Denied::tplContent() triggers an event ACTION_DENIED_TPLCONTENT, which we can hook into. 13 $contr->register_hook('ACTION_DENIED_TPLCONTENT','BEFORE',$this,'handle_action_denied',array()); 14 } 15 16 function handle_action_denied(&$e, $param){ 17 global $INPUT; 18 if (empty($INPUT->server->str('REMOTE_USER')) && actionOK('login')) { 19 $oldaction=$e->data; 20 $e->data='login'; 21 $this->handle_action($e,$param); 22 $e->data=$oldaction; 23 } 24 25 } 26 27 function handle_action(&$e, $param){ 28 if($this->isssl()) return; #already ssl, nothing to do. 29 $actions=$this->getConf('actions'); 30 if(is_string($actions)) $actions=explode(',',$actions); 31 if(!$actions) return; 32 if(!in_array('ALL',$actions) && !in_array($e->data,$actions)) return; 33 #mve(['servername'=>$this->servername(),'thisport'=>$this->thisport(),'httpsport'=>$this->httpsport(),'hasssl'=>$this->hasssl()]); 34 35 if($this->getConf('checkssl')&&!$this->hasssl()){ 36 msg("Redirecting to HTTPS is disabled because this server does not appear to have HTTPS capability. The site admin may turn off checkssl in the redirectssl plugin configuration to turn this check off and force redirect to HTTPS anyway."); 37 return; 38 } 39 if(!($servername=$this->servername())){ 40 msg("Redirecting to HTTPS is disabled because I could not determine the servername. The site admin may manually set the servername in the redirectssl plugin configuration."); 41 return; 42 } 43 if(!($port=$this->getConf('httpsport'))){ 44 msg("Redirecting to HTTPS is disabled because I could not determine the HTTPS port number. The site admin may manually set the port number in the redirectssl plugin configuration."); 45 return; 46 } 47 48 $url="https://$servername".($port==443?'':":$port").'/'.preg_replace('#^/#','',$_SERVER['REQUEST_URI']); 49 $url=str_replace("\r",rawurlencode("\r"),$url); 50 $url=str_replace("\n",rawurlencode("\n"),$url); 51 header("Location: $url"); 52 exit(); 53 } 54 55 function isssl(){ 56 if (isset($_SERVER['HTTPS'])) 57 return !preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS']); 58 elseif(isset($_SERVER['SCRIPT_URI'])&&strpos($_SERVER['SCRIPT_URI'],'https://')===0) return true; 59 return isset($_SERVER['SERVER_PORT'])&&preg_match('#443$#',$_SERVER['SERVER_PORT']); 60 } 61 function servername(){ 62 if($ret=$this->getConf('servername')) return $ret; 63 $ret=$_SERVER['HTTP_HOST']?: ($_SERVER['SERVER_NAME']?: ($_SERVER['COMPUTERNAME']? : NULL)); 64 if($ret) return preg_replace('#:\d+$#','',$ret); 65 } 66 function thisport(){ 67 if($ret=$_SERVER['SERVER_PORT']) return $ret; 68 if($ret=$_SERVER['HTTP_HOST']) return preg_replace('#^.*:(\d+)$#','$1',$ret); 69 } 70 function httpsport(){ 71 if($ret=$this->getConf('httpsport')) return $ret; 72 if(!$this->thisport()||$this->thisport()==80||$this->thisport()==443) return 443; #only return 443 if the current port is not available or it is the standard 80 or this is already 443. 73 } 74 function hasssl(){ 75 static $ret; if(isset($ret)) return $ret; 76 #I think the server_software string used to list the modules, but doesn't seem to be the case anymore, so the following if() is now useless. 77 if(isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'],'mod_ssl')!==FALSE) 78 return $ret=true; 79 80 try{ #need to use try-catch in case this is not an apache server. 81 if(in_array('mod_ssl', apache_get_modules())) return $ret=true; 82 }catch(Exception $e){} 83 84 if($port=$this->httpsport()){ 85 $socket = @socket_create(AF_INET,SOCK_STREAM,SOL_TCP); 86 if ($socket >= 0 && @socket_connect($socket,$this->servername()?:'127.0.0.1',$port)>=0){ 87 @socket_close($socket); 88 return $ret=true; 89 } 90 @socket_close($socket); 91 } 92 return $ret=false; 93 } 94 95 96} 97