1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

Raw site settings editor

Source commit: caf055e335fef5e08a1685b4fb7a52986f3043cf
This commit is contained in:
Martin Prikryl
2019-08-07 09:07:51 +00:00
parent db52308b89
commit 177f67ba48
10 changed files with 231 additions and 22 deletions

View File

@@ -116,7 +116,7 @@ TSessionData * __fastcall TSessionData::Clone()
return Data.release();
}
//---------------------------------------------------------------------
void __fastcall TSessionData::Default()
void __fastcall TSessionData::DefaultSettings()
{
HostName = L"";
PortNumber = SshPortNumber;
@@ -275,6 +275,11 @@ void __fastcall TSessionData::Default()
CustomParam1 = L"";
CustomParam2 = L"";
}
//---------------------------------------------------------------------
void __fastcall TSessionData::Default()
{
DefaultSettings();
IsWorkspace = false;
Link = L"";
@@ -1176,7 +1181,12 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
WRITE_DATA(String, CustomParam2);
}
SavePasswords(Storage, PuttyExport, DoNotEncryptPasswords);
// This is for collecting all keys for TSiteRawDialog::AddButtonClick.
// It should be enough to test for (Default == NULL),
// the DoNotEncryptPasswords and PuttyExport were added to limit a possible unintended impact.
bool SaveAll = (Default == NULL) && DoNotEncryptPasswords && !PuttyExport;
SavePasswords(Storage, PuttyExport, DoNotEncryptPasswords, SaveAll);
}
//---------------------------------------------------------------------
TStrings * __fastcall TSessionData::SaveToOptions(const TSessionData * Default, bool SaveName)
@@ -1486,21 +1496,26 @@ void __fastcall TSessionData::ImportFromFilezilla(
}
//---------------------------------------------------------------------
void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool PuttyExport, bool DoNotEncryptPasswords)
void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool PuttyExport, bool DoNotEncryptPasswords, bool SaveAll)
{
if (!Configuration->DisablePasswordStoring && !PuttyExport && !FPassword.IsEmpty())
if (!Configuration->DisablePasswordStoring && !PuttyExport && (!FPassword.IsEmpty() || SaveAll))
{
// DoNotEncryptPasswords is set when called from GenerateOpenCommandArgs only
// and it never saves session password
DebugAssert(!DoNotEncryptPasswords);
Storage->WriteBinaryDataAsString(L"Password", StronglyRecryptPassword(FPassword, UserName+HostName));
if (DoNotEncryptPasswords)
{
Storage->WriteString(L"PasswordPlain", Password);
Storage->DeleteValue(L"Password");
}
else
{
Storage->WriteBinaryDataAsString(L"Password", StronglyRecryptPassword(FPassword, UserName+HostName));
Storage->DeleteValue(L"PasswordPlain");
}
}
else
{
Storage->DeleteValue(L"Password");
Storage->DeleteValue(L"PasswordPlain");
}
Storage->DeleteValue(L"PasswordPlain");
if (PuttyExport)
{
@@ -1511,7 +1526,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
{
if (DoNotEncryptPasswords)
{
if (!FProxyPassword.IsEmpty())
if (!FProxyPassword.IsEmpty() || SaveAll)
{
Storage->WriteString(L"ProxyPassword", ProxyPassword);
}
@@ -1524,7 +1539,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
else
{
// save password encrypted
if (!FProxyPassword.IsEmpty())
if (!FProxyPassword.IsEmpty() || SaveAll)
{
Storage->WriteBinaryDataAsString(L"ProxyPasswordEnc", StronglyRecryptPassword(FProxyPassword, ProxyUsername+ProxyHost));
}
@@ -1537,7 +1552,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
if (DoNotEncryptPasswords)
{
if (!FTunnelPassword.IsEmpty())
if (!FTunnelPassword.IsEmpty() || SaveAll)
{
Storage->WriteString(L"TunnelPasswordPlain", TunnelPassword);
}
@@ -1548,7 +1563,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
}
else
{
if (!Configuration->DisablePasswordStoring && !FTunnelPassword.IsEmpty())
if (!Configuration->DisablePasswordStoring && (!FTunnelPassword.IsEmpty() || SaveAll))
{
Storage->WriteBinaryDataAsString(L"TunnelPassword", StronglyRecryptPassword(FTunnelPassword, TunnelUserName+TunnelHostName));
}
@@ -1560,7 +1575,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
if (DoNotEncryptPasswords)
{
if (!FEncryptKey.IsEmpty())
if (!FEncryptKey.IsEmpty() || SaveAll)
{
Storage->WriteString(L"EncryptKeyPlain", EncryptKey);
}
@@ -1572,7 +1587,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
}
else
{
if (!FEncryptKey.IsEmpty())
if (!FEncryptKey.IsEmpty() || SaveAll)
{
Storage->WriteBinaryDataAsString(L"EncryptKey", StronglyRecryptPassword(FEncryptKey, UserName+HostName));
}
@@ -1664,7 +1679,7 @@ void __fastcall TSessionData::SaveRecryptedPasswords(THierarchicalStorage * Stor
{
RecryptPasswords();
SavePasswords(Storage, false, false);
SavePasswords(Storage, false, false, false);
}
__finally
{

View File

@@ -403,7 +403,7 @@ private:
void __fastcall SetEncryptKey(UnicodeString value);
TDateTime __fastcall GetTimeoutDT();
void __fastcall SavePasswords(THierarchicalStorage * Storage, bool PuttyExport, bool DoNotEncryptPasswords);
void __fastcall SavePasswords(THierarchicalStorage * Storage, bool PuttyExport, bool DoNotEncryptPasswords, bool SaveAll);
UnicodeString __fastcall GetLocalName();
UnicodeString __fastcall GetFolderName();
void __fastcall Modify();
@@ -444,8 +444,6 @@ private:
void __fastcall AddAssemblyProperty(
UnicodeString & Result, TAssemblyLanguage Language,
const UnicodeString & Name, bool Value);
TStrings * __fastcall SaveToOptions(const TSessionData * Default, bool SaveName);
void __fastcall ApplyRawSettings(TStrings * RawSettings);
TStrings * __fastcall GetRawSettingsForUrl();
void __fastcall DoCopyData(TSessionData * SourceData, bool NoRecrypt);
template<class AlgoT>
@@ -460,8 +458,10 @@ public:
virtual __fastcall ~TSessionData();
TSessionData * __fastcall Clone();
void __fastcall Default();
void __fastcall DefaultSettings();
void __fastcall NonPersistant();
void __fastcall Load(THierarchicalStorage * Storage, bool PuttyImport);
void __fastcall ApplyRawSettings(TStrings * RawSettings);
void __fastcall ApplyRawSettings(THierarchicalStorage * Storage);
void __fastcall ImportFromFilezilla(_di_IXMLNode Node, const UnicodeString & Path, _di_IXMLNode SettingsNode);
void __fastcall Save(THierarchicalStorage * Storage, bool PuttyExport,
@@ -483,6 +483,7 @@ public:
bool __fastcall ParseUrl(UnicodeString Url, TOptions * Options,
TStoredSessionList * StoredSessions, bool & DefaultsOnly,
UnicodeString * FileName, bool * AProtocolDefined, UnicodeString * MaskedUrl, int Flags);
TStrings * __fastcall SaveToOptions(const TSessionData * Default, bool SaveName);
void __fastcall ConfigureTunnel(int PortNumber);
void __fastcall RollbackTunnel();
void __fastcall ExpandEnvironmentVariables();

View File

@@ -1443,3 +1443,165 @@ void __fastcall DoUsageStatisticsDialog()
std::unique_ptr<TUsageStatisticsDialog> Dialog(new TUsageStatisticsDialog());
Dialog->Execute();
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class TSiteRawDialog : public TCustomDialog
{
public:
__fastcall TSiteRawDialog();
bool __fastcall Execute(TSessionData * Data);
protected:
// virtual void __fastcall DoChange(bool & CanSubmit);
private:
TMemo * SettingsMemo;
TButton * AdddButton;
void __fastcall AddButtonClick(TObject * Sender);
void __fastcall SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift);
void DeleteNames(TStrings * Names, TStrings * Options);
};
//---------------------------------------------------------------------------
__fastcall TSiteRawDialog::TSiteRawDialog() :
TCustomDialog(HELP_SITE_RAW)
{
Caption = LoadStr(SITE_RAW_CAPTION);
Width = ScaleByTextHeight(this, 400);
SettingsMemo = new TMemo(this);
SettingsMemo->Height = ScaleByTextHeight(this, 300);
SettingsMemo->OnKeyDown = SettingsMemoKeyDown;
AddEdit(SettingsMemo, NULL);
AdddButton = new TButton(this);
AdddButton->Caption = LoadStr(SITE_RAW_ADD);
AdddButton->Width = OKButton->Width;
AdddButton->OnClick = AddButtonClick;
AddDialogButton(AdddButton);
}
//---------------------------------------------------------------------------
bool __fastcall TSiteRawDialog::Execute(TSessionData * Data)
{
std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));
std::unique_ptr<TSessionData> RawData(new TSessionData(L""));
RawData->Assign(Data);
// SFTP-only is not reflected by the protocol prefix, we have to use rawsettings for that
if (RawData->FSProtocol != fsSFTPonly)
{
RawData->FSProtocol = FactoryDefaults->FSProtocol;
}
RawData->HostName = FactoryDefaults->HostName;
RawData->PortNumber = FactoryDefaults->PortNumber;
RawData->UserName = FactoryDefaults->UserName;
RawData->Password = FactoryDefaults->Password;
RawData->Ftps = FactoryDefaults->Ftps;
std::unique_ptr<TStrings> Options(RawData->SaveToOptions(FactoryDefaults.get(), false));
SettingsMemo->Lines = Options.get();
bool Result = TCustomDialog::Execute();
if (Result)
{
std::unique_ptr<TSessionData> BackupData(new TSessionData(L""));
BackupData->Assign(Data);
Data->DefaultSettings();
Data->FSProtocol = BackupData->FSProtocol;
Data->HostName = BackupData->HostName;
Data->PortNumber = BackupData->PortNumber;
Data->UserName = BackupData->UserName;
Data->Password = BackupData->Password;
Data->Ftps = BackupData->Ftps;
Data->ApplyRawSettings(SettingsMemo->Lines);
}
return Result;
}
//---------------------------------------------------------------------------
void __fastcall TSiteRawDialog::SettingsMemoKeyDown(TObject * Sender, WORD & Key, TShiftState Shift)
{
MemoKeyDown(Sender, Key, Shift);
}
//---------------------------------------------------------------------------
void __fastcall TSiteRawDialog::AddButtonClick(TObject *)
{
std::unique_ptr<TSessionData> FactoryDefaults(new TSessionData(L""));
std::unique_ptr<TSessionData> BasicData(new TSessionData(L""));
BasicData->FSProtocol = TFSProtocol(FactoryDefaults->FSProtocol + 1);
UnicodeString RandomAppendix(L"_");
BasicData->HostName = FactoryDefaults->HostName + RandomAppendix;
BasicData->Ftps = TFtps(FactoryDefaults->Ftps + 1);
BasicData->PortNumber = DefaultPort(BasicData->FSProtocol, BasicData->Ftps) + 1;
BasicData->UserName = FactoryDefaults->UserName + RandomAppendix;
BasicData->Password = FactoryDefaults->Password + RandomAppendix;
std::unique_ptr<TStrings> BasicOptions(BasicData->SaveToOptions(FactoryDefaults.get(), false));
std::unique_ptr<TStrings> AllOptions(FactoryDefaults->SaveToOptions(NULL, false));
std::unique_ptr<TStrings> Names(CreateSortedStringList());
for (int Index = 0; Index < AllOptions->Count; Index++)
{
Names->Add(AllOptions->Names[Index]);
}
DeleteNames(Names.get(), BasicOptions.get());
DeleteNames(Names.get(), SettingsMemo->Lines);
std::unique_ptr<TCustomDialog> AddDialog(new TCustomDialog(HelpKeyword));
AddDialog->Caption = LoadStr(SITE_RAW_ADD_CAPTION);
TComboBox * AddComboBox = new TComboBox(AddDialog.get());
AddComboBox->Style = csDropDownList;
AddComboBox->DropDownCount = Max(AddComboBox->DropDownCount, 16);
AddDialog->AddComboBox(AddComboBox, CreateLabel(LoadStr(SITE_RAW_ADD_LABEL)), Names.get(), true);
AddComboBox->ItemIndex = 0;
if (AddDialog->Execute())
{
UnicodeString Name = AddComboBox->Items->Strings[AddComboBox->ItemIndex];
UnicodeString Value = AllOptions->Values[Name];
UnicodeString NameAndSeparator = Name + SettingsMemo->Lines->NameValueSeparator;
int Start = (SettingsMemo->Lines->Text + NameAndSeparator).Length();
SettingsMemo->Lines->Add(NameAndSeparator + Value);
SettingsMemo->SetFocus();
SettingsMemo->SelStart = Start;
SettingsMemo->SelLength = Value.Length();
}
}
//---------------------------------------------------------------------------
void TSiteRawDialog::DeleteNames(TStrings * Names, TStrings * Options)
{
for (int Index = 0; Index < Options->Count; Index++)
{
UnicodeString Name = Options->Names[Index];
if (!Name.IsEmpty())
{
int I = Names->IndexOf(Name);
if (I >= 0)
{
Names->Delete(I);
}
}
}
}
//---------------------------------------------------------------------------
/*void __fastcall TUsageStatisticsDialog::DoChange(bool & CanSubmit)
{
TCustomDialog::DoChange(CanSubmit);
UnicodeString Text = Configuration->Usage->Serialize(L"\n", FilterEdit->Text);
bool NoUsage = Text.IsEmpty();
ClipboardButton->Enabled = !NoUsage;
if (NoUsage)
{
Text = LoadStr(USAGE_DATA_NONE2);
}
UsageMemo->Lines->Text = Text;
} */
//---------------------------------------------------------------------------
void __fastcall DoSiteRawDialog(TSessionData * Data)
{
std::unique_ptr<TSiteRawDialog> Dialog(new TSiteRawDialog());
Dialog->Execute(Data);
}

View File

@@ -1182,6 +1182,10 @@ void __fastcall TLoginDialog::ActionListUpdate(TBasicAction * BasicAction,
{
SessionAdvancedAction->Enabled = Editable;
}
else if (Action == SessionRawAction)
{
SessionRawAction->Enabled = Editable;
}
else if (Action == SaveAsSessionAction)
{
// Save as is needed for new site only when !SupportsSplitButton()
@@ -2773,7 +2777,7 @@ void __fastcall TLoginDialog::PersistNewSiteIfNeeded()
}
}
//---------------------------------------------------------------------------
void __fastcall TLoginDialog::SessionAdvancedActionExecute(TObject * /*Sender*/)
void __fastcall TLoginDialog::SessionAdvancedActionExecute(TObject * Sender)
{
// If we ever allow showing advanced settings, while read-only,
// we must make sure that FSessionData actually holds the advanced settings,
@@ -2789,7 +2793,14 @@ void __fastcall TLoginDialog::SessionAdvancedActionExecute(TObject * /*Sender*/)
ParseHostName();
SaveSession(FSessionData);
DoSiteAdvancedDialog(FSessionData);
if (Sender == SessionAdvancedAction)
{
DoSiteAdvancedDialog(FSessionData);
}
else
{
DoSiteRawDialog(FSessionData);
}
// Needed only for Note.
// The only other property visible on Login dialog that Advanced site dialog
// can change is protocol (between fsSFTP and fsSFTPonly),

View File

@@ -682,6 +682,11 @@ object LoginDialog: TLoginDialog
Caption = 'Close and Do Not Show Automatically Again'
OnExecute = NeverShowAgainActionExecute
end
object SessionRawAction: TAction
Category = 'Session'
Caption = 'Edit &Raw Settings...'
OnExecute = SessionAdvancedActionExecute
end
end
object ToolsPopupMenu: TPopupMenu
Left = 144
@@ -1387,6 +1392,9 @@ object LoginDialog: TLoginDialog
Action = SessionAdvancedAction
Default = True
end
object EditRawSettings1: TMenuItem
Action = SessionRawAction
end
object TransferSettingsRule1: TMenuItem
Action = CopyParamRuleAction
end

View File

@@ -211,6 +211,8 @@ __published:
TMenuItem *MenuItem20;
TAction *CloseAction;
TAction *NeverShowAgainAction;
TAction *SessionRawAction;
TMenuItem *EditRawSettings1;
void __fastcall DataChange(TObject *Sender);
void __fastcall FormShow(TObject *Sender);
void __fastcall SessionTreeDblClick(TObject *Sender);

View File

@@ -65,5 +65,6 @@
#define HELP_DD_TARGET_UNKNOWN "ui_pref_dragdrop#fake_file"
#define HELP_FILE_COLORS "ui_file_color"
#define HELP_AUTOMATIC_UPDATE "updates#automatic_upgrade"
#define HELP_SITE_RAW "ui_login_raw"
#endif // TextsWin

View File

@@ -620,6 +620,10 @@
#define UPDATES_DONATE_HTML 6020
#define EDITOR_NEW 6021
#define PREFERENCES_STATISTICS_CAPTION 6022
#define SITE_RAW_CAPTION 6023
#define SITE_RAW_ADD 6024
#define SITE_RAW_ADD_CAPTION 6025
#define SITE_RAW_ADD_LABEL 6026
// 2xxx is reserved for TextsFileZilla.h

View File

@@ -625,6 +625,10 @@ BEGIN
UPDATES_DONATE_HTML, "To enable automatic updates, please <a href=\"%DONATE_URL%\">donate to WinSCP development</a> or %GET_IMG% WinSCP from <a href=\"%STORE_URL%\">Microsoft Store</a>."
EDITOR_NEW, "New"
PREFERENCES_STATISTICS_CAPTION, "Statistics"
SITE_RAW_CAPTION, "Raw Site Settings"
SITE_RAW_ADD, "&Add..."
SITE_RAW_ADD_CAPTION, "Add Raw Site Setting"
SITE_RAW_ADD_LABEL, "&Site Setting:"
WIN_VARIABLE_STRINGS, "WIN_VARIABLE"
WINSCP_COPYRIGHT, "Copyright © 2000-2019 Martin Prikryl"

View File

@@ -150,6 +150,7 @@ bool __fastcall DoCustomCommandOptionsDialog(
const TCustomCommandType * Command, TStrings * CustomCommandOptions, TShortCut * ShortCut, unsigned int Flags,
TCustomCommand * CustomCommandForOptions, const UnicodeString & Site, const TShortCuts * ShortCuts);
void __fastcall DoUsageStatisticsDialog();
void __fastcall DoSiteRawDialog(TSessionData * Data);
// windows\UserInterface.cpp
bool __fastcall DoMasterPasswordDialog();