MyTetra Share
Делитесь знаниями!
Поддержка SFTP в midnight commander
Время создания: 11.12.2011 15:45
Раздел: OS tools - Linux
Запись: YellowRaven/myTetra_repo/master/base/1323603931l53vhn58ja/text.html на raw.github.com

Поддержка SFTP в midnight commander

Это перевод заметки о моем тестировании поддержки SFTP в midnight commander. Оригинал на английском опубликован в моем блоге (http://blog.tataranovich.com/2011/12/sftp-suppot-in-midnight-commander.html).

Продолжаю следить за разработкой поддержки SFTP в midnight commander, на этой неделе общался с автором — в поддержке sftp появилась авторизация через ssh-agent. На радостях я быстренько накидал пакет и затестил его.


И первое разочарование — midnight не может авторизоваться через агента. Я попробовал предыдущие схемы авторизации, которые работали в предыдущей версии:

  • по паролю — работает без проблем;
  • по ключу — работает, но только для ключей, которые не защищены паролем (судя по всему это ограничение библиотеки).


Испробовав разные варианты с агентом — поинтересовался у автора, как работает у него. Оказалось, что без проблем. Позже нашел 
пример авторизации через ssh-agent (http://www.libssh2.org/examples/ssh2_agent.html) на сайте разработчиков libssh2 и попробовал его скомпилировать

$ gcc -o agent_auth -Wall -I/usr/include -I. -lssh2 ssh2_agent.c

ssh2_agent.c: In function ‘main’:

ssh2_agent.c:99: warning: implicit declaration of function ‘libssh2_session_handshake’

/home/andrey/tmp/ccmczn2V.o: In function `main':

ssh2_agent.c:(.text+0x1a8): undefined reference to `libssh2_session_handshake'

collect2: ld returned 1 exit status


Сообщение об ошибке навело на мысль, что пример рассчитан на версию, которая новее той, что находится в репозитарии debian squeeze. Попробовал собрать текущую версию libssh2 (1.3.0) и пересобрать пример с уже новой библиотекой.

$ gcc -o agent_auth -Wall -I$PWD/libssh2/include -I. -L$PWD/libssh2/lib -lssh2 ssh2_agent.c


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

$ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent-auth localhost andrey

failed to connect!

zsh: segmentation fault ./agent_auth localhost andrey


Запуск под strace показал, что во-первых соединение идет на 255.255.255.255 вместо 127.0.0.1, а во вторых код примера пытается освобождать ресурсы без проверки их использования. Отсюда и segfault при выходе.

munmap(0xb7813000, 4096) = 0

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3

connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("255.255.255.255")}, 16) = -1 ENETUNREACH (Network is unreachable)

write(2, "failed to connect!\n", 19failed to connect!

) = 19

--- SIGSEGV (Segmentation fault) @ 0 (0) ---

+++ killed by SIGSEGV +++

zsh: segmentation fault strace -f ./agent_auth localhost username


Добавил проверку перед освобождением ресурсов

--- ssh2_agent.c.orig 2011-12-08 23:53:41.000000000 +0300

+++ ssh2_agent.c 2011-12-09 00:02:10.000000000 +0300

@@ -231,10 +231,12 @@ int main(int argc, char *argv[])

*/

shutdown:

-

- libssh2_agent_disconnect(agent);

- libssh2_agent_free(agent);

+ if (agent) {

+ libssh2_agent_disconnect(agent);

+

+ libssh2_agent_free(agent);

+ }

if(session) {


После чего пересобрал и запустил.

$ gcc -o agent_auth -Wall -I$PWD/libssh2/include -I. -L$PWD/libssh2/lib -lssh2 ssh2_agent.c

$ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent_auth localhost andrey

failed to connect!


Уже лучше — segfault на выходе исчез, но ругается на невозможность подключиться. Снова смотрю в код. Для преобразования хоста в формат понятный функции connect() используется inet_addr()

if (argc > 1) {

hostaddr = inet_addr(argv[1]);

} else {

hostaddr = htonl(0x7F000001);

}


Смотрю в man 3 inet_addr и вижу, что функция преобразует символьную запись ip адреса в его бинарное представление. Bingo! Я ведь передаю имя хоста как localhost. Заменив localhost на 127.0.0.1 получаю работающий пример.

$ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent_auth 127.0.0.1 andrey

Fingerprint: FA F3 92 9E C4 AE 14 B4 FC BE ED 2A E8 33 0C 1E 34 09 9F B3

Authentication methods: publickey,password

Authentication with username andrey and public key /home/andrey/.ssh/id_rsa failed!

Authentication with username andrey and public key /home/andrey/.ssh/id_dsa succeeded!

all done!


Теперь дело за малым — собрать версию libssh2 (1.3.0) для squeeze и пересобрать midnight с новой версией библиотеки. Готовую сборку можно забрать 
тут (http://www.tataranovich.com/public/mc-sftp/2011-12-08/)

 
MyTetra Share v.0.59
Яндекс индекс цитирования