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