diff --git a/os400/README400 b/os400/README400 index e14bcf36..acb1eb7e 100644 --- a/os400/README400 +++ b/os400/README400 @@ -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: diff --git a/os400/ccsid.c b/os400/ccsid.c index 637b12e5..49ca4b1f 100644 --- a/os400/ccsid.c +++ b/os400/ccsid.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Patrick Monnerat, D+H + * Copyright (C) Patrick Monnerat * All rights reserved. * * Redistribution and use in source and binary forms, @@ -48,6 +48,7 @@ #include #include #include +#include @@ -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); } } diff --git a/os400/config400.default b/os400/config400.default new file mode 100644 index 00000000..5147cb20 --- /dev/null +++ b/os400/config400.default @@ -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. diff --git a/os400/initscript.sh b/os400/initscript.sh index d5334e35..87d9f3c5 100644 --- a/os400/initscript.sh +++ b/os400/initscript.sh @@ -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 diff --git a/os400/libssh2rpg/libssh2.rpgle.in b/os400/libssh2rpg/libssh2.rpgle.in index 51f376e2..e19848eb 100644 --- a/os400/libssh2rpg/libssh2.rpgle.in +++ b/os400/libssh2rpg/libssh2.rpgle.in @@ -1,4 +1,4 @@ - * Copyright (C) Patrick Monnerat, D+H + * Copyright (C) Patrick Monnerat * 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() * diff --git a/os400/libssh2rpg/libssh2_sftp.rpgle b/os400/libssh2rpg/libssh2_sftp.rpgle index 9d063245..4ccb81b5 100644 --- a/os400/libssh2rpg/libssh2_sftp.rpgle +++ b/os400/libssh2rpg/libssh2_sftp.rpgle @@ -1,4 +1,4 @@ - * Copyright (C) Patrick Monnerat, D+H + * Copyright (C) Patrick Monnerat * 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... diff --git a/os400/macros.h b/os400/macros.h index 80cba05b..9766489b 100644 --- a/os400/macros.h +++ b/os400/macros.h @@ -1,5 +1,5 @@ /* - * Copyright (C) Patrick Monnerat, D+H + * Copyright (C) Patrick Monnerat * 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); diff --git a/os400/make.sh b/os400/make.sh index 317c56e7..96642f43 100644 --- a/os400/make.sh +++ b/os400/make.sh @@ -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 diff --git a/os400/rpg-examples/SFTPXMPLE b/os400/rpg-examples/SFTPXMPLE new file mode 100644 index 00000000..051ddda2 --- /dev/null +++ b/os400/rpg-examples/SFTPXMPLE @@ -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 ('' '' '' '' '') + * + * 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 diff --git a/src/os400qc3.c b/src/os400qc3.c index ae5693fc..0a3a6cb4 100644 --- a/src/os400qc3.c +++ b/src/os400qc3.c @@ -1,5 +1,4 @@ /* - * Copyright (C) Patrick Monnerat, D+H * Copyright (C) Patrick Monnerat * 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; } diff --git a/src/os400qc3.h b/src/os400qc3.h index e1e4b117..c430627b 100644 --- a/src/os400qc3.h +++ b/src/os400qc3.h @@ -1,7 +1,6 @@ #ifndef LIBSSH2_OS400QC3_H #define LIBSSH2_OS400QC3_H /* - * Copyright (C) Patrick Monnerat, D+H * Copyright (C) Patrick Monnerat * 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. */