1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-08-07 08:02:56 +03:00

os400: maintain up to date (#1309)

- Handle MD5 conditionals in os400qc3.
- Check for errors in os400qc3 pbkdf1.
- Implement an optional build options override file.
- Sync ILE/RPG copy files with current C header files.
- Allow a null session within a string conversion cache.
- Add an ILE/RPG example.
- Adjust outdated copyrights in changed files.
This commit is contained in:
monnerat
2024-01-19 20:37:34 +01:00
committed by GitHub
parent aea63ad997
commit 8457c37afd
11 changed files with 772 additions and 86 deletions

View File

@@ -37,22 +37,29 @@ archive extraction. Do not ask questions about these subjects if you're not
familiar with.
_ As a prerequisite, QADRT development environment must be installed.
_ Install the libssh2 sources directory in IFS.
For more information on downloading and installing the QADRT development kit,
please see https://www.ibm.com/support/pages/node/6258183
_ If data compression has to be supported, ZLIB development environment must
be installed.
_ Install the libssh2 sources directory in IFS. Do NOT install it in the
installation target directory (which defaults to /libssh2).
_ Enter shell (QSH). You may need to change the LANG environment variable
to be in phase with the libssh2 source files CCSID.
_ Change current directory to the libssh2 sources installation directory
_ Change current directory to os400
_ Edit file iniscript.sh. You may want to change tunable configuration
parameters, like debug info generation, optimisation level, listing option,
target library, zlib availability and location, etc.
- If you want to change the default configuration parameters like debug info
generation, optimization level, listing option, target library, zlib
availability and location, etc., copy file config400.default to
config400.override and edit the latter. Do not edit the original default file
as it might be overwritten by a subsequent source installation.
_ Copy any file in the current directory to makelog (i.e.:
cp initscript.sh makelog): this is intended to create the makelog file with
an ASCII CCSID!
_ Enter the command "sh make.sh > makelog 2>&1'
_ Examine the makelog file to check for compilation errors.
Leaving file initscript.sh unchanged, this will produce the following OS/400
objects:
Without configuration parameters override, this will produce the following
OS/400 objects:
_ Library LIBSSH2. All other objects will be stored in this library.
_ Modules for all libssh2 units.
_ Binding directory LIBSSH2_A, to be used at calling program link time for
@@ -123,7 +130,8 @@ char * libssh2_to_ccsid(LIBSSH2_SESSION *session,
size_t *outlen);
where:
session is a libssh2 session used for memory allocation.
session is a libssh2 session used for memory allocation or NULL for
global allocation scheme.
cache is the address of a string cache.
ccsid is the external (i.e.: non libssh2) coded character set id.
65535 means no conversion and 0 means the current job's CCSID.
@@ -145,6 +153,8 @@ or NULL if an error occurred. In addition, the variable pointed by outlen
receives the effective byte length of the (cached) translated string, or -1
in case of error.
Please take care to never mix different sessions into the same cache.
ILE/RPG support:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -48,6 +48,7 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -58,6 +59,11 @@
#define OFFSET_OF(t, f) ((size_t) ((char *) &((t *) 0)->f - (char *) 0))
#define ALLOC(s, sz) ((s)? LIBSSH2_ALLOC((s), (sz)): malloc(sz))
#define REALLOC(s, p, sz) ((s)? LIBSSH2_REALLOC((s), (p), (sz)): \
realloc((p), (sz)))
#define FREE(s, p) ((s)? LIBSSH2_FREE((s), (p)): free(p))
struct _libssh2_string_cache {
libssh2_string_cache * next;
@@ -133,7 +139,7 @@ convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
}
if (outlen)
*outlen = -1;
if (!session || !cache)
if (!cache)
return NULL;
/* Get terminator size. */
@@ -157,12 +163,12 @@ convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
}
/* Allocate output string buffer and open conversion descriptor. */
dst = LIBSSH2_ALLOC(session, buflen + termsize);
dst = ALLOC(session, buflen + termsize);
if (!dst)
return NULL;
cd = QtqIconvOpen(&outcode, &incode);
if (cd.return_value == -1) {
LIBSSH2_FREE(session, (char *) dst);
FREE(session, dst);
return NULL;
}
@@ -184,7 +190,7 @@ convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
break;
/* Must expand buffer. */
buflen += STRING_GRANULE;
outp = LIBSSH2_REALLOC(session, dst, buflen + termsize);
outp = REALLOC(session, dst, buflen + termsize);
if (!outp)
break;
dst = outp;
@@ -194,7 +200,7 @@ convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
/* Check for error. */
if (i < 0 || !outp) {
LIBSSH2_FREE(session, dst);
FREE(session, dst);
return NULL;
}
@@ -206,7 +212,7 @@ convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache,
/* Shorten buffer if possible. */
if (curlen < buflen)
dst = LIBSSH2_REALLOC(session, dst, curlen + termsize);
dst = REALLOC(session, dst, curlen + termsize);
/* Link to cache. */
outstring = (libssh2_string_cache *) dst;
@@ -244,10 +250,10 @@ libssh2_release_string_cache(LIBSSH2_SESSION *session,
{
libssh2_string_cache *p;
if (session && cache)
if (cache)
while ((p = *cache)) {
*cache = p->next;
LIBSSH2_FREE(session, (char *) p);
FREE(session, (char *) p);
}
}

28
os400/config400.default Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/sh
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
################################################################################
# Tunable configuration parameters.
setenv TARGETLIB 'LIBSSH2' # Target OS/400 program library.
setenv STATBNDDIR 'LIBSSH2_A' # Static binding directory.
setenv DYNBNDDIR 'LIBSSH2' # Dynamic binding directory.
setenv SRVPGM "LIBSSH2.${SONAME}" # Service program.
setenv TGTCCSID '500' # Target CCSID of objects.
setenv DEBUG '*ALL' # Debug level.
setenv OPTIMIZE '10' # Optimisation level
setenv OUTPUT '*NONE' # Compilation output option.
setenv TGTRLS '*CURRENT' # Target OS release.
setenv IFSDIR '/libssh2' # Installation IFS directory.
setenv QADRTDIR '/QIBM/ProdData/qadrt' # QADRT IFS directory.
setenv WITH_MD5 'yes' # enable MD5 support.
# Define ZLIB availability and locations.
setenv WITH_ZLIB 0 # Define to 1 to enable.
setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory.
setenv ZLIB_LIB 'ZLIB' # ZLIB library.
setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory.

View File

@@ -35,34 +35,12 @@ SONAME=`sed -e '/^VERSION=/!d' -e 's/^.* \([0-9]*\):.*$/\1/' -e 'q' \
< "${TOPDIR}/src/Makefile.am"`
export SONAME
# Get OS/400 configuration parameters.
################################################################################
#
# Tunable configuration parameters.
#
################################################################################
setenv TARGETLIB 'LIBSSH2' # Target OS/400 program library.
setenv STATBNDDIR 'LIBSSH2_A' # Static binding directory.
setenv DYNBNDDIR 'LIBSSH2' # Dynamic binding directory.
setenv SRVPGM "LIBSSH2.${SONAME}" # Service program.
setenv TGTCCSID '500' # Target CCSID of objects.
setenv DEBUG '*ALL' # Debug level.
setenv OPTIMIZE '10' # Optimisation level
setenv OUTPUT '*NONE' # Compilation output option.
setenv TGTRLS 'V7R3M0' # Target OS release.
setenv IFSDIR '/libssh2' # Installation IFS directory.
setenv QADRTDIR '/QIBM/ProdData/qadrt' # QADRT IFS directory.
# Define ZLIB availability and locations.
setenv WITH_ZLIB 0 # Define to 1 to enable.
setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory.
setenv ZLIB_LIB 'ZLIB' # ZLIB library.
setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory.
################################################################################
. "${SCRIPTDIR}/config400.default"
if [ -f "${SCRIPTDIR}/config400.override" ]
then . "${SCRIPTDIR}/config400.override"
fi
# Need to get the version definitions.
@@ -203,6 +181,10 @@ make_module()
then DEFINES="${DEFINES} LIBSSH2_HAVE_ZLIB"
fi
if [ "${WITH_MD5}" != 'yes' ]
then DEFINES="${DEFINES} LIBSSH2_NO_MD5"
fi
if [ "${DEFINES}" ]
then CMD="${CMD} DEFINE(${DEFINES})"
fi

View File

@@ -1,4 +1,4 @@
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -112,8 +112,12 @@
d libssh2_uint8_t...
d s 3u 0 based(######typedef######)
d libssh2_uint16_t...
d s 5u 0 based(######typedef######)
d libssh2_uint32_t...
d s 10u 0 based(######typedef######)
d libssh2_int32_t...
d s 10i 0 based(######typedef######)
d libssh2_uint64_t...
d s 20u 0 based(######typedef######)
d libssh2_int64_t...
@@ -123,6 +127,10 @@
d s 10i 0 based(######typedef######)
d LIBSSH2_INVALID_SOCKET...
d c -1
d LIBSSH2_SOCKET_CLOSE...
d pr extproc('close')
d like(libssh2_Cint)
d s value like(libssh2_socket_t)
d libssh2_mode_t s 10u 0 based(######typedef######)
d libssh2_ino_t s 10u 0 based(######typedef######)
@@ -165,9 +173,9 @@
* Part of every banner, user specified or not.
d LIBSSH2_SSH_BANNER...
d c 'SSH-2.0-libssh2_1.6.1_DEV'
d c 'SSH-2.0-libssh2_@LIBSSH2_VERSION@'
d LIBSSH2_SSH_DEFAULT_BANNER...
d c 'SSH-2.0-libssh2_1.6.1_DEV'
d c 'SSH-2.0-libssh2_@LIBSSH2_VERSION@'
* Default generate and safe prime sizes for
* diffie-hellman-group-exchange-sha1.
@@ -213,8 +221,8 @@
d LIBSSH2_USERAUTH_KBDINT_PROMPT...
d ds based(######typedef######)
d align qualified
d text * char *
d length like(libssh2_Cuint)
d text * unsigned char *
d length like(libssh2_Csize_t)
d echo like(libssh2_Cuchar)
d LIBSSH2_USERAUTH_KBDINT_RESPONSE...
@@ -223,6 +231,22 @@
d text * char *
d length like(libssh2_Cuint)
d LIBSSH2_SK_SIG_INFO...
d ds based(######typedef######)
d align qualified
d flags like(libssh2_uint8_t)
d counter like(libssh2_uint32_t)
d sig_r * unsigned char *
d sig_r_len like(libssh2_Csize_t)
d sig_s * unsigned char *
d sig_s_len like(libssh2_Csize_t)
* Flags for SK authentication
d LIBSSH2_SK_PRESENCE_REQUIRED...
d c X'01'
d LIBSSH2_SK_VERIFICATION_REQUIRED...
d c X'04'
* libssh2_session_callback_set() constants.
d LIBSSH2_CALLBACK_IGNORE...
d c 0
@@ -238,6 +262,12 @@
d c 5
d LIBSSH2_CALLBACK_RECV...
d c 6
d LIBSSH2_CALLBACK_AUTHAGENT...
d c 7
d LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES...
d c 8
d LIBSSH2_CALLBACK_AUTHAGENT_SIGN...
d c 9
* libssh2_session_method_pref() constants.
d LIBSSH2_METHOD_KEX...
@@ -260,12 +290,38 @@
d c 8
d LIBSSH2_METHOD_LANG_SC...
d c 9
d LIBSSH2_METHOD_SIGN_ALGO...
d c 10
* flags.
d LIBSSH2_FLAG_SIGPIPE...
d c X'0001'
d LIBSSH2_FLAG_COMPRESS...
d c X'0002'
d LIBSSH2_FLAG_QUOTE_PATHS...
d c X'0003'
* SK signature callback
d LIBSSH2_PRIVKEY_SK...
d ds based(######typedef######)
d align qualified
d algorithm like(libssh2_Cint)
d flags like(libssh2_uint8_t)
d application * const char *
d key_handle * const uchar *
d handle_len like(libssh2_Csize_t)
d sign_callback * procptr
d orig_abstract * void **
d libssh2_sign_sk...
d pr extproc('libssh2_sign_sk')
d like(libssh2_Cint)
d session * value LIBSSH2_SESSION *
d sig * unsigned char *[]
d sig_len value like(libssh2_Csize_t)
d data * value const uchar *
d data_len value like(libssh2_Csize_t)
d abstract * void *
d LIBSSH2_POLLFD ds based(######typedef######)
d align qualified
@@ -323,6 +379,8 @@
d c 1
d LIBSSH2_HOSTKEY_HASH_SHA1...
d c 2
d LIBSSH2_HOSTKEY_HASH_SHA256...
d c 3
* Hostkey Types.
d LIBSSH2_HOSTKEY_TYPE_UNKNOWN...
@@ -331,6 +389,14 @@
d c 1
d LIBSSH2_HOSTKEY_TYPE_DSS...
d c 2
d LIBSSH2_HOSTKEY_TYPE_ECDSA_256...
d c 3
d LIBSSH2_HOSTKEY_TYPE_ECDSA_384...
d c 4
d LIBSSH2_HOSTKEY_TYPE_ECDSA_521...
d c 5
d LIBSSH2_HOSTKEY_TYPE_ED25519...
d c 6
* Disconnect Codes (defined by SSH protocol).
d SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT...
@@ -468,6 +534,20 @@
d c -45
d LIBSSH2_ERROR_KNOWN_HOSTS...
d c -46
d LIBSSH2_ERROR_CHANNEL_WINDOW_FULL...
d c -47
d LIBSSH2_ERROR_KEYFILE_AUTH_FAILED...
d c -48
d LIBSSH2_ERROR_RANDGEN...
d c -49
d LIBSSH2_ERROR_MISSING_USERAUTH_BANNER...
d c -50
d LIBSSH2_ERROR_ALGO_UNSUPPORTED...
d c -51
d LIBSSH2_ERROR_MAC_FAILURE...
d c -52
d LIBSSH2_ERROR_HASH_INIT...
d c -53
* this is a define to provide the old (<= 1.2.7) name.
d LIBSSH2_ERROR_BANNER_NONE...
@@ -542,6 +622,17 @@
d pr * extproc('libssh2_session_abstract') void * *
d session * value LIBSSH2_SESSION *
d libssh2_cb_generic_ptr...
d s * based(######typedef######) procptr
d libssh2_session_callback_set2...
d pr extproc(
d 'libssh2_session_callback_set2')
d like(libssh2_cb_generic_ptr)
d session * value LIBSSH2_SESSION *
d cbtype value like(libssh2_Cint)
d callback value like(libssh2_cb_generic_ptr)
d libssh2_session_callback_set...
d pr * extproc( void *
d 'libssh2_session_callback_set')
@@ -555,6 +646,7 @@
d session * value LIBSSH2_SESSION *
d banner * value options(*string) const char *
/if not defined(LIBSSH2_NO_DEPRECATED)
d libssh2_banner_set...
d pr extproc('libssh2_banner_set')
d like(libssh2_Cint)
@@ -566,6 +658,7 @@
d like(libssh2_Cint)
d session * value LIBSSH2_SESSION *
d sock value like(libssh2_Cint)
/endif
d libssh2_session_handshake...
d pr extproc('libssh2_session_handshake')
@@ -664,6 +757,12 @@
d username * value options(*string) const char *
d username_len value like(libssh2_Cuint)
d libssh2_userauth_banner...
d pr extproc('libssh2_userauth_banner')
d like(libssh2_Cint)
d session * value LIBSSH2_SESSION *
d banner * char *
d libssh2_userauth_authenticated...
d pr extproc(
d 'libssh2_userauth_authenticated')
@@ -796,6 +895,24 @@
d response_callback...
d * value procptr
d libssh2_userauth_publickey_sk...
d pr extproc(
d 'libssh2_userauth_publickey_sk')
d like(libssh2_Cint)
d session * value LIBSSH2_SESSION *
d username * value options(*string) const char *
d username_len value like(libssh2_Csize_t)
d pubkeydata * value const uchar *
d pubkeydata_len...
d value like(libssh2_Csize_t)
d privatekeydata...
d * value options(*string) const char *
d privatekeydata_len...
d value like(libssh2_Csize_t)
d passphrase * value options(*string) const char *
d sign_callback * value procptr
d abstract * void *
d libssh2_poll pr extproc('libssh2_poll')
d like(libssh2_Cint)
d fds * value LIBSSH2_POLLFD *
@@ -860,6 +977,14 @@
d host * value options(*string) const char *
d port value like(libssh2_Cint)
d libssh2_channel_direct_streamlocal_ex...
d pr * extproc('libssh2_channel_direct- LIBSSH2_CHANNEL *
d _streamlocal_ex')
d session * value LIBSSH2_SESSION *
d socket_path * value options(*string) const char *
d shost * value options(*string) const char *
d sport value like(libssh2_Cint)
d libssh2_channel_forward_listen_ex...
d pr * extproc( LIBSSH2_LISTENER *
d 'libssh2_channel_forward_listen_ex')
@@ -904,6 +1029,12 @@
d varname * value options(*string) const char *
d value * value options(*string) const char *
d libssh2_channel_request_auth_agent...
d pr extproc(
d 'libssh2_channel_request_auth_agent')
d like(libssh2_Cint)
d channel * value LIBSSH2_CHANNEL *
d libssh2_channel_request_pty_ex...
d pr extproc(
d 'libssh2_channel_request_pty_ex')
@@ -963,6 +1094,20 @@
d channel * value LIBSSH2_CHANNEL *
d screen_number value like(libssh2_Cint)
d libssh2_channel_signal_ex...
d pr extproc('libssh2_channel_signal_ex')
d like(libssh2_Cint)
d channel * value LIBSSH2_CHANNEL *
d signame * value options(*string) const char *
d signame_len value like(libssh2_Csize_t)
* C macro implementation
d libssh2_channel_signal...
d pr extproc('libssh2_channel_signal_ex')
d like(libssh2_Cint)
d channel * value LIBSSH2_CHANNEL *
d signame * value options(*string) const char *
d libssh2_channel_process_startup...
d pr extproc(
d 'libssh2_channel_process_startup')
@@ -1040,6 +1185,16 @@
d like(libssh2_Culong)
d channel * value LIBSSH2_CHANNEL *
/if not defined(LIBSSH2_NO_DEPRECATED)
d libssh2_channel_receive_window_adjust...
d pr extproc('libssh2_channel_receive_win-
d dow_adjust')
d like(libssh2_Culong)
d channel * value LIBSSH2_CHANNEL *
d adjustment value like(libssh2_Culong)
d force value like(libssh2_Cuchar)
/endif
d libssh2_channel_receive_window_adjust2...
d pr extproc('libssh2_channel_receive_win-
d dow_adjust2')
@@ -1119,6 +1274,26 @@
d like(libssh2_Clong)
d session * value LIBSSH2_SESSION *
d libssh2_session_set_read_timeout...
d pr extproc(
d 'libssh2_session_set_read_timeout')
d session * value LIBSSH2_SESSION *
d timeout value like(libssh2_Clong)
d libssh2_session_get_read_timeout...
d pr extproc(
d 'libssh2_session_get_read_timeout')
d like(libssh2_Clong)
d session * value LIBSSH2_SESSION *
/if not defined(LIBSSH2_NO_DEPRECATED)
d libssh2_channel_handle_extended_data...
d pr extproc('libssh2_channel_handle_exte-
d nded_data')
d channel * value LIBSSH2_CHANNEL *
d ignore_mode value like(libssh2_Cint)
/endif
d libssh2_channel_handle_extended_data2...
d pr extproc('libssh2_channel_handle_exte-
d nded_data2')
@@ -1126,8 +1301,16 @@
d channel * value LIBSSH2_CHANNEL *
d ignore_mode value like(libssh2_Cint)
/if not defined(LIBSSH2_NO_DEPRECATED)
* libssh2_channel_ignore_extended_data() is defined below for BC with
* version 0.1.
* C macro implementation.
d libssh2_channel_ignore_extended_data...
d pr extproc('libssh2_channel-
d _ignore_extended_data')
d channel * value LIBSSH2_CHANNEL *
d ignore value like(libssh2_Cint)
/endif
d LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA...
d c -1
@@ -1203,6 +1386,14 @@
d like(libssh2_Cint)
d channel * value LIBSSH2_CHANNEL *
/if not defined(LIBSSH2_NO_DEPRECATED)
d libssh2_scp_recv...
d pr * extproc('libssh2_scp_recv') LIBSSH2_CHANNEL *
d session * value LIBSSH2_SESSION *
d path * value options(*string) const char *
d sb * value struct stat *
/endif
* Use libssh2_scp_recv2 for large (> 2GB) file support.
d libssh2_scp_recv2...
d pr * extproc('libssh2_scp_recv2') LIBSSH2_CHANNEL *
@@ -1236,6 +1427,7 @@
d mode value like(libssh2_Cint)
d size value like(libssh2_int64_t)
* DEPRECATED
d libssh2_base64_decode...
d pr extproc('libssh2_base64_decode')
d like(libssh2_Cint)
@@ -1251,6 +1443,26 @@
d req_version_num...
d value like(libssh2_Cint)
d libssh2_crypto_engine_t...
d s based(######typedef######)
d like(libssh2_Cenum)
d libssh2_no_crypto...
d c 0
d libssh2_openssl...
d c 1
d libssh2_gcrypt...
d c 2
d libssh2_mbedtls...
d c 3
d libssh2_wincng...
d c 4
d libssh2_os400qc3...
d c 5
d libssh2_crypto_engine...
d pr extproc('libssh2_crypto_engine')
d like(libssh2_crypto_engine_t)
d HAVE_LIBSSH2_KNOWNHOST_API... since 1.1.1
d c X'010101'
d HAVE_LIBSSH2_VERSION_API... since 1.1
@@ -1313,9 +1525,9 @@
d LIBSSH2_KNOWNHOST_KEYENC_BASE64...
d c X'00020000'
* type of key (3 bits).
* type of key (4 bits).
d LIBSSH2_KNOWNHOST_KEY_MASK...
d c X'001C0000'
d c X'003C0000'
d LIBSSH2_KNOWNHOST_KEY_SHIFT...
d c 18
d LIBSSH2_KNOWNHOST_KEY_RSA1...
@@ -1324,8 +1536,16 @@
d c X'00080000'
d LIBSSH2_KNOWNHOST_KEY_SSHDSS...
d c X'000C0000'
d LIBSSH2_KNOWNHOST_KEY_UNKNOWN...
d LIBSSH2_KNOWNHOST_KEY_ECDSA_256...
d c X'00100000'
d LIBSSH2_KNOWNHOST_KEY_ECDSA_384...
d c X'00140000'
d LIBSSH2_KNOWNHOST_KEY_ECDSA_521...
d c X'00180000'
d LIBSSH2_KNOWNHOST_KEY_ED25519...
d c X'001C0000'
d LIBSSH2_KNOWNHOST_KEY_UNKNOWN...
d c X'003C0000'
d libssh2_knownhost_add...
d pr extproc('libssh2_knownhost_add')
@@ -1611,6 +1831,24 @@
d username * value options(*string) const char *
d identity likeds(libssh2_agent_publickey)
* libssh2_agent_sign()
*
* Sign a payload using a system-installed ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
d libssh2_agent_sign...
d pr extproc('libssh2_agent_sign')
d like(libssh2_Cint)
d agent * value LIBSSH2_AGENT *
d identity likeds(libssh2_agent_publickey)
d sig * unsigned char *
d s_len like(libssh2_Csize_t)
d data * value const uchar *
d d_len value like(libssh2_Csize_t)
d method * value options(*string) const char *
d method_len value like(libssh2_Cuint)
* libssh2_agent_disconnect()
*
* Close a connection to an ssh-agent.
@@ -1631,6 +1869,24 @@
d pr extproc('libssh2_agent_free')
d agent * value LIBSSH2_AGENT *
* libssh2_agent_set_identity_path()
*
* Allows a custom agent identity socket path beyond SSH_AUTH_SOCK env
d libssh2_agent_set_identity_path...
d pr extproc(
d 'libssh2_agent_set_identity_path')
d agent * value LIBSSH2_AGENT *
d path * value options(*string) const char *
* libssh2_agent_get_identity_path()
*
* Returns the custom agent identity socket path if set
d libssh2_agent_get_identity_path...
d pr * extproc( const char *
d 'libssh2_agent_get_identity_path')
d agent * value LIBSSH2_AGENT *
* libssh2_keepalive_config()
*

View File

@@ -1,4 +1,4 @@
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -79,6 +79,10 @@
d LIBSSH2_SFTP_REALPATH...
d c 2
* Flags for sftp_mkdir()
d LIBSSH2_SFTP_DEFAULT_MODE...
d c -1
* SFTP attribute flag bits.
d LIBSSH2_SFTP_ATTR_SIZE...
d c X'00000001'
@@ -97,7 +101,7 @@
d LIBSSH2_SFTP_ST_NOSUID...
d c X'00000002'
d #LIBSSH2_SFTP_ATTRIBUTES...
d LIBSSH2_SFTP_ATTRIBUTES...
d ds based(######typedef######)
d align qualified
* If flags & ATTR_* bit is set, then the value in this struct will be
@@ -336,8 +340,7 @@
* C macro implementation.
d libssh2_sftp_open...
d pr * extproc('libssh2_sftp_open') LIBSSH2_SFTP_HANDLE
d *
d pr * extproc('libssh2_sftp_open') LIBSSH2_SFTP_HANDLE*
d sftp * value LIBSSH2_SFTP *
d filename * value options(*string) const char *
d flags value like(libssh2_Culong)
@@ -346,16 +349,34 @@
* C macro libssh2_sftp_opendir implementation.
* Renamed to avoid upper/lower case name clash.
d libssh2_sftp_open_dir...
d pr * extproc('libssh2_sftp_opendir') LIBSSH2_SFTP_HANDLE
d *
d pr * extproc('libssh2_sftp_opendir') LIBSSH2_SFTP_HANDLE*
d sftp * value LIBSSH2_SFTP *
d path * value options(*string) const char *
d libssh2_sftp_open_ex_r...
d pr * extproc('libssh2_sftp_open_ex_r') LIBSSH2_SFTP_HANDLE*
d sftp * value LIBSSH2_SFTP *
d filename * value options(*string) const char *
d filename_len value like(libssh2_Csize_t)
d flags value like(libssh2_Culong)
d mode value like(libssh2_Clong)
d open_type value like(libssh2_Cint)
d attrs likeds(LIBSSH2_SFTP_ATTRIBUTES)
* C macro implementation.
d libssh2_sftp_open_r...
d pr * extproc('libssh2_sftp_open_r') LIBSSH2_SFTP_HANDLE*
d sftp * value LIBSSH2_SFTP *
d filename * value options(*string) const char *
d flags value like(libssh2_Culong)
d mode value like(libssh2_Clong)
d attrs likeds(LIBSSH2_SFTP_ATTRIBUTES)
d libssh2_sftp_read...
d pr extproc('libssh2_sftp_read')
d like(libssh2_Cssize_t)
d handle * value LIBSSH2_SFTP_HANDLE*
d buffer * value options(*string) char *
d buffer * value char *
d buffer_maxlen value like(libssh2_Csize_t)
d libssh2_sftp_readdir_ex...

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -92,6 +92,8 @@ libssh2_channel_request_pty_size(LIBSSH2_CHANNEL *channel,
LIBSSH2_API int
libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number);
LIBSSH2_API int
libssh2_channel_signal(LIBSSH2_CHANNEL *channel, const char *signame);
LIBSSH2_API int
libssh2_channel_shell(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int
libssh2_channel_exec(LIBSSH2_CHANNEL *channel, const char *command);
@@ -110,6 +112,8 @@ libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel,
const char *buf, size_t buflen);
LIBSSH2_API unsigned long
libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
LIBSSH2_API void
libssh2_channel_ignore_extended_data(LIBSSH2_CHANNEL *channel, int ignore);
LIBSSH2_API int libssh2_channel_flush(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_flush_stderr(LIBSSH2_CHANNEL *channel);
LIBSSH2_API LIBSSH2_CHANNEL *
@@ -137,6 +141,10 @@ libssh2_sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
unsigned long flags, long mode);
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_opendir(LIBSSH2_SFTP *sftp, const char *path);
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_open_r(LIBSSH2_SFTP *sftp, const char *filename,
unsigned long flags, long mode,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen,
LIBSSH2_SFTP_ATTRIBUTES *attrs);

View File

@@ -44,6 +44,36 @@ do MEMBER="${LIBIFSNAME}/DOCS.FILE/`db2_name \"${TEXT}\"`.MBR"
done
# Create the RPGXAMPLES source file if it does not exist.
if action_needed "${LIBIFSNAME}/RPGXAMPLES.FILE"
then CMD="CRTSRCPF FILE(${TARGETLIB}/RPGXAMPLES) RCDLEN(240)"
CMD="${CMD} CCSID(${TGTCCSID}) TEXT('ILE/RPG examples')"
system "${CMD}"
fi
# Copy RPG examples if needed.
for EXAMPLE in "${SCRIPTDIR}/rpg-examples"/*
do MEMBER="`basename \"${EXAMPLE}\"`"
IFSMEMBER="${LIBIFSNAME}/RPGXAMPLES.FILE/`db2_name \"${MEMBER}\"`.MBR"
[ -e "${EXAMPLE}" ] || continue
if action_needed "${IFSMEMBER}" "${EXAMPLE}"
then CMD="CPY OBJ('${EXAMPLE}') TOOBJ('${IFSMEMBER}')"
CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
system "${CMD}"
MBRTEXT=`sed -e '1!d;/^ \*/!d;s/^ *\* *//' \
-e 's/ *$//;s/'"'"'/&&/g' < "${EXAMPLE}"`
CMD="CHGPFM FILE(${TARGETLIB}/RPGXAMPLES) MBR(${MEMBER})"
CMD="${CMD} SRCTYPE(RPGLE) TEXT('${MBRTEXT}')"
system "${CMD}"
fi
done
# Build in each directory.
for SUBDIR in include rpg src

View File

@@ -0,0 +1,326 @@
* Example: print a remote ascii file using sftp
*
h DFTACTGRP(*NO) ACTGRP(*NEW)
h OPTION(*NOSHOWCPY)
h BNDDIR('LIBSSH2')
h BNDDIR('QC2LE')
*
* Copyright (C) The libssh2 project and its contributors.
*
* Usage:
*
* CALL SFTPXMPLE ('<host>' '<port>' '<user>' '<password>' '<filepath>')
*
* SPDX-License-Identifier: BSD-3-Clause
*
fQPRINT o f 120 printer
*
/include LIBSSH2RPG,SSH2_SFTP
/include LIBSSH2RPG,SSH2_CCSID
*
d pi
d host 120
d port 5
d user 20
d password 120
d filepath 120
*
**************************************************************************
* External definitions
**************************************************************************
*
d atoi pr 10i 0 extproc('atoi')
d numstr * value options(*string)
*
d inet_addr pr 10u 0 extproc('inet_addr')
d char_addr * value options(*string)
*
d socket pr 10i 0 extproc('socket')
d domain 10i 0 value
d type 10i 0 value
d protocol 10i 0 value
*
d AF_INET c 2
d SOCK_STREAM c 1
d IPPROTO_IP c 0
*
d connect pr 10i 0 extproc('connect')
d sockfd 10i 0 value
d addr * value
d addrlen 10u 0 value
*
d sockaddr_in ds based(######typedef######)
d align qualified
d sin_family 5i 0
d sin_port 5i 0
d sin_addr 10u 0
d sin_zero 8
*
d shutdown pr 10i 0 extproc('shutdown')
d socket 10i 0 value
d how 10i 0 value
*
d SHUT_RDWR c 2
*
d qmhsndpm pr extpgm('QMHSNDPM')
d msgid 7 const
d qmsgfn 20 const
d data 999999 const options(*varsize)
d datalength 10u 0 const
d msgtype 10 const
d csentry 999999 const options(*varsize)
d cscounter 10u 0 const
d msgkey 4
d errcode 999999 options(*varsize)
d csentrylen 10u 0 const options(*nopass)
d csqual 20 const options(*nopass)
d waittime 10u 0 const options(*nopass)
d csentrytype 10 const options(*nopass)
d ccsid 10u 0 const options(*nopass)
*
**************************************************************************
* Constants
**************************************************************************
*
d EBCDIC_CR c X'0D'
d EBCDIC_LF c X'25'
*
**************************************************************************
* Global storage
**************************************************************************
*
d sc s * inz(*NULL) String cache
d session s * inz(*NULL) Session
d sftp_session s * inz(*NULL) LIBSSH2_SFTP *
d sftp_handle s * inz(*NULL) LIBSSH2_SFTP_HANDLE*
d sin ds likeds(sockaddr_in) Remote IP address
d sock s 10i 0 inz(LIBSSH2_INVALID_SOCKET) Socket descriptor
d rc s 10i 0 Result code
d hostlen s 10u 0 Host name length
*
**************************************************************************
* Main program
**************************************************************************
// Initialize ssh lbrary
rc = libssh2_init(0);
if rc <> 0;
error('libssh2 initialization failed (' + %trim(%char(rc)) + ')');
else;
// Build remote address
sin.sin_family = AF_INET;
hostlen = trimmed_length(host: %len(host): %addr(port));
if hostlen <> 0;
sin.sin_addr = inet_addr(%subst(host: 1: hostlen));
else;
sin.sin_addr = inet_addr('127.0.0.1');
endif;
sin.sin_port = atoi(port);
if sin.sin_port <= 0;
sin.sin_port = 22;
endif;
sin.sin_zero = *ALLX'00';
main();
cleanout();
endif;
*inlr = *on;
/space 3
begsr *pssr;
cleanout();
endsr;
/eject
**************************************************************************
* Main procedure
**************************************************************************
*
p main b
*
d buf s 1024 Data buffer
d nread s 10i 0 Read bytes count
// Connect to remote server
sock = socket(AF_INET: SOCK_STREAM: IPPROTO_IP);
if sock = LIBSSH2_INVALID_SOCKET;
error('failed to create socket');
return;
endif;
if connect(sock: %addr(sin): %size(sin)) <> 0;
error('failed to connect');
return;
endif;
// Create a session instance
session = libssh2_session_init();
if session = *NULL;
error('Could not initialize SSH session');
return;
endif;
// 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 <> 0;
error('Failure establishing SSH session: ' + %trim(%char(rc)));
return;
endif;
// Authenticate
if libssh2_userauth_password(session:
libssh2_from_ccsid(session: sc: 0: user:
trimmed_length(user: %size(user):
%addr(password)): *omit):
libssh2_from_ccsid(session: sc: 0: password:
trimmed_length(password: %size(password):
%addr(filepath)): *omit)) <> 0;
error('Authentication by password failed');
return;
endif;
// Request a file via SFTP
sftp_session = libssh2_sftp_init(session);
if sftp_session = *NULL;
error('Unable to init SFTP session');
return;
endif;
sftp_handle = libssh2_sftp_open(sftp_session:
libssh2_from_ccsid(session: sc: 0: filepath:
trimmed_length(filepath: %size(filepath): *null):
*omit): LIBSSH2_FXF_READ: 0);
if sftp_handle = *NULL;
error('Unable to open file with SFTP: ' +
%trim(%char(libssh2_sftp_last_error(sftp_session))));
return;
endif;
// Download and display the remote file
nread = libssh2_sftp_read(sftp_handle: %addr(buf): %size(buf));
dow nread > 0; // loop until we fail
print(libssh2_to_ccsid(session: sc: 0: %addr(buf): nread: *omit):
-1);
libssh2_release_string_cache(session: sc);
nread = libssh2_sftp_read(sftp_handle: %addr(buf): %size(buf));
enddo;
p main e
/eject
**************************************************************************
* Release all allocated resources
**************************************************************************
*
p cleanout b
*
if sftp_handle <> *NULL;
libssh2_sftp_close(sftp_handle);
endif;
if sftp_session <> *NULL;
libssh2_sftp_shutdown(sftp_session);
endif;
if session <> *NULL;
libssh2_session_disconnect(session: libssh2_from_ccsid(session: sc:
0: 'Normal shutdown': -1: *omit));
libssh2_release_string_cache(session: sc);
libssh2_session_free(session);
endif;
if sock <> LIBSSH2_INVALID_SOCKET;
shutdown(sock: SHUT_RDWR);
LIBSSH2_SOCKET_CLOSE(sock);
endif;
libssh2_exit();
p cleanout e
/eject
**************************************************************************
* Print data line by line
**************************************************************************
*
p print b
d pi
d string * value options(*string)
d len 10i 0 value
*
d recout ds Output line buffer
d lineout 120 inz(*blanks)
*
d i s 10u 0
d j s 10u 0 inz(0)
if len < 0;
len = %len(%str(string));
endif;
for i = 0 to len - 1;
if %str(string + i: 1) <> EBCDIC_CR;
if %str(string + i: 1) = EBCDIC_LF;
write QPRINT recout;
lineout = *blanks;
j = 0;
else;
if j >= %size(lineout);
write QPRINT recout;
lineout = *blanks;
j = 0;
endif;
j = j + 1;
%subst(lineout: j: 1) = %str(string + i: 1);
endif;
endif;
endfor;
if j > 0;
write QPRINT recout;
endif;
p print e
/eject
**************************************************************************
* Error procedure
**************************************************************************
*
p error b
d pi
d message * value options(*string)
*
d errcode ds qualified
d provided 10u 0 inz(0)
d available 10u 0
*
d msgkey s 4
// Send error as an exception to the calling level.
qmhsndpm('CPF9898': 'QCPFMSG QSYS':
%str(message): %len(%str(message)): '*ESCAPE':
'* ': 1: msgkey: errcode);
p error e
/eject
**************************************************************************
* Get the length of right-trimmed string
**************************************************************************
*
p trimmed_length b
d pi 10u 0
d string 999999 options(*varsize)
d length 10u 0 value
d nextarg * value
*
d len s 10u 0
if nextarg <> *null;
len = nextarg - %addr(string);
if length > len;
length = len;
endif;
endif;
len = %scan(X'00': string: 1: length); // Maybe zero-terminated
if len = 0;
len = length + 1;
endif;
return %checkr(' ': string: len - 1); // Trim right
p trimmed_length e

View File

@@ -1,5 +1,4 @@
/*
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
@@ -219,12 +218,14 @@ static const pkcs5algo rc2CBC = {
'\0', 0, 0, 0, 8, 0, 32
};
static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5,
pkcs5algo *algo, asn1Element *param);
#if LIBSSH2_MD5
/* pbeWithMD5AndDES-CBC OID: 1.2.840.113549.1.5.3 */
static const unsigned char OID_pbeWithMD5AndDES_CBC[] = {
9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03
};
static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5,
pkcs5algo *algo, asn1Element *param);
static const pkcs5algo pbeWithMD5AndDES_CBC = {
OID_pbeWithMD5AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC,
Qc3_Pad_Counter, '\0', 8, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 0
@@ -238,6 +239,7 @@ static const pkcs5algo pbeWithMD5AndRC2_CBC = {
OID_pbeWithMD5AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC,
Qc3_Pad_Counter, '\0', 0, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 64
};
#endif
/* pbeWithSHA1AndDES-CBC OID: 1.2.840.113549.1.5.10 */
static const unsigned char OID_pbeWithSHA1AndDES_CBC[] = {
@@ -262,8 +264,10 @@ static const pkcs5algo pbeWithSHA1AndRC2_CBC = {
/* pbeWithMD2AndRC2-CBC OID: 1.2.840.113549.1.5.4: MD2 not implemented. */
static const pkcs5algo * pbestable[] = {
#if LIBSSH2_MD5
&pbeWithMD5AndDES_CBC,
&pbeWithMD5AndRC2_CBC,
#endif
&pbeWithSHA1AndDES_CBC,
&pbeWithSHA1AndRC2_CBC,
&PBES2,
@@ -1427,6 +1431,7 @@ pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase,
Qc3_Format_ALGD0100_T hctx;
int len = pkcs5->saltlen;
char *data = (char *) pkcs5->salt;
Qus_EC_t errcode;
*dk = NULL;
if(pkcs5->dklen > pkcs5->hashlen)
@@ -1437,22 +1442,34 @@ pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase,
if(!*dk)
return -1;
/* Initial hash. */
/* FIXME: check result */
_libssh2_os400qc3_hash_init(&hctx, pkcs5->hash);
/* FIXME: check result */
_libssh2_os400qc3_hash_update(&hctx, passphrase, strlen(passphrase));
hctx.Final_Op_Flag = Qc3_Final;
/* FIXME: check result */
Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data, (char *) &hctx,
Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull);
set_EC_length(errcode, sizeof(errcode));
errcode.Bytes_Available = 1; /* Defaults to error flagging. */
/* Iterate. */
len = pkcs5->hashlen;
for(i = 1; i < pkcs5->itercount; i++)
/* FIXME: check result */
Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx,
Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull);
/* Initial hash. */
if(_libssh2_os400qc3_hash_init(&hctx, pkcs5->hash)) {
if(_libssh2_os400qc3_hash_update(&hctx,
passphrase, strlen(passphrase))) {
hctx.Final_Op_Flag = Qc3_Final;
Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data,
(char *) &hctx, Qc3_Alg_Token, anycsp, NULL, *dk,
(char *) &errcode);
/* Iterate. */
len = pkcs5->hashlen;
for(i = 1; !errcode.Bytes_Available && i < pkcs5->itercount; i++)
Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx,
Qc3_Alg_Token, anycsp, NULL, *dk,
(char *) &errcode);
}
Qc3DestroyAlgorithmContext(hctx.Alg_Context_Token, (char *) &ecnull);
}
if(errcode.Bytes_Available) {
LIBSSH2_FREE(session, *dk);
*dk = NULL;
return -1;
}
/* Special stuff for PBES1: split derived key into 8-byte key and 8-byte
initialization vector. */
@@ -1460,8 +1477,6 @@ pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase,
pkcs5->ivlen = 8;
pkcs5->iv = *dk + 8;
/* Clean-up and exit. */
Qc3DestroyAlgorithmContext(hctx.Alg_Context_Token, (char *) &ecnull);
return 0;
}

View File

@@ -1,7 +1,6 @@
#ifndef LIBSSH2_OS400QC3_H
#define LIBSSH2_OS400QC3_H
/*
* Copyright (C) Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
@@ -165,7 +164,12 @@
#define Qc3_MK_Pending '\xF3' /* '3' */
/* Define which features are supported. */
#define LIBSSH2_MD5 1
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
@@ -187,10 +191,6 @@
#include "crypto_config.h"
/* FIXME: Disable MD5 macros, constants and functions when
LIBSSH2_MD5 and LIBSSH_MD5_PEM have the value 0. */
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
@@ -247,7 +247,6 @@ typedef struct { /* Diffie-Hellman context. */
#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha384_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha512_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx
@@ -280,11 +279,16 @@ typedef struct { /* Diffie-Hellman context. */
#define libssh2_sha512(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA512)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_init(x) _libssh2_os400qc3_hash_init(x, Qc3_MD5)
#define libssh2_md5_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#endif
#define _libssh2_bn_ctx int /* Not used. */