AutoHotkey: Launch a putty session out of an active sftp-plugin connection within TC: Difference between revisions

From TotalcmdWiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
<pre>
<pre>
; AHK script to lauch a putty session out of active sftp-plugin connection within TC
; AHK script to launch a putty session out of active sftp-plugin connection within TC
;  using "server" and "user" params (client certificate not supported here)
;  using "server", "user" and "password" parameters (client certificate not supported here)
; version 09.09.2008
; version 29.09.2008
; author: TWatcher
; author: TWatcher
; this works only with sftp-plugin provided by Mr. Ghisler
; 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


#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 = 09.09.2008
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
  MsgBox,16,, TC is not active, doing nothing
  return
  return
}
}


Line 35: Line 50:
if 0 > 0
if 0 > 0
{
{
   par1 = %1%
   par = %1%
   if ( par1 = "-logToFile" )
   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 . " : AHK script to lauch a putty session out of active sftp-plugin connection within TC")
   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
      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
      Run, %startprg% -ssh %ItemServer% -l %ItemUser%, , UseErrorLevel  ;
      {
      if ErrorLevel = ERROR
        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,, The programm 'putty.exe' was not found or could not be launched`, please check your 'path' settings`!
         Log("Run, " . startprg . " -ssh " . ItemServer . " -l " . ItemUser )
         ;exit
        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,, The programm 'putty.exe' was not found or could not be launched`, please check your 'path' settings`!
         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