|
|
@@ -2468,11 +2468,13 @@ void TSecureShell::ParseFingerprint(const UnicodeString & Fingerprint, UnicodeSt
|
|
|
//---------------------------------------------------------------------------
|
|
|
void __fastcall TSecureShell::VerifyHostKey(
|
|
|
const UnicodeString & AHost, int Port, const UnicodeString & KeyType, const UnicodeString & KeyStr,
|
|
|
- const UnicodeString & AFingerprintSHA256, const UnicodeString & AFingerprintMD5)
|
|
|
+ const UnicodeString & AFingerprintSHA256, const UnicodeString & AFingerprintMD5,
|
|
|
+ bool IsCertificate, int CACount, bool AlreadyVerified)
|
|
|
{
|
|
|
if (Configuration->ActualLogProtocol >= 1)
|
|
|
{
|
|
|
- LogEvent(FORMAT(L"Verifying host key %s %s with fingerprints %s, %s", (KeyType, FormatKeyStr(KeyStr), AFingerprintSHA256, AFingerprintMD5)));
|
|
|
+ UnicodeString HostKeyAction = AlreadyVerified ? L"Got" : L"Verifying";
|
|
|
+ LogEvent(FORMAT(L"%s host key %s %s with fingerprints %s, %s", (HostKeyAction, KeyType, FormatKeyStr(KeyStr), AFingerprintSHA256, AFingerprintMD5)));
|
|
|
}
|
|
|
|
|
|
GotHostKey();
|
|
|
@@ -2507,257 +2509,299 @@ void __fastcall TSecureShell::VerifyHostKey(
|
|
|
Abort();
|
|
|
}
|
|
|
|
|
|
- bool AcceptNew = HaveAcceptNewHostKeyPolicy();
|
|
|
- UnicodeString ConfigHostKey;
|
|
|
- if (!AcceptNew)
|
|
|
+ if (!AlreadyVerified)
|
|
|
{
|
|
|
- ConfigHostKey = FSessionData->HostKey;
|
|
|
- }
|
|
|
-
|
|
|
- UnicodeString StoredKeys = RetrieveHostKey(Host, Port, KeyType);
|
|
|
- bool Result = VerifyCachedHostKey(StoredKeys, KeyStr, FingerprintMD5, FingerprintSHA256);
|
|
|
- if (!Result && AcceptNew)
|
|
|
- {
|
|
|
- if (!StoredKeys.IsEmpty()) // optimization + avoiding the log message
|
|
|
+ bool AcceptNew = HaveAcceptNewHostKeyPolicy();
|
|
|
+ UnicodeString ConfigHostKey;
|
|
|
+ if (!AcceptNew)
|
|
|
{
|
|
|
- AcceptNew = false;
|
|
|
+ ConfigHostKey = FSessionData->HostKey;
|
|
|
}
|
|
|
- else if (have_any_ssh2_hostkey(FSeat, AnsiString(Host).c_str(), Port))
|
|
|
- {
|
|
|
- LogEvent(L"Host key not found in the cache, but other key types found, cannot accept new key");
|
|
|
- AcceptNew = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- bool ConfiguredKeyNotMatch = false;
|
|
|
|
|
|
- if (!Result && !ConfigHostKey.IsEmpty() &&
|
|
|
- // Should test have_any_ssh2_hostkey + No need to bother with AcceptNew, as we never get here
|
|
|
- (StoredKeys.IsEmpty() || FSessionData->OverrideCachedHostKey))
|
|
|
- {
|
|
|
- UnicodeString Buf = ConfigHostKey;
|
|
|
- while (!Result && !Buf.IsEmpty())
|
|
|
+ UnicodeString StoredKeys = RetrieveHostKey(Host, Port, KeyType);
|
|
|
+ bool Result = VerifyCachedHostKey(StoredKeys, KeyStr, FingerprintMD5, FingerprintSHA256);
|
|
|
+ if (!Result && AcceptNew)
|
|
|
{
|
|
|
- UnicodeString ExpectedKey = CutToChar(Buf, HostKeyDelimiter, false);
|
|
|
- if (ExpectedKey == L"*")
|
|
|
+ if (!StoredKeys.IsEmpty()) // optimization + avoiding the log message
|
|
|
{
|
|
|
- UnicodeString Message = LoadStr(ANY_HOSTKEY);
|
|
|
- FUI->Information(Message, true);
|
|
|
- FLog->Add(llException, Message);
|
|
|
- Result = true;
|
|
|
+ AcceptNew = false;
|
|
|
}
|
|
|
- else if (VerifyFingerprint(ExpectedKey, FingerprintMD5, FingerprintSHA256))
|
|
|
+ else if (have_any_ssh2_hostkey(FSeat, AnsiString(Host).c_str(), Port))
|
|
|
{
|
|
|
- LogEvent(L"Host key matches configured key fingerprint");
|
|
|
- Result = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- LogEvent(FORMAT(L"Host key does not match configured key fingerprint %s", (ExpectedKey)));
|
|
|
+ LogEvent(L"Host key not found in the cache, but other key types found, cannot accept new key");
|
|
|
+ AcceptNew = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!Result)
|
|
|
- {
|
|
|
- ConfiguredKeyNotMatch = true;
|
|
|
- }
|
|
|
- }
|
|
|
+ bool ConfiguredKeyNotMatch = false;
|
|
|
|
|
|
- if (!Result && AcceptNew && DebugAlwaysTrue(ConfigHostKey.IsEmpty()))
|
|
|
- {
|
|
|
- try
|
|
|
+ if (!Result && !ConfigHostKey.IsEmpty() &&
|
|
|
+ // Should test have_any_ssh2_hostkey + No need to bother with AcceptNew, as we never get here
|
|
|
+ (StoredKeys.IsEmpty() || FSessionData->OverrideCachedHostKey))
|
|
|
{
|
|
|
- UnicodeString StorageSource = StoreHostKey(Host, Port, KeyType, KeyStr);
|
|
|
- UnicodeString StoredKeys = RetrieveHostKey(Host, Port, KeyType);
|
|
|
- if (StoredKeys != KeyStr)
|
|
|
+ UnicodeString Buf = ConfigHostKey;
|
|
|
+ while (!Result && !Buf.IsEmpty())
|
|
|
+ {
|
|
|
+ UnicodeString ExpectedKey = CutToChar(Buf, HostKeyDelimiter, false);
|
|
|
+ if (ExpectedKey == L"*")
|
|
|
+ {
|
|
|
+ UnicodeString Message = LoadStr(ANY_HOSTKEY);
|
|
|
+ FUI->Information(Message, true);
|
|
|
+ FLog->Add(llException, Message);
|
|
|
+ Result = true;
|
|
|
+ }
|
|
|
+ else if (VerifyFingerprint(ExpectedKey, FingerprintMD5, FingerprintSHA256))
|
|
|
+ {
|
|
|
+ LogEvent(L"Host key matches configured key fingerprint");
|
|
|
+ Result = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LogEvent(FORMAT(L"Host key does not match configured key fingerprint %s", (ExpectedKey)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!Result)
|
|
|
{
|
|
|
- throw Exception(UnicodeString());
|
|
|
+ ConfiguredKeyNotMatch = true;
|
|
|
}
|
|
|
- Configuration->Usage->Inc(L"HostKeyNewAccepted");
|
|
|
- LogEvent(FORMAT(L"Warning: Stored new host key to %s - This should occur only on the first connection", (StorageSource)));
|
|
|
- Result = true;
|
|
|
- }
|
|
|
- catch (Exception & E)
|
|
|
- {
|
|
|
- FUI->FatalError(&E, LoadStr(STORE_NEW_HOSTKEY_ERROR));
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (!Result)
|
|
|
- {
|
|
|
- bool Verified;
|
|
|
- if (ConfiguredKeyNotMatch || Configuration->DisableAcceptingHostKeys)
|
|
|
+ if (!Result && AcceptNew && DebugAlwaysTrue(ConfigHostKey.IsEmpty()))
|
|
|
{
|
|
|
- Verified = false;
|
|
|
- }
|
|
|
- // no point offering manual verification, if we cannot persist the verified key
|
|
|
- else if (!Configuration->Persistent && Configuration->Scripting)
|
|
|
- {
|
|
|
- Verified = false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // We should not offer caching if !Configuration->Persistent,
|
|
|
- // but as scripting mode is handled earlier and in GUI it hardly happens,
|
|
|
- // it's a small issue.
|
|
|
- TClipboardHandler ClipboardHandler;
|
|
|
- ClipboardHandler.Text = FingerprintSHA256 + L"\n" + FingerprintMD5;
|
|
|
- TPasteKeyHandler PasteKeyHandler;
|
|
|
- PasteKeyHandler.KeyStr = KeyStr;
|
|
|
- PasteKeyHandler.FingerprintMD5 = FingerprintMD5;
|
|
|
- PasteKeyHandler.FingerprintSHA256 = FingerprintSHA256;
|
|
|
- PasteKeyHandler.UI = FUI;
|
|
|
-
|
|
|
- bool Unknown = StoredKeys.IsEmpty();
|
|
|
-
|
|
|
- UnicodeString AcceptButton = LoadStr(HOSTKEY_ACCEPT_BUTTON);
|
|
|
- UnicodeString OnceButton = LoadStr(HOSTKEY_ONCE_BUTTON);
|
|
|
- UnicodeString CancelButton = Vcl_Consts_SMsgDlgCancel;
|
|
|
- UnicodeString UpdateButton = LoadStr(UPDATE_KEY_BUTTON);
|
|
|
- UnicodeString AddButton = LoadStr(ADD_KEY_BUTTON);
|
|
|
- int Answers;
|
|
|
- std::vector<TQueryButtonAlias> Aliases;
|
|
|
-
|
|
|
- TQueryButtonAlias CopyAlias;
|
|
|
- CopyAlias.Button = qaRetry;
|
|
|
- CopyAlias.Alias = LoadStr(COPY_KEY_BUTTON);
|
|
|
- CopyAlias.ActionAlias = LoadStr(COPY_KEY_ACTION);
|
|
|
- CopyAlias.OnSubmit = &ClipboardHandler.Copy;
|
|
|
- Aliases.push_back(CopyAlias);
|
|
|
-
|
|
|
- TQueryButtonAlias PasteAlias;
|
|
|
- PasteAlias.Button = qaIgnore;
|
|
|
- PasteAlias.Alias = LoadStr(PASTE_KEY_BUTTON);
|
|
|
- PasteAlias.OnSubmit = &PasteKeyHandler.Paste;
|
|
|
- PasteAlias.GroupWith = qaYes;
|
|
|
- Aliases.push_back(PasteAlias);
|
|
|
-
|
|
|
- TQueryButtonAlias OnceAlias;
|
|
|
- OnceAlias.Button = qaOK;
|
|
|
- OnceAlias.Alias = OnceButton;
|
|
|
- OnceAlias.GroupWith = qaYes;
|
|
|
- Aliases.push_back(OnceAlias);
|
|
|
-
|
|
|
- Answers = qaYes | qaOK | qaCancel | qaRetry | qaIgnore;
|
|
|
- if (!Unknown)
|
|
|
+ try
|
|
|
{
|
|
|
- TQueryButtonAlias UpdateAlias;
|
|
|
- UpdateAlias.Button = qaYes;
|
|
|
- UpdateAlias.Alias = UpdateButton;
|
|
|
- Aliases.push_back(UpdateAlias);
|
|
|
-
|
|
|
- TQueryButtonAlias AddAlias;
|
|
|
- AddAlias.Button = qaNo;
|
|
|
- AddAlias.Alias = AddButton;
|
|
|
- AddAlias.GroupWith = qaYes;
|
|
|
- Aliases.push_back(AddAlias);
|
|
|
-
|
|
|
- Answers |= qaNo;
|
|
|
+ UnicodeString StorageSource = StoreHostKey(Host, Port, KeyType, KeyStr);
|
|
|
+ UnicodeString StoredKeys = RetrieveHostKey(Host, Port, KeyType);
|
|
|
+ if (StoredKeys != KeyStr)
|
|
|
+ {
|
|
|
+ throw Exception(UnicodeString());
|
|
|
+ }
|
|
|
+ Configuration->Usage->Inc(L"HostKeyNewAccepted");
|
|
|
+ LogEvent(FORMAT(L"Warning: Stored new host key to %s - This should occur only on the first connection", (StorageSource)));
|
|
|
+ Result = true;
|
|
|
}
|
|
|
- else
|
|
|
+ catch (Exception & E)
|
|
|
{
|
|
|
- TQueryButtonAlias AcceptAlias;
|
|
|
- AcceptAlias.Button = qaYes;
|
|
|
- AcceptAlias.Alias = AcceptButton;
|
|
|
- Aliases.push_back(AcceptAlias);
|
|
|
+ FUI->FatalError(&E, LoadStr(STORE_NEW_HOSTKEY_ERROR));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- TQueryParams Params(qpWaitInBatch);
|
|
|
- Params.NoBatchAnswers = qaYes | qaNo | qaRetry | qaIgnore | qaOK;
|
|
|
- Params.HelpKeyword = (Unknown ? HELP_UNKNOWN_KEY : HELP_DIFFERENT_KEY);
|
|
|
- Params.Aliases = &Aliases[0];
|
|
|
- Params.AliasesCount = Aliases.size();
|
|
|
-
|
|
|
- UnicodeString NewLine = L"\n";
|
|
|
- UnicodeString Para = NewLine + NewLine;
|
|
|
- UnicodeString Message;
|
|
|
- UnicodeString ServerPara = FMTLOAD(HOSTKEY_SERVER, (Host, Port)) + Para;
|
|
|
- UnicodeString KeyTypeHuman = GetKeyTypeHuman(KeyType);
|
|
|
- UnicodeString Nbsp = L"\xA0";
|
|
|
- UnicodeString Indent = Nbsp + Nbsp + Nbsp + Nbsp;
|
|
|
- UnicodeString FingerprintPara =
|
|
|
- Indent + FMTLOAD(HOSTKEY_FINGERPRINT, (KeyTypeHuman)) + NewLine +
|
|
|
- Indent + ReplaceStr(FingerprintSHA256, L" ", Nbsp) + Para;
|
|
|
- if (Unknown)
|
|
|
+ if (!Result)
|
|
|
+ {
|
|
|
+ bool Verified;
|
|
|
+ if (ConfiguredKeyNotMatch || Configuration->DisableAcceptingHostKeys)
|
|
|
{
|
|
|
- Message =
|
|
|
- MainInstructions(LoadStr(HOSTKEY_UNKNOWN)) + Para +
|
|
|
- LoadStr(HOSTKEY_NOT_CACHED) + NewLine +
|
|
|
- ServerPara +
|
|
|
- LoadStr(HOSTKEY_NO_GUARANTEE) + Para +
|
|
|
- FingerprintPara +
|
|
|
- FMTLOAD(HOSTKEY_ACCEPT_NEW, (StripHotkey(AcceptButton))) + NewLine +
|
|
|
- FMTLOAD(HOSTKEY_ONCE_NEW, (StripHotkey(OnceButton))) + NewLine +
|
|
|
- FMTLOAD(HOSTKEY_CANCEL_NEW, (StripHotkey(CancelButton)));
|
|
|
+ Verified = false;
|
|
|
}
|
|
|
- else
|
|
|
+ // no point offering manual verification, if we cannot persist the verified key
|
|
|
+ else if (!Configuration->Persistent && Configuration->Scripting)
|
|
|
{
|
|
|
- Message =
|
|
|
- MainInstructions(LoadStr(HOSTKEY_SECURITY_BREACH)) + Para +
|
|
|
- LoadStr(HOSTKEY_DOESNT_MATCH) + NewLine +
|
|
|
- ServerPara +
|
|
|
- FMTLOAD(HOSTKEY_TWO_EXPLANATIONS, (LoadStr(HOSTKEY_ADMINISTRATOR_CHANGED), LoadStr(HOSTKEY_ANOTHER_COMPUTER))) + Para +
|
|
|
- FingerprintPara +
|
|
|
- FMTLOAD(HOSTKEY_ACCEPT_CHANGE, (StripHotkey(UpdateButton), StripHotkey(AddButton))) + NewLine +
|
|
|
- FMTLOAD(HOSTKEY_ONCE_CHANGE, (StripHotkey(OnceButton))) + NewLine +
|
|
|
- FMTLOAD(HOSTKEY_CANCEL_CHANGE, (StripHotkey(CancelButton), StripHotkey(CancelButton)));
|
|
|
+ Verified = false;
|
|
|
}
|
|
|
-
|
|
|
- if (Configuration->Scripting)
|
|
|
+ else
|
|
|
{
|
|
|
- AddToList(Message, LoadStr(SCRIPTING_USE_HOSTKEY), Para);
|
|
|
- }
|
|
|
+ // We should not offer caching if !Configuration->Persistent,
|
|
|
+ // but as scripting mode is handled earlier and in GUI it hardly happens,
|
|
|
+ // it's a small issue.
|
|
|
+ TClipboardHandler ClipboardHandler;
|
|
|
+ ClipboardHandler.Text = FingerprintSHA256 + L"\n" + FingerprintMD5;
|
|
|
+ TPasteKeyHandler PasteKeyHandler;
|
|
|
+ PasteKeyHandler.KeyStr = KeyStr;
|
|
|
+ PasteKeyHandler.FingerprintMD5 = FingerprintMD5;
|
|
|
+ PasteKeyHandler.FingerprintSHA256 = FingerprintSHA256;
|
|
|
+ PasteKeyHandler.UI = FUI;
|
|
|
+
|
|
|
+ bool Unknown = StoredKeys.IsEmpty();
|
|
|
+
|
|
|
+ UnicodeString AcceptButton = LoadStr(HOSTKEY_ACCEPT_BUTTON);
|
|
|
+ UnicodeString OnceButton = LoadStr(HOSTKEY_ONCE_BUTTON);
|
|
|
+ UnicodeString CancelButton = Vcl_Consts_SMsgDlgCancel;
|
|
|
+ UnicodeString UpdateButton = LoadStr(UPDATE_KEY_BUTTON);
|
|
|
+ UnicodeString AddButton = LoadStr(ADD_KEY_BUTTON);
|
|
|
+ int Answers;
|
|
|
+ std::vector<TQueryButtonAlias> Aliases;
|
|
|
+
|
|
|
+ TQueryButtonAlias CopyAlias;
|
|
|
+ CopyAlias.Button = qaRetry;
|
|
|
+ CopyAlias.Alias = LoadStr(COPY_KEY_BUTTON);
|
|
|
+ CopyAlias.ActionAlias = LoadStr(COPY_KEY_ACTION);
|
|
|
+ CopyAlias.OnSubmit = &ClipboardHandler.Copy;
|
|
|
+ Aliases.push_back(CopyAlias);
|
|
|
+
|
|
|
+ TQueryButtonAlias PasteAlias;
|
|
|
+ PasteAlias.Button = qaIgnore;
|
|
|
+ PasteAlias.Alias = LoadStr(PASTE_KEY_BUTTON);
|
|
|
+ PasteAlias.OnSubmit = &PasteKeyHandler.Paste;
|
|
|
+ PasteAlias.GroupWith = qaYes;
|
|
|
+ Aliases.push_back(PasteAlias);
|
|
|
+
|
|
|
+ TQueryButtonAlias OnceAlias;
|
|
|
+ OnceAlias.Button = qaOK;
|
|
|
+ OnceAlias.Alias = OnceButton;
|
|
|
+ OnceAlias.GroupWith = qaYes;
|
|
|
+ Aliases.push_back(OnceAlias);
|
|
|
+
|
|
|
+ Answers = qaYes | qaOK | qaCancel | qaRetry | qaIgnore;
|
|
|
+ if (!Unknown)
|
|
|
+ {
|
|
|
+ TQueryButtonAlias UpdateAlias;
|
|
|
+ UpdateAlias.Button = qaYes;
|
|
|
+ UpdateAlias.Alias = UpdateButton;
|
|
|
+ Aliases.push_back(UpdateAlias);
|
|
|
+
|
|
|
+ TQueryButtonAlias AddAlias;
|
|
|
+ AddAlias.Button = qaNo;
|
|
|
+ AddAlias.Alias = AddButton;
|
|
|
+ AddAlias.GroupWith = qaYes;
|
|
|
+ Aliases.push_back(AddAlias);
|
|
|
+
|
|
|
+ Answers |= qaNo;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ TQueryButtonAlias AcceptAlias;
|
|
|
+ AcceptAlias.Button = qaYes;
|
|
|
+ AcceptAlias.Alias = AcceptButton;
|
|
|
+ Aliases.push_back(AcceptAlias);
|
|
|
+ }
|
|
|
|
|
|
- unsigned int R =
|
|
|
- FUI->QueryUser(Message, NULL, Answers, &Params, qtWarning);
|
|
|
- UnicodeString StoreKeyStr = KeyStr;
|
|
|
+ TQueryParams Params(qpWaitInBatch);
|
|
|
+ Params.NoBatchAnswers = qaYes | qaNo | qaRetry | qaIgnore | qaOK;
|
|
|
+ Params.HelpKeyword = (Unknown ? HELP_UNKNOWN_KEY : HELP_DIFFERENT_KEY);
|
|
|
+ Params.Aliases = &Aliases[0];
|
|
|
+ Params.AliasesCount = Aliases.size();
|
|
|
+
|
|
|
+ UnicodeString NewLine = L"\n";
|
|
|
+ UnicodeString Para = NewLine + NewLine;
|
|
|
+ UnicodeString Message;
|
|
|
+ UnicodeString ServerPara = FMTLOAD(HOSTKEY_SERVER, (Host, Port)) + Para;
|
|
|
+ UnicodeString Nbsp = L"\xA0";
|
|
|
+ UnicodeString Indent = Nbsp + Nbsp + Nbsp + Nbsp;
|
|
|
+ UnicodeString FingerprintPara =
|
|
|
+ Indent + FMTLOAD(HOSTKEY_FINGERPRINT, (KeyType)) + NewLine +
|
|
|
+ Indent + ReplaceStr(FingerprintSHA256, L" ", Nbsp) + Para;
|
|
|
+ UnicodeString AdministratorChangerOrAnotherComputerExplanationPara =
|
|
|
+ FMTLOAD(HOSTKEY_TWO_EXPLANATIONS, (LoadStr(HOSTKEY_ADMINISTRATOR_CHANGED), LoadStr(HOSTKEY_ANOTHER_COMPUTER))) + Para;
|
|
|
+ UnicodeString CertifiedTrustLine;
|
|
|
+ if (IsCertificate)
|
|
|
+ {
|
|
|
+ Message =
|
|
|
+ MainInstructions(LoadStr(HOSTKEY_SECURITY_BREACH)) + Para +
|
|
|
+ LoadStr(HOSTKEY_CERTIFIED1) + NewLine +
|
|
|
+ ServerPara;
|
|
|
+ if (CACount > 0)
|
|
|
+ {
|
|
|
+ Message +=
|
|
|
+ LoadStr(HOSTKEY_CERTIFIED2) + Para;
|
|
|
+ if (!Unknown)
|
|
|
+ {
|
|
|
+ Message += LoadStr(HOSTKEY_CERTIFIED_DOESNT_MATCH_ALSO) + Para;
|
|
|
+ }
|
|
|
+ Message +=
|
|
|
+ FMTLOAD(HOSTKEY_TWO_EXPLANATIONS, (LoadStr(HOSTKEY_CERTIFIED_ANOTHER), LoadStr(HOSTKEY_ANOTHER_COMPUTER))) + Para;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Message +=
|
|
|
+ LoadStr(HOSTKEY_CERTIFIED_DOESNT_MATCH) + Para +
|
|
|
+ AdministratorChangerOrAnotherComputerExplanationPara;
|
|
|
+ }
|
|
|
|
|
|
- switch (R) {
|
|
|
- case qaNo:
|
|
|
- DebugAssert(!Unknown);
|
|
|
- StoreKeyStr = (StoredKeys + HostKeyDelimiter + StoreKeyStr);
|
|
|
- // fall thru
|
|
|
- case qaYes:
|
|
|
- StoreHostKey(Host, Port, KeyType, StoreKeyStr);
|
|
|
- Verified = true;
|
|
|
- break;
|
|
|
+ CertifiedTrustLine = LoadStr(HOSTKEY_CERTIFIED_TRUST) + NewLine;
|
|
|
+ }
|
|
|
+ else if (Unknown)
|
|
|
+ {
|
|
|
+ Message =
|
|
|
+ MainInstructions(LoadStr(HOSTKEY_UNKNOWN)) + Para +
|
|
|
+ LoadStr(HOSTKEY_NOT_CACHED) + NewLine +
|
|
|
+ ServerPara +
|
|
|
+ LoadStr(HOSTKEY_NO_GUARANTEE) + Para;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Message =
|
|
|
+ MainInstructions(LoadStr(HOSTKEY_SECURITY_BREACH)) + Para +
|
|
|
+ LoadStr(HOSTKEY_DOESNT_MATCH) + NewLine +
|
|
|
+ ServerPara +
|
|
|
+ AdministratorChangerOrAnotherComputerExplanationPara;
|
|
|
+ }
|
|
|
|
|
|
- case qaCancel:
|
|
|
- Verified = false;
|
|
|
- break;
|
|
|
+ Message += FingerprintPara;
|
|
|
|
|
|
- default:
|
|
|
- Verified = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
+ if (Unknown)
|
|
|
+ {
|
|
|
+ Message +=
|
|
|
+ FMTLOAD(HOSTKEY_ACCEPT_NEW, (StripHotkey(AcceptButton))) + NewLine +
|
|
|
+ CertifiedTrustLine +
|
|
|
+ FMTLOAD(HOSTKEY_ONCE_NEW, (StripHotkey(OnceButton))) + NewLine +
|
|
|
+ FMTLOAD(HOSTKEY_CANCEL_NEW, (StripHotkey(CancelButton)));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Message +=
|
|
|
+ FMTLOAD(HOSTKEY_ACCEPT_CHANGE, (StripHotkey(UpdateButton), StripHotkey(AddButton))) + NewLine +
|
|
|
+ CertifiedTrustLine +
|
|
|
+ FMTLOAD(HOSTKEY_ONCE_CHANGE, (StripHotkey(OnceButton))) + NewLine +
|
|
|
+ FMTLOAD(HOSTKEY_CANCEL_CHANGE, (StripHotkey(CancelButton), StripHotkey(CancelButton)));
|
|
|
+ }
|
|
|
|
|
|
- if (!Verified)
|
|
|
- {
|
|
|
- Configuration->Usage->Inc(L"HostNotVerified");
|
|
|
+ if (Configuration->Scripting)
|
|
|
+ {
|
|
|
+ AddToList(Message, LoadStr(SCRIPTING_USE_HOSTKEY), Para);
|
|
|
+ }
|
|
|
|
|
|
- UnicodeString Message;
|
|
|
- if (ConfiguredKeyNotMatch)
|
|
|
- {
|
|
|
- Message = FMTLOAD(CONFIGURED_KEY_NOT_MATCH, (ConfigHostKey));
|
|
|
- }
|
|
|
- else if (!Configuration->Persistent && Configuration->Scripting)
|
|
|
- {
|
|
|
- Message = LoadStr(HOSTKEY_NOT_CONFIGURED);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Message = LoadStr(KEY_NOT_VERIFIED);
|
|
|
+ unsigned int R =
|
|
|
+ FUI->QueryUser(Message, NULL, Answers, &Params, qtWarning);
|
|
|
+ UnicodeString StoreKeyStr = KeyStr;
|
|
|
+
|
|
|
+ switch (R) {
|
|
|
+ case qaNo:
|
|
|
+ DebugAssert(!Unknown);
|
|
|
+ StoreKeyStr = (StoredKeys + HostKeyDelimiter + StoreKeyStr);
|
|
|
+ // fall thru
|
|
|
+ case qaYes:
|
|
|
+ StoreHostKey(Host, Port, KeyType, StoreKeyStr);
|
|
|
+ Verified = true;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case qaCancel:
|
|
|
+ Verified = false;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ Verified = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- Exception * E = new Exception(MainInstructions(Message));
|
|
|
- try
|
|
|
+ if (!Verified)
|
|
|
{
|
|
|
- FUI->FatalError(E, FMTLOAD(HOSTKEY, (FingerprintSHA256)));
|
|
|
- }
|
|
|
- __finally
|
|
|
- {
|
|
|
- delete E;
|
|
|
+ Configuration->Usage->Inc(L"HostNotVerified");
|
|
|
+
|
|
|
+ UnicodeString Message;
|
|
|
+ if (ConfiguredKeyNotMatch)
|
|
|
+ {
|
|
|
+ Message = FMTLOAD(CONFIGURED_KEY_NOT_MATCH, (ConfigHostKey));
|
|
|
+ }
|
|
|
+ else if (!Configuration->Persistent && Configuration->Scripting)
|
|
|
+ {
|
|
|
+ Message = LoadStr(HOSTKEY_NOT_CONFIGURED);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Message = LoadStr(KEY_NOT_VERIFIED);
|
|
|
+ }
|
|
|
+
|
|
|
+ Exception * E = new Exception(MainInstructions(Message));
|
|
|
+ try
|
|
|
+ {
|
|
|
+ FUI->FatalError(E, FMTLOAD(HOSTKEY, (FingerprintSHA256)));
|
|
|
+ }
|
|
|
+ __finally
|
|
|
+ {
|
|
|
+ delete E;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|