1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <vector>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <osl/process.h>
30cdf0e10cSrcweir #include <osl/socket.hxx>
31cdf0e10cSrcweir #include <osl/mutex.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <rtl/string.hxx>
34cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <com/sun/star/security/RuntimePermission.hpp>
37cdf0e10cSrcweir #include <com/sun/star/security/AllPermission.hpp>
38cdf0e10cSrcweir #include <com/sun/star/io/FilePermission.hpp>
39cdf0e10cSrcweir #include <com/sun/star/connection/SocketPermission.hpp>
40cdf0e10cSrcweir #include <com/sun/star/security/AccessControlException.hpp>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include "permissions.h"
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 
47cdf0e10cSrcweir using namespace ::std;
48cdf0e10cSrcweir using namespace ::osl;
49cdf0e10cSrcweir using namespace ::com::sun::star;
50cdf0e10cSrcweir using namespace ::com::sun::star::uno;
51cdf0e10cSrcweir using ::rtl::OUString;
52cdf0e10cSrcweir using ::rtl::OUStringBuffer;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir namespace stoc_sec
55cdf0e10cSrcweir {
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
makeMask(OUString const & items,char const * const * strings)58cdf0e10cSrcweir static inline sal_Int32 makeMask(
59cdf0e10cSrcweir     OUString const & items, char const * const * strings ) SAL_THROW( () )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     sal_Int32 mask = 0;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir     sal_Int32 n = 0;
64cdf0e10cSrcweir     do
65cdf0e10cSrcweir     {
66cdf0e10cSrcweir         OUString item( items.getToken( 0, ',', n ).trim() );
67cdf0e10cSrcweir         if (! item.getLength())
68cdf0e10cSrcweir             continue;
69cdf0e10cSrcweir         sal_Int32 nPos = 0;
70cdf0e10cSrcweir         while (strings[ nPos ])
71cdf0e10cSrcweir         {
72cdf0e10cSrcweir             if (item.equalsAscii( strings[ nPos ] ))
73cdf0e10cSrcweir             {
74cdf0e10cSrcweir                 mask |= (0x80000000 >> nPos);
75cdf0e10cSrcweir                 break;
76cdf0e10cSrcweir             }
77cdf0e10cSrcweir             ++nPos;
78cdf0e10cSrcweir         }
79cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
80cdf0e10cSrcweir         if (! strings[ nPos ])
81cdf0e10cSrcweir         {
82cdf0e10cSrcweir             OUStringBuffer buf( 48 );
83cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("### ignoring unknown socket action: ") );
84cdf0e10cSrcweir             buf.append( item );
85cdf0e10cSrcweir             ::rtl::OString str( ::rtl::OUStringToOString(
86cdf0e10cSrcweir                 buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
87cdf0e10cSrcweir             OSL_TRACE( str.getStr() );
88cdf0e10cSrcweir         }
89cdf0e10cSrcweir #endif
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir     while (n >= 0); // all items
92cdf0e10cSrcweir     return mask;
93cdf0e10cSrcweir }
94cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
makeStrings(sal_Int32 mask,char const * const * strings)95cdf0e10cSrcweir static inline OUString makeStrings(
96cdf0e10cSrcweir     sal_Int32 mask, char const * const * strings ) SAL_THROW( () )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     OUStringBuffer buf( 48 );
99cdf0e10cSrcweir     while (mask)
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         if (0x80000000 & mask)
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             buf.appendAscii( *strings );
104cdf0e10cSrcweir             if (mask << 1) // more items following
105cdf0e10cSrcweir                 buf.append( (sal_Unicode)',' );
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir         mask = (mask << 1);
108cdf0e10cSrcweir         ++strings;
109cdf0e10cSrcweir     }
110cdf0e10cSrcweir     return buf.makeStringAndClear();
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir //##################################################################################################
114cdf0e10cSrcweir 
115cdf0e10cSrcweir //==================================================================================================
116cdf0e10cSrcweir class SocketPermission : public Permission
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     static char const * s_actions [];
119cdf0e10cSrcweir     sal_Int32 m_actions;
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     OUString m_host;
122cdf0e10cSrcweir     sal_Int32 m_lowerPort;
123cdf0e10cSrcweir     sal_Int32 m_upperPort;
124cdf0e10cSrcweir     mutable OUString m_ip;
125cdf0e10cSrcweir     mutable bool m_resolveErr;
126cdf0e10cSrcweir     mutable bool m_resolvedHost;
127cdf0e10cSrcweir     bool m_wildCardHost;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     inline bool resolveHost() const SAL_THROW( () );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir public:
132cdf0e10cSrcweir     SocketPermission(
133cdf0e10cSrcweir         connection::SocketPermission const & perm,
134cdf0e10cSrcweir         ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
135cdf0e10cSrcweir         SAL_THROW( () );
136cdf0e10cSrcweir     virtual bool implies( Permission const & perm ) const SAL_THROW( () );
137cdf0e10cSrcweir     virtual OUString toString() const SAL_THROW( () );
138cdf0e10cSrcweir };
139cdf0e10cSrcweir //__________________________________________________________________________________________________
140cdf0e10cSrcweir char const * SocketPermission::s_actions [] = { "accept", "connect", "listen", "resolve", 0 };
141cdf0e10cSrcweir //__________________________________________________________________________________________________
SocketPermission(connection::SocketPermission const & perm,::rtl::Reference<Permission> const & next)142cdf0e10cSrcweir SocketPermission::SocketPermission(
143cdf0e10cSrcweir     connection::SocketPermission const & perm,
144cdf0e10cSrcweir     ::rtl::Reference< Permission > const & next )
145cdf0e10cSrcweir     SAL_THROW( () )
146cdf0e10cSrcweir     : Permission( SOCKET, next )
147cdf0e10cSrcweir     , m_actions( makeMask( perm.Actions, s_actions ) )
148cdf0e10cSrcweir     , m_host( perm.Host )
149cdf0e10cSrcweir     , m_lowerPort( 0 )
150cdf0e10cSrcweir     , m_upperPort( 65535 )
151cdf0e10cSrcweir     , m_resolveErr( false )
152cdf0e10cSrcweir     , m_resolvedHost( false )
153cdf0e10cSrcweir     , m_wildCardHost( perm.Host.getLength() && '*' == perm.Host.pData->buffer[ 0 ] )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     if (0xe0000000 & m_actions) // if any (except resolve) is given => resolve implied
156cdf0e10cSrcweir         m_actions |= 0x10000000;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     // separate host from portrange
159cdf0e10cSrcweir     sal_Int32 colon = m_host.indexOf( ':' );
160cdf0e10cSrcweir     if (colon >= 0) // port [range] given
161cdf0e10cSrcweir     {
162cdf0e10cSrcweir         sal_Int32 minus = m_host.indexOf( '-', colon +1 );
163cdf0e10cSrcweir         if (minus < 0)
164cdf0e10cSrcweir         {
165cdf0e10cSrcweir             m_lowerPort = m_upperPort = m_host.copy( colon +1 ).toInt32();
166cdf0e10cSrcweir         }
167cdf0e10cSrcweir         else if (minus == (colon +1)) // -N
168cdf0e10cSrcweir         {
169cdf0e10cSrcweir             m_upperPort = m_host.copy( minus +1 ).toInt32();
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir         else if (minus == (m_host.getLength() -1)) // N-
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir             m_lowerPort = m_host.copy( colon +1, m_host.getLength() -1 -colon -1 ).toInt32();
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir         else // A-B
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             m_lowerPort = m_host.copy( colon +1, minus - colon -1 ).toInt32();
178cdf0e10cSrcweir             m_upperPort = m_host.copy( minus +1, m_host.getLength() -minus -1 ).toInt32();
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir         m_host = m_host.copy( 0, colon );
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir }
183cdf0e10cSrcweir //__________________________________________________________________________________________________
resolveHost() const184cdf0e10cSrcweir inline bool SocketPermission::resolveHost() const SAL_THROW( () )
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     if (m_resolveErr)
187cdf0e10cSrcweir         return false;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir     if (! m_resolvedHost)
190cdf0e10cSrcweir     {
191cdf0e10cSrcweir         // dns lookup
192cdf0e10cSrcweir         SocketAddr addr;
193cdf0e10cSrcweir         SocketAddr::resolveHostname( m_host, addr );
194cdf0e10cSrcweir         OUString ip;
195cdf0e10cSrcweir         m_resolveErr = (::osl_Socket_Ok != ::osl_getDottedInetAddrOfSocketAddr(
196cdf0e10cSrcweir             addr.getHandle(), &ip.pData ));
197cdf0e10cSrcweir         if (m_resolveErr)
198cdf0e10cSrcweir             return false;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
201cdf0e10cSrcweir         if (! m_resolvedHost)
202cdf0e10cSrcweir         {
203cdf0e10cSrcweir             m_ip = ip;
204cdf0e10cSrcweir             m_resolvedHost = true;
205cdf0e10cSrcweir         }
206cdf0e10cSrcweir     }
207cdf0e10cSrcweir     return m_resolvedHost;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir //__________________________________________________________________________________________________
implies(Permission const & perm) const210cdf0e10cSrcweir bool SocketPermission::implies( Permission const & perm ) const SAL_THROW( () )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir     // check type
213cdf0e10cSrcweir     if (SOCKET != perm.m_type)
214cdf0e10cSrcweir         return false;
215cdf0e10cSrcweir     SocketPermission const & demanded = static_cast< SocketPermission const & >( perm );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     // check actions
218cdf0e10cSrcweir     if ((m_actions & demanded.m_actions) != demanded.m_actions)
219cdf0e10cSrcweir         return false;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     // check ports
222cdf0e10cSrcweir     if (demanded.m_lowerPort < m_lowerPort)
223cdf0e10cSrcweir         return false;
224cdf0e10cSrcweir     if (demanded.m_upperPort > m_upperPort)
225cdf0e10cSrcweir         return false;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     // quick check host (DNS names: RFC 1034/1035)
228cdf0e10cSrcweir     if (m_host.equalsIgnoreAsciiCase( demanded.m_host ))
229cdf0e10cSrcweir         return true;
230cdf0e10cSrcweir     // check for host wildcards
231cdf0e10cSrcweir     if (m_wildCardHost)
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         OUString const & demanded_host = demanded.m_host;
234cdf0e10cSrcweir         if (demanded_host.getLength() <= m_host.getLength())
235cdf0e10cSrcweir             return false;
236cdf0e10cSrcweir         sal_Int32 len = m_host.getLength() -1; // skip star
237cdf0e10cSrcweir         return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
238cdf0e10cSrcweir             demanded_host.getStr() + demanded_host.getLength() - len, len,
239cdf0e10cSrcweir             m_host.pData->buffer + 1, len ));
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir     if (demanded.m_wildCardHost)
242cdf0e10cSrcweir         return false;
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     // compare IP addresses
245cdf0e10cSrcweir     if (! resolveHost())
246cdf0e10cSrcweir         return false;
247cdf0e10cSrcweir     if (! demanded.resolveHost())
248cdf0e10cSrcweir         return false;
249cdf0e10cSrcweir     return (sal_False != m_ip.equals( demanded.m_ip ));
250cdf0e10cSrcweir }
251cdf0e10cSrcweir //__________________________________________________________________________________________________
toString() const252cdf0e10cSrcweir OUString SocketPermission::toString() const SAL_THROW( () )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir     OUStringBuffer buf( 48 );
255cdf0e10cSrcweir     // host
256cdf0e10cSrcweir     buf.appendAscii(
257cdf0e10cSrcweir         RTL_CONSTASCII_STRINGPARAM("com.sun.star.connection.SocketPermission (host=\"") );
258cdf0e10cSrcweir     buf.append( m_host );
259cdf0e10cSrcweir     if (m_resolvedHost)
260cdf0e10cSrcweir     {
261cdf0e10cSrcweir         buf.append( (sal_Unicode)'[' );
262cdf0e10cSrcweir         buf.append( m_ip );
263cdf0e10cSrcweir         buf.append( (sal_Unicode)']' );
264cdf0e10cSrcweir     }
265cdf0e10cSrcweir     // port
266cdf0e10cSrcweir     if (0 != m_lowerPort || 65535 != m_upperPort)
267cdf0e10cSrcweir     {
268cdf0e10cSrcweir         buf.append( (sal_Unicode)':' );
269cdf0e10cSrcweir         if (m_lowerPort > 0)
270cdf0e10cSrcweir             buf.append( m_lowerPort );
271cdf0e10cSrcweir         if (m_upperPort > m_lowerPort)
272cdf0e10cSrcweir         {
273cdf0e10cSrcweir             buf.append( (sal_Unicode)'-' );
274cdf0e10cSrcweir             if (m_upperPort < 65535)
275cdf0e10cSrcweir                 buf.append( m_upperPort );
276cdf0e10cSrcweir         }
277cdf0e10cSrcweir     }
278cdf0e10cSrcweir     // actions
279cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
280cdf0e10cSrcweir     buf.append( makeStrings( m_actions, s_actions ) );
281cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
282cdf0e10cSrcweir     return buf.makeStringAndClear();
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir //##################################################################################################
286cdf0e10cSrcweir 
287cdf0e10cSrcweir //==================================================================================================
288cdf0e10cSrcweir class FilePermission : public Permission
289cdf0e10cSrcweir {
290cdf0e10cSrcweir     static char const * s_actions [];
291cdf0e10cSrcweir     sal_Int32 m_actions;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     OUString m_url;
294cdf0e10cSrcweir     bool m_allFiles;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir public:
297cdf0e10cSrcweir     FilePermission(
298cdf0e10cSrcweir         io::FilePermission const & perm,
299cdf0e10cSrcweir         ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
300cdf0e10cSrcweir         SAL_THROW( () );
301cdf0e10cSrcweir     virtual bool implies( Permission const & perm ) const SAL_THROW( () );
302cdf0e10cSrcweir     virtual OUString toString() const SAL_THROW( () );
303cdf0e10cSrcweir };
304cdf0e10cSrcweir //__________________________________________________________________________________________________
305cdf0e10cSrcweir char const * FilePermission::s_actions [] = { "read", "write", "execute", "delete", 0 };
306cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
getWorkingDir()307cdf0e10cSrcweir static OUString const & getWorkingDir() SAL_THROW( () )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir     static OUString * s_workingDir = 0;
310cdf0e10cSrcweir     if (! s_workingDir)
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         OUString workingDir;
313cdf0e10cSrcweir         ::osl_getProcessWorkingDir( &workingDir.pData );
314cdf0e10cSrcweir 
315cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
316cdf0e10cSrcweir         if (! s_workingDir)
317cdf0e10cSrcweir         {
318cdf0e10cSrcweir             static OUString s_dir( workingDir );
319cdf0e10cSrcweir             s_workingDir = &s_dir;
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir     return *s_workingDir;
323cdf0e10cSrcweir }
324cdf0e10cSrcweir //__________________________________________________________________________________________________
FilePermission(io::FilePermission const & perm,::rtl::Reference<Permission> const & next)325cdf0e10cSrcweir FilePermission::FilePermission(
326cdf0e10cSrcweir     io::FilePermission const & perm,
327cdf0e10cSrcweir     ::rtl::Reference< Permission > const & next )
328cdf0e10cSrcweir     SAL_THROW( () )
329cdf0e10cSrcweir     : Permission( FILE, next )
330cdf0e10cSrcweir     , m_actions( makeMask( perm.Actions, s_actions ) )
331cdf0e10cSrcweir     , m_url( perm.URL )
332cdf0e10cSrcweir     , m_allFiles( sal_False != perm.URL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("<<ALL FILES>>")) )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir     if (! m_allFiles)
335cdf0e10cSrcweir     {
336cdf0e10cSrcweir         if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ))
337cdf0e10cSrcweir         {
338cdf0e10cSrcweir             OUStringBuffer buf( 64 );
339cdf0e10cSrcweir             buf.append( getWorkingDir() );
340cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/*") );
341cdf0e10cSrcweir             m_url = buf.makeStringAndClear();
342cdf0e10cSrcweir         }
343cdf0e10cSrcweir         else if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("-") ))
344cdf0e10cSrcweir         {
345cdf0e10cSrcweir             OUStringBuffer buf( 64 );
346cdf0e10cSrcweir             buf.append( getWorkingDir() );
347cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/-") );
348cdf0e10cSrcweir             m_url = buf.makeStringAndClear();
349cdf0e10cSrcweir         }
350cdf0e10cSrcweir         else if (0 != m_url.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:///") ))
351cdf0e10cSrcweir         {
352cdf0e10cSrcweir             // relative path
353cdf0e10cSrcweir             OUString out;
354cdf0e10cSrcweir             oslFileError rc = ::osl_getAbsoluteFileURL(
355cdf0e10cSrcweir                 getWorkingDir().pData, perm.URL.pData, &out.pData );
356cdf0e10cSrcweir             m_url = (osl_File_E_None == rc ? out : perm.URL); // fallback
357cdf0e10cSrcweir         }
358cdf0e10cSrcweir #ifdef SAL_W32
359cdf0e10cSrcweir         // correct win drive letters
360cdf0e10cSrcweir         if (9 < m_url.getLength() && '|' == m_url[ 9 ]) // file:///X|
361cdf0e10cSrcweir         {
362cdf0e10cSrcweir             static OUString s_colon = OUSTR(":");
363cdf0e10cSrcweir             // common case in API is a ':' (sal), so convert '|' to ':'
364cdf0e10cSrcweir             m_url = m_url.replaceAt( 9, 1, s_colon );
365cdf0e10cSrcweir         }
366cdf0e10cSrcweir #endif
367cdf0e10cSrcweir     }
368cdf0e10cSrcweir }
369cdf0e10cSrcweir //__________________________________________________________________________________________________
implies(Permission const & perm) const370cdf0e10cSrcweir bool FilePermission::implies( Permission const & perm ) const SAL_THROW( () )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     // check type
373cdf0e10cSrcweir     if (FILE != perm.m_type)
374cdf0e10cSrcweir         return false;
375cdf0e10cSrcweir     FilePermission const & demanded = static_cast< FilePermission const & >( perm );
376cdf0e10cSrcweir 
377cdf0e10cSrcweir     // check actions
378cdf0e10cSrcweir     if ((m_actions & demanded.m_actions) != demanded.m_actions)
379cdf0e10cSrcweir         return false;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     // check url
382cdf0e10cSrcweir     if (m_allFiles)
383cdf0e10cSrcweir         return true;
384cdf0e10cSrcweir     if (demanded.m_allFiles)
385cdf0e10cSrcweir         return false;
386cdf0e10cSrcweir 
387cdf0e10cSrcweir #ifdef SAL_W32
388cdf0e10cSrcweir     if (m_url.equalsIgnoreAsciiCase( demanded.m_url ))
389cdf0e10cSrcweir         return true;
390cdf0e10cSrcweir #else
391cdf0e10cSrcweir     if (m_url.equals( demanded.m_url ))
392cdf0e10cSrcweir         return true;
393cdf0e10cSrcweir #endif
394cdf0e10cSrcweir     if (m_url.getLength() > demanded.m_url.getLength())
395cdf0e10cSrcweir         return false;
396cdf0e10cSrcweir     // check /- wildcard: all files and recursive in that path
397cdf0e10cSrcweir     if (1 < m_url.getLength() &&
398cdf0e10cSrcweir         0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/-" ))
399cdf0e10cSrcweir     {
400cdf0e10cSrcweir         // demanded url must start with granted path (including path trailing path sep)
401cdf0e10cSrcweir         sal_Int32 len = m_url.getLength() -1;
402cdf0e10cSrcweir #ifdef SAL_W32
403cdf0e10cSrcweir         return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
404cdf0e10cSrcweir                     demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
405cdf0e10cSrcweir #else
406cdf0e10cSrcweir         return (0 == ::rtl_ustr_reverseCompare_WithLength(
407cdf0e10cSrcweir                     demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
408cdf0e10cSrcweir #endif
409cdf0e10cSrcweir     }
410cdf0e10cSrcweir     // check /* wildcard: all files in that path (not recursive!)
411cdf0e10cSrcweir     if (1 < m_url.getLength() &&
412cdf0e10cSrcweir         0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/*" ))
413cdf0e10cSrcweir     {
414cdf0e10cSrcweir         // demanded url must start with granted path (including path trailing path sep)
415cdf0e10cSrcweir         sal_Int32 len = m_url.getLength() -1;
416cdf0e10cSrcweir #ifdef SAL_W32
417cdf0e10cSrcweir         return ((0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
418cdf0e10cSrcweir                      demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
419cdf0e10cSrcweir                 (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
420cdf0e10cSrcweir #else
421cdf0e10cSrcweir         return ((0 == ::rtl_ustr_reverseCompare_WithLength(
422cdf0e10cSrcweir                      demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
423cdf0e10cSrcweir                 (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
424cdf0e10cSrcweir #endif
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir     return false;
427cdf0e10cSrcweir }
428cdf0e10cSrcweir //__________________________________________________________________________________________________
toString() const429cdf0e10cSrcweir OUString FilePermission::toString() const SAL_THROW( () )
430cdf0e10cSrcweir {
431cdf0e10cSrcweir     OUStringBuffer buf( 48 );
432cdf0e10cSrcweir     // url
433cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.io.FilePermission (url=\"") );
434cdf0e10cSrcweir     buf.append( m_url );
435cdf0e10cSrcweir     // actions
436cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
437cdf0e10cSrcweir     buf.append( makeStrings( m_actions, s_actions ) );
438cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
439cdf0e10cSrcweir     return buf.makeStringAndClear();
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
442cdf0e10cSrcweir //##################################################################################################
443cdf0e10cSrcweir 
444cdf0e10cSrcweir //==================================================================================================
445cdf0e10cSrcweir class RuntimePermission : public Permission
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     OUString m_name;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir public:
RuntimePermission(security::RuntimePermission const & perm,::rtl::Reference<Permission> const & next=::rtl::Reference<Permission> ())450cdf0e10cSrcweir     inline RuntimePermission(
451cdf0e10cSrcweir         security::RuntimePermission const & perm,
452cdf0e10cSrcweir         ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
453cdf0e10cSrcweir         SAL_THROW( () )
454cdf0e10cSrcweir         : Permission( RUNTIME, next )
455cdf0e10cSrcweir         , m_name( perm.Name )
456cdf0e10cSrcweir         {}
457cdf0e10cSrcweir     virtual bool implies( Permission const & perm ) const SAL_THROW( () );
458cdf0e10cSrcweir     virtual OUString toString() const SAL_THROW( () );
459cdf0e10cSrcweir };
460cdf0e10cSrcweir //__________________________________________________________________________________________________
implies(Permission const & perm) const461cdf0e10cSrcweir bool RuntimePermission::implies( Permission const & perm ) const SAL_THROW( () )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir     // check type
464cdf0e10cSrcweir     if (RUNTIME != perm.m_type)
465cdf0e10cSrcweir         return false;
466cdf0e10cSrcweir     RuntimePermission const & demanded = static_cast< RuntimePermission const & >( perm );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir     // check name
469cdf0e10cSrcweir     return (sal_False != m_name.equals( demanded.m_name ));
470cdf0e10cSrcweir }
471cdf0e10cSrcweir //__________________________________________________________________________________________________
toString() const472cdf0e10cSrcweir OUString RuntimePermission::toString() const SAL_THROW( () )
473cdf0e10cSrcweir {
474cdf0e10cSrcweir     OUStringBuffer buf( 48 );
475cdf0e10cSrcweir     buf.appendAscii(
476cdf0e10cSrcweir         RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.RuntimePermission (name=\"") );
477cdf0e10cSrcweir     buf.append( m_name );
478cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
479cdf0e10cSrcweir     return buf.makeStringAndClear();
480cdf0e10cSrcweir }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir //##################################################################################################
483cdf0e10cSrcweir 
484cdf0e10cSrcweir //__________________________________________________________________________________________________
implies(Permission const &) const485cdf0e10cSrcweir bool AllPermission::implies( Permission const & ) const SAL_THROW( () )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir     return true;
488cdf0e10cSrcweir }
489cdf0e10cSrcweir //__________________________________________________________________________________________________
toString() const490cdf0e10cSrcweir OUString AllPermission::toString() const SAL_THROW( () )
491cdf0e10cSrcweir {
492cdf0e10cSrcweir     return OUSTR("com.sun.star.security.AllPermission");
493cdf0e10cSrcweir }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir //##################################################################################################
496cdf0e10cSrcweir 
497cdf0e10cSrcweir //__________________________________________________________________________________________________
PermissionCollection(Sequence<Any> const & permissions,PermissionCollection const & addition)498cdf0e10cSrcweir PermissionCollection::PermissionCollection(
499cdf0e10cSrcweir     Sequence< Any > const & permissions, PermissionCollection const & addition )
500cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
501cdf0e10cSrcweir     : m_head( addition.m_head )
502cdf0e10cSrcweir {
503cdf0e10cSrcweir     Any const * perms = permissions.getConstArray();
504cdf0e10cSrcweir     for ( sal_Int32 nPos = permissions.getLength(); nPos--; )
505cdf0e10cSrcweir     {
506cdf0e10cSrcweir         Any const & perm = perms[ nPos ];
507cdf0e10cSrcweir         Type const & perm_type = perm.getValueType();
508cdf0e10cSrcweir 
509cdf0e10cSrcweir         // supported permission types
510cdf0e10cSrcweir         if (perm_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
511cdf0e10cSrcweir         {
512cdf0e10cSrcweir             m_head = new FilePermission(
513cdf0e10cSrcweir                 *reinterpret_cast< io::FilePermission const * >( perm.pData ), m_head );
514cdf0e10cSrcweir         }
515cdf0e10cSrcweir         else if (perm_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
516cdf0e10cSrcweir         {
517cdf0e10cSrcweir             m_head = new SocketPermission(
518cdf0e10cSrcweir                 *reinterpret_cast< connection::SocketPermission const * >( perm.pData ), m_head );
519cdf0e10cSrcweir         }
520cdf0e10cSrcweir         else if (perm_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
521cdf0e10cSrcweir         {
522cdf0e10cSrcweir             m_head = new RuntimePermission(
523cdf0e10cSrcweir                 *reinterpret_cast< security::RuntimePermission const * >( perm.pData ), m_head );
524cdf0e10cSrcweir         }
525cdf0e10cSrcweir         else if (perm_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
526cdf0e10cSrcweir         {
527cdf0e10cSrcweir             m_head = new AllPermission( m_head );
528cdf0e10cSrcweir         }
529cdf0e10cSrcweir         else
530cdf0e10cSrcweir         {
531cdf0e10cSrcweir             OUStringBuffer buf( 48 );
532cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
533cdf0e10cSrcweir                 "checking for unsupported permission type: ") );
534cdf0e10cSrcweir             buf.append( perm_type.getTypeName() );
535cdf0e10cSrcweir             throw RuntimeException(
536cdf0e10cSrcweir                 buf.makeStringAndClear(), Reference< XInterface >() );
537cdf0e10cSrcweir         }
538cdf0e10cSrcweir     }
539cdf0e10cSrcweir }
540cdf0e10cSrcweir #ifdef __DIAGNOSE
541cdf0e10cSrcweir //__________________________________________________________________________________________________
toStrings() const542cdf0e10cSrcweir Sequence< OUString > PermissionCollection::toStrings() const SAL_THROW( () )
543cdf0e10cSrcweir {
544cdf0e10cSrcweir     vector< OUString > strings;
545cdf0e10cSrcweir     strings.reserve( 8 );
546cdf0e10cSrcweir     for ( Permission * perm = m_head.get(); perm; perm = perm->m_next.get() )
547cdf0e10cSrcweir     {
548cdf0e10cSrcweir         strings.push_back( perm->toString() );
549cdf0e10cSrcweir     }
550cdf0e10cSrcweir     return Sequence< OUString >(
551cdf0e10cSrcweir         strings.empty() ? 0 : &strings[ 0 ], strings.size() );
552cdf0e10cSrcweir }
553cdf0e10cSrcweir #endif
554cdf0e10cSrcweir //__________________________________________________________________________________________________
__implies(::rtl::Reference<Permission> const & head,Permission const & demanded)555cdf0e10cSrcweir inline static bool __implies(
556cdf0e10cSrcweir     ::rtl::Reference< Permission > const & head, Permission const & demanded ) SAL_THROW( () )
557cdf0e10cSrcweir {
558cdf0e10cSrcweir     for ( Permission * perm = head.get(); perm; perm = perm->m_next.get() )
559cdf0e10cSrcweir     {
560cdf0e10cSrcweir         if (perm->implies( demanded ))
561cdf0e10cSrcweir             return true;
562cdf0e10cSrcweir     }
563cdf0e10cSrcweir     return false;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir #ifdef __DIAGNOSE
567cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
demanded_diag(Permission const & perm)568cdf0e10cSrcweir static void demanded_diag(
569cdf0e10cSrcweir     Permission const & perm )
570cdf0e10cSrcweir     SAL_THROW( () )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir     OUStringBuffer buf( 48 );
573cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("demanding ") );
574cdf0e10cSrcweir     buf.append( perm.toString() );
575cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" => ok.") );
576cdf0e10cSrcweir     ::rtl::OString str(
577cdf0e10cSrcweir         ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
578cdf0e10cSrcweir     OSL_TRACE( str.getStr() );
579cdf0e10cSrcweir }
580cdf0e10cSrcweir #endif
581cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
throwAccessControlException(Permission const & perm,Any const & demanded_perm)582cdf0e10cSrcweir static void throwAccessControlException(
583cdf0e10cSrcweir     Permission const & perm, Any const & demanded_perm )
584cdf0e10cSrcweir     SAL_THROW( (security::AccessControlException) )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir     OUStringBuffer buf( 48 );
587cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("access denied: ") );
588cdf0e10cSrcweir     buf.append( perm.toString() );
589cdf0e10cSrcweir     throw security::AccessControlException(
590cdf0e10cSrcweir         buf.makeStringAndClear(), Reference< XInterface >(), demanded_perm );
591cdf0e10cSrcweir }
592cdf0e10cSrcweir //==================================================================================================
checkPermission(Any const & perm) const593cdf0e10cSrcweir void PermissionCollection::checkPermission( Any const & perm ) const
594cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir     Type const & demanded_type = perm.getValueType();
597cdf0e10cSrcweir 
598cdf0e10cSrcweir     // supported permission types
599cdf0e10cSrcweir     // stack object of SimpleReferenceObject are ok, as long as they are not
600cdf0e10cSrcweir     // assigned to a ::rtl::Reference<> (=> delete this)
601cdf0e10cSrcweir     if (demanded_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
602cdf0e10cSrcweir     {
603cdf0e10cSrcweir         FilePermission demanded(
604cdf0e10cSrcweir             *reinterpret_cast< io::FilePermission const * >( perm.pData ) );
605cdf0e10cSrcweir         if (__implies( m_head, demanded ))
606cdf0e10cSrcweir         {
607cdf0e10cSrcweir #ifdef __DIAGNOSE
608cdf0e10cSrcweir             demanded_diag( demanded );
609cdf0e10cSrcweir #endif
610cdf0e10cSrcweir             return;
611cdf0e10cSrcweir         }
612cdf0e10cSrcweir         throwAccessControlException( demanded, perm );
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir     else if (demanded_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
615cdf0e10cSrcweir     {
616cdf0e10cSrcweir         SocketPermission demanded(
617cdf0e10cSrcweir             *reinterpret_cast< connection::SocketPermission const * >( perm.pData ) );
618cdf0e10cSrcweir         if (__implies( m_head, demanded ))
619cdf0e10cSrcweir         {
620cdf0e10cSrcweir #ifdef __DIAGNOSE
621cdf0e10cSrcweir             demanded_diag( demanded );
622cdf0e10cSrcweir #endif
623cdf0e10cSrcweir             return;
624cdf0e10cSrcweir         }
625cdf0e10cSrcweir         throwAccessControlException( demanded, perm );
626cdf0e10cSrcweir     }
627cdf0e10cSrcweir     else if (demanded_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
628cdf0e10cSrcweir     {
629cdf0e10cSrcweir         RuntimePermission demanded(
630cdf0e10cSrcweir             *reinterpret_cast< security::RuntimePermission const * >( perm.pData ) );
631cdf0e10cSrcweir         if (__implies( m_head, demanded ))
632cdf0e10cSrcweir         {
633cdf0e10cSrcweir #ifdef __DIAGNOSE
634cdf0e10cSrcweir             demanded_diag( demanded );
635cdf0e10cSrcweir #endif
636cdf0e10cSrcweir             return;
637cdf0e10cSrcweir         }
638cdf0e10cSrcweir         throwAccessControlException( demanded, perm );
639cdf0e10cSrcweir     }
640cdf0e10cSrcweir     else if (demanded_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
641cdf0e10cSrcweir     {
642cdf0e10cSrcweir         AllPermission demanded;
643cdf0e10cSrcweir         if (__implies( m_head, demanded ))
644cdf0e10cSrcweir         {
645cdf0e10cSrcweir #ifdef __DIAGNOSE
646cdf0e10cSrcweir             demanded_diag( demanded );
647cdf0e10cSrcweir #endif
648cdf0e10cSrcweir             return;
649cdf0e10cSrcweir         }
650cdf0e10cSrcweir         throwAccessControlException( demanded, perm );
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir     else
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         OUStringBuffer buf( 48 );
655cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("checking for unsupported permission type: ") );
656cdf0e10cSrcweir         buf.append( demanded_type.getTypeName() );
657cdf0e10cSrcweir         throw RuntimeException(
658cdf0e10cSrcweir             buf.makeStringAndClear(), Reference< XInterface >() );
659cdf0e10cSrcweir     }
660cdf0e10cSrcweir }
661cdf0e10cSrcweir 
662cdf0e10cSrcweir }
663