1
0
mirror of https://github.com/libssh2/libssh2.git synced 2026-10-24 03:48:58 +03:00

build: improve building in ISO and C89 modes, test in CI

Note: On Linux with glibc, ISO mode also requires setting
the `_DEFAULT_SOURCE` macro to enable necessary POSIX features when
building tests (for `popen()`, `pclose()` and examples (for `fileno()`,
`tcsetattr()`). On other platforms and environments it may require
something else.

- replace `strdup()` with local implementation.
- replace `getline()` with C89 `fgets()`.
- replace `u_char`, `u_int` with C89 types.
- fix type mismatches in chacha-poly1305 code.
- silence `-Wno-format-nonliteral` locally. The global method was not
  effective (like because it was overridden by `-Wformat=2`) and caused
  these warnings when building in C89 mode.
- GHA: test ISO C89 in zlib-enabled Linux jobs with all crypto backends.
- fix formatting nits along the way.
- configure, cmake: silence silly `-Wno-comma` warnings with clang in
  C89 mode.
- examples: include `select.h` again, where `select()` is used. As its
  canonical header. Seen required on Linux glibc non-GNU/ISO builds.
  Follow-up to a683133dfe #999

Assisted-by: Raul Tambre
Ref: #1674

Closes #1688
This commit is contained in:
Viktor Szakats
2025-09-27 22:15:54 +02:00
parent 734ec12c92
commit e8e6bc2c50
27 changed files with 151 additions and 65 deletions

View File

@@ -296,6 +296,7 @@ jobs:
CC: ${{ matrix.compiler == 'clang-tidy' && 'clang' || matrix.compiler }}
MATRIX_ARCH: '${{ matrix.arch }}'
MATRIX_BUILD: '${{ matrix.build }}'
MATRIX_COMPILER: '${{ matrix.compiler }}'
MATRIX_CRYPTO: '${{ matrix.crypto }}'
MATRIX_ZLIB: '${{ matrix.zlib }}'
FIXTURE_TRACE_ALL_CONNECT: 0
@@ -518,9 +519,17 @@ jobs:
crypto="${MATRIX_CRYPTO}"
fi
[ -d "$HOME"/usr ] && options+=" -DCMAKE_PREFIX_PATH=$HOME/usr"
[ "${MATRIX_ARCH}" = 'i386' ] && options+=" -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_SYSTEM_PROCESSOR=${MATRIX_ARCH} -DCMAKE_C_FLAGS=-m32"
if [ "${MATRIX_ARCH}" = 'i386' ]; then
options+=" -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_SYSTEM_PROCESSOR=${MATRIX_ARCH}"
cflags+=' -m32'
fi
[ "${MATRIX_COMPILER}" = 'clang-tidy' ] && options+=' -DLIBSSH2_CLANG_TIDY=ON'
if [[ "${MATRIX_CRYPTO}" =~ ^(OpenSSL|Libgcrypt|mbedTLS|wolfSSL)$ && "${MATRIX_COMPILER}" != 'clang-tidy' && "${MATRIX_ZLIB}" = 'ON' ]]; then
options+=' -DCMAKE_C_STANDARD=90'
cflags+=' -D_DEFAULT_SOURCE' # for glibc ISO mode, in tests: popen(), pclose(), in examples: fileno(), tcsetattr()
fi
cmake -B bld -G Ninja ${options} $TOOLCHAIN_OPTION \
-DCMAKE_C_FLAGS="${cflags}" \
-DCMAKE_UNITY_BUILD=ON \
-DENABLE_WERROR=ON \
-DCRYPTO_BACKEND=${crypto} \

View File

@@ -233,7 +233,6 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare])
tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar"
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef])
tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral"
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes])
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [declaration-after-statement])
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align])
@@ -338,6 +337,14 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [xor-used-as-pow])
fi
case "$CFLAGS" in
*-std=c89*|*-std=c90*|*-std=gnu89*|*-std=gnu90*)
if test "$compiler_num" -ge "309"; then
tmp_CFLAGS="$tmp_CFLAGS -Wno-comma" # Just silly
fi
;;
esac
CFLAGS="$CFLAGS $tmp_CFLAGS"
AC_MSG_NOTICE([Added this set of compiler options: $tmp_CFLAGS])
@@ -411,11 +418,6 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef])
fi
#
dnl Only gcc 2.97 or later
if test "$compiler_num" -ge "297"; then
tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral"
fi
#
dnl Only gcc 3.0 or later
if test "$compiler_num" -ge "300"; then
tmp_CFLAGS="$tmp_CFLAGS -Wno-system-headers"

