AutoHotkey: Launch a putty session out of an active sftp-plugin connection within TC: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
<pre> | <pre> | ||
; AHK script to | ; AHK script to launch a putty session out of active sftp-plugin connection within TC | ||
; using "server" and " | ; using "server", "user" and "password" parameters (client certificate not supported here) | ||
; version | ; version 29.09.2008 | ||
; author: TWatcher | ; author: TWatcher | ||
; | ; This works only with sftp-plugin provided by Mr. Ghisler. | ||
; precondition: putty.exe has to be found within PC's path | ; precondition: putty.exe has to be found within PC's path | ||
; parameter: "-logToFile" will generate some log statements in file TcStrtPty.log, located in same dir as wincmd.ini | ; parameter: "-logToFile" will generate some log statements in file TcStrtPty.log, located in same dir as wincmd.ini | ||
; preparation: | ; preparation: | ||
; (1) save this AHK script to a file, e.g. TcStrtPty.ahk | ; (1) save this AHK script to a file, e.g. "TcStrtPty.ahk" | ||
; (2) compile this AHK script to an exe, execute: "Ahk2Exe.exe /in TcStrtPty.ahk" | ; (2) compile this AHK script to an exe, execute: "Ahk2Exe.exe /in TcStrtPty.ahk" | ||
; result should be TcStrtPty.exe | ; result should be "TcStrtPty.exe" | ||
; (3) Drag TcStrtPty.exe with the mouse to TC's Button bar. | ; (3) Drag "TcStrtPty.exe" with the mouse to TC's Button bar. | ||
; usage: | ; usage: | ||
; (4) within TC, within an active SFTP Session (!) just click on "TcStrtPty.exe-Button" in TC's Button bar. | ; (4) within TC, within an active SFTP Session (!) just click on "TcStrtPty.exe-Button" in TC's Button bar. | ||
; A putty window should open asking for username (if not stored in plugin-session settings) | |||
; and the password (if not stored in plugin-session settings). | |||
; If "user" and "password" are stored in plugin-session settings, then the scripts logs in automatically | |||
; without any further user interaction and the script tries to send a "cd" command to change | |||
; into directory which is the active directory in TotalCommander's sftp-plugin connection. | |||
; Note: | |||
; To avoid undesired user input during login/changing directory the AHK script blocks user input | |||
; (keyboard and mouse) for about 3 seconds. | |||
; Note: | |||
; Storage of passwords is a security risk and is not recommended, | |||
; however it is user's decision to use it or not and depending on the environment | |||
; (e.g. separate network) it is reasonable to use it. | |||
#IfWinExist, ahk_class TTOTAL_CMD | |||
title = AHK script to lauch a putty session out of active sftp-plugin connection within TotalCommander | |||
puttyErrMsg = The programm 'putty.exe' was not found or could not be launched`, please check your 'path' settings`! | |||
version = | version = 29.09.2008 | ||
startprg = putty.exe | startprg = putty.exe | ||
SearchStrg = \\\Secure FTP\ | SearchStrg = \\\Secure FTP\ | ||
Line 24: | Line 39: | ||
if not WinActive( "ahk_class TTOTAL_CMD" ) | if not WinActive( "ahk_class TTOTAL_CMD" ) | ||
{ | { | ||
MsgBox,16,, TC is not active, doing nothing | |||
return | |||
} | } | ||
Line 35: | Line 50: | ||
if 0 > 0 | if 0 > 0 | ||
{ | { | ||
par = %1% | |||
if ( | if ( par = "-h" ) { | ||
msgstring := title . "`n`n" | |||
msgstring := msgstring . "Usage:`n" | |||
msgstring := msgstring . A_ScriptName . " [-h]`n" | |||
msgstring := msgstring . A_ScriptName . " [-logToFile]`n" | |||
msgstring := msgstring . " '-h' : this help text`n" | |||
msgstring := msgstring . " '-logToFile' : logs to log file`n" | |||
MsgBox, 64, ,%msgstring% | |||
exitapp | |||
} | |||
loop, %0% | |||
{ | { | ||
DoLogToFile = True | par := %A_Index% | ||
if ( par = "-logToFile" ) { | |||
DoLogToFile = True | |||
} | |||
if ( par = "-showClearPw" ) { | |||
ShowClearPw = True | |||
} | |||
} | } | ||
} | } | ||
iniPath = %COMMANDER_INI% | iniPath = %COMMANDER_INI% | ||
Line 48: | Line 81: | ||
pos += 1 | pos += 1 | ||
StringLeft, iniPath, iniPath, pos | StringLeft, iniPath, iniPath, pos | ||
if DoLogToFile = True | if DoLogToFile = True | ||
Line 53: | Line 87: | ||
LogFile = %iniPath%TcStrtPty.log | LogFile = %iniPath%TcStrtPty.log | ||
FileDelete, %LogFile% | FileDelete, %LogFile% | ||
Log(A_ScriptName . " : | Log(A_ScriptName . " : " . title) | ||
Log("version: " . version) | Log("version: " . version) | ||
Log("Logging to file is active, LogFile: " . LogFile) | Log("Param: '-logToFile' : Logging to file is active, LogFile: " . LogFile) | ||
} | |||
if showClearPw | |||
{ | |||
Log("Param: '-showClearPw' : Show clear password in log is active") | |||
} | } | ||
Line 97: | Line 136: | ||
{ | { | ||
Log("Did not detect active 'Secure FTP' window in TC") | Log("Did not detect active 'Secure FTP' window in TC") | ||
MsgBox, 16,,Did not detect active 'Secure FTP' window in TC, can do nothing, aborting now... | MsgBox, 16,, Did not detect active 'Secure FTP' window in TC, can do nothing, aborting now... | ||
} | } | ||
Line 127: | Line 166: | ||
} | } | ||
IfInString, element, %Host% | IfInString, element, %Host% | ||
SectionFound := true | |||
} | } | ||
If SectionFound | If SectionFound | ||
Line 137: | Line 176: | ||
Indextmp += 1 | Indextmp += 1 | ||
ItemUser := Array%Indextmp% | ItemUser := Array%Indextmp% | ||
Indextmp += 1 | |||
ItemPassword := Array%Indextmp% | |||
Log(ItemServer . " " . ItemUser . " " . ItemPassword) | |||
StringReplace, ItemServer, ItemServer, server=, | StringReplace, ItemServer, ItemServer, server=, | ||
Line 151: | Line 193: | ||
StringReplace, ItemUser, ItemUser, user=, | StringReplace, ItemUser, ItemUser, user=, | ||
StringReplace, ItemPassword, ItemPassword, password=, | |||
Log("server='" . ItemServer . "' user='" . ItemUser . "'") | Log("server='" . ItemServer . "' user='" . ItemUser . "' password='" . ItemPassword . "'") | ||
Log("startdir='" . startdir . "'") | Log("startdir='" . startdir . "'") | ||
Line 160: | Line 203: | ||
MsgBox,16,, Empty entry for server in section '%element%' can do nothing, aborting now.. | MsgBox,16,, Empty entry for server in section '%element%' can do nothing, aborting now.. | ||
break | break | ||
} | |||
passwordClear = | |||
if ItemPassword | |||
{ | |||
passwordClear := DecryptPW(ItemPassword) | |||
} | } | ||
Line 165: | Line 214: | ||
{ | { | ||
Log("Now trying to start putty session to " . ItemUser . "@" . ItemServer ) | Log("Now trying to start putty session to " . ItemUser . "@" . ItemServer ) | ||
Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser ) | if passwordClear | ||
{ | |||
if ShowClearPw | |||
{ | |||
Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser . " -pw " . passwordClear) | |||
} | |||
else | |||
{ | |||
Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser . " -pw ******") | |||
} | |||
Run, %startprg% -ssh %ItemServer% -l %ItemUser% -pw %passwordClear%, , UseErrorLevel ; | |||
if ErrorLevel = ERROR | |||
{ | |||
MsgBox,16,, %puttyErrMsg% | |||
;exit | |||
} | |||
else | |||
{ | |||
if startdir | |||
{ | |||
Log("ItemServer: '" . ItemServer . "'") | |||
SetTitleMatchMode, 2 | |||
WinWait, %ItemServer%,, 10 | |||
if not ErrorLevel | |||
{ | |||
Log("found window: '" . ItemServer . "'") | |||
Log("switch BlockInput On ...") | |||
BlockInput On | |||
Log("going to sleep for 1000 ms ...") | |||
Sleep, 1000 | |||
IfWinActive, PuTTY Security | |||
{ | |||
Log("-found active window: PuTTY Security") | |||
Log("-switch BlockInput Off ...") | |||
BlockInput Off | |||
WinWaitNotActive, Security, , 55 | |||
if ErrorLevel | |||
{ | |||
Log("-active window: PuTTY Security was not closed within 55 seconds, aborting now") | |||
ExitApp ; | |||
} | |||
Log("-active window: PuTTY Security was closed") | |||
Log("going to sleep for 500 ms ...") | |||
Sleep, 500 | |||
} | |||
Log("after (optional) handling of Security alert ...") | |||
IfWinExist, %ItemServer% | |||
{ | |||
Log("+found existing window: '" . ItemServer . "'") | |||
IfWinNotActive, %ItemServer% | |||
{ | |||
Log("++window: '" . ItemServer . "' is not active, try to activate, wait 5 s") | |||
WinWaitActive, %ItemServer%,, 5 | |||
if ErrorLevel | |||
{ | |||
Log("ErrorLevel while wait for WinWaitActive for '" . ItemServer . "', ErrorLevel:'" . ErrorLevel . "'") | |||
} | |||
} | |||
Log("+found active window: '" . ItemServer . "'") | |||
Log("+switch BlockInput On ...") | |||
BlockInput On | |||
Log("+going to sleep for 500 ms ...") | |||
Sleep, 500 | |||
; check again | |||
IfWinActive, %ItemServer% | |||
{ | |||
Log("++found again active window: '" . ItemServer . "'") | |||
Log("++going to sleep for 1000 ms ...") | |||
Sleep, 1000 | |||
Log("++Sending input string startdir '" . startdir . "' ...") | |||
SendInput, cd %startdir%{Enter} | |||
} | |||
Log("+switch BlockInput Off ...") | |||
BlockInput Off | |||
Sleep, 2000 | |||
} | |||
else | |||
{ | |||
Log("+did not find window: '" . ItemServer . "', establishing of Putty session not successful, aborting now...") | |||
MsgBox Establishing of Putty session not successful, aborting now... | |||
Sleep, 2000 | |||
} | |||
} | |||
} | |||
} | |||
} | |||
else | |||
{ | { | ||
MsgBox,16,, | Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser ) | ||
Run, %startprg% -ssh %ItemServer% -l %ItemUser%, , UseErrorLevel ; | |||
if ErrorLevel = ERROR | |||
{ | |||
MsgBox,16,, %puttyErrMsg% | |||
} | |||
} | } | ||
} | } | ||
Line 180: | Line 323: | ||
if ErrorLevel = ERROR | if ErrorLevel = ERROR | ||
{ | { | ||
MsgBox,16,, | MsgBox,16,, %puttyErrMsg% | ||
} | } | ||
} | } | ||
break | break | ||
return | |||
} | } | ||
} | } | ||
Log("After loop, now return") | Log("After loop, now return") | ||
return | return | ||
;############################## | ;############################## | ||
Line 198: | Line 344: | ||
{ | { | ||
if LogFile | if LogFile | ||
FileAppend, %LogString% `n, %LogFile% | FormatTime, TimeString , , hh:mm:ss | ||
FileAppend, %TimeString% %LogString% `n, %LogFile% | |||
} | |||
} | |||
DecryptPW(pwString) | |||
{ | |||
g_pszKey = unpzScGeCInX7XcRM2z+svTK+gegRLhz9KXVbYKJl5boSvVCcfym | |||
iKeyLength := StrLen(g_pszKey) | |||
Log("called DecryptPW with pwString: " . pwString) | |||
iEncryptedLength := StrLen(pwString) | |||
EnvDiv, iEncryptedLength, 3 | |||
Log("iEncryptedLength: " . iEncryptedLength) | |||
iPos := mod(iEncryptedLength,iKeyLength) | |||
pwResult= | |||
Loop %iEncryptedLength% | |||
{ | |||
SetFormat, integer, hex | |||
StringLeft, i3Digits, pwString, 3 | |||
if i3Digits is not integer | |||
{ | |||
Log("--: i3Digits: should have digits only!, aborted") | |||
return | |||
} | |||
StringRight, pwString, pwString, StrLen(pwString)-3 | |||
encryptCharPos := Mod(A_Index + iPos,iKeyLength) | |||
encryptChar := SubStr(g_pszKey, encryptCharPos , 1) | |||
iEncryptChar := asc(encryptChar) | |||
Transform, result2, BitXOr, %iEncryptChar%, %i3Digits% | |||
pwResult:=pwResult . chr(result2) | |||
SetFormat, integer, d | |||
} | } | ||
global ShowClearPw | |||
if ShowClearPw | |||
Log("pwResult:: '" . pwResult . "'" ) | |||
Log("DecryptPW done") | |||
return pwResult | |||
} | } | ||
</pre> | </pre> |
Revision as of 21:08, 30 September 2008
; AHK script to launch a putty session out of active sftp-plugin connection within TC ; using "server", "user" and "password" parameters (client certificate not supported here) ; version 29.09.2008 ; author: TWatcher ; This works only with sftp-plugin provided by Mr. Ghisler. ; precondition: putty.exe has to be found within PC's path ; parameter: "-logToFile" will generate some log statements in file TcStrtPty.log, located in same dir as wincmd.ini ; preparation: ; (1) save this AHK script to a file, e.g. "TcStrtPty.ahk" ; (2) compile this AHK script to an exe, execute: "Ahk2Exe.exe /in TcStrtPty.ahk" ; result should be "TcStrtPty.exe" ; (3) Drag "TcStrtPty.exe" with the mouse to TC's Button bar. ; usage: ; (4) within TC, within an active SFTP Session (!) just click on "TcStrtPty.exe-Button" in TC's Button bar. ; A putty window should open asking for username (if not stored in plugin-session settings) ; and the password (if not stored in plugin-session settings). ; If "user" and "password" are stored in plugin-session settings, then the scripts logs in automatically ; without any further user interaction and the script tries to send a "cd" command to change ; into directory which is the active directory in TotalCommander's sftp-plugin connection. ; Note: ; To avoid undesired user input during login/changing directory the AHK script blocks user input ; (keyboard and mouse) for about 3 seconds. ; Note: ; Storage of passwords is a security risk and is not recommended, ; however it is user's decision to use it or not and depending on the environment ; (e.g. separate network) it is reasonable to use it. #IfWinExist, ahk_class TTOTAL_CMD title = AHK script to lauch a putty session out of active sftp-plugin connection within TotalCommander puttyErrMsg = The programm 'putty.exe' was not found or could not be launched`, please check your 'path' settings`! version = 29.09.2008 startprg = putty.exe SearchStrg = \\\Secure FTP\ if not WinActive( "ahk_class TTOTAL_CMD" ) { MsgBox,16,, TC is not active, doing nothing return } ; Read current TC dir from the panel left of the command line ControlGetText, TCPath, TMyPanel2 DoLogToFile = if 0 > 0 { par = %1% if ( par = "-h" ) { msgstring := title . "`n`n" msgstring := msgstring . "Usage:`n" msgstring := msgstring . A_ScriptName . " [-h]`n" msgstring := msgstring . A_ScriptName . " [-logToFile]`n" msgstring := msgstring . " '-h' : this help text`n" msgstring := msgstring . " '-logToFile' : logs to log file`n" MsgBox, 64, ,%msgstring% exitapp } loop, %0% { par := %A_Index% if ( par = "-logToFile" ) { DoLogToFile = True } if ( par = "-showClearPw" ) { ShowClearPw = True } } } iniPath = %COMMANDER_INI% StringLen, pos_prev, iniPath pos_prev += 1 StringGetPos, pos, iniPath, \, R1 pos += 1 StringLeft, iniPath, iniPath, pos if DoLogToFile = True { LogFile = %iniPath%TcStrtPty.log FileDelete, %LogFile% Log(A_ScriptName . " : " . title) Log("version: " . version) Log("Param: '-logToFile' : Logging to file is active, LogFile: " . LogFile) } if showClearPw { Log("Param: '-showClearPw' : Show clear password in log is active") } FormatTime, TimeString Log("Start " . TimeString) Log("iniPath: " . iniPath ) Log("Found running TC") Log("Active TCPath is: '" . TCPath ) ; Check whether TCPath starts with SearchStrg if ( InStr( TCPath, SearchStrg) > 0 ) { Log("Found SFTP within path") ; Replace SearchStrg StringReplace, TCPath, TCPath, %SearchStrg%, ; Replace the trailing > with a \ StringReplace, TCPath, TCPath, >, \ ; now replace any "\" by "/" StringReplace, TCPath, TCPath, \ , / , all ; now find 1st "/" StringGetPos, pos, TCPath, / if pos >= 0 { ; save startdir StringRight, startdir, TCPath, StrLen(TCPath) - pos ; and Remove rest StringLeft, Host, TCPath, pos } } Log("Host: '" . Host . "'") iniFile = %iniPath%sftpplug.ini ;############################## if Host { Log("SFTP-Ini File is : " . iniFile ) Gosub, SearchSection } else { Log("Did not detect active 'Secure FTP' window in TC") MsgBox, 16,, Did not detect active 'Secure FTP' window in TC, can do nothing, aborting now... } Log("done...") exitApp ;############################## SearchSection: ArrayCount = 0 SectionFound = Loop, Read, %iniFile% { ArrayCount += 1 ; Keep track of how many items are in the array. Array%ArrayCount% := A_LoopReadLine ; Store this line in the next array element. } ; Read from the array: Loop %ArrayCount% { If not SectionFound { element := Array%A_Index% if ( InStr( element, "[" ) = 1 ) { Log("Found section: " . element) } IfInString, element, %Host% SectionFound := true } If SectionFound { Log("--> found Host in charge") Indextmp = %A_Index% Indextmp += 1 ItemServer := Array%Indextmp% Indextmp += 1 ItemUser := Array%Indextmp% Indextmp += 1 ItemPassword := Array%Indextmp% Log(ItemServer . " " . ItemUser . " " . ItemPassword) StringReplace, ItemServer, ItemServer, server=, ; now replace any "\" by "/" StringReplace, ItemServer, ItemServer, \ , / , all ; now find 1st "/" StringGetPos, pos, ItemServer, / if pos >= 0 { ; Remove rest StringLeft, ItemServer, ItemServer, pos } StringReplace, ItemUser, ItemUser, user=, StringReplace, ItemPassword, ItemPassword, password=, Log("server='" . ItemServer . "' user='" . ItemUser . "' password='" . ItemPassword . "'") Log("startdir='" . startdir . "'") if not ItemServer { Log("Empty entry for server in section '" . element . "' can do nothing, aborting now..") MsgBox,16,, Empty entry for server in section '%element%' can do nothing, aborting now.. break } passwordClear = if ItemPassword { passwordClear := DecryptPW(ItemPassword) } if ItemUser { Log("Now trying to start putty session to " . ItemUser . "@" . ItemServer ) if passwordClear { if ShowClearPw { Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser . " -pw " . passwordClear) } else { Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser . " -pw ******") } Run, %startprg% -ssh %ItemServer% -l %ItemUser% -pw %passwordClear%, , UseErrorLevel ; if ErrorLevel = ERROR { MsgBox,16,, %puttyErrMsg% ;exit } else { if startdir { Log("ItemServer: '" . ItemServer . "'") SetTitleMatchMode, 2 WinWait, %ItemServer%,, 10 if not ErrorLevel { Log("found window: '" . ItemServer . "'") Log("switch BlockInput On ...") BlockInput On Log("going to sleep for 1000 ms ...") Sleep, 1000 IfWinActive, PuTTY Security { Log("-found active window: PuTTY Security") Log("-switch BlockInput Off ...") BlockInput Off WinWaitNotActive, Security, , 55 if ErrorLevel { Log("-active window: PuTTY Security was not closed within 55 seconds, aborting now") ExitApp ; } Log("-active window: PuTTY Security was closed") Log("going to sleep for 500 ms ...") Sleep, 500 } Log("after (optional) handling of Security alert ...") IfWinExist, %ItemServer% { Log("+found existing window: '" . ItemServer . "'") IfWinNotActive, %ItemServer% { Log("++window: '" . ItemServer . "' is not active, try to activate, wait 5 s") WinWaitActive, %ItemServer%,, 5 if ErrorLevel { Log("ErrorLevel while wait for WinWaitActive for '" . ItemServer . "', ErrorLevel:'" . ErrorLevel . "'") } } Log("+found active window: '" . ItemServer . "'") Log("+switch BlockInput On ...") BlockInput On Log("+going to sleep for 500 ms ...") Sleep, 500 ; check again IfWinActive, %ItemServer% { Log("++found again active window: '" . ItemServer . "'") Log("++going to sleep for 1000 ms ...") Sleep, 1000 Log("++Sending input string startdir '" . startdir . "' ...") SendInput, cd %startdir%{Enter} } Log("+switch BlockInput Off ...") BlockInput Off Sleep, 2000 } else { Log("+did not find window: '" . ItemServer . "', establishing of Putty session not successful, aborting now...") MsgBox Establishing of Putty session not successful, aborting now... Sleep, 2000 } } } } } else { Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser ) Run, %startprg% -ssh %ItemServer% -l %ItemUser%, , UseErrorLevel ; if ErrorLevel = ERROR { MsgBox,16,, %puttyErrMsg% } } } else { Log("Now trying to start putty session to " . ItemServer ) Log("Run, " . startprg . " -ssh " . ItemServer ) Run, %startprg% -ssh %ItemServer% , , UseErrorLevel ; if ErrorLevel = ERROR { MsgBox,16,, %puttyErrMsg% } } break return } } Log("After loop, now return") return ;############################## ;functions: ;############################## Log(LogString) { global if DoLogToFile = True { if LogFile FormatTime, TimeString , , hh:mm:ss FileAppend, %TimeString% %LogString% `n, %LogFile% } } DecryptPW(pwString) { g_pszKey = unpzScGeCInX7XcRM2z+svTK+gegRLhz9KXVbYKJl5boSvVCcfym iKeyLength := StrLen(g_pszKey) Log("called DecryptPW with pwString: " . pwString) iEncryptedLength := StrLen(pwString) EnvDiv, iEncryptedLength, 3 Log("iEncryptedLength: " . iEncryptedLength) iPos := mod(iEncryptedLength,iKeyLength) pwResult= Loop %iEncryptedLength% { SetFormat, integer, hex StringLeft, i3Digits, pwString, 3 if i3Digits is not integer { Log("--: i3Digits: should have digits only!, aborted") return } StringRight, pwString, pwString, StrLen(pwString)-3 encryptCharPos := Mod(A_Index + iPos,iKeyLength) encryptChar := SubStr(g_pszKey, encryptCharPos , 1) iEncryptChar := asc(encryptChar) Transform, result2, BitXOr, %iEncryptChar%, %i3Digits% pwResult:=pwResult . chr(result2) SetFormat, integer, d } global ShowClearPw if ShowClearPw Log("pwResult:: '" . pwResult . "'" ) Log("DecryptPW done") return pwResult }
Back to AutoHotkey