1

私は自分の娯楽のために小さなftpプロジェクトを書いています。これは4つのことができると思われます。

  1. FTPに直接接続する
  2. SSL(ラッパー)を使用してFTPに直接接続する
  3. sshトンネルを介してftpに接続します
  4. sshトンネルを介してSSLを使用してftpに接続します。

私は、2と4のOpenSSLに加えて、3と4のlibssh2を使用して、1と2の標準ライブラリを使用してプレーンC(unix、この場合は重要ではありません)でプログラムを書いています。

私は1〜3を動作させることができますが、4は動作しません。

  1. host:portへのソケットを開き、接続し、ソケットから書き込み/読み取りを行います。
  2. host:portへのソケットを開き、接続し、「AUTH SSL」を書き込んで、前のソケットからのBIOでSSLオブジェクトを開始します-> SSL_connect()、SSL_read()、SSL_write()。
  3. ターゲットとローカルホストの間にトンネルを開くことによって行われます(ただし、私のアプローチでローカルホストバインドを何に使用しているかはわかりません:)

何かのようなもの:

test_ssh_channel = libssh2_channel_direct_tcpip_ex(test_ssh_session, "100.100.100.100", 21, "127.0.0.1", 21);

次に、そのチャネルに書き込み/読み取りを行います(libssh2_channel_read())。これにより、次のフローが得られます。プレーンテキスト->ssh経由で送信->プレーンテキストをsshホストからターゲットに配信します。3.の目的のために、それは問題なく、仕事をします。

さて、4の場合、私は(単純にしようとして)どういうわけかこのチャネルをソケットに変える必要があるので、行き詰まっています。だから私はそれを見る方法には2つの選択肢があります:

  • a。疑似ソケットを作成し、読み取り/書き込みが必要になるたびに、チャネルから読み取り/書き込みを行い、それをソケットに送信/取得し、SSL_connect(pseudo_socket)が疑似ソケットと通信できるようにします。ssl_writeが送信するものを取り込むたびに、それをチャネルに送信し、その逆も同様です。

また

  • b。BIOバッファを設定し(頭を包み込むことができるよりも多くのBIO関数があります。ドキュメントはまったく役に立ちませんでした)、どういうわけかそれに読み取り/書き込みを行います。

この理由から、理想的には2を選択します。私のプロジェクトはCで記述されているため、他のコードを実行している間、ソケットの読み取り/書き込みを維持することは、私が望むよりも少し複雑になります。

ただし、b。問題が発生します。ハンドシェークがどのように機能するかが心配です。特に、いわばリモートホストではなくローカルホストでハンドシェイクを行うことになります。

私の質問を要約すると、チャネルを介してSSLで読み取り/書き込み(ラッパーを配置)して、4のフローが次のようになるようにすることはできますか?プレーンテキスト-> SSL(プレーンテキスト)->sshを介して->SSLを配信(プレーンテキスト)sshホストからターゲットホストに?

少し長いですが、理解できたと思います。そうでない場合は、お知らせください。明確にします。グーグル/検索stackoverflowから、これと同じ問題を抱えているのは私とmysqlで作業している人のようで、答えは限られています。

どんな入力でも大歓迎です!

  • ジェームズ
4

1 に答える 1

2

はい、オプション2が正しい方法です。でBIOペアを作成しBIO_make_bio_pair()、でSSLオブジェクトに割り当てますSSL_set_bio()

次に、暗号化された側のSSLデータをBIO_read()で読み取ってlibsshトンネルに書き込み、libsshトンネルから読み取ってで書き込みますBIO_write()


補遺:

このメソッドを使用する場合、SSLオブジェクトには独自のファイル記述子がありません。BIOがファイル記述子/ソケットを置き換えますOpenSSLは、ファイル記述子からの読み取りと書き込みの代わりに、指定したBIOからの読み取りと書き込みを行います。

BIOは、OpenSSLライブラリと独自のコードの間にある単なるインターフェイスです。これらは、暗号化された側のSSLデータの実際の転送を(ソケットを直接使用するOpenSSLの代わりに)反対側に実装するための方法です。

提供したBIO_read()BIOでを実行すると、暗号化された側のSSLデータが読み取られ、これを自分で反対側に送信する必要があります(おそらく何らかの機能を使用して)。同様に、暗号化された側のSSLデータを反対側から(ここでも一部の関数から)受信する場合は、として指定したBIOを使用してSSLにデータを送ります。wbioSSL_set_bio()libssh2libssh2BIO_write()rbio

おそらく、この図が役立つでしょう。SSLオブジェクトから読み取りと書き込みを行う場合、OpenSSLは基盤となるBIOから読み取りと書き込みを行うだけで、後で処理できるようにデータを残します。

+------+               +-----+               +-----+
| Your | SSL_write()   | SSL | BIO_read()    | BIO |
| code | ------------> |     | <------------ |     |
|      |               |     |               |     |
|      |               |     | BIO_write()   |     |
|      |               |     | ------------> |     |
+------+               +-----+               +-----+

+------+              +-----+               +-----+
| Your | SSL_read()   | SSL | BIO_read()    | BIO |
| code | <----------- |     | <------------ |     |
|      |              |     |               |     |
|      |              |     | BIO_write()   |     |
|      |              |     | ------------> |     |
+------+              +-----+               +-----+

(ただし、は基になるBIOからの読み取りSSL_write()を引き起こす可能性があり、その逆もあることに注意してください)。

にデータがある場合はwbio、それを読み取って反対側に発送する必要があります。

+------+              +-----+
| Your | BIO_read()   | BIO |
| code | <----------- |     |
|      |              +-----+
|      |                           +---------+
|      | libssh2_channel_write()   | libssh2 |
|      | ------------------------> |         | -> (... to other side)
|      |                           +---------+
+------+

逆に、反対側から利用可能なデータがある場合は、それを読み取ってrbio:に渡す必要があります。

+------+
| Your |                          +---------+
| code | libssh2_channel_read()   | libssh2 |
|      | <----------------------- |         | -> (... from other side)
|      |                          +---------+
|      |              +-----+
|      | BIO_write()  | BIO |
|      | -----------> |     |
|      |              +-----+
+------+
于 2010-06-21T14:47:03.813 に答える