View File

@@ -91,7 +91,6 @@ if(PICKY_COMPILER)
-Wignored-qualifiers # clang 2.8 gcc 4.3
-Wmissing-field-initializers # clang 2.7 gcc 4.1
-Wmissing-noreturn # clang 2.7 gcc 4.1
-Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0)
-Wno-system-headers # clang 1.0 gcc 3.0
# -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs
-Wold-style-definition # clang 2.7 gcc 3.4
@@ -289,6 +288,13 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC)
endforeach()
endif()
if(CMAKE_C_STANDARD STREQUAL 90)
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9) OR
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.1))
list(APPEND _picky "-Wno-comma") # Just silly
endif()
endif()
if(_picky_nocheck OR _picky)
set(_picky_tmp "${_picky_nocheck}" "${_picky}")
string(REPLACE ";" " " _picky_tmp "${_picky_tmp}")

View File

@@ -15,6 +15,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -20,6 +20,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -11,6 +11,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -21,6 +21,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -21,6 +21,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -17,6 +17,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -17,6 +17,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -19,6 +19,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -14,6 +14,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,6 +16,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -15,6 +15,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -23,6 +23,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -13,11 +13,6 @@
/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
typedef unsigned char u8;
typedef unsigned int u32;
typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U)
#define U32C(v) (v##U)
@@ -55,8 +50,7 @@ typedef struct chacha_ctx chacha_ctx;
static const char sigma[17] = "expand 32-byte k";
static const char tau[17] = "expand 16-byte k";
void
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
void chacha_keysetup(struct chacha_ctx *x, const u8 *k, u32 kbits)
{
const char *constants;
@@ -81,8 +75,7 @@ chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
x->input[3] = U8TO32_LITTLE(constants + 12);
}
void
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
void chacha_ivsetup(struct chacha_ctx *x, const u8 *iv, const u8 *counter)
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
@@ -90,14 +83,14 @@ chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
x->input[15] = U8TO32_LITTLE(iv + 4);
}
void
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
void chacha_encrypt_bytes(struct chacha_ctx *x, const u8 *m, u8 *c,
size_t bytes)
{
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
u8 *ctarget = NULL;
u8 tmp[64];
u_int i;
size_t i;
if(!bytes)
return;

View File

@@ -14,8 +14,11 @@
#include <stdlib.h>
typedef unsigned char u8;
typedef unsigned int u32;
struct chacha_ctx {
u_int input[16];
u32 input[16];
};
#define CHACHA_MINKEYLEN 16
@@ -24,9 +27,9 @@ struct chacha_ctx {
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
u_char *c, u_int bytes);
void chacha_keysetup(struct chacha_ctx *x, const u8 *k, u32 kbits);
void chacha_ivsetup(struct chacha_ctx *x, const u8 *iv, const u8 *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const u8 *m,
u8 *c, size_t bytes);
#endif /* CHACHA_H */

View File

@@ -28,7 +28,8 @@ int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n);
int
chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen)
chachapoly_init(struct chachapoly_ctx *ctx, const unsigned char *key,
size_t keylen)
{
if(keylen != (32 + 32)) /* 2 x 256 bit keys */
return LIBSSH2_ERROR_INVAL;
@@ -47,12 +48,15 @@ chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen)
* tag. This tag is written on encryption and verified on decryption.
*/
int
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, int do_encrypt)
chachapoly_crypt(struct chachapoly_ctx *ctx, libssh2_uint64_t seqnr,
unsigned char *dest, const unsigned char *src, size_t len,
size_t aadlen, int do_encrypt)
{
u_char seqbuf[8];
const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
unsigned char seqbuf[8];
const unsigned char one[8] = {
1, 0, 0, 0, 0, 0, 0, 0 /* NB little-endian */
};
unsigned char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
int r = LIBSSH2_ERROR_INVAL;
unsigned char *ptr = NULL;
@@ -69,7 +73,7 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
/* If decrypting, check tag before anything else */
if(!do_encrypt) {
const u_char *tag = src + aadlen + len;
const unsigned char *tag = src + aadlen + len;
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
if(chachapoly_timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN)
@@ -106,10 +110,10 @@ out:
/* Decrypt and extract the encrypted packet length */
int
chachapoly_get_length(struct chachapoly_ctx *ctx, unsigned int *plenp,
unsigned int seqnr, const unsigned char *cp,
unsigned int len)
libssh2_uint64_t seqnr, const unsigned char *cp,
size_t len)
{
u_char buf[4], seqbuf[8];
unsigned char buf[4], seqbuf[8];
unsigned char *ptr = NULL;
if(len < 4)
@@ -130,5 +134,5 @@ chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n)
for(; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
return ret != 0;
}

View File

@@ -30,12 +30,12 @@ struct chachapoly_ctx {
};
int chachapoly_init(struct chachapoly_ctx *cpctx,
const u_char *key, u_int keylen);
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
u_char *dest, const u_char *src, u_int len, u_int aadlen,
int do_encrypt);
const unsigned char *key, size_t keylen);
int chachapoly_crypt(struct chachapoly_ctx *cpctx, libssh2_uint64_t seqnr,
unsigned char *dest, const unsigned char *src, size_t len,
size_t aadlen, int do_encrypt);
int chachapoly_get_length(struct chachapoly_ctx *cpctx,
u_int *plenp, u_int seqnr, const u_char *cp,
u_int len);
unsigned int *plenp, libssh2_uint64_t seqnr,
const unsigned char *cp, size_t len);
#endif /* CHACHA_POLY_AEAD_H */

