LCOV - code coverage report
Current view: top level - port - cpl_aws.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 36 44 81.8 %
Date: 2026-06-20 20:44:25 Functions: 16 21 76.2 %

          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        3360 : class IVSIS3LikeHandleHelper
      40             : {
      41             :     CPL_DISALLOW_COPY_ASSIGN(IVSIS3LikeHandleHelper)
      42             : 
      43             :   protected:
      44             :     std::map<std::string, std::string> m_oMapQueryParameters{};
      45             : 
      46             :     virtual void RebuildURL() = 0;
      47             :     std::string GetQueryString(bool bAddEmptyValueAfterEqual) const;
      48             : 
      49             :   public:
      50             :     IVSIS3LikeHandleHelper();
      51             :     virtual ~IVSIS3LikeHandleHelper();
      52             : 
      53             :     void ResetQueryParameters();
      54             :     void AddQueryParameter(const std::string &osKey,
      55             :                            const std::string &osValue);
      56             : 
      57             :     virtual struct curl_slist *
      58             :     GetCurlHeaders(const std::string &osVerb, struct curl_slist *psHeaders,
      59             :                    const void *pabyDataContent = nullptr,
      60             :                    size_t nBytesContent = 0) const = 0;
      61             : 
      62           0 :     virtual bool AllowAutomaticRedirection()
      63             :     {
      64           0 :         return true;
      65             :     }
      66             : 
      67           2 :     virtual bool CanRestartOnError(const char *, const char * /* pszHeaders*/,
      68             :                                    bool /*bSetError*/)
      69             :     {
      70           2 :         return false;
      71             :     }
      72             : 
      73             :     virtual const std::string &GetURL() const = 0;
      74             :     std::string GetURLNoKVP() const;
      75             : 
      76           0 :     virtual std::string GetCopySourceHeader() const
      77             :     {
      78           0 :         return std::string();
      79             :     }
      80             : 
      81           0 :     virtual const char *GetMetadataDirectiveREPLACE() const
      82             :     {
      83           0 :         return "";
      84             :     }
      85             : 
      86             :     static bool GetBucketAndObjectKey(const char *pszURI,
      87             :                                       const char *pszFSPrefix,
      88             :                                       bool bAllowNoObject,
      89             :                                       std::string &osBucketOut,
      90             :                                       std::string &osObjectKeyOut);
      91             : 
      92             :     static std::string BuildCanonicalizedHeaders(
      93             :         std::map<std::string, std::string> &oSortedMapHeaders,
      94             :         const struct curl_slist *psExistingHeaders,
      95             :         const char *pszHeaderPrefix);
      96             : 
      97             :     static std::string GetRFC822DateTime();
      98             : };
      99             : 
     100             : enum class AWSCredentialsSource
     101             : {
     102             :     UNINITIALIZED,
     103             :     NO_SIGN_REQUEST,
     104             :     REGULAR,       // credentials from env variables or ~/.aws/crediential
     105             :     EC2,           // credentials from EC2 private networking
     106             :     WEB_IDENTITY,  // credentials from Web Identity Token
     107             :                    // See
     108             :     // https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html
     109             :     ASSUMED_ROLE,  // credentials from an STS assumed role
     110             :     // See
     111             :     // https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html
     112             :     // and
     113             :     // https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
     114             :     SSO,  // credentials from Single-Sign On
     115             :     // credentials from credential_process command
     116             :     // See https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html
     117             :     CREDENTIAL_PROCESS,
     118             :     NASA_EARTHDATA,  // credentials from Nasa Earthdata login mechanism
     119             : };
     120             : 
     121             : class VSIS3HandleHelper final : public IVSIS3LikeHandleHelper
     122             : {
     123             :     CPL_DISALLOW_COPY_ASSIGN(VSIS3HandleHelper)
     124             : 
     125             :     std::string m_osURL{};
     126             :     std::string m_osService{};
     127             :     mutable std::string m_osSecretAccessKey{};
     128             :     mutable std::string m_osAccessKeyId{};
     129             :     mutable std::string m_osSessionToken{};
     130             :     std::string m_osS3SessionToken{};
     131             :     std::string m_osEndpoint{};
     132             :     std::string m_osRegion{};
     133             :     std::string m_osRequestPayer{};
     134             :     std::string m_osBucket{};
     135             :     std::string m_osObjectKey{};
     136             :     bool m_bUseHTTPS = false;
     137             :     bool m_bUseVirtualHosting = false;
     138             :     bool m_bIsDirectoryBucket = false;
     139             :     AWSCredentialsSource m_eCredentialsSource = AWSCredentialsSource::REGULAR;
     140             : 
     141             :     void RebuildURL() override;
     142             : 
     143             :     static bool GetOrRefreshTemporaryCredentialsForRole(
     144             :         bool bForceRefresh, std::string &osSecretAccessKey,
     145             :         std::string &osAccessKeyId, std::string &osSessionToken,
     146             :         std::string &osRegion);
     147             : 
     148             :     static bool GetOrRefreshTemporaryCredentialsForSSO(
     149             :         bool bForceRefresh, std::string &osSecretAccessKey,
     150             :         std::string &osAccessKeyId, std::string &osSessionToken,
     151             :         std::string &osRegion);
     152             : 
     153             :     static bool GetOrRefreshTemporaryCredentialsFromProcess(
     154             :         bool bForceRefresh, std::string &osSecretAccessKey,
     155             :         std::string &osAccessKeyId, std::string &osSessionToken);
     156             : 
     157             :     static bool GetConfigurationFromAssumeRoleWithWebIdentity(
     158             :         bool bForceRefresh, const std::string &osPathForOption,
     159             :         const std::string &osRoleArnIn,
     160             :         const std::string &osWebIdentityTokenFileIn,
     161             :         std::string &osSecretAccessKey, std::string &osAccessKeyId,
     162             :         std::string &osSessionToken);
     163             : 
     164             :     static bool GetConfigurationFromEC2(bool bForceRefresh,
     165             :                                         const std::string &osPathForOption,
     166             :                                         std::string &osSecretAccessKey,
     167             :                                         std::string &osAccessKeyId,
     168             :                                         std::string &osSessionToken);
     169             : 
     170             :     static bool GetConfigurationFromAWSConfigFiles(
     171             :         const std::string &osPathForOption, const char *pszProfile,
     172             :         std::string &osSecretAccessKey, std::string &osAccessKeyId,
     173             :         std::string &osSessionToken, std::string &osRegion,
     174             :         std::string &osCredentials, std::string &osRoleArn,
     175             :         std::string &osSourceProfile, std::string &osExternalId,
     176             :         std::string &osMFASerial, std::string &osRoleSessionName,
     177             :         std::string &osWebIdentityTokenFile, std::string &osSSOStartURL,
     178             :         std::string &osSSOAccountID, std::string &osSSORoleName,
     179             :         std::string &osSSOSession, std::string &osCredentialProcess);
     180             : 
     181             :     static bool GetConfiguration(const std::string &osPathForOption,
     182             :                                  CSLConstList papszOptions,
     183             :                                  std::string &osSecretAccessKey,
     184             :                                  std::string &osAccessKeyId,
     185             :                                  std::string &osSessionToken,
     186             :                                  std::string &osRegion,
     187             :                                  AWSCredentialsSource &eCredentialsSource);
     188             : 
     189             :     void RefreshCredentials(const std::string &osPathForOption,
     190             :                             bool bForceRefresh) const;
     191             : 
     192             :   protected:
     193             :   public:
     194             :     VSIS3HandleHelper(
     195             :         const std::string &osService, const std::string &osSecretAccessKey,
     196             :         const std::string &osAccessKeyId, const std::string &osSessionToken,
     197             :         const std::string &osS3SessionToken, const std::string &osEndpoint,
     198             :         const std::string &osRegion, const std::string &osRequestPayer,
     199             :         const std::string &osBucket, const std::string &osObjectKey,
     200             :         bool bUseHTTPS, bool bUseVirtualHosting,
     201             :         AWSCredentialsSource eCredentialsSource, bool bIsDirectoryBucket);
     202             :     ~VSIS3HandleHelper() override;
     203             : 
     204             :     static VSIS3HandleHelper *BuildFromURI(const char *pszURI,
     205             :                                            const char *pszFSPrefix,
     206             :                                            bool bAllowNoObject,
     207             :                                            CSLConstList papszOptions = nullptr);
     208             :     static std::string BuildURL(const std::string &osEndpoint,
     209             :                                 const std::string &osBucket,
     210             :                                 const std::string &osObjectKey, bool bUseHTTPS,
     211             :                                 bool bUseVirtualHosting);
     212             : 
     213             :     struct curl_slist *GetCurlHeaders(const std::string &osVerb,
     214             :                                       struct curl_slist *psHeaders,
     215             :                                       const void *pabyDataContent = nullptr,
     216             :                                       size_t nBytesContent = 0) const override;
     217             : 
     218         152 :     bool IsDirectoryBucket() const
     219             :     {
     220         152 :         return m_bIsDirectoryBucket;
     221             :     }
     222             : 
     223         188 :     bool AllowAutomaticRedirection() override
     224             :     {
     225         188 :         return false;
     226             :     }
     227             : 
     228             :     bool CanRestartOnError(const char *, const char *pszHeaders,
     229             :                            bool bSetError) override;
     230             : 
     231        1199 :     const std::string &GetURL() const override
     232             :     {
     233        1199 :         return m_osURL;
     234             :     }
     235             : 
     236        1016 :     const std::string &GetBucket() const
     237             :     {
     238        1016 :         return m_osBucket;
     239             :     }
     240             : 
     241           0 :     const std::string &GetObjectKey() const
     242             :     {
     243           0 :         return m_osObjectKey;
     244             :     }
     245             : 
     246          16 :     const std::string &GetEndpoint() const
     247             :     {
     248          16 :         return m_osEndpoint;
     249             :     }
     250             : 
     251          16 :     const std::string &GetRegion() const
     252             :     {
     253          16 :         return m_osRegion;
     254             :     }
     255             : 
     256             :     const std::string &GetAccessKeyId() const
     257             :     {
     258             :         return m_osAccessKeyId;
     259             :     }
     260             : 
     261             :     const std::string &GetSecretAccessKey() const
     262             :     {
     263             :         return m_osSecretAccessKey;
     264             :     }
     265             : 
     266             :     const std::string &GetSessionToken() const
     267             :     {
     268             :         return m_osSessionToken;
     269             :     }
     270             : 
     271             :     AWSCredentialsSource GetCredentialsSource() const
     272             :     {
     273             :         return m_eCredentialsSource;
     274             :     }
     275             : 
     276          16 :     const std::string &GetRequestPayer() const
     277             :     {
     278          16 :         return m_osRequestPayer;
     279             :     }
     280             : 
     281          16 :     bool GetVirtualHosting() const
     282             :     {
     283          16 :         return m_bUseVirtualHosting;
     284             :     }
     285             : 
     286             :     bool GetUseHTTPS() const
     287             :     {
     288             :         return m_bUseHTTPS;
     289             :     }
     290             : 
     291             :     void SetEndpoint(const std::string &osStr);
     292             :     void SetRegion(const std::string &osStr);
     293             :     void SetRequestPayer(const std::string &osStr);
     294             :     void SetVirtualHosting(bool b);
     295             : 
     296           5 :     std::string GetCopySourceHeader() const override
     297             :     {
     298           5 :         return "x-amz-copy-source";
     299             :     }
     300             : 
     301           3 :     const char *GetMetadataDirectiveREPLACE() const override
     302             :     {
     303           3 :         return "x-amz-metadata-directive: REPLACE";
     304             :     }
     305             : 
     306             :     std::string GetSignedURL(CSLConstList papszOptions);
     307             : 
     308             :     static void CleanMutex();
     309             :     static void ClearCache();
     310             : };
     311             : 
     312             : class VSIS3UpdateParams
     313             : {
     314             :   private:
     315             :     std::string m_osRegion{};
     316             :     std::string m_osEndpoint{};
     317             :     std::string m_osRequestPayer{};
     318             :     bool m_bUseVirtualHosting = false;
     319             : 
     320          16 :     explicit VSIS3UpdateParams(const VSIS3HandleHelper *poHelper)
     321          16 :         : m_osRegion(poHelper->GetRegion()),
     322          16 :           m_osEndpoint(poHelper->GetEndpoint()),
     323          16 :           m_osRequestPayer(poHelper->GetRequestPayer()),
     324          16 :           m_bUseVirtualHosting(poHelper->GetVirtualHosting())
     325             :     {
     326          16 :     }
     327             : 
     328         113 :     void UpdateHandlerHelper(VSIS3HandleHelper *poHelper)
     329             :     {
     330         113 :         poHelper->SetRegion(m_osRegion);
     331         113 :         poHelper->SetEndpoint(m_osEndpoint);
     332         113 :         poHelper->SetRequestPayer(m_osRequestPayer);
     333         113 :         poHelper->SetVirtualHosting(m_bUseVirtualHosting);
     334         113 :     }
     335             : 
     336             :     static std::mutex gsMutex;
     337             :     static std::map<std::string, VSIS3UpdateParams> goMapBucketsToS3Params;
     338             : 
     339             :   public:
     340          11 :     VSIS3UpdateParams() = default;
     341             : 
     342             :     static void UpdateMapFromHandle(VSIS3HandleHelper *poS3HandleHelper);
     343             :     static void UpdateHandleFromMap(VSIS3HandleHelper *poS3HandleHelper);
     344             :     static void ClearCache();
     345             : };
     346             : 
     347             : #endif /* HAVE_CURL */
     348             : 
     349             : #endif /* #ifndef DOXYGEN_SKIP */
     350             : 
     351             : #endif /* CPL_AWS_INCLUDED_H */

Generated by: LCOV version 1.14