Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / stoc / test / security / test_security.cxx
bloba094b21e2402144d85e98394a9be1c726eb16108
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <stdio.h>
23 #include <sal/main.h>
24 #include <osl/diagnose.h>
25 #include <osl/socket.hxx>
26 #include <rtl/string.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <uno/current_context.hxx>
30 #include <cppuhelper/implbase1.hxx>
31 #include <cppuhelper/bootstrap.hxx>
32 #include <cppuhelper/access_control.hxx>
34 #include <com/sun/star/lang/XComponent.hpp>
35 #include <com/sun/star/uno/XCurrentContext.hpp>
37 #include <com/sun/star/io/FilePermission.hpp>
39 #define USER_CREDS "access-control.user-credentials"
40 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
43 using namespace ::osl;
44 using namespace ::rtl;
45 using namespace ::cppu;
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
49 //--------------------------------------------------------------------------------------------------
50 static OUString localhost( OUString const & addition ) SAL_THROW(())
52 static OUString ip;
53 if (! ip.getLength())
55 // dns lookup
56 SocketAddr addr;
57 SocketAddr::resolveHostname( OUSTR("localhost"), addr );
58 ::oslSocketResult rc = ::osl_getDottedInetAddrOfSocketAddr( addr.getHandle(), &ip.pData );
59 if (::osl_Socket_Ok != rc)
60 fprintf(stdout, "### cannot resolve localhost!" );
62 OUStringBuffer buf( 48 );
63 buf.append( ip );
64 buf.append( addition );
65 return buf.makeStringAndClear();
68 //--------------------------------------------------------------------------------------------------
69 static inline void dispose( Reference< XInterface > const & x )
70 SAL_THROW( (RuntimeException) )
72 Reference< lang::XComponent > xComp( x, UNO_QUERY );
73 if (xComp.is())
75 xComp->dispose();
78 //==================================================================================================
79 class user_CurrentContext
80 : public ImplHelper1< XCurrentContext >
82 oslInterlockedCount m_refcount;
84 Reference< XCurrentContext > m_xDelegate;
85 Any m_userId;
87 public:
88 inline user_CurrentContext(
89 Reference< XCurrentContext > const & xDelegate,
90 OUString const & userId )
91 SAL_THROW(())
92 : m_refcount( 0 )
93 , m_xDelegate( xDelegate )
94 , m_userId( makeAny( userId ) )
97 // XInterface impl
98 virtual void SAL_CALL acquire()
99 throw ();
100 virtual void SAL_CALL release()
101 throw ();
103 // XCurrentContext impl
104 virtual Any SAL_CALL getValueByName( OUString const & name )
105 throw (RuntimeException);
107 //__________________________________________________________________________________________________
108 void user_CurrentContext::acquire()
109 throw ()
111 ::osl_atomic_increment( &m_refcount );
113 //__________________________________________________________________________________________________
114 void user_CurrentContext::release()
115 throw ()
117 if (! ::osl_atomic_decrement( &m_refcount ))
119 delete this;
122 //__________________________________________________________________________________________________
123 Any user_CurrentContext::getValueByName( OUString const & name )
124 throw (RuntimeException)
126 if ( name == USER_CREDS ".id" )
128 return m_userId;
130 else if (m_xDelegate.is())
132 return m_xDelegate->getValueByName( name );
134 else
136 return Any();
140 // prepends line number
141 #define CHECK( check, negative_test ) \
143 try \
145 if (negative_test) \
147 bool thrown = true; \
148 try \
150 check; \
151 thrown = false; \
153 catch (RuntimeException &) \
156 if (! thrown) \
158 throw RuntimeException( \
159 OUSTR("expected RuntimeException upon check!"), Reference< XInterface >() ); \
162 else \
164 check; \
167 catch (const RuntimeException & exc) \
169 OUStringBuffer buf( 64 ); \
170 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[line ") ); \
171 buf.append( (sal_Int32)__LINE__ ); \
172 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); \
173 buf.append( exc.Message ); \
174 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() ); \
179 grant
181 permission com.sun.star.io.FilePermission "file:///usr/bin/ *", "read";
182 permission com.sun.star.io.FilePermission "file:///tmp/-", "read,write";
183 permission com.sun.star.io.FilePermission "file:///etc/profile", "read";
185 permission com.sun.star.security.RuntimePermission "DEF";
187 permission com.sun.star.connection.SocketPermission "127.0.0.1:-1023", "resolve, connect, listen";
188 permission com.sun.star.connection.SocketPermission "localhost:1024-", "accept, connect, listen, resolve,";
189 permission com.sun.star.connection.SocketPermission "*.sun.com:1024-", "resolve";
192 static void check_defaults_pos( AccessControl & ac, bool invert = false )
194 // positive tests
195 CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("read") ), invert );
196 CHECK( ac.checkFilePermission( OUSTR("file:///tmp/bla"), OUSTR("read,write") ), invert );
197 CHECK( ac.checkFilePermission( OUSTR("file:///tmp/path/path/bla"), OUSTR("write") ), invert );
198 CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("read") ), invert );
199 CHECK( ac.checkRuntimePermission( OUSTR("DEF") ), invert );
200 CHECK( ac.checkSocketPermission( OUSTR("localhost:1024"), OUSTR("connect") ), invert );
201 CHECK( ac.checkSocketPermission( OUSTR("localhost:65535"), OUSTR("resolve") ), invert );
202 CHECK( ac.checkSocketPermission( localhost(OUSTR(":2048")), OUSTR("accept,listen") ), invert );
203 CHECK( ac.checkSocketPermission( localhost(OUSTR(":1024-")), OUSTR("accept,connect,listen,resolve") ), invert );
204 CHECK( ac.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("resolve,listen,connect") ), invert );
205 CHECK( ac.checkSocketPermission( OUSTR("jl-1036.germany.sun.com:1024-"), OUSTR("resolve") ), invert );
207 static void check_defaults_neg( AccessControl & ac, bool invert = false )
209 // negative tests
210 CHECK( ac.checkFilePermission( OUSTR("file:///usr/tmp"), OUSTR("read") ), !invert );
211 CHECK( ac.checkFilePermission( OUSTR("file:///"), OUSTR("read") ), !invert );
212 CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin"), OUSTR("read") ), !invert );
213 CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("write") ), !invert );
214 CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("execute") ), !invert );
215 CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/path/bla"), OUSTR("read") ), !invert );
216 CHECK( ac.checkFilePermission( OUSTR("file:///tmp"), OUSTR("read") ), !invert );
217 CHECK( ac.checkFilePermission( OUSTR("file:///tmp/"), OUSTR("read") ), !invert );
218 CHECK( ac.checkFilePermission( OUSTR("file:///tm"), OUSTR("read") ), !invert );
219 CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("write") ), !invert );
220 CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile/bla"), OUSTR("read") ), !invert );
221 CHECK( ac.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), !invert );
222 CHECK( ac.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), !invert );
223 CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), !invert );
224 CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("delete") ), !invert );
225 CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUString() ), !invert );
226 CHECK( ac.checkRuntimePermission( OUSTR("ROOT") ), !invert );
227 CHECK( ac.checkSocketPermission( OUSTR("localhost:1023"), OUSTR("accept") ), !invert );
228 CHECK( ac.checkSocketPermission( OUSTR("localhost:123-"), OUSTR("accept") ), !invert );
229 CHECK( ac.checkSocketPermission( localhost(OUSTR(":-1023")), OUSTR("accept") ), !invert );
230 CHECK( ac.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("accept,resolve") ), !invert );
231 CHECK( ac.checkSocketPermission( OUSTR("sun.com:1024-"), OUSTR("resolve") ), !invert );
235 grant user "dbo"
237 permission com.sun.star.io.FilePermission "file:///home/dbo/-", "read,write";
238 permission com.sun.star.io.FilePermission "-", "read,write";
239 permission com.sun.star.io.FilePermission "file:///usr/local/dbo/ *", "read";
241 permission com.sun.star.security.RuntimePermission "DBO";
243 permission com.sun.star.connection.SocketPermission "dbo-1:1024-", "listen";
244 permission com.sun.star.connection.SocketPermission "dbo-11081:-1023", "resolve";
245 permission com.sun.star.connection.SocketPermission "dbo-11081:18", "listen";
246 permission com.sun.star.connection.SocketPermission "dbo-11081:20-24", "listen";
247 permission com.sun.star.connection.SocketPermission "dbo-11081", "connect";
250 static void check_dbo_pos( AccessControl & ac, bool invert = false )
252 check_defaults_pos( ac, invert );
253 // positive tests
254 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), invert );
255 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), invert );
256 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), invert );
257 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read,write") ), invert );
258 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,write") ), invert );
259 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/*"), OUSTR("read") ), invert );
260 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), invert );
261 CHECK( ac.checkRuntimePermission( OUSTR("DBO") ), invert );
262 CHECK( ac.checkSocketPermission( OUSTR("dbo-1:1024-"), OUSTR("listen") ), invert );
263 CHECK( ac.checkSocketPermission( OUSTR("dbo-1:2048-3122"), OUSTR("listen") ), invert );
264 CHECK( ac.checkSocketPermission( OUSTR("dbo-1:2048-"), OUSTR("listen") ), invert );
265 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:-1023"), OUSTR("resolve") ), invert );
266 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:20-1023"), OUSTR("resolve") ), invert );
267 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:18"), OUSTR("listen") ), invert );
268 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:20-24"), OUSTR("listen") ), invert );
269 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("listen") ), invert );
270 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), invert );
271 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("connect") ), invert );
273 static void check_dbo_neg( AccessControl & ac, bool invert = false )
275 check_defaults_neg( ac, invert );
276 // negative tests
277 CHECK( ac.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert );
278 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), !invert );
279 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), !invert );
280 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), !invert );
281 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read") ), !invert );
282 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,execute") ), !invert );
283 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert );
284 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/bla"), OUSTR("read") ), !invert );
285 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert );
286 CHECK( ac.checkRuntimePermission( OUSTR("JBU") ), !invert );
287 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("listen") ), !invert );
288 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("accept") ), !invert );
289 CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:22"), OUSTR("resolve") ), !invert );
293 grant user "jbu"
295 permission com.sun.star.io.FilePermission "file:///home/jbu/-", "read,write";
296 permission com.sun.star.io.FilePermission "*", "read,write";
298 permission com.sun.star.security.RuntimePermission "JBU";
300 permission com.sun.star.connection.SocketPermission "jbu-11096","resolve";
303 static void check_jbu_pos( AccessControl & ac, bool invert = false )
305 check_defaults_pos( ac, invert );
306 // positive tests
307 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), invert );
308 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), invert );
309 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), invert );
310 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read,write") ), invert );
311 CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/path/bla"), OUSTR("read,write") ), invert );
312 CHECK( ac.checkRuntimePermission( OUSTR("JBU") ), invert );
313 CHECK( ac.checkSocketPermission( OUSTR("jbu-11096"), OUSTR("resolve") ), invert );
314 CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("resolve") ), invert );
315 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com:2048"), OUSTR("resolve") ), invert );
317 static void check_jbu_neg( AccessControl & ac, bool invert = false )
319 check_defaults_neg( ac, invert );
320 // negative tests
321 CHECK( ac.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert );
322 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read") ), !invert );
323 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read") ), !invert );
324 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), !invert );
325 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), !invert );
326 CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), !invert );
327 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert );
328 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), !invert );
329 CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert );
330 CHECK( ac.checkRuntimePermission( OUSTR("DBO") ), !invert );
331 CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("accept") ), !invert );
332 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), !invert );
333 CHECK( ac.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com"), OUSTR("connect") ), !invert );
337 grant principal "root"
339 permission com.sun.star.security.AllPermission;
342 //==================================================================================================
343 static void check_root_pos( AccessControl & ac, bool invert = false )
345 check_defaults_pos( ac, invert );
346 check_defaults_neg( ac, !invert );
347 check_dbo_pos( ac, invert );
348 check_dbo_neg( ac, !invert );
349 check_jbu_pos( ac, invert );
350 check_jbu_neg( ac, !invert );
351 // some more root positive
352 CHECK( ac.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), invert );
353 CHECK( ac.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), invert );
354 CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), invert );
355 CHECK( ac.checkRuntimePermission( OUSTR("ROOT") ), invert );
358 //==================================================================================================
359 class acc_Restr
360 : public WeakImplHelper1< security::XAccessControlContext >
362 Any m_perm;
364 public:
365 inline acc_Restr( Any const & perm = Any() ) SAL_THROW(())
366 : m_perm( perm )
369 // XAccessControlContext impl
370 virtual void SAL_CALL checkPermission( Any const & perm )
371 throw (RuntimeException);
373 //__________________________________________________________________________________________________
374 void acc_Restr::checkPermission( Any const & perm )
375 throw (RuntimeException)
377 if (perm != m_perm)
379 throw security::AccessControlException(
380 OUSTR("dyn violation!"), Reference< XInterface >(), perm );
384 typedef void (* t_action)( AccessControl &, Any const & arg );
386 //==================================================================================================
387 class Action
388 : public WeakImplHelper1< security::XAction >
390 t_action m_action;
391 AccessControl & m_ac;
392 Any m_arg;
394 public:
395 inline Action( t_action action, AccessControl & ac, Any const & arg = Any() ) SAL_THROW(())
396 : m_action( action )
397 , m_ac( ac )
398 , m_arg( arg )
401 // XAction impl
402 virtual Any SAL_CALL run()
403 throw (Exception);
405 //__________________________________________________________________________________________________
406 Any Action::run()
407 throw (Exception)
409 (*m_action)( m_ac, m_arg );
410 return Any();
413 //==================================================================================================
414 // static void restr_file_permissions( AccessControl & ac )
415 // {
416 // // running in dbo's domain
417 // /* permission com.sun.star.io.FilePermission "file:///home/dbo/-", ",,read , write "; */
418 // CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write,execute") ), true );
419 // CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), false );
420 // }
421 //==================================================================================================
422 static void all_dbo_permissions( AccessControl & ac, Any const & )
424 check_dbo_pos( ac );
425 check_dbo_neg( ac );
427 //==================================================================================================
428 static void no_permissions( AccessControl & ac, Any const & arg )
430 check_dbo_pos( ac, true );
431 check_dbo_neg( ac );
432 // set privs to old dbo restr
433 Reference< security::XAccessControlContext > xContext;
434 OSL_VERIFY( arg >>= xContext );
435 ac->doPrivileged(
436 new Action( all_dbo_permissions, ac ),
437 xContext );
439 //==================================================================================================
440 static void check_dbo_dynamic( AccessControl & ac )
442 Any arg( makeAny( ac->getContext() ) );
443 ac->doRestricted(
444 new Action( no_permissions, ac, arg ),
445 new acc_Restr() );
448 SAL_IMPLEMENT_MAIN()
452 // single-user test
453 Reference< XComponentContext > xContext( defaultBootstrap_InitialComponentContext(
454 OUSTR("../../test/security/test_security_singleuser.ini") ) );
456 ::fprintf( stderr, "[security test] single-user checking dbo..." );
457 AccessControl ac( xContext );
458 check_dbo_pos( ac );
459 check_dbo_neg( ac );
460 check_dbo_dynamic( ac );
461 ::fprintf( stderr, "dbo checked.\n" );
464 // multi-user test
465 dispose( xContext );
466 xContext = defaultBootstrap_InitialComponentContext(
467 OUSTR("../../test/security/test_security.ini") ); // UNO_AC=on
468 AccessControl ac( xContext );
471 // set up dbo current context
472 ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("dbo") ) );
473 ::fprintf( stderr, "[security test] multi-user checking dbo..." );
474 check_dbo_pos( ac );
475 check_dbo_neg( ac );
476 check_dbo_dynamic( ac );
477 ::fprintf( stderr, "dbo checked.\n" );
480 // set up jbu current context
481 ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("jbu") ) );
482 ::fprintf( stderr, "[security test] multi-user checking jbu..." );
483 check_jbu_pos( ac );
484 check_jbu_neg( ac );
485 ::fprintf( stderr, "jbu checked.\n" );
488 // set up root current context
489 ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("root") ) );
490 ::fprintf( stderr, "[security test] multi-user checking root..." );
491 check_root_pos( ac );
492 ::fprintf( stderr, "root checked.\n" );
495 // set up unknown guest user current context => default permissions
496 ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("guest") ) );
497 ::fprintf( stderr, "[security test] multi-user checking guest..." );
498 check_defaults_pos( ac );
499 check_defaults_neg( ac );
500 ::fprintf( stderr, "guest checked.\n" );
503 dispose( xContext );
504 ::fprintf( stderr, "security test succeeded.\n" );
505 return 0;
507 catch (const Exception & exc)
509 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
510 ::fprintf( stderr, "[security test] error: %s!\n", str.getStr() );
511 return 1;
515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */