LCOV - code coverage report
Current view: top level - port - cpl_aws.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 35 41 85.4 %
Date: 2025-01-18 12:42:00 Functions: 15 19 78.9 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Name:     cpl_aws.h
       4             :  * Project:  CPL - Common Portability Library
       5             :  * Purpose:  Amazon Web Services routines
       6             :  * Author:   Even Rouault <even.rouault at spatialys.com>
       7             :  *
       8             :  **********************************************************************
       9             :  * Copyright (c) 2015, Even Rouault <even.rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef CPL_AWS_INCLUDED_H
      15             : #define CPL_AWS_INCLUDED_H
      16             : 
      17             : #ifndef DOXYGEN_SKIP
      18             : 
      19             : #ifdef HAVE_CURL
      20             : 
      21             : #include <cstddef>
      22             : #include <mutex>
      23             : 
      24             : #include "cpl_string.h"
      25             : 
      26             : #include <curl/curl.h>
      27             : #include <map>
      28             : 
      29             : std::string CPLGetLowerCaseHexSHA256(const void *pabyData, size_t nBytes);
      30             : std::string CPLGetLowerCaseHexSHA256(const std::string &osStr);
      31             : 
      32             : std::string CPLGetAWS_SIGN4_Timestamp(GIntBig timestamp);
      33             : 
      34             : std::string CPLAWSURLEncode(const std::string &osURL, bool bEncodeSlash = true);
      35             : 
      36             : std::string CPLAWSGetHeaderVal(const struct curl_slist *psExistingHeaders,
      37             :                                const char *pszKey);
      38             : 
      39             : std::string CPLGetAWS_SIGN4_Signature(
      40             :     const std::string &osSecretAccessKey, const std::string &osAccessToken,
      41             :     const std::string &osRegion, const std::string &osRequestPayer,
      42             :     const std::string &osService, const std::string &osVerb,
      43             :     const struct curl_slist *psExistingHeaders, const std::string &osHost,
      44             :     const std::string &osCanonicalURI,
      45             :     const std::string &osCanonicalQueryString,
      46             :     const std::string &osXAMZContentSHA256, bool bAddHeaderAMZContentSHA256,
      47             :     const std::string &osTimestamp, std::string &osSignedHeaders);
      48             : 
      49             : std::string CPLGetAWS_SIGN4_Authorization(
      50             :     const std::string &osSecretAccessKey, const std::string &osAccessKeyId,
      51             :     const std::string &osAccessToken, const std::string &osRegion,
      52             :     const std::string &osRequestPayer, const std::string &osService,
      53             :     const std::string &osVerb, const struct curl_slist *psExistingHeaders,
      54             :     const std::string &osHost, const std::string &osCanonicalURI,
      55             :     const std::string &osCanonicalQueryString,
      56             :     const std::string &osXAMZContentSHA256, bool bAddHeaderAMZContentSHA256,
      57             :     const std::string &osTimestamp);
      58             : 
      59             : class IVSIS3LikeHandleHelper
      60             : {
      61             :     CPL_DISALLOW_COPY_ASSIGN(IVSIS3LikeHandleHelper)
      62             : 
      63             :   protected:
      64             :     std::map<std::string, std::string> m_oMapQueryParameters{};
      65             : 
      66             :     virtual void RebuildURL() = 0;
      67             :     std::string GetQueryString(bool bAddEmptyValueAfterEqual) const;
      68             : 
      69             :   public:
      70         984 :     IVSIS3LikeHandleHelper() = default;
      71         984 :     virtual ~IVSIS3LikeHandleHelper() = default;
      72             : 
      73             :     void ResetQueryParameters();
      74             :     void AddQueryParameter(const std::string &osKey,
      75             :                            const std::string &osValue);
      76             : 
      77             :     virtual struct curl_slist *
      78             :     GetCurlHeaders(const std::string &osVerb,
      79             :                    const struct curl_slist *psExistingHeaders,
      80             :                    const void *pabyDataContent = nullptr,
      81             :                    size_t nBytesContent = 0) const = 0;
      82             : 
      83           0 :     virtual bool AllowAutomaticRedirection()
      84             :     {
      85           0 :         return true;
      86             :     }
      87             : 
      88           2 :     virtual bool CanRestartOnError(const char *, const char * /* pszHeaders*/,
      89             :                                    bool /*bSetError*/)
      90             :     {
      91           2 :         return false;
      92             :     }
      93             : 
      94             :     virtual const std::string &GetURL() const = 0;
      95             :     std::string GetURLNoKVP() const;
      96             : 
      97           0 :     virtual std::string GetCopySourceHeader() const
      98             :     {
      99           0 :         return std::string();
     100             :     }
     101             : 
     102           0 :     virtual const char *GetMetadataDirectiveREPLACE() const
     103             :     {
     104           0 :         return "";
     105             :     }
     106             : 
     107             :     static bool GetBucketAndObjectKey(const char *pszURI,
     108             :                                       const char *pszFSPrefix,
     109             :                                       bool bAllowNoObject,
     110             :                                       std::string &osBucketOut,
     111             :                                       std::string &osObjectKeyOut);
     112             : 
     113             :     static std::string BuildCanonicalizedHeaders(
     114             :         std::map<std::string, std::string> &oSortedMapHeaders,
     115             :         const struct curl_slist *psExistingHeaders,
     116             :         const char *pszHeaderPrefix);
     117             : 
     118             :     static std::string GetRFC822DateTime();
     119             : };
     120             : 
     121             : enum class AWSCredentialsSource
     122             : {
     123             :     REGULAR,       // credentials from env variables or ~/.aws/crediential
     124             :     EC2,           // credentials from EC2 private networking
     125             :     WEB_IDENTITY,  // credentials from Web Identity Token
     126             :                    // See
     127             :     // https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html
     128             :     ASSUMED_ROLE,  // credentials from an STS assumed role
     129             :     // See
     130             :     // https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html
     131             :     // and
     132             :     // https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
     133             :     SSO,  // credentials from Single-Sign On
     134             : };
     135             : 
     136             : class VSIS3HandleHelper final : public IVSIS3LikeHandleHelper
     137             : {
     138             :     CPL_DISALLOW_COPY_ASSIGN(VSIS3HandleHelper)
     139             : 
     140             :     std::string m_osURL{};
     141             :     mutable std::string m_osSecretAccessKey{};
     142             :     mutable std::string m_osAccessKeyId{};
     143             :     mutable std::string m_osSessionToken{};
     144             :     std::string m_osEndpoint{};
     145             :     std::string m_osRegion{};
     146             :     std::string m_osRequestPayer{};
     147             :     std::string m_osBucket{};
     148             :     std::string m_osObjectKey{};
     149             :     bool m_bUseHTTPS = false;
     150             :     bool m_bUseVirtualHosting = false;
     151             :     AWSCredentialsSource m_eCredentialsSource = AWSCredentialsSource::REGULAR;
     152             : 
     153             :     void RebuildURL() override;
     154             : 
     155             :     static bool GetOrRefreshTemporaryCredentialsForRole(
     156             :         bool bForceRefresh, std::string &osSecretAccessKey,
     157             :         std::string &osAccessKeyId, std::string &osSessionToken,
     158             :         std::string &osRegion);
     159             : 
     160             :     static bool GetOrRefreshTemporaryCredentialsForSSO(
     161             :         bool bForceRefresh, std::string &osSecretAccessKey,
     162             :         std::string &osAccessKeyId, std::string &osSessionToken,
     163             :         std::string &osRegion);
     164             : 
     165             :     static bool GetConfigurationFromAssumeRoleWithWebIdentity(
     166             :         bool bForceRefresh, const std::string &osPathForOption,
     167             :         const std::string &osRoleArnIn,
     168             :         const std::string &osWebIdentityTokenFileIn,
     169             :         std::string &osSecretAccessKey, std::string &osAccessKeyId,
     170             :         std::string &osSessionToken);
     171             : 
     172             :     static bool GetConfigurationFromEC2(bool bForceRefresh,
     173             :                                         const std::string &osPathForOption,
     174             :                                         std::string &osSecretAccessKey,
     175             :                                         std::string &osAccessKeyId,
     176             :                                         std::string &osSessionToken);
     177             : 
     178             :     static bool GetConfigurationFromAWSConfigFiles(
     179             :         const std::string &osPathForOption, const char *pszProfile,
     180             :         std::string &osSecretAccessKey, std::string &osAccessKeyId,
     181             :         std::string &osSessionToken, std::string &osRegion,
     182             :         std::string &osCredentials, std::string &osRoleArn,
     183             :         std::string &osSourceProfile, std::string &osExternalId,
     184             :         std::string &osMFASerial, std::string &osRoleSessionName,
     185             :         std::string &osWebIdentityTokenFile, std::string &osSSOStartURL,
     186             :         std::string &osSSOAccountID, std::string &osSSORoleName);
     187             : 
     188             :     static bool GetConfiguration(const std::string &osPathForOption,
     189             :                                  CSLConstList papszOptions,
     190             :                                  std::string &osSecretAccessKey,
     191             :                                  std::string &osAccessKeyId,
     192             :                                  std::string &osSessionToken,
     193             :                                  std::string &osRegion,
     194             :                                  AWSCredentialsSource &eCredentialsSource);
     195             : 
     196             :     void RefreshCredentials(const std::string &osPathForOption,
     197             :                             bool bForceRefresh) const;
     198             : 
     199             :   protected:
     200             :   public:
     201             :     VSIS3HandleHelper(
     202             :         const std::string &osSecretAccessKey, const std::string &osAccessKeyId,
     203             :         const std::string &osSessionToken, const std::string &osEndpoint,
     204             :         const std::string &osRegion, const std::string &osRequestPayer,
     205             :         const std::string &osBucket, const std::string &osObjectKey,
     206             :         bool bUseHTTPS, bool bUseVirtualHosting,
     207             :         AWSCredentialsSource eCredentialsSource);
     208             :     ~VSIS3HandleHelper();
     209             : 
     210             :     static VSIS3HandleHelper *BuildFromURI(const char *pszURI,
     211             :                                            const char *pszFSPrefix,
     212             :                                            bool bAllowNoObject,
     213             :                                            CSLConstList papszOptions = nullptr);
     214             :     static std::string BuildURL(const std::string &osEndpoint,
     215             :                                 const std::string &osBucket,
     216             :                                 const std::string &osObjectKey, bool bUseHTTPS,
     217             :                                 bool bUseVirtualHosting);
     218             : 
     219             :     struct curl_slist *
     220             :     GetCurlHeaders(const std::string &osVerb,
     221             :                    const struct curl_slist *psExistingHeaders,
     222             :                    const void *pabyDataContent = nullptr,
     223             :                    size_t nBytesContent = 0) const override;
     224             : 
     225         141 :     bool AllowAutomaticRedirection() override
     226             :     {
     227         141 :         return false;
     228             :     }
     229             : 
     230             :     bool CanRestartOnError(const char *, const char *pszHeaders,
     231             :                            bool bSetError) override;
     232             : 
     233         816 :     const std::string &GetURL() const override
     234             :     {
     235         816 :         return m_osURL;
     236             :     }
     237             : 
     238         478 :     const std::string &GetBucket() const
     239             :     {
     240         478 :         return m_osBucket;
     241             :     }
     242             : 
     243             :     const std::string &GetObjectKey() const
     244             :     {
     245             :         return m_osObjectKey;
     246             :     }
     247             : 
     248          14 :     const std::string &GetEndpoint() const
     249             :     {
     250          14 :         return m_osEndpoint;
     251             :     }
     252             : 
     253          14 :     const std::string &GetRegion() const
     254             :     {
     255          14 :         return m_osRegion;
     256             :     }
     257             : 
     258          14 :     const std::string &GetRequestPayer() const
     259             :     {
     260          14 :         return m_osRequestPayer;
     261             :     }
     262             : 
     263          14 :     bool GetVirtualHosting() const
     264             :     {
     265          14 :         return m_bUseVirtualHosting;
     266             :     }
     267             : 
     268             :     void SetEndpoint(const std::string &osStr);
     269             :     void SetRegion(const std::string &osStr);
     270             :     void SetRequestPayer(const std::string &osStr);
     271             :     void SetVirtualHosting(bool b);
     272             : 
     273           5 :     std::string GetCopySourceHeader() const override
     274             :     {
     275           5 :         return "x-amz-copy-source";
     276             :     }
     277             : 
     278           3 :     const char *GetMetadataDirectiveREPLACE() const override
     279             :     {
     280           3 :         return "x-amz-metadata-directive: REPLACE";
     281             :     }
     282             : 
     283             :     std::string GetSignedURL(CSLConstList papszOptions);
     284             : 
     285             :     static void CleanMutex();
     286             :     static void ClearCache();
     287             : };
     288             : 
     289             : class VSIS3UpdateParams
     290             : {
     291             :   private:
     292             :     std::string m_osRegion{};
     293             :     std::string m_osEndpoint{};
     294             :     std::string m_osRequestPayer{};
     295             :     bool m_bUseVirtualHosting = false;
     296             : 
     297          14 :     explicit VSIS3UpdateParams(const VSIS3HandleHelper *poHelper)
     298          14 :         : m_osRegion(poHelper->GetRegion()),
     299          14 :           m_osEndpoint(poHelper->GetEndpoint()),
     300          14 :           m_osRequestPayer(poHelper->GetRequestPayer()),
     301          14 :           m_bUseVirtualHosting(poHelper->GetVirtualHosting())
     302             :     {
     303          14 :     }
     304             : 
     305          52 :     void UpdateHandlerHelper(VSIS3HandleHelper *poHelper)
     306             :     {
     307          52 :         poHelper->SetRegion(m_osRegion);
     308          52 :         poHelper->SetEndpoint(m_osEndpoint);
     309          52 :         poHelper->SetRequestPayer(m_osRequestPayer);
     310          52 :         poHelper->SetVirtualHosting(m_bUseVirtualHosting);
     311          52 :     }
     312             : 
     313             :     static std::mutex gsMutex;
     314             :     static std::map<std::string, VSIS3UpdateParams> goMapBucketsToS3Params;
     315             : 
     316             :   public:
     317           9 :     VSIS3UpdateParams() = default;
     318             : 
     319             :     static void UpdateMapFromHandle(VSIS3HandleHelper *poS3HandleHelper);
     320             :     static void UpdateHandleFromMap(VSIS3HandleHelper *poS3HandleHelper);
     321             :     static void ClearCache();
     322             : };
     323             : 
     324             : #endif /* HAVE_CURL */
     325             : 
     326             : #endif /* #ifndef DOXYGEN_SKIP */
     327             : 
     328             : #endif /* CPL_AWS_INCLUDED_H */

Generated by: LCOV version 1.14