00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 include_once( 'lib/ezutils/classes/ezini.php' );
00048 include_once( 'lib/ezutils/classes/ezsys.php' );
00049
00050 class eZSSLZone
00051 {
00052
00053
00054
00055
00056
00057
00058
00059 function enabled()
00060 {
00061 if ( isset( $GLOBALS['eZSSLZoneEnabled'] ) )
00062 return $GLOBALS['eZSSLZoneEnabled'];
00063
00064 $enabled = false;
00065 $ini =& eZINI::instance();
00066 if ( $ini->hasVariable( 'SSLZoneSettings', 'SSLZones' ) )
00067 $enabled = ( $ini->variable( 'SSLZoneSettings', 'SSLZones' ) == 'enabled' );
00068
00069 return $GLOBALS['eZSSLZoneEnabled'] = $enabled;
00070 }
00071
00072
00073
00074
00075 function cacheFileName()
00076 {
00077 include_once( 'lib/ezutils/classes/ezsys.php' );
00078 include_once( 'lib/ezfile/classes/ezdir.php' );
00079 return eZDir::path( array( eZSys::cacheDirectory(), 'ssl_zones_cache.php' ) );
00080 }
00081
00082
00083
00084
00085 function clearCacheIfNeeded()
00086 {
00087 if ( eZSSLZone::enabled() )
00088 eZSSLZone::clearCache();
00089 }
00090
00091
00092
00093
00094 function clearCache()
00095 {
00096 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'Clearing caches.' );
00097
00098
00099 unset( $GLOBALS['eZSSLZonesCachedPathStrings'] );
00100
00101
00102 $cacheFileName = eZSSLZone::cacheFileName();
00103 if ( file_exists( $cacheFileName ) )
00104 unlink( $cacheFileName );
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 function getSSLZones()
00116 {
00117 if ( !isset( $GLOBALS['eZSSLZonesCachedPathStrings'] ) )
00118 {
00119 $cacheFileName = eZSSLZone::cacheFileName();
00120 $cacheDirName = eZSys::cacheDirectory();
00121
00122
00123 if ( !is_readable( $cacheFileName ) )
00124 {
00125 $ini =& eZINI::instance();
00126 $sslSubtrees = $ini->variable( 'SSLZoneSettings', 'SSLSubtrees' );
00127
00128 if ( !isset( $sslSubtrees ) || !$sslSubtrees )
00129 return array();
00130
00131
00132
00133 $pathStringsArray = array();
00134 foreach ( $sslSubtrees as $uri )
00135 {
00136 $node = eZContentObjectTreeNode::fetchByURLPath( preg_replace( '/^\//', '', $uri ) );
00137 if ( !is_object( $node ) )
00138 {
00139 eZDebug::writeError( "cannot fetch node by URI '$uri'", 'eZSSLZone::getSSLZones' );
00140 continue;
00141 }
00142 $pathStringsArray[$uri] = $node->attribute( 'path_string' );
00143 unset( $node );
00144 }
00145
00146
00147 if ( !file_exists( $cacheDirName ) )
00148 {
00149 eZDir::mkdir( $cacheDirName, false, true );
00150 }
00151 $fh = fopen( $cacheFileName, 'w' );
00152 if ( $fh )
00153 {
00154 fwrite( $fh, "<?php\n\$pathStringsArray = " . var_export( $pathStringsArray, true ) . ";\n?>" );
00155 fclose( $fh );
00156 }
00157
00158 return $GLOBALS['eZSSLZonesCachedPathStrings'] = $pathStringsArray;
00159 }
00160 else
00161 {
00162
00163 include_once( $cacheFileName );
00164 return $GLOBALS['eZSSLZonesCachedPathStrings'] = $pathStringsArray;
00165 }
00166 }
00167
00168
00169 $pathStringsArray = $GLOBALS['eZSSLZonesCachedPathStrings'];
00170
00171 return $pathStringsArray;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 function viewIsInArray( $module, $view, $moduleViews )
00184 {
00185 if ( in_array( "$module/$view", $moduleViews ) )
00186 return 2;
00187 if ( in_array( "$module/*", $moduleViews ) )
00188 return 1;
00189 return 0;
00190 }
00191
00192
00193
00194
00195
00196 function isKeepModeView( $module, $view )
00197 {
00198 $ini =& eZINI::instance();
00199 $viewsModes = $ini->variable( 'SSLZoneSettings', 'ModuleViewAccessMode' );
00200 $sslViews = array_keys( $viewsModes, 'ssl' );
00201 $keepModeViews = array_keys( $viewsModes, 'keep' );
00202
00203 if ( eZSSLZone::viewIsInArray( $module, $view, $keepModeViews ) <
00204 eZSSLZone::viewIsInArray( $module, $view, $sslViews ) )
00205 {
00206 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'The view cannot choose access mode itself.' );
00207 return false;
00208 }
00209
00210 return true;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 function switchIfNeeded( $inSSL )
00228 {
00229
00230 if ( !isset( $inSSL ) )
00231 return;
00232
00233
00234 $nowSSL = eZSys::isSSLNow();
00235
00236 $requestURI = eZSys::requestURI();
00237 $indexDir = eZSys::indexDir( false );
00238
00239 $sslZoneRedirectionURL = false;
00240 if ( $nowSSL && !$inSSL )
00241 {
00242
00243 $ini =& eZINI::instance();
00244 $host = $ini->variable( 'SiteSettings', 'SiteURL' );
00245 $sslZoneRedirectionURL = "http://" . $host . $indexDir . $requestURI;
00246 }
00247 elseif ( !$nowSSL && $inSSL )
00248 {
00249
00250 $host = eZSys::serverVariable( 'HTTP_HOST' );
00251 $host = preg_replace( '/:\d+$/', '', $host );
00252
00253 $ini =& eZINI::instance();
00254 $sslPort = $ini->variable( 'SiteSettings', 'SSLPort' );
00255 $sslPortString = ( $sslPort == EZSSLZONE_DEFAULT_SSL_PORT ) ? '' : ":$sslPort";
00256 $sslZoneRedirectionURL = "https://" . $host . $sslPortString . $indexDir . $requestURI;
00257 }
00258
00259 if ( $sslZoneRedirectionURL )
00260 {
00261 eZDebugSetting::writeDebug( 'kernel-ssl-zone', "redirecting to [$sslZoneRedirectionURL]" );
00262 eZHTTPTool::redirect( $sslZoneRedirectionURL );
00263 eZExecution::cleanExit();
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 function checkNodeID( $module, $view, $nodeID )
00277 {
00278 if ( !eZSSLZone::enabled() )
00279 return;
00280
00281
00282
00283
00284
00285 if ( !eZSSLZone::isKeepModeView( $module, $view ) )
00286 return;
00287
00288
00289 $pathStrings = eZPersistentObject::fetchObjectList(
00290 eZContentObjectTreeNode::definition(),
00291 array( 'path_string' ),
00292 array( 'node_id' => $nodeID ),
00293 null,
00294 null,
00295 false
00296 );
00297
00298 if ( !$pathStrings )
00299 {
00300 eZDebug::writeError( "Node #$nodeID not found", "eZSSLZone::checkNodeID" );
00301 return;
00302 }
00303
00304 eZSSLZone::checkNodePath( $module, $view, $pathStrings[0]['path_string'] );
00305 }
00306
00307
00308
00309
00310
00311
00312 function checkNode( $module, $view, &$node, $redirect = true )
00313 {
00314 if ( !eZSSLZone::enabled() )
00315 return;
00316
00317
00318
00319
00320
00321 if ( !$redirect && !eZSSLZone::isKeepModeView( $module, $view ) )
00322 return;
00323
00324 include_once( 'kernel/classes/ezcontentobjecttreenode.php' );
00325 $pathString = $node->attribute( 'path_string' );
00326
00327 return eZSSLZone::checkNodePath( $module, $view, $pathString, $redirect );
00328 }
00329
00330
00331
00332
00333
00334
00335 function checkNodePath( $module, $view, $pathString, $redirect = true )
00336 {
00337 if ( !eZSSLZone::enabled() )
00338 return;
00339
00340
00341
00342
00343
00344 if ( !$redirect && !eZSSLZone::isKeepModeView( $module, $view ) )
00345 return;
00346
00347
00348 $sslZones = eZSSLZone::getSSLZones();
00349
00350 $inSSLZone = false;
00351 foreach ( $sslZones as $sslZonePathString )
00352 {
00353 if ( strpos( $pathString, $sslZonePathString ) === 0 )
00354 {
00355 $inSSLZone = true;
00356 break;
00357 }
00358 }
00359
00360 eZDebugSetting::writeDebug( 'kernel-ssl-zone',
00361 ( $inSSLZone ? 'yes' : 'no' ),
00362 "Does the node having path $pathString belong to an SSL zone?" );
00363
00364 if ( $redirect )
00365 eZSSLZone::switchIfNeeded( $inSSLZone );
00366
00367 return $inSSLZone;
00368 }
00369
00370
00371
00372
00373
00374
00375 function checkObject( $module, $view, $object )
00376 {
00377 if ( !eZSSLZone::enabled() )
00378 return;
00379
00380
00381
00382
00383
00384 if ( !eZSSLZone::isKeepModeView( $module, $view ) )
00385 return;
00386
00387 $pathStringList = eZPersistentObject::fetchObjectList(
00388 eZContentObjectTreeNode::definition(),
00389 array( 'path_string' ),
00390 array( 'contentobject_id' => $object->attribute( 'id' ) ),
00391 null,
00392 null,
00393 false
00394 );
00395
00396 if ( is_array( $pathStringList ) && count( $pathStringList ) )
00397 {
00398
00399
00400
00401
00402
00403
00404 array_walk( $pathStringList, create_function( '&$a', '$a = $a[\'path_string\'];' ) );
00405 }
00406 else
00407 {
00408
00409
00410
00411
00412
00413 $pathStringList = array();
00414 $nodes = $object->parentNodes( $object->attribute( 'current' ) );
00415 if ( !is_array( $nodes ) )
00416 {
00417 eZDebug::writeError( 'Object ' . $object->attribute( 'is' ) .
00418 'does not have neither assigned nor parent nodes.' );
00419 }
00420 else
00421 {
00422 foreach( $nodes as $node )
00423 {
00424 $pathStringList[] = $node->attribute( 'path_string' );
00425 }
00426 }
00427 }
00428
00429 $inSSL = false;
00430 foreach ( $pathStringList as $pathString )
00431 {
00432 if ( eZSSLZone::checkNodePath( $module, $view, $pathString, false ) )
00433 {
00434 $inSSL = true;
00435 break;
00436 }
00437 }
00438
00439 eZSSLZone::switchIfNeeded( $inSSL );
00440 }
00441
00442
00443
00444
00445
00446
00447 function checkModuleView( $module, $view )
00448 {
00449 if ( !eZSSLZone::enabled() )
00450 return;
00451
00452 $ini =& eZINI::instance();
00453 $viewsModes = $ini->variable( 'SSLZoneSettings', 'ModuleViewAccessMode' );
00454
00455 $sslViews = array_keys( $viewsModes, 'ssl' );
00456 $keepModeViews = array_keys( $viewsModes, 'keep' );
00457
00458 $sslPriority = eZSSLZone::viewIsInArray( $module, $view, $sslViews );
00459 $keepModePriority = eZSSLZone::viewIsInArray( $module, $view, $keepModeViews );
00460
00461 if ( $sslPriority && $keepModePriority && $sslPriority == $keepModePriority )
00462 {
00463 eZDebug::writeError( "Configuration error: view $module/$view is defined both as 'ssl' and 'keep'",
00464 'eZSSLZone' );
00465 return;
00466 }
00467
00468
00469
00470
00471
00472 if ( $keepModePriority > $sslPriority )
00473 {
00474 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'Keeping current access mode...' );
00475 return;
00476 }
00477
00478
00479
00480
00481 $inSSL = ( $sslPriority > 0 );
00482
00483 eZDebugSetting::writeDebug( 'kernel-ssl-zone',
00484 ( isset( $inSSL ) ? ( $inSSL?'yes':'no') : 'dunno' ),
00485 'Should we use SSL for this view?' );
00486
00487
00488 eZSSLZone::switchIfNeeded( $inSSL );
00489 }
00490 }
00491 ?>