1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "cppuhelper/factory.hxx"
31 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
32 #include "com/sun/star/task/NoMasterException.hpp"
33 #include "com/sun/star/task/XInteractionHandler.hpp"
34 #include "com/sun/star/task/XMasterPasswordHandling.hpp"
35 #include "com/sun/star/task/XPasswordContainer.hpp"
36 #include "com/sun/star/task/XUrlContainer.hpp"
37 #include "com/sun/star/ucb/AuthenticationRequest.hpp"
38 #include "com/sun/star/ucb/URLAuthenticationRequest.hpp"
39 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
40 #include "com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp"
42 #include "passwordcontainer.hxx"
44 using namespace com::sun::star
;
48 //=========================================================================
49 bool fillContinuation(
50 bool bUseSystemCredentials
,
51 const ucb::AuthenticationRequest
& rRequest
,
52 const task::UrlRecord
& aRec
,
53 const uno::Reference
< ucb::XInteractionSupplyAuthentication
> &
54 xSupplyAuthentication
,
55 const uno::Reference
< ucb::XInteractionSupplyAuthentication2
> &
56 xSupplyAuthentication2
,
57 bool bCanUseSystemCredentials
,
58 bool bCheckForEqualPasswords
)
60 if ( bUseSystemCredentials
)
62 // "use system creds" record found.
63 // Wants client that we use it?
64 if ( xSupplyAuthentication2
.is() && bCanUseSystemCredentials
)
66 xSupplyAuthentication2
->setUseSystemCredentials( sal_True
);
71 else if (aRec
.UserList
.getLength() != 0)
73 if (aRec
.UserList
[0].Passwords
.getLength() == 0)
75 // Password sequence can be empty, for instance if master
76 // password was not given (e.g. master pw dialog canceled)
77 // pw container does not throw NoMasterException in this case.
82 // "user/pass" record found.
83 if (!bCheckForEqualPasswords
|| !rRequest
.HasPassword
84 || rRequest
.Password
!= aRec
.UserList
[0].Passwords
[0]) // failed login attempt?
86 if (xSupplyAuthentication
->canSetUserName())
87 xSupplyAuthentication
->
88 setUserName(aRec
.UserList
[0].UserName
.getStr());
90 if (xSupplyAuthentication
->canSetPassword())
91 xSupplyAuthentication
->
92 setPassword(aRec
.UserList
[0].Passwords
[0].getStr());
93 if (aRec
.UserList
[0].Passwords
.getLength() > 1)
95 if (rRequest
.HasRealm
)
97 if (xSupplyAuthentication
->canSetRealm())
98 xSupplyAuthentication
->
99 setRealm(aRec
.UserList
[0].Passwords
[1].
102 else if (xSupplyAuthentication
->canSetAccount())
103 xSupplyAuthentication
->
104 setAccount(aRec
.UserList
[0].Passwords
[1].
108 if ( xSupplyAuthentication2
.is() && bCanUseSystemCredentials
)
109 xSupplyAuthentication2
->setUseSystemCredentials( sal_False
);
121 //=========================================================================
122 PasswordContainerHelper::PasswordContainerHelper(
123 uno::Reference
< lang::XMultiServiceFactory
> const & xServiceFactory
)
125 OSL_ENSURE(xServiceFactory
.is(), "no service factory given!");
126 if (xServiceFactory
.is())
130 = uno::Reference
< task::XPasswordContainer
>(
134 RTL_CONSTASCII_USTRINGPARAM(
135 "com.sun.star.task.PasswordContainer"))),
138 catch (uno::Exception
const &)
140 OSL_ENSURE(m_xPasswordContainer
.is(),
141 "unable to instanciate password container service");
144 //=========================================================================
145 bool PasswordContainerHelper::handleAuthenticationRequest(
146 ucb::AuthenticationRequest
const & rRequest
,
147 uno::Reference
< ucb::XInteractionSupplyAuthentication
> const &
148 xSupplyAuthentication
,
149 rtl::OUString
const & rURL
,
150 uno::Reference
< task::XInteractionHandler
> const & xIH
)
151 SAL_THROW((uno::RuntimeException
))
153 // Is continuation even a XInteractionSupplyAuthentication2, which
154 // is derived from XInteractionSupplyAuthentication?
155 uno::Reference
< ucb::XInteractionSupplyAuthentication2
>
156 xSupplyAuthentication2(xSupplyAuthentication
, uno::UNO_QUERY
);
158 sal_Bool bCanUseSystemCredentials
= sal_False
;
159 if (xSupplyAuthentication2
.is())
161 sal_Bool bDefaultUseSystemCredentials
;
162 bCanUseSystemCredentials
163 = xSupplyAuthentication2
->canUseSystemCredentials(
164 bDefaultUseSystemCredentials
);
167 uno::Reference
< task::XPasswordContainer
> xContainer(
168 m_xPasswordContainer
);
169 uno::Reference
< task::XUrlContainer
> xUrlContainer(
170 m_xPasswordContainer
, uno::UNO_QUERY
);
171 OSL_ENSURE( xUrlContainer
.is(), "Got no XUrlContainer!" );
173 if ( !xContainer
.is() || !xUrlContainer
.is() )
176 if ( bCanUseSystemCredentials
)
178 // Runtime / Persistent info avail for current auth request?
180 rtl::OUString aResult
= xUrlContainer
->findUrl(
181 rURL
.isEmpty() ? rRequest
.ServerName
: rURL
);
182 if ( !aResult
.isEmpty() )
184 if ( fillContinuation( true,
187 xSupplyAuthentication
,
188 xSupplyAuthentication2
,
189 bCanUseSystemCredentials
,
197 // xContainer works with userName passwdSequences pairs:
198 if (rRequest
.HasUserName
&& rRequest
.HasPassword
)
202 if (rRequest
.UserName
.isEmpty())
204 task::UrlRecord aRec
;
205 if ( !rURL
.isEmpty() )
206 aRec
= xContainer
->find(rURL
, xIH
);
208 if ( aRec
.UserList
.getLength() == 0 )
210 // compat: try server name.
211 aRec
= xContainer
->find(rRequest
.ServerName
, xIH
);
214 if ( fillContinuation( false,
217 xSupplyAuthentication
,
218 xSupplyAuthentication2
,
219 bCanUseSystemCredentials
,
227 task::UrlRecord aRec
;
228 if ( !rURL
.isEmpty() )
229 aRec
= xContainer
->findForName(
230 rURL
, rRequest
.UserName
, xIH
);
232 if ( aRec
.UserList
.getLength() == 0 )
234 // compat: try server name.
235 aRec
= xContainer
->findForName(
236 rRequest
.ServerName
, rRequest
.UserName
, xIH
);
239 if ( fillContinuation( false,
242 xSupplyAuthentication
,
243 xSupplyAuthentication2
,
244 bCanUseSystemCredentials
,
251 catch (task::NoMasterException
const &)
252 {} // user did not enter master password
257 //=========================================================================
258 bool PasswordContainerHelper::addRecord(
259 rtl::OUString
const & rURL
,
260 rtl::OUString
const & rUsername
,
261 uno::Sequence
< rtl::OUString
> const & rPasswords
,
262 uno::Reference
< task::XInteractionHandler
> const & xIH
,
264 SAL_THROW((uno::RuntimeException
))
268 if ( !rUsername
.isEmpty() )
270 OSL_ENSURE( m_xPasswordContainer
.is(),
271 "Got no XPasswordContainer!" );
272 if ( !m_xPasswordContainer
.is() )
277 uno::Reference
< task::XMasterPasswordHandling
> xMPH(
278 m_xPasswordContainer
, uno::UNO_QUERY_THROW
);
280 // If persistent storing of passwords is not yet
281 // allowed, enable it.
282 if ( !xMPH
->isPersistentStoringAllowed() )
283 xMPH
->allowPersistentStoring( sal_True
);
285 m_xPasswordContainer
->addPersistent( rURL
,
291 m_xPasswordContainer
->add( rURL
,
298 uno::Reference
< task::XUrlContainer
>
299 xContainer( m_xPasswordContainer
, uno::UNO_QUERY
);
300 OSL_ENSURE( xContainer
.is(), "Got no XUrlContainer!" );
301 if ( !xContainer
.is() )
304 xContainer
->addUrl( rURL
, bPersist
);
307 catch ( task::NoMasterException
const & )
309 // user did not enter master password
315 //=========================================================================
316 //=========================================================================
317 //=========================================================================
319 PasswordContainerInteractionHandler::PasswordContainerInteractionHandler(
320 const uno::Reference
< lang::XMultiServiceFactory
>& xSMgr
)
321 : m_aPwContainerHelper( xSMgr
)
325 //=========================================================================
327 PasswordContainerInteractionHandler::~PasswordContainerInteractionHandler()
331 //=========================================================================
333 // XServiceInfo methods.
335 //=========================================================================
338 ::rtl::OUString SAL_CALL
339 PasswordContainerInteractionHandler::getImplementationName()
340 throw ( uno::RuntimeException
)
342 return getImplementationName_Static();
345 //=========================================================================
348 PasswordContainerInteractionHandler::supportsService(
349 const ::rtl::OUString
& ServiceName
)
350 throw ( uno::RuntimeException
)
352 uno::Sequence
< rtl::OUString
> aSNL
= getSupportedServiceNames();
353 const rtl::OUString
* pArray
= aSNL
.getConstArray();
354 for ( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
356 if ( pArray
[ i
] == ServiceName
)
362 //=========================================================================
364 uno::Sequence
< ::rtl::OUString
> SAL_CALL
365 PasswordContainerInteractionHandler::getSupportedServiceNames()
366 throw ( uno::RuntimeException
)
368 return getSupportedServiceNames_Static();
371 //=========================================================================
374 PasswordContainerInteractionHandler::getImplementationName_Static()
376 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
377 "com.sun.star.comp.uui.PasswordContainerInteractionHandler" ) );
380 //=========================================================================
382 uno::Sequence
< rtl::OUString
>
383 PasswordContainerInteractionHandler::getSupportedServiceNames_Static()
385 uno::Sequence
< rtl::OUString
> aSNS( 1 );
387 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
388 "com.sun.star.task.PasswordContainerInteractionHandler" ) );
392 //=========================================================================
394 // XInteractionHandler methods.
396 //=========================================================================
400 PasswordContainerInteractionHandler::handle(
401 const uno::Reference
< task::XInteractionRequest
>& rRequest
)
402 throw ( uno::RuntimeException
)
404 if ( !rRequest
.is() )
407 uno::Any
aAnyRequest( rRequest
->getRequest() );
409 ucb::AuthenticationRequest aAuthenticationRequest
;
410 if ( !( aAnyRequest
>>= aAuthenticationRequest
) )
414 ucb::URLAuthenticationRequest aURLAuthenticationRequest
;
415 if ( aAnyRequest
>>= aURLAuthenticationRequest
)
416 aURL
= aURLAuthenticationRequest
.URL
;
418 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> >
419 rContinuations
= rRequest
->getContinuations();
421 uno::Reference
< ucb::XInteractionSupplyAuthentication
>
422 xSupplyAuthentication
;
424 for ( sal_Int32 i
= 0; i
< rContinuations
.getLength(); ++i
)
426 xSupplyAuthentication
427 = uno::Reference
< ucb::XInteractionSupplyAuthentication
>(
428 rContinuations
[i
], uno::UNO_QUERY
);
429 if( xSupplyAuthentication
.is() )
433 if ( !xSupplyAuthentication
.is() )
436 // Try to obtain credentials from password container.
437 if ( m_aPwContainerHelper
.
438 handleAuthenticationRequest( aAuthenticationRequest
,
439 xSupplyAuthentication
,
441 // @@@ FIXME: this not able to
442 // handle master pw request!
443 // master pw request is never
444 // solvable without UI!
447 // successfully handled
448 xSupplyAuthentication
->select();
452 //=========================================================================
454 // Service factory implementation.
456 //=========================================================================
458 static uno::Reference
< uno::XInterface
> SAL_CALL
459 PasswordContainerInteractionHandler_CreateInstance(
460 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
461 throw( uno::Exception
)
463 lang::XServiceInfo
* pX
= static_cast< lang::XServiceInfo
* >(
464 new PasswordContainerInteractionHandler( rSMgr
) );
465 return uno::Reference
< uno::XInterface
>::query( pX
);
468 //=========================================================================
470 uno::Reference
< lang::XSingleServiceFactory
>
471 PasswordContainerInteractionHandler::createServiceFactory(
472 const uno::Reference
< lang::XMultiServiceFactory
>& rxServiceMgr
)
474 return uno::Reference
< lang::XSingleServiceFactory
>(
475 cppu::createOneInstanceFactory(
477 PasswordContainerInteractionHandler::getImplementationName_Static(),
478 PasswordContainerInteractionHandler_CreateInstance
,
479 PasswordContainerInteractionHandler::getSupportedServiceNames_Static() ) );
484 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */