1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX 28 #define INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX 29 30 #include <list> 31 #include <vector> 32 #include <map> 33 #include <com/sun/star/task/XPasswordContainer.hpp> 34 #include <com/sun/star/task/XUrlContainer.hpp> 35 #include <com/sun/star/task/PasswordRequestMode.hpp> 36 #include <com/sun/star/lang/XServiceInfo.hpp> 37 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 38 #include <com/sun/star/lang/XEventListener.hpp> 39 #include <com/sun/star/lang/XComponent.hpp> 40 #include <com/sun/star/task/XMasterPasswordHandling2.hpp> 41 #include <cppuhelper/implbase5.hxx> 42 #include <cppuhelper/typeprovider.hxx> 43 #include <cppuhelper/queryinterface.hxx> 44 #include <cppuhelper/factory.hxx> 45 46 #include <tools/stream.hxx> 47 #include <unotools/configitem.hxx> 48 #include <ucbhelper/interactionrequest.hxx> 49 50 #include <rtl/ref.hxx> 51 #include <osl/mutex.hxx> 52 53 #include "syscreds.hxx" 54 55 #define MEMORY_RECORD 0 56 #define PERSISTENT_RECORD 1 57 58 //---------------------------------------------------------------------------------- 59 60 class NamePassRecord 61 { 62 ::rtl::OUString m_aName; 63 64 // there are two lists of passwords, memory passwords and persistent passwords 65 sal_Bool m_bHasMemPass; 66 ::std::vector< ::rtl::OUString > m_aMemPass; 67 68 // persistent passwords are encrypted in one string 69 sal_Bool m_bHasPersPass; 70 ::rtl::OUString m_aPersPass; 71 72 void InitArrays( sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList, 73 sal_Bool bHasPersistentList, const ::rtl::OUString& aPersistentList ) 74 { 75 m_bHasMemPass = bHasMemoryList; 76 if ( bHasMemoryList ) 77 m_aMemPass = aMemoryList; 78 79 m_bHasPersPass = bHasPersistentList; 80 if ( bHasPersistentList ) 81 m_aPersPass = aPersistentList; 82 } 83 84 public: 85 86 NamePassRecord( const ::rtl::OUString& aName ) 87 : m_aName( aName ) 88 , m_bHasMemPass( sal_False ) 89 , m_bHasPersPass( sal_False ) 90 { 91 } 92 93 NamePassRecord( const ::rtl::OUString& aName, const ::std::vector< ::rtl::OUString >& aMemoryList ) 94 : m_aName( aName ) 95 , m_bHasMemPass( sal_True ) 96 , m_aMemPass( aMemoryList ) 97 , m_bHasPersPass( sal_False ) 98 { 99 } 100 101 NamePassRecord( const ::rtl::OUString& aName, const ::rtl::OUString& aPersistentList ) 102 : m_aName( aName ) 103 , m_bHasMemPass( sal_False ) 104 , m_bHasPersPass( sal_True ) 105 , m_aPersPass( aPersistentList ) 106 { 107 } 108 109 NamePassRecord( const ::rtl::OUString& aName, 110 sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList, 111 sal_Bool bHasPersistentList, const ::rtl::OUString aPersistentList ) 112 : m_aName( aName ) 113 , m_bHasMemPass( bHasMemoryList ) 114 , m_bHasPersPass( bHasPersistentList ) 115 { 116 InitArrays( bHasMemoryList, aMemoryList, bHasPersistentList, aPersistentList ); 117 } 118 119 NamePassRecord( const NamePassRecord& aRecord ) 120 : m_aName( aRecord.m_aName ) 121 , m_bHasMemPass( sal_False ) 122 , m_bHasPersPass( sal_False ) 123 { 124 InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass ); 125 } 126 127 NamePassRecord& operator=( const NamePassRecord& aRecord ) 128 { 129 m_aName = aRecord.m_aName; 130 131 m_aMemPass.clear(); 132 m_aPersPass = ::rtl::OUString(); 133 InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass ); 134 135 return *this; 136 } 137 138 ::rtl::OUString GetUserName() const 139 { 140 return m_aName; 141 } 142 143 sal_Bool HasPasswords( sal_Int8 nStatus ) const 144 { 145 if ( nStatus == MEMORY_RECORD ) 146 return m_bHasMemPass; 147 if ( nStatus == PERSISTENT_RECORD ) 148 return m_bHasPersPass; 149 150 return sal_False; 151 } 152 153 ::std::vector< ::rtl::OUString > GetMemPasswords() const 154 { 155 if ( m_bHasMemPass ) 156 return m_aMemPass; 157 158 return ::std::vector< ::rtl::OUString >(); 159 } 160 161 ::rtl::OUString GetPersPasswords() const 162 { 163 if ( m_bHasPersPass ) 164 return m_aPersPass; 165 166 return ::rtl::OUString(); 167 } 168 169 void SetMemPasswords( const ::std::vector< ::rtl::OUString >& aMemList ) 170 { 171 m_aMemPass = aMemList; 172 m_bHasMemPass = sal_True; 173 } 174 175 void SetPersPasswords( const ::rtl::OUString& aPersList ) 176 { 177 m_aPersPass = aPersList; 178 m_bHasPersPass = sal_True; 179 } 180 181 void RemovePasswords( sal_Int8 nStatus ) 182 { 183 if ( nStatus == MEMORY_RECORD ) 184 { 185 m_bHasMemPass = sal_False; 186 m_aMemPass.clear(); 187 } 188 else if ( nStatus == PERSISTENT_RECORD ) 189 { 190 m_bHasPersPass = sal_False; 191 m_aPersPass = ::rtl::OUString(); 192 } 193 } 194 195 }; 196 197 //---------------------------------------------------------------------------------- 198 199 typedef ::std::pair< const ::rtl::OUString, ::std::list< NamePassRecord > > PairUrlRecord; 200 typedef ::std::map< ::rtl::OUString, ::std::list< NamePassRecord > > PassMap; 201 202 //---------------------------------------------------------------------------------- 203 204 class PasswordContainer; 205 206 class StorageItem : public ::utl::ConfigItem { 207 PasswordContainer* mainCont; 208 sal_Bool hasEncoded; 209 ::rtl::OUString mEncoded; 210 public: 211 StorageItem( PasswordContainer* point, const ::rtl::OUString& path ) : 212 ConfigItem( path, CONFIG_MODE_IMMEDIATE_UPDATE ), 213 mainCont( point ), 214 hasEncoded( sal_False ) 215 { 216 ::com::sun::star::uno::Sequence< ::rtl::OUString > aNode( 1 ); 217 *aNode.getArray() = path; 218 *aNode.getArray() += ::rtl::OUString::createFromAscii( "/Store" ); 219 EnableNotification( aNode ); 220 } 221 222 PassMap getInfo(); 223 void update( const ::rtl::OUString& url, const NamePassRecord& rec ); 224 void remove( const ::rtl::OUString& url, const ::rtl::OUString& rec ); 225 void clear(); 226 227 sal_Bool getEncodedMP( ::rtl::OUString& aResult ); 228 void setEncodedMP( const ::rtl::OUString& aResult, sal_Bool bAcceptEnmpty = sal_False ); 229 void setUseStorage( sal_Bool bUse ); 230 sal_Bool useStorage(); 231 232 virtual void Notify( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ); 233 virtual void Commit(); 234 }; 235 236 //---------------------------------------------------------------------------------- 237 238 enum PasswordState { 239 no_password, 240 entered, 241 cancelled 242 }; 243 244 class PasswordContainer : public ::cppu::WeakImplHelper5< 245 ::com::sun::star::task::XPasswordContainer, 246 ::com::sun::star::task::XMasterPasswordHandling2, 247 ::com::sun::star::task::XUrlContainer, 248 ::com::sun::star::lang::XServiceInfo, 249 ::com::sun::star::lang::XEventListener > 250 { 251 private: 252 PassMap m_aContainer; 253 StorageItem* m_pStorageFile; 254 ::osl::Mutex mMutex; 255 ::rtl::OUString m_aMasterPasswd; // master password is set when the string is not empty 256 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mComponent; 257 SysCredentialsConfig mUrlContainer; 258 259 ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > CopyToUserRecordSequence( 260 const ::std::list< NamePassRecord >& original, 261 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 262 throw(::com::sun::star::uno::RuntimeException); 263 264 ::com::sun::star::task::UserRecord CopyToUserRecord( 265 const NamePassRecord& aRecord, 266 sal_Bool& io_bTryToDecode, 267 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ); 268 269 ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > FindUsr( 270 const ::std::list< NamePassRecord >& userlist, 271 const ::rtl::OUString& name, 272 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 273 throw(::com::sun::star::uno::RuntimeException); 274 bool createUrlRecord( 275 const PassMap::iterator & rIter, 276 bool bName, 277 const ::rtl::OUString & aName, 278 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler, 279 ::com::sun::star::task::UrlRecord & rRec ) 280 throw( ::com::sun::star::uno::RuntimeException ); 281 282 ::com::sun::star::task::UrlRecord find( 283 const ::rtl::OUString& aURL, 284 const ::rtl::OUString& aName, 285 bool bName, // only needed to support empty user names 286 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ) throw(::com::sun::star::uno::RuntimeException); 287 288 ::rtl::OUString GetDefaultMasterPassword(); 289 290 ::rtl::OUString RequestPasswordFromUser( 291 ::com::sun::star::task::PasswordRequestMode aRMode, 292 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ); 293 294 ::rtl::OUString GetMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 295 throw(::com::sun::star::uno::RuntimeException); 296 297 void UpdateVector( const ::rtl::OUString& url, ::std::list< NamePassRecord >& toUpdate, NamePassRecord& rec, sal_Bool writeFile ) 298 throw(::com::sun::star::uno::RuntimeException); 299 300 void PrivateAdd( const ::rtl::OUString& aUrl, 301 const ::rtl::OUString& aUserName, 302 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, 303 char aMode, 304 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 305 throw(::com::sun::star::uno::RuntimeException); 306 307 ::std::vector< ::rtl::OUString > DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPassword ) 308 throw(::com::sun::star::uno::RuntimeException); 309 310 ::rtl::OUString EncodePasswords( ::std::vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPassword ) 311 throw(::com::sun::star::uno::RuntimeException); 312 313 public: 314 PasswordContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); 315 ~PasswordContainer(); 316 317 virtual void SAL_CALL add( const ::rtl::OUString& aUrl, 318 const ::rtl::OUString& aUserName, 319 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, 320 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 321 throw(::com::sun::star::uno::RuntimeException); 322 323 virtual void SAL_CALL addPersistent( const ::rtl::OUString& aUrl, 324 const ::rtl::OUString& aUserName, 325 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, 326 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 327 throw(::com::sun::star::uno::RuntimeException); 328 329 virtual ::com::sun::star::task::UrlRecord SAL_CALL 330 find( const ::rtl::OUString& aUrl, 331 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 332 throw(::com::sun::star::uno::RuntimeException); 333 334 virtual ::com::sun::star::task::UrlRecord SAL_CALL 335 findForName( const ::rtl::OUString& aUrl, 336 const ::rtl::OUString& aUserName, 337 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) 338 throw(::com::sun::star::uno::RuntimeException); 339 340 virtual void SAL_CALL remove( const ::rtl::OUString& aUrl, 341 const ::rtl::OUString& aUserName ) 342 throw(::com::sun::star::uno::RuntimeException); 343 344 virtual void SAL_CALL removePersistent( const ::rtl::OUString& aUrl, 345 const ::rtl::OUString& aUserName ) 346 throw(::com::sun::star::uno::RuntimeException); 347 348 virtual void SAL_CALL removeAllPersistent() throw(::com::sun::star::uno::RuntimeException); 349 350 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::task::UrlRecord > SAL_CALL 351 getAllPersistent( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException); 352 353 354 // provide factory 355 static ::rtl::OUString SAL_CALL impl_getStaticImplementationName( ) throw(::com::sun::star::uno::RuntimeException); 356 static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL 357 impl_getStaticSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); 358 static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > SAL_CALL 359 impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager ) throw(::com::sun::star::uno::RuntimeException); 360 static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL 361 impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) throw( ::com::sun::star::uno::RuntimeException ); 362 363 // XServiceInfo 364 virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); 365 virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); 366 367 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL 368 getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); 369 370 // XEventListener 371 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) 372 throw(::com::sun::star::uno::RuntimeException); 373 374 // XMasterPasswordHandling 375 virtual ::sal_Bool SAL_CALL authorizateWithMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) 376 throw (::com::sun::star::uno::RuntimeException); 377 virtual ::sal_Bool SAL_CALL changeMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException); 378 virtual void SAL_CALL removeMasterPassword() throw (::com::sun::star::uno::RuntimeException); 379 virtual ::sal_Bool SAL_CALL hasMasterPassword( ) throw (::com::sun::star::uno::RuntimeException); 380 virtual ::sal_Bool SAL_CALL allowPersistentStoring( ::sal_Bool bAllow ) throw (::com::sun::star::uno::RuntimeException); 381 virtual ::sal_Bool SAL_CALL isPersistentStoringAllowed( ) throw (::com::sun::star::uno::RuntimeException); 382 383 // XMasterPasswordHandling2 384 virtual ::sal_Bool SAL_CALL useDefaultMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException); 385 virtual ::sal_Bool SAL_CALL isDefaultMasterPasswordUsed( ) throw (::com::sun::star::uno::RuntimeException); 386 387 // XUrlContainer 388 virtual void SAL_CALL addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) throw (::com::sun::star::uno::RuntimeException); 389 virtual ::rtl::OUString SAL_CALL findUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException); 390 virtual void SAL_CALL removeUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException); 391 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getUrls( ::sal_Bool OnlyPersistent ) throw (::com::sun::star::uno::RuntimeException); 392 393 void Notify(); 394 }; 395 396 //---------------------------------------------------------------------------------- 397 398 class MasterPasswordRequest_Impl : public ucbhelper::InteractionRequest 399 { 400 ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > m_xAuthSupplier; 401 402 public: 403 MasterPasswordRequest_Impl( ::com::sun::star::task::PasswordRequestMode Mode ); 404 405 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & 406 getAuthenticationSupplier() const { return m_xAuthSupplier; } 407 408 }; 409 410 //---------------------------------------------------------------------------------- 411 412 class RW_SvMemoryStream : public SvMemoryStream { 413 public: 414 RW_SvMemoryStream( void* Buf, sal_uLong Size, StreamMode eMode ): 415 SvMemoryStream( Buf, Size, eMode){} 416 417 RW_SvMemoryStream( sal_uLong InitSize=512, sal_uLong Resize=64 ): 418 SvMemoryStream( InitSize, Resize ){} 419 420 sal_uLong getActualSize(){ return nEndOfData; } 421 }; 422 423 424 425 #endif // #ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX 426 427