1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svl.hxx" 30 #include <svl/restrictedpaths.hxx> 31 32 #include <algorithm> 33 #include <osl/process.h> 34 #include <tools/urlobj.hxx> 35 #include <unotools/localfilehelper.hxx> 36 #include <unotools/syslocale.hxx> 37 38 namespace svt 39 { 40 namespace 41 { 42 // ---------------------------------------------------------------- 43 /** retrieves the value of an environment variable 44 @return <TRUE/> if and only if the retrieved string value is not empty 45 */ 46 bool lcl_getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) 47 { 48 _rValue = ::rtl::OUString(); 49 ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); 50 osl_getEnvironment( sEnvName.pData, &_rValue.pData ); 51 return _rValue.getLength() != 0; 52 } 53 54 //----------------------------------------------------------------- 55 void lcl_convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) 56 { 57 const sal_Unicode s_cSeparator = 58 #if defined(WNT) 59 ';' 60 #else 61 ':' 62 #endif 63 ; 64 xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); 65 _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); 66 for ( xub_StrLen i=0; i<nTokens; ++i ) 67 { 68 // the current token in the list 69 String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); 70 if ( !sCurrentToken.Len() ) 71 continue; 72 73 INetURLObject aCurrentURL; 74 75 String sURL; 76 if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) 77 aCurrentURL = INetURLObject( sURL ); 78 else 79 { 80 // smart URL parsing, assuming FILE protocol 81 aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); 82 } 83 84 if ( _bFinalSlash ) 85 aCurrentURL.setFinalSlash( ); 86 else 87 aCurrentURL.removeFinalSlash( ); 88 _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); 89 } 90 } 91 92 } 93 94 //===================================================================== 95 //= CheckURLAllowed 96 //===================================================================== 97 struct CheckURLAllowed 98 { 99 protected: 100 #ifdef WNT 101 SvtSysLocale m_aSysLocale; 102 #endif 103 String m_sCheckURL; // the URL to check 104 bool m_bAllowParent; 105 public: 106 inline CheckURLAllowed( const String& _rCheckURL, bool bAllowParent = true ) 107 :m_sCheckURL( _rCheckURL ), m_bAllowParent( bAllowParent ) 108 { 109 #ifdef WNT 110 // on windows, assume that the relevant file systems are case insensitive, 111 // thus normalize the URL 112 m_sCheckURL = m_aSysLocale.GetCharClass().toLower( m_sCheckURL, 0, m_sCheckURL.Len() ); 113 #endif 114 } 115 116 bool operator()( const String& _rApprovedURL ) 117 { 118 #ifdef WNT 119 // on windows, assume that the relevant file systems are case insensitive, 120 // thus normalize the URL 121 String sApprovedURL( m_aSysLocale.GetCharClass().toLower( _rApprovedURL, 0, _rApprovedURL.Len() ) ); 122 #else 123 String sApprovedURL( _rApprovedURL ); 124 #endif 125 126 xub_StrLen nLenApproved = sApprovedURL.Len(); 127 xub_StrLen nLenChecked = m_sCheckURL.Len(); 128 129 if ( nLenApproved > nLenChecked ) 130 { 131 if ( m_bAllowParent ) 132 { 133 if ( sApprovedURL.Search( m_sCheckURL ) == 0 ) 134 { 135 if ( ( m_sCheckURL.GetChar( nLenChecked - 1 ) == '/' ) 136 || ( sApprovedURL.GetChar( nLenChecked ) == '/' ) ) 137 return true; 138 } 139 } 140 else 141 { 142 // just a difference in final slash? 143 if ( ( nLenApproved == ( nLenChecked + 1 ) ) && 144 ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) ) 145 return true; 146 } 147 return false; 148 } 149 else if ( nLenApproved < nLenChecked ) 150 { 151 if ( m_sCheckURL.Search( sApprovedURL ) == 0 ) 152 { 153 if ( ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) 154 || ( m_sCheckURL.GetChar( nLenApproved ) == '/' ) ) 155 return true; 156 } 157 return false; 158 } 159 else 160 { 161 // strings have equal length 162 return ( sApprovedURL == m_sCheckURL ); 163 } 164 } 165 }; 166 167 //===================================================================== 168 //= RestrictedPaths 169 //===================================================================== 170 //--------------------------------------------------------------------- 171 RestrictedPaths::RestrictedPaths() 172 :m_bFilterIsEnabled( true ) 173 { 174 ::rtl::OUString sRestrictedPathList; 175 if ( lcl_getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) ) 176 // append a final slash. This ensures that when we later on check 177 // for unrestricted paths, we don't allow paths like "/home/user35" just because 178 // "/home/user3" is allowed - with the final slash, we make it "/home/user3/". 179 lcl_convertStringListToUrls( sRestrictedPathList, m_aUnrestrictedURLs, true ); 180 } 181 182 RestrictedPaths::~RestrictedPaths() {} 183 184 // -------------------------------------------------------------------- 185 bool RestrictedPaths::isUrlAllowed( const String& _rURL ) const 186 { 187 if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) 188 return true; 189 190 ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( 191 m_aUnrestrictedURLs.begin(), 192 m_aUnrestrictedURLs.end(), 193 CheckURLAllowed( _rURL, true ) 194 ); 195 196 return ( aApprovedURL != m_aUnrestrictedURLs.end() ); 197 } 198 199 // -------------------------------------------------------------------- 200 bool RestrictedPaths::isUrlAllowed( const String& _rURL, bool allowParents ) const 201 { 202 if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) 203 return true; 204 205 ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( 206 m_aUnrestrictedURLs.begin(), 207 m_aUnrestrictedURLs.end(), 208 CheckURLAllowed( _rURL, allowParents ) 209 ); 210 211 return ( aApprovedURL != m_aUnrestrictedURLs.end() ); 212 } 213 214 } // namespace svt 215