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 28 #include "syscreds.hxx" 29 #include "com/sun/star/beans/PropertyValue.hpp" 30 31 using namespace com::sun::star; 32 33 SysCredentialsConfigItem::SysCredentialsConfigItem( 34 SysCredentialsConfig * pOwner ) 35 : utl::ConfigItem( rtl::OUString::createFromAscii( "Office.Common/Passwords" ), 36 CONFIG_MODE_IMMEDIATE_UPDATE ), 37 m_bInited( false ), 38 m_pOwner( pOwner ) 39 { 40 uno::Sequence< ::rtl::OUString > aNode( 1 ); 41 aNode[ 0 ] = rtl::OUString::createFromAscii( 42 "Office.Common/Passwords/AuthenticateUsingSystemCredentials" ); 43 EnableNotification( aNode ); 44 } 45 46 //virtual 47 void SysCredentialsConfigItem::Notify( 48 const uno::Sequence< rtl::OUString > & /*seqPropertyNames*/ ) 49 { 50 { 51 ::osl::MutexGuard aGuard( m_aMutex ); 52 m_bInited = false; 53 // rebuild m_seqURLs 54 getSystemCredentialsURLs(); 55 } 56 m_pOwner->persistentConfigChanged(); 57 } 58 59 void SysCredentialsConfigItem::Commit() 60 { 61 // does nothing 62 } 63 64 uno::Sequence< rtl::OUString > 65 SysCredentialsConfigItem::getSystemCredentialsURLs() 66 { 67 ::osl::MutexGuard aGuard( m_aMutex ); 68 if ( !m_bInited ) 69 { 70 // read config item 71 uno::Sequence< ::rtl::OUString > aPropNames( 1 ); 72 aPropNames[ 0 ] = rtl::OUString::createFromAscii( 73 "AuthenticateUsingSystemCredentials" ); 74 uno::Sequence< uno::Any > aAnyValues( 75 utl::ConfigItem::GetProperties( aPropNames ) ); 76 77 OSL_ENSURE( 78 aAnyValues.getLength() == 1, 79 "SysCredentialsConfigItem::getSystemCredentialsURLs: " 80 "Error reading config item!" ); 81 82 uno::Sequence< rtl::OUString > aValues; 83 if ( ( aAnyValues[ 0 ] >>= aValues ) || 84 ( !aAnyValues[ 0 ].hasValue() ) ) 85 { 86 m_seqURLs = aValues; 87 m_bInited = true; 88 } 89 } 90 return m_seqURLs; 91 } 92 93 void SysCredentialsConfigItem::setSystemCredentialsURLs( 94 const uno::Sequence< rtl::OUString > & seqURLList ) 95 { 96 ::osl::MutexGuard aGuard( m_aMutex ); 97 98 // write config item. 99 uno::Sequence< rtl::OUString > aPropNames( 1 ); 100 uno::Sequence< uno::Any > aPropValues( 1 ); 101 aPropNames[ 0 ] 102 = ::rtl::OUString::createFromAscii( 103 "AuthenticateUsingSystemCredentials" ); 104 aPropValues[ 0 ] <<= seqURLList; 105 106 utl::ConfigItem::SetModified(); 107 utl::ConfigItem::PutProperties( aPropNames, aPropValues ); 108 109 m_seqURLs = seqURLList; 110 m_bInited = true; 111 } 112 113 //============================================================================ 114 115 namespace 116 { 117 // TODO: This code is actually copied from svl/source/passwordcontainer.cxx 118 bool removeLastSegment( ::rtl::OUString & aURL ) 119 { 120 sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) ); 121 122 if( aInd > 0 ) 123 { 124 sal_Int32 aPrevInd = aURL.lastIndexOf( sal_Unicode( '/' ), aInd ); 125 if ( aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) 126 != aPrevInd - 2 || 127 aInd != aURL.getLength() - 1 ) 128 { 129 aURL = aURL.copy( 0, aInd ); 130 return true; 131 } 132 } 133 134 return false; 135 } 136 137 bool findURL( StringSet const & rContainer, rtl::OUString const & aURL, rtl::OUString & aResult ) 138 { 139 // TODO: This code is actually copied from svl/source/passwordcontainer.cxx 140 if( !rContainer.empty() && aURL.getLength() ) 141 { 142 ::rtl::OUString aUrl( aURL ); 143 144 // each iteration remove last '/...' section from the aUrl 145 // while it's possible, up to the most left '://' 146 do 147 { 148 // first look for <url>/somename and then look for <url>/somename/... 149 StringSet::const_iterator aIter = rContainer.find( aUrl ); 150 if( aIter != rContainer.end() ) 151 { 152 aResult = *aIter; 153 return true; 154 } 155 else 156 { 157 ::rtl::OUString tmpUrl( aUrl ); 158 if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) 159 tmpUrl += ::rtl::OUString::createFromAscii( "/" ); 160 161 aIter = rContainer.lower_bound( tmpUrl ); 162 if( aIter != rContainer.end() && aIter->match( tmpUrl ) ) 163 { 164 aResult = *aIter; 165 return true; 166 } 167 } 168 } 169 while( removeLastSegment( aUrl ) && aUrl.getLength() ); 170 } 171 aResult = rtl::OUString(); 172 return false; 173 } 174 175 } // namespace 176 177 SysCredentialsConfig::SysCredentialsConfig() 178 : m_aConfigItem( this ), 179 m_bCfgInited( false ) 180 { 181 } 182 183 void SysCredentialsConfig::initCfg() 184 { 185 osl::MutexGuard aGuard( m_aMutex ); 186 if ( !m_bCfgInited ) 187 { 188 uno::Sequence< rtl::OUString > aURLs( 189 m_aConfigItem.getSystemCredentialsURLs() ); 190 for ( sal_Int32 n = 0; n < aURLs.getLength(); ++n ) 191 m_aCfgContainer.insert( aURLs[ n ] ); 192 193 m_bCfgInited = true; 194 } 195 } 196 197 void SysCredentialsConfig::writeCfg() 198 { 199 osl::MutexGuard aGuard( m_aMutex ); 200 201 OSL_ENSURE( m_bCfgInited, "SysCredentialsConfig::writeCfg : not initialized!" ); 202 203 uno::Sequence< rtl::OUString > aURLs( m_aCfgContainer.size() ); 204 StringSet::const_iterator it = m_aCfgContainer.begin(); 205 const StringSet::const_iterator end = m_aCfgContainer.end(); 206 sal_Int32 n = 0; 207 208 while ( it != end ) 209 { 210 aURLs[ n ] = *it; 211 ++it; 212 ++n; 213 } 214 215 m_aConfigItem.setSystemCredentialsURLs( aURLs ); 216 } 217 218 rtl::OUString SysCredentialsConfig::find( rtl::OUString const & aURL ) 219 { 220 osl::MutexGuard aGuard( m_aMutex ); 221 rtl::OUString aResult; 222 if ( findURL( m_aMemContainer, aURL, aResult ) ) 223 return aResult; 224 225 initCfg(); 226 if ( findURL( m_aCfgContainer, aURL, aResult ) ) 227 return aResult; 228 229 return rtl::OUString(); 230 } 231 232 void SysCredentialsConfig::add( rtl::OUString const & rURL, bool bPersistent ) 233 { 234 ::osl::MutexGuard aGuard( m_aMutex ); 235 236 if ( bPersistent ) 237 { 238 m_aMemContainer.erase( rURL ); 239 240 initCfg(); 241 m_aCfgContainer.insert( rURL ); 242 writeCfg(); 243 } 244 else 245 { 246 initCfg(); 247 if ( m_aCfgContainer.erase( rURL ) > 0 ) 248 writeCfg(); 249 250 m_aMemContainer.insert( rURL ); 251 } 252 } 253 254 void SysCredentialsConfig::remove( rtl::OUString const & rURL ) 255 { 256 m_aMemContainer.erase( rURL ); 257 258 initCfg(); 259 if ( m_aCfgContainer.erase( rURL ) > 0 ) 260 writeCfg(); 261 } 262 263 uno::Sequence< rtl::OUString > SysCredentialsConfig::list( bool bOnlyPersistent ) 264 { 265 initCfg(); 266 sal_Int32 nCount = m_aCfgContainer.size() 267 + ( bOnlyPersistent ? 0 : m_aMemContainer.size() ); 268 uno::Sequence< rtl::OUString > aResult( nCount ); 269 270 StringSet::const_iterator it = m_aCfgContainer.begin(); 271 StringSet::const_iterator end = m_aCfgContainer.end(); 272 sal_Int32 n = 0; 273 274 while ( it != end ) 275 { 276 aResult[ n ] = *it; 277 ++it; 278 ++n; 279 } 280 281 if ( !bOnlyPersistent ) 282 { 283 it = m_aMemContainer.begin(); 284 end = m_aMemContainer.end(); 285 286 while ( it != end ) 287 { 288 aResult[ n ] = *it; 289 ++it; 290 ++n; 291 } 292 } 293 return aResult; 294 } 295 296 void SysCredentialsConfig::persistentConfigChanged() 297 { 298 ::osl::MutexGuard aGuard( m_aMutex ); 299 m_bCfgInited = false; // re-init on demand. 300 } 301