c ++ libssh - ssh_channel_read () продолжает возвращать 0, а ssh_channel_is_open () возвращает false - PullRequest
0 голосов
/ 19 мая 2018

Это первый раз, когда я внедряю ssh программным способом, и я озадачен тем, почему мой код не работает - если быть более точным, ssh_channel_read () продолжает возвращать прочитанные 0 байт.Я не знаю, что я делаю не так!Я следовал инструкциям API шаг за шагом, но я явно что-то случайно пропускаю.

Я пытаюсь подключиться к своему Pi с именем пользователя + паролем.Вот полный код, вы можете просто скопировать вставить и скомпилировать его:

g++ main.cpp -lssh -o myapp

После кода вы можете увидеть вывод, который я получаю.Пожалуйста, не будьте грубыми, как я уже сказал, это первый раз, когда я имею дело с SSH:

#include <iostream>
#include <string>
#include <libssh/libsshpp.hpp>

int main(int argc, const char **argv)
{
   int vbs                    = SSH_LOG_RARE;
   int timeout_ms             = 1000;
   ssh_session session        = ssh_new();

   ssh_channel channel;

   char        buffer[256];
   int         bytes_red;

   if (session == NULL)
   {
      std::cout << "Failed to create ssh session." << std::endl;
      exit(-1);
   }

   ssh_set_blocking(session, 1);

   std::cout << "Created SSH session..." << std::endl;

   ssh_options_set(session, SSH_OPTIONS_HOST, "192.168.1.5");
   ssh_options_set(session, SSH_OPTIONS_PORT_STR, "22");
   ssh_options_set(session, SSH_OPTIONS_USER, "pi@192.168.1.5");
   ssh_options_set(session,SSH_OPTIONS_LOG_VERBOSITY, &vbs);

   int con_result             = ssh_connect(session);
   int auth_result            = ssh_userauth_password(session, "pi", "1234");

   std::cout << "Connecton Result is: "   << con_result  << std::endl;
   std::cout << "Auth Result is: "        << auth_result << std::endl;

   ///////////////////////////////////////////
   // Did we create the session successfully?
   ///////////////////////////////////////////
   if (con_result != SSH_OK)
   {
      std::cout << "SSH connection failed. Error code is:  " << con_result << std::endl;
      ssh_free(session);
      return con_result;
   }

   ///////////////////////////////////////////
   // Did we authenticate?
   ///////////////////////////////////////////
   if (auth_result != SSH_AUTH_SUCCESS)
   {
      std::cout << "SSH authentication failed. Error code is:  " << auth_result << std::endl;
      ssh_free(session);
      return auth_result;
   }

   ///////////////////////////////////////////
   // Create a new ssh_channel
   ///////////////////////////////////////////
   channel = ssh_channel_new(session);

   if (channel == NULL)
   {
      std::cout << "Failed to create SSH channel." << std::endl;
      ssh_free(session);
      return SSH_ERROR;
   }

   if (ssh_channel_is_open(channel))
      std::cout << "Channel is open" << std::endl;
   else
      std::cout << "Channel is closed" << std::endl;

   while(!ssh_channel_is_eof(channel))
   {
      bytes_red = ssh_channel_read_timeout(channel, buffer, sizeof(buffer), 0, timeout_ms);

//    if (bytes_red)
         std::cout << "Bytes read: " << bytes_red << std::endl;
   }

   std::cout << "Exiting ..." << std::endl;

   ssh_channel_close(channel);
   ssh_channel_free(channel);
   ssh_free(session);

  return 0;
}

и вот вывод, который я получаю при его запуске:

$./myapp
Created SSH session...
[2018/05/19 14:57:14.246759, 1] socket_callback_connected:  Socket connection callback: 1 (0)
[2018/05/19 14:57:14.301270, 1] ssh_client_connection_callback:  SSH server banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 14:57:14.301321, 1] ssh_analyze_banner:  Analyzing banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 14:57:14.301337, 1] ssh_analyze_banner:  We are talking to an OpenSSH client version: 7.4 (70400)
Connecton Result is: 0
Auth Result is: 0
Channel is closed
[2018/05/19 14:57:14.669298, 1] ssh_packet_process:  Couldn't do anything with packet type 80
Bytes read: 0
Bytes read: 0
Bytes read: 0
Bytes read: 0
Bytes read: 0
^C
$

Я вижу ошибку "Канал закрыт", но почему?Что я делаю неправильно?

После этого я также хочу отправить данные на сервер и, очевидно, получить обратную связь.Из того, что я прочитал, ssh_channel_write () - это функция, которую нужно использовать.

Раньше я не имел дело с SSH программно, и я изучаю это, когда пишу это.

Вся ваша помощь очень ценится.

Обновление