View File

@@ -443,13 +443,13 @@ crypt_encrypt_chacha20_poly_buffer(LIBSSH2_SESSION * session,
length
*/
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len) - 4, 4, ctx->encrypt);
buf_len - 4, 4, ctx->encrypt);
}
else {
/* buf is full packet including size and auth tag but buf_len
doesn't include size */
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len), 4, ctx->encrypt);
buf_len, 4, ctx->encrypt);
/* the api expects the size field to already be removed
from the decrypted packet so we'll help it out */
@@ -459,7 +459,7 @@ crypt_encrypt_chacha20_poly_buffer(LIBSSH2_SESSION * session,
}
}
return (ret == 0 ? 0 : 1);
return (ret == 0) ? 0 : 1;
}
static int
@@ -472,7 +472,7 @@ crypt_get_length_chacha20_poly(LIBSSH2_SESSION * session, unsigned int seqno,
(void)session;
return chachapoly_get_length(&ctx->chachapoly_ctx, len, seqno, data,
(u_int)data_size);
data_size);
}
static int

View File

@@ -75,7 +75,7 @@
# if !defined(LIBSSH2_LIBRARY) || defined(LIBSSH2_TESTS)
/* apply to examples and tests only */
# ifndef _CRT_NONSTDC_NO_DEPRECATE
# define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write() */
# define _CRT_NONSTDC_NO_DEPRECATE /* for write() */
# endif
# ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* for inet_addr() */
@@ -89,7 +89,6 @@
# endif
# endif
# if _MSC_VER < 1900
# define strdup _strdup
/* Silence bogus warning C4127: conditional expression is constant */
# pragma warning(disable:4127)
# endif

View File

@@ -610,7 +610,14 @@ _libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
buflen -= len;
msglen = len;
va_start(vargs, format);
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
len = vsnprintf(buffer + msglen, buflen, format, vargs);
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
va_end(vargs);
msglen += len < buflen ? len : buflen - 1;
}

View File

