web-dev-qa-db-ja.com

コードでSSHを介してファイルを送信するためのプロトコルは何ですか?

SSHクライアントを介してファイルを送信するGoコードを読んでいました。

https://github.com/tmc/scp/blob/master/scp.go#L

それが行うことの1つはscp -t /remote/path。それは何ですか -tフラグ? man scp、しかしそれは文書化されていないようです。コマンドをローカルで実行したところ、猫のように動作しているようです。

実行後scp -tリモートで、コードは次のようにバイトをサーバーに送信します。

// Some special control header? What is this?
fmt.Fprintf(w, "C%#o %d %s\n", mode, size, fileName)
// Send file bytes.
io.Copy(w, contents)
// Send termination signal?
fmt.Fprint(w, "\x00")

このプロトコルは何ですか?どこに文書化されていますか?

6
425nesp

申し訳ありませんが、scpプロトコルは scp.c のソースコード以外のドキュメントには記載されていません。そのため、scpの動作の概要を説明します。

ソースまたは宛先のいずれかがリモートマシンである場合、scpsshを使用して接続し、scpプログラムを開始します。コピー方向がリモートからローカルである場合、scp -f src((from/source)、それ以外の場合はscp -t dstto/sink)として開始され、ローカルのscpは反対の姿勢をとります。

この後、2つのscpプロセスがscp接続の両端で実行され、それをstdin/stdoutとして使用して、ファイルデータとメタデータを渡します。

両端では、次の応答を使用してメッセージを確認したり、エラー状態を通知したりできます。

  1. "\0":OK

  2. "\1%s\n", err_msg:致命的でないエラー

  3. "\2%s\n", err_msg:致命的なエラー

転送は、to/sink scp\0(OK)ackを送信することから始まります。

次に、from/source scpは次のメッセージを使用します。

  1. "C%04o %lld %s\n", mode, size, filename:ファイルを作成

    この後には、sizeバイトのファイルデータとack(\0 = OK)が続きます。

  2. "D%04o 0 %.1024s\n", mode, dirname:ディレクトリの開始

    CD、またはTメッセージが再帰的に続き、

  3. "E\n":ディレクトリの終わり

  4. "T%llu 0 %llu 0\n", mtime, atime:ファイル時間

    これは、-pスイッチが使用された場合、CまたはDメッセージの前に送信されます。

これらのメッセージは、ファイルデータを送信する前のCとその後に送信されたackを含めて、先に進む前に相手側から確認応答を受ける必要があります。

上記のCおよびDメッセージでは、ファイル/ディレクトリ名の改行およびその他の制御文字(\tおよび\x7fを除く)は、たとえば次のようにエスケープされます。 \^J、ただし、宛先ではエスケープ解除されません。元の名前のリテラル\^Jまたは\^Mはそのまま残されます。

致命的なエラーと致命的でないエラーの違いは一貫していません。どちらかの側で\1(致命的ではない)エラーのみが生成されますが、それらのいくつかは致命的と見なされ、scpは送信または受信時に終了し、反対側は両方の部分を保持します。両側は\2(致命的)エラーまたは予期しない何かで終了します。

Httpとは異なり、ファイルデータをチャンクで送信するための規定はありません。ソースscpが、Cメッセージの後に送信を開始した大きなファイルを読み取ることができなくなった場合、\1エラーメッセージ/ nakの前に、そのsize NULバイトまで送信します。

6
mosvy