Спасибо Джарре, я решил это!Вот окончательный код, который работает!

#include <iostream>
#include <string>
#include <libssh/libsshpp.hpp>

int main(int argc, const char **argv)
{
   int vbs                    = SSH_LOG_RARE;
   int timeout_ms             = 1000;
   ssh_session session = ssh_new();

   ssh_channel channel;

   char        buffer[256];
   int         bytes_red;

   if (session == NULL)
   {
      std::cout << "Failed to create ssh session." << std::endl;
      exit(-1);
   }

   ssh_set_blocking(session, 1);

   std::cout << "Created SSH session..." << std::endl;

   ssh_options_set(session, SSH_OPTIONS_HOST, "192.168.1.5");
   ssh_options_set(session, SSH_OPTIONS_PORT_STR, "22");
   ssh_options_set(session, SSH_OPTIONS_USER, "pi@192.168.1.5");
   ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &vbs);

   int con_result             = ssh_connect(session);
   int auth_result            = ssh_userauth_password(session, "pi", "1234");

   std::cout << "Connecton Result is: "   << con_result  << std::endl;
   std::cout << "Auth Result is: "        << auth_result << std::endl;

   ///////////////////////////////////////////
   // Did we create the session successfully?
   ///////////////////////////////////////////
   if (con_result != SSH_OK)
   {
      std::cout << "SSH connection failed. Error code is:  " << con_result << std::endl;
      ssh_free(session);
      return con_result;
   }

   ///////////////////////////////////////////
   // Did we authenticate?
   ///////////////////////////////////////////
   if (auth_result != SSH_AUTH_SUCCESS)
   {
      std::cout << "SSH authentication failed. Error code is:  " << auth_result << std::endl;
      ssh_free(session);
      return auth_result;
   }

   ///////////////////////////////////////////
   // Create a new ssh_channel
   ///////////////////////////////////////////
   channel = ssh_channel_new(session);

   if (channel == NULL)
   {
      std::cout << "Failed to create SSH channel." << std::endl;
      ssh_free(session);
      return SSH_ERROR;
   }

   ssh_channel_open_session(channel);

   if (ssh_channel_is_open(channel))
      std::cout << "Channel is open" << std::endl;
   else
      std::cout << "Channel is closed" << std::endl;

   int rc = ssh_channel_request_exec(channel, "ls");


   while(!ssh_channel_is_eof(channel))
   {
      bytes_red = ssh_channel_read_timeout(channel, buffer, sizeof(buffer), 0, timeout_ms);

//    if (bytes_red)
//       std::cout << "Bytes read: " << bytes_red << std::endl;

      std::cout << buffer << std::endl;
   }

   std::cout << "Exiting ..." << std::endl;

   ssh_channel_close(channel);
   ssh_channel_free(channel);
   ssh_free(session);

  return 0;
}

Для компиляции: g++ main.cpp -lssh -o myapp и вот что вы получаете, когда я запускаю его:

./myapp
Created SSH session...
[2018/05/19 16:01:41.830861, 1] socket_callback_connected:  Socket connection callback: 1 (0)
[2018/05/19 16:01:41.884875, 1] ssh_client_connection_callback:  SSH server banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 16:01:41.884929, 1] ssh_analyze_banner:  Analyzing banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 16:01:41.884945, 1] ssh_analyze_banner:  We are talking to an OpenSSH client version: 7.4 (70400)
Connecton Result is: 0
Auth Result is: 0
[2018/05/19 16:01:42.258668, 1] ssh_packet_process:  Couldn't do anything with packet type 80
Channel is open
Desktop
Documents
Downloads
Music
Pictures
Public
python_games
Templates
Videos
����s
Exiting ...

Мне просто нужно поработать над этимпоследний бит с забавными персонажами.Это прямо из моего редактора исходного кода, когда я только начал работать, поэтому код не идеален.

1 Ответ

0 голосов
/ 19 мая 2018

ssh_channel_new выделил ресурсы для нового канала.Он не открывается.

В зависимости от того, чего вы пытаетесь достичь, вам следует вызвать соответствующую функцию ssh_channel_open_XXXX на этом канале.

Простой пример можно найти здесь: https://github.com/substack/libssh/blob/c073979235eb0d0587ac9cb3c192e91e32d34b06/examples/exec.c

Сначала вызывается ssh_channel_open_session для открытия канала сеанса (оболочки), а затем вызывается ssh_channel_request_exec для выполнения команды lsof.

Как / когда вы будете писать вканал зависит от типа канала, который вы открыли.Пример записи в канал сеанса (после вызова cat > /dev/null на хосте для передачи записанных данных в / dev / null) можно увидеть здесь: https://github.com/substack/libssh/blob/c073979235eb0d0587ac9cb3c192e91e32d34b06/examples/senddata.c

...