mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 386: Automatic upload of keys pairs + Public key can be displayed in Advanced Site Settings dialog
https://winscp.net/tracker/386 Source commit: 78d8baba92c09728ef3bccc9b49f1590a76d4ca5
This commit is contained in:
@@ -81,6 +81,7 @@ public:
|
||||
const TRemoteFile * File, UnicodeString Command, int Params, TCaptureOutputEvent OutputEvent) = 0;
|
||||
virtual void __fastcall DoStartup() = 0;
|
||||
virtual void __fastcall HomeDirectory() = 0;
|
||||
virtual UnicodeString __fastcall GetHomeDirectory() { throw Exception(L"Not implemented"); };
|
||||
virtual bool __fastcall IsCapable(int Capability) const = 0;
|
||||
virtual void __fastcall LookupUsersGroups() = 0;
|
||||
virtual void __fastcall ReadCurrentDirectory() = 0;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "CoreMain.h"
|
||||
#include "TextsCore.h"
|
||||
#include <StrUtils.hpp>
|
||||
#include <Soap.EncdDecd.hpp>
|
||||
//---------------------------------------------------------------------------
|
||||
char sshver[50];
|
||||
extern const char commitid[] = "";
|
||||
@@ -686,6 +687,49 @@ void FreeKey(TPrivateKey * PrivateKey)
|
||||
sfree(Ssh2Key);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
RawByteString LoadPublicKey(const UnicodeString & FileName, UnicodeString & Algorithm, UnicodeString & Comment)
|
||||
{
|
||||
RawByteString Result;
|
||||
UTF8String UtfFileName = UTF8String(FileName);
|
||||
Filename * KeyFile = filename_from_str(UtfFileName.c_str());
|
||||
try
|
||||
{
|
||||
char * AlgorithmStr = NULL;
|
||||
int PublicKeyLen = 0;
|
||||
char * CommentStr = NULL;
|
||||
const char * ErrorStr = NULL;
|
||||
unsigned char * PublicKeyPtr =
|
||||
ssh2_userkey_loadpub(KeyFile, &AlgorithmStr, &PublicKeyLen, &CommentStr, &ErrorStr);
|
||||
if (PublicKeyPtr == NULL)
|
||||
{
|
||||
UnicodeString Error = UnicodeString(AnsiString(ErrorStr));
|
||||
throw Exception(Error);
|
||||
}
|
||||
Algorithm = UnicodeString(AnsiString(AlgorithmStr));
|
||||
sfree(AlgorithmStr);
|
||||
Comment = UnicodeString(AnsiString(CommentStr));
|
||||
sfree(CommentStr);
|
||||
Result = RawByteString(reinterpret_cast<char *>(PublicKeyPtr), PublicKeyLen);
|
||||
free(PublicKeyPtr);
|
||||
}
|
||||
__finally
|
||||
{
|
||||
filename_free(KeyFile);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
UnicodeString GetPublicKeyLine(const UnicodeString & FileName, UnicodeString & Comment)
|
||||
{
|
||||
UnicodeString Algorithm;
|
||||
RawByteString PublicKey = LoadPublicKey(FileName, Algorithm, Comment);
|
||||
UnicodeString PublicKeyBase64 = EncodeBase64(PublicKey.c_str(), PublicKey.Length());
|
||||
PublicKeyBase64 = ReplaceStr(PublicKeyBase64, L"\r", L"");
|
||||
PublicKeyBase64 = ReplaceStr(PublicKeyBase64, L"\n", L"");
|
||||
UnicodeString Result = FORMAT(L"%s %s %s", (Algorithm, PublicKeyBase64, Comment));
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall HasGSSAPI(UnicodeString CustomPath)
|
||||
{
|
||||
static int has = -1;
|
||||
@@ -879,4 +923,13 @@ UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType)
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool IsOpenSSH(const UnicodeString & SshImplementation)
|
||||
{
|
||||
return
|
||||
// e.g. "OpenSSH_5.3"
|
||||
(SshImplementation.Pos(L"OpenSSH") == 1) ||
|
||||
// Sun SSH is based on OpenSSH (suffers the same bugs)
|
||||
(SshImplementation.Pos(L"Sun_SSH") == 1);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -17,6 +17,7 @@ void ChangeKeyComment(TPrivateKey * PrivateKey, const UnicodeString & Comment);
|
||||
void SaveKey(TKeyType KeyType, const UnicodeString & FileName,
|
||||
const UnicodeString & Passphrase, TPrivateKey * PrivateKey);
|
||||
void FreeKey(TPrivateKey * PrivateKey);
|
||||
UnicodeString GetPublicKeyLine(const UnicodeString & FileName, UnicodeString & Comment);
|
||||
extern const UnicodeString PuttyKeyExt;
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall HasGSSAPI(UnicodeString CustomPath);
|
||||
@@ -37,4 +38,6 @@ UnicodeString __fastcall ParseOpenSshPubLine(const UnicodeString & Line, const s
|
||||
//---------------------------------------------------------------------------
|
||||
UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType);
|
||||
//---------------------------------------------------------------------------
|
||||
bool IsOpenSSH(const UnicodeString & SshImplementation);
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -455,10 +455,7 @@ void __fastcall TSecureShell::Open()
|
||||
FOpened = true;
|
||||
|
||||
UnicodeString SshImplementation = GetSessionInfo().SshImplementation;
|
||||
if (// e.g. "OpenSSH_5.3"
|
||||
(SshImplementation.Pos(L"OpenSSH") == 1) ||
|
||||
// Sun SSH is based on OpenSSH (suffers the same bugs)
|
||||
(SshImplementation.Pos(L"Sun_SSH") == 1))
|
||||
if (IsOpenSSH(SshImplementation))
|
||||
{
|
||||
FSshImplementation = sshiOpenSSH;
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ bool __fastcall TSessionData::IsSame(const TSessionData * Default, bool Advanced
|
||||
return IsSame(Default, AdvancedOnly, NULL);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
static TFSProtocol NormalizeFSProtocol(TFSProtocol FSProtocol)
|
||||
TFSProtocol NormalizeFSProtocol(TFSProtocol FSProtocol)
|
||||
{
|
||||
if ((FSProtocol == fsSCPonly) || (FSProtocol == fsSFTPonly))
|
||||
{
|
||||
|
||||
@@ -711,5 +711,6 @@ bool __fastcall IsSshProtocol(TFSProtocol FSProtocol);
|
||||
int __fastcall DefaultPort(TFSProtocol FSProtocol, TFtps Ftps);
|
||||
bool __fastcall IsIPv6Literal(const UnicodeString & HostName);
|
||||
UnicodeString __fastcall EscapeIPv6Literal(const UnicodeString & IP);
|
||||
TFSProtocol NormalizeFSProtocol(TFSProtocol FSProtocol);
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
const TRemoteFile * File, UnicodeString Command, int Params, TCaptureOutputEvent OutputEvent);
|
||||
virtual void __fastcall DoStartup();
|
||||
virtual void __fastcall HomeDirectory();
|
||||
virtual UnicodeString __fastcall GetHomeDirectory();
|
||||
virtual bool __fastcall IsCapable(int Capability) const;
|
||||
virtual void __fastcall LookupUsersGroups();
|
||||
virtual void __fastcall ReadCurrentDirectory();
|
||||
@@ -132,7 +133,6 @@ protected:
|
||||
TRemoteFile *& File, unsigned char Type, TRemoteFile * ALinkedByFile = NULL,
|
||||
int AllowStatus = -1);
|
||||
virtual UnicodeString __fastcall GetCurrentDirectory();
|
||||
UnicodeString __fastcall GetHomeDirectory();
|
||||
unsigned long __fastcall GotStatusPacket(TSFTPPacket * Packet, int AllowStatus);
|
||||
bool __fastcall RemoteFileExists(const UnicodeString FullPath, TRemoteFile ** File = NULL);
|
||||
TRemoteFile * __fastcall LoadFile(TSFTPPacket * Packet,
|
||||
|
||||
@@ -4681,6 +4681,11 @@ void __fastcall TTerminal::HomeDirectory()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
UnicodeString __fastcall TTerminal::GetHomeDirectory()
|
||||
{
|
||||
return FFileSystem->GetHomeDirectory();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminal::ChangeDirectory(const UnicodeString Directory)
|
||||
{
|
||||
DebugAssert(FFileSystem);
|
||||
|
||||
@@ -500,6 +500,7 @@ public:
|
||||
void __fastcall ChangeDirectory(const UnicodeString Directory);
|
||||
void __fastcall EndTransaction();
|
||||
void __fastcall HomeDirectory();
|
||||
UnicodeString __fastcall GetHomeDirectory();
|
||||
void __fastcall ChangeFileProperties(UnicodeString FileName,
|
||||
const TRemoteFile * File, /*const TRemoteProperties */ void * Properties);
|
||||
void __fastcall ChangeFilesProperties(TStrings * FileList,
|
||||
|
||||
@@ -9486,6 +9486,19 @@ void __fastcall TCustomScpExplorerForm::ChangePassword()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::CanPrivateKeyUpload()
|
||||
{
|
||||
// No nice way to assert SSH2
|
||||
return (Terminal != NULL) && Terminal->Active && (Terminal->FSProtocol == cfsSFTP);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::PrivateKeyUpload()
|
||||
{
|
||||
TOperationVisualizer OperationVisualizer;
|
||||
UnicodeString FileName = Terminal->SessionData->PublicKeyFile;
|
||||
TTerminalManager::Instance()->UploadPublicKey(Terminal, NULL, FileName);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::ChangeScale(int M, int D)
|
||||
{
|
||||
TForm::ChangeScale(M, D);
|
||||
|
||||
@@ -717,6 +717,8 @@ public:
|
||||
bool __fastcall CanConsole();
|
||||
bool __fastcall CanChangePassword();
|
||||
void __fastcall ChangePassword();
|
||||
bool __fastcall CanPrivateKeyUpload();
|
||||
void __fastcall PrivateKeyUpload();
|
||||
bool __fastcall IsComponentPossible(Byte Component);
|
||||
|
||||
__property bool ComponentVisible[Byte Component] = { read = GetComponentVisible, write = SetComponentVisible };
|
||||
|
||||
@@ -417,6 +417,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
|
||||
UPD(NewFileAction, DirViewEnabled(osCurrent) && !WinConfiguration->DisableOpenEdit)
|
||||
UPD(EditorListCustomizeAction, true)
|
||||
UPD(ChangePasswordAction, ScpExplorer->CanChangePassword())
|
||||
UPD(PrivateKeyUploadAction, ScpExplorer->CanPrivateKeyUpload())
|
||||
|
||||
// CUSTOM COMMANDS
|
||||
UPD(CustomCommandsFileAction, true)
|
||||
@@ -730,6 +731,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
|
||||
EXE(NewFileAction, ScpExplorer->EditNew(osCurrent))
|
||||
EXE(EditorListCustomizeAction, PreferencesDialog(pmEditor))
|
||||
EXE(ChangePasswordAction, ScpExplorer->ChangePassword())
|
||||
EXE(PrivateKeyUploadAction, ScpExplorer->PrivateKeyUpload())
|
||||
|
||||
// CUSTOM COMMANDS
|
||||
EXE(CustomCommandsFileAction, CreateCustomCommandsMenu(CustomCommandsFileAction, ccltFile))
|
||||
|
||||
@@ -2208,6 +2208,13 @@ object NonVisualDataModule: TNonVisualDataModule
|
||||
HelpKeyword = 'task_change_password'
|
||||
Hint = 'Change account password'
|
||||
end
|
||||
object PrivateKeyUploadAction: TAction
|
||||
Tag = 15
|
||||
Category = 'Session'
|
||||
Caption = '&Install Public Key into Server...'
|
||||
HelpKeyword = 'guide_public_key'
|
||||
Hint = 'Install public key for authentication into the server'
|
||||
end
|
||||
object RemoteNewFileAction: TAction
|
||||
Tag = 15
|
||||
Category = 'Remote Selected Operation'
|
||||
|
||||
@@ -615,6 +615,7 @@ __published: // IDE-managed Components
|
||||
TTBXSubmenuItem *TBXSubmenuItem4;
|
||||
TTBXSubmenuItem *TBXSubmenuItem6;
|
||||
TTBXSubmenuItem *TBXSubmenuItem9;
|
||||
TAction *PrivateKeyUploadAction;
|
||||
void __fastcall ExplorerActionsUpdate(TBasicAction *Action, bool &Handled);
|
||||
void __fastcall ExplorerActionsExecute(TBasicAction *Action, bool &Handled);
|
||||
void __fastcall SessionIdleTimerTimer(TObject *Sender);
|
||||
|
||||
@@ -429,6 +429,9 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
object TBXItem227: TTBXItem
|
||||
Action = NonVisualDataModule.ChangePasswordAction
|
||||
end
|
||||
object TBXItem76: TTBXItem
|
||||
Action = NonVisualDataModule.PrivateKeyUploadAction
|
||||
end
|
||||
object TBXSeparatorItem29: TTBXSeparatorItem
|
||||
end
|
||||
object TBXSubmenuItem21: TTBXSubmenuItem
|
||||
|
||||
@@ -423,6 +423,7 @@ __published:
|
||||
TTBXItem *TBXItem248;
|
||||
TTBXItem *TBXItem249;
|
||||
TTBXItem *TBXItem250;
|
||||
TTBXItem *TBXItem76;
|
||||
void __fastcall SplitterMoved(TObject *Sender);
|
||||
void __fastcall SplitterCanResize(TObject *Sender, int &NewSize,
|
||||
bool &Accept);
|
||||
|
||||
@@ -305,6 +305,9 @@ inherited ScpExplorerForm: TScpExplorerForm
|
||||
object TBXItem160: TTBXItem
|
||||
Action = NonVisualDataModule.ChangePasswordAction
|
||||
end
|
||||
object TBXItem14: TTBXItem
|
||||
Action = NonVisualDataModule.ChangePasswordAction
|
||||
end
|
||||
object TBXSeparatorItem29: TTBXSeparatorItem
|
||||
end
|
||||
object TBXSubmenuItem21: TTBXSubmenuItem
|
||||
|
||||
@@ -313,6 +313,7 @@ __published:
|
||||
TTBXItem *TBXItem247;
|
||||
TTBXItem *TBXItem244;
|
||||
TTBXItem *TBXItem246;
|
||||
TTBXItem *TBXItem14;
|
||||
void __fastcall RemoteDirViewUpdateStatusBar(TObject *Sender,
|
||||
const TStatusFileInfo &FileInfo);
|
||||
void __fastcall UnixPathComboBoxBeginEdit(TTBEditItem *Sender,
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "Tools.h"
|
||||
#include "WinConfiguration.h"
|
||||
#include "PuttyTools.h"
|
||||
#include "TerminalManager.h"
|
||||
#include "Authenticate.h"
|
||||
//---------------------------------------------------------------------
|
||||
#pragma link "ComboEdit"
|
||||
#pragma link "PasswordEdit"
|
||||
@@ -105,8 +107,7 @@ void __fastcall TSiteAdvancedDialog::InitControls()
|
||||
SelectScaledImageList(ColorImageList);
|
||||
SetSessionColor((TColor)0);
|
||||
|
||||
UnicodeString Dummy;
|
||||
PrivateKeyGenerateButton->Enabled = FindTool(PuttygenTool, Dummy);
|
||||
MenuButton(PrivateKeyToolsButton);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::LoadSession()
|
||||
@@ -752,8 +753,7 @@ void __fastcall TSiteAdvancedDialog::UpdateControls()
|
||||
TAutoNestingCounter NoUpdateCounter(NoUpdate);
|
||||
|
||||
bool SshProtocol = FSessionData->UsesSsh;
|
||||
bool SftpProtocol =
|
||||
(FSessionData->FSProtocol == fsSFTPonly) || (FSessionData->FSProtocol == fsSFTP);
|
||||
bool SftpProtocol = (NormalizeFSProtocol(FSessionData->FSProtocol) == fsSFTP);
|
||||
bool ScpProtocol = (FSessionData->FSProtocol == fsSCPonly);
|
||||
bool FtpProtocol = (FSessionData->FSProtocol == fsFTP);
|
||||
bool WebDavProtocol = (FSessionData->FSProtocol == fsWebDAV);
|
||||
@@ -794,6 +794,7 @@ void __fastcall TSiteAdvancedDialog::UpdateControls()
|
||||
((AuthTISCheck->Enabled && AuthTISCheck->Checked) ||
|
||||
(AuthKICheck->Enabled && AuthKICheck->Checked)));
|
||||
EnableControl(AuthenticationParamsGroup, AuthenticationGroup->Enabled);
|
||||
EnableControl(PrivateKeyViewButton, PrivateKeyEdit3->Enabled && !PrivateKeyEdit3->Text.IsEmpty());
|
||||
EnableControl(AuthGSSAPICheck3,
|
||||
AuthenticationGroup->Enabled && (GetSshProt() == ssh2only));
|
||||
EnableControl(GSSAPIFwdTGTCheck,
|
||||
@@ -1255,7 +1256,7 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyEdit3AfterDialog(TObject * Sender
|
||||
TFilenameEdit * Edit = dynamic_cast<TFilenameEdit *>(Sender);
|
||||
if (Name != Edit->Text)
|
||||
{
|
||||
VerifyAndConvertKey(Name, GetSshProt());
|
||||
VerifyAndConvertKey(Name, GetSshProt(), true);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -1521,14 +1522,61 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyCreatedOrModified(TObject * /*Sen
|
||||
{
|
||||
if (SameText(ExtractFileExt(FileName), FORMAT(L".%s", (PuttyKeyExt))))
|
||||
{
|
||||
PrivateKeyEdit3->FileName = FileName;
|
||||
PrivateKeyEdit3->Text = FileName;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::PrivateKeyGenerateButtonClick(TObject * /*Sender*/)
|
||||
void __fastcall TSiteAdvancedDialog::PrivateKeyToolsButtonClick(TObject * /*Sender*/)
|
||||
{
|
||||
UnicodeString Dummy;
|
||||
PrivateKeyGenerateItem->Enabled = FindTool(PuttygenTool, Dummy);
|
||||
PrivateKeyUploadItem->Enabled = (GetSshProt() == ssh2only) && (NormalizeFSProtocol(FSessionData->FSProtocol) == fsSFTP);
|
||||
MenuPopup(PrivateKeyMenu, PrivateKeyToolsButton);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::PrivateKeyGenerateItemClick(TObject * /*Sender*/)
|
||||
{
|
||||
unsigned int Filters = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
FPrivateKeyMonitors.reset(StartCreationDirectoryMonitorsOnEachDrive(Filters, PrivateKeyCreatedOrModified));
|
||||
ExecuteTool(PuttygenTool);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::PrivateKeyUploadItemClick(TObject * /*Sender*/)
|
||||
{
|
||||
SaveSession();
|
||||
FSessionData->FSProtocol = fsSFTPonly; // no SCP fallback, as SCP does not implement GetHomeDirectory
|
||||
FSessionData->RemoteDirectory = UnicodeString();
|
||||
|
||||
UnicodeString FileName = PrivateKeyEdit3->Text;
|
||||
if (TTerminalManager::Instance()->UploadPublicKey(NULL, FSessionData, FileName))
|
||||
{
|
||||
PrivateKeyEdit3->Text = FileName;
|
||||
PrivateKeyEdit3->SetFocus();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::PrivateKeyViewButtonClick(TObject * /*Sender*/)
|
||||
{
|
||||
UnicodeString FileName = PrivateKeyEdit3->Text;
|
||||
VerifyAndConvertKey(FileName, GetSshProt(), false);
|
||||
PrivateKeyEdit3->Text = FileName;
|
||||
UnicodeString CommentDummy;
|
||||
UnicodeString Line = GetPublicKeyLine(FileName, CommentDummy);
|
||||
std::unique_ptr<TStrings> Messages(TextToStringList(Line));
|
||||
|
||||
TClipboardHandler ClipboardHandler;
|
||||
ClipboardHandler.Text = Line;
|
||||
|
||||
TMessageParams Params;
|
||||
TQueryButtonAlias Aliases[1];
|
||||
Aliases[0].Button = qaRetry;
|
||||
Aliases[0].Alias = LoadStr(COPY_KEY_BUTTON);
|
||||
Aliases[0].OnSubmit = &ClipboardHandler.Copy;
|
||||
Params.Aliases = Aliases;
|
||||
Params.AliasesCount = LENOF(Aliases);
|
||||
|
||||
UnicodeString Message = LoadStr(LOGIN_AUTHORIZED_KEYS);
|
||||
int Answers = qaOK | qaRetry;
|
||||
MoreMessageDialog(Message, Messages.get(), qtInformation, Answers, HELP_LOGIN_AUTHORIZED_KEYS, &Params);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -2048,15 +2048,23 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
|
||||
Text = 'PrivateKeyEdit3'
|
||||
OnChange = DataChange
|
||||
end
|
||||
object PrivateKeyGenerateButton: TButton
|
||||
Left = 12
|
||||
object PrivateKeyToolsButton: TButton
|
||||
Left = 151
|
||||
Top = 86
|
||||
Width = 101
|
||||
Height = 25
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Ge&nerate...'
|
||||
Caption = '&Tools'
|
||||
TabOrder = 2
|
||||
OnClick = PrivateKeyGenerateButtonClick
|
||||
OnClick = PrivateKeyToolsButtonClick
|
||||
end
|
||||
object PrivateKeyViewButton: TButton
|
||||
Left = 12
|
||||
Top = 86
|
||||
Width = 133
|
||||
Height = 25
|
||||
Caption = '&Display Public Key'
|
||||
TabOrder = 3
|
||||
OnClick = PrivateKeyViewButtonClick
|
||||
end
|
||||
end
|
||||
object GSSAPIGroup: TGroupBox
|
||||
@@ -3662,4 +3670,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
|
||||
FFFFFFFF00000000000000000000000000000000000000000000000000000000
|
||||
000000000000}
|
||||
end
|
||||
object PrivateKeyMenu: TPopupMenu
|
||||
Left = 128
|
||||
Top = 384
|
||||
object PrivateKeyGenerateItem: TMenuItem
|
||||
Caption = '&Generate New Key Pair with PuTTYgen...'
|
||||
OnClick = PrivateKeyGenerateItemClick
|
||||
end
|
||||
object PrivateKeyUploadItem: TMenuItem
|
||||
Caption = '&Install Public Key into Server...'
|
||||
OnClick = PrivateKeyUploadItemClick
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -257,7 +257,11 @@ __published:
|
||||
TImageList *ColorImageList120;
|
||||
TImageList *ColorImageList144;
|
||||
TImageList *ColorImageList192;
|
||||
TButton *PrivateKeyGenerateButton;
|
||||
TButton *PrivateKeyToolsButton;
|
||||
TPopupMenu *PrivateKeyMenu;
|
||||
TMenuItem *PrivateKeyGenerateItem;
|
||||
TMenuItem *PrivateKeyUploadItem;
|
||||
TButton *PrivateKeyViewButton;
|
||||
void __fastcall DataChange(TObject *Sender);
|
||||
void __fastcall FormShow(TObject *Sender);
|
||||
void __fastcall PageControlChange(TObject *Sender);
|
||||
@@ -290,7 +294,10 @@ __published:
|
||||
void __fastcall NoteMemoKeyDown(TObject *Sender, WORD &Key, TShiftState Shift);
|
||||
void __fastcall TlsCertificateFileEditAfterDialog(TObject *Sender, UnicodeString &Name,
|
||||
bool &Action);
|
||||
void __fastcall PrivateKeyGenerateButtonClick(TObject *Sender);
|
||||
void __fastcall PrivateKeyUploadItemClick(TObject *Sender);
|
||||
void __fastcall PrivateKeyGenerateItemClick(TObject *Sender);
|
||||
void __fastcall PrivateKeyToolsButtonClick(TObject *Sender);
|
||||
void __fastcall PrivateKeyViewButtonClick(TObject *Sender);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@@ -60,5 +60,6 @@
|
||||
#define HELP_EXTENSION_OPTIONS "ui_pref_commands"
|
||||
#define HELP_CHANGE_PASSWORD "task_change_password"
|
||||
#define HELP_FILTER "ui_filter"
|
||||
#define HELP_LOGIN_AUTHORIZED_KEYS "guide_public_key"
|
||||
|
||||
#endif // TextsWin
|
||||
|
||||
@@ -598,6 +598,13 @@
|
||||
#define PREFERENCES_DRAGEXT_NOT_INSTALLED 6000
|
||||
#define PREFERENCES_DRAGEXT_NOT_RUNNING 6001
|
||||
#define PREFERENCES_DRAGEXT_RUNNING 6002
|
||||
#define LOGIN_AUTHORIZED_KEYS 6003
|
||||
#define LOGIN_NOT_OPENSSH 6004
|
||||
#define LOGIN_PUBLIC_KEY_UPLOAD 6005
|
||||
#define LOGIN_PUBLIC_KEY_UPLOADED 6006
|
||||
#define LOGIN_PUBLIC_KEY_PERMISSIONS 6007
|
||||
#define LOGIN_PUBLIC_KEY_TITLE 6008
|
||||
#define LOGIN_PUBLIC_KEY_FILTER 6009
|
||||
|
||||
// 2xxx is reserved for TextsFileZilla.h
|
||||
|
||||
|
||||
@@ -601,6 +601,13 @@ BEGIN
|
||||
PREFERENCES_DRAGEXT_NOT_INSTALLED, "Shell extension is not installed."
|
||||
PREFERENCES_DRAGEXT_NOT_RUNNING, "Shell extension is installed, but is not loaded."
|
||||
PREFERENCES_DRAGEXT_RUNNING, "Shell extension is installed and loaded."
|
||||
LOGIN_AUTHORIZED_KEYS, "**Public key for pasting into OpenSSH authorized_keys file:**"
|
||||
LOGIN_NOT_OPENSSH, "**Install public key to non-OpenSSH server?**\n\nInstalling public key is supported for OpenSSH server only (authorized_keys file).\n\nYour server is %s."
|
||||
LOGIN_PUBLIC_KEY_UPLOAD, "Installing public key \"%s\"..."
|
||||
LOGIN_PUBLIC_KEY_UPLOADED, "**Public key \"%s\" was installed.**\n\nYou can now login to the server using the key pair."
|
||||
LOGIN_PUBLIC_KEY_PERMISSIONS, "Though potentially wrong permissions of \"%s\" file and/or its parent folder were detected. Please check them."
|
||||
LOGIN_PUBLIC_KEY_TITLE, "Select key to install into server"
|
||||
LOGIN_PUBLIC_KEY_FILTER, "PuTTY Private Key Files (*.ppk)|*.ppk|All Private Key Files (*.ppk;*.pem;*.key;id_*)|*.ppk;*.pem;*.key;id_*|All Files (*.*)|*.*"
|
||||
|
||||
WIN_VARIABLE_STRINGS, "WIN_VARIABLE"
|
||||
WINSCP_COPYRIGHT, "Copyright © 2000-2018 Martin Prikryl"
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <Exceptions.h>
|
||||
#include <VCLCommon.h>
|
||||
#include <WinApi.h>
|
||||
#include <PuttyTools.h>
|
||||
#include <HelpWin.h>
|
||||
#include <System.IOUtils.hpp>
|
||||
#include <StrUtils.hpp>
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -72,6 +76,7 @@ __fastcall TTerminalManager::TTerminalManager() :
|
||||
FMainThread = GetCurrentThreadId();
|
||||
FChangeSection.reset(new TCriticalSection());
|
||||
FPendingConfigurationChange = 0;
|
||||
FKeepAuthenticateForm = false;
|
||||
|
||||
FApplicationsEvents.reset(new TApplicationEvents(Application));
|
||||
FApplicationsEvents->OnException = ApplicationException;
|
||||
@@ -116,7 +121,7 @@ __fastcall TTerminalManager::~TTerminalManager()
|
||||
delete FQueues;
|
||||
delete FTerminationMessages;
|
||||
delete FTerminalList;
|
||||
delete FAuthenticateForm;
|
||||
CloseAutheticateForm();
|
||||
delete FQueueSection;
|
||||
ReleaseTaskbarList();
|
||||
}
|
||||
@@ -218,7 +223,7 @@ void __fastcall TTerminalManager::FreeActiveTerminal()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminalManager::DoConnectTerminal(TTerminal * Terminal, bool Reopen)
|
||||
void __fastcall TTerminalManager::DoConnectTerminal(TTerminal * Terminal, bool Reopen, bool AdHoc)
|
||||
{
|
||||
TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
|
||||
// it must be managed terminal, unless it is secondary terminal (of managed terminal)
|
||||
@@ -263,22 +268,21 @@ void __fastcall TTerminalManager::DoConnectTerminal(TTerminal * Terminal, bool R
|
||||
__finally
|
||||
{
|
||||
TerminalThread->OnIdle = NULL;
|
||||
if (!TerminalThread->Release() && (DebugAlwaysTrue(Terminal == FActiveTerminal)))
|
||||
if (!TerminalThread->Release())
|
||||
{
|
||||
// terminal was abandoned, must create a new one to replace it
|
||||
Terminal = CreateTerminal(new TSessionData(L""));
|
||||
SetupTerminal(Terminal);
|
||||
OwnsObjects = false;
|
||||
Items[ActiveTerminalIndex] = Terminal;
|
||||
OwnsObjects = true;
|
||||
FActiveTerminal = Terminal;
|
||||
if (!AdHoc && (DebugAlwaysTrue(Terminal == FActiveTerminal)))
|
||||
{
|
||||
// terminal was abandoned, must create a new one to replace it
|
||||
Terminal = CreateTerminal(new TSessionData(L""));
|
||||
SetupTerminal(Terminal);
|
||||
OwnsObjects = false;
|
||||
Items[ActiveTerminalIndex] = Terminal;
|
||||
OwnsObjects = true;
|
||||
FActiveTerminal = Terminal;
|
||||
}
|
||||
|
||||
// when abandoning cancelled terminal, the form remains open
|
||||
if (FAuthenticateForm != NULL)
|
||||
{
|
||||
delete FAuthenticateForm;
|
||||
FAuthenticateForm = NULL;
|
||||
}
|
||||
CloseAutheticateForm();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -299,6 +303,11 @@ void __fastcall TTerminalManager::DoConnectTerminal(TTerminal * Terminal, bool R
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminalManager::CloseAutheticateForm()
|
||||
{
|
||||
SAFE_DESTROY(FAuthenticateForm);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TTerminalManager::ConnectTerminal(TTerminal * Terminal)
|
||||
{
|
||||
bool Result = true;
|
||||
@@ -306,7 +315,7 @@ bool __fastcall TTerminalManager::ConnectTerminal(TTerminal * Terminal)
|
||||
DebugAssert(Terminal != FActiveTerminal);
|
||||
try
|
||||
{
|
||||
DoConnectTerminal(Terminal, false);
|
||||
DoConnectTerminal(Terminal, false, false);
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
@@ -333,7 +342,7 @@ bool __fastcall TTerminalManager::ConnectActiveTerminalImpl(bool Reopen)
|
||||
{
|
||||
DebugAssert(ActiveTerminal);
|
||||
|
||||
DoConnectTerminal(ActiveTerminal, Reopen);
|
||||
DoConnectTerminal(ActiveTerminal, Reopen, false);
|
||||
|
||||
if (ScpExplorer)
|
||||
{
|
||||
@@ -1124,7 +1133,10 @@ void __fastcall TTerminalManager::TerminalInformation(
|
||||
BusyEnd(FBusyToken);
|
||||
FBusyToken = NULL;
|
||||
}
|
||||
SAFE_DESTROY(FAuthenticateForm);
|
||||
if (!FKeepAuthenticateForm)
|
||||
{
|
||||
CloseAutheticateForm();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1570,3 +1582,222 @@ TTerminalQueue * __fastcall TTerminalManager::FindQueueForTerminal(TTerminal * T
|
||||
int Index = IndexOf(Terminal);
|
||||
return reinterpret_cast<TTerminalQueue *>(FQueues->Items[Index]);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TRemoteFile * __fastcall TTerminalManager::CheckRights(
|
||||
TTerminal * Terminal, const UnicodeString & EntryType, const UnicodeString & FileName, bool & WrongRights)
|
||||
{
|
||||
std::unique_ptr<TRemoteFile> FileOwner;
|
||||
TRemoteFile * File;
|
||||
try
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"Checking %s \"%s\"...", (LowerCase(EntryType), FileName)));
|
||||
Terminal->ReadFile(FileName, File);
|
||||
FileOwner.reset(File);
|
||||
int ForbiddenRights = TRights::rfGroupWrite | TRights::rfOtherWrite;
|
||||
if ((File->Rights->Number & ForbiddenRights) != 0)
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"%s \"%s\" exists, but has incorrect permissions %s.", (EntryType, FileName, File->Rights->Octal)));
|
||||
WrongRights = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"%s \"%s\" exists and has correct permissions %s.", (EntryType, FileName, File->Rights->Octal)));
|
||||
}
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
}
|
||||
return FileOwner.release();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TTerminalManager::UploadPublicKey(
|
||||
TTerminal * Terminal, TSessionData * Data, UnicodeString & FileName)
|
||||
{
|
||||
std::unique_ptr<TOpenDialog> OpenDialog(new TOpenDialog(Application));
|
||||
OpenDialog->Title = LoadStr(LOGIN_PUBLIC_KEY_TITLE);
|
||||
OpenDialog->Filter = LoadStr(LOGIN_PUBLIC_KEY_FILTER);
|
||||
OpenDialog->DefaultExt = PuttyKeyExt;
|
||||
OpenDialog->FileName = FileName;
|
||||
|
||||
bool Result = OpenDialog->Execute();
|
||||
if (Result)
|
||||
{
|
||||
Configuration->Usage->Inc(L"PublicKeyInstallation");
|
||||
FileName = OpenDialog->FileName;
|
||||
|
||||
bool AutoReadDirectory;
|
||||
bool ExceptionOnFail;
|
||||
UnicodeString TemporaryDir;
|
||||
|
||||
bool WrongRights = false;
|
||||
const UnicodeString SshFolder = L".ssh";
|
||||
const UnicodeString AuthorizedKeysFile = L"authorized_keys";
|
||||
UnicodeString AuthorizedKeysFilePath = FORMAT(L"%s/%s", (SshFolder, AuthorizedKeysFile));
|
||||
|
||||
VerifyAndConvertKey(FileName, ssh2only, false);
|
||||
|
||||
UnicodeString Comment;
|
||||
UnicodeString Line = GetPublicKeyLine(FileName, Comment);
|
||||
|
||||
bool AdHocTerminal = (Terminal == NULL);
|
||||
std::unique_ptr<TTerminal> TerminalOwner;
|
||||
if (AdHocTerminal)
|
||||
{
|
||||
DebugAssert(Data != NULL);
|
||||
|
||||
TAutoFlag KeepAuthenticateFormFlag(FKeepAuthenticateForm);
|
||||
try
|
||||
{
|
||||
TerminalOwner.reset(CreateTerminal(Data));
|
||||
Terminal = TerminalOwner.get();
|
||||
SetupTerminal(Terminal);
|
||||
Terminal->OnProgress = NULL;
|
||||
Terminal->OnFinished = NULL;
|
||||
DoConnectTerminal(Terminal, false, true);
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
CloseAutheticateForm();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
AutoReadDirectory = Terminal->AutoReadDirectory;
|
||||
ExceptionOnFail = Terminal->ExceptionOnFail;
|
||||
|
||||
try
|
||||
{
|
||||
Terminal->AutoReadDirectory = false;
|
||||
Terminal->ExceptionOnFail = true;
|
||||
|
||||
UnicodeString SshImplementation = Terminal->GetSessionInfo().SshImplementation;
|
||||
UnicodeString NotOpenSSHMessage = FMTLOAD(LOGIN_NOT_OPENSSH, (SshImplementation));
|
||||
if (IsOpenSSH(SshImplementation) ||
|
||||
(MessageDialog(NotOpenSSHMessage, qtConfirmation, qaOK | qaCancel, HELP_LOGIN_AUTHORIZED_KEYS) == qaOK))
|
||||
{
|
||||
Terminal->Log->AddSeparator();
|
||||
Terminal->LogEvent(FORMAT(L"Adding public key line to \"%s\" file:\n%s", (AuthorizedKeysFilePath, Line)));
|
||||
|
||||
// Ad-hoc terminal
|
||||
if (FAuthenticateForm != NULL)
|
||||
{
|
||||
FAuthenticateForm->Log(FMTLOAD(LOGIN_PUBLIC_KEY_UPLOAD, (Comment)));
|
||||
}
|
||||
|
||||
UnicodeString SshFolderAbsolutePath = UnixIncludeTrailingBackslash(Terminal->GetHomeDirectory()) + SshFolder;
|
||||
std::unique_ptr<TRemoteFile> SshFolderFile(CheckRights(Terminal, L"Folder", SshFolderAbsolutePath, WrongRights));
|
||||
if (SshFolderFile.get() == NULL)
|
||||
{
|
||||
TRights SshFolderRights;
|
||||
SshFolderRights.Number = TRights::rfUserRead | TRights::rfUserWrite | TRights::rfUserExec;
|
||||
TRemoteProperties SshFolderProperties;
|
||||
SshFolderProperties.Rights = SshFolderRights;
|
||||
SshFolderProperties.Valid = TValidProperties() << vpRights;
|
||||
|
||||
Terminal->LogEvent(FORMAT(L"Trying to create \"%s\" folder with permissions %s...", (SshFolder, SshFolderRights.Octal)));
|
||||
Terminal->CreateDirectory(SshFolderAbsolutePath, &SshFolderProperties);
|
||||
}
|
||||
|
||||
TemporaryDir = ExcludeTrailingBackslash(WinConfiguration->TemporaryDir());
|
||||
if (!ForceDirectories(ApiPath(TemporaryDir)))
|
||||
{
|
||||
throw EOSExtException(FMTLOAD(CREATE_TEMP_DIR_ERROR, (TemporaryDir)));
|
||||
}
|
||||
UnicodeString TemporaryAuthorizedKeysFile = IncludeTrailingBackslash(TemporaryDir) + AuthorizedKeysFile;
|
||||
|
||||
UnicodeString AuthorizedKeysFileAbsolutePath = UnixIncludeTrailingBackslash(SshFolderAbsolutePath) + AuthorizedKeysFile;
|
||||
|
||||
bool Updated = true;
|
||||
TCopyParamType CopyParam; // Use factory defaults
|
||||
CopyParam.ResumeSupport = rsOff; // not to break the permissions
|
||||
CopyParam.PreserveTime = false; // not needed
|
||||
|
||||
UnicodeString AuthorizedKeys;
|
||||
std::unique_ptr<TRemoteFile> AuthorizedKeysFileFile(CheckRights(Terminal, L"File", AuthorizedKeysFileAbsolutePath, WrongRights));
|
||||
if (AuthorizedKeysFileFile.get() != NULL)
|
||||
{
|
||||
AuthorizedKeysFileFile->FullFileName = AuthorizedKeysFileAbsolutePath;
|
||||
std::unique_ptr<TStrings> Files(new TStringList());
|
||||
Files->AddObject(AuthorizedKeysFileAbsolutePath, AuthorizedKeysFileFile.get());
|
||||
Terminal->LogEvent(FORMAT(L"Downloading current \"%s\" file...", (AuthorizedKeysFile)));
|
||||
Terminal->CopyToLocal(Files.get(), TemporaryDir, &CopyParam, cpNoConfirmation, NULL);
|
||||
// Overload with Encoding parameter work incorrectly, when used on a file without BOM
|
||||
AuthorizedKeys = TFile::ReadAllText(TemporaryAuthorizedKeysFile);
|
||||
|
||||
std::unique_ptr<TStrings> AuthorizedKeysLines(TextToStringList(AuthorizedKeys));
|
||||
int P = Line.Pos(L" ");
|
||||
if (DebugAlwaysTrue(P > 0))
|
||||
{
|
||||
P = PosEx(L" ", Line, P + 1);
|
||||
}
|
||||
UnicodeString Prefix = Line.SubString(1, P); // including the space
|
||||
for (int Index = 0; Index < AuthorizedKeysLines->Count; Index++)
|
||||
{
|
||||
if (StartsStr(Prefix, AuthorizedKeysLines->Strings[Index]))
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"\"%s\" file already contains public key line:\n%s", (AuthorizedKeysFile, AuthorizedKeysLines->Strings[Index])));
|
||||
Updated = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Updated)
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"\"%s\" file does not contain the public key line yet.", (AuthorizedKeysFile)));
|
||||
if (!EndsStr(L"\n", AuthorizedKeys))
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"Adding missing trailing new line to \"%s\" file...", (AuthorizedKeysFile)));
|
||||
AuthorizedKeys += L"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"Creating new \"%s\" file...", (AuthorizedKeysFile)));
|
||||
CopyParam.PreserveRights = true;
|
||||
CopyParam.Rights.Number = TRights::rfUserRead | TRights::rfUserWrite;
|
||||
}
|
||||
|
||||
if (Updated)
|
||||
{
|
||||
AuthorizedKeys += Line + L"\n";
|
||||
// Overload without Encoding parameter uses TEncoding::UTF8, but does not write BOM, what we want
|
||||
TFile::WriteAllText(TemporaryAuthorizedKeysFile, AuthorizedKeys);
|
||||
std::unique_ptr<TStrings> Files(new TStringList());
|
||||
Files->Add(TemporaryAuthorizedKeysFile);
|
||||
Terminal->LogEvent(FORMAT(L"Uploading updated \"%s\" file...", (AuthorizedKeysFile)));
|
||||
Terminal->CopyToRemote(Files.get(), SshFolderAbsolutePath, &CopyParam, cpNoConfirmation, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
Terminal->AutoReadDirectory = AutoReadDirectory;
|
||||
Terminal->ExceptionOnFail = ExceptionOnFail;
|
||||
if (!TemporaryDir.IsEmpty())
|
||||
{
|
||||
RecursiveDeleteFile(ExcludeTrailingBackslash(TemporaryDir), false);
|
||||
}
|
||||
CloseAutheticateForm(); // When uploading from Login dialog
|
||||
}
|
||||
|
||||
Terminal->LogEvent(L"Public key installation done.");
|
||||
if (AdHocTerminal)
|
||||
{
|
||||
TerminalOwner.reset(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Terminal->Log->AddSeparator();
|
||||
}
|
||||
|
||||
UnicodeString Message = FMTLOAD(LOGIN_PUBLIC_KEY_UPLOADED, (Comment));
|
||||
if (WrongRights)
|
||||
{
|
||||
Message += L"\n\n" + FMTLOAD(LOGIN_PUBLIC_KEY_PERMISSIONS, (AuthorizedKeysFilePath));
|
||||
}
|
||||
|
||||
MessageDialog(Message, qtInformation, qaOK, HELP_LOGIN_AUTHORIZED_KEYS);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
TTerminal * __fastcall FindActiveTerminalForSite(TSessionData * Data);
|
||||
TTerminalQueue * __fastcall FindQueueForTerminal(TTerminal * Terminal);
|
||||
void __fastcall UpdateSessionCredentials(TSessionData * Data);
|
||||
void __fastcall DoConnectTerminal(TTerminal * Terminal, bool Reopen);
|
||||
bool __fastcall UploadPublicKey(TTerminal * Terminal, TSessionData * Data, UnicodeString & FileName);
|
||||
|
||||
__property TCustomScpExplorerForm * ScpExplorer = { read = FScpExplorer, write = SetScpExplorer };
|
||||
__property TTerminal * ActiveTerminal = { read = FActiveTerminal, write = SetActiveTerminal };
|
||||
@@ -76,6 +76,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual TTerminal * __fastcall CreateTerminal(TSessionData * Data);
|
||||
void __fastcall DoConnectTerminal(TTerminal * Terminal, bool Reopen, bool AdHoc);
|
||||
|
||||
private:
|
||||
static TTerminalManager * FInstance;
|
||||
@@ -104,6 +105,7 @@ private:
|
||||
void * FBusyToken;
|
||||
bool FAuthenticationCancelled;
|
||||
std::unique_ptr<TApplicationEvents> FApplicationsEvents;
|
||||
bool FKeepAuthenticateForm;
|
||||
|
||||
bool __fastcall ConnectActiveTerminalImpl(bool Reopen);
|
||||
bool __fastcall ConnectActiveTerminal();
|
||||
@@ -166,6 +168,9 @@ private:
|
||||
void __fastcall DoConfigurationChange();
|
||||
bool __fastcall ShouldDisplayQueueStatusOnAppTitle();
|
||||
void __fastcall SetupTerminal(TTerminal * Terminal);
|
||||
void __fastcall CloseAutheticateForm();
|
||||
TRemoteFile * __fastcall CheckRights(
|
||||
TTerminal * Terminal, const UnicodeString & EntryType, const UnicodeString & FileName, bool & WrongRights);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -1162,7 +1162,7 @@ static void __fastcall ConvertKey(UnicodeString & FileName, TKeyType Type)
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static void __fastcall DoVerifyKey(
|
||||
UnicodeString & FileName, TSshProt SshProt, bool Convert)
|
||||
UnicodeString & FileName, TSshProt SshProt, bool Convert, bool CanIgnore)
|
||||
{
|
||||
if (!FileName.Trim().IsEmpty())
|
||||
{
|
||||
@@ -1242,8 +1242,8 @@ static void __fastcall DoVerifyKey(
|
||||
if (!Message.IsEmpty())
|
||||
{
|
||||
Configuration->Usage->Inc(L"PrivateKeySelectErrors");
|
||||
if (MoreMessageDialog(Message, MoreMessages.get(), qtWarning, qaIgnore | qaAbort,
|
||||
HelpKeyword) == qaAbort)
|
||||
unsigned int Answers = (CanIgnore ? (qaIgnore | qaAbort) : qaOK);
|
||||
if (MoreMessageDialog(Message, MoreMessages.get(), qtWarning, Answers, HelpKeyword) != qaIgnore)
|
||||
{
|
||||
Abort();
|
||||
}
|
||||
@@ -1251,14 +1251,14 @@ static void __fastcall DoVerifyKey(
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt)
|
||||
void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt, bool CanIgnore)
|
||||
{
|
||||
DoVerifyKey(FileName, SshProt, true);
|
||||
DoVerifyKey(FileName, SshProt, true, CanIgnore);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall VerifyKey(UnicodeString FileName, TSshProt SshProt)
|
||||
{
|
||||
DoVerifyKey(FileName, SshProt, false);
|
||||
DoVerifyKey(FileName, SshProt, false, true);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall VerifyCertificate(const UnicodeString & FileName)
|
||||
|
||||
@@ -68,7 +68,7 @@ void __fastcall CopyToClipboard(TStrings * Strings);
|
||||
void __fastcall ShutDownWindows();
|
||||
void __fastcall SuspendWindows();
|
||||
void __fastcall EditSelectBaseName(HWND Edit);
|
||||
void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt);
|
||||
void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt, bool CanIgnore);
|
||||
void __fastcall VerifyKey(UnicodeString FileName, TSshProt SshProt);
|
||||
void __fastcall VerifyCertificate(const UnicodeString & FileName);
|
||||
TStrings * __fastcall GetUnwrappedMemoLines(TMemo * Memo);
|
||||
|
||||
Reference in New Issue
Block a user