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 void processResponse( CurlRequest &curlRequest, 93 CURLcode curlCode ); 94 95 static CURLcode Curl_SSLContextCallback( CURL *curl, 96 void *ssl_ctx, 97 void *userptr ); 98 static int OPENSSL_VerifyCertificate( X509_STORE_CTX *x509_ctx, void *arg ); 99 int verifyServerX509Certificate( X509_STORE_CTX *x509StoreContext ); 100 int verifyCertificateChain ( 101 std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates ); 102 103 static int Curl_DebugCallback( CURL *, 104 curl_infotype type, 105 unsigned char *data, 106 size_t size, 107 void* userdata ); 108 int curlDebugOutput( curl_infotype type, char *data, int size ); 109 110 static bool Curl_ProvideCredentials( long statusCode, 111 void *userdata ); 112 bool provideCredentials( const DAVRequestEnvironment &env, 113 CurlRequest &request, 114 long statusCode ); 115 116 protected: 117 virtual ~CurlSession(); 118 119 public: 120 CurlSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory, 121 const rtl::OUString& inUri, 122 const ucbhelper::InternetProxyDecider & rProxyDecider ); 123 124 // DAVSession methods 125 virtual sal_Bool CanUse( const ::rtl::OUString & inUri ); 126 127 virtual sal_Bool UsesProxy(); 128 129 const DAVRequestEnvironment & getRequestEnvironment() const 130 { return m_aEnv; } 131 132 // allprop & named 133 virtual void 134 PROPFIND( const ::rtl::OUString & inPath, 135 const Depth inDepth, 136 const std::vector< ::rtl::OUString > & inPropNames, 137 std::vector< DAVResource > & ioResources, 138 const DAVRequestEnvironment & rEnv ); 139 140 // propnames 141 virtual void 142 PROPFIND( const ::rtl::OUString & inPath, 143 const Depth inDepth, 144 std::vector< DAVResourceInfo >& ioResInfo, 145 const DAVRequestEnvironment & rEnv ); 146 147 virtual void 148 PROPPATCH( const ::rtl::OUString & inPath, 149 const std::vector< ProppatchValue > & inValues, 150 const DAVRequestEnvironment & rEnv ); 151 152 virtual void 153 HEAD( const ::rtl::OUString & inPath, 154 const std::vector< ::rtl::OUString > & inHeaderNames, 155 DAVResource & ioResource, 156 const DAVRequestEnvironment & rEnv ); 157 158 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 159 GET( const ::rtl::OUString & inPath, 160 const DAVRequestEnvironment & rEnv ); 161 162 virtual void 163 GET( const ::rtl::OUString & inPath, 164 com::sun::star::uno::Reference< 165 com::sun::star::io::XOutputStream > & ioOutputStream, 166 const DAVRequestEnvironment & rEnv ); 167 168 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 169 GET( const ::rtl::OUString & inPath, 170 const std::vector< ::rtl::OUString > & inHeaderNames, 171 DAVResource & ioResource, 172 const DAVRequestEnvironment & rEnv ); 173 174 virtual void 175 GET( const ::rtl::OUString & inPath, 176 com::sun::star::uno::Reference< 177 com::sun::star::io::XOutputStream > & ioOutputStream, 178 const std::vector< ::rtl::OUString > & inHeaderNames, 179 DAVResource & ioResource, 180 const DAVRequestEnvironment & rEnv ); 181 182 virtual void 183 PUT( const ::rtl::OUString & inPath, 184 const com::sun::star::uno::Reference< 185 com::sun::star::io::XInputStream > & inInputStream, 186 const DAVRequestEnvironment & rEnv ); 187 188 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 189 POST( const rtl::OUString & inPath, 190 const rtl::OUString & rContentType, 191 const rtl::OUString & rReferer, 192 const com::sun::star::uno::Reference< 193 com::sun::star::io::XInputStream > & inInputStream, 194 const DAVRequestEnvironment & rEnv ); 195 196 virtual void 197 POST( const rtl::OUString & inPath, 198 const rtl::OUString & rContentType, 199 const rtl::OUString & rReferer, 200 const com::sun::star::uno::Reference< 201 com::sun::star::io::XInputStream > & inInputStream, 202 com::sun::star::uno::Reference< 203 com::sun::star::io::XOutputStream > & oOutputStream, 204 const DAVRequestEnvironment & rEnv ); 205 206 virtual void 207 MKCOL( const ::rtl::OUString & inPath, 208 const DAVRequestEnvironment & rEnv ); 209 210 virtual void 211 COPY( const ::rtl::OUString & inSourceURL, 212 const ::rtl::OUString & inDestinationURL, 213 const DAVRequestEnvironment & rEnv, 214 sal_Bool inOverWrite ); 215 216 virtual void 217 MOVE( const ::rtl::OUString & inSourceURL, 218 const ::rtl::OUString & inDestinationURL, 219 const DAVRequestEnvironment & rEnv, 220 sal_Bool inOverWrite ); 221 222 virtual void DESTROY( const ::rtl::OUString & inPath, 223 const DAVRequestEnvironment & rEnv ); 224 225 // set new lock. 226 virtual void LOCK( const ::rtl::OUString & inURL, 227 com::sun::star::ucb::Lock & inLock, 228 const DAVRequestEnvironment & rEnv ); 229 230 // refresh existing lock. 231 virtual sal_Int64 LOCK( const ::rtl::OUString & inURL, 232 sal_Int64 nTimeout, 233 const DAVRequestEnvironment & rEnv ); 234 235 virtual void UNLOCK( const ::rtl::OUString & inURL, 236 const DAVRequestEnvironment & rEnv ); 237 238 // helpers 239 virtual void abort(); 240 241 const rtl::OUString & getHostName() const { return m_aUri.GetHost(); } 242 int getPort() const { return m_aUri.GetPort(); } 243 244 const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF() 245 { return m_xFactory->getServiceFactory(); } 246 247 sal_Bool isDomainMatch( rtl::OUString certHostName ); 248 249 const rtl::OString & getServerHeaderField() { return m_aServerHeaderField; }; 250 251 private: 252 friend class CurlLockStore; 253 254 void Init( void ); 255 256 void Init( const DAVRequestEnvironment & rEnv ); 257 258 const ucbhelper::InternetProxyServer & getProxySettings() const; 259 260 void propfind( CurlRequest &curlRequest, 261 const rtl::OUString &inPath, 262 const Depth inDepth, 263 const std::vector< ::rtl::OUString > * propNames, 264 const bool onlyPropertyNames, 265 const DAVRequestEnvironment & rEnv ); 266 267 bool removeExpiredLocktoken( const rtl::OUString & inURL, 268 const DAVRequestEnvironment & rEnv ); 269 270 // refresh lock, called by CurlLockStore::refreshLocks 271 bool LOCK( CurlLock * pLock, 272 sal_Int32 & rlastChanceToSendRefreshRequest ); 273 274 // unlock, called by CurlLockStore::~CurlLockStore 275 bool UNLOCK( CurlLock * pLock ); 276 277 /* 278 // low level GET implementation, used by public GET implementations 279 static int GET( CurlConnection * sess, 280 const char * uri, 281 //ne_block_reader reader, 282 bool getheaders, 283 void * userdata ); 284 285 // Buffer-based PUT implementation. Serf only has file descriptor- 286 // based API. 287 static int PUT( CurlConnection * sess, 288 const char * uri, 289 const char * buffer, 290 size_t size ); 291 292 // Buffer-based POST implementation. Serf only has file descriptor- 293 // based API. 294 int POST( CurlConnection * sess, 295 const char * uri, 296 const char * buffer, 297 //ne_block_reader reader, 298 void * userdata, 299 const rtl::OUString & rContentType, 300 const rtl::OUString & rReferer ); 301 */ 302 303 // Helper: XInputStream -> Sequence< sal_Int8 > 304 static bool getDataFromInputStream( 305 const com::sun::star::uno::Reference< 306 com::sun::star::io::XInputStream > & xStream, 307 com::sun::star::uno::Sequence< sal_Int8 > & rData, 308 bool bAppendTrailingZeroByte ); 309 310 /* 311 rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const; 312 */ 313 }; 314 315 } // namespace http_dav_ucp 316 317 #endif // INCLUDED_CURLSESSION_HXX 318