Pull to refresh

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

Configuring Linux *
Это перевод заметки о моем тестировании поддержки SFTP в midnight commander. Оригинал на английском опубликован в моем блоге.

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

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

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

Испробовав разные варианты с агентом — поинтересовался у автора, как работает у него. Оказалось, что без проблем. Позже нашел пример авторизации через ssh-agent на сайте разработчиков 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 с новой версией библиотеки. Готовую сборку можно забрать тут
Tags:
Hubs:
Total votes 29: ↑26 and ↓3 +23
Views 19K
Comments Comments 34