putty.iniからssh_configを生成する(手抜き)スクリプトを作ってみた

沢山あるPuTTyのホスト設定を移行するのが面倒だったので、かっとなって作りました。

  • PuTTyをiniファイル形式で使っている人用ですが。
  • PuTTyのバージョンによっては使えないかもしれません。
  • 全ての設定を変換するわけではありません。
  • 手抜きなので、Default Settingsも変換します(ご自身で削除して下さい)。
  • bash用です。
  • うまく変換できないときは、putty.iniの改行コードをLFにしてみて下さい。

変換できる設定は以下のものだけです。

  • セッション名
    • これが接続Hostになりますが、基本的には変換後にご自身で手を入れて頂くのが良いかと。エスケープ文字とかも入ると思うので。
  • 接続先情報(ホスト名、ポート番号)
  • ユーザ名
  • 秘密鍵
    • 但し、末尾の拡張子.ppkは除去します(どうせそのままでは使えないので)。
  • プロキシ(ホスト名・ポート番号)
    • SOCKS4、SOCKS5に限ります。
    • 認証は考えていません。
    • 実際に動作させるためには、connectコマンドを導入している必要があります。
  • トンネル

スクリプトの変数は以下の様に定めています。
それ以外は内部で使っているものなので変更はしないで下さい。

  • INIFILE
    • putty.iniのファイル名
  • CONFFILE
    • sshのconfigのファイル名
  • SOCKSCMD
    • connectコマンドのパス
  • TRCMD
    • trコマンドのパス

実行は、引数を付けずに実行するだけです。
CONFFILEに指定したファイルに出力しますが、標準出力にも同時に出力します。
標準出力に何も表示されずにコマンドが終了したときは、putty.iniの改行コードをLFにして再度試してみて下さい。


#!/usr/bin/bash

INIFILE=./putty.ini
CONFFILE=./p2config
SOCKSCMD=/usr/bin/connect
TRCMD=/usr/bin/tr

TMP_PXY_ENABLED=no
TMP_PXY_HOST=""
TMP_PXY_PORT=0
TMP_FWD_LALL=no
TMP_FWD_RALL=no
TMP_FWD_LIST=""

cat $INIFILE | while read -r LINE; do

    if [[ "$LINE" =~ ^\[Session:(.+)\]$ ]]; then
        TMP_PXY_ENABLED=no
        TMP_PXY_HOST=""
        TMP_PXY_PORT=0
        TMP_FWD_LALL=no
        TMP_FWD_RALL=no
        TMP_FWD_LIST=""
        echo Host ${BASH_REMATCH[1]} | tee -a $CONFFILE
    elif [[ "$LINE" =~ ^HostName=\"(.+)\"$ ]]; then
        echo -e \\tHostName\\t${BASH_REMATCH[1]} | tee -a $CONFFILE
    elif [[ "$LINE" =~ ^PortNumber=([0-9]+)$ ]]; then
        echo -e \\tPort\\t${BASH_REMATCH[1]} | tee -a $CONFFILE
    elif [[ "$LINE" =~ ^UserName=\"(.+)\"$ ]]; then
        echo -e \\tUser\\t${BASH_REMATCH[1]} | tee -a $CONFFILE
    elif [[ "$LINE" =~ ^PublicKeyFile=\"(.+)\.ppk\"$ ]]; then
        echo -e \\tIdentityFile\\t${BASH_REMATCH[1]} | tee -a $CONFFILE
    elif [[ "$LINE" =~ ^ProxyMethod=1|2$ ]]; then
        TMP_PXY_ENABLED=yes
    elif [[ "$LINE" =~ ^ProxyHost=\"(.+)\"$ ]]; then
        TMP_PXY_HOST=${BASH_REMATCH[1]}
    elif [[ "$LINE" =~ ^ProxyPort=([0-9]+)$ ]]; then
        TMP_PXY_PORT=${BASH_REMATCH[1]}
    elif [[ "$LINE" =~ ^LocalPortAcceptAll=1$ ]]; then
        TMP_FWD_LALL=yes
    elif [[ "$LINE" =~ ^RemotePortAcceptAll=1$ ]]; then
        TMP_FWD_RALL=yes
    elif [[ "$LINE" =~ ^PortForwardings=\"(.+)\"$ ]]; then
        TMP_FWD_LIST=${BASH_REMATCH[1]}
    fi

    # ProxyCommand
    if [ "$TMP_PXY_PORT" != "no" -a "$TMP_PXY_HOST" != "" -a $TMP_PXY_PORT -ne 0 ]; then
        echo -e \\tProxyCommand\\t$SOCKSCMD -S $TMP_PXY_HOST:$TMP_PXY_PORT %h %p | tee -a $CONFFILE
        TMP_PXY_ENABLED=no
        TMP_PXY_HOST=""
        TMP_PXY_PORT=0
    fi

    # PortForward
    if [ "$TMP_FWD_LIST" != "" ]; then
        FWD_LIST=( `echo "$TMP_FWD_LIST" | $TRCMD -s ',' ' '` )
        for ITEM in ${FWD_LIST[@]}; do
            if [[ "$ITEM" =~ ^L([0-9]+)=(.+:[0-9]+)$ ]]; then
                echo -en \\tLocalForward\\t | tee -a $CONFFILE
                if [ "$TMP_FWD_LALL" != "no" ]; then
                    echo -n : | tee -a $CONFFILE
                fi
                echo -e ${BASH_REMATCH[1]}\\t${BASH_REMATCH[2]} | tee -a $CONFFILE
            fi
            if [[ "$ITEM" =~ ^R([0-9]+)=(.+:[0-9]+)$ ]]; then
                echo -en \\tRemoteForward\\t | tee -a $CONFFILE
                if [ "$TMP_FWD_RALL" != "no" ]; then
                    echo -n : | tee -a $CONFFILE
                fi
                echo -e ${BASH_REMATCH[1]}\\t${BASH_REMATCH[2]} | tee -a $CONFFILE
            fi
            if [[ "$ITEM" =~ ^D([0-9]+)$ ]]; then
                echo -e \\tDynamicForward\\t${BASH_REMATCH[1]} | tee -a $CONFFILE
            fi
        done
        TMP_FWD_LALL=no
        TMP_FWD_RALL=no
        TMP_FWD_LIST=""
    fi

done

バグ報告は歓迎しますが、修正するとは限りません(ぇ