Explorar el Código

Bug 1839: Support for authentication using temporary credentials from AWS Security Token Service (STS)

https://winscp.net/tracker/1839

Source commit: 42a774881e2a5d649f6e3012ac2e2d948eacd5d8
Martin Prikryl hace 5 años
padre
commit
0c14ec6da3

+ 7 - 3
source/core/S3FileSystem.cpp

@@ -113,6 +113,9 @@ void __fastcall TS3FileSystem::Open()
   }
   FSecretAccessKey = UTF8String(SecretAccessKey);
 
+  FSecurityTokenBuf = UTF8String(Data->S3SessionToken);
+  FSecurityToken = static_cast<const char *>(FSecurityTokenBuf.data());
+
   FHostName = UTF8String(Data->HostNameExpanded);
   FPortSuffix = UTF8String();
   int ADefaultPort = DefaultPort(FTerminal->SessionData->FSProtocol, FTerminal->SessionData->Ftps);
@@ -519,7 +522,7 @@ TLibS3BucketContext TS3FileSystem::GetBucketContext(const UnicodeString & Bucket
     Result.uriStyle = UriStyle;
     Result.accessKeyId = FAccessKeyId.c_str();
     Result.secretAccessKey = FSecretAccessKey.c_str();
-    Result.securityToken = NULL;
+    Result.securityToken = FSecurityToken;
     Result.AuthRegionBuf = UTF8String(Region);
     Result.authRegion = Result.AuthRegionBuf.c_str();
 
@@ -879,7 +882,7 @@ void TS3FileSystem::ReadDirectoryInternal(
       Retry = false;
 
       S3_list_service(
-        FLibS3Protocol, FAccessKeyId.c_str(), FSecretAccessKey.c_str(), 0, (FHostName + FPortSuffix).c_str(),
+        FLibS3Protocol, FAccessKeyId.c_str(), FSecretAccessKey.c_str(), FSecurityToken, (FHostName + FPortSuffix).c_str(),
         StrToS3(FAuthRegion), MaxKeys, FRequestContext, FTimeout, &ListServiceHandler, &Data);
 
       HandleNonBucketStatus(Data, Retry);
@@ -1101,7 +1104,8 @@ void __fastcall TS3FileSystem::CreateDirectory(const UnicodeString & ADirName, b
       Retry = false;
 
       S3_create_bucket(
-        FLibS3Protocol, FAccessKeyId.c_str(), FSecretAccessKey.c_str(), NULL, (FHostName + FPortSuffix).c_str(), StrToS3(BucketName),
+        FLibS3Protocol, FAccessKeyId.c_str(), FSecretAccessKey.c_str(), FSecurityToken,
+        (FHostName + FPortSuffix).c_str(), StrToS3(BucketName),
         StrToS3(FAuthRegion), S3CannedAclPrivate, Region, FRequestContext, FTimeout, &ResponseHandler, &Data);
 
       HandleNonBucketStatus(Data, Retry);

+ 2 - 0
source/core/S3FileSystem.h

@@ -115,6 +115,8 @@ protected:
   TSessionInfo FSessionInfo;
   UTF8String FAccessKeyId;
   UTF8String FSecretAccessKey;
+  UTF8String FSecurityTokenBuf;
+  const char * FSecurityToken;
   UTF8String FHostName;
   UTF8String FPortSuffix;
   int FTimeout;

+ 9 - 0
source/core/SessionData.cpp

@@ -233,6 +233,7 @@ void __fastcall TSessionData::DefaultSettings()
   NotUtf = asAuto;
 
   S3DefaultRegion = L"";
+  S3SessionToken = L"";
   S3UrlStyle = s3usVirtualHost;
 
   // SFTP
@@ -390,6 +391,7 @@ void __fastcall TSessionData::NonPersistant()
   PROPERTY(PostLoginCommands); \
   \
   PROPERTY(S3DefaultRegion); \
+  PROPERTY(S3SessionToken); \
   PROPERTY(S3UrlStyle); \
   \
   PROPERTY(ProxyMethod); \
@@ -721,6 +723,7 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   InternalEditorEncoding = Storage->ReadInteger(L"InternalEditorEncoding", InternalEditorEncoding);
 
   S3DefaultRegion = Storage->ReadString(L"S3DefaultRegion", S3DefaultRegion);
+  S3SessionToken = Storage->ReadString(L"S3SessionToken", S3SessionToken);
   S3UrlStyle = (TS3UrlStyle)Storage->ReadInteger(L"S3UrlStyle", S3UrlStyle);
 
   // PuTTY defaults to TcpNoDelay, but the psftp/pscp ignores this preference, and always set this to off (what is our default too)
@@ -1100,6 +1103,7 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
     WRITE_DATA_EX(Integer, L"Utf", NotUtf, );
     WRITE_DATA(Integer, InternalEditorEncoding);
     WRITE_DATA(String, S3DefaultRegion);
+    WRITE_DATA(String, S3SessionToken);
     WRITE_DATA(Integer, S3UrlStyle);
     WRITE_DATA(Integer, SendBuf);
     WRITE_DATA(String, SourceAddress);
@@ -4069,6 +4073,11 @@ void __fastcall TSessionData::SetS3DefaultRegion(UnicodeString value)
   SET_SESSION_PROPERTY(S3DefaultRegion);
 }
 //---------------------------------------------------------------------
+void __fastcall TSessionData::SetS3SessionToken(UnicodeString value)
+{
+  SET_SESSION_PROPERTY(S3SessionToken);
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::SetS3UrlStyle(TS3UrlStyle value)
 {
   SET_SESSION_PROPERTY(S3UrlStyle);

+ 3 - 0
source/core/SessionData.h

@@ -221,6 +221,7 @@ private:
   TAutoSwitch FNotUtf;
   int FInternalEditorEncoding;
   UnicodeString FS3DefaultRegion;
+  UnicodeString FS3SessionToken;
   TS3UrlStyle FS3UrlStyle;
   bool FIsWorkspace;
   UnicodeString FLink;
@@ -400,6 +401,7 @@ private:
   void __fastcall SetNotUtf(TAutoSwitch value);
   void __fastcall SetInternalEditorEncoding(int value);
   void __fastcall SetS3DefaultRegion(UnicodeString value);
+  void __fastcall SetS3SessionToken(UnicodeString value);
   void __fastcall SetS3UrlStyle(TS3UrlStyle value);
   void __fastcall SetLogicalHostName(UnicodeString value);
   void __fastcall SetIsWorkspace(bool value);
@@ -663,6 +665,7 @@ public:
   __property TAutoSwitch NotUtf = { read = FNotUtf, write = SetNotUtf };
   __property int InternalEditorEncoding = { read = FInternalEditorEncoding, write = SetInternalEditorEncoding };
   __property UnicodeString S3DefaultRegion = { read = FS3DefaultRegion, write = SetS3DefaultRegion };
+  __property UnicodeString S3SessionToken = { read = FS3SessionToken, write = SetS3SessionToken };
   __property TS3UrlStyle S3UrlStyle = { read = FS3UrlStyle, write = SetS3UrlStyle };
   __property bool IsWorkspace = { read = FIsWorkspace, write = SetIsWorkspace };
   __property UnicodeString Link = { read = FLink, write = SetLink };

+ 4 - 0
source/core/SessionInfo.cpp

@@ -1365,6 +1365,10 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
       {
         ADF(L"S3: Default region: %s", (Data->S3DefaultRegion));
       }
+      if (!Data->S3SessionToken.IsEmpty())
+      {
+        ADF(L"S3: Session token: %s", (Data->S3SessionToken));
+      }
     }
     if (FtpsOn)
     {

+ 3 - 0
source/forms/SiteAdvanced.cpp

@@ -223,6 +223,7 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     {
       S3UrlStyleCombo->ItemIndex = 0;
     }
+    S3SessionTokenMemo->Lines->Text = FSessionData->S3SessionToken;
 
     // Authentication page
     SshNoUserAuthCheck->Checked = FSessionData->SshNoUserAuth;
@@ -633,6 +634,8 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
   {
     SessionData->S3UrlStyle = s3usVirtualHost;
   }
+  // Trim not to try to authenticate with a stray new-line
+  SessionData->S3SessionToken = S3SessionTokenMemo->Lines->Text.Trim();
 
   // Proxy page
   SessionData->ProxyMethod = GetProxyMethod();

+ 30 - 0
source/forms/SiteAdvanced.dfm

@@ -1067,6 +1067,36 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
               'Path')
           end
         end
+        object S3AuthenticationGroup: TGroupBox
+          Left = 1
+          Top = 82
+          Width = 393
+          Height = 143
+          Anchors = [akLeft, akTop, akRight]
+          Caption = 'Authentication'
+          TabOrder = 1
+          DesignSize = (
+            393
+            143)
+          object Label5: TLabel
+            Left = 12
+            Top = 20
+            Width = 73
+            Height = 13
+            Caption = '&Security token:'
+          end
+          object S3SessionTokenMemo: TMemo
+            Left = 11
+            Top = 36
+            Width = 371
+            Height = 93
+            Anchors = [akLeft, akTop, akRight, akBottom]
+            MaxLength = 10000
+            TabOrder = 0
+            OnChange = DataChange
+            OnKeyDown = NoteMemoKeyDown
+          end
+        end
       end
       object WebDavSheet: TTabSheet
         Tag = 2

+ 3 - 0
source/forms/SiteAdvanced.h

@@ -284,6 +284,9 @@ __published:
   TTabSheet *WebDavSheet;
   TGroupBox *WebdavGroup;
   TCheckBox *WebDavLiberalEscapingCheck;
+  TGroupBox *S3AuthenticationGroup;
+  TLabel *Label5;
+  TMemo *S3SessionTokenMemo;
   void __fastcall DataChange(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
   void __fastcall PageControlChange(TObject *Sender);