mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Updating to PuTTY 0.80 – mostly Issue 2246 – Mitigations for SSH protocol "Terrapin" vulnerability
https://winscp.net/tracker/2246 Source commit: f7b34a47547af9b0b4bd32fb66d6d278c8b6b342
This commit is contained in:
@@ -291,18 +291,21 @@ bool have_ssh_host_key(Seat * seat, const char * hostname, int port,
|
||||
return SecureShell->HaveHostKey(hostname, port, keytype) ? 1 : 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
SeatPromptResult confirm_weak_crypto_primitive(Seat * seat, const char * algtype, const char * algname,
|
||||
void (*/*callback*/)(void * ctx, SeatPromptResult result), void * /*ctx*/)
|
||||
SeatPromptResult confirm_weak_crypto_primitive(
|
||||
Seat * seat, SeatDialogText *,
|
||||
void (*DebugUsedArg(callback))(void * ctx, SeatPromptResult result), void * DebugUsedArg(ctx),
|
||||
const char * algtype, const char *algname, int wcr)
|
||||
{
|
||||
TSecureShell * SecureShell = static_cast<ScpSeat *>(seat)->SecureShell;
|
||||
SecureShell->AskAlg(algtype, algname);
|
||||
SecureShell->AskAlg(algtype, algname, wcr);
|
||||
|
||||
// We should return 0 when alg was not confirmed, we throw exception instead.
|
||||
return SPR_OK;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
SeatPromptResult confirm_weak_cached_hostkey(Seat *, const char * /*algname*/, const char * /*betteralgs*/,
|
||||
void (*/*callback*/)(void *ctx, SeatPromptResult result), void * /*ctx*/)
|
||||
SeatPromptResult confirm_weak_cached_hostkey(
|
||||
Seat *, SeatDialogText *,
|
||||
void (*DebugUsedArg(callback))(void * ctx, SeatPromptResult result), void * DebugUsedArg(ctx))
|
||||
{
|
||||
return SPR_OK;
|
||||
}
|
||||
@@ -470,11 +473,12 @@ int reg_override_winscp()
|
||||
return (PuttyRegistryMode != prmPass);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
HKEY open_regkey_fn_winscp(bool Create, HKEY Key, const char * Path, ...)
|
||||
HKEY open_regkey_fn_winscp(bool Create, bool Write, HKEY Key, const char * Path, ...)
|
||||
{
|
||||
HKEY Result;
|
||||
if (PuttyRegistryMode == prmCollect)
|
||||
{
|
||||
DebugAssert(Write && Create);
|
||||
Result = reinterpret_cast<HKEY>(1);
|
||||
}
|
||||
else if (PuttyRegistryMode == prmFail)
|
||||
@@ -519,7 +523,7 @@ HKEY open_regkey_fn_winscp(bool Create, HKEY Key, const char * Path, ...)
|
||||
DebugAssert(RegKey == L"SshHostKeys");
|
||||
|
||||
DebugAssert(PuttyStorage != NULL);
|
||||
DebugAssert(PuttyStorage->AccessMode == (Create ? smReadWrite : smRead));
|
||||
DebugAssert(PuttyStorage->AccessMode == (Write ? smReadWrite : smRead));
|
||||
if (PuttyStorage->OpenSubKey(RegKey, Create))
|
||||
{
|
||||
Result = reinterpret_cast<HKEY>(PuttyStorage);
|
||||
|
||||
@@ -2841,7 +2841,7 @@ bool __fastcall TSecureShell::HaveHostKey(UnicodeString Host, int Port, const Un
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSecureShell::AskAlg(UnicodeString AlgType, UnicodeString AlgName)
|
||||
void TSecureShell::AskAlg(const UnicodeString & AAlgType, const UnicodeString & AlgName, int WeakCryptoReason)
|
||||
{
|
||||
// beware of changing order
|
||||
static const TPuttyTranslation AlgTranslation[] = {
|
||||
@@ -2852,9 +2852,33 @@ void __fastcall TSecureShell::AskAlg(UnicodeString AlgType, UnicodeString AlgNam
|
||||
{ L"hostkey type", KEYKEY_TYPE },
|
||||
};
|
||||
|
||||
UnicodeString AlgType = AAlgType;
|
||||
TranslatePuttyMessage(AlgTranslation, LENOF(AlgTranslation), AlgType);
|
||||
|
||||
UnicodeString Msg = FMTLOAD(ALG_BELOW_TRESHOLD, (AlgType, AlgName));
|
||||
UnicodeString Msg;
|
||||
UnicodeString NewLine = UnicodeString(sLineBreak);
|
||||
switch (WeakCryptoReason)
|
||||
{
|
||||
default:
|
||||
DebugFail();
|
||||
case 0:
|
||||
Msg = FMTLOAD(ALG_BELOW_TRESHOLD2, (AlgType, AlgName));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
Msg = FMTLOAD(CIPHER_TERRAPIN, (AlgType, AlgName));
|
||||
if (WeakCryptoReason == 2)
|
||||
{
|
||||
Msg += NewLine + NewLine + FMTLOAD(CIPHER_TERRAPIN_AVOID, (AlgName));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Msg =
|
||||
MainInstructions(LoadStr(WEAK_ALG_TITLE)) + NewLine + NewLine +
|
||||
Msg + NewLine + NewLine +
|
||||
LoadStr(WEAK_ALG_RISK_CONFIRM);
|
||||
|
||||
if (FUI->QueryUser(Msg, NULL, qaYes | qaNo, NULL, qtWarning) == qaNo)
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ public:
|
||||
const UnicodeString & FingerprintSHA256, const UnicodeString & FingerprintMD5,
|
||||
bool IsCertificate, int CACount, bool AlreadyVerified);
|
||||
bool __fastcall HaveHostKey(UnicodeString Host, int Port, const UnicodeString KeyType);
|
||||
void __fastcall AskAlg(UnicodeString AlgType, UnicodeString AlgName);
|
||||
void AskAlg(const UnicodeString & AlgType, const UnicodeString & AlgName, int WeakCryptoReason);
|
||||
void __fastcall DisplayBanner(const UnicodeString & Banner);
|
||||
void __fastcall PuttyLogEvent(const char * Str);
|
||||
UnicodeString __fastcall ConvertFromPutty(const char * Str, int Length);
|
||||
|
||||
12
source/putty/putty.h
vendored
12
source/putty/putty.h
vendored
@@ -1295,7 +1295,8 @@ struct SeatVtable {
|
||||
*/
|
||||
SeatPromptResult (*confirm_weak_crypto_primitive)(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
const char *algtype, const char *algname, int wcr);
|
||||
|
||||
/*
|
||||
* Variant form of confirm_weak_crypto_primitive, which prints a
|
||||
@@ -1447,9 +1448,11 @@ static inline SeatPromptResult seat_confirm_ssh_host_key(
|
||||
fingerprints, is_certificate, ca_count, already_verified); } // WINSCP
|
||||
static inline SeatPromptResult seat_confirm_weak_crypto_primitive(
|
||||
InteractionReadySeat iseat, SeatDialogText *text,
|
||||
void (*cb)(void *ctx, SeatPromptResult result), void *ctx)
|
||||
void (*cb)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
const char *algtype, const char *algname, int wcr) // WINSCP
|
||||
{ return iseat.seat->vt->confirm_weak_crypto_primitive(
|
||||
iseat.seat, text, cb, ctx); }
|
||||
iseat.seat, text, cb, ctx,
|
||||
algtype, algname, wcr); } // WINSCP
|
||||
static inline SeatPromptResult seat_confirm_weak_cached_hostkey(
|
||||
InteractionReadySeat iseat, SeatDialogText *text,
|
||||
void (*cb)(void *ctx, SeatPromptResult result), void *ctx)
|
||||
@@ -1542,7 +1545,8 @@ SeatPromptResult nullseat_confirm_ssh_host_key(
|
||||
char **fingerprints, bool is_certificate, int ca_count, bool already_verified); // WINSCP
|
||||
SeatPromptResult nullseat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
const char *algtype, const char *algname, int wcr); // WINSCP
|
||||
SeatPromptResult nullseat_confirm_weak_cached_hostkey(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
|
||||
@@ -1188,10 +1188,13 @@ SeatPromptResult confirm_weak_crypto_primitive(
|
||||
|
||||
seat_dialog_text_append(text, SDT_PROMPT, "Continue with connection?");
|
||||
|
||||
{ // WINSCP
|
||||
SeatPromptResult toret = seat_confirm_weak_crypto_primitive(
|
||||
iseat, text, callback, ctx);
|
||||
iseat, text, callback, ctx,
|
||||
algtype, algname, wcr); // WINSCP
|
||||
seat_dialog_text_free(text);
|
||||
return toret;
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
SeatPromptResult confirm_weak_cached_hostkey(
|
||||
@@ -1214,8 +1217,11 @@ SeatPromptResult confirm_weak_cached_hostkey(
|
||||
"The server also provides the following types of host key "
|
||||
"above the threshold, which we do not have stored:");
|
||||
|
||||
for (const char **p = betteralgs; *p; p++)
|
||||
{ // WINSCP
|
||||
const char **p; // WINSCP
|
||||
for (p = betteralgs; *p; p++)
|
||||
seat_dialog_text_append(text, SDT_DISPLAY, "%s", *p);
|
||||
} // WINSCP
|
||||
|
||||
/* In batch mode, we print the above information and then this
|
||||
* abort message, and stop. */
|
||||
@@ -1228,10 +1234,12 @@ SeatPromptResult confirm_weak_cached_hostkey(
|
||||
|
||||
seat_dialog_text_append(text, SDT_PROMPT, "Continue with connection?");
|
||||
|
||||
{ // WINSCP
|
||||
SeatPromptResult toret = seat_confirm_weak_cached_hostkey(
|
||||
iseat, text, callback, ctx);
|
||||
seat_dialog_text_free(text);
|
||||
return toret;
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@@ -1023,7 +1023,8 @@ struct server_hostkeys {
|
||||
|
||||
static bool kexinit_keyword_found(ptrlen list, ptrlen keyword)
|
||||
{
|
||||
for (ptrlen word; get_commasep_word(&list, &word) ;)
|
||||
ptrlen word; // WINSCP
|
||||
for (; get_commasep_word(&list, &word) ;)
|
||||
if (ptrlen_eq_ptrlen(word, keyword))
|
||||
return true;
|
||||
return false;
|
||||
@@ -1079,7 +1080,7 @@ static ScanKexinitsResult ssh2_scan_kexinits(
|
||||
slists[i] = get_string(server);
|
||||
if (get_err(client) || get_err(server)) {
|
||||
ScanKexinitsResult skr = {
|
||||
.success = false, .error = SKR_INCOMPLETE,
|
||||
/*.success =*/ false, /*.error =*/ SKR_INCOMPLETE,
|
||||
};
|
||||
return skr;
|
||||
}
|
||||
@@ -1129,10 +1130,9 @@ static ScanKexinitsResult ssh2_scan_kexinits(
|
||||
* produce a reasonably useful message instead of an
|
||||
* assertion failure.
|
||||
*/
|
||||
ScanKexinitsResult skr = {
|
||||
.success = false, .error = SKR_UNKNOWN_ID,
|
||||
.kind = kexlist_descr[i], .desc = found,
|
||||
};
|
||||
ScanKexinitsResult skr;
|
||||
skr.success = false, skr.error = SKR_UNKNOWN_ID,
|
||||
skr.kind = kexlist_descr[i], skr.desc = found;
|
||||
return skr;
|
||||
}
|
||||
|
||||
@@ -1188,10 +1188,9 @@ static ScanKexinitsResult ssh2_scan_kexinits(
|
||||
/*
|
||||
* Otherwise, any match failure _is_ a fatal error.
|
||||
*/
|
||||
ScanKexinitsResult skr = {
|
||||
.success = false, .error = SKR_UNKNOWN_ID,
|
||||
.kind = kexlist_descr[i], .desc = slists[i],
|
||||
};
|
||||
ScanKexinitsResult skr;
|
||||
skr.success = false, skr.error = SKR_UNKNOWN_ID,
|
||||
skr.kind = kexlist_descr[i], skr.desc = slists[i];
|
||||
return skr;
|
||||
}
|
||||
|
||||
@@ -1291,8 +1290,10 @@ static ScanKexinitsResult ssh2_scan_kexinits(
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
ScanKexinitsResult skr = { .success = true };
|
||||
{ // WINSCP
|
||||
ScanKexinitsResult skr = { /*.success =*/ true };
|
||||
return skr;
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
static void ssh2_report_scan_kexinits_error(Ssh *ssh, ScanKexinitsResult skr)
|
||||
@@ -1381,6 +1382,7 @@ static void filter_outgoing_kexinit(struct ssh2_transport_state *s)
|
||||
searchword = kex_strict_c;
|
||||
}
|
||||
|
||||
{ // WINSCP
|
||||
bool add = false;
|
||||
ptrlen iword; // WINSCP
|
||||
for (; get_commasep_word(&ilist_copy, &iword) ;) {
|
||||
@@ -1405,6 +1407,7 @@ static void filter_outgoing_kexinit(struct ssh2_transport_state *s)
|
||||
|
||||
if (add)
|
||||
add_to_commasep_pl(out, oword);
|
||||
} // WINSCP
|
||||
}
|
||||
put_stringpl(pktout, ptrlen_from_strbuf(out));
|
||||
} // WINSCP
|
||||
@@ -2697,8 +2700,10 @@ static bool try_to_avoid_terrapin(const struct ssh2_transport_state *s)
|
||||
* previously above it. If not, don't do anything - we don't want
|
||||
* to _promote_ it.
|
||||
*/
|
||||
{ // WINSCP
|
||||
int ccp_pos_now = -1, ccp_pos_wanted = -1;
|
||||
for (int i = 0; i < CIPHER_MAX; i++) {
|
||||
int i; // WINSCP
|
||||
for (i = 0; i < CIPHER_MAX; i++) {
|
||||
switch (conf_get_int_int(alt_conf, CONF_ssh_cipherlist,
|
||||
i)) {
|
||||
case CIPHER_CHACHA20:
|
||||
@@ -2722,6 +2727,7 @@ static bool try_to_avoid_terrapin(const struct ssh2_transport_state *s)
|
||||
}
|
||||
conf_set_int_int(alt_conf, CONF_ssh_cipherlist,
|
||||
ccp_pos_now + 1, CIPHER_CHACHA20);
|
||||
} // WINSCP
|
||||
|
||||
/*
|
||||
* Make the outgoing KEXINIT we would have made using this
|
||||
@@ -2730,7 +2736,7 @@ static bool try_to_avoid_terrapin(const struct ssh2_transport_state *s)
|
||||
put_byte(alt_client_kexinit, SSH2_MSG_KEXINIT);
|
||||
put_padding(alt_client_kexinit, 16, 'x'); /* fake random padding */
|
||||
ssh2_write_kexinit_lists(
|
||||
BinarySink_UPCAST(alt_client_kexinit), alt_kexlists, alt_conf,
|
||||
/*WINSCP*/ s->ppl.seat, BinarySink_UPCAST(alt_client_kexinit), alt_kexlists, alt_conf,
|
||||
s->ssc, s->ppl.remote_bugs, s->savedhost, s->savedport, s->hostkey_alg,
|
||||
s->thc, s->host_cas, s->hostkeys, s->nhostkeys, !s->got_session_id,
|
||||
s->can_gssapi_keyex,
|
||||
@@ -2742,6 +2748,7 @@ static bool try_to_avoid_terrapin(const struct ssh2_transport_state *s)
|
||||
* Re-analyse the incoming KEXINIT with respect to this one, to
|
||||
* see what we'd have decided on.
|
||||
*/
|
||||
{ // WINSCP
|
||||
transport_direction cstrans, sctrans;
|
||||
bool warn_kex, warn_hk, warn_cscipher, warn_sccipher;
|
||||
bool can_send_ext_info = false, strict_kex = false;
|
||||
@@ -2785,12 +2792,16 @@ static bool try_to_avoid_terrapin(const struct ssh2_transport_state *s)
|
||||
|
||||
out:
|
||||
|
||||
for (size_t i = 0; i < NKEXLIST; i++)
|
||||
{ // WINSCP
|
||||
size_t i;
|
||||
for (i = 0; i < NKEXLIST; i++)
|
||||
sfree(alt_kexlists[i].algs);
|
||||
strbuf_free(alt_client_kexinit);
|
||||
conf_free(alt_conf);
|
||||
|
||||
return avoidable;
|
||||
} // WINSCP
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
#include "puttyexp.h"
|
||||
|
||||
@@ -28,7 +28,8 @@ SeatPromptResult nullseat_confirm_ssh_host_key(
|
||||
{ return SPR_SW_ABORT("this seat can't handle interactive prompts"); }
|
||||
SeatPromptResult nullseat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
const char *algtype, const char *algname, int wcr) // WINSCP
|
||||
{ return SPR_SW_ABORT("this seat can't handle interactive prompts"); }
|
||||
SeatPromptResult nullseat_confirm_weak_cached_hostkey(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
@@ -61,8 +62,8 @@ const SeatDialogPromptDescriptions *nullseat_prompt_descriptions(Seat *seat)
|
||||
/*.hk_connect_once_action =*/ "",
|
||||
/*.hk_cancel_action =*/ "",
|
||||
/*.hk_cancel_action_Participle =*/ "",
|
||||
.weak_accept_action = "",
|
||||
.weak_cancel_action = "",
|
||||
/*.weak_accept_action =*/ "",
|
||||
/*.weak_cancel_action =*/ "",
|
||||
};
|
||||
return &descs;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,8 @@ static SeatPromptResult tempseat_confirm_ssh_host_key(
|
||||
|
||||
static SeatPromptResult tempseat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
const char *algtype, const char *algname, int wcr) // WINSCP
|
||||
{
|
||||
unreachable("confirm_weak_crypto_primitive "
|
||||
"should never be called on TempSeat");
|
||||
|
||||
@@ -244,6 +244,7 @@ void launch_help(HWND hwnd, const char *topic);
|
||||
void quit_help(HWND hwnd);
|
||||
int has_embedded_chm(void); /* 1 = yes, 0 = no, -1 = N/A */
|
||||
|
||||
#ifndef WINSCP
|
||||
/*
|
||||
* GUI seat methods in dialog.c, so that the vtable definition in
|
||||
* window.c can refer to them.
|
||||
@@ -251,8 +252,7 @@ int has_embedded_chm(void); /* 1 = yes, 0 = no, -1 = N/A */
|
||||
SeatPromptResult win_seat_confirm_ssh_host_key(
|
||||
Seat *seat, const char *host, int port, const char *keytype,
|
||||
char *keystr, SeatDialogText *text, HelpCtx helpctx,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx,
|
||||
char **fingerprints, bool is_certificate, int ca_count, bool already_verified); // WINSCP
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
SeatPromptResult win_seat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
@@ -260,6 +260,7 @@ SeatPromptResult win_seat_confirm_weak_cached_hostkey(
|
||||
Seat *seat, SeatDialogText *text,
|
||||
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
|
||||
const SeatDialogPromptDescriptions *win_seat_prompt_descriptions(Seat *seat);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Windows-specific clipboard helper function shared with dialog.c,
|
||||
@@ -753,13 +754,13 @@ char *get_jumplist_registry_entries(void);
|
||||
/* In utils */
|
||||
int reg_override_winscp(void);
|
||||
HKEY open_regkey_fn(bool create, bool write, HKEY base, const char *path, ...);
|
||||
HKEY open_regkey_fn_winscp(bool create, HKEY base, const char *path, ...);
|
||||
HKEY open_regkey_fn_winscp(bool create, bool write, HKEY base, const char *path, ...);
|
||||
#define open_regkey_ro(base, ...) \
|
||||
open_regkey_fn(false, false, base, __VA_ARGS__, (const char *)NULL)
|
||||
reg_override_winscp() ? open_regkey_fn_winscp(false, false, base, __VA_ARGS__, (const char *)NULL) : open_regkey_fn(false, false, base, __VA_ARGS__, (const char *)NULL)
|
||||
#define open_regkey_rw(base, ...) \
|
||||
open_regkey_fn(false, true, base, __VA_ARGS__, (const char *)NULL)
|
||||
DebugFail();
|
||||
#define create_regkey(base, ...) \
|
||||
open_regkey_fn(true, true, base, __VA_ARGS__, (const char *)NULL)
|
||||
reg_override_winscp() ? open_regkey_fn_winscp(true, true, base, __VA_ARGS__, (const char *)NULL) : open_regkey_fn(true, true, base, __VA_ARGS__, (const char *)NULL)
|
||||
void close_regkey(HKEY key);
|
||||
void close_regkey_winscp(HKEY key);
|
||||
void del_regkey(HKEY key, const char *name);
|
||||
|
||||
@@ -294,7 +294,6 @@
|
||||
#define PROMPT_KEY_PASSPHRASE 303
|
||||
#define FILE_OVERWRITE 304
|
||||
#define DIRECTORY_OVERWRITE 305
|
||||
#define ALG_BELOW_TRESHOLD 306
|
||||
#define CIPHER_TYPE_BOTH2 307
|
||||
#define CIPHER_TYPE_CS2 308
|
||||
#define CIPHER_TYPE_SC2 309
|
||||
@@ -372,6 +371,11 @@
|
||||
#define HOSTKEY_CERTIFIED_ANOTHER 388
|
||||
#define HOSTKEY_CERTIFIED_DOESNT_MATCH 389
|
||||
#define HOSTKEY_CERTIFIED_TRUST 390
|
||||
#define WEAK_ALG_TITLE 391
|
||||
#define WEAK_ALG_RISK_CONFIRM 392
|
||||
#define ALG_BELOW_TRESHOLD2 393
|
||||
#define CIPHER_TERRAPIN 394
|
||||
#define CIPHER_TERRAPIN_AVOID 395
|
||||
|
||||
#define CORE_INFORMATION_STRINGS 400
|
||||
#define YES_STR 401
|
||||
|
||||
@@ -270,7 +270,6 @@ BEGIN
|
||||
PROMPT_KEY_PASSPHRASE, "&Passphrase for key '%s':"
|
||||
FILE_OVERWRITE, "File '%s' already exists. Overwrite?"
|
||||
DIRECTORY_OVERWRITE, "Directory '%s' already exists. Overwrite?"
|
||||
ALG_BELOW_TRESHOLD, "The first %s supported by the server is %s, which is below the configured warning threshold.\n\nDo you want to continue with this connection?"
|
||||
CIPHER_TYPE_BOTH2, "cipher"
|
||||
CIPHER_TYPE_CS2, "client-to-server cipher"
|
||||
CIPHER_TYPE_SC2, "server-to-client cipher"
|
||||
@@ -345,6 +344,11 @@ BEGIN
|
||||
HOSTKEY_CERTIFIED_ANOTHER, "another certification authority is operating in this realm"
|
||||
HOSTKEY_CERTIFIED_DOESNT_MATCH, "which does not match the certified key WinSCP had previously cached for this server."
|
||||
HOSTKEY_CERTIFIED_TRUST, "(Storing this certified key in the cache will NOT cause its certification authority to be trusted for any other key or host.)"
|
||||
WEAK_ALG_TITLE, "Security Alert"
|
||||
WEAK_ALG_RISK_CONFIRM, "Do you want to accept the risk and continue with this session?"
|
||||
ALG_BELOW_TRESHOLD2, "The first %s supported by the server is %s, which is below the configured warning threshold."
|
||||
CIPHER_TERRAPIN, "The %s selected for this session is %s, which, with this server, is vulnerable to the 'Terrapin' attack CVE-2023-48795, potentially allowing an attacker to modify the encrypted session.\n\nUpgrading, patching, or reconfiguring this SSH server is the best way to avoid this vulnerability, if possible."
|
||||
CIPHER_TERRAPIN_AVOID, "You can also avoid this vulnerability by abandoning this session, moving %s to below the 'warn below here' line in WinSCP's SSH cipher configuration (so that an algorithm without the vulnerability will be selected), and starting a new session."
|
||||
|
||||
CORE_INFORMATION_STRINGS, "CORE_INFORMATION"
|
||||
YES_STR, "Yes"
|
||||
|
||||
Reference in New Issue
Block a user