Back to Home

SFTP support in midnight commander

This is a translation of a note on my testing of SFTP support in the midnight commander. The original in English is published on my blog. I continue to monitor the development of SFTP support in midnight ...

SFTP support in midnight commander

    This is a translation of a note on my testing of SFTP support in the midnight commander. The original in English is published on my blog .

    I continue to monitor the development of SFTP support in the midnight commander, this week I talked with the author - authorization via ssh-agent appeared in sftp support. To celebrate, I quickly threw the bag and tested it.

    And the first disappointment is that midnight cannot log in through the agent. I tried the previous authorization schemes that worked in the previous version:

    • by password - it works without problems;
    • by key - it works, but only for keys that are not password protected (apparently this is a library limitation).

    Having tried different options with an agent, I asked the author how it works for him. It turned out that no problem. Later I found an authorization example via ssh-agent on the libssh2 developers site and tried to compile it

    $ gcc -o agent_auth -Wall -I/usr/include -I. -lssh2 ssh2_agent.c
    ssh2_agent.c: Infunction ‘main’:
    ssh2_agent.c:99: warning: implicit declaration offunction ‘libssh2_session_handshake’
    /home/andrey/tmp/ccmczn2V.o: Infunction `main':
    ssh2_agent.c:(.text+0x1a8): undefined reference to `libssh2_session_handshake'
    collect2: ld returned 1exit status
    

    The error message suggested that the example is designed for a version that is newer than the one in the debian squeeze repository. I tried to build the current version of libssh2 (1.3.0) and rebuild the example with an already new library.

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

    After that, the example was assembled without errors, but refused to work, citing the inability to connect.

    $ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent-auth localhost andrey
    failed toconnect!
    zsh: segmentation fault  ./agent_auth localhost andrey
    

    Running under strace showed that, firstly, the connection goes to 255.255.255.255 instead of 127.0.0.1, and secondly, the example code tries to free resources without checking their use. Hence the segfault when exiting.

    munmap(0xb7813000, 4096)                = 0
    socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3connect(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 toconnect!
    )    = 19--- SIGSEGV (Segmentation fault) @ 0 (0) ---
    +++ killed by SIGSEGV +++
    zsh: segmentation fault  strace -f ./agent_auth localhost username
    

    Added check before releasing resources

    --- 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) {
    

    Then rebuilt and launched.

    $ 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!
    

    Already better - segfault at the exit disappeared, but swears at the inability to connect. I look at the code again. Inet_addr () is used to convert the host into a format that the connect () function understands.

    if (argc > 1) {
            hostaddr = inet_addr(argv[1]);
        } else {
            hostaddr = htonl(0x7F000001);
        }
    

    I look in man 3 inet_addr and see that the function converts the symbolic record of the ip address into its binary representation. Bingo! I pass the host name as localhost. Replacing localhost with 127.0.0.1, I get a working example.

    $ 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 andpublickey /home/andrey/.ssh/id_rsa failed!
    	Authenticationwith username andrey andpublickey /home/andrey/.ssh/id_dsa succeeded!
    all done!
    

    Now it's up to you to build a version of libssh2 (1.3.0) for squeeze and rebuild midnight with the new version of the library. You can pick up the finished assembly here

    Read Next