「Qtの基礎 - SSH」の版間の差分

ナビゲーションに移動 検索に移動
418行目: 418行目:
<br><br>
<br><br>


== libSSH2の使用例 ==
== libSSH2ライブラリを使用したコマンドの使用例 ==
以下の例では、リモート側のPCにSSH接続して、SCPでファイルを送信している。<br>
以下の例では、リモート側のPCにSSH接続して、lsコマンドを実行してその結果をローカル側のPCに表示している。<br>
<br>
<br>
以下の例は、<u>ノンブロッキングモード</u>でSCPを実行している。<br>
以下の例は、<u>ノンブロッキングモード</u>でSCPを実行している。<br>
473行目: 473行目:
  #include <QDebug>
  #include <QDebug>
  #include <libssh2.h>
  #include <libssh2.h>
#include <libssh2_sftp.h>
  #include "DivideByZeroException.h"
  #include "DivideByZeroException.h"
   
   
498行目: 497行目:
     int  Send(QTcpSocket &sock, LIBSSH2_SESSION *session);
     int  Send(QTcpSocket &sock, LIBSSH2_SESSION *session);
  #endif
  #endif
 
  int main(int argc, char *argv[])
  int main(int argc, char *argv[])
  {
  {
     QCoreApplication a(argc, argv);
     QCoreApplication a(argc, argv);
   
   
     int rc  = 0;
     const char *fingerprint;
 
     LIBSSH2_SESSION *session;
#if NOQTCPSOCKET
     LIBSSH2_CHANNEL *channel;
     int sock = 0;
     char *userauth_list;
 
     #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
      WSADATA wsadata;
      rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
      if(rc) {
          std::cerr << "WSAStartup failed with error: " << rc << std::endl;
          return -1;
      }
    #endif
 
#else
     QTcpSocket sock;
#endif
 
    LIBSSH2_SESSION *session = nullptr;
   
   
     // 初期化
     // libSSH2オブジェクトの初期化
     rc = libssh2_init(0);
     auto rc = libssh2_init(0);
     if (rc != 0) {
     if (rc != 0) {
      qDebug() << QString("libssh2 initialization failed %1").arg(rc);
        qDebug() << "libssh2 initialization failed";
      DisConnect(sock, session);
        return -1;
      return -1;
     }
     }
   
   
#if NOQTCPSOCKET  // QTcpSocketクラスを使用しない場合
     // QTcpSocketクラスのインスタンスを生成して、リモートPCに接続
     // ソケットの作成
     QTcpSocket socket;
     sock = socket(AF_INET, SOCK_STREAM, 0);
     socket.connectToHost(<リモートPCのIPアドレスまたはホスト名>, <リモートPCにSSH接続するポート番号>);
     if (sock == -1) {
      qDebug() << QString("failed to create socket.");
      DisConnect(sock, session);
   
   
    // 最大10[秒]待機
    if (!socket.waitForConnected(10000)) {
      qDebug() << "SSH接続に失敗:" << socket.errorString();
       return -1;
       return -1;
     }
     }
   
   
     struct sockaddr_in sin = {};
     // セッションの初期化
     sin.sin_family = AF_INET;
     session = libssh2_session_init();
    sin.sin_port = htons(<SSHのポート番号>);
     if (libssh2_session_handshake(session, socket.socketDescriptor()) != 0) {
    sin.sin_addr.s_addr = inet_addr("<リモート側PCのIPアドレス または ホスト名>");
       qDebug() << "SSHセッションの確立に失敗";
    // SSH接続
     if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) == -1) {
       qDebug() << QString("failed to connect.");
      DisConnect(sock, session);
       return -1;
       return -1;
     }
     }
#else  // QTcpSocketクラスを使用する場合
    QTcpSocket sock;
    sock.connectToHost(host, port);
    if (!sock.waitForConnected()) {
        qDebug() << "Failed to connect";
        DisConnect(sock, session);
   
   
        return -1;
    // リモートPCのフィンガープリントを確認
     }
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
#endif
     qDebug() << "リモートPCのフィンガープリント:" << fingerprint;
   
   
     // libSSH2のセッションを初期化
     // 認証方法の確認
     session = libssh2_session_init();
     userauth_list = libssh2_userauth_list(session, USERNAME, strlen(USERNAME));
     if (!session) {
     qDebug() << "認証方法:" << userauth_list;
      qDebug() << "Failed to initialize SSH session";
      DisConnect(sock, session);
   
   
    // パスワード認証を行う場合
    //if (libssh2_userauth_password(session, "<リモートPCのユーザ名>", "<リモートPCのユーザパスワード>") != 0) {
    //  qDebug() << "パスワードによる認証に失敗";
    //  return -1;
    //}
    // 公開鍵認証
    if (libssh2_userauth_publickey_fromfile(session, "<リモートPCのユーザ名>", "<公開鍵ファイルのパス>", "<秘密鍵ファイルのパス>", "<秘密鍵のパスフレーズ>") != 0) {
      qDebug() << "公開鍵認証に失敗";
       return -1;
       return -1;
     }
     }
   
   
#if NOQTCPSOCKET  // QTcpSocketクラスを使用しない場合
    // チャンネルをオープン
     // リモート側のPCとのハンドシェイク
     channel = libssh2_channel_open_session(session);
     if (libssh2_session_handshake(session, sock)) {
     if (!channel) {
       qDebug() << "SSH handshake failed";
       qDebug() << "チャンネルのオープンに失敗";
      DisConnect(sock, session);
       return -1;
       return -1;
     }
     }
#else  // QTcpSocketクラスを使用する場合
    if (libssh2_session_handshake(session, sock.socketDescriptor())) {
      qDebug() << "SSH handshake failed";
      DisConnect(sock, session);
   
   
    // リモートPC上でls -alコマンドを実行
    if (libssh2_channel_exec(channel, "ls -la") != 0) {
      qDebug() << "コマンドの実行に失敗";
       return -1;
       return -1;
     }
     }
#endif
    // パスワード認証
    if (libssh2_userauth_password(session, "<リモート側のユーザ名>", "<ユーザ名のパスワード>") != 0) {
      qDebug() << QString("Authentication failed.");
      DisConnect(sock, session);
   
   
       return -1;
    // ls -alコマンドの実行結果
    char buffer[1024] = {};
    while ((rc = libssh2_channel_read(channel, buffer, sizeof(buffer))) > 0) {
       qDebug().noquote() << QString::fromUtf8(buffer, rc);
     }
     }
   
   
     qDebug() << QString("Authentication succeeded.");
     // チャンネルをクローズ
    libssh2_channel_free(channel);
   
   
     // SSH接続後の処理
     // セッションのクローズ
     // SCPでファイルを送信
     libssh2_session_disconnect(session, "Normal Shutdown");
    rc = Send(sock, session);
     libssh2_session_free(session);
     if (rc != 0) {
      DisConnect(sock, session);
   
   
      return -1;
    // ソケットのクローズ
     }
     socket.disconnectFromHost();
   
   
     // SSH接続の終了
     // libssh2の初期化を解除
     DisConnect(sock, session);
     libssh2_exit();
   
   
     return 0;
     return a.exec();
  }
  }
   
   

案内メニュー