Libssh2 linux examples с

Libssh2 linux examples с

libssh2 is a client-side C library implementing the SSH2 protocol

  • Key Exchange Methods: diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group-exchange-sha256
  • Hostkey Types: ssh-rsa, ssh-dss
  • Ciphers: aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, arcfour, arcfour128, none
  • Compression Schemes: zlib, zlib@openssh.com, none
  • MAC hashes: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, hmac-md5-96, hmac-ripemd160 (hmac-ripemd160@openssh.com), none
  • Authentication: none, password, public-key, hostbased, keyboard-interactive
  • Channels: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem
  • Global Requests: tcpip-forward
  • Channel Requests: x11, pty, exit-signal, keepalive@openssh.com
  • Subsystems: sftp(version 3), publickey(version 2)
  • SFTP: statvfs@openssh.com, fstatvfs@openssh.com
  • Thread-safe: just don’t share handles simultaneously
  • Non-blocking: it can be used both blocking and non-blocking
  • Your sockets: the app hands over the socket, calls select() etc.
  • Crypto backends: OpenSSL, libgcrypt, mbedTLS or WinCNG (native since Windows Vista): builds with either
  • mail: The main place to take issues, discuss development or ask about how to use libssh2 is the libssh2-devel mailing list.
  • Bugs:github issue tracker

Источник

C: libssh — пример SSH-«клиента»

Ниже рассматривается пример написания SSH-клиента на C с использованием libssh .

Сама библиотека libssh уже устарела, и вместо неё рекомендуется libssh2 .

Сравнение libssh и libssh2 есть тут>>>.

Тем не менее у libssh отличные примеры (которые и используются в примерах ниже с небольшими отличаями) и документация, поэтому использую её.

RFC 4251 в SSH Protocol Architecture описывает три основных компонента:

  • SSH-TRANS : The Secure Shell (SSH) Transport Layer Protocol
    Предоставляет авторизацию сервера, секретность и целостность данных. так же может предосталвять компрессию. Как правило работает поверх установленного TCP/IP соединения.
  • SSH-USERAUTH : The Secure Shell (SSH) Authentication Protocol
    Предоставляет аутентификацию клиента на сервере. Работает поверх SSH Transport Layer Protocol.
  • SSH-CONNECT : The Secure Shell (SSH) Connection Protocol
    Разделяет зашифрованный туннель на несколько логических каналов. Предоставляет интерактивные сессии для авторизации, удалённого выполенния команд, форвардинга TCP/IP и X11 соединений. Работает поверх SSH Authentication Protocol.

Последовательность установления сессии хорошо описана тут>>> и тут>>>.

Кратко — стандартная SSH сессия устанавливается следующим образом:

  • Установка соединения с SSH-сервером. Выполняется handshake, в результате которого клиент получает от сервера публичный ключ. Клиент выполняет проверку ключа с помощью отпечатка или файла known_hosts .
  • Клиент выполняет авторизацию. Стандартный способ — пароль, так же может использоваться авторизация по ключам (RSA или DSA, сгенерированные с помощью openssl ) или SSH-агент.
  • Как только клиент авторизован — можно открыть один или больше каналов (теоретически — любое кол-во). Каналы являются способом передачи данных через единое SSH-соединение. Каждый такой канал имеет свой stdout и stderr .
  • Открыв канал клиент может:
    • выполнить удалённую команду
    • открыть командную оболочку (shell)
    • использовать подсистемы sftp или scp для передачи данных
  • По завершении сеанса — закрывается канал, затем закрывается само соединение.

Создание и параметры сессии

Наиболее важным объектом в SSH соединении является SSH сессия.

Для создания сессии — используется функция ssh_new() :

libssh следует модели allocate-it-deallocate-it, т.е. каждый объект, созданный с помощью xxxxx_new() должен быть удалён с помощью xxxxx_free() .

В данном случае — мы создаём объект с помощью ssh_new() , и очищаем его из памяти с помощью ssh_free() .

