SFTP запись с использованием libssh2 ошибка сегментации

#openssl #libssh2

#openssl #libssh2

Вопрос:

Я пытаюсь скопировать файл на ftp-сервер, используя API libssh2, как показано в примере ниже в моем приложении:

  sock = socket(AF_INET, SOCK_STREAM, 0);
 
    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = hostaddr;
    if(connect(sock, (struct sockaddr*)(amp;sin),
            sizeof(struct sockaddr_in)) != 0) {
        fprintf(stderr, "failed to connect!n");
        return -1;
    }
 
    /* Create a session instance
     */ 
    session = libssh2_session_init();

    if(!session)
        return -1;
 
    /* Since we have set non-blocking, tell libssh2 we are blocking */ 
    libssh2_session_set_blocking(session, 1);

 
    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */ 
    rc = libssh2_session_handshake(session, sock);

    if(rc) {
        fprintf(stderr, "Failure establishing SSH session: %dn", rc);
        return -1;
    }
 
    /* At this point we havn't yet authenticated.  The first thing to do
     * is check the hostkey's fingerprint against our known hosts Your app
     * may have it hard coded, may go to a file, may present it to the
     * user, that's your call
     */ 
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);

    fprintf(stderr, "Fingerprint: ");
    for(i = 0; i < 20; i  ) {
        fprintf(stderr, "X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "n");
 
    if(auth_pw) {
        /* We could authenticate via password */ 
        if(libssh2_userauth_password(session, username, password)) {

            fprintf(stderr, "Authentication by password failed.n");
            goto shutdown;
        }
    }
    else {
        /* Or by public key */ 
        const char *pubkey = "/home/username/.ssh/id_rsa.pub";
        const char *privkey = "/home/username/.ssh/id_rsa.pub";
        if(libssh2_userauth_publickey_fromfile(session, username,

                                               pubkey, privkey,
                                               password)) {
            fprintf(stderr, "tAuthentication by public key failedn");
            goto shutdown;
        }
    }
 
    fprintf(stderr, "libssh2_sftp_init()!n");

    sftp_session = libssh2_sftp_init(session);

 
    if(!sftp_session) {
        fprintf(stderr, "Unable to init SFTP sessionn");
        goto shutdown;
    }
 
    fprintf(stderr, "libssh2_sftp_open()!n");

    /* Request a file via SFTP */ 
    sftp_handle =
        libssh2_sftp_open(sftp_session, sftppath,

                      LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
                      LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                      LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
 
    if(!sftp_handle) {
        fprintf(stderr, "Unable to open file with SFTPn");
        goto shutdown;
    }
    fprintf(stderr, "libssh2_sftp_open() is done, now send data!n");

    do {
        nread = fread(mem, 1, sizeof(mem), local);
        if(nread <= 0) {
            /* end of file */ 
            break;
        }
        ptr = mem;
 
        do {
            /* write data in a loop until we block */ 
            rc = libssh2_sftp_write(sftp_handle, ptr, nread);

            if(rc < 0)
                break;
            ptr  = rc;
            nread -= rc;
        } while(nread);
 
    } while(rc > 0);
 
    libssh2_sftp_close(sftp_handle);

    libssh2_sftp_shutdown(sftp_session);

 
shutdown:
    libssh2_session_disconnect(session,

                               "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);

 
#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    if(local)
        fclose(local);
 

но в первый раз файл передается успешно. Но при попытке во второй раз из моего приложения
возникает ошибка сегментации в libssh2_session_handshake().

 */openssl/crypto/evp/evp_enc.c:157: OpenSSL internal error: assertion failed: ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || ctx->cipher->block_size == 16
Signal: SIGABRT (Aborted)*


stacktrace:
__GI_raise 0x00007f567ae16438
__GI_abort 0x00007f567ae1803a
OPENSSL_die cryptlib.c:421
EVP_CipherInit_ex evp_enc.c:155
EVP_CipherInit evp_enc.c:56
_libssh2_cipher_init openssl.c:407
crypt_init crypt.c:88
ecdh_sha2_nistp kex.c:2219
kex_method_ecdh_key_exchange kex.c:2479
_libssh2_kex_exchange kex.c:3990
session_startup session.c:732
libssh2_session_handshake session.c:814
 

Пожалуйста, подскажите, как я могу преодолеть эту ошибку сегментации.

Комментарии:

1. Я использую openssl 1.1.1g, а версия Libssh2 — 1.8.0

2. Я получаю ошибку во второй раз при вызове этого кода. Мне поможет любой указатель.

3. Вы пробовали использовать последнюю версию libssh2 1.9.0?