Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include "cppuhelper/factory.hxx"
21 : :
22 : : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
23 : : #include "com/sun/star/task/NoMasterException.hpp"
24 : : #include "com/sun/star/task/XInteractionHandler.hpp"
25 : : #include "com/sun/star/task/XMasterPasswordHandling.hpp"
26 : : #include "com/sun/star/task/XPasswordContainer.hpp"
27 : : #include "com/sun/star/task/XUrlContainer.hpp"
28 : : #include "com/sun/star/ucb/AuthenticationRequest.hpp"
29 : : #include "com/sun/star/ucb/URLAuthenticationRequest.hpp"
30 : : #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
31 : : #include "com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp"
32 : :
33 : : #include "passwordcontainer.hxx"
34 : :
35 : : using namespace com::sun::star;
36 : :
37 : : namespace {
38 : :
39 : : //=========================================================================
40 : 0 : bool fillContinuation(
41 : : bool bUseSystemCredentials,
42 : : const ucb::AuthenticationRequest & rRequest,
43 : : const task::UrlRecord & aRec,
44 : : const uno::Reference< ucb::XInteractionSupplyAuthentication > &
45 : : xSupplyAuthentication,
46 : : const uno::Reference< ucb::XInteractionSupplyAuthentication2 > &
47 : : xSupplyAuthentication2,
48 : : bool bCanUseSystemCredentials,
49 : : bool bCheckForEqualPasswords )
50 : : {
51 [ # # ]: 0 : if ( bUseSystemCredentials )
52 : : {
53 : : // "use system creds" record found.
54 : : // Wants client that we use it?
55 [ # # ][ # # ]: 0 : if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
[ # # ]
56 : : {
57 : 0 : xSupplyAuthentication2->setUseSystemCredentials( sal_True );
58 : 0 : return true;
59 : : }
60 : 0 : return false;
61 : : }
62 [ # # ]: 0 : else if (aRec.UserList.getLength() != 0)
63 : : {
64 [ # # ]: 0 : if (aRec.UserList[0].Passwords.getLength() == 0)
65 : : {
66 : : // Password sequence can be empty, for instance if master
67 : : // password was not given (e.g. master pw dialog canceled)
68 : : // pw container does not throw NoMasterException in this case.
69 : : // bug???
70 : 0 : return false;
71 : : }
72 : :
73 : : // "user/pass" record found.
74 [ # # ]: 0 : if (!bCheckForEqualPasswords || !rRequest.HasPassword
[ # # # # ]
[ # # ]
75 : 0 : || rRequest.Password != aRec.UserList[0].Passwords[0]) // failed login attempt?
76 : : {
77 [ # # ]: 0 : if (xSupplyAuthentication->canSetUserName())
78 : 0 : xSupplyAuthentication->
79 [ # # ]: 0 : setUserName(aRec.UserList[0].UserName.getStr());
80 : :
81 [ # # ]: 0 : if (xSupplyAuthentication->canSetPassword())
82 : 0 : xSupplyAuthentication->
83 [ # # ]: 0 : setPassword(aRec.UserList[0].Passwords[0].getStr());
84 [ # # ]: 0 : if (aRec.UserList[0].Passwords.getLength() > 1)
85 : : {
86 [ # # ]: 0 : if (rRequest.HasRealm)
87 : : {
88 [ # # ]: 0 : if (xSupplyAuthentication->canSetRealm())
89 : 0 : xSupplyAuthentication->
90 : 0 : setRealm(aRec.UserList[0].Passwords[1].
91 [ # # ]: 0 : getStr());
92 : : }
93 [ # # ]: 0 : else if (xSupplyAuthentication->canSetAccount())
94 : 0 : xSupplyAuthentication->
95 : 0 : setAccount(aRec.UserList[0].Passwords[1].
96 [ # # ]: 0 : getStr());
97 : : }
98 : :
99 [ # # ][ # # ]: 0 : if ( xSupplyAuthentication2.is() && bCanUseSystemCredentials )
[ # # ]
100 : 0 : xSupplyAuthentication2->setUseSystemCredentials( sal_False );
101 : :
102 : 0 : return true;
103 : : }
104 : : }
105 : 0 : return false;
106 : : }
107 : :
108 : : } // namespace
109 : :
110 : : namespace uui {
111 : :
112 : : //=========================================================================
113 : 0 : PasswordContainerHelper::PasswordContainerHelper(
114 : 0 : uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory )
115 : : {
116 : : OSL_ENSURE(xServiceFactory.is(), "no service factory given!");
117 [ # # ]: 0 : if (xServiceFactory.is())
118 : : try
119 : : {
120 : : m_xPasswordContainer
121 : : = uno::Reference< task::XPasswordContainer >(
122 [ # # ]: 0 : xServiceFactory->
123 : : createInstance(
124 : : rtl::OUString(
125 : : RTL_CONSTASCII_USTRINGPARAM(
126 : 0 : "com.sun.star.task.PasswordContainer"))),
127 [ # # ][ # # ]: 0 : uno::UNO_QUERY);
[ # # ][ # # ]
[ # # ]
128 : : }
129 [ # # ]: 0 : catch (uno::Exception const &)
130 : : {}
131 : : OSL_ENSURE(m_xPasswordContainer.is(),
132 : : "unable to instanciate password container service");
133 : 0 : }
134 : :
135 : : //=========================================================================
136 : 0 : bool PasswordContainerHelper::handleAuthenticationRequest(
137 : : ucb::AuthenticationRequest const & rRequest,
138 : : uno::Reference< ucb::XInteractionSupplyAuthentication > const &
139 : : xSupplyAuthentication,
140 : : rtl::OUString const & rURL,
141 : : uno::Reference< task::XInteractionHandler > const & xIH )
142 : : SAL_THROW((uno::RuntimeException))
143 : : {
144 : : // Is continuation even a XInteractionSupplyAuthentication2, which
145 : : // is derived from XInteractionSupplyAuthentication?
146 : : uno::Reference< ucb::XInteractionSupplyAuthentication2 >
147 [ # # ]: 0 : xSupplyAuthentication2(xSupplyAuthentication, uno::UNO_QUERY);
148 : :
149 : 0 : sal_Bool bCanUseSystemCredentials = sal_False;
150 [ # # ]: 0 : if (xSupplyAuthentication2.is())
151 : : {
152 : : sal_Bool bDefaultUseSystemCredentials;
153 : : bCanUseSystemCredentials
154 [ # # ]: 0 : = xSupplyAuthentication2->canUseSystemCredentials(
155 [ # # ]: 0 : bDefaultUseSystemCredentials );
156 : : }
157 : :
158 : : uno::Reference< task::XPasswordContainer > xContainer(
159 : 0 : m_xPasswordContainer );
160 : : uno::Reference< task::XUrlContainer > xUrlContainer(
161 [ # # ]: 0 : m_xPasswordContainer, uno::UNO_QUERY );
162 : : OSL_ENSURE( xUrlContainer.is(), "Got no XUrlContainer!" );
163 : :
164 [ # # ][ # # ]: 0 : if ( !xContainer.is() || !xUrlContainer.is() )
[ # # ]
165 : 0 : return false;
166 : :
167 [ # # ]: 0 : if ( bCanUseSystemCredentials )
168 : : {
169 : : // Runtime / Persistent info avail for current auth request?
170 : :
171 [ # # ]: 0 : rtl::OUString aResult = xUrlContainer->findUrl(
172 [ # # ][ # # ]: 0 : rURL.isEmpty() ? rRequest.ServerName : rURL );
173 [ # # ]: 0 : if ( !aResult.isEmpty() )
174 : : {
175 [ # # ][ # # ]: 0 : if ( fillContinuation( true,
176 : : rRequest,
177 : : task::UrlRecord(),
178 : : xSupplyAuthentication,
179 : : xSupplyAuthentication2,
180 : : bCanUseSystemCredentials,
181 [ # # ][ # # ]: 0 : false ) )
182 : : {
183 : 0 : return true;
184 : : }
185 [ # # ]: 0 : }
186 : : }
187 : :
188 : : // xContainer works with userName passwdSequences pairs:
189 [ # # ][ # # ]: 0 : if (rRequest.HasUserName && rRequest.HasPassword)
190 : : {
191 : : try
192 : : {
193 [ # # ]: 0 : if (rRequest.UserName.isEmpty())
194 : : {
195 [ # # ]: 0 : task::UrlRecord aRec;
196 [ # # ]: 0 : if ( !rURL.isEmpty() )
197 [ # # ][ # # ]: 0 : aRec = xContainer->find(rURL, xIH);
[ # # ][ # # ]
198 : :
199 [ # # ]: 0 : if ( aRec.UserList.getLength() == 0 )
200 : : {
201 : : // compat: try server name.
202 [ # # ][ # # ]: 0 : aRec = xContainer->find(rRequest.ServerName, xIH);
[ # # ][ # # ]
203 : : }
204 : :
205 [ # # ][ # # ]: 0 : if ( fillContinuation( false,
206 : : rRequest,
207 : : aRec,
208 : : xSupplyAuthentication,
209 : : xSupplyAuthentication2,
210 : : bCanUseSystemCredentials,
211 : 0 : false ) )
212 : : {
213 : 0 : return true;
214 [ # # ][ # # ]: 0 : }
215 : : }
216 : : else
217 : : {
218 [ # # ]: 0 : task::UrlRecord aRec;
219 [ # # ]: 0 : if ( !rURL.isEmpty() )
220 [ # # ]: 0 : aRec = xContainer->findForName(
221 [ # # ][ # # ]: 0 : rURL, rRequest.UserName, xIH);
[ # # ]
222 : :
223 [ # # ]: 0 : if ( aRec.UserList.getLength() == 0 )
224 : : {
225 : : // compat: try server name.
226 [ # # ]: 0 : aRec = xContainer->findForName(
227 [ # # ][ # # ]: 0 : rRequest.ServerName, rRequest.UserName, xIH);
[ # # ]
228 : : }
229 : :
230 [ # # ][ # # ]: 0 : if ( fillContinuation( false,
231 : : rRequest,
232 : : aRec,
233 : : xSupplyAuthentication,
234 : : xSupplyAuthentication2,
235 : : bCanUseSystemCredentials,
236 : 0 : true ) )
237 : : {
238 : 0 : return true;
239 [ # # ][ # # ]: 0 : }
[ # # ]
240 : : }
241 : : }
242 [ # # ]: 0 : catch (task::NoMasterException const &)
243 : : {} // user did not enter master password
244 : : }
245 : 0 : return false;
246 : : }
247 : :
248 : : //=========================================================================
249 : 0 : bool PasswordContainerHelper::addRecord(
250 : : rtl::OUString const & rURL,
251 : : rtl::OUString const & rUsername,
252 : : uno::Sequence< rtl::OUString > const & rPasswords,
253 : : uno::Reference< task::XInteractionHandler > const & xIH,
254 : : bool bPersist )
255 : : SAL_THROW((uno::RuntimeException))
256 : : {
257 : : try
258 : : {
259 [ # # ]: 0 : if ( !rUsername.isEmpty() )
260 : : {
261 : : OSL_ENSURE( m_xPasswordContainer.is(),
262 : : "Got no XPasswordContainer!" );
263 [ # # ]: 0 : if ( !m_xPasswordContainer.is() )
264 : 0 : return false;
265 : :
266 [ # # ]: 0 : if ( bPersist )
267 : : {
268 : : uno::Reference< task::XMasterPasswordHandling > xMPH(
269 [ # # ]: 0 : m_xPasswordContainer, uno::UNO_QUERY_THROW );
270 : :
271 : : // If persistent storing of passwords is not yet
272 : : // allowed, enable it.
273 [ # # ][ # # ]: 0 : if ( !xMPH->isPersistentStoringAllowed() )
[ # # ]
274 [ # # ][ # # ]: 0 : xMPH->allowPersistentStoring( sal_True );
275 : :
276 [ # # ]: 0 : m_xPasswordContainer->addPersistent( rURL,
277 : : rUsername,
278 : : rPasswords,
279 [ # # ]: 0 : xIH );
280 : : }
281 : : else
282 [ # # ]: 0 : m_xPasswordContainer->add( rURL,
283 : : rUsername,
284 : : rPasswords,
285 [ # # ]: 0 : xIH );
286 : : }
287 : : else
288 : : {
289 : : uno::Reference< task::XUrlContainer >
290 [ # # ]: 0 : xContainer( m_xPasswordContainer, uno::UNO_QUERY );
291 : : OSL_ENSURE( xContainer.is(), "Got no XUrlContainer!" );
292 [ # # ]: 0 : if ( !xContainer.is() )
293 : 0 : return false;
294 : :
295 [ # # ][ # # ]: 0 : xContainer->addUrl( rURL, bPersist );
[ # # ][ # # ]
296 : : }
297 : : }
298 : 0 : catch ( task::NoMasterException const & )
299 : : {
300 : : // user did not enter master password
301 : 0 : return false;
302 : : }
303 : 0 : return true;
304 : : }
305 : :
306 : : //=========================================================================
307 : : //=========================================================================
308 : : //=========================================================================
309 : :
310 : 0 : PasswordContainerInteractionHandler::PasswordContainerInteractionHandler(
311 : : const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
312 [ # # ]: 0 : : m_aPwContainerHelper( xSMgr )
313 : : {
314 : 0 : }
315 : :
316 : : //=========================================================================
317 : : // virtual
318 [ # # ]: 0 : PasswordContainerInteractionHandler::~PasswordContainerInteractionHandler()
319 : : {
320 [ # # ]: 0 : }
321 : :
322 : : //=========================================================================
323 : : //
324 : : // XServiceInfo methods.
325 : : //
326 : : //=========================================================================
327 : :
328 : : // virtual
329 : : ::rtl::OUString SAL_CALL
330 : 0 : PasswordContainerInteractionHandler::getImplementationName()
331 : : throw ( uno::RuntimeException )
332 : : {
333 : 0 : return getImplementationName_Static();
334 : : }
335 : :
336 : : //=========================================================================
337 : : // virtual
338 : : sal_Bool SAL_CALL
339 : 0 : PasswordContainerInteractionHandler::supportsService(
340 : : const ::rtl::OUString& ServiceName )
341 : : throw ( uno::RuntimeException )
342 : : {
343 [ # # ]: 0 : uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
344 : 0 : const rtl::OUString * pArray = aSNL.getConstArray();
345 [ # # ]: 0 : for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
346 : : {
347 [ # # ]: 0 : if ( pArray[ i ] == ServiceName )
348 : 0 : return sal_True;
349 : : }
350 [ # # ]: 0 : return sal_False;
351 : : }
352 : :
353 : : //=========================================================================
354 : : // virtual
355 : : uno::Sequence< ::rtl::OUString > SAL_CALL
356 : 0 : PasswordContainerInteractionHandler::getSupportedServiceNames()
357 : : throw ( uno::RuntimeException )
358 : : {
359 : 0 : return getSupportedServiceNames_Static();
360 : : }
361 : :
362 : : //=========================================================================
363 : : // static
364 : : rtl::OUString
365 : 0 : PasswordContainerInteractionHandler::getImplementationName_Static()
366 : : {
367 : : return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
368 : 0 : "com.sun.star.comp.uui.PasswordContainerInteractionHandler" ) );
369 : : }
370 : :
371 : : //=========================================================================
372 : : // static
373 : : uno::Sequence< rtl::OUString >
374 : 0 : PasswordContainerInteractionHandler::getSupportedServiceNames_Static()
375 : : {
376 : 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
377 : : aSNS.getArray()[ 0 ]
378 : : = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
379 [ # # ][ # # ]: 0 : "com.sun.star.task.PasswordContainerInteractionHandler" ) );
380 : 0 : return aSNS;
381 : : }
382 : :
383 : : //=========================================================================
384 : : //
385 : : // XInteractionHandler methods.
386 : : //
387 : : //=========================================================================
388 : :
389 : : // virtual
390 : : void SAL_CALL
391 : 0 : PasswordContainerInteractionHandler::handle(
392 : : const uno::Reference< task::XInteractionRequest >& rRequest )
393 : : throw ( uno::RuntimeException )
394 : : {
395 [ # # ]: 0 : if ( !rRequest.is() )
396 : : return;
397 : :
398 [ # # ][ # # ]: 0 : uno::Any aAnyRequest( rRequest->getRequest() );
399 : :
400 [ # # ]: 0 : ucb::AuthenticationRequest aAuthenticationRequest;
401 [ # # ][ # # ]: 0 : if ( !( aAnyRequest >>= aAuthenticationRequest ) )
402 : : return;
403 : :
404 : 0 : rtl::OUString aURL;
405 [ # # ]: 0 : ucb::URLAuthenticationRequest aURLAuthenticationRequest;
406 [ # # ][ # # ]: 0 : if ( aAnyRequest >>= aURLAuthenticationRequest )
407 : 0 : aURL = aURLAuthenticationRequest.URL;
408 : :
409 : : uno::Sequence< uno::Reference< task::XInteractionContinuation > >
410 [ # # ][ # # ]: 0 : rContinuations = rRequest->getContinuations();
411 : :
412 : : uno::Reference< ucb::XInteractionSupplyAuthentication >
413 : 0 : xSupplyAuthentication;
414 : :
415 [ # # ]: 0 : for ( sal_Int32 i = 0; i < rContinuations.getLength(); ++i )
416 : : {
417 : : xSupplyAuthentication
418 : : = uno::Reference< ucb::XInteractionSupplyAuthentication >(
419 [ # # ][ # # ]: 0 : rContinuations[i], uno::UNO_QUERY );
[ # # ]
420 [ # # ]: 0 : if( xSupplyAuthentication.is() )
421 : 0 : break;
422 : : }
423 : :
424 [ # # ]: 0 : if ( !xSupplyAuthentication.is() )
425 : : return;
426 : :
427 : : // Try to obtain credentials from password container.
428 [ # # # # ]: 0 : if ( m_aPwContainerHelper.
429 : : handleAuthenticationRequest( aAuthenticationRequest,
430 : : xSupplyAuthentication,
431 : : aURL,
432 : : // @@@ FIXME: this not able to
433 : : // handle master pw request!
434 : : // master pw request is never
435 : : // solvable without UI!
436 [ # # ]: 0 : this ) )
437 : : {
438 : : // successfully handled
439 [ # # ][ # # ]: 0 : xSupplyAuthentication->select();
440 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
441 : : }
442 : :
443 : : //=========================================================================
444 : : //
445 : : // Service factory implementation.
446 : : //
447 : : //=========================================================================
448 : :
449 : : static uno::Reference< uno::XInterface > SAL_CALL
450 : 0 : PasswordContainerInteractionHandler_CreateInstance(
451 : : const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
452 : : throw( uno::Exception )
453 : : {
454 : : lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
455 [ # # ][ # # ]: 0 : new PasswordContainerInteractionHandler( rSMgr ) );
456 : 0 : return uno::Reference< uno::XInterface >::query( pX );
457 : : }
458 : :
459 : : //=========================================================================
460 : : // static
461 : : uno::Reference< lang::XSingleServiceFactory >
462 : 0 : PasswordContainerInteractionHandler::createServiceFactory(
463 : : const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
464 : : {
465 : : return uno::Reference< lang::XSingleServiceFactory >(
466 : : cppu::createOneInstanceFactory(
467 : : rxServiceMgr,
468 : : PasswordContainerInteractionHandler::getImplementationName_Static(),
469 : : PasswordContainerInteractionHandler_CreateInstance,
470 [ # # ][ # # ]: 0 : PasswordContainerInteractionHandler::getSupportedServiceNames_Static() ) );
471 : : }
472 : :
473 : : } // namespace uui
474 : :
475 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|