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 10cdf0e10cSrcweir * 11*647a425cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 184cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 210cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 252cdf0e10cSrcweir 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 //-------------------------------------------------------------------------------------------------- 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 370cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 429cdf0e10cSrcweir 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: 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 //__________________________________________________________________________________________________ 461cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 472cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 485cdf0e10cSrcweir bool AllPermission::implies( Permission const & ) const SAL_THROW( () ) 486cdf0e10cSrcweir { 487cdf0e10cSrcweir return true; 488cdf0e10cSrcweir } 489cdf0e10cSrcweir //__________________________________________________________________________________________________ 490cdf0e10cSrcweir OUString AllPermission::toString() const SAL_THROW( () ) 491cdf0e10cSrcweir { 492cdf0e10cSrcweir return OUSTR("com.sun.star.security.AllPermission"); 493cdf0e10cSrcweir } 494cdf0e10cSrcweir 495cdf0e10cSrcweir //################################################################################################## 496cdf0e10cSrcweir 497cdf0e10cSrcweir //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 542cdf0e10cSrcweir 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 //__________________________________________________________________________________________________ 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 //-------------------------------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------------------------------- 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 //================================================================================================== 593cdf0e10cSrcweir 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