1*40df464eSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*40df464eSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*40df464eSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*40df464eSAndrew Rist  * distributed with this work for additional information
6*40df464eSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*40df464eSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*40df464eSAndrew Rist  * "License"); you may not use this file except in compliance
9*40df464eSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*40df464eSAndrew Rist  *
11*40df464eSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*40df464eSAndrew Rist  *
13*40df464eSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*40df464eSAndrew Rist  * software distributed under the License is distributed on an
15*40df464eSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*40df464eSAndrew Rist  * KIND, either express or implied.  See the License for the
17*40df464eSAndrew Rist  * specific language governing permissions and limitations
18*40df464eSAndrew Rist  * under the License.
19*40df464eSAndrew Rist  *
20*40df464eSAndrew Rist  *************************************************************/
21*40df464eSAndrew Rist 
22*40df464eSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svl.hxx"
26cdf0e10cSrcweir #include <svl/restrictedpaths.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <algorithm>
29cdf0e10cSrcweir #include <osl/process.h>
30cdf0e10cSrcweir #include <tools/urlobj.hxx>
31cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
32cdf0e10cSrcweir #include <unotools/syslocale.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir namespace svt
35cdf0e10cSrcweir {
36cdf0e10cSrcweir     namespace
37cdf0e10cSrcweir     {
38cdf0e10cSrcweir         // ----------------------------------------------------------------
39cdf0e10cSrcweir         /** retrieves the value of an environment variable
40cdf0e10cSrcweir             @return <TRUE/> if and only if the retrieved string value is not empty
41cdf0e10cSrcweir         */
lcl_getEnvironmentValue(const sal_Char * _pAsciiEnvName,::rtl::OUString & _rValue)42cdf0e10cSrcweir         bool lcl_getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue )
43cdf0e10cSrcweir         {
44cdf0e10cSrcweir             _rValue = ::rtl::OUString();
45cdf0e10cSrcweir             ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName );
46cdf0e10cSrcweir             osl_getEnvironment( sEnvName.pData, &_rValue.pData );
47cdf0e10cSrcweir             return _rValue.getLength() != 0;
48cdf0e10cSrcweir         }
49cdf0e10cSrcweir 
50cdf0e10cSrcweir         //-----------------------------------------------------------------
lcl_convertStringListToUrls(const String & _rColonSeparatedList,::std::vector<String> & _rTokens,bool _bFinalSlash)51cdf0e10cSrcweir         void lcl_convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash )
52cdf0e10cSrcweir         {
53cdf0e10cSrcweir             const sal_Unicode s_cSeparator =
54cdf0e10cSrcweir     #if defined(WNT)
55cdf0e10cSrcweir                 ';'
56cdf0e10cSrcweir     #else
57cdf0e10cSrcweir                 ':'
58cdf0e10cSrcweir     #endif
59cdf0e10cSrcweir                 ;
60cdf0e10cSrcweir             xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator );
61cdf0e10cSrcweir             _rTokens.resize( 0 ); _rTokens.reserve( nTokens );
62cdf0e10cSrcweir             for ( xub_StrLen i=0; i<nTokens; ++i )
63cdf0e10cSrcweir             {
64cdf0e10cSrcweir                 // the current token in the list
65cdf0e10cSrcweir                 String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator );
66cdf0e10cSrcweir                 if ( !sCurrentToken.Len() )
67cdf0e10cSrcweir                     continue;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir                 INetURLObject aCurrentURL;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir                 String sURL;
72cdf0e10cSrcweir                 if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) )
73cdf0e10cSrcweir                     aCurrentURL = INetURLObject( sURL );
74cdf0e10cSrcweir                 else
75cdf0e10cSrcweir                 {
76cdf0e10cSrcweir                     // smart URL parsing, assuming FILE protocol
77cdf0e10cSrcweir                     aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE );
78cdf0e10cSrcweir                 }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir                 if ( _bFinalSlash )
81cdf0e10cSrcweir                     aCurrentURL.setFinalSlash( );
82cdf0e10cSrcweir                 else
83cdf0e10cSrcweir                     aCurrentURL.removeFinalSlash( );
84cdf0e10cSrcweir                 _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) );
85cdf0e10cSrcweir             }
86cdf0e10cSrcweir         }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir     //=====================================================================
91cdf0e10cSrcweir     //= CheckURLAllowed
92cdf0e10cSrcweir     //=====================================================================
93cdf0e10cSrcweir     struct CheckURLAllowed
94cdf0e10cSrcweir     {
95cdf0e10cSrcweir     protected:
96cdf0e10cSrcweir     #ifdef WNT
97cdf0e10cSrcweir         SvtSysLocale    m_aSysLocale;
98cdf0e10cSrcweir     #endif
99cdf0e10cSrcweir         String          m_sCheckURL;    // the URL to check
100cdf0e10cSrcweir         bool            m_bAllowParent;
101cdf0e10cSrcweir     public:
CheckURLAllowedsvt::CheckURLAllowed102cdf0e10cSrcweir         inline CheckURLAllowed( const String& _rCheckURL, bool bAllowParent = true )
103cdf0e10cSrcweir             :m_sCheckURL( _rCheckURL ), m_bAllowParent( bAllowParent )
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir     #ifdef WNT
106cdf0e10cSrcweir             // on windows, assume that the relevant file systems are case insensitive,
107cdf0e10cSrcweir             // thus normalize the URL
108cdf0e10cSrcweir             m_sCheckURL = m_aSysLocale.GetCharClass().toLower( m_sCheckURL, 0, m_sCheckURL.Len() );
109cdf0e10cSrcweir     #endif
110cdf0e10cSrcweir         }
111cdf0e10cSrcweir 
operator ()svt::CheckURLAllowed112cdf0e10cSrcweir         bool operator()( const String& _rApprovedURL )
113cdf0e10cSrcweir         {
114cdf0e10cSrcweir     #ifdef WNT
115cdf0e10cSrcweir             // on windows, assume that the relevant file systems are case insensitive,
116cdf0e10cSrcweir             // thus normalize the URL
117cdf0e10cSrcweir             String sApprovedURL( m_aSysLocale.GetCharClass().toLower( _rApprovedURL, 0, _rApprovedURL.Len() ) );
118cdf0e10cSrcweir     #else
119cdf0e10cSrcweir             String sApprovedURL( _rApprovedURL );
120cdf0e10cSrcweir     #endif
121cdf0e10cSrcweir 
122cdf0e10cSrcweir             xub_StrLen nLenApproved = sApprovedURL.Len();
123cdf0e10cSrcweir             xub_StrLen nLenChecked  = m_sCheckURL.Len();
124cdf0e10cSrcweir 
125cdf0e10cSrcweir             if ( nLenApproved > nLenChecked )
126cdf0e10cSrcweir             {
127cdf0e10cSrcweir                 if ( m_bAllowParent )
128cdf0e10cSrcweir                 {
129cdf0e10cSrcweir                     if ( sApprovedURL.Search( m_sCheckURL ) == 0 )
130cdf0e10cSrcweir                     {
131cdf0e10cSrcweir                         if ( ( m_sCheckURL.GetChar( nLenChecked - 1 ) == '/' )
132cdf0e10cSrcweir                             || ( sApprovedURL.GetChar( nLenChecked ) == '/' ) )
133cdf0e10cSrcweir                             return true;
134cdf0e10cSrcweir                     }
135cdf0e10cSrcweir                 }
136cdf0e10cSrcweir                 else
137cdf0e10cSrcweir                 {
138cdf0e10cSrcweir                     // just a difference in final slash?
139cdf0e10cSrcweir                     if ( ( nLenApproved == ( nLenChecked + 1 ) ) &&
140cdf0e10cSrcweir                         ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) )
141cdf0e10cSrcweir                         return true;
142cdf0e10cSrcweir                 }
143cdf0e10cSrcweir                 return false;
144cdf0e10cSrcweir             }
145cdf0e10cSrcweir             else if ( nLenApproved < nLenChecked )
146cdf0e10cSrcweir             {
147cdf0e10cSrcweir                 if ( m_sCheckURL.Search( sApprovedURL ) == 0 )
148cdf0e10cSrcweir                 {
149cdf0e10cSrcweir                     if ( ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' )
150cdf0e10cSrcweir                         || ( m_sCheckURL.GetChar( nLenApproved ) == '/' ) )
151cdf0e10cSrcweir                         return true;
152cdf0e10cSrcweir                 }
153cdf0e10cSrcweir                 return false;
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir             else
156cdf0e10cSrcweir             {
157cdf0e10cSrcweir                 // strings have equal length
158cdf0e10cSrcweir                 return ( sApprovedURL == m_sCheckURL );
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir         }
161cdf0e10cSrcweir     };
162cdf0e10cSrcweir 
163cdf0e10cSrcweir     //=====================================================================
164cdf0e10cSrcweir     //= RestrictedPaths
165cdf0e10cSrcweir     //=====================================================================
166cdf0e10cSrcweir     //---------------------------------------------------------------------
RestrictedPaths()167cdf0e10cSrcweir     RestrictedPaths::RestrictedPaths()
168cdf0e10cSrcweir         :m_bFilterIsEnabled( true )
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         ::rtl::OUString sRestrictedPathList;
171cdf0e10cSrcweir         if ( lcl_getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) )
172cdf0e10cSrcweir             // append a final slash. This ensures that when we later on check
173cdf0e10cSrcweir             // for unrestricted paths, we don't allow paths like "/home/user35" just because
174cdf0e10cSrcweir             // "/home/user3" is allowed - with the final slash, we make it "/home/user3/".
175cdf0e10cSrcweir             lcl_convertStringListToUrls( sRestrictedPathList, m_aUnrestrictedURLs, true );
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir 
~RestrictedPaths()178cdf0e10cSrcweir     RestrictedPaths::~RestrictedPaths() {}
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     // --------------------------------------------------------------------
isUrlAllowed(const String & _rURL) const181cdf0e10cSrcweir     bool RestrictedPaths::isUrlAllowed( const String& _rURL ) const
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled )
184cdf0e10cSrcweir             return true;
185cdf0e10cSrcweir 
186cdf0e10cSrcweir         ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if(
187cdf0e10cSrcweir             m_aUnrestrictedURLs.begin(),
188cdf0e10cSrcweir             m_aUnrestrictedURLs.end(),
189cdf0e10cSrcweir             CheckURLAllowed( _rURL, true )
190cdf0e10cSrcweir         );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         return ( aApprovedURL != m_aUnrestrictedURLs.end() );
193cdf0e10cSrcweir     }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir     // --------------------------------------------------------------------
isUrlAllowed(const String & _rURL,bool allowParents) const196cdf0e10cSrcweir     bool RestrictedPaths::isUrlAllowed( const String& _rURL, bool allowParents ) const
197cdf0e10cSrcweir     {
198cdf0e10cSrcweir         if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled )
199cdf0e10cSrcweir             return true;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir         ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if(
202cdf0e10cSrcweir             m_aUnrestrictedURLs.begin(),
203cdf0e10cSrcweir             m_aUnrestrictedURLs.end(),
204cdf0e10cSrcweir             CheckURLAllowed( _rURL, allowParents )
205cdf0e10cSrcweir         );
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         return ( aApprovedURL != m_aUnrestrictedURLs.end() );
208cdf0e10cSrcweir     }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir }   // namespace svt
211