@@ -28,9 +28,10 @@
(p)[3] = (uint8_t)((v) >> 24); \
} while (0)
void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m,
size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
void poly1305_auth(unsigned char out[POLY1305_TAGLEN],
const unsigned char *m, size_t inlen,
const unsigned char key[POLY1305_KEYLEN])
{
uint32_t t0;
uint32_t t1;
uint32_t t2;

View File

@@ -14,7 +14,8 @@
#define POLY1305_KEYLEN 32
#define POLY1305_TAGLEN 16
void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
const u_char key[POLY1305_KEYLEN]);
void poly1305_auth(unsigned char out[POLY1305_TAGLEN],
const unsigned char *m, size_t inlen,
const unsigned char key[POLY1305_KEYLEN]);
#endif /* POLY1305_H */

View File

@@ -97,7 +97,14 @@ static int run_command_varg(char **output, const char *command, va_list args)
}
/* Format the command string */
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
ret = vsnprintf(command_buf, sizeof(command_buf), command, args);
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
if(ret < 0 || ret >= BUFSIZ) {
fprintf(stderr, "Unable to format command (%s)\n", command);
return -1;
@@ -142,7 +149,7 @@ static int run_command_varg(char **output, const char *command, va_list args)
buf[end - 1] = '\0';
}
*output = strdup(buf);
*output = libssh2_strdup(buf);
}
return ret;
}
@@ -212,7 +219,7 @@ static int start_openssh_server(char **container_id_out)
"libssh2/openssh_server");
}
else {
*container_id_out = strdup("");
*container_id_out = libssh2_strdup("");
return 0;
}
}
@@ -237,24 +244,22 @@ static int is_running_inside_a_container(void)
#ifdef _WIN32
return 0;
#else
const char *cgroup_filename = "/proc/self/cgroup";
static const char *cgroup_filename = "/proc/self/cgroup";
FILE *f;
char *line = NULL;
size_t len = 0;
char line[256];
int found = 0;
f = fopen(cgroup_filename, "r");
if(!f) {
/* Don't go further, we are not in a container */
return 0;
}
while(getline(&line, &len, f) != -1) {
while(fgets(line, sizeof(line), f)) {
if(strstr(line, "docker")) {
found = 1;
break;
}
}
fclose(f);
free(line);
return found;
#endif
}
@@ -320,7 +325,7 @@ static int ip_address_from_container(char *container_id, char **ip_address_out)
static int port_from_container(char *container_id, char **port_out)
{
if(is_running_inside_a_container()) {
*port_out = strdup("22");
*port_out = libssh2_strdup("22");
return 0;
}
else {
@@ -364,12 +369,12 @@ static libssh2_socket_t open_socket_to_container(char *container_id)
if(!env) {
env = "127.0.0.1";
}
ip_address = strdup(env);
ip_address = libssh2_strdup(env);
env = openssh_server_port();
if(!env) {
env = "4711";
}
port_string = strdup(env);
port_string = libssh2_strdup(env);
}
/* 0.0.0.0 is returned by Docker for Windows, because the container
@@ -377,7 +382,7 @@ static libssh2_socket_t open_socket_to_container(char *container_id)
instead we assume localhost and try to connect to 127.0.0.1. */
if(ip_address && strcmp(ip_address, "0.0.0.0") == 0) {
free(ip_address);
ip_address = strdup("127.0.0.1");
ip_address = libssh2_strdup("127.0.0.1");
}
hostaddr = inet_addr(ip_address);
@@ -487,3 +492,21 @@ void close_socket_to_openssh_server(libssh2_socket_t sock)
{
close_socket_to_container(sock);
}
char *libssh2_strdup(const char *str)
{
size_t len;
char *newstr;
if(!str)
return (char *)NULL;
len = strlen(str) + 1;
newstr = malloc(len);
if(!newstr)
return (char *)NULL;
memcpy(newstr, str, len);
return newstr;
}

View File

@@ -46,4 +46,6 @@ libssh2_socket_t open_socket_to_openssh_server(void);
void close_socket_to_openssh_server(libssh2_socket_t sock);
int openssh_fixture_have_docker(void);
char *libssh2_strdup(const char *str);
#endif

View File

@@ -309,7 +309,7 @@ static void kbd_callback(const char *name, int name_len,
}
if(num_prompts == 1) {
responses[0].text = strdup(kbd_password);
responses[0].text = libssh2_strdup(kbd_password);
responses[0].length = (unsigned int)strlen(kbd_password);
}
}