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 #ifndef INCLUDED_CURLSESSION_HXX 25 #define INCLUDED_CURLSESSION_HXX 26 27 #include <vector> 28 #include <boost/shared_ptr.hpp> 29 #include <osl/mutex.hxx> 30 #include <comphelper/componentcontext.hxx> 31 #include <comphelper/logging.hxx> 32 #include "DAVResource.hxx" 33 #include "DAVSession.hxx" 34 #include "CurlTypes.hxx" 35 #include "CurlRequest.hxx" 36 #include "CurlLockStore.hxx" 37 #include "CurlUri.hxx" 38 #include "CurlInputStream.hxx" 39 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 40 #include <com/sun/star/security/CertificateContainer.hpp> 41 #include <com/sun/star/security/XCertificateContainer.hpp> 42 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 43 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> 44 #include <curl/curl.h> 45 #include <openssl/ssl.h> 46 47 namespace ucbhelper { class ProxyDecider; } 48 49 namespace http_dav_ucp 50 { 51 52 // ------------------------------------------------------------------- 53 // CurlSession 54 // A DAVSession implementation using the Curl library 55 // ------------------------------------------------------------------- 56 57 class CurlSession : public DAVSession 58 { 59 private: 60 osl::Mutex m_aMutex; 61 ::comphelper::ComponentContext m_aContext; 62 ::comphelper::EventLogger m_aLogger; 63 64 CurlUri m_aUri; 65 66 rtl::OUString m_aProxyName; 67 sal_Int32 m_nProxyPort; 68 // The server, according RFC7231 69 // http://tools.ietf.org/html/rfc7231#section-7.4.2 70 rtl::OString m_aServerHeaderField; 71 72 CURL* m_pCurl; 73 bool m_bUseChunkedEncoding; 74 bool m_bTransferEncodingSwitched; 75 76 const ucbhelper::InternetProxyDecider & m_rProxyDecider; 77 78 DAVRequestEnvironment m_aEnv; 79 80 static CurlLockStore m_aCurlLockStore; 81 82 ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateContainer > m_xCertificateContainer; 83 ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext > m_xSecurityContext; 84 ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > m_xSecurityEnv; 85 86 bool isSSLNeeded(); 87 88 89 rtl::OUString composeCurrentUri( const rtl::OUString & inPath ); 90 void addEnvironmentRequestHeaders( CurlRequest &curlRequest, 91 const DAVRequestEnvironment &env ) 92 throw ( DAVException ); 93 void processResponse( CurlRequest &curlRequest, 94 CURLcode curlCode ) 95 throw ( DAVException ); 96 97 static CURLcode Curl_SSLContextCallback( CURL *curl, 98 void *ssl_ctx, 99 void *userptr ); 100 static int OPENSSL_VerifyCertificate( X509_STORE_CTX *x509_ctx, void *arg ); 101 int verifyServerX509Certificate( X509_STORE_CTX *x509StoreContext ); 102 int verifyCertificateChain ( 103 std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates ); 104 105 static int Curl_DebugCallback( CURL *, 106 curl_infotype type, 107 unsigned char *data, 108 size_t size, 109 void* userdata ); 110 int curlDebugOutput( curl_infotype type, char *data, int size ); 111 112 static bool Curl_ProvideCredentials( long statusCode, 113 void *userdata ) throw (DAVException); 114 bool provideCredentials( const DAVRequestEnvironment &env, 115 CurlRequest &request, 116 long statusCode ) throw (DAVException); 117 118 protected: 119 virtual ~CurlSession(); 120 121 public: 122 CurlSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory, 123 const rtl::OUString& inUri, 124 const ucbhelper::InternetProxyDecider & rProxyDecider ) 125 throw ( DAVException ); 126 127 // DAVSession methods 128 virtual sal_Bool CanUse( const ::rtl::OUString & inUri ); 129 130 virtual sal_Bool UsesProxy(); 131 getRequestEnvironment() const132 const DAVRequestEnvironment & getRequestEnvironment() const 133 { return m_aEnv; } 134 135 // allprop & named 136 virtual void 137 PROPFIND( const ::rtl::OUString & inPath, 138 const Depth inDepth, 139 const std::vector< ::rtl::OUString > & inPropNames, 140 std::vector< DAVResource > & ioResources, 141 const DAVRequestEnvironment & rEnv ) 142 throw ( DAVException ); 143 144 // propnames 145 virtual void 146 PROPFIND( const ::rtl::OUString & inPath, 147 const Depth inDepth, 148 std::vector< DAVResourceInfo >& ioResInfo, 149 const DAVRequestEnvironment & rEnv ) 150 throw ( DAVException ); 151 152 virtual void 153 PROPPATCH( const ::rtl::OUString & inPath, 154 const std::vector< ProppatchValue > & inValues, 155 const DAVRequestEnvironment & rEnv ) 156 throw ( DAVException ); 157 158 virtual void 159 HEAD( const ::rtl::OUString & inPath, 160 const std::vector< ::rtl::OUString > & inHeaderNames, 161 DAVResource & ioResource, 162 const DAVRequestEnvironment & rEnv ) 163 throw ( DAVException ); 164 165 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 166 GET( const ::rtl::OUString & inPath, 167 const DAVRequestEnvironment & rEnv ) 168 throw ( DAVException ); 169 170 virtual void 171 GET( const ::rtl::OUString & inPath, 172 com::sun::star::uno::Reference< 173 com::sun::star::io::XOutputStream > & ioOutputStream, 174 const DAVRequestEnvironment & rEnv ) 175 throw ( DAVException ); 176 177 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 178 GET( const ::rtl::OUString & inPath, 179 const std::vector< ::rtl::OUString > & inHeaderNames, 180 DAVResource & ioResource, 181 const DAVRequestEnvironment & rEnv ) 182 throw ( DAVException ); 183 184 virtual void 185 GET( const ::rtl::OUString & inPath, 186 com::sun::star::uno::Reference< 187 com::sun::star::io::XOutputStream > & ioOutputStream, 188 const std::vector< ::rtl::OUString > & inHeaderNames, 189 DAVResource & ioResource, 190 const DAVRequestEnvironment & rEnv ) 191 throw ( DAVException ); 192 193 virtual void 194 PUT( const ::rtl::OUString & inPath, 195 const com::sun::star::uno::Reference< 196 com::sun::star::io::XInputStream > & inInputStream, 197 const DAVRequestEnvironment & rEnv ) 198 throw ( DAVException ); 199 200 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 201 POST( const rtl::OUString & inPath, 202 const rtl::OUString & rContentType, 203 const rtl::OUString & rReferer, 204 const com::sun::star::uno::Reference< 205 com::sun::star::io::XInputStream > & inInputStream, 206 const DAVRequestEnvironment & rEnv ) 207 throw ( DAVException ); 208 209 virtual void 210 POST( const rtl::OUString & inPath, 211 const rtl::OUString & rContentType, 212 const rtl::OUString & rReferer, 213 const com::sun::star::uno::Reference< 214 com::sun::star::io::XInputStream > & inInputStream, 215 com::sun::star::uno::Reference< 216 com::sun::star::io::XOutputStream > & oOutputStream, 217 const DAVRequestEnvironment & rEnv ) 218 throw ( DAVException ); 219 220 virtual void 221 MKCOL( const ::rtl::OUString & inPath, 222 const DAVRequestEnvironment & rEnv ) 223 throw ( DAVException ); 224 225 virtual void 226 COPY( const ::rtl::OUString & inSourceURL, 227 const ::rtl::OUString & inDestinationURL, 228 const DAVRequestEnvironment & rEnv, 229 sal_Bool inOverWrite ) 230 throw ( DAVException ); 231 232 virtual void 233 MOVE( const ::rtl::OUString & inSourceURL, 234 const ::rtl::OUString & inDestinationURL, 235 const DAVRequestEnvironment & rEnv, 236 sal_Bool inOverWrite ) 237 throw ( DAVException ); 238 239 virtual void DESTROY( const ::rtl::OUString & inPath, 240 const DAVRequestEnvironment & rEnv ) 241 throw ( DAVException ); 242 243 // set new lock. 244 virtual void LOCK( const ::rtl::OUString & inURL, 245 com::sun::star::ucb::Lock & inLock, 246 const DAVRequestEnvironment & rEnv ) 247 throw ( DAVException ); 248 249 // refresh existing lock. 250 virtual sal_Int64 LOCK( const ::rtl::OUString & inURL, 251 sal_Int64 nTimeout, 252 const DAVRequestEnvironment & rEnv ) 253 throw ( DAVException ); 254 255 virtual void UNLOCK( const ::rtl::OUString & inURL, 256 const DAVRequestEnvironment & rEnv ) 257 throw ( DAVException ); 258 259 // helpers 260 virtual void abort() 261 throw ( DAVException ); 262 getHostName() const263 const rtl::OUString & getHostName() const { return m_aUri.GetHost(); } getPort() const264 int getPort() const { return m_aUri.GetPort(); } 265 getMSF()266 const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF() 267 { return m_xFactory->getServiceFactory(); } 268 269 sal_Bool isDomainMatch( rtl::OUString certHostName ); 270 getServerHeaderField()271 const rtl::OString & getServerHeaderField() { return m_aServerHeaderField; }; 272 273 private: 274 friend class CurlLockStore; 275 276 void Init( void ) 277 throw ( DAVException ); 278 279 void Init( const DAVRequestEnvironment & rEnv ) 280 throw ( DAVException ); 281 282 const ucbhelper::InternetProxyServer & getProxySettings() const; 283 284 void propfind( CurlRequest &curlRequest, 285 const rtl::OUString &inPath, 286 const Depth inDepth, 287 const std::vector< ::rtl::OUString > * propNames, 288 const bool onlyPropertyNames, 289 const DAVRequestEnvironment & rEnv ); 290 291 bool removeExpiredLocktoken( const rtl::OUString & inURL, 292 const DAVRequestEnvironment & rEnv ); 293 294 // refresh lock, called by CurlLockStore::refreshLocks 295 bool LOCK( CurlLock * pLock, 296 sal_Int32 & rlastChanceToSendRefreshRequest ); 297 298 // unlock, called by CurlLockStore::~CurlLockStore 299 bool UNLOCK( CurlLock * pLock ); 300 301 /* 302 // low level GET implementation, used by public GET implementations 303 static int GET( CurlConnection * sess, 304 const char * uri, 305 //ne_block_reader reader, 306 bool getheaders, 307 void * userdata ); 308 309 // Buffer-based PUT implementation. Serf only has file descriptor- 310 // based API. 311 static int PUT( CurlConnection * sess, 312 const char * uri, 313 const char * buffer, 314 size_t size ); 315 316 // Buffer-based POST implementation. Serf only has file descriptor- 317 // based API. 318 int POST( CurlConnection * sess, 319 const char * uri, 320 const char * buffer, 321 //ne_block_reader reader, 322 void * userdata, 323 const rtl::OUString & rContentType, 324 const rtl::OUString & rReferer ); 325 */ 326 327 // Helper: XInputStream -> Sequence< sal_Int8 > 328 static bool getDataFromInputStream( 329 const com::sun::star::uno::Reference< 330 com::sun::star::io::XInputStream > & xStream, 331 com::sun::star::uno::Sequence< sal_Int8 > & rData, 332 bool bAppendTrailingZeroByte ); 333 334 /* 335 rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const; 336 */ 337 }; 338 339 } // namespace http_dav_ucp 340 341 #endif // INCLUDED_CURLSESSION_HXX 342