最終更新: haruyama_seigo 2011年07月19日(火) 15:37:23履歴
https://github.com/haruyama/ssh_client_sample/blob...
private def execCommand(transportManager: TransportManager, command: String) { // SSH-2.0-OpenSSH_5.8p1 Debian-4 の sshd に依存した作りになっている // 他の環境では動かない可能性がある // クライアント側のチャンネル番号 val senderChannel = 0 // initial window size と maximum packet size 値は適当 var windowSize = 32678 val maximumPacketSize = 32678 // SSH_MSG_CHANNEL_OPEN を送信する transportManager.sendMessage(ConnectionMessageBuilder.buildChannelOpenSession(senderChannel, windowSize, maximumPacketSize)) // SSH_MSG_CHANNEL_OPEN_CONFIRMATION を受信する val channelOpenConfirmation = transportManager.recvMessage().asInstanceOf[ChannelOpenConfirmation] // サーバ側のチャンネル番号 val serverChannel = channelOpenConfirmation.senderChannel.value // SSH_MSG_CHANNEL_REQUEST を送信する transportManager.sendMessage(ConnectionMessageBuilder.buildChannelRequestExec(serverChannel, command)) // SSH_MSG_CHANNEL_WINDOW_ADJUST を受信する val channelWindowAdjust = transportManager.recvMessage().asInstanceOf[ChannelWindowAdjust] // SSH_MSG_CHANNEL_SUCCESS を受信する val channelSuccess = transportManager.recvMessage().asInstanceOf[ChannelSuccess] // SSH_MSG_CHANNEL_DATA を受信する コマンド実行結果が含まれている val channelData = transportManager.recvMessage().asInstanceOf[ChannelData] println(new String(channelData.data.value)) // SSH_MSG_CHANNEL_EOF を受信する val channelEof = transportManager.recvMessage().asInstanceOf[ChannelEof] // SSH_MSG_CHANNEL_REQUEST を受信する val channelExitStatus = transportManager.recvMessage().asInstanceOf[ChannelRequestExitStatus] // SSH_MSG_CHANNEL_CLOSE を送信する transportManager.sendMessage(ConnectionMessageBuilder.buildChannelClose(serverChannel)) // SSH_MSG_CHANNEL_CLOSE を受信する val channelClose = transportManager.recvMessage().asInstanceOf[ChannelClose] }
コマンドの実行には, インタラクティブなセッションのチャンネルを開始する必要があります.
以下の形式の, SSH_MSG_CHANNEL_OPEN をクライアントはサーバに送ります.
byte SSH_MSG_CHANNEL_OPEN string "session" uint32 sender channel uint32 initial window size uint32 maximum packet size
- sender channel : 送り手(ここではクライアント)側のチャンネル. コネクションプロトコルでは同時に複数のチャンネルを実行することが可能なため, チャンネル番号でどのチャンネルへのメッセージかを判別する. サンプルプログラムでは1つのチャンネルのみを利用している.
- initial window size : チャンネルのデータを送り手に window の調整なしで送れる byte 数を指定する SSHコネクションプロトコルではチャンネルごとにフロー制御をするが, サンプルプログラムでは省略している.
- maximum packet size : 送り手に送ることができる1つのデータパケットの最大サイズを指定する
サーバはクライアントに SSH_MSG_CHANNEL_OPEN_CONFIRMATION を返します.
byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION uint32 recipient channel uint32 sender channel uint32 initial window size uint32 maximum packet size
- recipient channel : 受け取り手(ここではクライアント)側のチャンネル
- sender channel : 送り手(ここではサーバ)側のチャンネル
コマンドの実行には, 以下の形式の SSH_MSG_CHANNEL_REQUEST をクライアントはサーバに送ります.
byte SSH_MSG_CHANNEL_REQUEST uint32 recipient channel string "exec" boolean want reply string command
- recipient channel : 受け取り手(ここではサーバ)側のチャンネル. 受信した SSH_MSG_CHANNEL_OPEN_CONFIRMATION の recipient channel を指定します.
- want reply : 要求に対する返答が欲しいかどうか. サンプルプログラムでは TRUE を指定. FALSE を指定すると 後の SSH_MSG_CHANNEL_SUCCESS が送られてきません.
- command : コマンド
サーバはクライアントに SSH_MSG_CHANNEL_WINDOW_ADJUST を返します.
byte SSH_MSG_CHANNEL_WINDOW_ADJUST uint32 recipient channel uint32 bytes to add
- bytes to add : window に何バイト追加するか
サーバはクライアントに 要求が成功したことを示す SSH_MSG_CHANNEL_SUCCESS を返します. SSH_MSG_CHANNEL_REQUEST で want reply が FALSE の場合は返されません.
byte SSH_MSG_CHANNEL_SUCCESS uint32 recipient channel
サーバはクライアントに, コマンドの実行結果を含む SSH_MSG_CHANNEL_DATA を返します.
byte SSH_MSG_CHANNEL_DATA uint32 recipient channel string data
- data : この場合はコマンドの実行結果
サーバはクライアントに, もうこれ以上データを送らないことを示す SSH_MSG_CHANNEL_EOF を返します.
byte SSH_MSG_CHANNEL_EOF uint32 recipient channel
サーバはクライアントに, 終了ステータスの返却を行なう SSH_MSG_CHANNEL_REQUEST を返します.
この SSH_MSG_CHANNEL_REQUEST は以下の形式です. クライアントからコマンド文字列を送ったのも SSH_MSG_CHANNEL_REQUEST メッセージですが, 少し形式が異なります.
byte SSH_MSG_CHANNEL_REQUEST uint32 recipient channel string "exit-status" boolean FALSE uint32 exit_status
クライアントはこのメッセージに応答する必要はありません.
クライアントはサーバに チャンネルの終了を要求する SSH_MSG_CHANNEL_CLOSE を送り, サーバも SSH_MSG_CHANNEL_CLOSE を返します.
byte SSH_MSG_CHANNEL_CLOSE uint32 recipient channel
ローカルホストにid:test, password:test というユーザを作成して, 「ls」コマンドを実行してみた結果です. 外からアクセスできるホストにこのようなユーザは作らないようにしましょう.
% ls ~test a hotate ほげ % ls -l ~test 合計 0 -rw-r--r-- 1 test test 0 2011-06-21 13:33 a -rw-r--r-- 1 root root 0 2011-06-21 13:25 hotate -rw-r--r-- 1 root root 0 2011-07-04 15:11 ほげ % scala -cp lib/ganymed-ssh2-build210.jar target/scala-2.9.0.final/ssh-client-sample_2.9.0-1.0.jar \ localhost 22 test test "ls" a hotate ほげ % scala -cp lib/ganymed-ssh2-build210.jar target/scala-2.9.0.final/ssh-client-sample_2.9.0-1.0.jar \ localhost 22 test test "ls -l" 合計 0 -rw-r--r-- 1 test test 0 2011-06-21 13:33 a -rw-r--r-- 1 root root 0 2011-06-21 13:25 hotate -rw-r--r-- 1 root root 0 2011-07-04 15:11 ほげ
- カテゴリ:
- インターネット
- インターネットセキュリティ
最新コメント