#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?