Для задания параметров сесси используется функция ssh_options_set() .

Наиболее важные опции:

  • SSH_OPTIONS_HOST : имя хоста, к котормоу выполняется подключение
  • SSH_OPTIONS_PORT : порт для подключения (по умолчанию 22)
  • SSH_OPTIONS_USER : пользователь
  • SSH_OPTIONS_LOG_VERBOSITY : уровень детализации сообщений об ошибках

Обязательным параметром является только SSH_OPTIONS_HOST .

Если вы не указываете SSH_OPTIONS_USER — будет использовано имя пользователя, который выполняет программу:

Подключение

Теперь, когда сессия и параметры готовы — можно выполнить подключение.

Читайте также:  Резервное копирование профиля пользователя windows 10

Для этого используем ssh_connect() .

Перепишем код — вынесем имя хоста в первый аргумент, порт — во второй, и попробуем подключиться:

Источник

Асинхронный обмен данными с удалённым приложением через SSH

Доброго времени суток, друзья и коллеги. Меня всё ещё зовут Дмитрий Смирнов, и я всё ещё, к моему вящему удовольствию, являюсь разработчиком ISPsystem. Некоторое время назад я начал работу над совершенно новым проектом, который меня очень вдохновил, поскольку новое — это в нашем случае отсутствие легаси кода и поддержки старых компиляторов. Здравствуй, Boost, C++17 и все прочие радости современной разработки.

Так случилось, что все мои прошлые проекты были многопоточными, соответственно, у меня было крайне мало опыта с асинхронными решениями. Именно это стало самым приятным для меня в этой разработке, помимо современных мощных инструментов.

Одной из последних сопутствующих задач стала необходимость написать обёртку над библиотекой libssh2 в реалиях асинхронного приложения, использующего Boost.Asio, и способного породить не более двух потоков. Об этом и расскажу.

Примечание: автор предполагает, что читатель знаком с основами асинхронной разработки и boost::asio.

Задача

В общих чертах задача стояла следующим образом: подключиться к удалённому серверу, используя rsa-ключ или логин и пароль; загрузить на удалённую машину некий скрипт и запустить его; вычитывать его ответы и присылать ему команды через то же самое соединение. При этом, разумеется, не блокируя потока (который является половиной всего возможного пула).

Дисклеймер: я знаю, что в Poco реализована работа с SSH, но я не нашёл способа поженить его с Asio, да и написать что-то своё было интереснее :-).

Инициализация

Для инициализации и сворачивания библиотеки я решил воспользоваться обычным синглтоном:

Есть в этом решении, разумеется, и подводные камни, согласно моей любимой настольной книге «Тысяча и один способ выстрелить себе в ногу в C++». Если кто-то порождает поток, который забудут поджойнить, и главный завершится раньше, вполне могут возникнуть интересные спецэффекты. Но в данном случае я не буду учитывать подобную возможность.

Основные сущности

После разбора примера становится понятно, что для нашей небольшой библиотеки понадобятся три несложные сущности: сокет, сессия и канал. Поскольку неплохо иметь и синхронные инструменты, мы пока оставим Asio в стороне.

Начнём с простого сокета:

Раз уж мы теперь имеем сокет и сессию, неплохо было бы написать функцию ожидания для сокета в реалиях libssh2:

Собственно, это практически ничем не отличается от приведённого выше примера, кроме того, что там используется select вместо poll.

Остаётся канал. В libssh2 есть несколько видов каналов: простой, SCP, direct tcp. Нас интересует самый простой, базовый канал:

Теперь, когда все основные инструменты готовы, остаётся установить соединение с хостом и производить необходимые нам манипуляции. Асинхронная запись в канал и синхронная, разумеется, будут очень сильно различаться, а вот процесс установления соединения — нет.

Поэтому напишем базовый класс:

Вот теперь мы готовы написать простейший класс для соединения с удалённым хостом и выполнения на нем какой-либо команды:

