mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
SSH password change + When opening secondary shell session fails, the main session is not Closed + Session.ExecuteCommand unit tests
ChangePassword + PasswordChangesFailed counters task_change_password help keyword Source commit: 335f4de0796d0367a8ed427790cf1407607cc0d8
This commit is contained in:
@@ -148,7 +148,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "WinSCP.Session.#TestHandlesClosedInternal")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
|
||||
[assembly: SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.SessionOptions.#GetPassword()")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.SessionOptions.#GetPassword(System.Security.SecureString)")]
|
||||
[assembly: SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Scope = "member", Target = "WinSCP.SessionOptions.#ParseUrl(System.String)")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess+NoopSafeHandle.#.ctor(System.IntPtr)")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#CreateFileMapping(System.String)")]
|
||||
@@ -158,6 +158,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.ExeSessionProcess.#CreateFileMapping(System.String)")]
|
||||
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.Logger.#CreateCounters()")]
|
||||
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.SessionLogReader.#LogContents()")]
|
||||
[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "WinSCP.Session.#SessionOptionsToSwitches(WinSCP.SessionOptions,System.Boolean)")]
|
||||
[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "WinSCP.Session.#SessionOptionsToSwitches(WinSCP.SessionOptions,System.Boolean,System.String&,System.String&)")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#RegGetValue(System.UIntPtr,System.String,System.String,WinSCP.RegistryFlags,WinSCP.RegistryType&,System.IntPtr,System.UInt32&)")]
|
||||
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#GetInstallationPath(Microsoft.Win32.RegistryHive)")]
|
||||
|
||||
@@ -1463,22 +1463,27 @@ namespace WinSCP
|
||||
url += tail;
|
||||
logUrl += tail;
|
||||
|
||||
string arguments = SessionOptionsToSwitches(sessionOptions, scanFingerprint);
|
||||
string arguments;
|
||||
string logArguments;
|
||||
SessionOptionsToSwitches(sessionOptions, scanFingerprint, out arguments, out logArguments);
|
||||
|
||||
const string switchName = "-rawsettings";
|
||||
Tools.AddRawParameters(ref arguments, sessionOptions.RawSettings, "-rawsettings");
|
||||
Tools.AddRawParameters(ref logArguments, sessionOptions.RawSettings, switchName);
|
||||
|
||||
if (!string.IsNullOrEmpty(arguments))
|
||||
{
|
||||
arguments = " " + arguments;
|
||||
logArguments = " " + logArguments;
|
||||
}
|
||||
|
||||
// Switches should (and particularly the -rawsettings MUST) come after the URL
|
||||
command = "\"" + Tools.ArgumentEscape(url) + "\"" + arguments;
|
||||
log = "\"" + Tools.ArgumentEscape(logUrl) + "\"" + arguments;
|
||||
log = "\"" + Tools.ArgumentEscape(logUrl) + "\"" + logArguments;
|
||||
}
|
||||
}
|
||||
|
||||
private string SessionOptionsToSwitches(SessionOptions sessionOptions, bool scanFingerprint)
|
||||
private void SessionOptionsToSwitches(SessionOptions sessionOptions, bool scanFingerprint, out string arguments, out string logArguments)
|
||||
{
|
||||
using (Logger.CreateCallstack())
|
||||
{
|
||||
@@ -1580,7 +1585,20 @@ namespace WinSCP
|
||||
|
||||
switches.Add(FormatSwitch("timeout", (int)sessionOptions.Timeout.TotalSeconds));
|
||||
|
||||
return string.Join(" ", switches.ToArray());
|
||||
List<string> logSwitches = new List<string>(switches);
|
||||
|
||||
if ((sessionOptions.SecureNewPassword != null) && !scanFingerprint)
|
||||
{
|
||||
if (sessionOptions.SecurePassword == null)
|
||||
{
|
||||
throw new ArgumentException("SessionOptions.SecureNewPassword is set, but SessionOptions.SecurePassword is not.");
|
||||
}
|
||||
switches.Add(FormatSwitch("newpassword", sessionOptions.NewPassword));
|
||||
logSwitches.Add(FormatSwitch("newpassword", "***"));
|
||||
}
|
||||
|
||||
arguments = string.Join(" ", switches.ToArray());
|
||||
logArguments = string.Join(" ", logSwitches.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,10 @@ namespace WinSCP
|
||||
public string HostName { get; set; }
|
||||
public int PortNumber { get { return _portNumber; } set { SetPortNumber(value); } }
|
||||
public string UserName { get; set; }
|
||||
public string Password { get { return GetPassword(); } set { SetPassword(value); } }
|
||||
public SecureString SecurePassword { get; set; }
|
||||
public string Password { get { return GetPassword(_securePassword); } set { SetPassword(ref _securePassword, value); } }
|
||||
public SecureString SecurePassword { get { return _securePassword; } set { _securePassword = value; } }
|
||||
public string NewPassword { get { return GetPassword(_secureNewPassword); } set { SetPassword(ref _secureNewPassword, value); } }
|
||||
public SecureString SecureNewPassword { get { return _secureNewPassword; } set { _secureNewPassword = value; } }
|
||||
public TimeSpan Timeout { get { return _timeout; } set { SetTimeout(value); } }
|
||||
public int TimeoutInMilliseconds { get { return Tools.TimeSpanToMilliseconds(Timeout); } set { Timeout = Tools.MillisecondsToTimeSpan(value); } }
|
||||
public string PrivateKeyPassphrase { get; set; }
|
||||
@@ -364,25 +366,25 @@ namespace WinSCP
|
||||
_webdavRoot = value;
|
||||
}
|
||||
|
||||
private void SetPassword(string value)
|
||||
private static void SetPassword(ref SecureString securePassword, string value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
SecurePassword = null;
|
||||
securePassword = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SecurePassword = new SecureString();
|
||||
securePassword = new SecureString();
|
||||
foreach (char c in value)
|
||||
{
|
||||
SecurePassword.AppendChar(c);
|
||||
securePassword.AppendChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPassword()
|
||||
private static string GetPassword(SecureString securePassword)
|
||||
{
|
||||
if (SecurePassword == null)
|
||||
if (securePassword == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -391,7 +393,7 @@ namespace WinSCP
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
ptr = Marshal.SecureStringToGlobalAllocUnicode(SecurePassword);
|
||||
ptr = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
|
||||
return Marshal.PtrToStringUni(ptr);
|
||||
}
|
||||
finally
|
||||
@@ -401,6 +403,8 @@ namespace WinSCP
|
||||
}
|
||||
}
|
||||
|
||||
private SecureString _securePassword;
|
||||
private SecureString _secureNewPassword;
|
||||
private string _sshHostKeyFingerprint;
|
||||
private string _tlsHostCertificateFingerprint;
|
||||
private TimeSpan _timeout;
|
||||
|
||||
@@ -2351,6 +2351,7 @@ bool __fastcall TFTPFileSystem::IsCapable(int Capability) const
|
||||
case fcLocking:
|
||||
case fcPreservingTimestampDirs:
|
||||
case fcResumeSupport:
|
||||
case fcChangePassword:
|
||||
return false;
|
||||
|
||||
default:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define SCRIPT_SWITCH "script"
|
||||
#define COMMAND_SWITCH L"Command"
|
||||
#define SESSIONNAME_SWICH L"SessionName"
|
||||
#define NEWPASSWORD_SWITCH L"newpassword"
|
||||
#define INI_NUL L"nul"
|
||||
#define PRESERVETIME_SWITCH L"preservetime"
|
||||
#define PRESERVETIMEDIRS_SWITCH_VALUE L"all"
|
||||
|
||||
@@ -464,6 +464,9 @@ bool __fastcall TSCPFileSystem::IsCapable(int Capability) const
|
||||
case fcResumeSupport:
|
||||
return false;
|
||||
|
||||
case fcChangePassword:
|
||||
return FSecureShell->CanChangePassword();
|
||||
|
||||
default:
|
||||
DebugFail();
|
||||
return false;
|
||||
|
||||
@@ -2059,7 +2059,7 @@ __fastcall TManagementScript::TManagementScript(TStoredSessionList * StoredSessi
|
||||
|
||||
FCommands->Register(L"exit", SCRIPT_EXIT_DESC, SCRIPT_EXIT_HELP, &ExitProc, 0, 0, false);
|
||||
FCommands->Register(L"bye", 0, SCRIPT_EXIT_HELP, &ExitProc, 0, 0, false);
|
||||
FCommands->Register(L"open", SCRIPT_OPEN_DESC, SCRIPT_OPEN_HELP8, &OpenProc, 0, -1, true);
|
||||
FCommands->Register(L"open", SCRIPT_OPEN_DESC, SCRIPT_OPEN_HELP9, &OpenProc, 0, -1, true);
|
||||
FCommands->Register(L"close", SCRIPT_CLOSE_DESC, SCRIPT_CLOSE_HELP, &CloseProc, 0, 1, false);
|
||||
FCommands->Register(L"session", SCRIPT_SESSION_DESC, SCRIPT_SESSION_HELP, &SessionProc, 0, 1, false);
|
||||
FCommands->Register(L"lpwd", SCRIPT_LPWD_DESC, SCRIPT_LPWD_HELP, &LPwdProc, 0, 0, false);
|
||||
|
||||
@@ -166,6 +166,7 @@ Conf * __fastcall TSecureShell::StoreToConfig(TSessionData * Data, bool Simple)
|
||||
conf_set_str(conf, CONF_username, UTF8String(Data->UserNameExpanded).c_str());
|
||||
conf_set_int(conf, CONF_port, Data->PortNumber);
|
||||
conf_set_int(conf, CONF_protocol, PROT_SSH);
|
||||
conf_set_int(conf, CONF_change_password, Data->ChangePassword);
|
||||
// always set 0, as we will handle keepalives ourselves to avoid
|
||||
// multi-threaded issues in putty timer list
|
||||
conf_set_int(conf, CONF_ping_interval, 0);
|
||||
@@ -866,6 +867,24 @@ bool __fastcall TSecureShell::PromptUser(bool /*ToServer*/,
|
||||
FStoredPassphraseTried = true;
|
||||
}
|
||||
}
|
||||
else if (PromptKind == pkNewPassword)
|
||||
{
|
||||
if (FSessionData->ChangePassword)
|
||||
{
|
||||
FUI->Information(LoadStr(AUTH_CHANGING_PASSWORD), false);
|
||||
|
||||
if (!FSessionData->Password.IsEmpty() && !FSessionData->NewPassword.IsEmpty() && !FStoredPasswordTried)
|
||||
{
|
||||
LogEvent(L"Using stored password and new password.");
|
||||
Result = true;
|
||||
DebugAssert(Results->Count == 3);
|
||||
Results->Strings[0] = FSessionData->Password;
|
||||
Results->Strings[1] = FSessionData->NewPassword;
|
||||
Results->Strings[2] = FSessionData->NewPassword;
|
||||
FStoredPasswordTried = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
@@ -896,7 +915,10 @@ void __fastcall TSecureShell::GotHostKey()
|
||||
if (!FAuthenticating && !FAuthenticated)
|
||||
{
|
||||
FAuthenticating = true;
|
||||
FUI->Information(LoadStr(STATUS_AUTHENTICATE), true);
|
||||
if (!FSessionData->ChangePassword)
|
||||
{
|
||||
FUI->Information(LoadStr(STATUS_AUTHENTICATE), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2520,3 +2542,11 @@ void __fastcall TSecureShell::CollectUsage()
|
||||
Configuration->Usage->Inc(L"OpenedSessionsSSHOther");
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TSecureShell::CanChangePassword()
|
||||
{
|
||||
return
|
||||
// These major SSH servers explicitly do not support password change.
|
||||
(SshImplementation != sshiOpenSSH) && // See userauth_passwd
|
||||
(SshImplementation != sshiProFTPD); // See sftp_auth_password
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ public:
|
||||
void __fastcall ClearStdError();
|
||||
bool __fastcall GetStoredCredentialsTried();
|
||||
void __fastcall CollectUsage();
|
||||
bool __fastcall CanChangePassword();
|
||||
|
||||
void __fastcall RegisterReceiveHandler(TNotifyEvent Handler);
|
||||
void __fastcall UnregisterReceiveHandler(TNotifyEvent Handler);
|
||||
|
||||
@@ -104,6 +104,8 @@ void __fastcall TSessionData::Default()
|
||||
PortNumber = SshPortNumber;
|
||||
UserName = L"";
|
||||
Password = L"";
|
||||
NewPassword = L"";
|
||||
ChangePassword = false;
|
||||
PingInterval = 30;
|
||||
PingType = ptOff;
|
||||
Timeout = 15;
|
||||
@@ -277,6 +279,8 @@ void __fastcall TSessionData::NonPersistant()
|
||||
PROPERTY(Note);
|
||||
//---------------------------------------------------------------------
|
||||
#define ADVANCED_PROPERTIES \
|
||||
PROPERTY(NewPassword); \
|
||||
PROPERTY(ChangePassword); \
|
||||
PROPERTY(PingInterval); \
|
||||
PROPERTY(PingType); \
|
||||
PROPERTY(Timeout); \
|
||||
@@ -1420,6 +1424,7 @@ void __fastcall TSessionData::SavePasswords(THierarchicalStorage * Storage, bool
|
||||
void __fastcall TSessionData::RecryptPasswords()
|
||||
{
|
||||
Password = Password;
|
||||
NewPassword = NewPassword;
|
||||
ProxyPassword = ProxyPassword;
|
||||
TunnelPassword = TunnelPassword;
|
||||
Passphrase = Passphrase;
|
||||
@@ -1437,12 +1442,17 @@ bool __fastcall TSessionData::HasAnySessionPassword()
|
||||
//---------------------------------------------------------------------
|
||||
bool __fastcall TSessionData::HasAnyPassword()
|
||||
{
|
||||
return HasAnySessionPassword() || !FProxyPassword.IsEmpty();
|
||||
return
|
||||
HasAnySessionPassword() ||
|
||||
!FProxyPassword.IsEmpty() ||
|
||||
// will probably be never used
|
||||
FNewPassword.IsEmpty();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSessionData::ClearSessionPasswords()
|
||||
{
|
||||
FPassword = L"";
|
||||
FNewPassword = L"";
|
||||
FTunnelPassword = L"";
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
@@ -1560,7 +1570,9 @@ bool __fastcall TSessionData::IsProtocolUrl(
|
||||
//---------------------------------------------------------------------
|
||||
bool __fastcall TSessionData::IsSensitiveOption(const UnicodeString & Option)
|
||||
{
|
||||
return SameText(Option, PassphraseOption);
|
||||
return
|
||||
SameText(Option, PassphraseOption) ||
|
||||
SameText(Option, NEWPASSWORD_SWITCH);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool __fastcall TSessionData::ParseUrl(UnicodeString Url, TOptions * Options,
|
||||
@@ -1869,6 +1881,11 @@ bool __fastcall TSessionData::ParseUrl(UnicodeString Url, TOptions * Options,
|
||||
{
|
||||
Name = Value;
|
||||
}
|
||||
if (Options->FindSwitch(NEWPASSWORD_SWITCH, Value))
|
||||
{
|
||||
ChangePassword = true;
|
||||
NewPassword = Value;
|
||||
}
|
||||
if (Options->FindSwitch(L"privatekey", Value))
|
||||
{
|
||||
PublicKeyFile = Value;
|
||||
@@ -2077,6 +2094,7 @@ void __fastcall TSessionData::SetHostName(UnicodeString value)
|
||||
{
|
||||
// HostName is key for password encryption
|
||||
UnicodeString XPassword = Password;
|
||||
UnicodeString XNewPassword = Password;
|
||||
|
||||
// This is now hardly used as hostname is parsed directly on login dialog.
|
||||
// But can be used when importing sites from PuTTY, as it allows same format too.
|
||||
@@ -2090,7 +2108,9 @@ void __fastcall TSessionData::SetHostName(UnicodeString value)
|
||||
Modify();
|
||||
|
||||
Password = XPassword;
|
||||
NewPassword = XNewPassword;
|
||||
Shred(XPassword);
|
||||
Shred(XNewPassword);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
@@ -2141,9 +2161,12 @@ void __fastcall TSessionData::SetUserName(UnicodeString value)
|
||||
{
|
||||
// UserName is key for password encryption
|
||||
UnicodeString XPassword = Password;
|
||||
UnicodeString XNewPassword = NewPassword;
|
||||
SET_SESSION_PROPERTY(UserName);
|
||||
Password = XPassword;
|
||||
NewPassword = XNewPassword;
|
||||
Shred(XPassword);
|
||||
Shred(XNewPassword);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
@@ -2163,6 +2186,22 @@ UnicodeString __fastcall TSessionData::GetPassword() const
|
||||
return DecryptPassword(FPassword, UserName+HostName);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSessionData::SetNewPassword(UnicodeString avalue)
|
||||
{
|
||||
RawByteString value = EncryptPassword(avalue, UserName+HostName);
|
||||
SET_SESSION_PROPERTY(NewPassword);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
UnicodeString __fastcall TSessionData::GetNewPassword() const
|
||||
{
|
||||
return DecryptPassword(FNewPassword, UserName+HostName);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSessionData::SetChangePassword(bool value)
|
||||
{
|
||||
SET_SESSION_PROPERTY(ChangePassword);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSessionData::SetPingInterval(int value)
|
||||
{
|
||||
SET_SESSION_PROPERTY(PingInterval);
|
||||
@@ -3646,6 +3685,19 @@ UnicodeString __fastcall TSessionData::ComposePath(
|
||||
{
|
||||
return UnixIncludeTrailingBackslash(Path) + Name;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TSessionData::DisableAuthentationsExceptPassword()
|
||||
{
|
||||
SshNoUserAuth = false;
|
||||
AuthTIS = false;
|
||||
AuthKI = false;
|
||||
AuthKIPassword = false;
|
||||
AuthGSSAPI = false;
|
||||
PublicKeyFile = L"";
|
||||
TlsCertificateFile = L"";
|
||||
Passphrase = L"";
|
||||
TryAgent = false;
|
||||
}
|
||||
//=== TStoredSessionList ----------------------------------------------
|
||||
__fastcall TStoredSessionList::TStoredSessionList(bool aReadOnly):
|
||||
TNamedObjectList(), FReadOnly(aReadOnly)
|
||||
|
||||
@@ -93,6 +93,8 @@ private:
|
||||
int FPortNumber;
|
||||
UnicodeString FUserName;
|
||||
RawByteString FPassword;
|
||||
RawByteString FNewPassword;
|
||||
bool FChangePassword;
|
||||
int FPingInterval;
|
||||
TPingType FPingType;
|
||||
bool FTryAgent;
|
||||
@@ -219,6 +221,9 @@ private:
|
||||
UnicodeString __fastcall GetUserNameExpanded();
|
||||
void __fastcall SetPassword(UnicodeString value);
|
||||
UnicodeString __fastcall GetPassword() const;
|
||||
void __fastcall SetNewPassword(UnicodeString value);
|
||||
UnicodeString __fastcall GetNewPassword() const;
|
||||
void __fastcall SetChangePassword(bool value);
|
||||
void __fastcall SetPingInterval(int value);
|
||||
void __fastcall SetTryAgent(bool value);
|
||||
void __fastcall SetAgentFwd(bool value);
|
||||
@@ -442,6 +447,7 @@ public:
|
||||
void __fastcall ConfigureTunnel(int PortNumber);
|
||||
void __fastcall RollbackTunnel();
|
||||
void __fastcall ExpandEnvironmentVariables();
|
||||
void __fastcall DisableAuthentationsExceptPassword();
|
||||
bool __fastcall IsSame(const TSessionData * Default, bool AdvancedOnly);
|
||||
bool __fastcall IsSameSite(const TSessionData * Default);
|
||||
bool __fastcall IsInFolderOrWorkspace(UnicodeString Name);
|
||||
@@ -465,6 +471,8 @@ public:
|
||||
__property UnicodeString UserName = { read=FUserName, write=SetUserName };
|
||||
__property UnicodeString UserNameExpanded = { read=GetUserNameExpanded };
|
||||
__property UnicodeString Password = { read=GetPassword, write=SetPassword };
|
||||
__property UnicodeString NewPassword = { read=GetNewPassword, write=SetNewPassword };
|
||||
__property bool ChangePassword = { read=FChangePassword, write=SetChangePassword };
|
||||
__property int PingInterval = { read=FPingInterval, write=SetPingInterval };
|
||||
__property bool TryAgent = { read=FTryAgent, write=SetTryAgent };
|
||||
__property bool AgentFwd = { read=FAgentFwd, write=SetAgentFwd };
|
||||
|
||||
@@ -42,6 +42,7 @@ enum TFSCapability { fcUserGroupListing, fcModeChanging, fcGroupChanging,
|
||||
fcModeChangingUpload, fcPreservingTimestampUpload, fcShellAnyCommand,
|
||||
fcSecondaryShell, fcRemoveCtrlZUpload, fcRemoveBOMUpload, fcMoveToQueue,
|
||||
fcLocking, fcPreservingTimestampDirs, fcResumeSupport,
|
||||
fcChangePassword,
|
||||
fcCount };
|
||||
//---------------------------------------------------------------------------
|
||||
struct TFileSystemInfo
|
||||
|
||||
@@ -2161,6 +2161,9 @@ bool __fastcall TSFTPFileSystem::IsCapable(int Capability) const
|
||||
case fcLocking:
|
||||
return false;
|
||||
|
||||
case fcChangePassword:
|
||||
return FSecureShell->CanChangePassword();
|
||||
|
||||
default:
|
||||
DebugFail();
|
||||
return false;
|
||||
|
||||
@@ -822,8 +822,7 @@ void __fastcall TTerminal::Close()
|
||||
{
|
||||
FFileSystem->Close();
|
||||
|
||||
// Cannot rely on CommandSessionOpened here as Status is set to ssClosed
|
||||
// only after the OnClose is called
|
||||
// Cannot rely on CommandSessionOpened here as Status is set to ssClosed too late
|
||||
if ((FCommandSession != NULL) && FCommandSession->Active)
|
||||
{
|
||||
// prevent recursion
|
||||
@@ -1264,14 +1263,6 @@ void __fastcall TTerminal::Reopen(int Params)
|
||||
SessionData->FSProtocol = (FFSProtocol == cfsSCP ? fsSCPonly : fsSFTPonly);
|
||||
}
|
||||
|
||||
// Could be active before, if fatal error occured in the secondary terminal.
|
||||
// But now, since we handle the secondary terminal's OnClose,
|
||||
// by closing outselves, it should not happen anymore.
|
||||
if (DebugAlwaysFalse(Active))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
Open();
|
||||
}
|
||||
__finally
|
||||
@@ -4088,6 +4079,25 @@ bool __fastcall TTerminal::GetCommandSessionOpened()
|
||||
(FCommandSession->Status == ssOpened);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TTerminal * __fastcall TTerminal::CreateSecondarySession(const UnicodeString & Name, TSessionData * SessionData)
|
||||
{
|
||||
std::unique_ptr<TTerminal> Result(new TSecondaryTerminal(this, SessionData, Configuration, Name));
|
||||
|
||||
Result->AutoReadDirectory = false;
|
||||
|
||||
Result->FExceptionOnFail = FExceptionOnFail;
|
||||
|
||||
Result->OnQueryUser = OnQueryUser;
|
||||
Result->OnPromptUser = OnPromptUser;
|
||||
Result->OnShowExtendedException = OnShowExtendedException;
|
||||
Result->OnProgress = OnProgress;
|
||||
Result->OnFinished = OnFinished;
|
||||
Result->OnInformation = OnInformation;
|
||||
Result->OnCustomCommand = OnCustomCommand;
|
||||
// do not copy OnDisplayBanner to avoid it being displayed
|
||||
return Result.release();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TTerminal * __fastcall TTerminal::GetCommandSession()
|
||||
{
|
||||
if ((FCommandSession != NULL) && !FCommandSession->Active)
|
||||
@@ -4101,50 +4111,32 @@ TTerminal * __fastcall TTerminal::GetCommandSession()
|
||||
// levels between main and command session
|
||||
DebugAssert(FInTransaction == 0);
|
||||
|
||||
try
|
||||
{
|
||||
FCommandSession = new TSecondaryTerminal(this, SessionData,
|
||||
Configuration, L"Shell");
|
||||
std::unique_ptr<TSessionData> CommandSessionData(SessionData->Clone());
|
||||
CommandSessionData->RemoteDirectory = CurrentDirectory;
|
||||
CommandSessionData->FSProtocol = fsSCPonly;
|
||||
CommandSessionData->ClearAliases = false;
|
||||
CommandSessionData->UnsetNationalVars = false;
|
||||
CommandSessionData->LookupUserGroups = asOff;
|
||||
|
||||
FCommandSession->AutoReadDirectory = false;
|
||||
FCommandSession = CreateSecondarySession(L"Shell", CommandSessionData.get());
|
||||
|
||||
TSessionData * CommandSessionData = FCommandSession->FSessionData;
|
||||
CommandSessionData->RemoteDirectory = CurrentDirectory;
|
||||
CommandSessionData->FSProtocol = fsSCPonly;
|
||||
CommandSessionData->ClearAliases = false;
|
||||
CommandSessionData->UnsetNationalVars = false;
|
||||
CommandSessionData->LookupUserGroups = asOff;
|
||||
FCommandSession->AutoReadDirectory = false;
|
||||
|
||||
FCommandSession->FExceptionOnFail = FExceptionOnFail;
|
||||
FCommandSession->FExceptionOnFail = FExceptionOnFail;
|
||||
|
||||
FCommandSession->OnQueryUser = OnQueryUser;
|
||||
FCommandSession->OnPromptUser = OnPromptUser;
|
||||
FCommandSession->OnShowExtendedException = OnShowExtendedException;
|
||||
FCommandSession->OnProgress = OnProgress;
|
||||
FCommandSession->OnFinished = OnFinished;
|
||||
FCommandSession->OnInformation = OnInformation;
|
||||
FCommandSession->OnCustomCommand = OnCustomCommand;
|
||||
FCommandSession->OnClose = CommandSessionClose;
|
||||
// do not copy OnDisplayBanner to avoid it being displayed
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
SAFE_DESTROY(FCommandSession);
|
||||
throw;
|
||||
}
|
||||
FCommandSession->OnQueryUser = OnQueryUser;
|
||||
FCommandSession->OnPromptUser = OnPromptUser;
|
||||
FCommandSession->OnShowExtendedException = OnShowExtendedException;
|
||||
FCommandSession->OnProgress = OnProgress;
|
||||
FCommandSession->OnFinished = OnFinished;
|
||||
FCommandSession->OnInformation = OnInformation;
|
||||
FCommandSession->OnCustomCommand = OnCustomCommand;
|
||||
// do not copy OnDisplayBanner to avoid it being displayed
|
||||
}
|
||||
|
||||
return FCommandSession;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminal::CommandSessionClose(TObject * /*Sender*/)
|
||||
{
|
||||
// Keep the states in sync.
|
||||
// This is particularly to invoke ours OnClose,
|
||||
// So that it is triggered before Reopen is called
|
||||
Close();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminal::AnyCommand(const UnicodeString Command,
|
||||
TCaptureOutputEvent OutputEvent)
|
||||
{
|
||||
|
||||
@@ -394,7 +394,6 @@ protected:
|
||||
const UnicodeString & FileName, TFileOperation Operation1, TFileOperation Operation2 = foNone);
|
||||
void __fastcall StartOperationWithFile(
|
||||
const UnicodeString & FileName, TFileOperation Operation1, TFileOperation Operation2 = foNone);
|
||||
void __fastcall CommandSessionClose(TObject * Sender);
|
||||
bool __fastcall CanRecurseToDirectory(const TRemoteFile * File);
|
||||
bool __fastcall DoOnCustomCommand(const UnicodeString & Command);
|
||||
|
||||
@@ -497,6 +496,7 @@ public:
|
||||
void __fastcall ReflectSettings();
|
||||
void __fastcall CollectUsage();
|
||||
bool __fastcall IsThisOrChild(TTerminal * Terminal);
|
||||
TTerminal * __fastcall CreateSecondarySession(const UnicodeString & Name, TSessionData * SessionData);
|
||||
|
||||
const TSessionInfo & __fastcall GetSessionInfo();
|
||||
const TFileSystemInfo & __fastcall GetFileSystemInfo(bool Retrieve = false);
|
||||
|
||||
@@ -702,6 +702,7 @@ bool __fastcall TWebDAVFileSystem::IsCapable(int Capability) const
|
||||
case fcRemoteCopy:
|
||||
case fcPreservingTimestampDirs:
|
||||
case fcResumeSupport:
|
||||
case fcChangePassword:
|
||||
return false;
|
||||
|
||||
case fcLocking:
|
||||
|
||||
@@ -242,6 +242,7 @@ void __fastcall TConsoleDialog::ExecuteCommand()
|
||||
catch(Exception & E)
|
||||
{
|
||||
DebugAssert(FLastTerminal != NULL);
|
||||
// Should use the command session, if there's one, not to close the main session
|
||||
FLastTerminal->ShowExtendedException(&E);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5599,20 +5599,9 @@ void __fastcall TCustomScpExplorerForm::DoOpenDirectoryDialog(
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::CommandSessionFallback()
|
||||
{
|
||||
bool Result = true;
|
||||
|
||||
DebugAssert(!FTerminal->CommandSessionOpened);
|
||||
|
||||
try
|
||||
{
|
||||
TTerminalManager::ConnectTerminal(FTerminal->CommandSession, false);
|
||||
}
|
||||
catch(Exception & E)
|
||||
{
|
||||
ShowExtendedExceptionEx(FTerminal->CommandSession, &E);
|
||||
Result = false;
|
||||
}
|
||||
return Result;
|
||||
return TTerminalManager::Instance()->ConnectTerminal(FTerminal->CommandSession);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::EnsureCommandSessionFallback(TFSCapability Capability)
|
||||
@@ -9132,3 +9121,28 @@ void __fastcall TCustomScpExplorerForm::SessionsPageControlContextPopup(TObject
|
||||
Handled = true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::CanChangePassword()
|
||||
{
|
||||
return (Terminal != NULL) && Terminal->Active && Terminal->IsCapable[fcChangePassword];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::ChangePassword()
|
||||
{
|
||||
Configuration->Usage->Inc(L"PasswordChanges");
|
||||
std::unique_ptr<TSessionData> ChangePasswordData(Terminal->SessionData->Clone());
|
||||
ChangePasswordData->DisableAuthentationsExceptPassword();
|
||||
ChangePasswordData->ChangePassword = true;
|
||||
|
||||
std::unique_ptr<TTerminal> ChangePasswordSession(
|
||||
Terminal->CreateSecondarySession(L"ChangePassword", ChangePasswordData.get()));
|
||||
ChangePasswordSession->AutoReadDirectory = false;
|
||||
|
||||
if (TTerminalManager::Instance()->ConnectTerminal(ChangePasswordSession.get()))
|
||||
{
|
||||
MessageDialog(MainInstructions(LoadStr(PASSWORD_CHANGED)), qtInformation, qaOK, HELP_CHANGE_PASSWORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
Configuration->Usage->Inc(L"PasswordChangesFailed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,6 +684,8 @@ public:
|
||||
virtual void __fastcall DisplaySystemContextMenu();
|
||||
virtual void __fastcall GoToAddress() = 0;
|
||||
bool __fastcall CanConsole();
|
||||
bool __fastcall CanChangePassword();
|
||||
void __fastcall ChangePassword();
|
||||
|
||||
__property bool ComponentVisible[Byte Component] = { read = GetComponentVisible, write = SetComponentVisible };
|
||||
__property bool EnableFocusedOperation[TOperationSide Side] = { read = GetEnableFocusedOperation, index = 0 };
|
||||
|
||||
@@ -444,6 +444,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
|
||||
UPD(ClearCachesAction, HasTerminal && !ScpExplorer->Terminal->AreCachesEmpty)
|
||||
UPD(NewFileAction, DirViewEnabled(osCurrent) && !WinConfiguration->DisableOpenEdit)
|
||||
UPD(EditorListCustomizeAction, true)
|
||||
UPD(ChangePasswordAction, ScpExplorer->CanChangePassword())
|
||||
|
||||
// CUSTOM COMMANDS
|
||||
UPD(CustomCommandsFileAction, true)
|
||||
@@ -778,6 +779,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
|
||||
EXE(ClearCachesAction, ScpExplorer->Terminal->ClearCaches())
|
||||
EXE(NewFileAction, ScpExplorer->EditNew(osCurrent))
|
||||
EXE(EditorListCustomizeAction, PreferencesDialog(pmEditor))
|
||||
EXE(ChangePasswordAction, ScpExplorer->ChangePassword())
|
||||
|
||||
// CUSTOM COMMANDS
|
||||
EXE(CustomCommandsFileAction, CreateCustomCommandsMenu(CustomCommandsFileAction, ccltFile))
|
||||
|
||||
@@ -2259,6 +2259,13 @@ object NonVisualDataModule: TNonVisualDataModule
|
||||
Hint = 'Displays tips on using WinSCP'
|
||||
ImageIndex = 110
|
||||
end
|
||||
object ChangePasswordAction: TAction
|
||||
Tag = 15
|
||||
Category = 'Session'
|
||||
Caption = '&Change Password...'
|
||||
HelpKeyword = 'task_change_password'
|
||||
Hint = 'Change account password'
|
||||
end
|
||||
end
|
||||
object ExplorerBarPopup: TTBXPopupMenu
|
||||
Images = GlyphsModule.ExplorerImages
|
||||
|
||||
@@ -617,6 +617,7 @@ __published: // IDE-managed Components
|
||||
TTBXSubmenuItem *RemoteDirViewPopupCustomCommandsMenu;
|
||||
TTBXItem *TBXItem75;
|
||||
TTBXItem *TBXItem76;
|
||||
TAction *ChangePasswordAction;
|
||||
void __fastcall LogActionsUpdate(TBasicAction *Action, bool &Handled);
|
||||
void __fastcall LogActionsExecute(TBasicAction *Action, bool &Handled);
|
||||
void __fastcall ExplorerActionsUpdate(TBasicAction *Action, bool &Handled);
|
||||
|
||||
@@ -425,6 +425,9 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
object TBXItem135: TTBXItem
|
||||
Action = NonVisualDataModule.SessionGenerateUrlAction2
|
||||
end
|
||||
object TBXItem227: TTBXItem
|
||||
Action = NonVisualDataModule.ChangePasswordAction
|
||||
end
|
||||
object TBXSeparatorItem29: TTBXSeparatorItem
|
||||
end
|
||||
object TBXSubmenuItem21: TTBXSubmenuItem
|
||||
|
||||
@@ -420,6 +420,7 @@ __published:
|
||||
TTBXItem *TBXItem216;
|
||||
TTBXItem *TBXItem217;
|
||||
TTBXSubmenuItem *TBXSubmenuItem28;
|
||||
TTBXItem *TBXItem227;
|
||||
void __fastcall SplitterMoved(TObject *Sender);
|
||||
void __fastcall SplitterCanResize(TObject *Sender, int &NewSize,
|
||||
bool &Accept);
|
||||
|
||||
@@ -301,6 +301,9 @@ inherited ScpExplorerForm: TScpExplorerForm
|
||||
object TBXItem144: TTBXItem
|
||||
Action = NonVisualDataModule.SessionGenerateUrlAction2
|
||||
end
|
||||
object TBXItem160: TTBXItem
|
||||
Action = NonVisualDataModule.ChangePasswordAction
|
||||
end
|
||||
object TBXSeparatorItem29: TTBXSeparatorItem
|
||||
end
|
||||
object TBXSubmenuItem21: TTBXSubmenuItem
|
||||
|
||||
@@ -312,6 +312,7 @@ __published:
|
||||
TTBXItem *TBXItem216;
|
||||
TTBXItem *TBXItem159;
|
||||
TTBXSubmenuItem *TBXSubmenuItem28;
|
||||
TTBXItem *TBXItem160;
|
||||
void __fastcall RemoteDirViewUpdateStatusBar(TObject *Sender,
|
||||
const TStatusFileInfo &FileInfo);
|
||||
void __fastcall UnixPathComboBoxBeginEdit(TTBEditItem *Sender,
|
||||
|
||||
@@ -913,6 +913,7 @@ void cleanup_exit(int);
|
||||
X(INT, NONE, connect_timeout) \
|
||||
X(INT, NONE, sndbuf) \
|
||||
X(INT, NONE, force_remote_cmd2) \
|
||||
X(INT, NONE, change_password) \
|
||||
/* MPEXT END */ \
|
||||
|
||||
/* Now define the actual enum of option keywords using that macro. */
|
||||
|
||||
@@ -9145,6 +9145,9 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
|
||||
int kbd_inter_refused;
|
||||
int we_are_in, userauth_success;
|
||||
prompts_t *cur_prompt;
|
||||
#ifdef MPEXT
|
||||
int change_password;
|
||||
#endif
|
||||
int num_prompts;
|
||||
char *username;
|
||||
char *password;
|
||||
@@ -10372,6 +10375,17 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
|
||||
|
||||
ssh->pkt_actx = SSH2_PKTCTX_PASSWORD;
|
||||
|
||||
#ifdef MPEXT
|
||||
s->change_password = conf_get_int(ssh->conf, CONF_change_password);
|
||||
if (s->change_password != 0)
|
||||
{
|
||||
s->password = dupstr("");
|
||||
s->type = AUTH_TYPE_PASSWORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no indentation to ease merges */
|
||||
#endif
|
||||
s->cur_prompt = new_prompts(ssh->frontend);
|
||||
s->cur_prompt->to_server = TRUE;
|
||||
s->cur_prompt->name = dupstr("SSH password");
|
||||
@@ -10436,10 +10450,16 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
|
||||
* request.
|
||||
*/
|
||||
crWaitUntilV(pktin);
|
||||
#ifdef MPEXT
|
||||
}
|
||||
#endif
|
||||
changereq_first_time = TRUE;
|
||||
|
||||
while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
|
||||
|
||||
while ((pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ)
|
||||
#ifdef MPEXT
|
||||
|| (s->change_password != 0)
|
||||
#endif
|
||||
) {
|
||||
/*
|
||||
* We're being asked for a new password
|
||||
* (perhaps not for the first time).
|
||||
@@ -10450,6 +10470,9 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
|
||||
char *prompt; /* not live over crReturn */
|
||||
int prompt_len; /* not live over crReturn */
|
||||
|
||||
#ifdef MPEXT
|
||||
if (s->change_password == 0)
|
||||
#endif
|
||||
{
|
||||
const char *msg;
|
||||
if (changereq_first_time)
|
||||
@@ -10461,6 +10484,10 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
|
||||
c_write_str(ssh, "\r\n");
|
||||
}
|
||||
|
||||
#ifdef MPEXT
|
||||
s->change_password = 0;
|
||||
#endif
|
||||
|
||||
ssh_pkt_getstring(pktin, &prompt, &prompt_len);
|
||||
|
||||
s->cur_prompt = new_prompts(ssh->frontend);
|
||||
|
||||
@@ -58,5 +58,6 @@
|
||||
#define HELP_TIPS "ui_tips"
|
||||
#define HELP_DEBUGGING "debugging"
|
||||
#define HELP_EXTENSION_OPTIONS "ui_pref_commands"
|
||||
#define HELP_CHANGE_PASSWORD "task_change_password"
|
||||
|
||||
#endif // TextsWin
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define SCRIPT_HELP_HELP 4
|
||||
#define SCRIPT_EXIT_HELP 5
|
||||
#define SCRIPT_OPEN_HELP8 6
|
||||
#define SCRIPT_OPEN_HELP9 6
|
||||
#define SCRIPT_CLOSE_HELP 7
|
||||
#define SCRIPT_SESSION_HELP 8
|
||||
#define SCRIPT_PWD_HELP 9
|
||||
@@ -456,6 +456,7 @@
|
||||
#define COPY_INFO_PRESERVE_TIME_DIRS 554
|
||||
#define TEXT_FILE_ENCODING 555
|
||||
#define AND_STR 556
|
||||
#define AUTH_CHANGING_PASSWORD 557
|
||||
|
||||
#define CORE_VARIABLE_STRINGS 600
|
||||
#define PUTTY_BASED_ON 601
|
||||
|
||||
@@ -426,6 +426,7 @@ BEGIN
|
||||
COPY_INFO_PRESERVE_TIME_DIRS, "%s (including directories)"
|
||||
TEXT_FILE_ENCODING, "The file must be in UTF-8 or UTF-16 encoding."
|
||||
AND_STR, "%s and %s"
|
||||
AUTH_CHANGING_PASSWORD, "Changing password."
|
||||
|
||||
CORE_VARIABLE_STRINGS, "CORE_VARIABLE"
|
||||
PUTTY_BASED_ON, "SSH and SCP code based on PuTTY %s"
|
||||
|
||||
@@ -59,7 +59,7 @@ BEGIN
|
||||
" Closes all sessions and terminates the program.\n"
|
||||
"alias:\n"
|
||||
" bye\n"
|
||||
SCRIPT_OPEN_HELP8,
|
||||
SCRIPT_OPEN_HELP9,
|
||||
"open <site>\n"
|
||||
"open sftp|scp|ftp[es]|http[s] :// [ <user> [ :password ] @ ] <host> [ :<port> ]\n"
|
||||
" Establishes connection to given host. Use either name of the site or\n"
|
||||
@@ -79,6 +79,7 @@ BEGIN
|
||||
" Configures any site settings using raw format\n"
|
||||
" as in an INI file\n"
|
||||
" -filezilla Load <site> from FileZilla site manager\n"
|
||||
" -newpassword=<password> Changes password to <password>\n"
|
||||
"examples:\n"
|
||||
" open\n"
|
||||
" open sftp://martin@example.com:2222 -privatekey=mykey.ppk\n"
|
||||
|
||||
@@ -283,6 +283,7 @@
|
||||
#define USAGE_SESSIONNAME 1573
|
||||
#define USAGE_REFRESH 1574
|
||||
#define USAGE_LOGSIZE 1575
|
||||
#define PASSWORD_CHANGED 1576
|
||||
|
||||
#define WIN_FORMS_STRINGS 1600
|
||||
#define LOG_NOLOG 1601
|
||||
|
||||
@@ -286,6 +286,7 @@ BEGIN
|
||||
USAGE_SESSIONNAME, "Gives a name to the session"
|
||||
USAGE_REFRESH, "Reloads remote panel of all running instances of WinSCP. If session (and optionally a path) is specified, refreshes only the instances with that session (and path)."
|
||||
USAGE_LOGSIZE, "Enables log rotation and optionally deleting of old logs."
|
||||
PASSWORD_CHANGED, "Password has been changed."
|
||||
|
||||
WIN_FORMS_STRINGS, "WIN_FORMS_STRINGS"
|
||||
LOG_NOLOG, "No session log."
|
||||
|
||||
@@ -210,7 +210,7 @@ void __fastcall TTerminalManager::FreeActiveTerminal()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void TTerminalManager::ConnectTerminal(TTerminal * Terminal, bool Reopen)
|
||||
void __fastcall TTerminalManager::DoConnectTerminal(TTerminal * Terminal, bool Reopen)
|
||||
{
|
||||
TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
|
||||
// it must be managed terminal, unless it is secondary terminal (of managed terminal)
|
||||
@@ -271,6 +271,21 @@ void TTerminalManager::ConnectTerminal(TTerminal * Terminal, bool Reopen)
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TTerminalManager::ConnectTerminal(TTerminal * Terminal)
|
||||
{
|
||||
bool Result = true;
|
||||
try
|
||||
{
|
||||
DoConnectTerminal(Terminal, false);
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
ShowExtendedExceptionEx(Terminal, &E);
|
||||
Result = false;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TTerminalManager::TerminalThreadIdle(void * /*Data*/, TObject * /*Sender*/)
|
||||
{
|
||||
Application->ProcessMessages();
|
||||
@@ -288,7 +303,7 @@ bool __fastcall TTerminalManager::ConnectActiveTerminalImpl(bool Reopen)
|
||||
{
|
||||
DebugAssert(ActiveTerminal);
|
||||
|
||||
ConnectTerminal(ActiveTerminal, Reopen);
|
||||
DoConnectTerminal(ActiveTerminal, Reopen);
|
||||
|
||||
if (ScpExplorer)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
void __fastcall ReconnectActiveTerminal();
|
||||
void __fastcall FreeActiveTerminal();
|
||||
void __fastcall CycleTerminals(bool Forward);
|
||||
static void ConnectTerminal(TTerminal * Terminal, bool Reopen);
|
||||
bool __fastcall ConnectTerminal(TTerminal * Terminal);
|
||||
void __fastcall SetActiveTerminalWithAutoReconnect(TTerminal * value);
|
||||
void __fastcall UpdateAppTitle();
|
||||
bool __fastcall CanOpenInPutty();
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
TTerminal * __fastcall FindActiveTerminalForSite(TSessionData * Data);
|
||||
TTerminalQueue * __fastcall FindQueueForTerminal(TTerminal * Terminal);
|
||||
void __fastcall UpdateSessionCredentials(TSessionData * Data);
|
||||
void __fastcall DoConnectTerminal(TTerminal * Terminal, bool Reopen);
|
||||
|
||||
__property TCustomScpExplorerForm * ScpExplorer = { read = FScpExplorer, write = SetScpExplorer };
|
||||
__property TTerminal * ActiveTerminal = { read = FActiveTerminal, write = SetActiveTerminal };
|
||||
|
||||
@@ -175,7 +175,7 @@ void __fastcall ShowExtendedExceptionEx(TTerminal * Terminal,
|
||||
WinConfiguration->ConfirmExitOnCompletion;
|
||||
|
||||
if (E->InheritsFrom(__classid(EFatal)) && (Terminal != NULL) &&
|
||||
(Manager != NULL) && (Manager->ActiveTerminal != NULL) && Manager->ActiveTerminal->IsThisOrChild(Terminal))
|
||||
(Manager != NULL) && (Manager->ActiveTerminal == Terminal))
|
||||
{
|
||||
int SessionReopenTimeout = 0;
|
||||
TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Manager->ActiveTerminal);
|
||||
|
||||
@@ -892,12 +892,14 @@ void __fastcall HideAsModal(TForm * Form, void *& Storage)
|
||||
delete AStorage;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall ReleaseAsModal(TForm * Form, void *& Storage)
|
||||
bool __fastcall ReleaseAsModal(TForm * Form, void *& Storage)
|
||||
{
|
||||
if (Storage != NULL)
|
||||
bool Result = (Storage != NULL);
|
||||
if (Result)
|
||||
{
|
||||
HideAsModal(Form, Storage);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall SelectDirectory(UnicodeString & Path, const UnicodeString Prompt,
|
||||
|
||||
@@ -31,7 +31,7 @@ bool __fastcall HasLabelHintPopup(TLabel * Label, const UnicodeString & HintStr)
|
||||
void __fastcall FixComboBoxResizeBug(TCustomComboBox * ComboBox);
|
||||
void __fastcall ShowAsModal(TForm * Form, void *& Storage, bool BringToFront = true);
|
||||
void __fastcall HideAsModal(TForm * Form, void *& Storage);
|
||||
void __fastcall ReleaseAsModal(TForm * Form, void *& Storage);
|
||||
bool __fastcall ReleaseAsModal(TForm * Form, void *& Storage);
|
||||
TImageList * __fastcall SharedSystemImageList(bool Large);
|
||||
bool __fastcall SelectDirectory(UnicodeString & Path, const UnicodeString Prompt,
|
||||
bool PreserveFileName);
|
||||
|
||||
Reference in New Issue
Block a user