1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_shell.hxx" 26 27 // For MAXHOSTNAMELEN constant 28 #include <sys/param.h> 29 30 #include <premac.h> 31 #include <SystemConfiguration/SystemConfiguration.h> 32 #include <Foundation/NSPathUtilities.h> 33 #include <postmac.h> 34 35 #include "macbackend.hxx" 36 37 #include "com/sun/star/beans/Optional.hpp" 38 #include "rtl/ustrbuf.hxx" 39 #include "osl/file.h" 40 41 #define SPACE ' ' 42 #define SEMI_COLON ';' 43 44 typedef struct 45 { 46 rtl::OUString Server; 47 sal_Int32 Port; 48 } ProxyEntry; 49 50 typedef enum { 51 sHTTP, 52 sHTTPS, 53 sFTP 54 } ServiceType; 55 56 //------------------------------------------------------------------------ 57 // helper functions 58 //------------------------------------------------------------------------ 59 60 namespace // private 61 { 62 63 /* 64 * Returns current proxy settings for selected service type (HTTP or 65 * FTP) as a C string (in the buffer specified by host and hostSize) 66 * and a port number. 67 */ 68 69 bool GetProxySetting(ServiceType sType, char *host, size_t hostSize, UInt16 *port) 70 { 71 bool result; 72 CFDictionaryRef proxyDict; 73 CFNumberRef enableNum; 74 int enable; 75 CFStringRef hostStr; 76 CFNumberRef portNum; 77 int portInt; 78 79 proxyDict = SCDynamicStoreCopyProxies(NULL); 80 81 if (!proxyDict) 82 return false; 83 84 CFStringRef proxiesEnable; 85 CFStringRef proxiesProxy; 86 CFStringRef proxiesPort; 87 88 switch ( sType ) 89 { 90 case sHTTP : proxiesEnable = kSCPropNetProxiesHTTPEnable; 91 proxiesProxy = kSCPropNetProxiesHTTPProxy; 92 proxiesPort = kSCPropNetProxiesHTTPPort; 93 break; 94 case sHTTPS: proxiesEnable = kSCPropNetProxiesHTTPSEnable; 95 proxiesProxy = kSCPropNetProxiesHTTPSProxy; 96 proxiesPort = kSCPropNetProxiesHTTPSPort; 97 break; 98 default: proxiesEnable = kSCPropNetProxiesFTPEnable; 99 proxiesProxy = kSCPropNetProxiesFTPProxy; 100 proxiesPort = kSCPropNetProxiesFTPPort; 101 break; 102 } 103 // Proxy enabled? 104 enableNum = (CFNumberRef) CFDictionaryGetValue( proxyDict, 105 proxiesEnable ); 106 107 result = (enableNum != NULL) && (CFGetTypeID(enableNum) == CFNumberGetTypeID()); 108 109 if (result) 110 result = CFNumberGetValue(enableNum, kCFNumberIntType, &enable) && (enable != 0); 111 112 // Proxy enabled -> get hostname 113 if (result) 114 { 115 hostStr = (CFStringRef) CFDictionaryGetValue( proxyDict, 116 proxiesProxy ); 117 118 result = (hostStr != NULL) && (CFGetTypeID(hostStr) == CFStringGetTypeID()); 119 } 120 121 if (result) 122 result = CFStringGetCString(hostStr, host, (CFIndex) hostSize, kCFStringEncodingASCII); 123 124 // Get proxy port 125 if (result) 126 { 127 portNum = (CFNumberRef) CFDictionaryGetValue( proxyDict, 128 proxiesPort ); 129 130 result = (portNum != NULL) && (CFGetTypeID(portNum) == CFNumberGetTypeID()); 131 } 132 else 133 { 134 CFRelease(proxyDict); 135 return false; 136 } 137 138 if (result) 139 result = CFNumberGetValue(portNum, kCFNumberIntType, &portInt); 140 141 if (result) 142 *port = (UInt16) portInt; 143 144 if (proxyDict) 145 CFRelease(proxyDict); 146 147 if (!result) 148 { 149 *host = 0; 150 *port = 0; 151 } 152 153 return result; 154 } 155 156 } // end private namespace 157 158 //------------------------------------------------------------------------------ 159 160 MacOSXBackend::MacOSXBackend() 161 { 162 } 163 164 //------------------------------------------------------------------------------ 165 166 MacOSXBackend::~MacOSXBackend(void) 167 { 168 } 169 170 //------------------------------------------------------------------------------ 171 172 MacOSXBackend* MacOSXBackend::createInstance() 173 { 174 return new MacOSXBackend; 175 } 176 177 // --------------------------------------------------------------------------------------- 178 179 rtl::OUString CFStringToOUString(const CFStringRef sOrig) { 180 CFRetain(sOrig); 181 182 CFIndex nStringLen = CFStringGetLength(sOrig)+1; 183 184 // Allocate a c string buffer 185 char sBuffer[nStringLen]; 186 187 CFStringGetCString(sOrig, sBuffer, nStringLen, kCFStringEncodingASCII); 188 189 CFRelease(sOrig); 190 191 return rtl::OUString::createFromAscii((sal_Char*)sBuffer); 192 } 193 194 rtl::OUString GetOUString( NSString* pStr ) 195 { 196 if( ! pStr ) 197 return rtl::OUString(); 198 int nLen = [pStr length]; 199 if( nLen == 0 ) 200 return rtl::OUString(); 201 202 rtl::OUStringBuffer aBuf( nLen+1 ); 203 aBuf.setLength( nLen ); 204 [pStr getCharacters: const_cast<sal_Unicode*>(aBuf.getStr())]; 205 return aBuf.makeStringAndClear(); 206 } 207 208 void MacOSXBackend::setPropertyValue( 209 rtl::OUString const &, css::uno::Any const &) 210 throw ( 211 css::beans::UnknownPropertyException, css::beans::PropertyVetoException, 212 css::lang::IllegalArgumentException, css::lang::WrappedTargetException, 213 css::uno::RuntimeException) 214 { 215 throw css::lang::IllegalArgumentException( 216 rtl::OUString( 217 RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")), 218 static_cast< cppu::OWeakObject * >(this), -1); 219 } 220 221 css::uno::Any MacOSXBackend::getPropertyValue( 222 rtl::OUString const & PropertyName) 223 throw ( 224 css::beans::UnknownPropertyException, css::lang::WrappedTargetException, 225 css::uno::RuntimeException) 226 { 227 if (PropertyName.equalsAsciiL( 228 RTL_CONSTASCII_STRINGPARAM("WorkPathVariable"))) 229 { 230 rtl::OUString aDocDir; 231 NSArray* pPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true ); 232 if( pPaths && [pPaths count] > 0 ) 233 { 234 aDocDir = GetOUString( [pPaths objectAtIndex: 0] ); 235 236 rtl::OUString aDocURL; 237 if( aDocDir.getLength() > 0 && 238 osl_getFileURLFromSystemPath( aDocDir.pData, &aDocURL.pData ) == osl_File_E_None ) 239 { 240 return css::uno::makeAny( 241 css::beans::Optional< css::uno::Any >( 242 true, css::uno::makeAny( aDocURL ) ) ); 243 } 244 else 245 { 246 OSL_TRACE( "user documents list contains empty file path or conversion failed" ); 247 } 248 } 249 else 250 { 251 OSL_TRACE( "Got nil or empty list of user document directories" ); 252 } 253 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 254 } else if (PropertyName.equalsAsciiL( 255 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyName"))) 256 { 257 ProxyEntry aFtpProxy; 258 259 char host[MAXHOSTNAMELEN]; 260 UInt16 port; 261 bool retVal; 262 263 retVal = GetProxySetting(sFTP, host, 100, &port); 264 265 if (retVal) 266 { 267 aFtpProxy.Server = rtl::OUString::createFromAscii( host ); 268 } 269 270 // ftp proxy name 271 if( aFtpProxy.Server.getLength() > 0 ) 272 { 273 return css::uno::makeAny( 274 css::beans::Optional< css::uno::Any >( 275 true, uno::makeAny( aFtpProxy.Server ) ) ); 276 } 277 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 278 } else if (PropertyName.equalsAsciiL( 279 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyPort"))) 280 { 281 ProxyEntry aFtpProxy; 282 283 char host[MAXHOSTNAMELEN]; 284 UInt16 port; 285 bool retVal; 286 287 retVal = GetProxySetting(sFTP, host, 100, &port); 288 289 if (retVal) 290 { 291 aFtpProxy.Port = port; 292 } 293 294 // ftp proxy port 295 if( aFtpProxy.Port > 0 ) 296 { 297 return css::uno::makeAny( 298 css::beans::Optional< css::uno::Any >( 299 true, uno::makeAny( aFtpProxy.Port ) ) ); 300 } 301 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 302 } else if (PropertyName.equalsAsciiL( 303 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyName"))) 304 { 305 ProxyEntry aHttpProxy; 306 307 char host[MAXHOSTNAMELEN]; 308 UInt16 port; 309 bool retVal; 310 311 retVal = GetProxySetting(sHTTP, host, 100, &port); 312 313 if (retVal) 314 { 315 aHttpProxy.Server = rtl::OUString::createFromAscii( host ); 316 } 317 318 // http proxy name 319 if( aHttpProxy.Server.getLength() > 0 ) 320 { 321 return css::uno::makeAny( 322 css::beans::Optional< css::uno::Any >( 323 true, uno::makeAny( aHttpProxy.Server ) ) ); 324 } 325 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 326 } else if (PropertyName.equalsAsciiL( 327 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyPort"))) 328 { 329 ProxyEntry aHttpProxy; 330 331 char host[MAXHOSTNAMELEN]; 332 UInt16 port; 333 bool retVal; 334 335 retVal = GetProxySetting(sHTTP, host, 100, &port); 336 337 if (retVal) 338 { 339 aHttpProxy.Port = port; 340 } 341 342 // http proxy port 343 if( aHttpProxy.Port > 0 ) 344 { 345 return css::uno::makeAny( 346 css::beans::Optional< css::uno::Any >( 347 true, uno::makeAny( aHttpProxy.Port ) ) ); 348 } 349 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 350 } else if (PropertyName.equalsAsciiL( 351 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyName"))) 352 { 353 ProxyEntry aHttpsProxy; 354 355 char host[MAXHOSTNAMELEN]; 356 UInt16 port; 357 bool retVal; 358 359 retVal = GetProxySetting(sHTTPS, host, 100, &port); 360 361 if (retVal) 362 { 363 aHttpsProxy.Server = rtl::OUString::createFromAscii( host ); 364 } 365 366 // https proxy name 367 if( aHttpsProxy.Server.getLength() > 0 ) 368 { 369 return css::uno::makeAny( 370 css::beans::Optional< css::uno::Any >( 371 true, uno::makeAny( aHttpsProxy.Server ) ) ); 372 } 373 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 374 } else if (PropertyName.equalsAsciiL( 375 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyPort"))) 376 { 377 ProxyEntry aHttpsProxy; 378 379 char host[MAXHOSTNAMELEN]; 380 UInt16 port; 381 bool retVal; 382 383 retVal = GetProxySetting(sHTTPS, host, 100, &port); 384 385 if (retVal) 386 { 387 aHttpsProxy.Port = port; 388 } 389 390 // https proxy port 391 if( aHttpsProxy.Port > 0 ) 392 { 393 return css::uno::makeAny( 394 css::beans::Optional< css::uno::Any >( 395 true, uno::makeAny( aHttpsProxy.Port ) ) ); 396 } 397 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 398 } else if (PropertyName.equalsAsciiL( 399 RTL_CONSTASCII_STRINGPARAM("ooInetProxyType"))) 400 { 401 // override default for ProxyType, which is "0" meaning "No proxies". 402 sal_Int32 nProperties = 1; 403 return css::uno::makeAny( 404 css::beans::Optional< css::uno::Any >( 405 true, uno::makeAny( nProperties ) ) ); 406 } else if (PropertyName.equalsAsciiL( 407 RTL_CONSTASCII_STRINGPARAM("ooInetNoProxy"))) 408 { 409 rtl::OUString aProxyBypassList; 410 411 CFArrayRef rExceptionsList; 412 CFDictionaryRef rProxyDict = SCDynamicStoreCopyProxies(NULL); 413 414 if (!rProxyDict) 415 rExceptionsList = false; 416 else 417 rExceptionsList = (CFArrayRef) CFDictionaryGetValue(rProxyDict, kSCPropNetProxiesExceptionsList); 418 419 if (rExceptionsList) 420 { 421 for (CFIndex idx = 0; idx < CFArrayGetCount(rExceptionsList); idx++) 422 { 423 CFStringRef rException = (CFStringRef) CFArrayGetValueAtIndex(rExceptionsList, idx); 424 425 if (idx>0) 426 aProxyBypassList += rtl::OUString::createFromAscii( ";" ); 427 428 aProxyBypassList += CFStringToOUString(rException); 429 } 430 } 431 432 if (rProxyDict) 433 CFRelease(rProxyDict); 434 435 // fill proxy bypass list 436 if( aProxyBypassList.getLength() > 0 ) 437 { 438 return css::uno::makeAny( 439 css::beans::Optional< css::uno::Any >( 440 true, 441 uno::makeAny( aProxyBypassList.replace( SPACE, SEMI_COLON ) ) ) ); 442 } 443 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 444 } else { 445 throw css::beans::UnknownPropertyException( 446 PropertyName, static_cast< cppu::OWeakObject * >(this)); 447 } 448 } 449 450 //------------------------------------------------------------------------------ 451 452 rtl::OUString SAL_CALL MacOSXBackend::getBackendName(void) 453 { 454 return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.backend.MacOSXBackend"); 455 } 456 457 //------------------------------------------------------------------------------ 458 459 rtl::OUString SAL_CALL MacOSXBackend::getImplementationName(void) 460 throw (uno::RuntimeException) 461 { 462 return getBackendName(); 463 } 464 465 //------------------------------------------------------------------------------ 466 467 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getBackendServiceNames(void) 468 { 469 uno::Sequence<rtl::OUString> aServiceNameList(1); 470 aServiceNameList[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.MacOSXBackend")); 471 472 return aServiceNameList; 473 } 474 475 //------------------------------------------------------------------------------ 476 477 sal_Bool SAL_CALL MacOSXBackend::supportsService(const rtl::OUString& aServiceName) 478 throw (uno::RuntimeException) 479 { 480 uno::Sequence< rtl::OUString > const svc = getBackendServiceNames(); 481 482 for(sal_Int32 i = 0; i < svc.getLength(); ++i ) 483 if(svc[i] == aServiceName) 484 return true; 485 486 return false; 487 } 488 489 //------------------------------------------------------------------------------ 490 491 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void) 492 throw (uno::RuntimeException) 493 { 494 return getBackendServiceNames(); 495 } 496