До сих пор всё, что мы писали, было простым приведением примеров libssh2 к более цивилизованному виду. Но теперь, имея все простые инструменты для синхронной записи данных в канал, мы можем перейти к Asio.

Иметь стандартный сокет — это хорошо, но не слишком практично, если нужно асинхронно дождаться его готовности к чтению\записи, занимаясь в процессе своими делами. Тут на помощь приходит boost::asio::ip::tcp::socket, имеющий замечательный метод:

Он замечательным образом конструируется из обычного сокета, для которого мы уже заблаговременно установили соединение и boost::asio::io_context — контекста выполнения нашего приложения.

Теперь нам надо начать выполнение какой-либо команды на удалённом хосте и, по мере поступления данных от нее, отдавать их в некоторый коллбэк.

Таким образом, запустив команду, мы передаем управление методу TryRead().

Первым делом мы проверяем, не запущен ли уже процесс чтения каким-то предыдущим вызовом. Если нет, то начинаем ожидать готовности сокета для чтения. В качестве хендлера ожидания используется обычная лямбда с захватом shared_from_this().

Читайте также:  Как найти windows phone с компьютера

Обратите внимание на вызов WantRead(). Async_wait, как оказалось, тоже имеет свои изъяны, и может просто вернуться по таймауту. Чтобы в этом случае не производить лишних действий, я решил проверять сокет через poll без таймаута — действительно ли сокет хочет читать сейчас. Если нет, то мы просто снова запускаем TryRead() и ждём. В противном случае мы сразу приступаем к чтению и передаче данных в коллбэк.

Таким образом, запускается бесконечный асинхронный цикл чтения от запущенного приложения. Следующим шагом для нас станет отправление инструкций приложению:

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

Таким образом, мы будем записывать в канал данные до тех пор, пока они все не будут успешно переданы. Затем вернём управление вызывающей стороне, чтобы можно было передать новую порцию данных. Так можно не только слать инструкции какому-то приложению на хосте, но и, например, загружать небольшими порциями файлы любого размера, при этом не блокируя тред, что немаловажно.

С помощью этой библиотеки мне удалось успешно запускать на удалённом сервере скрипт, отслеживающий изменения файловой системы, одновременно вычитывая его вывод и посылая различные команды. В целом: очень ценный опыт адаптации си-стайл библиотеки для современного C++ проекта, использующего Boost.

Источник

libssh

This is the online reference for developing with the libssh library. It documents the libssh C API and the C++ wrapper.

Linking

We created a small howto how to link libssh against your application, read The Linking HowTo .

Tutorial

You should start by reading The Tutorial , then reading the documentation of the interesting functions as you go.

Features

The libssh library provides:

  • Key Exchange Methods : curve25519-sha256 @ libssh . org, ecdh-sha2-nistp256, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
  • Hostkey Types : ecdsa-sha2-nistp256, ssh-dss, ssh-rsa
  • Ciphers : aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc (rijndael-cbc @ lysator . liu . se), aes192-cbc, aes128-cbc, 3des-cbc, des-cbc-ssh1, blowfish-cbc, none
  • Compression Schemes : zlib, zlib @ openssh . com, none
  • MAC hashes : hmac-sha1, none
  • Authentication : none, password, public-key, hostbased, keyboard-interactive, gssapi-with-mic
  • Channels : shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, auth-agent-req @ openssh . com
  • Global Requests : tcpip-forward, forwarded-tcpip
  • Channel Requests : x11, pty, exit-status, signal, exit-signal, keepalive @ openssh . com, auth-agent-req @ openssh . com
  • Subsystems : sftp(version 3), publickey(version 2), OpenSSH Extensions
  • SFTP : statvfs @ openssh . com, fstatvfs @ openssh . com
  • Thread-safe : Just don’t share sessions
  • Non-blocking : it can be used both blocking and non-blocking
  • Your sockets : the app hands over the socket, or uses libssh sockets
  • OpenSSL or gcrypt : builds with either

Additional Features

  • Client and server support
  • SSHv2 and SSHv1 protocol support
  • Supports Linux, UNIX, BSD, Solaris, OS/2 and Windows
  • Automated test cases with nightly tests
  • Event model based on poll(2), or a poll(2)-emulation.

libssh is a project with distributed copyright ownership, which means we prefer the copyright on parts of libssh to be held by individuals rather than corporations if possible. There are historical legal reasons for this, but one of the best ways to explain it is that it’s much easier to work with individuals who have ownership than corporate legal departments if we ever need to make reasonable compromises with people using and working with libssh.

We track the ownership of every part of libssh via git, our source code control system, so we know the provenance of every piece of code that is committed to libssh.

So if possible, if you’re doing libssh changes on behalf of a company who normally owns all the work you do please get them to assign personal copyright ownership of your changes to you as an individual, that makes things very easy for us to work with and avoids bringing corporate legal departments into the picture.

Читайте также:  Linux дополнительные кнопки мыши

If you can’t do this we can still accept patches from you owned by your employer under a standard employment contract with corporate copyright ownership. It just requires a simple set-up process first.

We use a process very similar to the way things are done in the Linux Kernel community, so it should be very easy to get a sign off from your corporate legal department. The only changes we’ve made are to accommodate the license we use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.

The process is called signing.

How to sign your work

Once you have permission to contribute to libssh from your employer, simply email a copy of the following text from your corporate email address to:

We will maintain a copy of that email as a record that you have the rights to contribute code to libssh under the required licenses whilst working for the company where the email came from.

Then when sending in a patch via the normal mechanisms described above, add a line that states:

using your real name and the email address you sent the original email you used to send the libssh Developer’s Certificate of Origin to us (sorry, no pseudonyms or anonymous contributions.)

That’s it! Such code can then quite happily contain changes that have copyright messages such as:

and can be merged into the libssh codebase in the same way as patches from any other individual. You don’t need to send in a copy of the libssh Developer’s Certificate of Origin for each patch, or inside each patch. Just the sign-off message is all that is required once we’ve received the initial email.

Have fun and happy libssh hacking!

The libssh Team

Internet standard

Secure Shell (SSH)

The following RFC documents described SSH-2 protcol as an Internet standard.

  • RFC 4250, The Secure Shell (SSH) Protocol Assigned Numbers
  • RFC 4251, The Secure Shell (SSH) Protocol Architecture
  • RFC 4252, The Secure Shell (SSH) Authentication Protocol
  • RFC 4253, The Secure Shell (SSH) Transport Layer Protocol
  • RFC 4254, The Secure Shell (SSH) Connection Protocol
  • RFC 4255, Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
  • RFC 4256, Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
  • RFC 4335, The Secure Shell (SSH) Session Channel Break Extension
  • RFC 4344, The Secure Shell (SSH) Transport Layer Encryption Modes
  • RFC 4345, Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol

It was later modified and expanded by the following RFCs.

  • RFC 4419, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
  • RFC 4432, RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
  • RFC 4462, Generic Security Service Application Program Interface (GSS-API) Authentication and Key Exchange for the Secure Shell (SSH) Protocol
  • RFC 4716, The Secure Shell (SSH) Public Key File Format
  • RFC 5647, AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
  • RFC 5656, Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer

Interesting cryptography documents:

  • PKCS #11, PKCS #11 reference documents, describing interface with smartcards.

Secure Shell File Transfer Protocol (SFTP)

The protocol is not an Internet standard but it is still widely implemented. OpenSSH and most other implementation implement Version 3 of the protocol. We do the same in libssh.

Secure Shell Extensions

The libssh project has an extension to support Curve25519 which is also supported by the OpenSSH project.

The OpenSSH project has defined some extensions to the protocol. We support some of them like the statvfs calls in SFTP or the ssh-agent.

Источник

Оцените статью